| Overall Statistics |
|
Total Trades 117 Average Win 5.39% Average Loss -1.29% Compounding Annual Return 39.523% Drawdown 12.600% Expectancy 2.293 Net Profit 445.883% Sharpe Ratio 1.959 Probabilistic Sharpe Ratio 95.753% Loss Rate 36% Win Rate 64% Profit-Loss Ratio 4.16 Alpha 0.223 Beta 0.505 Annual Standard Deviation 0.171 Annual Variance 0.029 Information Ratio 0.666 Tracking Error 0.17 Treynor Ratio 0.663 Total Fees $764.64 |
class OnInOut(QCAlgorithm):
def Initialize(self):
self.MinsAfterOpen = int(self.GetParameter("minsAfterOpen"))
# Indicators
self.RsiLowGap = int(self.GetParameter("rsiLow"))
self.RsiHighGap = int(self.GetParameter("rsiHigh"))
self.PpoGap = float(self.GetParameter("ppo"))
self.SlopeGap = float(self.GetParameter("slope"))
self.MompGap = 100 # not in use ATM float(self.GetParameter("momp"))
self.MacdGap = float(self.GetParameter("macd"))
self.MacdSignalGap = float(self.GetParameter("macdSignal"))
#Indicators' input
self.SmaDays = int(self.GetParameter("smaDays"))
self.MacdFastDays = int(self.GetParameter("macdFastDays"))
self.MacdSlowDays = int(self.GetParameter("macdSlowDays"))
self.MacdSignalDays = int(self.GetParameter("macdSignalDays"))
self.RsiDays = int(self.GetParameter("rsiDays"))
self.SmaLongDays = 30 # not in use ATM int(self.GetParameter("smaLongDays"))
self.SmaShortDays = int(self.GetParameter("smaShortDays"))
self.PpoSlowDays = int(self.GetParameter("ppoSlowDays"))
self.PpoFastDays = int(self.GetParameter("ppoFastDays"))
# used with the SMA indicator. Not used ATM.
self.Factor = float(self.GetParameter("factor"))
self.StartYear = int(self.GetParameter("startYear"))
self.EndYear = int(self.GetParameter("endYear"))
# Trade time in minutes after market open
self.MinDaysOut = int(self.GetParameter("daysOut"))
self.OutEquity="TLT" #,"VXX"] # Out of market portfolio. Divide Cash among list
self.InEquity ="QQQ" # In market asset
#For Plots on Equity Graph
self.InEquityHistory = [] # now used for QQQ
self.OutEquityHistory = [] # now used to TLT
self.SetStartDate(self.StartYear, 1, 1)
self.SetEndDate(self.EndYear,12,31)
self.StartCash = 100000
self.SetCash(self.StartCash)
# Debug Algo Input parameters
#self.Debug(f"After Market Open. rsiLow:{self.RsiLowGap} rsiHigh:{self.RsiHighGap} ppo:{self.PpoGap} rsiDays:{self.RsiDays} smaLongDays:{self.SmaLongDays} smaShortDays:{self.SmaShortDays} ppoFastDays:{self.PpoFastDays} ppoSlowDays:{self.PpoSlowDays}")
# ------------------------------------------- Defining Tickers and collection Indicators -----------------------------
self.VXX = self.AddEquity("VXX", Resolution.Daily).Symbol
self.VIXY = self.AddEquity("VIXY", Resolution.Daily).Symbol
self.tickers = ["QQQ","TLT"] # ,"FDN","SPY","ARKK","SQQQ","GLD","PSQ","SH","EMTY", "XLU","XLP","TBT","IEF", "FDN","TLH"]
self.TickerTable = {}
for ticker in self.tickers:
# --------- Add Equity
self.AddEquity(ticker, Resolution.Hour)
# --------- Add Equity indicators
#self.Debug(f"{self.RsiDays} {self.SmaShortDays} {self.SmaLongDays} {self.PpoFastDays} {self.PpoSlowDays} ")
rsi = self.RSI(ticker, self.RsiDays, Resolution.Daily)
smaLong = self.SMA(ticker, self.SmaLongDays, Resolution.Daily)
smaShort = self.SMA(ticker, self.SmaShortDays, Resolution.Daily)
rcShort = self.RC(ticker,self.SmaShortDays, Resolution.Daily)
ppo = self.PPO(ticker, self.PpoFastDays, self.PpoSlowDays, MovingAverageType.Simple, Resolution.Daily)
momp = self.MOMP(ticker, 28, Resolution.Daily)
sma = self.SMA(ticker, self.SmaDays, Resolution.Daily)
ema = self.EMA(ticker, self.SmaDays, Resolution.Daily)
macd = self.MACD(ticker, self.MacdFastDays,self.MacdSlowDays,self.MacdSignalDays,MovingAverageType.Exponential, Resolution.Daily)
symbolData = SymbolData(ticker, rsi, smaLong, smaShort, rcShort, ppo, momp, sma, ema, macd)
self.TickerTable[ticker] = symbolData
self.Schedule.On(self.DateRules.EveryDay(self.InEquity),self.TimeRules.AfterMarketOpen(self.InEquity,self.MinsAfterOpen), self.Trade)
self.SetBenchmark("QQQ")
self.MyInOutIndicator = 1 # Default Enter the Market
self.DaysOut = 0 # Cooldown days after exiting the Market
self.TotalDays =0 # Counter for total days
self.TotalDaysIn = 0 # Counter for days in the MArket
self.SetWarmUp(timedelta(days=30))
# ------------------------------------------------- On Data -----------------------------------------------------
def OnData(self, data):
pass
# ---------------------------------------------- Trade Function --------------------------------------------------
def Trade(self):
self.TotalDays +=1
self.InEquity_RSI = self.TickerTable[self.InEquity].Rsi.Current.Value
self.InEquity_PPO = self.TickerTable[self.InEquity].Ppo.Current.Value
self.InEquity_BIG_SMA_WINDOW = self.TickerTable[self.InEquity].SmaLong.Current.Value
self.InEquity_SMALL_SMA_WINDOW = self.TickerTable[self.InEquity].SmaShort.Current.Value
self.InEquity_SLOPE = self.TickerTable[self.InEquity].RcShort.Slope.Current.Value
self.InEquity_MOMP = self.TickerTable[self.InEquity].Momp.Current.Value
self.InEquity_SMA = self.TickerTable[self.InEquity].Sma.Current.Value
self.InEquity_EMA = self.TickerTable[self.InEquity].Ema.Current.Value
self.InEquity_MACD = self.TickerTable[self.InEquity].Macd.Current.Value
self.InEquity_MACD_Signal = self.TickerTable[self.InEquity].Macd.Signal.Current.Value
#self.Debug(f"{self.Time} PPO:{round(self.InEquity_PPO,2)} Slope:{round(self.InEquity_SLOPE,2)} RSI:{round(self.InEquity_RSI,2)} BIG_SMA_WINDOW:{round(self.InEquity_BIG_SMA_WINDOW,2)} SMALL_SMA_WINDOW:{round(self.InEquity_SMALL_SMA_WINDOW,2)}")
#if self.InEquity_MACD < self.InEquity_MACD_Signal * self.Factor:
#if self.InEquity_EMA > self.Securities[self.InEquity].Price * self.Factor:
# Go out if SIGNAL is High and VALUE is Low
#if self.InEquity_MACD_Signal > self.MacdSignalGap and self.InEquity_MACD < self.MacdGap:
#if self.InEquity_MACD_Signal > self.InEquity_MACD * 1.2:
if self.InEquity_PPO <= self.PpoGap or self.InEquity_SLOPE < self.SlopeGap or self.InEquity_RSI < self.RsiLowGap:
self.MyInOutIndicator = 0
self.DaysOut = 0 # Zero the DaysOut counter
self.Log(f"{self.Time} {self.InEquity_PPO} {self.InEquity_RSI} {self.InEquity_SLOPE}")
else:
if self.DaysOut >= self.MinDaysOut:
self.MyInOutIndicator = 1
self.DaysOut = 0
else:
self.DaysOut +=1 # ---- Unless in Market out Cooldown
if self.MyInOutIndicator == 1:
self.TotalDaysIn +=1
if not self.Securities[self.InEquity].Invested:
self.SetHoldings(self.InEquity, 1.00, True,f"PPO:{self.InEquity_PPO} SLOPE:{self.InEquity_SLOPE} RSI:{self.InEquity_RSI}")
self.Notify.Sms("+972542224488", self.InEquity +" In:" + str(self.Securities[self.InEquity].Price))
else:
if not self.Securities[self.OutEquity].Invested:
self.SetHoldings(self.OutEquity, 1.00, True,f"PPO:{self.InEquity_PPO} SLOPE:{self.InEquity_SLOPE} RSI:{self.InEquity_RSI}")
self.Notify.Sms("+972542224488", self.InEquity + " Out:" + str(self.Securities[self.InEquity].Price))
self.PlotIt()
# ----------------------------------------------- End of Algo ---------------------------------------------------
def OnEndOfAlgorithm(self):
self.Liquidate()
if self.TotalDays>0:
self.Debug(f"TPV:{round(self.Portfolio.TotalPortfolioValue,2)} Total Days:{self.TotalDays} Total Days In:{self.TotalDaysIn} {round(self.TotalDaysIn/self.TotalDays*100,2)}%")
# ---------------------------------------------- Plot Function --------------------------------------------------
def PlotIt(self):
self.Plot("In/Out Indicator","InOut",self.MyInOutIndicator)
self.Plot("RSI","RSI",self.InEquity_RSI)
self.Plot("PPO","PPO",self.InEquity_PPO)
self.Plot("Slope","SLOPE",self.InEquity_SLOPE)
self.Plot("Momp","MOMP", self.InEquity_MOMP)
#self.Plot("MACD","Value",self.InEquity_MACD)
#self.Plot("MACD","Signal",self.InEquity_MACD_Signal)
try:
self.Plot("VXX","TLT",self.Securities[self.VXX.Value].Price)
except:
pass
# Benchmark Ploting
hist = self.History([self.InEquity], 2, Resolution.Daily)['close'].unstack(level= 0).dropna()
self.InEquityHistory.append(hist[self.InEquity].iloc[-1])
perf = self.InEquityHistory[-1] / self.InEquityHistory[0] * self.StartCash
self.Plot("Strategy Equity", self.InEquity, perf)
hist = self.History([self.OutEquity], 2, Resolution.Daily)['close'].unstack(level= 0).dropna()
self.OutEquityHistory.append(hist[self.OutEquity].iloc[-1])
perf = self.OutEquityHistory[-1] / self.OutEquityHistory[0] * self.StartCash
self.Plot("Strategy Equity", self.OutEquity, perf)
# ---------------------------------------------- SymbolData --------------------------------------------------
class SymbolData:
def __init__(self, symbol, rsi, smaLong, smaShort, rcShort, ppo, momp, sma, ema, macd):
self.Symbol = symbol
self.Rsi = rsi
self.SmaLong = smaLong
self.SmaShort = smaShort
self.RcShort = rcShort
self.Ppo = ppo
self.Momp = momp
self.Sma = sma
self.Ema = ema
self.Macd = macd