tests.TestTALIB.test_talib_with_minute_data()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 14
rs 9.4286
1
#
2
# Copyright 2013 Quantopian, Inc.
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
import pytz
17
import numpy as np
18
import pandas as pd
19
import talib
20
21
from datetime import timedelta, datetime
22
from unittest import TestCase, skip
23
24
from zipline.utils.test_utils import setup_logger, teardown_logger
25
26
import zipline.utils.factory as factory
27
from zipline.finance.trading import TradingEnvironment
28
29
from zipline.test_algorithms import TALIBAlgorithm
30
31
import zipline.transforms.ta as ta
32
33
34
class TestTALIB(TestCase):
35
36
    @classmethod
37
    def setUpClass(cls):
38
        cls.env = TradingEnvironment()
39
40
    @classmethod
41
    def tearDownClass(cls):
42
        del cls.env
43
44
    def setUp(self):
45
        setup_logger(self)
46
        sim_params = factory.create_simulation_parameters(
47
            start=datetime(1990, 1, 1, tzinfo=pytz.utc),
48
            end=datetime(1990, 3, 30, tzinfo=pytz.utc))
49
        self.source, self.panel = \
50
            factory.create_test_panel_ohlc_source(sim_params, self.env)
51
52
    def tearDown(self):
53
        teardown_logger(self)
54
55
    @skip
56
    def test_talib_with_default_params(self):
57
        BLACKLIST = ['make_transform', 'BatchTransform',
58
                     # TODO: Figure out why MAVP generates a KeyError
59
                     'MAVP']
60
        names = [name for name in dir(ta)
61
                 if name[0].isupper() and name not in BLACKLIST]
62
63
        for name in names:
64
            print(name)
65
            zipline_transform = getattr(ta, name)(sid=0)
66
            talib_fn = getattr(talib.abstract, name)
67
68
            start = datetime(1990, 1, 1, tzinfo=pytz.utc)
69
            end = start + timedelta(days=zipline_transform.lookback + 10)
70
            sim_params = factory.create_simulation_parameters(
71
                start=start, end=end)
72
            source, panel = \
73
                factory.create_test_panel_ohlc_source(sim_params, self.env)
74
75
            algo = TALIBAlgorithm(talib=zipline_transform)
76
            algo.run(source)
77
78
            zipline_result = np.array(
79
                algo.talib_results[zipline_transform][-1])
80
81
            talib_data = dict()
82
            data = zipline_transform.window
83
            # TODO: Figure out if we are clobbering the tests by this
84
            # protection against empty windows
85
            if not data:
86
                continue
87
            for key in ['open', 'high', 'low', 'volume']:
88
                if key in data:
89
                    talib_data[key] = data[key][0].values
90
            talib_data['close'] = data['price'][0].values
91
            expected_result = talib_fn(talib_data)
92
93
            if isinstance(expected_result, list):
94
                expected_result = np.array([e[-1] for e in expected_result])
95
            else:
96
                expected_result = np.array(expected_result[-1])
97
            if not (np.all(np.isnan(zipline_result)) and
98
                    np.all(np.isnan(expected_result))):
99
                self.assertTrue(np.allclose(zipline_result, expected_result))
100
            else:
101
                print('--- NAN')
102
103
            # reset generator so next iteration has data
104
            # self.source, self.panel = \
105
                # factory.create_test_panel_ohlc_source(self.sim_params)
106
107
    def test_multiple_talib_with_args(self):
108
        zipline_transforms = [ta.MA(timeperiod=10),
109
                              ta.MA(timeperiod=25)]
110
        talib_fn = talib.abstract.MA
111
        algo = TALIBAlgorithm(talib=zipline_transforms, identifiers=[0])
112
        algo.run(self.source)
113
        # Test if computed values match those computed by pandas rolling mean.
114
        sid = 0
115
        talib_values = np.array([x[sid] for x in
116
                                 algo.talib_results[zipline_transforms[0]]])
117
        np.testing.assert_array_equal(talib_values,
118
                                      pd.rolling_mean(self.panel[0]['price'],
119
                                                      10).values)
120
        talib_values = np.array([x[sid] for x in
121
                                 algo.talib_results[zipline_transforms[1]]])
122
        np.testing.assert_array_equal(talib_values,
123
                                      pd.rolling_mean(self.panel[0]['price'],
124
                                                      25).values)
125
        for t in zipline_transforms:
126
            talib_result = np.array(algo.talib_results[t][-1])
127
            talib_data = dict()
128
            data = t.window
129
            # TODO: Figure out if we are clobbering the tests by this
130
            # protection against empty windows
131
            if not data:
132
                continue
133
            for key in ['open', 'high', 'low', 'volume']:
134
                if key in data:
135
                    talib_data[key] = data[key][0].values
136
            talib_data['close'] = data['price'][0].values
137
            expected_result = talib_fn(talib_data, **t.call_kwargs)[-1]
138
            np.testing.assert_allclose(talib_result, expected_result)
139
140
    def test_talib_with_minute_data(self):
141
142
        ma_one_day_minutes = ta.MA(timeperiod=10, bars='minute')
143
144
        # Assert that the BatchTransform window length is enough to cover
145
        # the amount of minutes in the timeperiod.
146
147
        # Here, 10 minutes only needs a window length of 1.
148
        self.assertEquals(1, ma_one_day_minutes.window_length)
149
150
        # With minutes greater than the 390, i.e. one trading day, we should
151
        # have a window_length of two days.
152
        ma_two_day_minutes = ta.MA(timeperiod=490, bars='minute')
153
        self.assertEquals(2, ma_two_day_minutes.window_length)
154
155
        # TODO: Ensure that the lookback into the datapanel is returning
156
        # expected results.
157
        # Requires supplying minute instead of day data to the unit test.
158
        # When adding test data, should add more minute events than the
159
        # timeperiod to ensure that lookback is behaving properly.
160