Overall Statistics |
Total Trades 360 Average Win 1.65% Average Loss -2.55% Compounding Annual Return 6.332% Drawdown 40.500% Expectancy 0.272 Net Profit 97.112% Sharpe Ratio 0.42 Probabilistic Sharpe Ratio 1.975% Loss Rate 23% Win Rate 77% Profit-Loss Ratio 0.65 Alpha 0.068 Beta -0.057 Annual Standard Deviation 0.146 Annual Variance 0.021 Information Ratio -0.296 Tracking Error 0.213 Treynor Ratio -1.084 Total Fees $1524.64 |
# Take the original SPY pullback strategy and add multiple entries class SPYMeanReversionAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2009,1, 1) #Set Start Date self.SetEndDate(2020,1,20) #Set End Date self.SetCash(10000) #Set Strategy Cash self.spy = self.AddEquity("SPY", Resolution.Daily) self.spy = self.AddEquity("GLD", Resolution.Daily) self.upro = self.AddEquity("UPRO", Resolution.Daily) self.shy = self.AddEquity("SHY", Resolution.Daily) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage) self.rsi2 = self.RSI("SPY", 2, MovingAverageType.Simple, Resolution.Daily); self.rsi20 = self.RSI("SPY", 20, MovingAverageType.Simple, Resolution.Daily); self.sma200 = self.SMA("SPY", 200, Resolution.Daily); self.SetWarmUp(200) # dictionary to hold our target position sizes {position count: % allocation} self.targets = {0:0, 1:0.25, 2:0.5, 3:0.65, 4:0.85, 5:1} # counter which tracks where in the sequence of sizes we are, start at zero for no position self.counter = 0 def OnData(self, data): if self.IsWarmingUp: return if not self.sma200.IsReady: return if not self.rsi2.IsReady: return if not self.rsi20.IsReady: return if data.ContainsKey("SPY") == False: return if data[self.spy.Symbol].Low>self.sma200.Current.Value and self.rsi2.Current.Value<20: # if we add 1 to our current position count and it is greater than our 100% allocation, then we do nothing if self.counter + 1 not in self.targets: return # since this is a new buy signal, we look at our current position counter and go up to the next allocation amount self.counter += 1 #self.SetHoldings("SHY", 0) self.SetHoldings("UPRO", self.targets[self.counter]) if data[self.spy.Symbol].High>self.sma200.Current.Value and self.rsi2.Current.Value>75 or data[self.spy.Symbol].High<self.sma200.Current.Value and self.rsi2.Current.Value>70: self.SetHoldings("UPRO", 0) #self.SetHoldings("SHY", 1) # Reset the positions counter to zero for the next trade, else you will only get 5 entries forever. self.counter = 0