Hello all, I wrote an N day breakout strategy to test on some futures markets and am finding a problem with the data for the 10y treasury note (ZN). In the backtest the price gaps from around 126 to 26 which never happened or any move close to it I might add. Now I thought initially the algo might assume that I was forced delivery on the underlying bonds but looking through the order log I can see that the data shows the the price is wrong. I am attaching my code and apologize if this discrepancy is coming in some way from my own implementation as I am a self taught in python. Thanks for all the help from everyone in the community, Best Regards
from AlgorithmImports import *
class BasicTemplateFuturesAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 1)
self.SetEndDate(2012, 1, 1)
self.SetCash(1000000)
self.contractSymbol = None
# Subscribe and set our expiry filter for the futures chain
futureSP500 = self.AddFuture(Futures.Financials.Y10TreasuryNote, Resolution.Minute)
# set our expiry filter for this futures chain
# SetFilter method accepts timedelta objects or integer for days.
# The following statements yield the same filtering criteria
futureSP500.SetFilter(timedelta(30), timedelta(182))
seeder = FuncSecuritySeeder(self.GetLastKnownPrices)
self.SetSecurityInitializer(lambda security: seeder.SeedSecurity(security))
self.new_day = True
self.Schedule.On(self.DateRules.EveryDay(),
self.TimeRules.At(9, 30),
self.EveryDay)
def EveryDay(self):
self.new_day = True
def OnData(self,slice):
if self.new_day is True:
for chain in slice.FutureChains:
# Get contracts expiring no earlier than in 90 days
contracts = list(filter(lambda x: x.Expiry > self.Time + timedelta(90), chain.Value))
# if there is any contract, trade the front contract
if len(contracts) == 0: continue
front = sorted(contracts, key = lambda x: x.Volume, reverse=True)[0]
if self.contractSymbol is not None:
holdings = self.Portfolio[self.contractSymbol].Quantity
if self.contractSymbol != front.Symbol:
if holdings > 0:
self.Liquidate()
self.MarketOrder(front.Symbol, 1)
if holdings < 0:
self.Liquidate()
self.MarketOrder(front.Symbol, -1)
self.contractSymbol = front.Symbol
self.max = self.MAX(self.contractSymbol, 80, Resolution.Daily)
self.min = self.MIN(self.contractSymbol, 80, Resolution.Daily)
history = self.History(self.contractSymbol, 80, Resolution.Daily).reset_index(drop=False)
for bar in history.itertuples():
if bar.time.minute == 0 and ((self.Time-bar.time)/pd.Timedelta(minutes=1)) >= 2:
self.max.Update(bar.time, bar.high)
self.min.Update(bar.time, bar.low)
self.new_day = False
price = self.Securities[self.contractSymbol].Close
if self.max.IsReady:
if not self.Portfolio.Invested:
if price > self.max.Current.Value:
self.MarketOrder(self.contractSymbol, 1)
if price < self.min.Current.Value:
self.MarketOrder(self.contractSymbol, -1)
if self.Portfolio[self.contractSymbol].IsLong:
if price < self.min.Current.Value:
self.Liquidate()
self.MarketOrder(self.contractSymbol, -1)
if self.Portfolio[self.contractSymbol].IsShort:
if price > self.max.Current.Value:
self.Liquidate()
self.MarketOrder(self.contractSymbol, 1)
def OnEndOfAlgorithm(self):
# Get the margin requirements
buyingPowerModel = self.Securities[self.contractSymbol].BuyingPowerModel
name = type(buyingPowerModel).__name__
if name != 'FutureMarginModel':
raise Exception(f"Invalid buying power model. Found: {name}. Expected: FutureMarginModel")
initialOvernight = buyingPowerModel.InitialOvernightMarginRequirement
maintenanceOvernight = buyingPowerModel.MaintenanceOvernightMarginRequirement
initialIntraday = buyingPowerModel.InitialIntradayMarginRequirement
maintenanceIntraday = buyingPowerModel.MaintenanceIntradayMarginRequirement
def OnSecuritiesChanged(self, changes):
for addedSecurity in changes.AddedSecurities:
if addedSecurity.Symbol.SecurityType == SecurityType.Future and not addedSecurity.Symbol.IsCanonical() and not addedSecurity.HasData:
raise Exception(f"Future contracts did not work up as expected: {addedSecurity.Symbol}")
Varad Kabade
Hi AegeanFutures,
Please create a minimum example highlighting the problem and create a data issue.
We've created a portal for the submission and management of Data issues. This way, the community can transparently identify any issues and have visibility when they are fixed.
Can you please post your ticket here?
See a quick video demonstration of how to use this tool.
Best,
Varad Kabade
AegeanFutures
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!