Overall Statistics |
Total Orders 10001 Average Win 0.65% Average Loss -0.98% Compounding Annual Return 105.086% Drawdown 29.000% Expectancy 0.428 Start Equity 100000 End Equity 682448.98 Net Profit 582.449% Sharpe Ratio 2.088 Sortino Ratio 2.163 Probabilistic Sharpe Ratio 88.223% Loss Rate 14% Win Rate 86% Profit-Loss Ratio 0.66 Alpha 0.649 Beta 0.799 Annual Standard Deviation 0.346 Annual Variance 0.12 Information Ratio 2.023 Tracking Error 0.312 Treynor Ratio 0.904 Total Fees $947.93 Estimated Strategy Capacity $430000000.00 Lowest Capacity Asset AMZN R735QTJ8XC9X Portfolio Turnover 5.29% |
from AlgorithmImports import * class EMAMovingAverageStrategy(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) self.SetEndDate(2021, 1, 1) self.SetCash(100000) # Add all symbols in S&P 500 self.symbols = ["AAPL", "MSFT", "GOOGL", "AMZN", "FB", "JPM", "V", "PG", "DIS", "HD", # Add more symbols as needed "VZ", "KO", "INTC", "NFLX", "TSLA", "NVDA", "UNH", "PYPL", "PEP", "ABT", "BAC", "CMCSA", "ADBE", "XOM", "MRK", "PFE", "WMT", "NKE", "CSCO", "MCD", "MA", "ABNB", "CRM", "AVGO", "T", "ORCL", "ACN", "CVX", "LMT", "MDT", "IBM", "TXN", "QCOM", "LOW", "AMGN", "SBUX", "TMO", "COST", "GILD", "UPS"] # Initialize indicators and rolling windows for each symbol self.indicators = {} self.ema60_tracks = {} for symbol in self.symbols: equity = self.AddEquity(symbol, Resolution.Daily) self.indicators[symbol] = { "ema9": self.EMA(equity.Symbol, 9, Resolution.Daily), "ema15": self.EMA(equity.Symbol, 15, Resolution.Daily), "ema65": self.EMA(equity.Symbol, 65, Resolution.Daily), "ema200": self.EMA(equity.Symbol, 150, Resolution.Daily), "ema35": self.EMA(equity.Symbol, 35 , Resolution.Daily), "rsi": self.RSI(equity.Symbol, 10, Resolution.Daily) } self.ema60_tracks[symbol] = RollingWindow[IndicatorDataPoint](60) self.SetWarmUp(200) def OnData(self, data): if self.IsWarmingUp: return for symbol in self.symbols: if data.ContainsKey(symbol): current_data = data[symbol] if current_data: self.ema60_tracks[symbol].Add(self.indicators[symbol]["ema35"].Current) for symbol in self.symbols: if self.ema60_tracks[symbol].IsReady: self.TradeSymbol(symbol) def TradeSymbol(self, symbol): indicators = self.indicators[symbol] ema60_track = self.ema60_tracks[symbol] # Corrected attribute name if self.IsBuyCondition(indicators, ema60_track): # Pass ema60_track to IsBuyCondition self.SetHoldings(symbol, 1) elif self.IsSellCondition(indicators, ema60_track): # Pass ema60_track to IsSellCondition self.Liquidate(symbol) elif self.Portfolio[symbol].Invested: if self.IsExitBuyCondition(indicators): self.Liquidate(symbol) elif self.IsExitSellCondition(indicators): self.Liquidate(symbol) def IsBuyCondition(self, indicators, ema60_track): # Added ema60_track parameter ema_condition = (indicators["ema9"].Current.Value > indicators["ema15"].Current.Value > indicators["ema65"].Current.Value > indicators["ema200"].Current.Value) ema35_condition = all(x.Value > 60 for x in ema60_track) return ema_condition and ema35_condition def IsSellCondition(self, indicators, ema60_track): # Added ema60_track parameter ema_condition = (indicators["ema9"].Current.Value < indicators["ema15"].Current.Value < indicators["ema65"].Current.Value < indicators["ema200"].Current.Value) ema35_condition = all(x.Value < 60 for x in ema60_track) return ema_condition and ema35_condition def IsExitBuyCondition(self, indicators): ema_cross_condition = (indicators["ema9"].Current.Value < indicators["ema65"].Current.Value or indicators["ema15"].Current.Value < indicators["ema65"].Current.Value) rsi_condition = indicators["rsi"].Current.Value < 40 return ema_cross_condition and rsi_condition def IsExitSellCondition(self, indicators): ema_cross_condition = (indicators["ema9"].Current.Value > indicators["ema65"].Current.Value or indicators["ema15"].Current.Value > indicators["ema65"].Current.Value) rsi_condition = indicators["rsi"].Current.Value > 60 return ema_cross_condition and rsi_condition