| Overall Statistics |
|
Total Orders 10001 Average Win 1.17% Average Loss -0.86% Compounding Annual Return 78.690% Drawdown 33.900% Expectancy 1.176 Start Equity 100000 End Equity 568750.24 Net Profit 468.750% Sharpe Ratio 1.583 Sortino Ratio 1.611 Probabilistic Sharpe Ratio 71.913% Loss Rate 8% Win Rate 92% Profit-Loss Ratio 1.36 Alpha 0.477 Beta 1.059 Annual Standard Deviation 0.364 Annual Variance 0.133 Information Ratio 1.587 Tracking Error 0.304 Treynor Ratio 0.545 Total Fees $1433.01 Estimated Strategy Capacity $43000000.00 Lowest Capacity Asset GOOG T1AZ164W5VTX Portfolio Turnover 4.36% |
from AlgorithmImports import *
class EMAMovingAverageStrategy(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 1, 1)
self.SetEndDate(2023, 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.rsi_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),
"rsi": self.RSI(equity.Symbol, 14, Resolution.Daily)
}
self.rsi_tracks[symbol] = RollingWindow[IndicatorDataPoint](1) # Track RSI over 1 days
#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.rsi_tracks[symbol].Add(self.indicators[symbol]["rsi"].Current)
for symbol in self.symbols:
if self.rsi_tracks[symbol].IsReady:
self.TradeSymbol(symbol)
def TradeSymbol(self, symbol):
indicators = self.indicators[symbol]
rsi_track = self.rsi_tracks[symbol] # Corrected attribute name
if self.IsBuyCondition(indicators, rsi_track): # Pass rsi_track to IsBuyCondition
self.SetHoldings(symbol, 1.0)
elif self.IsSellCondition(indicators, rsi_track): # Pass rsi_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, rsi_track): # Added rsi_track parameter
ema_condition = (indicators["ema9"].Current.Value > indicators["ema15"].Current.Value > indicators["ema65"].Current.Value > indicators["ema200"].Current.Value)
rsi_condition = all(x.Value > 60 for x in rsi_track)
return ema_condition and rsi_condition
def IsSellCondition(self, indicators, rsi_track): # Added rsi_track parameter
ema_condition = (indicators["ema9"].Current.Value < indicators["ema15"].Current.Value < indicators["ema65"].Current.Value < indicators["ema200"].Current.Value)
rsi_condition = all(x.Value < 50 for x in rsi_track)
return ema_condition and rsi_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