Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
3.379
Tracking Error
0.28
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
    #region imports
from AlgorithmImports import *
#endregion
from QuantConnect.Data.Consolidators import CalendarInfo

class UncoupledMultidimensionalAutosequencers(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 3)  # Set End 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.Minute).Symbol
            # Create symbol data for respective symbol
            self.symbolData[symbol] = SymbolData(self, symbol)

class SymbolData:
    
    def __init__(self, algorithm, symbol):
        self.algorithm = algorithm
        self.symbol = symbol
        # Define our consolidator for 30 min bars
        hourlyConsolidator = TradeBarConsolidator(self.Custom)
        hourlyConsolidator.DataConsolidated += self.OnDataConsolidated
        algorithm.SubscriptionManager.AddConsolidator(symbol, hourlyConsolidator)
        
        # Define our indicator
        self.sma = SimpleMovingAverage(14)
        # Register indicator to our consolidator
        algorithm.RegisterIndicator(symbol, self.sma, hourlyConsolidator)
        # Rolling window to hold 30 min bars
        self.barWindow = RollingWindow[TradeBar](2)
    
    # Store every thirty minute bar in rolling window
    def OnDataConsolidated(self, sender, bar):
        self.barWindow.Add(bar)
        self.algorithm.Debug("Handler@" + str(bar.Time)[11:] + " SMA:" + str(self.sma) )

        if self.IsReady:
            lastBar = self.barWindow[1] 
            currentBar = self.barWindow[0]
            sma = self.sma.Current.Value
            # Buy if there is a long cross over
            if lastBar.Close < sma and currentBar.Close > sma:
                self.algorithm.SetHoldings(self.symbol, 0.5)
            elif lastBar.Close > sma and currentBar.Close < sma:
                self.algorithm.SetHoldings(self.symbol, -0.5)
                
    @property
    def IsReady(self):
        return self.sma.IsReady and self.barWindow.IsReady
        
    def Custom(self, dt):
        # self.algorithm.Debug("dt:" + str(dt)[11:])
        period = timedelta(hours=1)
        start = dt.replace(minute=30)
        if start > dt:
            start -= period
        return CalendarInfo(start, period)