Overall Statistics |
Total Orders 10001 Average Win 0.16% Average Loss -0.32% Compounding Annual Return 49.592% Drawdown 26.300% Expectancy 0.304 Start Equity 100000 End Equity 298447.53 Net Profit 198.448% Sharpe Ratio 1.204 Sortino Ratio 1.15 Probabilistic Sharpe Ratio 56.104% Loss Rate 13% Win Rate 87% Profit-Loss Ratio 0.50 Alpha 0.294 Beta 0.925 Annual Standard Deviation 0.3 Annual Variance 0.09 Information Ratio 1.198 Tracking Error 0.241 Treynor Ratio 0.39 Total Fees $2098.91 Estimated Strategy Capacity $53000000.00 Lowest Capacity Asset TMO R735QTJ8XC9X Portfolio Turnover 3.59% |
from AlgorithmImports import * class EMAMovingAverageStrategy(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) self.SetEndDate(2024, 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.sma60_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), "sma14": self.EMA(equity.Symbol, 35, Resolution.Daily), "rsi": self.RSI(equity.Symbol, 14, Resolution.Daily) } self.sma60_tracks[symbol] = RollingWindow[IndicatorDataPoint](1) self.SetWarmUp(1) 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.sma60_tracks[symbol].Add(self.indicators[symbol]["sma14"].Current) for symbol in self.symbols: if self.sma60_tracks[symbol].IsReady: self.TradeSymbol(symbol) def TradeSymbol(self, symbol): indicators = self.indicators[symbol] sma60_track = self.sma60_tracks[symbol] # Corrected attribute name if self.IsBuyCondition(indicators, sma60_track): # Pass sma60_track to IsBuyCondition self.SetHoldings(symbol, 0.25) elif self.IsSellCondition(indicators, sma60_track): # Pass sma60_track to IsSellCondition self.Liquidate(symbol) if self.Portfolio[symbol].Invested: if self.IsExitBuyCondition(indicators): self.Liquidate(symbol) def IsBuyCondition(self, indicators, sma60_track): # Added sma60_track parameter ema_condition = (indicators["ema9"].Current.Value > indicators["ema15"].Current.Value > indicators["ema65"].Current.Value > indicators["ema200"].Current.Value) sma_condition = all(x.Value > 50 for x in sma60_track) return ema_condition and sma_condition def IsSellCondition(self, indicators, sma60_track): # Added sma60_track parameter ema_condition = (indicators["ema9"].Current.Value < indicators["ema15"].Current.Value < indicators["ema65"].Current.Value < indicators["ema200"].Current.Value) sma_condition = all(x.Value < 50 for x in sma60_track) return ema_condition and sma_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