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