QuantConnect
US Futures Security Master
Introduction
The US Futures Security Master dataset by QuantConnect provides mapping reference data for the most liquid contracts of the CME Group exchanges, calculated with popular rolling techniques. The data covers 157 root Future contracts, starts in May 2009, and is delivered on a daily frequency with a zip file with all the contract mappings. This dataset is created by daily processing of the US historical Future chains.
This dataset, paired with the US Futures dataset, supports the following rolling techniques: forward panama canal, backwards panama canal, and backwards ratio. You can set the specific rolling date to occur on the last trading day, first day month, or the day when the contract with the greatest open interest changes.
VIX Futures don't support continous contract rolling with open interest.
This is not the underlying Futures data (US Futures dataset), which you need to purchase separately with a license from AlgoSeek. This security master dataset is required to purchase the US Futures or US Future Options datasets.
For more information about the US Futures Security Master dataset, including CLI commands and pricing, see the dataset listing.
About the Provider
QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month.
Getting Started
You don't need any special code to utilize the US Futures Security Master. It automatically loads when you request US Futures data.
Key Concept
The US Futures Security Master lets you to construct continuous Futures, allowing the access of normalized historical data of the underlying assets, as well as trading the “lead” Future contracts for those assets.
Continuous Futures refer to sets of rolling lead Future contracts during their actively trading periods. Since Future contracts expire at their maturities, to analyze the historical price of a Future and to apply technical indicators, you need the continuous Future price series.
To access the continuous Future, use the Future's Symbolsymbol property.
# Set the data normalization mode and data mapping mode to select the contract as the continuous contract with price adjustment for smooth price series
future = self.add_future(Futures.Energy.CRUDE_OIL_WTI,
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
data_mapping_mode=DataMappingMode.OPEN_INTEREST,
contract_depth_offset=0)
self.continuous_contract_symbol = future.symbol // Set the data normalization mode and data mapping mode to select the contract as the continuous contract with price adjustment for smooth price series
var future = AddFuture(Futures.Energy.CrudeOilWTI,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
dataMappingMode: DataMappingMode.OpenInterest,
contractDepthOffset: 0
);
_continuousFutureSymbol = future.Symbol;
The dataNormalizationMode and dataMappingMode arguments makes the transition of the underlying contracts seemless. However, the Future Symbol doesn't map to an underlying Future contract. It works fine to trade within backtests, but could be subjected to friction costs during live trading since the order price could be a normalized price. For more information about this topic, see the Live Trading Considerations section.
Data Normalization Modes
The data normalization mode defines how the price series of two contracts are stitched together when the contract rollovers occur. The DataNormalizatoinMode enumeration has the following members available for continuous contracts:
If you use a data normalization mode that's not in the preceding list, LEAN automatically converts it to DataNormalizationMode.BackwardsRatio.
Data Mapping Modes
The data mapping mode defines when contract rollovers occur. The DataMappingMode enumeration has the following members:
VIX Futures don't support continous contract rolling with DataMappingMode.OpenInterestDataMappingMode.OPEN_INTEREST and DataMappingMode.OpenInterestAnnuakDataMappingMode.OPEN_INTEREST_ANNUAL.
Tracking Contract Changes
As the contracts roll over, the Mappedmapped property of the Future object references the next contract in the series and you receive a SymbolChangedEvent. To get the current Symbol change events, index the SymbolChangedEventssymbol_changed_events property of the current Slice with the continuous Futures Symbol. Slice objects deliver unique events to your algorithm as they happen, but the Slice may not contain data for your Future at every time step. To avoid issues, check if the Slice contains the data you want before you index it.
def on_data(self, slice: Slice) -> None:
# Get Symbol Change Event of the Continuous Future (change in mapped contract)
changed_event = slice.symbol_changed_events.get(self.continuous_future_symbol)
if changed_event:
old_symbol = changed_event.old_symbol
new_symbol = self.add_future_contract(changed_event.new_symbol).symbol
tag = f"Rollover - Symbol changed at {self.time}: {old_symbol} -> {new_symbol}"
quantity = self.portfolio[old_symbol].quantity
# Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
self.liquidate(old_symbol, tag = tag)
if quantity != 0: self.market_order(new_symbol, quantity, tag = tag)
self.log(tag) public override void OnData(Slice slice)
{
// Get Symbol Change Event of the Continuous Future (change in mapped contract)
if (slice.SymbolChangedEvents.TryGetValue(_continuousFutureSymbol, out var changedEvent))
{
var oldSymbol = changedEvent.OldSymbol;
var newSymbol = AddFutureContract(changedEvent.NewSymbol).Symbol;
var tag = $"Rollover - Symbol changed at {Time}: {oldSymbol} -> {newSymbol}";
var quantity = Portfolio[oldSymbol].Quantity;
// Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
Liquidate(oldSymbol, tag: tag);
if (quantity != 0) MarketOrder(newSymbol, quantity, tag: tag);
Log(tag);
}
}
SymbolChangedEvent objects have the following attributes:
Live Trading Considerations
You can trade continuous Futures, but the continuous Future Symbol doesn't map to a single underlying Future contract. Instead, it represents a set of rolling contracts. Thus, the prices could be frictional during a contract rollover, which could be catastrophic in live trading! For live trading, you should place your orders directly on the underlying contracts. To get the current underlying contract in the continuous Future series, use the Mappedmapped property.
# Get the mapped symbol current_contract = self.continuous_contract.mapped self.buy(current_contract, 1)
// Get the mapped symbol var currentContract = _continuousContract.Mapped; Buy(currentContract, 1);
Data Format
If you download the files in the US Futures Security Master, you get a factor file and a map file for each of the exchanges with supported continuous Futures. To view the files, see the \data\future\<exchange_name> directory under your LEAN CLI base directory.
For the factor file, it is a .zip collection of REST API styled .csv files for each Future Symbol, including the date, scaling factors for each type of data normalization and the data mapping mode that indicates the Symbol changing event is on that day for that mapping mode. The following line is an example line in the .csv file:
{"Date":"2009-10-31T00:00:00","BackwardsRatioScale":[0.9914163090128755364806866953,1.0,1.0],"BackwardsPanamaCanalScale":[-2.0,0.0,0.0],"ForwardPanamaCanalScale":[0.0,0.0,0.0],"DataMappingMode":1}
For the map file, it is a .zip collection of .csv files for each Future Symbol, including the date, new underlying contract Symbol, the exchange code, and the data mapping mode that indicates the Symbol changing event is on that day for that mapping mode. The following line is an example line in the .csv file:
20091130,aw uii3j0m6zbj9,CBOT,1Historical Data
You can get historical US Future Security Master data in an algorithm and the Research Environment.
Historical Data In Algorithms
To get historical US Future Security Master data in an algorithm, call the History<SymbolChangedEvent>history method with continuous Future Symbol and a lookback period. This method returns the old and new contract of each rollover. If there is no data for the period you requested, the history result is empty.
# Add the Future and define its rollover settings.
future = self.add_future(
Futures.Indices.SP_500_E_MINI,
data_mapping_mode=DataMappingMode.OPEN_INTEREST,
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
contract_depth_offset=0
)
# DataFrame example where the columns are the SymbolChangedEvent attributes:
history_df = self.history(SymbolChangedEvent, future.symbol, timedelta(365))
# SymbolChangedEvent objects example:
history = self.history[SymbolChangedEvent](future.symbol, timedelta(365)) // Add the Future and define its rollover settings.
var future = AddFuture(
Futures.Indices.SP500EMini,
dataMappingMode: DataMappingMode.OpenInterest,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
contractDepthOffset: 0
);
// Get historical data.
var history = History<SymbolChangedEvent>(future.Symbol, TimeSpan.FromDays(365));
For more information about historical US Future Security Master data in algorithms, see Symbol Changes.
Historical Data In Research
To get historical US Future Security Master data in the Research Environment, call the History<SymbolChangedEvent>history method with continuous Future Symbol and a time period. This method returns the old and new contract of each rollover. If there is no data for the period you requested, the history result is empty.
# Add the Future and define its rollover settings.
future = qb.add_future(
Futures.Indices.SP_500_E_MINI,
data_mapping_mode=DataMappingMode.OPEN_INTEREST,
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
contract_depth_offset=0
)
# DataFrame example where the columns are the SymbolChangedEvent attributes:
history_df = qb.history(SymbolChangedEvent, future.symbol, datetime(2023, 1, 1), datetime(2025, 1, 1))
# SymbolChangedEvent objects example:
history = qb.history[SymbolChangedEvent](future.symbol, datetime(2023, 1, 1), datetime(2025, 1, 1)) // Add the Future and define its rollover settings.
var future = qb.AddFuture(
Futures.Indices.SP500EMini,
dataMappingMode: DataMappingMode.OpenInterest,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
contractDepthOffset: 0
);
// Get historical data.
var history = qb.History<SymbolChangedEvent>(future.Symbol, new DateTime(2023, 1, 1), new DateTime(2025, 1, 1));
For more information about historical US Future Security Master data in the Research Environment, see Symbol Changes History.
Supported Assets
The following list shows the available (157) Futures:
Futures.Currencies.AUD: Australian Dollar Futures (CME: 6A)Futures.Currencies.AUDCAD: Australian Dollar/Canadian Dollar Futures (CME: ACD)Futures.Currencies.AUDJPY: Australian Dollar/Japanese Yen Futures (CME: AJY)Futures.Currencies.AUDNZD: Australian Dollar/New Zealand Dollar Futures (CME: ANE)Futures.Currencies.BRL: Brazillian Real Futures (CME: 6L)Futures.Currencies.BTC: Bitcoin Futures (CME: BTC)Futures.Currencies.BTICMicroBTCFutures.Currencies.BTIC_MICRO_BTC: BTIC on Micro Bitcoin Futures (CME: MIB)Futures.Currencies.BTICMicroEtherFutures.Currencies.BTIC_MICRO_ETHER: BTIC on Micro Ether Futures (CME: MRB)Futures.Currencies.CAD: Canadian Dollar Futures (CME: 6C)Futures.Currencies.CADJPY: Canadian Dollar/Japanese Yen Futures (CME: CJY)Futures.Currencies.CHF: Swiss Franc Futures (CME: 6S)Futures.Currencies.ETH: Ether Futures (CME: ETH)Futures.Currencies.EUR: Euro FX Futures (CME: 6E)Futures.Currencies.EURAUD: Euro/Australian Dollar Futures (CME: EAD)Futures.Currencies.EURCAD: Euro/Canadian Dollar Futures (CME: ECD)Futures.Currencies.EuroFXEminiFutures.Currencies.EURO_FX_EMINI: E-mini Euro FX Futures (CME: E7)Futures.Currencies.EURSEK: Euro/Swedish Krona Futures (CME: ESK)Futures.Currencies.GBP: British Pound Futures (CME: 6B)Futures.Currencies.JapaneseYenEminiFutures.Currencies.JAPANESE_YEN_EMINI: E-mini Japanese Yen Futures (CME: J7)Futures.Currencies.JPY: Japanese Yen Futures (CME: 6J)Futures.Currencies.MicroAUDFutures.Currencies.MICRO_AUD: Micro AUD/USD Futures (CME: M6A)Futures.Currencies.MicroBTCFutures.Currencies.MICRO_BTC: Micro Bitcoin Futures (CME: MBT)Futures.Currencies.MicroCADFutures.Currencies.MICRO_CAD: Micro USD/CAD Futures (CME: M6C)Futures.Currencies.MicroCADUSDFutures.Currencies.MICRO_CADUSD: Micro CAD/USD Futures (CME: MCD)Futures.Currencies.MicroCHFFutures.Currencies.MICRO_CHF: Micro CHF/USD Futures (CME: MSF)Futures.Currencies.MicroEtherFutures.Currencies.MICRO_ETHER: Micro Ether Futures (CME: MET)Futures.Currencies.MicroEURFutures.Currencies.MICRO_EUR: Micro EUR/USD Futures (CME: M6E)Futures.Currencies.MicroGBPFutures.Currencies.MICRO_GBP: Micro GBP/USD Futures (CME: M6B)Futures.Currencies.MicroINRUSDFutures.Currencies.MICRO_INRUSD: Micro INR/USD Futures (CME: MIR)Futures.Currencies.MicroJPYFutures.Currencies.MICRO_JPY: Micro JPY/USD Futures (CME: MJY)Futures.Currencies.MicroUSDCHFFutures.Currencies.MICRO_USDCHF: Micro USD/CHF Futures (CME: M6S)Futures.Currencies.MicroUSDCNHFutures.Currencies.MICRO_USDCNH: Micro USD/CNH Futures (CME: MNH)Futures.Currencies.MicroUSDJPYFutures.Currencies.MICRO_USDJPY: Micro USD/JPY Futures (CME: M6J)Futures.Currencies.MXN: Mexican Peso Futures (CME: 6M)Futures.Currencies.NZD: New Zealand Dollar Futures (CME: 6N)Futures.Currencies.RUB: Russian Ruble Futures (CME: 6R)Futures.Currencies.StandardSizeUSDOffshoreRMBCNHFutures.Currencies.STANDARD_SIZE_USD_OFFSHORE_RMBCNH: Standard-Size USD/Offshore RMB (CNH) Futures (CME: CNH)Futures.Currencies.ZAR: South African Rand Futures (CME: 6Z)Futures.Energy.ArgusLLSvsWTIArgusTradeMonthFutures.Energy.ARGUS_LL_SVS_WTI_ARGUS_TRADE_MONTH: Argus LLS vs. WTI (Argus) Trade Month Futures (NYMEX: AE5)Futures.Energy.ArgusPropaneFarEastIndexFutures.Energy.ARGUS_PROPANE_FAR_EAST_INDEX: Argus Propane Far East Index Futures (NYMEX: A7E)Futures.Energy.ArgusPropaneSaudiAramcoFutures.Energy.ARGUS_PROPANE_SAUDI_ARAMCO: Argus Propane (Saudi Aramco) Futures (NYMEX: A9N)Futures.Energy.BrentCrudeOilVsDubaiCrudeOilPlattsFutures.Energy.BRENT_CRUDE_OIL_VS_DUBAI_CRUDE_OIL_PLATTS: Brent Crude Oil vs. Dubai Crude Oil (Platts) Futures (NYMEX: ADB)Futures.Energy.BrentLastDayFinancialFutures.Energy.BRENT_LAST_DAY_FINANCIAL: Brent Last Day Financial Futures (NYMEX: BZ)Futures.Energy.ChicagoEthanolPlattsFutures.Energy.CHICAGO_ETHANOL_PLATTS: Chicago Ethaanol (Platts) Futures (NYMEX: CU)Futures.Energy.ConwayPropaneOPISFutures.Energy.CONWAY_PROPANE_OPIS: Conway Propane (OPIS) Futures (NYMEX: A8K)Futures.Energy.CrudeOilWTIFutures.Energy.CRUDE_OIL_WTI: Crude Oil WTI Futures (NYMEX: CL)Futures.Energy.DubaiCrudeOilPlattsFinancialFutures.Energy.DUBAI_CRUDE_OIL_PLATTS_FINANCIAL: Dubai Crude Oil (Platts) Financial Futures (NYMEX: DCB)Futures.Energy.EastWestGasolineSpreadPlattsArgusFutures.Energy.EAST_WEST_GASOLINE_SPREAD_PLATTS_ARGUS: East-West Gasoline Spread (Platts-Argus) Futures (NYMEX: EWG)Futures.Energy.EastWestNaphthaJapanCFvsCargoesCIFNWESpreadPlattsFutures.Energy.EAST_WEST_NAPHTHA_JAPAN_C_FVS_CARGOES_CIFNWE_SPREAD_PLATTS: East-West Naphtha: Japan C&F vs. Cargoes CIF NWE Spread (Platts) Futures (NYMEX: EWN)Futures.Energy.EthanolFutures.Energy.ETHANOL: Ethanol Futures (CBOT: EH)Futures.Energy.EthanolT2FOBRdamIncludingDutyPlattsFutures.Energy.ETHANOL_T_2_FOB_RDAM_INCLUDING_DUTY_PLATTS: Ethanol T2 FOB Rdam Including Duty (Platts) Futures (NYMEX: AZ1)Futures.Energy.EuropeanNaphthaPlattsCrackSpreadFutures.Energy.EUROPEAN_NAPHTHA_PLATTS_CRACK_SPREAD: European Naphtha (Platts) Crack Spread Futures (NYMEX: EN)Futures.Energy.EuropeanPropaneCIFARAArgusFutures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS: European Propane CIF ARA (Argus) Futures (NYMEX: APS)Futures.Energy.EuropeanPropaneCIFARAArgusVsNaphthaCargoesCIFNWEPlattsFutures.Energy.EUROPEAN_PROPANE_CIFARA_ARGUS_VS_NAPHTHA_CARGOES_CIFNWE_PLATTS: European Propane CIF ARA (Argus) vs. Naphtha Cargoes CIF NWE (Platts) Futures (NYMEX: EPN)Futures.Energy.FreightRouteTC14BalticFutures.Energy.FREIGHT_ROUTE_TC_14_BALTIC: Freight Route TC14 (Baltic) Futures (NYMEX: FRC)Futures.Energy.GasolineFutures.Energy.GASOLINE: Gasoline RBOB Futures (NYMEX: RB)Futures.Energy.GasolineEurobobOxyNWEBargesArgusFutures.Energy.GASOLINE_EUROBOB_OXY_NWE_BARGES_ARGUS: Gasoline Euro-bob Oxy NWE Barges (Argus) Futures (NYMEX: B7H)Futures.Energy.GroupThreeSuboctaneGasolinePlattsVsRBOBFutures.Energy.GROUP_THREE_SUBOCTANE_GASOLINE_PLATTS_VS_RBOB: Group Three Sub-octane Gasoliine (Platts) vs. RBOB Futures (NYMEX: AA8)Futures.Energy.GroupThreeULSDPlattsVsNYHarborULSDFutures.Energy.GROUP_THREE_ULSD_PLATTS_VS_NY_HARBOR_ULSD: Group Three ULSD (Platts) vs. NY Harbor ULSD Futures (NYMEX: AA6)Futures.Energy.GulfCoastCBOBGasolineA2PlattsVsRBOBGasolineFutures.Energy.GULF_COAST_CBOB_GASOLINE_A_2_PLATTS_VS_RBOB_GASOLINE: Gulf Coast CBOB Gasoline A2 (Platts) vs. RBOB Gasoline Futures (NYMEX: CRB)Futures.Energy.GulfCoastHSFOPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlattsFutures.Energy.GULF_COAST_HSFO_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS: Gulf Coast HSFO (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: GCU)Futures.Energy.HeatingOilFutures.Energy.HEATING_OIL: Heating Oil Futures (NYMEX: HO)Futures.Energy.LosAngelesCARBOBGasolineOPISvsRBOBGasolineFutures.Energy.LOS_ANGELES_CARBOB_GASOLINE_OPI_SVS_RBOB_GASOLINE: Los Angeles CARBOB Gasoline (OPIS) vs. RBOB Gasoline Futures (NYMEX: AJL)Futures.Energy.LosAngelesCARBDieselOPISvsNYHarborULSDFutures.Energy.LOS_ANGELES_CARB_DIESEL_OPI_SVS_NY_HARBOR_ULSD: Los Angeles CARB Diesel (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AKL)Futures.Energy.LosAngelesJetOPISvsNYHarborULSDFutures.Energy.LOS_ANGELES_JET_OPI_SVS_NY_HARBOR_ULSD: Los Angeles Jet (OPIS) vs. NY Harbor ULSD Futures (NYMEX: AJS)Futures.Energy.MarsArgusVsWTIFinancialFutures.Energy.MARS_ARGUS_VS_WTI_FINANCIAL: Mars (Argus) vs. WTI Financial Futures (NYMEX: AYX)Futures.Energy.MarsArgusVsWTITradeMonthFutures.Energy.MARS_ARGUS_VS_WTI_TRADE_MONTH: Mars (Argus) vs. WTI Trade Month Futures (NYMEX: AYV)Futures.Energy.MicroCrudeOilWTIFutures.Energy.MICRO_CRUDE_OIL_WTI: Micro WTI Crude Oil Futures (NYMEX: MCL)Futures.Energy.MicroEuropeanFOBRdamMarineFuelZeroPointFivePercentBargesPlattsFutures.Energy.MICRO_EUROPEAN_FOB_RDAM_MARINE_FUEL_ZERO_POINT_FIVE_PERCENT_BARGES_PLATTS: Micro European FOB Rdam Marine Fuel 0.5% Barges (Platts) Futures (NYMEX: R5O)Futures.Energy.MicroEuropeanThreePointFivePercentOilBargesFOBRdamPlattsFutures.Energy.MICRO_EUROPEAN_THREE_POINT_FIVE_PERCENT_OIL_BARGES_FOB_RDAM_PLATTS: Micro European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: MEF)Futures.Energy.MicroGasoilZeroPointOnePercentBargesFOBARAPlattsFutures.Energy.MICRO_GASOIL_ZERO_POINT_ONE_PERCENT_BARGES_FOBARA_PLATTS: Micro Gasoil 0.1% Barges FOB ARA (Platts) Futures (NYMEX: M1B)Futures.Energy.MicroSingaporeFOBMarineFuelZeroPointFivePercetPlattsFutures.Energy.MICRO_SINGAPORE_FOB_MARINE_FUEL_ZERO_POINT_FIVE_PERCET_PLATTS: Micro Singapore FOB Marine Fuel 0.5% (Platts) Futures (NYMEX: S5O)Futures.Energy.MicroSingaporeFuelOil380CSTPlattsFutures.Energy.MICRO_SINGAPORE_FUEL_OIL_380_CST_PLATTS: Micro Singapore Fuel Oil 380CST (Platts) Futures (NYMEX: MAF)Futures.Energy.MiniEuropeanThreePointPercentFiveFuelOilBargesPlattsFutures.Energy.MINI_EUROPEAN_THREE_POINT_PERCENT_FIVE_FUEL_OIL_BARGES_PLATTS: Mini European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: A0D)Futures.Energy.MiniSingaporeFuelOil180CstPlattsFutures.Energy.MINI_SINGAPORE_FUEL_OIL_180_CST_PLATTS: Mini Singapore Fuel Oil 180 cst (Platts) Futures (NYMEX: A0F)Futures.Energy.MontBelvieuEthaneOPISFutures.Energy.MONT_BELVIEU_ETHANE_OPIS: Mont Belvieu Ethane (OPIS) Futures (NYMEX: AC0)Futures.Energy.MontBelvieuLDHPropaneOPISFutures.Energy.MONT_BELVIEU_LDH_PROPANE_OPIS: Mont Belvieu LDH Propane (OPIS) Futures (NYMEX: B0)Futures.Energy.MontBelvieuNaturalGasolineOPISFutures.Energy.MONT_BELVIEU_NATURAL_GASOLINE_OPIS: Mont Belvieu Natural Gasoline (OPIS) Futures (NYMEX: A7Q)Futures.Energy.MontBelvieuNormalButaneOPISFutures.Energy.MONT_BELVIEU_NORMAL_BUTANE_OPIS: Mont Belvieu Normal Butane (OPIS) Futures (NYMEX: AD0)Futures.Energy.NaturalGasFutures.Energy.NATURAL_GAS: Natural Gas Futures (NYMEX: NG)Futures.Energy.NaturalGasHenryHubLastDayFinancialFutures.Energy.NATURAL_GAS_HENRY_HUB_LAST_DAY_FINANCIAL: Natural Gas (Henry Hub) Last-day Financial Futures (NYMEX: HH)Futures.Energy.NaturalGasHenryHubPenultimateFinancialFutures.Energy.NATURAL_GAS_HENRY_HUB_PENULTIMATE_FINANCIAL: Natural Gas (Henry Hub) Penultimate Financial Futures (NYMEX: HP)Futures.Energy.OnePercentFuelOilCargoesFOBNWEPlattsVsThreePointFivePercentFuelOilBargesFOBRdamPlattsFutures.Energy.ONE_PERCENT_FUEL_OIL_CARGOES_FOBNWE_PLATTS_VS_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS: 1% Fuel Oil Cargoes FOB NWE (Platts) vs. 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: FSS)Futures.Energy.PremiumUnleadedGasoline10ppmFOBMEDPlattsFutures.Energy.PREMIUM_UNLEADED_GASOLINE_10_PPM_FOBMED_PLATTS: Premium Unleaded Gasoline 10 ppm FOB MED (Platts) Futures (NYMEX: A3G)Futures.Energy.PropaneNonLDHMontBelvieuOPISFutures.Energy.PROPANE_NON_LDH_MONT_BELVIEU_OPIS: Propane Non-LDH Mont Belvieu (OPIS) Futures (NYMEX: A1R)Futures.Energy.RBOBGasolineCrackSpreadFutures.Energy.RBOB_GASOLINE_CRACK_SPREAD: RBOB Gasoline Crack Spread Futures (NYMEX: ARE)Futures.Energy.RBOBGasolineVsEurobobOxyNWEBargesArgusThreeHundredFiftyThousandGallonsFutures.Energy.RBOB_GASOLINE_VS_EUROBOB_OXY_NWE_BARGES_ARGUS_THREE_HUNDRED_FIFTY_THOUSAND_GALLONS: RBOB Gasoline vs. Euro-bob Oxy NWE Barges (Argus) (350,000 gallons) Futures (NYMEX: EXR)Futures.Energy.SingaporeFuelOil380cstPlattsVsEuropeanThreePointFivePercentFuelOilBargesFOBRdamPlattsFutures.Energy.SINGAPORE_FUEL_OIL_380_CST_PLATTS_VS_EUROPEAN_THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS: Singapore Fuel Oil 380 cst (Platts) vs. European 3.5% Fuel Oil Barges FOB Rdam (Platts) Futures (NYMEX: EVC)Futures.Energy.SingaporeGasoilPlattsVsLowSulphurGasoilFuturesFutures.Energy.SINGAPORE_GASOIL_PLATTS_VS_LOW_SULPHUR_GASOIL_FUTURES: Singapore Gasoil (Platts) vs. Low Sulphur Gasoil Futures (NYMEX: AGA)Futures.Energy.SingaporeMogas92UnleadedPlattsBrentCrackSpreadFutures.Energy.SINGAPORE_MOGAS_92_UNLEADED_PLATTS_BRENT_CRACK_SPREAD: Singapore Mogas 92 Unleaded (Platts) Brent Crack Spread Futures (NYMEX: D1N)Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpreadFutures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD: 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread Futures (NYMEX: FO)Futures.Energy.ThreePointFivePercentFuelOilBargesFOBRdamPlattsCrackSpread1000mtFutures.Energy.THREE_POINT_FIVE_PERCENT_FUEL_OIL_BARGES_FOB_RDAM_PLATTS_CRACK_SPREAD_1000_MT: 3.5% Fuel Oil Barges FOB Rdam (Platts) Crack Spread (1000mt) Futures (NYMEX: BOO)Futures.Energy.WTIBrentFinancialFutures.Energy.WTI_BRENT_FINANCIAL: WTI-Brent Financial Futures (NYMEX: BK)Futures.Energy.WTIFinancialFutures.Energy.WTI_FINANCIAL: WTI Financial Futures (NYMEX: CSX)Futures.Energy.WTIHoustonArgusVsWTITradeMonthFutures.Energy.WTI_HOUSTON_ARGUS_VS_WTI_TRADE_MONTH: WTI Houston (Argus) vs. WTI Trade Month Futures (NYMEX: HTT)Futures.Energy.WTIHoustonCrudeOilFutures.Energy.WTI_HOUSTON_CRUDE_OIL: WTI Houston Crude Oil Futures (NYMEX: HCL)Futures.Financials.EuroDollarFutures.Financials.EURO_DOLLAR: EuroDollar Futures (CME: GE)Futures.Financials.FiveYearUSDMACSwapFutures.Financials.FIVE_YEAR_USDMAC_SWAP: 5-Year USD MAC Swap Futures (CBOT: F1U)Futures.Financials.MicroY10TreasuryNoteFutures.Financials.MICRO_Y_10_TREASURY_NOTE: Micro 10-Year Yield Futures (CBOT: 10Y)Futures.Financials.MicroY2TreasuryBondFutures.Financials.MICRO_Y_2_TREASURY_BOND: Micro 2-Year Yield Futures (CBOT: 2YY)Futures.Financials.MicroY30TreasuryBondFutures.Financials.MICRO_Y_30_TREASURY_BOND: Micro 30-Year Yield Futures (CBOT: 30Y)Futures.Financials.MicroY5TreasuryBondFutures.Financials.MICRO_Y_5_TREASURY_BOND: Micro 5-Year Yield Futures (CBOT: 5YY)Futures.Financials.UltraTenYearUSTreasuryNoteFutures.Financials.ULTRA_TEN_YEAR_US_TREASURY_NOTE: Ultra 10-Year U.S. Treasury Note Futures (CBOT: TN)Futures.Financials.UltraUSTreasuryBondFutures.Financials.ULTRA_US_TREASURY_BOND: Ultra U.S. Treasury Bond Futures (CBOT: UB)Futures.Financials.Y10TreasuryNoteFutures.Financials.Y_10_TREASURY_NOTE: 10Y U.S. Treasury Note Futures (CBOT: ZN)Futures.Financials.Y2TreasuryNoteFutures.Financials.Y_2_TREASURY_NOTE: 2Y U.S. Treasury Note Futures (CBOT: ZT)Futures.Financials.Y30TreasuryBondFutures.Financials.Y_30_TREASURY_BOND: 30Y U.S. Treasury Bond Futures (CBOT: ZB)Futures.Financials.Y5TreasuryNoteFutures.Financials.Y_5_TREASURY_NOTE: 5Y U.S. Treasury Note Futures (CBOT: ZF)Futures.Forestry.LumberFutures.Forestry.LUMBER: Lumber Futures (CME: LBR)Futures.Forestry.RandomLengthLumberFutures.Forestry.RANDOM_LENGTH_LUMBER: Random Length Lumber Futures (CME: LBS)Futures.Grains.BlackSeaCornFinanciallySettledPlattsFutures.Grains.BLACK_SEA_CORN_FINANCIALLY_SETTLED_PLATTS: Black Sea Corn Financially Settled (Platts) Futures (CBOT: BCF)Futures.Grains.BlackSeaWheatFinanciallySettledPlattsFutures.Grains.BLACK_SEA_WHEAT_FINANCIALLY_SETTLED_PLATTS: Black Sea Wheat Financially Settled (Platts) Futures (CBOT: BWF)Futures.Grains.CornFutures.Grains.CORN: Corn Futures (CBOT: ZC)Futures.Grains.HRWWheatFutures.Grains.HRW_WHEAT: KC HRW Wheat Futures (CBOT: KE)Futures.Grains.OatsFutures.Grains.OATS: Oats Futures (CBOT: ZO)Futures.Grains.SoybeansFutures.Grains.SOYBEANS: Soybeans Futures (CBOT: ZS)Futures.Grains.SoybeanMealFutures.Grains.SOYBEAN_MEAL: Soybean Meal Futures (CBOT: ZM)Futures.Grains.SoybeanOilFutures.Grains.SOYBEAN_OIL: Soybean Oil Futures (CBOT: ZL)Futures.Grains.WheatFutures.Grains.WHEAT: Default wheat contract is SRWWheat (CBOT: ZW)Futures.Indices.BloombergCommodityIndexFutures.Indices.BLOOMBERG_COMMODITY_INDEX: Bloomberg Commodity Index Futures (CBOT: AW)Futures.Indices.Dow30EMiniFutures.Indices.DOW_30_E_MINI: E-mini Dow Indu 30 Futures (CBOT: YM)Futures.Indices.DowJonesRealEstateFutures.Indices.DOW_JONES_REAL_ESTATE: Dow Jones Real Estate futures on CME (CME: RX)Futures.Indices.FTSEEmergingEminiFutures.Indices.FTSE_EMERGING_EMINI: E-mini FTSE Emerging Index Futures (CME: EI)Futures.Indices.MicroDow30EMiniFutures.Indices.MICRO_DOW_30_E_MINI: Micro E-mini Dow Jones Industrial Average Index Futures (CBOT: MYM)Futures.Indices.MicroNASDAQ100EMiniFutures.Indices.MICRO_NASDAQ_100_E_MINI: Micro E-mini Nasdaq-100 Index Futures (CME: MNQ)Futures.Indices.MicroRussell2000EMiniFutures.Indices.MICRO_RUSSELL_2000_E_MINI: Micro E-mini Russell 2000 Index Futures (CME: M2K)Futures.Indices.MicroSP500EMiniFutures.Indices.MICRO_SP_500_E_MINI: Micro E-mini S&P 500 Index Futures (CME: MES)Futures.Indices.NASDAQ100BiotechnologyEMiniFutures.Indices.NASDAQ_100_BIOTECHNOLOGY_E_MINI: E-mini Nasdaq-100 Biotechnology Index Futures (CME: BIO)Futures.Indices.NASDAQ100EMiniFutures.Indices.NASDAQ_100_E_MINI: E-mini NASDAQ 100 Futures (CME: NQ)Futures.Indices.Nikkei225DollarFutures.Indices.NIKKEI_225_DOLLAR: Nikkei-225 Dollar Futures (CME: NKD)Futures.Indices.Nikkei225YenCMEFutures.Indices.NIKKEI_225_YEN_CME: Nikkei-225 Yen denominated Futures on CME (CME: NIY)Futures.Indices.Russell1000EMiniFutures.Indices.RUSSELL_1000_E_MINI: E-mini Russell 1000 futures on CME (CME: RS1)Futures.Indices.Russell2000EMiniFutures.Indices.RUSSELL_2000_E_MINI: E-mini Russell 2000 Futures (CME: RTY)Futures.Indices.SPGSCICommodityFutures.Indices.SPGSCI_COMMODITY: S&P-GSCI Commodity Index Futures (CME: GD)Futures.Indices.SP400MidCapEminiFutures.Indices.SP_400_MID_CAP_EMINI: E-mini S&P MidCap 400 Futures (CME: EMD)Futures.Indices.SP500AnnualDividendIndexFutures.Indices.SP_500_ANNUAL_DIVIDEND_INDEX: (CME: SDA)Futures.Indices.SP500EMiniFutures.Indices.SP_500_E_MINI: E-mini S&P 500 Futures (CME: ES)Futures.Indices.TOPIXYEN: YEN Denominated Topix Index Futures on CME (CME: TPY)Futures.Indices.USDDenominatedIbovespaFutures.Indices.USD_DENOMINATED_IBOVESPA: USD-Denominated Ibovespa Index Futures (CME: IBV)Futures.Indices.VIX: CBOE Volatility Index Futures (CFE: VX)Futures.Meats.FeederCattleFutures.Meats.FEEDER_CATTLE: Feeder Cattle Futures (CME: GF)Futures.Meats.LeanHogsFutures.Meats.LEAN_HOGS: Lean Hogs Futures (CME: HE)Futures.Meats.LiveCattleFutures.Meats.LIVE_CATTLE: Live Cattle Futures (CME: LE)Futures.Metals.AluminiumEuropeanPremiumDutyPaidMetalBulletinFutures.Metals.ALUMINIUM_EUROPEAN_PREMIUM_DUTY_PAID_METAL_BULLETIN: Aluminium European Premium Duty-Paid (Metal Bulletin) Futures (COMEX: EDP)Futures.Metals.AluminumMWUSTransactionPremiumPlatts25MTFutures.Metals.ALUMINUM_MWUS_TRANSACTION_PREMIUM_PLATTS_25_MT: Aluminum MW U.S. Transaction Premium Platts (25MT) Futures (COMEX: AUP)Futures.Metals.CopperFutures.Metals.COPPER: Copper Futures (COMEX: HG)Futures.Metals.GoldFutures.Metals.GOLD: Gold Futures (COMEX: GC)Futures.Metals.MicroGoldFutures.Metals.MICRO_GOLD: Micro Gold Futures (COMEX: MGC)Futures.Metals.MicroGoldTASFutures.Metals.MICRO_GOLD_TAS: Micro Gold TAS Futures (COMEX: MGT)Futures.Metals.MicroPalladiumFutures.Metals.MICRO_PALLADIUM: Micro Palladium Futures (NYMEX: PAM)Futures.Metals.MicroSilverFutures.Metals.MICRO_SILVER: Micro Silver Futures (COMEX: SIL)Futures.Metals.PalladiumFutures.Metals.PALLADIUM: Palladium Futures (NYMEX: PA)Futures.Metals.PlatinumFutures.Metals.PLATINUM: Platinum Futures (NYMEX: PL)Futures.Metals.SilverFutures.Metals.SILVER: Silver Futures (COMEX: SI)Futures.Metals.USMidwestDomesticHotRolledCoilSteelCRUIndexFutures.Metals.US_MIDWEST_DOMESTIC_HOT_ROLLED_COIL_STEEL_CRU_INDEX: U.S. Midwest Domestic Hot-Rolled Coil Steel (CRU) Index Futures (NYMEX: HRC)Futures.Softs.Sugar11Futures.Softs.SUGAR_11: Sugar #11 Futures ICE (ICE: SB)Futures.Softs.Sugar11CMEFutures.Softs.SUGAR_11_CME: Sugar #11 Futures CME (NYMEX: YO)
Example Applications
The US Futures Security Master enables you to design strategies harnessing continuous Futures contracts. Examples include the following strategies:
- Trading cyclical patterns in commodity Futures.
- Buying gold Futures as an inflation hedge with automatic contract roll-overs.
- Detecting arbitrage opportunities between index Futures and Equities.
Classic Algorithm Example
The following example algorithm buys the continuous Future contract for Crude Oil when its price rises above its simple moving average. When its price drops below its simple moving average, the algorithm sells the continuous contract. Each time the continuous Future contract rolls over, the algorithm logs the event.
from AlgorithmImports import *
class USFuturesSecurityMasterDataClassicAlgorithm(QCAlgorithm):
# Define a threshold for the SMA cross.
_threshold = 0.01
def initialize(self) -> None:
self.set_cash(1000000)
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
# Seed the price of each asset with its last known price to
# avoid trading errors.
self.set_security_initializer(
BrokerageModelSecurityInitializer(
self.brokerage_model,
FuncSecuritySeeder(self.get_last_known_prices)
)
)
# Add a Future. Set the continuous contract mapping criteria to
# the contract with highest open interest to provide the best
# price information for trend estimation.
self._future = self.add_future(
Futures.Energy.CRUDE_OIL_WTI,
data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
data_mapping_mode=DataMappingMode.OPEN_INTEREST,
contract_depth_offset=0
)
# Historical data: Get the contract rollovers for the trailing
# year.
history = self.history(
SymbolChangedEvent, self._future.symbol, timedelta(365)
)
# Set up an SMA indicator for to estimate the trend direction.
self._sma = self.sma(self._future.symbol, 10, Resolution.DAILY)
# Warm up the SMA indicator so we can trade right away.
self.warm_up_indicator(self._future.symbol, self._sma)
def on_data(self, slice: Slice) -> None:
# Wait until we have the latest TradeBar and the indicator is
# ready.
if not (self._future.symbol in slice.bars and self._sma.is_ready):
return
contract = self.portfolio[self._future.mapped]
# Long during an uptrend.
if (not contract.is_long and
self._future.price > self._sma.current.value * (1+self._threshold)):
quantity = 1
# Short during an downtrend.
elif (not contract.is_short and
self._future.price < self._sma.current.value * (1-self._threshold)):
quantity = -1
else:
return
self.market_order(self._future.mapped, quantity - contract.quantity)
def on_symbol_changed_events(self, symbol_changed_events):
for symbol, changed_event in symbol_changed_events.items():
old_symbol = changed_event.old_symbol
new_symbol = changed_event.new_symbol
# The quantity to roll over should be consistent.
quantity = self.portfolio[old_symbol].quantity
if not quantity:
continue
# Rolling over: Liquidate the old mapped contract and switch
# to the new mapped contract.
tag = f"Rollover: {old_symbol} -> {new_symbol}"
self.liquidate(old_symbol, tag=tag)
self.market_order(new_symbol, quantity, tag=tag) public class USFuturesSecurityMasterDataClassicAlgorithm : QCAlgorithm
{
private Future _future;
// Define a threshold for the SMA cross.
private decimal _threshold = 0.01m;
private SimpleMovingAverage _sma;
public override void Initialize()
{
SetCash(1000000);
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
// Seed the price of each asset with its last known price to
// avoid trading errors.
SetSecurityInitializer(
new BrokerageModelSecurityInitializer(
BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices)
)
);
// Add a Future. Set the continuous contract mapping criteria to
// the contract with highest open interest to provide the best
// price information for trend estimation.
_future = AddFuture(
Futures.Energy.CrudeOilWTI,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
dataMappingMode: DataMappingMode.OpenInterest,
contractDepthOffset: 0
);
// Historical data: Get the contract rollovers for the trailing
// year.
var history = History<SymbolChangedEvent>(_future.Symbol, TimeSpan.FromDays(365));
foreach (var symbolChangedEvent in history)
{
var t = symbolChangedEvent.EndTime;
var oldSymbol = symbolChangedEvent.OldSymbol;
var newSymbol = symbolChangedEvent.NewSymbol;
}
// Set up an SMA indicator for to estimate the trend direction.
_sma = SMA(_future.Symbol, 10, Resolution.Daily);
// Warm up the SMA indicator so we can trade right away.
WarmUpIndicator(_future.Symbol, _sma);
}
public override void OnData(Slice slice)
{
// Wait until we have the latest TradeBar and the indicator is
// ready.
if (!(slice.Bars.ContainsKey(_future.Symbol) && _sma.IsReady))
{
return;
}
var contract = Portfolio[_future.Mapped];
int quantity;
// Long during an uptrend.
if (!contract.IsLong && _future.Price > _sma.Current.Value * (1+_threshold))
{
quantity = 1;
}
// Short during an downtrend.
else if (!contract.IsShort && _future.Price < _sma.Current.Value * (1-_threshold))
{
quantity = -1;
}
else
{
return;
}
MarketOrder(_future.Mapped, quantity - contract.Quantity);
}
public override void OnSymbolChangedEvents(SymbolChangedEvents symbolChangedEvents)
{
foreach (var (symbol, changedEvent) in symbolChangedEvents)
{
var oldSymbol = changedEvent.OldSymbol;
var newSymbol = changedEvent.NewSymbol;
// The quantity to roll over should be consistent.
var quantity = Portfolio[oldSymbol].Quantity;
if (quantity == 0)
{
continue;
}
// Rolling over: Liquidate the old mapped contract and switch
// to the new mapped contract.
var tag = $"Rollover: {oldSymbol} -> {newSymbol}";
Liquidate(oldSymbol, tag: tag);
MarketOrder(newSymbol, quantity, tag: tag);
}
}
}
Framework Algorithm Example
The following example algorithm buys the continuous Future contract for Crude Oil when its price rises above its simple moving average. When its price drops below its simple moving average, the algorithm sells the continuous contract. Each time the contract rolls over, the algorithm logs the event.
from AlgorithmImports import *
class USFuturesSecurityMasterDataFrameworkAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_cash(1000000)
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
# Setting the continuous contract mapping criteria, the contract with highest open interest provide the best price information for trend estimation
self.add_future(Futures.Energies.CRUDE_OIL_WTI,
data_normalization_mode = DataNormalizationMode.BACKWARDS_RATIO,
data_mapping_mode = DataMappingMode.OPEN_INTEREST,
contract_depth_offset = 0)
self.add_alpha(ContinuousFuturesAlphaModel())
self.set_portfolio_construction(SingleSharePortfolioConstructionModel())
class ContinuousFuturesAlphaModel(AlphaModel):
# 1% margin to reassure trend direction
threshold = 0.01
symbol = None
continuous_contract = None
def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
insights = []
# Check if contract data available, since all trades are based on that only
if self.continuous_contract_symbol is None or self.continuous_contract is None:
return insights
# Up-to-date handling of switching the mapped contract for trade liquidity
for symbol, changed_event in slice.symbol_changed_events.items():
old_symbol = changed_event.old_symbol
if algorithm.insights.has_active_insights(old_symbol, algorithm.utc_time):
new_symbol = changed_event.new_symbol
tag = f"Rollover - Symbol changed at {algorithm.time}: {old_symbol} -> {new_symbol}"
last_insight = sorted(algorithm.insights[old_symbol], key=lambda x: x.close_time_utc)[-1]
insights.append(Insight.price(new_symbol, last_insight.close_time_utc, last_insight.direction, tag= tag))
algorithm.insights.clear([old_symbol])
algorithm.log(tag)
mapped_symbol = self.continuous_contract.mapped
# Make sure trade decisions are based on newly received data
if not slice.bars.contains_key(self.continuous_contract_symbol) or not self.sma.is_ready or not mapped_symbol:
return insights
direction = None
# Long if trend up by threshold to follow the trend
if slice.bars[self.continuous_contract_symbol].price > self.sma.current.value * (1+self.threshold) and not algorithm.portfolio[mapped_symbol].is_long:
direction = InsightDirection.UP
# Short if trend down by threshold to follow the trend
elif slice.bars[self.continuous_contract_symbol].price < self.sma.current.value * (1-self.threshold) and not algorithm.portfolio[mapped_symbol].is_short:
direction = InsightDirection.DOWN
if direction:
insights.append(Insight.price(mapped_symbol, timedelta(days=14), direction))
return insights
def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
for security in changes.added_securities:
symbol = security.symbol
# Set up SMA indicator for trend direction estimator, only for the canonical symbol
if symbol.is_canonical():
self.continuous_contract = security
self.continuous_contract_symbol = symbol
self.sma = algorithm.SMA(self.continuous_contract_symbol, 10, Resolution.DAILY)
# Historical data
history = algorithm.history(symbol, 60*24*10, Resolution.MINUTE)
algorithm.debug(f"We got {len(history)} from our history request for {symbol}")
if history.empty:
continue
# Warm up the SMA indicator for its readiness for immediate use
for time, row in history.droplevel(0).loc[self.continuous_contract_symbol].iterrows():
self.sma.update(IndicatorDataPoint(time, row.close))
class SingleSharePortfolioConstructionModel(PortfolioConstructionModel):
def create_targets(self, algorithm: QCAlgorithm, insights: List[Insight]) -> List[PortfolioTarget]:
targets = []
for insight in insights:
if algorithm.securities[insight.symbol].is_tradable:
targets.append(PortfolioTarget(insight.symbol, insight.direction))
return targets public class USFuturesSecurityMasterDataFrameworkAlgorithm : QCAlgorithm
{
public override void Initialize()
{
SetCash(1000000);
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
// Setting the continuous contract mapping criteria, the contract with highest open interest provide the best price information for trend estimation
AddFuture(Futures.Energies.CrudeOilWTI,
dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
dataMappingMode: DataMappingMode.OpenInterest,
contractDepthOffset: 0
);
AddAlpha(new ContinuousFuturesAlphaModel());
SetPortfolioConstruction(new SingleSharePortfolioConstructionModel());
}
class ContinuousFuturesAlphaModel : AlphaModel
{
private Future _continuousContract;
private Symbol _symbol;
// 1% margin to reassure trend direction
private decimal _threshold = 0.01m;
private SimpleMovingAverage _sma;
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
{
var insights = new List<Insight>();
// Check if contract data available, since all trades are based on that only
if (_symbol == null || _continuousContract == null)
{
return insights;
}
// Up-to-date handling of switching the mapped contract for trade liquidity
foreach (var (symbol, changedEvent) in slice.SymbolChangedEvents)
{
var oldSymbol = changedEvent.OldSymbol;
if (algorithm.Insights.HasActiveInsights(oldSymbol, algorithm.UtcTime))
{
var newSymbol = changedEvent.NewSymbol;
var tag = $"Rollover - Symbol changed at {algorithm.Time}: {oldSymbol} -> {newSymbol}";
var lastInsight = algorithm.Insights[oldSymbol].OrderBy(x => x.CloseTimeUtc).LastOrDefault();
insights.Add(Insight.Price(newSymbol, lastInsight.CloseTimeUtc, lastInsight.Direction, tag: tag));
algorithm.Insights.Clear(new Symbol[] { oldSymbol });
algorithm.Log(tag);
}
}
var mappedSymbol = _continuousContract.Mapped;
// Make sure trade decisions are based on newly received data
if (!slice.Bars.ContainsKey(_symbol) || !_sma.IsReady || mappedSymbol == null)
{
return insights;
}
// Long if trend up by threshold to follow the trend
if (slice.Bars[_symbol].Price > _sma.Current.Value * (1+_threshold) && !algorithm.Portfolio[mappedSymbol].IsLong)
{
insights.Add(Insight.Price(mappedSymbol, TimeSpan.FromDays(14), InsightDirection.Up));
}
// Short if trend down by threshold to follow the trend
else if (slice.Bars[_symbol].Price < _sma.Current.Value * (1-_threshold) && !algorithm.Portfolio[mappedSymbol].IsShort)
{
insights.Add(Insight.Price(mappedSymbol, TimeSpan.FromDays(14), InsightDirection.Down));
}
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
foreach (var security in changes.AddedSecurities)
{
var symbol = security.Symbol;
// Set up SMA indicator for trend direction estimator, only for the canonical symbol
if (symbol.IsCanonical())
{
_continuousContract = (Future)security;
_symbol = symbol;
_sma = algorithm.SMA(_symbol, 10, Resolution.Daily);
// Historical data
var history = algorithm.History(symbol, 60*24*10, Resolution.Minute);
algorithm.Debug($"We got {history.Count()} from our history request for {symbol}");
// Warm up the SMA indicator for its readiness for immediate use
foreach (var bar in history)
{
_sma.Update(new IndicatorDataPoint(bar.Time, bar.Close));
}
}
}
}
}
class SingleSharePortfolioConstructionModel : PortfolioConstructionModel
{
public override IEnumerable<PortfolioTarget> CreateTargets(QCAlgorithm algorithm, Insight[] insights)
{
var targets = new List<PortfolioTarget>();
foreach (var insight in insights)
{
if (algorithm.Securities[insight.Symbol].IsTradable)
{
targets.Add(new PortfolioTarget(insight.Symbol, (int) insight.Direction));
}
}
return targets;
}
}
}