Overall Statistics
Total Orders
10001
Average Win
0.64%
Average Loss
-0.99%
Compounding Annual Return
89.180%
Drawdown
29.000%
Expectancy
0.508
Start Equity
100000
End Equity
499579.20
Net Profit
399.579%
Sharpe Ratio
1.758
Sortino Ratio
1.874
Probabilistic Sharpe Ratio
77.265%
Loss Rate
9%
Win Rate
91%
Profit-Loss Ratio
0.65
Alpha
0.576
Beta
1.036
Annual Standard Deviation
0.362
Annual Variance
0.131
Information Ratio
1.937
Tracking Error
0.299
Treynor Ratio
0.615
Total Fees
$1127.21
Estimated Strategy Capacity
$45000000.00
Lowest Capacity Asset
NFLX SEWJWLJNHZDX
Portfolio Turnover
6.47%
from AlgorithmImports import *

class EMAMovingAverageStrategy(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2018, 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