Hi all! In this file I buy ES and VIX futures contracts and send a bracket order for both of them as well. I enter trades as pairs checking to see if I am in nothing before making an entrance, and there is no edge, I am just always invested. It is more about the code logic. I only go long and have a 5% bracket order. I have no reason for why I chose the numbers I did. 

I'm happy to hear any criticism and advice, hope you all find something useful. 

I made a YT video about this as well. I will add the link in a comment later on!


# region imports
from AlgorithmImports import *
# endregion

class SquareMagentaHamster(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 1)  # Set Start Date
        self.SetEndDate(2022, 1, 1) # Set End Date
        self.SetCash(500000)  # Set Strategy Cash

        self.future = self.AddFuture(Futures.Indices.SP500EMini, extendedMarketHours= True)
        self.future.SetFilter(0, 182)
        self.symbol = self.future.Symbol

        self.Vix = self.AddFuture(Futures.Indices.VIX, extendedMarketHours= True)
        self.Vix.SetFilter(0, 182)
        self.Vixsymbol = self.Vix.Symbol

        self.Longentry_ticket = None
        self.ESstopTicket = None
        self.ESprofitTicket = None
        self.LongcontractSymbol = None
        self.Esprice = None

        self.Vixentry_ticket = None
        self.VixstopTicket = None
        self.VixprofitTicket = None
        self.VixcontractSymbol = None
        self.VixPrice = None

    def OnData(self, data: Slice):

        if self.Longentry_ticket is None and self.Vixentry_ticket is None:
            self.BuyFuture(data)
            self.BuyVix(data)

        if self.Portfolio.Invested:

            if self.LongcontractSymbol == None or self.VixcontractSymbol == None:
                return

            if self.Portfolio[self.LongcontractSymbol.Symbol].IsLong:
                if self.Time + timedelta(1) > self.LongcontractSymbol.Expiry:
                    self.Liquidate(self.LongcontractSymbol.Symbol, "Future too close to expiration.")
                    self.Longentry_ticket = None
                   
            if self.Portfolio[self.VixcontractSymbol.Symbol].IsLong:
                if self.Time + timedelta(1) > self.VixcontractSymbol.Expiry:
                    self.Liquidate(self.VixcontractSymbol.Symbol, "Future too close to expiration.")
                    self.Vixentry_ticket = None

    def BuyFuture(self, data: Slice):

        chain = data.FuturesChains.get(self.symbol)
        if chain:
            
            self.LongcontractSymbol = sorted(chain, key=lambda contract: contract.Expiry, reverse=True)[0]
 
            self.Esprice = self.Securities[self.LongcontractSymbol.Symbol].Price
            self.Longentry_ticket = self.LimitOrder(self.LongcontractSymbol.Symbol, 2, self.Esprice)

            self.ESprofitTicket = self.LimitOrder(self.LongcontractSymbol.Symbol, -2, self.Esprice*1.05)
            self.ESstopTicket = self.StopMarketOrder(self.LongcontractSymbol.Symbol, -2, self.Esprice*0.95)
 
        return

    def BuyVix(self, data: Slice):


        Vixchain = data.FuturesChains.get(self.Vixsymbol)
        if Vixchain:
           
            self.VixcontractSymbol = sorted(Vixchain, key=lambda contract: contract.Expiry, reverse=True)[0]
 
            self.VixPrice = self.Securities[self.VixcontractSymbol.Symbol].Price
            self.Vixentry_ticket = self.LimitOrder(self.VixcontractSymbol.Symbol, 4, self.VixPrice)

            self.VixprofitTicket = self.LimitOrder(self.VixcontractSymbol.Symbol, -4, self.VixPrice*1.05)
            self.VixstopTicket = self.StopMarketOrder(self.VixcontractSymbol.Symbol, -4, self.VixPrice*0.95)
 
        return

    def OnOrderEvent(self, orderEvent):
 
        #self.Log(str(orderEvent))

        # Invalid order is blocking new orders
        if orderEvent.Status == OrderStatus.Invalid:
            self.Longentry_ticket = None
            self.Vixentry_ticket = None
            return

        if orderEvent.Status != OrderStatus.Filled:
            return

        if self.LongcontractSymbol is None:
            return

           
            # Otherwise, one of the exit orders was filled, so cancel the open orders
        if orderEvent.OrderId == self.ESprofitTicket.OrderId or orderEvent.OrderId == self.ESstopTicket.OrderId:
            self.Transactions.CancelOpenOrders(self.LongcontractSymbol.Symbol)
            self.Longentry_ticket = None
            return

        if self.VixcontractSymbol is None:
            return

           
            # Otherwise, one of the exit orders was filled, so cancel the open orders
        if orderEvent.OrderId == self.VixstopTicket.OrderId or orderEvent.OrderId == self.VixprofitTicket.OrderId:
            self.Transactions.CancelOpenOrders(self.VixcontractSymbol.Symbol)
            self.Vixentry_ticket = None
            return