Selecting Futures Contracts and Requesting Their Historical Data
Summary
This Lean example demonstrates subscribing to futures roots, limiting eligible contracts by expiration, inspecting the resulting futures chain, and requesting historical minute data. It adds E-mini S&P 500 and gold futures with expiration filters, then periodically queries recent history for subscribed securities. When securities are added, it also retrieves and logs a small sample of their latest bars.
The example illustrates data access and contract discovery rather than a trading strategy: it logs bid, ask, last price, and open interest but does not submit orders. Its scheduled history checks and end-of-run count serve as basic assertions that data is available during the example’s short configured run. The document supplies no trading performance evidence and does not explain continuous-contract construction, roll handling, or how to choose among contracts beyond filtering expirations and examining chain fields.
Key ideas
- A futures subscription can be filtered by the contracts’ expiration dates.
- The futures chain exposes contract-level fields such as bid, ask, last price, and open interest.
- Historical data requests can be made for subscribed securities and for newly added contracts.
- Scheduled checks in the example assert that recent minute history is returned.
- The code demonstrates data retrieval and inspection, not signal generation or order execution.
Tags
Full text
# BasicTemplateFuturesHistoryAlgorithm
# BasicTemplateFuturesHistoryAlgorithm
This example demonstrates how to get access to futures history for a given root symbol. It also shows how you can prefilter contracts easily based on expirations, and inspect the futures chain to pick a specific contract to trade.
## 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 get access to futures history for a given root symbol.
### It also shows how you can prefilter contracts easily based on expirations, and inspect the futures
### chain to pick a specific contract to trade.
### </summary>
### <meta name="tag" content="using data" />
### <meta name="tag" content="history and warm up" />
### <meta name="tag" content="history" />
### <meta name="tag" content="futures" />
class BasicTemplateFuturesHistoryAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2013, 10, 8)
self.set_end_date(2013, 10, 9)
self.set_cash(1000000)
extended_market_hours = self.get_extended_market_hours()
# Subscribe and set our expiry filter for the futures chain
# find the front contract expiring no earlier than in 90 days
future_es = self.add_future(Futures.Indices.SP_500_E_MINI, Resolution.MINUTE, extended_market_hours=extended_market_hours)
future_es.set_filter(timedelta(0), timedelta(182))
future_gc = self.add_future(Futures.Metals.GOLD, Resolution.MINUTE, extended_market_hours=extended_market_hours)
future_gc.set_filter(timedelta(0), timedelta(182))
self.set_benchmark(lambda x: 1000000)
self.schedule.on(self.date_rules.every_day(), self.time_rules.every(timedelta(hours=1)), self.make_history_call)
self._success_count = 0
def make_history_call(self):
history = self.history(self.securities.keys(), 10, Resolution.MINUTE)
if len(history) < 10:
raise AssertionError(f'Empty history at {self.time}')
self._success_count += 1
def on_end_of_algorithm(self):
if self._success_count < self.get_expected_history_call_count():
raise AssertionError(f'Scheduled Event did not assert history call as many times as expected: {self._success_count}/49')
def on_data(self,slice):
if self.portfolio.invested: return
for chain in slice.future_chains:
for contract in chain.value:
self.log(f'{contract.symbol.value},' +
f'Bid={contract.bid_price} ' +
f'Ask={contract.ask_price} ' +
f'Last={contract.last_price} ' +
f'OI={contract.open_interest}')
def on_securities_changed(self, changes):
for change in changes.added_securities:
history = self.history(change.symbol, 10, Resolution.MINUTE).sort_index(level='time', ascending=False)[:3]
for index, row in history.iterrows():
self.log(f'History: {index[1]} : {index[2]:%m/%d/%Y %I:%M:%S %p} > {row.close}')
def on_order_event(self, order_event):
# Order fill event handler. On an order fill update the resulting information is passed to this method.
# Order event details containing details of the events
self.log(f'{order_event}')
def get_extended_market_hours(self):
return False
def get_expected_history_call_count(self):
return 42
```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.