mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-26 13:18:31 +08:00
Merge pull request #1128 from quantopian/remove-extra-parameter-to-position-of-minute
Fix regression on retrieval of minute positions.
This commit is contained in:
@@ -38,8 +38,7 @@ def minute_value(ndarray[long_t, ndim=1] market_opens,
|
||||
def find_position_of_minute(ndarray[long_t, ndim=1] market_opens,
|
||||
ndarray[long_t, ndim=1] market_closes,
|
||||
long_t minute_val,
|
||||
short minutes_per_day,
|
||||
bool adjust_half_day_minutes):
|
||||
short minutes_per_day):
|
||||
"""
|
||||
Finds the position of a given minute in the given array of market opens.
|
||||
If not a market minute, adjusts to the last market minute.
|
||||
@@ -58,26 +57,6 @@ def find_position_of_minute(ndarray[long_t, ndim=1] market_opens,
|
||||
minutes_per_day: int
|
||||
The number of minutes per day (e.g. 390 for NYSE).
|
||||
|
||||
adjust_half_day_minutes: boolean
|
||||
Whether or not we want to adjust non trading minutes to early close on
|
||||
half days as opposed to normal close.
|
||||
|
||||
Further explanation of the use adjust_half_day_minutes:
|
||||
adjust_half_day_minutes=True:
|
||||
We are using this method for the purpose finding a value for a
|
||||
minute, and therefore, all non market minutes must be adjusted to
|
||||
the last available (e.g. 9 pm EST -> 4 pm EST, 2 pm EST -> 1 pm EST
|
||||
on a half day)
|
||||
|
||||
adjust_half_day_minutes=False:
|
||||
We are using this method for the purpose of finding the positions
|
||||
of minutes we want to ignore (1 pm to 4 pm EST on half days).
|
||||
The minute bar reader tape has 390 bars per day, with 0's filled in
|
||||
for the extra bars on half days. If we index a minute between
|
||||
1:01 pm and 4 pm on a half day, we want a position for that
|
||||
unadjusted time, not adjusted to 1 pm as in the above case
|
||||
(e.g. for all days: 9 pm EST -> 4 pm EST, 2 pm EST -> 2 pm EST)
|
||||
|
||||
Returns
|
||||
-------
|
||||
int: The position of the given minute in the market opens array.
|
||||
@@ -89,14 +68,7 @@ def find_position_of_minute(ndarray[long_t, ndim=1] market_opens,
|
||||
market_open = market_opens[market_open_loc]
|
||||
market_close = market_closes[market_open_loc]
|
||||
|
||||
if adjust_half_day_minutes:
|
||||
# The min of the distance to market open from minute_val and number
|
||||
# of trading minutes for that day
|
||||
delta = int_min(minute_val - market_open, market_close - market_open)
|
||||
else:
|
||||
# The min of the distance to market open from minute_val and number
|
||||
# of trading minutes for a normal day (390)
|
||||
delta = int_min(minute_val - market_open, minutes_per_day)
|
||||
delta = int_min(minute_val - market_open, market_close - market_open)
|
||||
|
||||
return (market_open_loc * minutes_per_day) + delta
|
||||
|
||||
@@ -140,7 +112,7 @@ def find_last_traded_position_internal(
|
||||
|
||||
minute_pos = int_min(
|
||||
find_position_of_minute(market_opens, market_closes, end_minute,
|
||||
minutes_per_day, True),
|
||||
minutes_per_day),
|
||||
len(volumes) - 1
|
||||
)
|
||||
|
||||
|
||||
+29
-23
@@ -16,7 +16,7 @@ from textwrap import dedent
|
||||
import bcolz
|
||||
from bcolz import ctable
|
||||
from intervaltree import IntervalTree
|
||||
from numpy import nan_to_num, timedelta64
|
||||
from numpy import nan_to_num
|
||||
from os.path import join
|
||||
import json
|
||||
import os
|
||||
@@ -30,7 +30,7 @@ from zipline.data._minute_bar_internal import (
|
||||
find_last_traded_position_internal
|
||||
)
|
||||
|
||||
from zipline.utils.memoize import remember_last, lazyval
|
||||
from zipline.utils.memoize import lazyval
|
||||
|
||||
US_EQUITIES_MINUTES_PER_DAY = 390
|
||||
|
||||
@@ -618,6 +618,9 @@ class BcolzMinuteBarReader(object):
|
||||
'volume': {},
|
||||
}
|
||||
|
||||
self._last_get_value_dt_position = None
|
||||
self._last_get_value_dt_value = None
|
||||
|
||||
def _get_metadata(self):
|
||||
return BcolzMinuteBarMetadata.read(self._rootdir)
|
||||
|
||||
@@ -646,12 +649,11 @@ class BcolzMinuteBarReader(object):
|
||||
minutes_per_day = (market_closes - market_opens).astype(np.int64)
|
||||
early_indices = np.where(
|
||||
minutes_per_day != US_EQUITIES_MINUTES_PER_DAY - 1)[0]
|
||||
regular_closes = market_opens[early_indices] + timedelta64(
|
||||
US_EQUITIES_MINUTES_PER_DAY - 1, 'm')
|
||||
early_closes = market_closes[early_indices]
|
||||
minutes = [pd.date_range(early, regular, freq='min')
|
||||
for early, regular
|
||||
in zip(early_closes + 1, regular_closes)]
|
||||
early_opens = self._market_opens[early_indices]
|
||||
early_closes = self._market_closes[early_indices]
|
||||
minutes = [(market_open, early_close)
|
||||
for market_open, early_close
|
||||
in zip(early_opens, early_closes)]
|
||||
return minutes
|
||||
|
||||
@lazyval
|
||||
@@ -673,11 +675,15 @@ class BcolzMinuteBarReader(object):
|
||||
because of early closes.
|
||||
"""
|
||||
itree = IntervalTree()
|
||||
for minute_range in self._minutes_to_exclude():
|
||||
# setting adjust_half_day_minutes to False because we want to find
|
||||
# the positions of minutes 211 to 390 on a 390-bar day
|
||||
start_pos = self._find_position_of_minute(minute_range[0], False)
|
||||
end_pos = self._find_position_of_minute(minute_range[-1], False)
|
||||
for market_open, early_close in self._minutes_to_exclude():
|
||||
start_pos = self._find_position_of_minute(early_close) + 1
|
||||
end_pos = (
|
||||
self._find_position_of_minute(market_open)
|
||||
+
|
||||
US_EQUITIES_MINUTES_PER_DAY
|
||||
-
|
||||
1
|
||||
)
|
||||
data = (start_pos, end_pos)
|
||||
itree[start_pos:end_pos + 1] = data
|
||||
return itree
|
||||
@@ -744,7 +750,13 @@ class BcolzMinuteBarReader(object):
|
||||
Returns the integer value of the volume.
|
||||
(A volume of 0 signifies no trades for the given dt.)
|
||||
"""
|
||||
minute_pos = self._find_position_of_minute(dt, True)
|
||||
if self._last_get_value_dt_value == dt.value:
|
||||
minute_pos = self._last_get_value_dt_position
|
||||
else:
|
||||
minute_pos = self._find_position_of_minute(dt)
|
||||
self._last_get_value_dt_value = dt.value
|
||||
self._last_get_value_dt_position = minute_pos
|
||||
|
||||
value = self._open_minute_file(field, sid)[minute_pos]
|
||||
if value == 0:
|
||||
if field == 'volume':
|
||||
@@ -787,8 +799,7 @@ class BcolzMinuteBarReader(object):
|
||||
|
||||
return pd.Timestamp(minute_epoch, tz='UTC', unit="m")
|
||||
|
||||
@remember_last
|
||||
def _find_position_of_minute(self, minute_dt, adjust_half_day_minutes):
|
||||
def _find_position_of_minute(self, minute_dt):
|
||||
"""
|
||||
Internal method that returns the position of the given minute in the
|
||||
list of every trading minute since market open of the first trading
|
||||
@@ -802,10 +813,6 @@ class BcolzMinuteBarReader(object):
|
||||
minute_dt: pd.Timestamp
|
||||
The minute whose position should be calculated.
|
||||
|
||||
adjust_half_day_minutes: boolean
|
||||
Whether or not we want to adjust minutes to early close on half
|
||||
days.
|
||||
|
||||
Returns
|
||||
-------
|
||||
int: The position of the given minute in the list of all trading
|
||||
@@ -816,7 +823,6 @@ class BcolzMinuteBarReader(object):
|
||||
self._market_close_values,
|
||||
minute_dt.value / NANOS_IN_MINUTE,
|
||||
US_EQUITIES_MINUTES_PER_DAY,
|
||||
adjust_half_day_minutes
|
||||
)
|
||||
|
||||
def unadjusted_window(self, fields, start_dt, end_dt, sids):
|
||||
@@ -839,8 +845,8 @@ class BcolzMinuteBarReader(object):
|
||||
(sids, minutes in range) with a dtype of float64, containing the
|
||||
values for the respective field over start and end dt range.
|
||||
"""
|
||||
start_idx = self._find_position_of_minute(start_dt, True)
|
||||
end_idx = self._find_position_of_minute(end_dt, True)
|
||||
start_idx = self._find_position_of_minute(start_dt)
|
||||
end_idx = self._find_position_of_minute(end_dt)
|
||||
|
||||
num_minutes = (end_idx - start_idx + 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user