Overall Statistics
# Ray Dalio's portfolio idea with futures.

class FuturePortfolio(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2016,10,1)  #Set Start Date - earliest can be (2009,6,1)
        #self.SetEndDate(2011,11,1)    #Set End Date
        self.SetCash(1000000)           #Set Strategy Cash
        self.spy = self.AddEquity("SPY", Resolution.Minute).Symbol
        self.qqq = self.AddEquity("QQQ", Resolution.Minute).Symbol
        self.futureNQ  = self.AddFuture(Futures.Indices.NASDAQ100EMini) 
        self.futureNQ .SetFilter(30, 120)    # Get contracts from 30 days to 120 days out
        #self.futureES  = self.AddFuture(Futures.Indices.SP500EMini) 
        #self.futureES .SetFilter(30, 120)    # Get contracts from 30 days to 120 days out
        #self.futureVX  = self.AddFuture(Futures.Indices.VIX) 
        #self.futureVX .SetFilter(30, 120)
        self.futureZB  = self.AddFuture(Futures.Financials.Y30TreasuryBond) 
        self.futureZB .SetFilter(30, 200)
        self.futureZN  = self.AddFuture(Futures.Financials.Y10TreasuryNote) 
        self.futureZN .SetFilter(30, 120)
        self.futureZT  = self.AddFuture(Futures.Financials.Y2TreasuryNote) 
        self.futureZT .SetFilter(30, 120)
        #self.Settings.FreePortfolioValuePercentage = 0.05
        self.SetBenchmark("QQQ")
        self.rebalance = True                            # Flag to initate trades
        self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), self.Rebalance)
        self.contract = None

    def OnData(self, data):
        if not (data.ContainsKey(self.spy) and data[self.spy] is not None and \
                self.rebalance):
            return

        self.Liquidate()    # close out of all contracts, this way we avoid having to roll as expiration nears.
        for contracts in data.FutureChains.Values:
            sorted_contracts = sorted(contracts, key=lambda c: c.Expiry, reverse = True)
            if len(sorted_contracts) == 0 or \
               (self.contract is not None and sorted_contracts[0].Symbol == self.contract.Symbol):
                continue
            self.contract = sorted_contracts[0]
            if self.contract.Symbol.ID.Symbol == Futures.Indices.NASDAQ100EMini:
                self.SetHoldings(sorted_contracts[0].Symbol, 0.2)
            if self.contract.Symbol.ID.Symbol == Futures.Financials.Y30TreasuryBond:
                self.SetHoldings(sorted_contracts[0].Symbol, 0.12)
            if self.contract.Symbol.ID.Symbol == Futures.Financials.Y10TreasuryNote:
                self.SetHoldings(sorted_contracts[0].Symbol, 0.12)
            if self.contract.Symbol.ID.Symbol == Futures.Financials.Y2TreasuryNote:
                self.SetHoldings(sorted_contracts[0].Symbol, 0.1)
            #else:
                #self.SetHoldings(sorted_contracts[0].Symbol, 0.0)
            
        self.rebalance = False     # Reset rebalance timer
        
    def Rebalance(self):
        self.rebalance = True