Overall Statistics
Total Orders
1021
Average Win
81.43%
Average Loss
-10.12%
Compounding Annual Return
62.294%
Drawdown
59.700%
Expectancy
2.393
Start Equity
100000.00
End Equity
696339.80
Net Profit
596.340%
Sharpe Ratio
1.175
Sortino Ratio
1.168
Probabilistic Sharpe Ratio
47.555%
Loss Rate
62%
Win Rate
38%
Profit-Loss Ratio
8.05
Alpha
0.501
Beta
0.312
Annual Standard Deviation
0.448
Annual Variance
0.2
Information Ratio
0.964
Tracking Error
0.462
Treynor Ratio
1.688
Total Fees
$0.00
Estimated Strategy Capacity
$6500000.00
Lowest Capacity Asset
BTCUSD 2XR
Portfolio Turnover
2.24%
from AlgorithmImports import *

class TechnicalIndicatorsAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2020, 1, 1)  # Set Start Date
        self.SetEndDate(2024, 1, 1)    # Set End Date
        self.SetCash(100000)           # Set Strategy Cash
        
        # Add the cryptocurrency pairs
        self.symbols = [
            self.AddCrypto("BTCUSD", Resolution.DAILY).Symbol,
            self.AddCrypto("ETHUSD", Resolution.DAILY).Symbol,
            self.AddCrypto("LTCUSD", Resolution.DAILY).Symbol,
            self.AddCrypto("XRPUSD", Resolution.DAILY).Symbol
        ]
        
        self.indicators = {}
        
        for symbol in self.symbols:
            self.indicators[symbol] = {
                "hammer": self.CandlestickPatterns.Hammer(symbol),
                "hanging_man": self.CandlestickPatterns.HangingMan(symbol),
                "doji": self.CandlestickPatterns.Doji(symbol),
                "spinning_top": self.CandlestickPatterns.SpinningTop(symbol),
                "engulfing": self.CandlestickPatterns.Engulfing(symbol),
                "rsi": self.RSI(symbol, 14, MovingAverageType.Wilders, Resolution.DAILY),
                "sma10": self.SMA(symbol, 10, Resolution.DAILY),
                "sma05": self.SMA(symbol, 5, Resolution.DAILY),
                "ema20": self.EMA(symbol, 20, Resolution.DAILY),
                "sma30": self.SMA(symbol, 30, Resolution.DAILY),
                "sma50": self.SMA(symbol, 50, Resolution.DAILY),
                "sma200": self.SMA(symbol, 200, Resolution.DAILY),
                "sma600": self.SMA(symbol, 600, Resolution.DAILY),
                "sma40": self.SMA(symbol, 40, Resolution.DAILY),
                "sma120": self.SMA(symbol, 120, Resolution.DAILY),
                "ema05": self.EMA(symbol, 5, Resolution.DAILY),
                "ema10": self.EMA(symbol, 10, Resolution.DAILY),
                "ema30": self.EMA(symbol, 30, Resolution.DAILY),
                "ema65": self.EMA(symbol, 65, Resolution.DAILY),
                "ema100": self.EMA(symbol, 100, Resolution.DAILY),
                "ema150": self.EMA(symbol, 150, Resolution.DAILY),
                "ema500": self.EMA(symbol, 500, Resolution.DAILY),
                "ema600": self.EMA(symbol, 600, Resolution.DAILY),
                "entry_price": None,
                "stop_price": None
            }
    
    def OnData(self, data):
        for symbol in self.symbols:
            if not data.ContainsKey(symbol):
                continue
            
            price = data[symbol].Close
            indicators = self.indicators[symbol]
            
            # Buy condition
            if (indicators["rsi"].Current.Value > 40) and (indicators["ema10"].Current.Value > indicators["ema20"].Current.Value > indicators["ema65"].Current.Value > indicators["ema150"].Current.Value):
                if not self.Portfolio[symbol].Invested:
                    self.SetHoldings(symbol, 1)
                    indicators["entry_price"] = price
                    indicators["stop_price"] = price * 0.95
            
            # Sell condition
            elif indicators["rsi"].Current.Value < 50 and ((indicators["ema10"].Current.Value < indicators["ema65"].Current.Value) or (indicators["ema20"].Current.Value < indicators["ema65"].Current.Value)):
                if self.Portfolio[symbol].Invested:
                    self.Liquidate(symbol)
                    indicators["entry_price"] = None
                    indicators["stop_price"] = None 
            
            # Stop-loss condition
            if self.Portfolio[symbol].Invested and indicators["entry_price"] is not None:
                if price < indicators["entry_price"] * 0.95:
                    self.Liquidate(symbol)
                    indicators["entry_price"] = None
                    indicators["stop_price"] = None
            #
            # Trailing stop-loss and target
            #if self.Portfolio[symbol].Invested:
            #    indicators["stop_price"] = max(indicators["stop_price"], price * 0.90)
            #    if price < indicators["stop_price"]:
            #        self.Liquidate(symbol)
            #        indicators["stop_price"] = None
            #    if price > indicators["entry_price"] * 1.15:  # Example target
             #       self.Liquidate(symbol)
            #        indicators["entry_price"] = None
            #        indicators["stop_price"] = None