Overall Statistics
Total Trades
10
Average Win
4.72%
Average Loss
-1.38%
Compounding Annual Return
14.719%
Drawdown
11.500%
Expectancy
1.211
Net Profit
14.662%
Sharpe Ratio
0.692
Probabilistic Sharpe Ratio
33.730%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
3.42
Alpha
0.094
Beta
-0.184
Annual Standard Deviation
0.166
Annual Variance
0.028
Information Ratio
0.787
Tracking Error
0.288
Treynor Ratio
-0.622
Total Fees
$10.00
Estimated Strategy Capacity
$170000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
4.48%
from AlgorithmImports import *

class EmaCrossoverAlgo(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2022, 1, 1) # start date 01.01.2022
        self.SetEndDate(2022, 12, 31) # end date 31.12.2022
        self.SetCash(10_000) # trading capital 10.000 $
        self.stopLoss = -300 # stop loss at 3% of trading capital
        self.Ticker = "SPY" # SPDR S&P 500 ETF Trust
        self.Symbol = self.AddEquity(self.Ticker, Resolution.Hour).Symbol
        self.EMA_Fast = self.EMA(self.Symbol,50,Resolution.Hour) # EMA Indicator (fast)
        self.EMA_Slow = self.EMA(self.Symbol,100,Resolution.Hour) # EMA Indicator (slow)
        self.Tolerance = 0.0015 # cross-over tolerance 0,15 %
        # get buy&hold param
        self.BuyAndHoldParam = False
        self.BuyAndHoldParam = self.GetParameter("Buy_and_Hold", "False") == "True"

    def OnData(self, data):
        # return if indicators aren't ready    
        if not self.EMA_Slow.IsReady or not self.EMA_Fast: 
            return

        if self.BuyAndHoldParam:
            # buy and hold mode
            if not self.Portfolio.Invested: # one-time buy if not invested
                self.SetHoldings(self.Symbol, 1)
            return
        else:
            # make trades
            holdings = self.Portfolio[self.Symbol].Quantity        
            if holdings <= 0:
                # go long (buy) if fast EMA-Indicator crosses above slow one 
                if self.EMA_Fast.Current.Value > self.EMA_Slow.Current.Value * ( 1 + self.Tolerance):
                    self.Debug(f"BUY  >> {self.Securities[self.Symbol].Price}")
                    self.SetHoldings(self.Symbol, 1)
            else:            
                # go short (sell) if fast EMA-Indicator crosses below slow one 
                if self.EMA_Fast < self.EMA_Slow:
                    self.Debug(f"SELL  >> {self.Securities[self.Symbol].Price}")
                    self.SetHoldings(self.Symbol, -1)
            
            # Risk management:
            #   liquidate open position if unrealized profit is greater then Stop-Loss value
            if self.Portfolio[self.Symbol].UnrealizedProfit <= self.stopLoss:
                self.Debug(f"Stop loss at {self.Securities[self.Symbol].Price}")
                self.Liquidate()