Overall Statistics |
Total Orders 10001 Average Win 0.53% Average Loss -1.20% Compounding Annual Return 21.440% Drawdown 37.700% Expectancy 0.205 Start Equity 100000 End Equity 490213.55 Net Profit 390.214% Sharpe Ratio 0.732 Sortino Ratio 0.742 Probabilistic Sharpe Ratio 15.542% Loss Rate 16% Win Rate 84% Profit-Loss Ratio 0.44 Alpha 0.084 Beta 0.78 Annual Standard Deviation 0.226 Annual Variance 0.051 Information Ratio 0.308 Tracking Error 0.2 Treynor Ratio 0.212 Total Fees $3240.54 Estimated Strategy Capacity $22000000.00 Lowest Capacity Asset FB V6OIPNZEM8V9 Portfolio Turnover 5.26% |
from AlgorithmImports import * class EMAMovingAverageStrategy(QCAlgorithm): def Initialize(self): self.SetStartDate(2009, 1, 1) self.SetEndDate(2022, 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, 200, Resolution.Daily), "sma14": self.SMA(equity.Symbol, 14, Resolution.Daily), "rsi": self.RSI(equity.Symbol, 14, Resolution.Daily) } self.sma60_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.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, 1.0) elif self.IsSellCondition(indicators, sma60_track): # Pass sma60_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, 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 > 60 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 < 60 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