Overall Statistics
Total Orders
10001
Average Win
0.04%
Average Loss
0%
Compounding Annual Return
33.448%
Drawdown
7.000%
Expectancy
0
Start Equity
100000
End Equity
111894.43
Net Profit
11.894%
Sharpe Ratio
1.503
Sortino Ratio
1.447
Probabilistic Sharpe Ratio
64.825%
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
0.201
Beta
0.291
Annual Standard Deviation
0.141
Annual Variance
0.02
Information Ratio
1.026
Tracking Error
0.171
Treynor Ratio
0.727
Total Fees
$27.89
Estimated Strategy Capacity
$15000000.00
Lowest Capacity Asset
NKE R735QTJ8XC9X
Portfolio Turnover
1.61%
from AlgorithmImports import *

class EMAMovingAverageStrategy(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2018, 1, 1)
        self.SetEndDate(2021, 1, 1)
        self.SetCash(100000)

        self.crypto_symbol = ["BTCUSD"]


        # 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


            for symbol in self.crypto_symbol:
                cryptos = self.AddCrypto(symbol, Resolution.Hour)
                self.indicators[symbol] = {
                    "ema9": self.EMA(cryptos.Symbol, 9, Resolution.HOUR),
                    "ema15": self.EMA(cryptos.Symbol, 15, Resolution.HOUR),
                    "ema65": self.EMA(cryptos.Symbol, 65, Resolution.HOUR),
                    "ema200": self.EMA(cryptos.Symbol, 200, Resolution.HOUR),
                    "rsi": self.RSI(cryptos.Symbol, 14, Resolution.HOUR)
            }
            self.rsi_tracks[symbol] = RollingWindow[IndicatorDataPoint](1)
        
        #self.SetWarmUp(200)

    def OnData(self, data):
        if self.IsWarmingUp:
            return

        for symbol in self.symbols or self.crypto_symbol:
            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 or self.crypto_symbol:
            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