| 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")