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
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
class RollContract(QCAlgorithm):

    def Initialize(self):
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        self.SetStartDate(2020, 1, 2)
        self.SetCash(1_000_000)
        self.SetTimeZone(TimeZones.Paris)
        
        # Select Future
        #self.generic_future_name = Futures.Indices.SP500EMini
        self.generic_future_name = Futures.Financials.Y10TreasuryNote
        
        self.generic_future = self.AddFuture(self.generic_future_name, Resolution.Hour, Market.CME, dataNormalizationMode = DataNormalizationMode.BackwardsRatio)
        self.order_ticket = None
        self.cur_contract = None
        
        # set our expiry filter for this futures chain
        self.generic_future.SetFilter(timedelta(0), timedelta(180))
        
    def OnOrderEvent(self, event):
        if self.order_ticket is not None:
            if event.OrderId == self.order_ticket.OrderId:
                if self.order_ticket.Status == OrderStatus.Filled:
                    self.cur_contract = self.order_ticket.Symbol
                    self.Log(f"Order filled for {self.order_ticket.Quantity} lots of {self.order_ticket.Symbol.ID}")
  

    def OnData(self, slice):
        # In case warming is required (for later use)
        if self.IsWarmingUp:
            return
        
        if slice.FuturesChains.ContainsKey(self.generic_future.Symbol):
            chain = slice.FuturesChains[self.generic_future.Symbol]
            contracts = chain.Contracts.Values
            eligible_contracts = [c for c in contracts if c.Expiry <= self.Time + timedelta(120)]
        
            # if there is any contract, trade the front contract
            if len(eligible_contracts) >= 2:
                valid_contracts = sorted(eligible_contracts, key = lambda x: x.Expiry)
                first_contract, second_contract = valid_contracts[0], valid_contracts[1]
                front_contract = first_contract if first_contract.Expiry >= self.Time + timedelta(5) else second_contract
                
                if not self.Portfolio.Invested:
                    self.order_ticket = self.MarketOrder(front_contract.Symbol, 1)
                else:
                    # handle roll
                    if self.order_ticket.Symbol.ID.Date <= self.Time + timedelta(2):
                        self.Liquidate()
                        self.order_ticket = self.MarketOrder(front_contract.Symbol, 1)