Overall Statistics |
Total Orders 1537 Average Win 0.12% Average Loss -0.12% Compounding Annual Return 82.177% Drawdown 7.700% Expectancy 0.730 Start Equity 100000 End Equity 117080.29 Net Profit 17.080% Sharpe Ratio 1.973 Sortino Ratio 2.196 Probabilistic Sharpe Ratio 66.658% Loss Rate 12% Win Rate 88% Profit-Loss Ratio 0.98 Alpha 0.042 Beta 2.159 Annual Standard Deviation 0.262 Annual Variance 0.069 Information Ratio 1.487 Tracking Error 0.2 Treynor Ratio 0.239 Total Fees $88.89 Estimated Strategy Capacity $26000000.00 Lowest Capacity Asset MA TIX2XDPLFR6T Portfolio Turnover 7.01% |
from AlgorithmImports import * class EMAMovingAverageStrategy(QCAlgorithm): def Initialize(self): self.SetStartDate(2024, 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 = {} 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, 14, Resolution.Daily) } self.WarmUpIndicator(symbol) # Ensure the algorithm waits until all indicators are warmed up self.SetWarmUp(200) def WarmUpIndicator(self, symbol): # Get historical data for warm-up history = self.History(symbol, 210, Resolution.Daily) # Warm up the indicators with historical data for bar in history: self.indicators[symbol]["ema9"].Update(bar.EndTime, bar.Close) self.indicators[symbol]["ema15"].Update(bar.EndTime, bar.Close) self.indicators[symbol]["ema65"].Update(bar.EndTime, bar.Close) self.indicators[symbol]["ema200"].Update(bar.EndTime, bar.Close) self.indicators[symbol]["ema35"].Update(bar.EndTime, bar.Close) self.indicators[symbol]["rsi"].Update(bar.EndTime, bar.Close) def OnData(self, data): if self.IsWarmingUp: return for symbol in self.symbols: if data.ContainsKey(symbol): self.TradeSymbol(symbol) def TradeSymbol(self, symbol): indicators = self.indicators[symbol] if self.IsBuyCondition(indicators): self.SetHoldings(symbol, 1) elif self.IsSellCondition(indicators): 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): ema_condition = (indicators["ema9"].Current.Value > indicators["ema15"].Current.Value > indicators["ema65"].Current.Value > indicators["ema200"].Current.Value) ema35_condition = indicators["ema35"].Current.Value > 60 return ema_condition and ema35_condition def IsSellCondition(self, indicators): ema_condition = (indicators["ema9"].Current.Value < indicators["ema15"].Current.Value < indicators["ema65"].Current.Value < indicators["ema200"].Current.Value) ema35_condition = indicators["ema35"].Current.Value < 40 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