class EmaCrossFuturesFrontMonthAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 1, 1)
self.SetEndDate(2020, 12, 30)
self.SetCash(1000000)
future = self.AddFuture(Futures.Energies.CrudeOilWTI)
# Only consider the front month contract
# Update the universe once per day to improve performance
future.SetFilter(lambda x: x.FrontMonth().OnlyApplyFilterAtMarketOpen())
# Symbol of the current contract
self.symbol = None
# Create two exponential moving averages
self.fast = ExponentialMovingAverage(9)
self.slow = ExponentialMovingAverage(21)
self.tolerance = 0.01
self.consolidator = None
# Add a custom chart to track the EMA cross
chart = Chart('EMA Cross')
chart.AddSeries(Series('Fast', SeriesType.Line, 0))
chart.AddSeries(Series('Slow', SeriesType.Line, 0))
self.AddChart(chart)
def OnData(self,slice):
holding = None if self.symbol is None else self.Portfolio.get(self.symbol)
position = self.Portfolio[self.symbol].Quantity
if holding is None:
return
if self.slow.IsReady:
# Buy the futures' front contract when the fast EMA is above the slow one
if self.fast.Current.Value > self.slow.Current.Value * (1 + self.tolerance):
if not holding.Invested:
self.MarketOrder(self.symbol, 1)
self.PlotEma()
elif holding.Invested and position < 0:
self.MarketOrder(self.symbol, 2)
self.PlotEma()
if self.fast.Current.Value < self.slow.Current.Value * (1 + self.tolerance):
if not holding.Invested:
self.MarketOrder(self.symbol, -1)
self.PlotEma()
elif holding.Invested and position > 0:
self.MarketOrder(self.symbol, -2)
self.PlotEma()
def OnSecuritiesChanged(self, changes):
if len(changes.RemovedSecurities) > 0:
# Remove the consolidator for the previous contract
# and reset the indicators
if self.symbol is not None and self.consolidator is not None:
self.SubscriptionManager.RemoveConsolidator(self.symbol, self.consolidator)
self.fast.Reset()
self.slow.Reset()
# We don't need to call Liquidate(_symbol),
# since its positions are liquidated because the contract has expired.
# Only one security will be added: the new front contract
self.symbol = changes.AddedSecurities[0].Symbol
# Create a new consolidator and register the indicators to it
self.consolidator = self.ResolveConsolidator(self.symbol, Resolution.Daily)
self.RegisterIndicator(self.symbol, self.fast, self.consolidator)
self.RegisterIndicator(self.symbol, self.slow, self.consolidator)
# Warm up the indicators
self.WarmUpIndicator(self.symbol, self.fast, Resolution.Daily)
self.WarmUpIndicator(self.symbol, self.slow, Resolution.Daily)
self.PlotEma()
def PlotEma(self):
self.Plot('EMA Cross', 'Fast', self.fast.Current.Value)
self.Plot('EMA Cross', 'Slow', self.slow.Current.Value)
Hello, I am working on an ema cross for futures markets. I am interested in running a program on multiple futures markets long/short and am currently working out the code for one underlying at a time. The system looks like its executing properly, as a contract is delisted it liquidates and reenters if the trend is still in tackt. My problem is that every backtest is giving me different results with the same code, no parameter changes. Can you help me with this?
Fred Painchaud
Hi Aegean,
It looks like you want to perform parameters optimization. In QC, this is different than plain backtesting. There is an upcoming section on parameters optimization in the V2 of the docs but it is not quite ready yet. In the meantime, this example is good:
Cheers,
Fred
Mak K
Hi Aegean,
I think the issue might have to do with this error message
Runtime Error: IndexError : list index out of range
at OnSecuritiesChanged
self.symbol = changes.AddedSecurities[0].Symbol
===
at Python.Runtime.PyObject.Invoke(PyTuple args in main.py: line 68 (Open Stacktrace)
Please check out this post and see if you can implement the changes suggested, thanks!
https://www.quantconnect.com/forum/discussion/12207/issue-with-quot-index-out-of-bounds-quot/p1
Let me know if this fixed your problem, thanks!
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!