mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-02 09:19:09 +08:00
ENH: Enable minute bar data with TALib transform.
Add a `bars` keyword arg, as is used with BatchTransform. Also, instead of overwriting the window_length kwarg with timeperiod, always use the lookback value from the created TALib function, as timeperiod will be an input into that value if it exists. Calculate `window_length` in minute mode so that there are enough days to cover the minutes in the timeperiod.
This commit is contained in:
@@ -372,3 +372,24 @@ class TestTALIB(TestCase):
|
||||
talib_data['close'] = data['price'][0].values
|
||||
expected_result = talib_fn(talib_data, **t.call_kwargs)[-1]
|
||||
np.testing.assert_allclose(talib_result, expected_result)
|
||||
|
||||
def test_talib_with_minute_data(self):
|
||||
|
||||
ma_one_day_minutes = ta.MA(timeperiod=10, bars='minute')
|
||||
|
||||
# Assert that the BatchTransform window length is enough to cover
|
||||
# the amount of minutes in the timeperiod.
|
||||
|
||||
# Here, 10 minutes only needs a window length of 1.
|
||||
self.assertEquals(1, ma_one_day_minutes.window_length)
|
||||
|
||||
# With minutes greater than the 390, i.e. one trading day, we should
|
||||
# have a window_length of two days.
|
||||
ma_two_day_minutes = ta.MA(timeperiod=490, bars='minute')
|
||||
self.assertEquals(2, ma_two_day_minutes.window_length)
|
||||
|
||||
# TODO: Ensure that the lookback into the datapanel is returning
|
||||
# expected results.
|
||||
# Requires supplying minute instead of day data to the unit test.
|
||||
# When adding test data, should add more minute events than the
|
||||
# timeperiod to ensure that lookback is behaving properly.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import math
|
||||
|
||||
import numpy as np
|
||||
import talib
|
||||
@@ -86,6 +87,7 @@ def make_transform(talib_fn, name):
|
||||
low='low',
|
||||
volume='volume',
|
||||
refresh_period=0,
|
||||
bars='daily',
|
||||
**kwargs):
|
||||
|
||||
key_map = {'high': high,
|
||||
@@ -94,11 +96,6 @@ def make_transform(talib_fn, name):
|
||||
'volume': volume,
|
||||
'close': close}
|
||||
|
||||
# Rename timeperiod to window_length to conform with
|
||||
# TALib interface.
|
||||
if 'timeperiod' in kwargs:
|
||||
kwargs['window_length'] = kwargs['timeperiod']
|
||||
|
||||
self.call_kwargs = kwargs
|
||||
|
||||
# Make deepcopy of talib abstract function.
|
||||
@@ -119,6 +116,15 @@ def make_transform(talib_fn, name):
|
||||
# get the lookback
|
||||
self.lookback = self.talib_fn.lookback
|
||||
|
||||
self.bars = bars
|
||||
if bars == 'daily':
|
||||
lookback = self.lookback + 1
|
||||
elif bars == 'minute':
|
||||
lookback = int(math.ceil(self.lookback / (6.5 * 60)))
|
||||
|
||||
# Ensure that window_length is at least 1 day's worth of data.
|
||||
window_length = max(lookback, 1)
|
||||
|
||||
def zipline_wrapper(data):
|
||||
# get required TA-Lib input names
|
||||
if 'price' in self.talib_fn.input_names:
|
||||
@@ -157,7 +163,7 @@ def make_transform(talib_fn, name):
|
||||
super(TALibTransform, self).__init__(
|
||||
func=zipline_wrapper,
|
||||
refresh_period=refresh_period,
|
||||
window_length=max(1, self.lookback + 1))
|
||||
window_length=window_length)
|
||||
|
||||
def __repr__(self):
|
||||
return 'Zipline BatchTransform: {0}'.format(
|
||||
|
||||
Reference in New Issue
Block a user