Overall Statistics
Total Trades
12
Average Win
0%
Average Loss
0%
Compounding Annual Return
37.113%
Drawdown
4.400%
Expectancy
0
Net Profit
43.048%
Sharpe Ratio
2.598
Probabilistic Sharpe Ratio
96.665%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.271
Beta
-0.025
Annual Standard Deviation
0.102
Annual Variance
0.01
Information Ratio
0.18
Tracking Error
0.153
Treynor Ratio
-10.603
Total Fees
$12.00
class UncoupledMultidimensionalAutosequencers(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        
        tickers = ["SPY", "TLT"]
        
        # Dictionary to hold Symbol Data
        self.symbolData = {}
        
        for ticker in tickers:
            # Add equity data
            symbol = self.AddEquity(ticker, Resolution.Daily).Symbol
            # Create symbol data for respective symbol
            self.symbolData[symbol] = SymbolData(self, symbol)
        
        
        
    def OnData(self, data):
        
        if not all([symbol.IsReady for symbol in self.symbolData.values()]):
            return
        
        for symbol, value in self.symbolData.items():
            rsi_2DaysPrior = value.rsiWindow[2].Value
            rsi_yesterday = value.rsiWindow[1].Value
            rsi_today = value.rsiWindow[0].Value
            # If rsi 2 candles ago is less than 30 and most recent rsi has increased by at least 5
            if rsi_2DaysPrior < 30 and rsi_today > rsi_yesterday + 5:
                self.MarketOrder(symbol, 100)
        
    
    

class SymbolData:
    
    def __init__(self, algorithm, symbol):
        self.algorithm = algorithm
        self.symbol = symbol
        # Define our indicator
        self.rsi = algorithm.RSI(symbol, 14, Resolution.Daily)
        # Define our rolling window to hold indicator points
        self.rsiWindow = RollingWindow[IndicatorDataPoint](3)
        # Set our event handler
        self.rsi.Updated += self.OnRSIUpdated
        
    def OnRSIUpdated(self, sender, updated):
        # Add updated indicator data to rolling window
        if self.rsi.IsReady:
            self.rsiWindow.Add(updated)
        
        
    @property
    def IsReady(self):
        return self.rsi.IsReady and self.rsiWindow.IsReady