| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.839 Tracking Error 0.073 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
from AlgorithmImports import *
from datetime import datetime
class WilliamsZenAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2023, 7, 1)
self.SetEndDate(datetime.now())
self.SetAccountCurrency("USD")
self.SetCash(100000)
self.SetBrokerageModel(BrokerageName.OandaBrokerage, AccountType.Margin) # InteractiveBrokersBrokerage, AccountType.Cash
# create empty dictionary to store indicators for each symbol
self.data = {}
# choose forex pairs
self.symbols = [
# "EURCHF","EURGBP","EURJPY","EURAUD","EURCAD",
# "EURUSD","AUDUSD","GBPUSD","USDCAD", "USDCHF",
"USDJPY", # "GBPJPY","AUDJPY","CADJPY", "CHFJPY", "NZDJPY",
# "AUDCAD", "AUDCHF", "AUDNZD", "CADCHF",
# "EURNZD", "GBPAUD", "GBPCAD", "GBPCHF", "GBPNZD", "NZDCAD", "NZDCHF",
# "NZDUSD",
]
# warm up 15 bars
self.SetWarmUp(15)
for symbol in self.symbols:
# Price Data
self.AddForex(symbol, Resolution.Hour, Market.Oanda)
self.data[symbol] = {}
# Lot Size per Symbol
self.data[symbol]["lotSize"] = self.Securities[symbol].SymbolProperties.LotSize
# self.data[symbol]["roundedOrderSize"] = round(orderQuantity/self.data[symbol]["lotSize"]) * self.data[symbol]["lotSize"]
# Set Indicators
self.Debug("Initiating Alligator for " + symbol)
self.data[symbol]["alligator"] = {}
self.data[symbol]["alligator"]["jaw"] = ExponentialMovingAverage("jaw", 25)
self.data[symbol]["alligator"]["teeth"] = ExponentialMovingAverage("teeth", 15)
self.data[symbol]["alligator"]["lips"] = ExponentialMovingAverage("lips", 9)
self.data[symbol]["ao"]= self.AO(symbol, 5, 34, MovingAverageType.Simple)
# self.data[symbol]["fractals"] = {}
# self.data[symbol]["fractals"]["bear"] = 4
# self.data[symbol]["fractals"]["bull"] = 5
# self.data[symbol]["divergent"] = {}
# self.data[symbol]["divergent"]["bear"] = 6
# self.data[symbol]["divergent"]["bull"] = 7
# chart = Chart(symbol+"-chart")
# self.AddChart(chart)
self.SetWarmUp(34)
def OnData(self, data) -> None: # slice: Slice) -> None:
for symbol in self.symbols:
# Calculate Indicators
if data.ContainsKey(symbol):
# Calcualte HL/2
hl2 = data[symbol].Ask.High + data[symbol].Ask.Low / 2
# Feed HL2 into Alligator Lines
self.data[symbol]["alligator"]["jaw"].Update(data.Time, hl2)
self.data[symbol]["alligator"]["teeth"].Update(data.Time, hl2)
self.data[symbol]["alligator"]["lips"].Update(data.Time, hl2)
# Plot Alligator
self.Plot(symbol+"-alligator", "jaw", self.data[symbol]["alligator"]["jaw"].Current.Value)
self.Plot(symbol+"-alligator", "teeth", self.data[symbol]["alligator"]["teeth"].Current.Value)
self.Plot(symbol+"-alligator", "lips", self.data[symbol]["alligator"]["lips"].Current.Value)
else:
return
if self.IsWarmingUp:
return
def OnWarmupFinished(self) -> None:
self.Log("Algorithm Ready")
def OnEndOfDay(self, symbol: Symbol) -> None:
pass
"""
self.History()
H = self.History(self.stock, 5, Resolution.Daily)['high']
L = self.History(self.stock, 5, Resolution.Daily)['low']
upFractal = (L[-5] > L[-3] < L[-4]) and (L[-2] > L[-3] < L[-1])
dnFractal = (H[-5] < H[-3] > H[-4]) and (H[-2] < H[-3] > H[-1])
"""
# BUY
# ticket = self.StopLimitOrder(symbol, quantity, stop_rice, limit_price, tag, order_properties)
# ticket = self.MarketOrder(symbol, quantity, tag=tag, orderProperties=order_properties)
# self.Debug(f"Quantity filled: {ticket.QuantityFilled}; Fill price: {ticket.AverageFillPrice}")
# SELL
# asset = self.Securities[symbol]
# base_currency = asset.BaseCurrency
# Avoid negative amount after liquidate
# quantity = min(asset.Holdings.Quantity, base_currency.Amount)
# Round down to observe the lot size
# lot_size = asset.SymbolProperties.LotSize;
# quantity = (round(quantity / lot_size) - 1) * lot_size
# if self.IsValidOrderSize(asset, quantity):
# self.MarketOrder(symbol, -quantity)
"""
if slice.ContainsKey(symbol):
price_data = slice[symbol]
if slice.Bars.ContainsKey(symbol):
trade_bar = slice.Bars[symbol]
if slice.QuoteBars.ContainsKey(symbol):
quote_bar = slice.QuoteBars[symbol]
last_price = self.Securities[symbol].GetLastData()
available_buying_power = self.Portfolio.GetBuyingPower(symbol, OrderDirection.Buy)
asset = self.Securities[symbol]
quote_currency = asset.QuoteCurrency
contract_mutiplier = asset.SymbolProperties.ContractMultiplier
minimum_price_variation = asset.SymbolProperties.MinimumPriceVariation
# Value of a pip in account currency
pip = minimum_price_variation * contract_mutiplier * quote_currency.ConversionRate
"""from AlgorithmImports import *
import pandas as pd
from typing import Tuple
from collections import deque
# Custom Indicator
# class MyCustomIndicator:
# def __init__(self, params):
# self.params = params
# Input can be any IBaseData object: Tick, TradeBar, QuoteBar, ...
# def Update(self, input):
# pass
class WilliamsAlligator(PythonIndicator):
def __init__(self, name, period):
self.Name = name
self.Time = datetime.min
# Queuing and Warmup
self.queue = deque(maxlen=period)
self.WarmUpPeriod = period
def __repr__(self):
return "{0} -> IsReady: {1}. Time: {2}. Value: {3}".format(
self.Name, self.IsReady, self.Time, self.Value)
def will_frac(df: pd.DataFrame, period: int = 2) -> Tuple[pd.Series, pd.Series]:
"""Indicate bearish and bullish fractal patterns using shifted Series.
:param df: OHLC data
:param period: number of lower (or higher) points on each side of a high (or low)
:return: tuple of boolean Series (bearish, bullish) where True marks a fractal pattern
"""
periods = [p for p in range(-period, period + 1) if p != 0] # default [-2, -1, 1, 2]
highs = [df['high'] > df['high'].shift(p) for p in periods]
bears = pd.Series(np.logical_and.reduce(highs), index=df.index)
lows = [df['low'] < df['low'].shift(p) for p in periods]
bulls = pd.Series(np.logical_and.reduce(lows), index=df.index)
return bears, bulls
# Input can be any IBaseData object: Tick, TradeBar, QuoteBar, ...
def Update(self, input: BaseData) -> bool:
self.queue.append([input.High, input.Low])
if len(self.queue) > 5:
queue_df = np.array(self.queue)
self.jaw_value = talib.EMA(queue_array, self.jaw_period)[-1]
self.teeth_value = talib.EMA(queue_array, self.teeth_period)[-1]
self.lips_value = talib.EMA(queue_array, self.lips_period)[-1]
self.Value = (self.jaw_value + self.teeth_value + self.lips_value) / 3
self.IsReady = True
return self.IsReady