Hi,

I added RollingWindow to a Moving Average strategy for futures. There are few examples of futures. I tried my best to write this strategy, but it still does not work. Can anyone point out what is wrong with my Algo? Thanks.

 

 

import clr
import decimal as d
import pandas as pd


class FuturesMovingAverage (QCAlgorithm):

def Initialize(self):

self.contract = None

self.SetStartDate(2019, 1, 1)
self.SetEndDate(2020, 1, 1)
self.SetCash(100000)
self.SetWarmUp(TimeSpan.FromDays(5))
self.SetTimeZone("America/New_York")

self.new_day = True
self.reset = True




CL = self.AddFuture(Futures.Energies.CrudeOilWTI)
CL.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(360))

self.consolidators = {}
self.movingAverages = {}


self.sma = None
self.sma_period = 60

self.window = RollingWindow[TradeBar](3)

def OnData(self, slice, data):

if not self.InitUpdateContract(slice):
return


if self.reset:
self.reset = False

self.window.Add(data["CL"])


def InitUpdateContract(self, slice):


if not self.new_day:
return True

if self.contract != None and (self.contract.Expiry - self.Time).days >= 3:
return True

for chain in slice.FutureChains.Values:

idx = 0
if self.contract != None:
self.Log('Expiry days away {} - {}'.format((self.contract.Expiry-self.Time).days, self.contract.Expiry))
if self.contract != None and (self.contract.Expiry - self.Time).days < 3:
idx = 1

contracts = list(chain.Contracts.Values)

chain_contracts = list(contracts)
chain_contracts = sorted(chain_contracts, key=lambda x: x.Expiry)

if len(chain_contracts) < 2:
return False

first = chain_contracts[idx]
second = chain_contracts[idx+1]

if (first.Expiry - self.Time).days >= 3:
self.contract = first
elif (first.Expiry - self.Time).days < 3 and (second.Expiry - self.Time).days >= 3:
self.contract = second
self.Log("Setting contract to: {}".format(self.contract.Symbol.Value))

self.new_day = False
self.reset = True

if self.contract.Symbol not in self.consolidators:
self.consolidators[self.contract.Symbol] = self.Consolidate(
self.contract.Symbol, timedelta(minutes=5), self.OnFiveMinutes)
if self.contract.Symbol not in self.movingAverages:
self.movingAverages[self.contract.Symbol] = self.SMA(self.contract.Symbol, self.sma_period, Resolution.Minute)
history = self.History(self.contract.Symbol, self.sma_period, Resolution.Minute).close.unstack(1)
for index, close in history[self.contract.Symbol].items():
time = index[1]
self.movingAverages[self.contract.Symbol].Update(time, close)



return True
return False

def OnFiveMinutes(self, bar):

if not self.window.IsReady:
return

currentBar = self.window[0]
nearBar = self.window[1]
farBar = self.window[2]


if bar.Symbol != self.contract.Symbol:
return

sma = self.movingAverages.get(bar.Symbol, None)
if sma is None or not sma.IsReady:
return

near = nearBar.Close
far = farBar.Close

sma = sma.Current.Value
price = bar.Close

holdings = self.Portfolio[bar.Symbol].Quantity

if not self.Portfolio.Invested:
if far < sma and near > sma and price > near:
self.MarketOrder(bar.Symbol, 1)
if far > sma and near < sma and price < near:
self.MarketOrder(bar.Symbol, -1)

if holdings > 0 and price < sma:
self.Liquidate(bar.Symbol)

if holdings < 0 and price > sma:
self.Liquidate(bar.Symbol)




def OnEndOfDay(self):
self.new_day = True