Overall Statistics |
Total Trades 93 Average Win 4.13% Average Loss -2.95% Compounding Annual Return 11.515% Drawdown 16.400% Expectancy 0.670 Net Profit 152.572% Sharpe Ratio 0.901 Probabilistic Sharpe Ratio 32.062% Loss Rate 30% Win Rate 70% Profit-Loss Ratio 1.40 Alpha 0.046 Beta 0.402 Annual Standard Deviation 0.092 Annual Variance 0.008 Information Ratio -0.069 Tracking Error 0.114 Treynor Ratio 0.206 Total Fees $241.57 Estimated Strategy Capacity $1100000000.00 Lowest Capacity Asset SPY R735QTJ8XC9X Portfolio Turnover 2.69% |
# region imports from AlgorithmImports import * # endregion class UpgradedRedOrangeSnake(QCAlgorithm): def Initialize(self): self.SetStartDate(2015, 1, 1) # Set Start Date self.SetEndDate(2023,7,1) self.SetCash(100000) # Set Strategy Cash self.UniverseSettings.Leverage = 2.0 self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol self.apo = self.APO(self.spy,10,20,MovingAverageType.Simple,Resolution.Daily).Signal self.SetWarmup(25) self.apo.Updated += self.ApoUpdated self.apoWin = RollingWindow[IndicatorDataPoint](2) self.SetBenchmark("SPY") self.lastExitTime = datetime.min #Crear promedios y desviaciones estándar para calcular la Z. self.signalmean = SimpleMovingAverage(5) self.signalstd = StandardDeviation(5) self.ZWin = RollingWindow[float](2) #Helper Variables para TP y SL self.stop_loss_percent = 0.075 def ApoUpdated(self, sender, updated): self.apoWin.Add(updated) def OnData(self, data: Slice): if not (self.apoWin.IsReady): return currApo = self.apoWin[0] pastApo = self.apoWin[1] self.signalmean.Update(self.Time,self.apo.Current.Value) self.signalstd.Update(self.Time, self.apo.Current.Value) try: signal_z = (self.apo.Current.Value-self.signalmean.Current.Value)/(self.signalstd.Current.Value) self.ZWin.Add(float(signal_z)) except: signal_z = 0.0 pastZ = self.ZWin[1] currZ = self.ZWin[0] if self.apo.IsReady: # The current value of self.apo is represented by self.apo.Current.Value self.Plot("AbsolutePriceOscillator", "Signal", currApo) self.Plot("AbsolutePriceOscillator","Apo Z", currZ) self.Plot("AbsolutePriceOscillator","Past Z", pastZ) if not self.Portfolio.Invested and currZ > -1.4 and pastZ < -1.4: if (self.Time - self.lastExitTime).days > 10: self.SetHoldings("SPY",0.90) if self.Portfolio.Invested and currZ < 1.0 and pastZ > 1.0: self.Liquidate(tag="Z Score Liquidation") self.lastExitTime = self.Time if self.Portfolio.Invested: try: price = data[self.spy].Close if price <= self.Portfolio[self.spy].AveragePrice * (1-self.stop_loss_percent): self.Liquidate(tag="Stop Loss Liquidation") self.lastExitTime = self.Time except: self.Log("No price data today")