I'm customizing the built-in GLOBEX calendar to add proper support for the daily trading halt with the following lines:
break_start_times = (
(None, time(15, 16)),
)
break_end_times = (
(None, time(15, 30)),
)
This is supported syntax in the original trading-calendars
package from Quantopian. However, it appears Zipline doesn't handle trading breaks when it's trying to fetch historical data:
quantrocket_zipline_1|Traceback (most recent call last):
quantrocket_zipline_1| File "sym://qrocket_app_py", line 807, in post
quantrocket_zipline_1| File "sym://qrocket_qrzipline_backtest_py", line 167, in backtest_algo
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/algorithm.py", line 675, in run
quantrocket_zipline_1| for perf in self.get_generator():
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/gens/tradesimulation.py", line 205, in transform
quantrocket_zipline_1| for capital_change_packet in every_bar(dt):
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/gens/tradesimulation.py", line 133, in every_bar
quantrocket_zipline_1| handle_data(algo, current_data, dt_to_use)
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/utils/events.py", line 218, in handle_data
quantrocket_zipline_1| dt,
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/utils/events.py", line 237, in handle_data
quantrocket_zipline_1| self.callback(context, data)
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/algorithm.py", line 485, in handle_data
quantrocket_zipline_1| self._handle_data(self, data)
quantrocket_zipline_1| File "data_integrity", line 26, in handle_data
quantrocket_zipline_1| File "data_integrity", line 32, in check_data
quantrocket_zipline_1| File "zipline/_protocol.pyx", line 121, in zipline._protocol.check_parameters.__call__.assert_keywords_and_call (zipline/_protocol.c:3824)
quantrocket_zipline_1| File "zipline/_protocol.pyx", line 744, in zipline._protocol.BarData.history (zipline/_protocol.c:9622)
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/data_portal.py", line 974, in get_history_window
quantrocket_zipline_1| field)
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/data_portal.py", line 906, in _get_history_minute_window
quantrocket_zipline_1| minutes_for_window,
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/data_portal.py", line 1063, in _get_minute_window_data
quantrocket_zipline_1| False)
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/history_loader.py", line 549, in history
quantrocket_zipline_1| is_perspective_after)
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/history_loader.py", line 431, in _ensure_sliding_windows
quantrocket_zipline_1| array = self._array(prefetch_dts, needed_assets, field)
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/history_loader.py", line 595, in _array
quantrocket_zipline_1| assets,
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/dispatch_bar_reader.py", line 121, in load_raw_arrays
quantrocket_zipline_1| for t in asset_types if sid_groups[t]}
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/dispatch_bar_reader.py", line 121, in <dictcomp>
quantrocket_flightlog_1|2021-05-16 16:54:16 data_integrity: ERROR Error occurred at timestamp '2021-03-01 07:45:00-06:00' in contract 'Future(QF000000026993 [ESH1])'.
quantrocket_zipline_1| for t in asset_types if sid_groups[t]}
quantrocket_houston_1|172.20.0.12 - - [16/May/2021:16:54:16 +0000] "POST /flightlog/handler HTTP/1.1" 200 5 "-" "-"
quantrocket_zipline_1| File "/opt/conda/lib/python3.6/site-packages/zipline/data/continuous_future_reader.py", line 280, in load_raw_arrays
quantrocket_zipline_1| out[start_loc:end_loc + 1, i] = result
quantrocket_zipline_1|ValueError: could not broadcast input array from shape (1574) into shape (1561)
I've narrowed the problem down to this function: zipline/minute_bars.py at master · quantrocket-llc/zipline · GitHub. It looks like the exclusion tree it builds only accounts for market opens and closes, so when there's a trading halt defined, it doesn't compensate for the shift in the calendar and tries requesting more data than it actually requires in the prefetch. I'm going to tinker with this a bit more to see if I can implement a fix. I'm posting this in case someone else has run into this already.