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:
Eddie Hebert
2013-07-09 11:26:26 -04:00
parent 5fb837bf37
commit 3d8bdeb429
2 changed files with 33 additions and 6 deletions
+21
View File
@@ -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
View File
@@ -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(