From e0448dc79c39403cd8dcfddedb0bdd8ba3432cef Mon Sep 17 00:00:00 2001 From: Alexandre Catarino Date: Fri, 18 Oct 2024 19:26:06 +0100 Subject: [PATCH] Updates Create Future Universe First Example --- .../06 Futures/11 Create Universes.html | 77 +++++++++++++++++-- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/03 Writing Algorithms/12 Universes/06 Futures/11 Create Universes.html b/03 Writing Algorithms/12 Universes/06 Futures/11 Create Universes.html index 24b2aa851a..19c5942971 100644 --- a/03 Writing Algorithms/12 Universes/06 Futures/11 Create Universes.html +++ b/03 Writing Algorithms/12 Universes/06 Futures/11 Create Universes.html @@ -1,12 +1,75 @@ -

To add a universe of Future contracts, in the Initializeinitialize method, call the AddFutureadd_future method. This method returns an Future object, which contains the continuous contract Symbolsymbol. The continuous contract Symbol is the key to access the contracts in the FutureChain that LEAN passes to the OnDataon_data method. When you create the Future subscription, save a reference to the continuous contract Symbolsymbol so you can use it later in your algorithm.

+

To add a universe of Future contracts, in the Initializeinitialize method, call the AddFutureadd_future method. This method returns an Future object, which contains the continuous contract Symbolsymbol. The continuous contract Symbolsymbol is the key to access the contracts in the FutureChain that LEAN passes to the OnDataon_data method. The continuous contract Mappedmapped property references the current contract in the continuous contract series. When you create the Future subscription, save a reference to the Future object so you can use it later in your algorithm.

-
UniverseSettings.Asynchronous = true;
-_future = AddFuture(Futures.Currencies.BTC);
-_symbol = _future.Symbol;
-
self.universe_settings.asynchronous = True
-self._future = self.add_future(Futures.Currencies.BTC)
-self._symbol = self._future.symbol
+
public class BasicFutureAlgorithm : QCAlgorithm
+{
+    private Future _future;
+    public override void Initialize()
+    {
+        UniverseSettings.Asynchronous = true;
+        _future = AddFuture(Futures.Currencies.BTC,
+            extendedMarketHours: true,
+            dataMappingMode: DataMappingMode.LastTradingDay,
+            dataNormalizationMode: DataNormalizationMode.BackwardsRatio,
+            contractDepthOffset: 0);
+        _future.SetFilter(0, 62);
+    }
+
+    public override void OnData(Slice data)
+    {
+        if (Portfolio.Invested)
+        {
+            return;
+        }
+        data.Bars.TryGetValue(_future.Symbol, out var continuousTradeBar);
+        data.Bars.TryGetValue(_future.Mapped, out var mappedTradeBar);
+        MarketOrder(_future.Mapped, 1);
+    }
+
+    // Track events when security changes its ticker, allowing the algorithm to adapt to these changes.
+    public override void OnSymbolChangedEvents(SymbolChangedEvents symbolChangedEvents)
+    {
+        foreach (var (symbol, changedEvent) in symbolChangedEvents)
+        {
+            var oldSymbol = changedEvent.OldSymbol;
+            var newSymbol = changedEvent.NewSymbol;
+            var quantity = Portfolio[oldSymbol].Quantity;
+
+            // Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
+            var tag = $"Rollover - Symbol changed at {Time}: {oldSymbol} -> {newSymbol}";
+            Liquidate(oldSymbol, tag: tag);
+            if (quantity != 0) MarketOrder(newSymbol, quantity, tag: tag);
+        }
+    }
+}
+
class BasicFutureAlgorithm(QCAlgorithm):
+    def initialize(self):
+        self.universe_settings.asynchronous = True
+        self._future = self.add_future(Futures.Currencies.BTC,
+            extended_market_hours=True,
+            data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
+            data_normalization_mode=DataNormalizationMode.BACKWARDS_RATIO,
+            contract_depth_offset=0)
+        self._future.set_filter(0,62)
+
+    def on_data(self, data):
+        if self.portfolio.invested:
+            return
+        continuous_trade_bar = data.bars.get(self._future.symbol)
+        mapped_trade_bar = data.bars.get(self._future.mapped)
+        self.market_order(self._future.mapped, 1)
+   
+    # Track events when security changes its ticker allowing algorithm to adapt to these changes.
+    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
+            quantity = self.portfolio[old_symbol].quantity
+
+            # Rolling over: to liquidate any position of the old mapped contract and switch to the newly mapped contract
+            tag = f"Rollover - Symbol changed at {self.time}: {old_symbol} -> {new_symbol}"
+            self.liquidate(old_symbol, tag=tag)
+            if quantity: self.market_order(new_symbol, quantity, tag=tag)

The following table describes the AddFutureadd_future method arguments: