I recently made a post regarding a bug in the futures data available here on QC and am running into another issue with a different futures contract where the backtests have extreme gaps down on discrepancies in price. This is extremely disconcerting to me as I've spent a considerable amount of my time learning to use the QC platform and am trading futures to support myself currently. Is anyone else here using futures data? I do not see other users complaining about these problems but the community seems to be relatively inactive as far as futures traders. The backtest I'm currently referring too is on the GC contract time period 2010-2011 jan for both years. Ive run into the same problem now using the ZN Y10 treasury bond contract, as well as the NG contract. Can anyone from QC explain this to me ? I am going to attach my code so you can see what I mean, the loss doesn't even reflect in the order logs, just in the equity and the algorithm stopping from inability to meet margin. Please forgive me if you see some error unknown to me in my code, however I think that is doubtful seeing as I've ran into this issue using different algorithm on different instruments. Best Regards, Ageanfutures
from AlgorithmImports import*
import pandas as pd
class FuturesSMAAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 1)
self.SetEndDate(2011, 1, 1)
self.SetCash(100000)
futureES = self.AddFuture(Futures.Metals.Gold)
futureES.SetFilter(TimeSpan.FromDays(30), TimeSpan.FromDays(720))
self.new_day = True
self.contract = None
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 30), self.SpecificTime)
self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x)))
def OnData(self, slice):
self.InitUpdateContract(slice)
def InitUpdateContract(self, slice):
if not self.new_day:
return
if self.contract != None and (self.contract.Expiry - self.Time).days >= 3: # rolling 3 days before expiry
return
for chain in slice.FutureChains.Values:
if self.contract != None:
self.Log('Expiry days away {} - {}'.format((self.contract.Expiry-self.Time).days, self.contract.Expiry))
self.Log('Reset: closing all positions')
self.Liquidate()
contracts = list(chain.Contracts.Values)
chain_contracts = list(contracts)
chain_contracts = sorted(chain_contracts, key=lambda x: x.Expiry)
self.contract = chain_contracts[0]
self.Log("Setting contract to: {}".format(self.contract.Symbol.Value))
one_day = TradeBarConsolidator(TimeSpan.FromDays(1))
self.SubscriptionManager.AddConsolidator(self.contract.Symbol, one_day)
self.sma = self.SMA(self.contract.Symbol, 80, Resolution.Daily)
history = self.History(self.contract.Symbol, 80, Resolution.Daily).reset_index(drop=False)
for bar in history.itertuples():
if len(history) < 80:
raise Exception(f'Empty history at {self.Time}')
if bar.time.minute == 0 and ((self.Time-bar.time)/pd.Timedelta(minutes=1)) >=2:
self.sma.Update(bar.time, bar.close)
if (self.sma != None and self.sma.IsReady):
holdings = self.Portfolio[self.contract.Symbol].Quantity
price = self.Securities[self.contract.Symbol].Price
if not self.Portfolio.Invested:
if price < self.sma.Current.Value:
self.MarketOrder(self.contract.Symbol, -1)
if price > self.sma.Current.Value:
self.MarketOrder(self.contract.Symbol, 1)
if holdings < 0 and price > self.sma.Current.Value:
self.Liquidate()
self.MarketOrder(self.contract.Symbol, 1)
if holdings > 0 and price < self.sma.Current.Value:
self.Liquidate()
self.MarketOrder(self.contract.Symbol, -1)
else:
self.Debug("SMA not yet Ready")
self.new_day = False
def SpecificTime(self):
self.Log(f"SpecificTime: Fired at : {self.Time}")
self.new_day = True
Louis Szeto
Hi Ageanfutures
LEAN uses L1 data for filling as default, as it provides more realistic results when your order is susceptible to bid-ask slippage.
If you would like to fill with trade events only but not quotes, you may use a custom Fill Model such that the orders are filled on the last trading price. You might do so by setting the FillPrice attribute:
You may also implement the SpreadExecutionModel to submit orders when the bid-ask spread is only within a preset range by:
Best
Louis
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.
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!