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