I have written a simple piece of code in the Research Environment that plots GBP continuous futures data between two dates (See below). The results show a flat period in the data of about a month. Am I doing something wrong?

import matplotlib.pyplot as plt
import matplotlib.dates as mdates # Import the mdates module
# Initialize QuantBook
qb = QuantBook()
# Define the continuous future contract for GBP
gbp_future = qb.add_future(
Futures.Currencies.GBP,
resolution = Resolution.DAILY,
data_normalization_mode=DataNormalizationMode.BACKWARDS_PANAMA_CANAL,
data_mapping_mode = DataMappingMode.OPEN_INTEREST,
contract_depth_offset=0,
extended_market_hours=True)
# Define the start and end dates for the historical data
start_date = datetime(2023, 9, 1)
end_date = datetime(2024, 5, 31)
# Get the historical data as a TradeBar dataframe for the continuous GBP future
history = qb.History(TradeBar, gbp_future.Symbol, start_date, end_date, Resolution.Daily)
#print(history.head())
#print(history.index)
# Extract the relevant data
close_prices = history.loc[('1899-12-30', '/6B')]['close']
sliced_data = close_prices['2023-12-01':'2023-12-31']
print(sliced_data)
# Convert the index to datetime objects if it's not already
close_prices.index = pd.to_datetime(close_prices.index)
# Create the plot
plt.figure(figsize=(10, 6)) # Adjust figure size as needed
plt.plot(close_prices.index, close_prices.values)
# Set monthly labels on the x-axis
plt.xlabel("Date")
plt.ylabel("Closing Price")
plt.title("GBP")
plt.xticks(pd.to_datetime(close_prices.resample('MS').first().index),
close_prices.resample('MS').first().index.strftime('%Y-%m'),
rotation=45, ha='right')
plt.tight_layout()
plt.show()
Mia Alissi
Here is a complete diagnosis and fix for Chris's issue with the flat GBP futures plot, including explanations and enhanced diagnostics.
How to use it:
('1899-12-30', '/6B')
) and instead inspects the full structure.data_normalization_mode
parameter toBACKWARDS_RATIO
orRAW
as a next step.If you have questions on interpreting the diagnostics, or want an automatic test of alternate normalization modes, let me know!
Sources: Pandas Data Frame History Algorithm, Universes - QuantConnect.com, Futures - QuantConnect.com, Residual Momentum, Individual Contracts - QuantConnect.com
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.
Chris Stichbury
---------------------------------------------------------------------------
ValueError                 Traceback (most recent call last)
File /opt/miniconda3/lib/python3.11/site-packages/pandas/core/indexes/multi.py:1542, in MultiIndex._get_level_number(self, level)
 1541 try:
-> 1542 Â Â level = self.names.index(level)
 1543 except ValueError as err:
ValueError: 'Symbol' is not in list
The above exception was the direct cause of the following exception:
KeyError                  Traceback (most recent call last)
Cell In[1], line 30
  27 # We'll check if it's a MultiIndex or single-level index
  28 if isinstance(history.index, pd.MultiIndex):
  29   # Typically, a MultiIndex with levels [Time, Symbol]
---> 30 Â Â continuous_df = history.xs(gbp_future.symbol, level="Symbol")
  31   print("\nDetected MultiIndex. Extracted continuous contract slice using xs(...).")
  32 else:
File /opt/miniconda3/lib/python3.11/site-packages/pandas/core/generic.py:4209, in NDFrame.xs(self, key, axis, level, drop_level)
 4207 if not isinstance(labels, MultiIndex):
 4208   raise TypeError("Index must be a MultiIndex")
-> 4209 loc, new_ax = labels.get_loc_level(key, level=level, drop_level=drop_level)
 4211 # create the tuple of the indexer
 4212 _indexer = [slice(None)] * self.ndim
File /opt/miniconda3/lib/python3.11/site-packages/pandas/core/indexes/multi.py:3031, in MultiIndex.get_loc_level(self, key, level, drop_level)
 2990 """
 2991 Get location and sliced index for requested label(s)/level(s).
 2992Â
 (...)
 3028 (1, None)
 3029 """
 3030 if not isinstance(level, (list, tuple)):
-> 3031 Â Â level = self._get_level_number(level)
 3032 else:
 3033   level = [self._get_level_number(lev) for lev in level]
File /opt/miniconda3/lib/python3.11/site-packages/pandas/core/indexes/multi.py:1545, in MultiIndex._get_level_number(self, level)
 1543 except ValueError as err:
 1544   if not is_integer(level):
-> 1545 Â Â Â Â raise KeyError(f"Level {level} not found") from err
 1546   if level < 0:
 1547     level += self.nlevels
KeyError: 'Level Symbol not found'
Chris Stichbury
---------------------------------------------------------------------------
AttributeError               Traceback (most recent call last)
Cell In[2], line 62
  59   print("\nNo flatline runs of more than 5 consecutive days detected.")
  60 # 6) Plot the properly selected close price series
  61 # Ensure index is a proper datetime type
---> 62 if not pd.api.types.is_datetime_64_any_dtype(continuous_df.index):
  63   continuous_df.index = pd.to_datetime(continuous_df.index)
  64 plt.figure(figsize=(10, 6))
AttributeError: module 'pandas.api.types' has no attribute 'is_datetime_64_any_dtype'
Chris Stichbury
================ DATAFRAME STRUCTURE ================
                    close   high   low   open  volume
expiry   symbol time                            Â
1899-12-30 /6B Â Â 2023-09-01 16:00:00 Â 1.2606 Â 1.2721 Â 1.2595 Â 1.2716 Â 50302.0
         2023-09-04 16:00:00  1.2646  1.2654  1.2633  1.2652  6453.0
         2023-09-05 16:00:00  1.2581  1.2604  1.2565  1.2597  30369.0
         2023-09-06 16:00:00  1.2525  1.2563  1.2500  1.2557  48173.0
         2023-09-07 16:00:00  1.2489  1.2508  1.2464  1.2485  31470.0
Index Type: <class 'pandas.core.indexes.multi.MultiIndex'>
Index Names: ['expiry', 'symbol', 'time']
Index Sample (first 5): MultiIndex([('1899-12-30', /6B, '2023-09-01 16:00:00'),
      ('1899-12-30', /6B, '2023-09-04 16:00:00'),
      ('1899-12-30', /6B, '2023-09-05 16:00:00'),
      ('1899-12-30', /6B, '2023-09-06 16:00:00'),
      ('1899-12-30', /6B, '2023-09-07 16:00:00')],
     names=['expiry', 'symbol', 'time'])
DataFrame Shape: (192, 5)
Detected MultiIndex. Extracted continuous contract slice using xs(...).
================ CLOSE COLUMN STATISTICS ================
Min Close: 1.2092
Max Close: 1.2889
Number of unique Close values: 147
NaN count: 0
No NaN values found in close prices.
Flatline runs (>5 consecutive days) detected:
Group 72 - Size 21 - From (Timestamp('1899-12-30 00:00:00'), Timestamp('2023-12-15 16:00:00')) to (Timestamp('1899-12-30 00:00:00'), Timestamp('2024-01-16 16:00:00'))
Louis Szeto
Hi Chris
Please file a data issue if you think it is a data missing issue, and we will investigate it. Thank you!
Best
Louis
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.
Chris Stichbury
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!