Front-Month Gold Futures Trading with an EMA Crossover
Summary
This example shows a long-only trend-following method for the current front-month gold futures contract. It compares a fast and a slow exponential moving average, entering when the fast average exceeds the slow average by a small tolerance and the contract is not already held. The example sets holdings to a fraction of portfolio value and exits when the entry condition no longer holds.
The contract universe is filtered to the front month and updated daily. When the selected contract changes, the algorithm removes the old consolidator, resets both averages, registers them on the new contract, and warms them with minute data. It also plots the two averages for monitoring. The document provides implementation detail rather than performance evidence: its configured run spans only a short date range, and no results are reported. It does not specify a separate protective stop or address how signals behave during contract rolls beyond relying on expiration liquidation.
Key ideas
- The strategy enters long when the fast EMA exceeds the slow EMA by a tolerance.
- It restricts its futures universe to the front-month gold contract.
- The EMA indicators are reset and warmed when the selected contract changes.
- The example supplies implementation details but no evidence of trading performance.
Tags
Full text
# EmaCrossFuturesFrontMonthAlgorithm
# EmaCrossFuturesFrontMonthAlgorithm
This example demonstrates how to implement a cross moving average for the futures front contract
## Source (Apache-2.0)
```python
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from AlgorithmImports import *
### <summary>
### This example demonstrates how to implement a cross moving average for the futures front contract
### </summary>
### <meta name="tag" content="using data" />
### <meta name="tag" content="indicator" />
### <meta name="tag" content="futures" />
class EmaCrossFuturesFrontMonthAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2013, 10, 8)
self.set_end_date(2013, 10, 10)
self.set_cash(1000000)
future = self.add_future(Futures.Metals.GOLD)
# Only consider the front month contract
# Update the universe once per day to improve performance
future.set_filter(lambda x: x.front_month().only_apply_filter_at_market_open())
# Symbol of the current contract
self._symbol = None
# Create two exponential moving averages
self.fast = ExponentialMovingAverage(100)
self.slow = ExponentialMovingAverage(300)
self.tolerance = 0.001
self.consolidator = None
# Add a custom chart to track the EMA cross
chart = Chart('EMA Cross')
chart.add_series(Series('Fast', SeriesType.LINE, 0))
chart.add_series(Series('Slow', SeriesType.LINE, 0))
self.add_chart(chart)
def on_data(self,slice):
holding = None if self._symbol is None else self.portfolio.get(self._symbol)
if holding is not None:
# 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.set_holdings(self._symbol, .1)
self.plot_ema()
elif holding.invested:
self.liquidate(self._symbol)
self.plot_ema()
def on_securities_changed(self, changes):
if len(changes.removed_securities) > 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.subscription_manager.remove_consolidator(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.added_securities[0].symbol
# Create a new consolidator and register the indicators to it
self.consolidator = self.resolve_consolidator(self._symbol, Resolution.MINUTE)
self.register_indicator(self._symbol, self.fast, self.consolidator)
self.register_indicator(self._symbol, self.slow, self.consolidator)
# Warm up the indicators
self.warm_up_indicator(self._symbol, self.fast, Resolution.MINUTE)
self.warm_up_indicator(self._symbol, self.slow, Resolution.MINUTE)
self.plot_ema()
def plot_ema(self):
self.plot('EMA Cross', 'Fast', self.fast.current.value)
self.plot('EMA Cross', 'Slow', self.slow.current.value)
```Shown in full with attribution under the source's licence. Licence: Apache-2.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.