mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-04 15:55:46 +08:00
BUG: History no longer fails on length-1 '1m' price-only HistorySpecs
The bug occurred because there is a special case in the initial window setup code for handling the case where only a length-1 history is used for a given frequency. Previously, the code was incorrectly calculating the period end using a hard-coded expression for the end of the day (the correct behavior for a length-1 '1d' history), and then using the frequency object to calculate the period start for the window. In the case of length 1 '1m' data, this resulted in an initial window whose start and end was the last minute of the day rather than the first minute of the day. For non-price fields, this error doesn't matter, because the window is only used for rolling digests (which doesn't happen when there's only a length-1 history), and for the forward-filling logic (which only happens on price fields). For a length-1 '1m' price, however, the incorrect window causes us to attempt to forward-fill an empty panel, resulting in an IndexError when we do an iloc[0] on a length-0 axis.
This commit is contained in:
@@ -44,6 +44,9 @@ def mixed_frequency_expected_data(count, frequency):
|
||||
MIXED_FREQUENCY_MINUTES = TradingEnvironment.instance().market_minute_window(
|
||||
to_utc('2013-07-03 9:31AM'), 600,
|
||||
)
|
||||
ONE_MINUTE_PRICE_ONLY_SPECS = [
|
||||
HistorySpec(1, '1m', 'price', True),
|
||||
]
|
||||
DAILY_OPEN_CLOSE_SPECS = [
|
||||
HistorySpec(3, '1d', 'open_price', False),
|
||||
HistorySpec(3, '1d', 'close_price', False),
|
||||
@@ -77,6 +80,55 @@ HISTORY_CONTAINER_TEST_CASES = {
|
||||
# 23 24 25 26 27 28 29
|
||||
# 30
|
||||
|
||||
'test one minute price only': {
|
||||
# A list of HistorySpec objects.
|
||||
'specs': ONE_MINUTE_PRICE_ONLY_SPECS,
|
||||
# Sids for the test.
|
||||
'sids': [1],
|
||||
# Start date for test.
|
||||
'dt': to_utc('2013-06-21 9:31AM'),
|
||||
# Sequency of updates to the container
|
||||
'updates': [
|
||||
BarData(
|
||||
{
|
||||
1: {
|
||||
'price': 5,
|
||||
'dt': to_utc('2013-06-21 9:31AM'),
|
||||
},
|
||||
},
|
||||
),
|
||||
BarData(
|
||||
{
|
||||
1: {
|
||||
'price': 6,
|
||||
'dt': to_utc('2013-06-21 9:32AM'),
|
||||
},
|
||||
},
|
||||
),
|
||||
],
|
||||
# Expected results
|
||||
'expected': {
|
||||
ONE_MINUTE_PRICE_ONLY_SPECS[0].key_str: [
|
||||
pd.DataFrame(
|
||||
data={
|
||||
1: [5],
|
||||
},
|
||||
index=[
|
||||
to_utc('2013-06-21 9:31AM'),
|
||||
],
|
||||
),
|
||||
pd.DataFrame(
|
||||
data={
|
||||
1: [6],
|
||||
},
|
||||
index=[
|
||||
to_utc('2013-06-21 9:32AM'),
|
||||
],
|
||||
),
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
'test daily open close': {
|
||||
# A list of HistorySpec objects.
|
||||
'specs': DAILY_OPEN_CLOSE_SPECS,
|
||||
|
||||
@@ -23,7 +23,6 @@ from . history import (
|
||||
index_at_dt,
|
||||
)
|
||||
|
||||
from zipline.finance import trading
|
||||
from zipline.utils.data import RollingPanel
|
||||
|
||||
|
||||
@@ -206,13 +205,14 @@ class HistoryContainer(object):
|
||||
# requiring the largest number of bars.
|
||||
largest_spec = specs[-1]
|
||||
if largest_spec.bar_count == 1:
|
||||
|
||||
# No need to allocate a digest panel; this frequency will only
|
||||
# ever use data drawn from self.buffer_panel.
|
||||
env = trading.environment
|
||||
first_window_closes[freq] = \
|
||||
env.get_open_and_close(initial_dt)[1]
|
||||
first_window_starts[freq] = \
|
||||
freq.window_open(first_window_closes[freq])
|
||||
first_window_starts[freq] = freq.window_open(initial_dt)
|
||||
first_window_closes[freq] = freq.window_close(
|
||||
first_window_starts[freq]
|
||||
)
|
||||
|
||||
continue
|
||||
|
||||
initial_dates = index_at_dt(largest_spec, initial_dt)
|
||||
|
||||
Reference in New Issue
Block a user