from collections import namedtuple
from datetime import datetime
from itertools import product
import numpy as np
import pandas as pd
import pytest
from numba import njit
import vectorbt as vbt
ray_available = True
try:
import ray
except:
ray_available = False
ta_available = True
try:
import ta
except:
ta_available = False
pandas_ta_available = True
try:
import pandas_ta
except:
try:
import pandas_ta_classic as pandas_ta
except:
pandas_ta_available = False
talib_available = True
try:
import talib
except:
talib_available = False
seed = 42
def setup_module():
vbt.settings.numba['check_func_suffix'] = True
vbt.settings.caching.enabled = False
vbt.settings.caching.whitelist = []
vbt.settings.caching.blacklist = []
if ray_available:
ray.init(local_mode=True, num_cpus=1)
def teardown_module():
if ray_available:
ray.shutdown()
vbt.settings.reset()
ts = pd.DataFrame({
'a': [1., 2., 3., 4., 5.],
'b': [5., 4., 3., 2., 1.],
'c': [1., 2., 3., 2., 1.]
}, index=pd.DatetimeIndex([
datetime(2018, 1, 1),
datetime(2018, 1, 2),
datetime(2018, 1, 3),
datetime(2018, 1, 4),
datetime(2018, 1, 5)
]))
class TestFactory:
def test_config(self, tmp_path):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def apply_func(ts, p, a, b=10):
return ts * p + a + b
I = F.from_apply_func(apply_func, var_args=True)
indicator = I.run(ts, [0, 1], 10, b=100)
assert I.loads(indicator.dumps()) == indicator
indicator.save(tmp_path / 'indicator')
assert I.load(tmp_path / 'indicator') == indicator
def test_from_custom_func(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def apply_func(i, ts, p, a, b=10):
return ts * p[i] + a + b
@njit
def apply_func_nb(i, ts, p, a, b):
return ts * p[i] + a + b
def custom_func(ts, p, *args, **kwargs):
return vbt.base.combine_fns.apply_and_concat_one(len(p), apply_func, ts, p, *args, **kwargs)
@njit
def custom_func_nb(ts, p, *args):
return vbt.base.combine_fns.apply_and_concat_one_nb(len(p), apply_func_nb, ts, p, *args)
target = pd.DataFrame(
np.array([
[110., 110., 110., 111., 115., 111.],
[110., 110., 110., 112., 114., 112.],
[110., 110., 110., 113., 113., 113.],
[110., 110., 110., 114., 112., 112.],
[110., 110., 110., 115., 111., 111.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func, var_args=True).run(ts, [0, 1], 10, b=100).out,
target
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func_nb, var_args=True).run(ts, [0, 1], 10, 100).out,
target
)
target = pd.DataFrame(
np.array([
[110., 115., 112.],
[110., 114., 114.],
[110., 113., 116.],
[110., 112., 114.],
[110., 111., 112.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(1, 'b'),
(2, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func, var_args=True).run(ts, [0, 1, 2], 10, b=100, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func_nb, var_args=True).run(ts, [0, 1, 2], 10, 100, per_column=True).out,
target
)
target = pd.DataFrame(
np.array([
[110., 111.],
[110., 112.],
[110., 113.],
[110., 114.],
[110., 115.]
]),
index=ts.index,
columns=pd.Index([0, 1], dtype='int64', name='custom_p')
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func, var_args=True).run(ts['a'], [0, 1], 10, b=100).out,
target
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func_nb, var_args=True).run(ts['a'], [0, 1], 10, 100).out,
target
)
target = pd.DataFrame(
np.array([
[110.],
[110.],
[110.],
[110.],
[110.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([(0, 'a')], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func, var_args=True).run(ts[['a']], 0, 10, b=100, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func_nb, var_args=True).run(ts[['a']], 0, 10, 100, per_column=True).out,
target
)
target = pd.Series(
np.array([110., 110., 110., 110., 110.]),
index=ts.index,
name=(0, 'a')
)
pd.testing.assert_series_equal(
F.from_custom_func(custom_func, var_args=True).run(ts['a'], 0, 10, b=100).out,
target
)
pd.testing.assert_series_equal(
F.from_custom_func(custom_func_nb, var_args=True).run(ts['a'], 0, 10, 100).out,
target
)
pd.testing.assert_series_equal(
F.from_custom_func(custom_func, var_args=True).run(ts['a'], 0, 10, b=100, per_column=True).out,
target
)
pd.testing.assert_series_equal(
F.from_custom_func(custom_func_nb, var_args=True).run(ts['a'], 0, 10, 100, per_column=True).out,
target
)
def test_from_apply_func(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def apply_func(ts, p, a, b=10):
return ts * p + a + b
@njit
def apply_func_nb(ts, p, a, b):
return ts * p + a + b
target = pd.DataFrame(
np.array([
[110., 110., 110., 111., 115., 111.],
[110., 110., 110., 112., 114., 112.],
[110., 110., 110., 113., 113., 113.],
[110., 110., 110., 114., 112., 112.],
[110., 110., 110., 115., 111., 111.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, var_args=True).run(ts, [0, 1], 10, b=100).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, var_args=True).run(ts, [0, 1], 10, 100).out,
target
)
target = pd.DataFrame(
np.array([
[110., 115., 112.],
[110., 114., 114.],
[110., 113., 116.],
[110., 112., 114.],
[110., 111., 112.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(1, 'b'),
(2, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, var_args=True).run(ts, [0, 1, 2], 10, b=100, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, var_args=True).run(ts, [0, 1, 2], 10, 100, per_column=True).out,
target
)
target = pd.DataFrame(
np.array([
[110., 111.],
[110., 112.],
[110., 113.],
[110., 114.],
[110., 115.]
]),
index=ts.index,
columns=pd.Index([0, 1], dtype='int64', name='custom_p')
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, var_args=True).run(ts['a'], [0, 1], 10, b=100).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, var_args=True).run(ts['a'], [0, 1], 10, 100).out,
target
)
target = pd.DataFrame(
np.array([
[110.],
[110.],
[110.],
[110.],
[110.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([(0, 'a')], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, var_args=True).run(ts[['a']], 0, 10, b=100, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, var_args=True).run(ts[['a']], 0, 10, 100, per_column=True).out,
target
)
target = pd.Series(
np.array([110., 110., 110., 110., 110.]),
index=ts.index,
name=(0, 'a')
)
pd.testing.assert_series_equal(
F.from_apply_func(apply_func, var_args=True).run(ts['a'], 0, 10, b=100).out,
target
)
pd.testing.assert_series_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, var_args=True)
.run(ts['a'], 0, 10, 100).out,
target
)
pd.testing.assert_series_equal(
F.from_apply_func(apply_func, var_args=True).run(ts['a'], 0, 10, b=100, per_column=True).out,
target
)
pd.testing.assert_series_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, var_args=True)
.run(ts['a'], 0, 10, 100, per_column=True).out,
target
)
def test_use_ray(self):
if ray_available:
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def apply_func(ts, p, a, b=10):
return ts * p + a + b
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, var_args=True)
.run(ts, np.arange(10), 10, b=100).out,
F.from_apply_func(apply_func, var_args=True)
.run(ts, np.arange(10), 10, b=100, use_ray=True).out,
)
def test_no_inputs(self):
F = vbt.IndicatorFactory(param_names=['p'], output_names=['out'])
def apply_func(p):
return np.full((3, 3), p)
@njit
def apply_func_nb(p):
return np.full((3, 3), p)
target = pd.DataFrame(
np.array([
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1]
]),
index=pd.RangeIndex(start=0, stop=3, step=1),
columns=pd.MultiIndex.from_tuples([
(0, 0),
(0, 1),
(0, 2),
(1, 0),
(1, 1),
(1, 2)
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run([0, 1]).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run([0, 1]).out,
target
)
with pytest.raises(Exception):
F.from_apply_func(apply_func).run([0, 1], per_column=True)
def test_input_shape(self):
F = vbt.IndicatorFactory(param_names=['p'], output_names=['out'])
def apply_func(input_shape, p):
return np.full(input_shape, p)
@njit
def apply_func_nb(input_shape, p):
return np.full(input_shape, p)
target = pd.Series(
np.array([0, 0, 0, 0, 0]),
index=pd.RangeIndex(start=0, stop=5, step=1)
)
pd.testing.assert_series_equal(
F.from_apply_func(apply_func, require_input_shape=True).run(5, 0).out,
target
)
pd.testing.assert_series_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, require_input_shape=True).run(5, 0).out,
target
)
target = pd.DataFrame(
np.array([
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1]
]),
index=pd.RangeIndex(start=0, stop=5, step=1),
columns=pd.Index([0, 1], dtype='int64', name='custom_p')
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, require_input_shape=True).run(5, [0, 1]).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, require_input_shape=True).run(5, [0, 1]).out,
target
)
target = pd.DataFrame(
np.array([
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, require_input_shape=True).run(
(5, 3), [0, 1], input_index=ts.index, input_columns=ts.columns).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, require_input_shape=True).run(
(5, 3), [0, 1], input_index=ts.index, input_columns=ts.columns).out,
target
)
target = pd.DataFrame(
np.array([
[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(1, 'b'),
(2, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, require_input_shape=True).run(
(5, 3), [0, 1, 2], input_index=ts.index, input_columns=ts.columns, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, require_input_shape=True).run(
(5, 3), [0, 1, 2], input_index=ts.index, input_columns=ts.columns, per_column=True).out,
target
)
def test_multiple_inputs(self):
F = vbt.IndicatorFactory(input_names=['ts1', 'ts2'], param_names=['p'], output_names=['out'])
def apply_func(ts1, ts2, p):
return ts1 * ts2 * p
@njit
def apply_func_nb(ts1, ts2, p):
return ts1 * ts2 * p
target = pd.DataFrame(
np.array([
[0., 0., 0., 1., 25., 1.],
[0., 0., 0., 4., 16., 4.],
[0., 0., 0., 9., 9., 9.],
[0., 0., 0., 16., 4., 4.],
[0., 0., 0., 25., 1., 1.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, ts, [0, 1]).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, ts, [0, 1]).out,
target
)
target = pd.DataFrame(
np.array([
[0., 25., 2.],
[0., 16., 8.],
[0., 9., 18.],
[0., 4., 8.],
[0., 1., 2.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(1, 'b'),
(2, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, ts, [0, 1, 2], per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, ts, [0, 1, 2], per_column=True).out,
target
)
def test_no_params(self):
F = vbt.IndicatorFactory(input_names=['ts'], output_names=['out'])
def apply_func(ts):
return ts * 2
@njit
def apply_func_nb(ts):
return ts * 2
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts).out,
ts * 2
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts).out,
ts * 2
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, per_column=True).out,
ts * 2
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, per_column=True).out,
ts * 2
)
def test_no_inputs_and_params(self):
F = vbt.IndicatorFactory(output_names=['out'])
def apply_func():
return np.full((3, 3), 1)
@njit
def apply_func_nb():
return np.full((3, 3), 1)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run().out,
pd.DataFrame(np.full((3, 3), 1))
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run().out,
pd.DataFrame(np.full((3, 3), 1))
)
with pytest.raises(Exception):
F.from_apply_func(apply_func).run(per_column=True)
def test_multiple_params(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
def apply_func(ts, p1, p2):
return ts * (p1 + p2)
@njit
def apply_func_nb(ts, p1, p2):
return ts * (p1 + p2)
target = pd.DataFrame(
np.array([
[2., 10., 2., 3., 15., 3.],
[4., 8., 4., 6., 12., 6.],
[6., 6., 6., 9., 9., 9.],
[8., 4., 4., 12., 6., 6.],
[10., 2., 2., 15., 3., 3.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 2, 'a'),
(0, 2, 'b'),
(0, 2, 'c'),
(1, 2, 'a'),
(1, 2, 'b'),
(1, 2, 'c')
], names=['custom_p1', 'custom_p2', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1]), 2).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, np.asarray([0, 1]), 2).out,
target
)
target = pd.DataFrame(
np.array([
[2., 15., 4.],
[4., 12., 8.],
[6., 9., 12.],
[8., 6., 8.],
[10., 3., 4.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 2, 'a'),
(1, 2, 'b'),
(2, 2, 'c')
], names=['custom_p1', 'custom_p2', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1, 2]), 2, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, np.asarray([0, 1, 2]), 2, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1, 2]), [2], per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1, 2]), np.array([2]), per_column=True).out,
target
)
with pytest.raises(Exception):
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1]), 2, per_column=True)
with pytest.raises(Exception):
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1, 2, 3]), 2, per_column=True)
def test_param_settings(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def apply_func(ts, p):
return ts * p
@njit
def apply_func_nb(ts, p):
return ts * p
target = pd.DataFrame(
np.array([
[0., 5., 2.],
[0., 4., 4.],
[0., 3., 6.],
[0., 2., 4.],
[0., 1., 2.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
('array_0', 'a'),
('array_0', 'b'),
('array_0', 'c'),
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1, 2]), param_settings={'p': {
'is_array_like': True
}}).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, np.asarray([0, 1, 2]), param_settings={'p': {
'is_array_like': True
}}).out,
target
)
target = pd.DataFrame(
np.array([
[0., 5., 2.],
[0., 4., 4.],
[0., 3., 6.],
[0., 2., 4.],
[0., 1., 2.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(1, 'b'),
(2, 'c'),
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, np.asarray([0, 1, 2]), param_settings={'p': {
'is_array_like': True,
'bc_to_input': 1,
'per_column': True
}}).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, np.asarray([0, 1, 2]), param_settings={'p': {
'is_array_like': True,
'bc_to_input': 1,
'per_column': True
}}).out,
target
)
def apply_func2(ts, p):
return ts * np.expand_dims(p, 1)
@njit
def apply_func2_nb(ts, p):
return ts * np.expand_dims(p, 1)
target = pd.DataFrame(
np.array([
[0., 0., 0.],
[2., 4., 2.],
[6., 6., 6.],
[12., 6., 6.],
[20., 4., 4.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
('array_0', 'a'),
('array_0', 'b'),
('array_0', 'c'),
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func2).run(ts, np.asarray([0, 1, 2, 3, 4]), param_settings={'p': {
'is_array_like': True,
'bc_to_input': 0
}}).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func2_nb).run(ts, np.asarray([0, 1, 2, 3, 4]), param_settings={'p': {
'is_array_like': True,
'bc_to_input': 0
}}).out,
target
)
def apply_func3(ts, p):
return ts * (p[0] + p[1])
@njit
def apply_func3_nb(ts, p):
return ts * (p[0] + p[1])
target = pd.DataFrame(
np.array([
[1., 5., 1.],
[2., 4., 2.],
[3., 3., 3.],
[4., 2., 2.],
[5., 1., 1.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
('tuple_0', 'a'),
('tuple_0', 'b'),
('tuple_0', 'c'),
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func3).run(ts, (0, 1), param_settings={'p': {
'is_tuple': True
}}).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func3_nb).run(ts, (0, 1), param_settings={'p': {
'is_tuple': True
}}).out,
target
)
def test_param_product(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
def apply_func(ts, p1, p2):
return ts * (p1 + p2)
@njit
def apply_func_nb(ts, p1, p2):
return ts * (p1 + p2)
target = pd.DataFrame(
np.array([
[2., 10., 2., 3., 15., 3., 3., 15., 3., 4., 20., 4.],
[4., 8., 4., 6., 12., 6., 6., 12., 6., 8., 16., 8.],
[6., 6., 6., 9., 9., 9., 9., 9., 9., 12., 12., 12.],
[8., 4., 4., 12., 6., 6., 12., 6., 6., 16., 8., 8.],
[10., 2., 2., 15., 3., 3., 15., 3., 3., 20., 4., 4.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 2, 'a'),
(0, 2, 'b'),
(0, 2, 'c'),
(0, 3, 'a'),
(0, 3, 'b'),
(0, 3, 'c'),
(1, 2, 'a'),
(1, 2, 'b'),
(1, 2, 'c'),
(1, 3, 'a'),
(1, 3, 'b'),
(1, 3, 'c')
], names=['custom_p1', 'custom_p2', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [0, 1], [2, 3], param_product=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, [0, 1], [2, 3], param_product=True).out,
target
)
def test_default(self):
F = vbt.IndicatorFactory(
input_names=['ts1', 'ts2'],
param_names=['p1', 'p2'],
in_output_names=['in_out1', 'in_out2'],
output_names=['out']
)
def apply_func(ts1, ts2, in_out1, in_out2, p1, p2):
in_out1[::2] = ts1[::2] * ts2[::2] * (p1 + p2)
in_out2[::2] = ts1[::2] * ts2[::2] * (p1 + p2)
return ts1 * ts2 * (p1 + p2)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, ts2=0).run(ts, [1, 2], 3).out,
F.from_apply_func(apply_func).run(ts, 0, [1, 2], 3).out
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, ts2='ts1').run(ts, [1, 2], 3).out,
F.from_apply_func(apply_func).run(ts, ts, [1, 2], 3).out
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, p2=0, hide_default=False)
.run(ts, ts, [1, 2]).out,
F.from_apply_func(apply_func, hide_default=False)
.run(ts, ts, [1, 2], 0).out
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, p2='p1', hide_default=False)
.run(ts, ts, [1, 2]).out,
F.from_apply_func(apply_func, hide_default=False)
.run(ts, ts, [1, 2], [1, 2]).out
)
with pytest.raises(Exception):
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, in_out1=1, in_out2=2)
.run(ts, ts, [1, 2], 3).in_out1,
F.from_apply_func(apply_func, in_out1=1, in_out2=2)
.run(ts, ts, [1, 2], 3).in_out2
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, in_out1=1, in_out2='in_out1')
.run(ts, ts, [1, 2], 3).in_out2,
F.from_apply_func(apply_func, in_out1=1, in_out2=1)
.run(ts, ts, [1, 2], 3).in_out2
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, in_out1=1, in_out2='ts1')
.run(ts, ts, [1, 2], 3).in_out2,
F.from_apply_func(apply_func, in_out1=1, in_out2=ts)
.run(ts, ts, [1, 2], 3).in_out2
)
def test_hide_params(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
assert F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2, hide_params=[]) \
.run(ts, [0, 1], 2) \
.out.columns.names == ['custom_p1', 'custom_p2', None]
assert F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2, hide_params=['p2']) \
.run(ts, [0, 1], 2) \
.out.columns.names == ['custom_p1', None]
def test_hide_default(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
assert F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2, p2=2, hide_default=False) \
.run(ts, [0, 1]) \
.out.columns.names == ['custom_p1', 'custom_p2', None]
assert F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2, p2=2, hide_default=True) \
.run(ts, [0, 1]) \
.out.columns.names == ['custom_p1', None]
def test_multiple_outputs(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['o1', 'o2'])
def apply_func(ts, p):
return (ts * p, (ts * p) ** 2)
@njit
def apply_func_nb(ts, p):
return (ts * p, (ts * p) ** 2)
target = pd.DataFrame(
np.array([
[0., 0., 0., 1., 5., 1.],
[0., 0., 0., 2., 4., 2.],
[0., 0., 0., 3., 3., 3.],
[0., 0., 0., 4., 2., 2.],
[0., 0., 0., 5., 1., 1.]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [0, 1]).o1,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, [0, 1]).o1,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts.vbt.tile(2), [0, 0, 0, 1, 1, 1], per_column=True).o1,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True)
.run(ts.vbt.tile(2), [0, 0, 0, 1, 1, 1], per_column=True).o1,
target
)
target = pd.DataFrame(
np.array([
[0., 0., 0., 1., 25., 1.],
[0., 0., 0., 4., 16., 4.],
[0., 0., 0., 9., 9., 9.],
[0., 0., 0., 16., 4., 4.],
[0., 0., 0., 25., 1., 1.]
]),
index=target.index,
columns=target.columns
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [0, 1]).o2,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, [0, 1]).o2,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts.vbt.tile(2), [0, 0, 0, 1, 1, 1], per_column=True).o2,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True)
.run(ts.vbt.tile(2), [0, 0, 0, 1, 1, 1], per_column=True).o2,
target
)
def test_in_outputs(self):
F = vbt.IndicatorFactory(
input_names=['ts'], param_names=['p'],
output_names=['out'], in_output_names=['in_out']
)
def apply_func(ts, in_out, p):
in_out[:, 0] = p
return ts * p
@njit
def apply_func_nb(ts, in_out, p):
in_out[:, 0] = p
return ts * p
target = pd.DataFrame(
np.array([
[0, -1, -1, 1, -1, -1],
[0, -1, -1, 1, -1, -1],
[0, -1, -1, 1, -1, -1],
[0, -1, -1, 1, -1, -1],
[0, -1, -1, 1, -1, -1]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
assert F.from_apply_func(apply_func).run(ts, [0, 1])._in_out.dtype == np.float64
assert F.from_apply_func(apply_func, in_output_settings={'in_out': {'dtype': np.int64}}) \
.run(ts, [0, 1])._in_out.dtype == np.int64
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, in_out=-1).run(ts, [0, 1]).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, in_out=-1).run(ts, [0, 1]).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [0, 1], in_out=-1).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, [0, 1], in_out=-1).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [0, 1], in_out=np.full(ts.shape, -1, dtype=int)).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True)
.run(ts, [0, 1], in_out=np.full(ts.shape, -1, dtype=int)).in_out,
target
)
target = pd.DataFrame(
np.array([
[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(1, 'b'),
(2, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [0, 1, 2], in_out=-1, per_column=True).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True).run(ts, [0, 1, 2], in_out=-1, per_column=True).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func)
.run(ts, [0, 1, 2], in_out=np.full(ts.shape, -1, dtype=int), per_column=True).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True)
.run(ts, [0, 1, 2], in_out=np.full(ts.shape, -1, dtype=int), per_column=True).in_out,
target
)
def test_no_outputs(self):
F = vbt.IndicatorFactory(
param_names=['p'], in_output_names=['in_out']
)
def apply_func(in_out, p):
in_out[:] = p
@njit
def apply_func_nb(in_out, p):
in_out[:] = p
target = pd.DataFrame(
np.array([
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, in_output_settings=dict(in_out=dict(dtype=np.int64)))
.run([0, 1], input_shape=ts.shape, input_index=ts.index, input_columns=ts.columns).in_out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, in_output_settings=dict(in_out=dict(dtype=np.int64)))
.run([0, 1], input_shape=ts.shape, input_index=ts.index, input_columns=ts.columns).in_out,
target
)
def test_kwargs_to_args(self):
F = vbt.IndicatorFactory(input_names=['ts'], output_names=['out'])
def apply_func(ts, kw):
return ts * kw
@njit
def apply_func_nb(ts, kw):
return ts * kw
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func, kwargs_to_args=['kw']).run(ts, kw=2).out,
ts * 2
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func_nb, numba_loop=True, kwargs_to_args=['kw']).run(ts, kw=2).out,
ts * 2
)
def test_cache(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def cache_func(ts, ps):
np.random.seed(seed)
return np.random.uniform(0, 1)
@njit
def cache_func_nb(ts, ps):
np.random.seed(seed)
return np.random.uniform(0, 1)
def apply_func(ts, p, c):
return ts * p + c
@njit
def apply_func_nb(ts, p, c):
return ts * p + c
target = pd.DataFrame(
np.array([
[0.37454012, 0.37454012, 0.37454012, 1.37454012, 5.37454012, 1.37454012],
[0.37454012, 0.37454012, 0.37454012, 2.37454012, 4.37454012, 2.37454012],
[0.37454012, 0.37454012, 0.37454012, 3.37454012, 3.37454012, 3.37454012],
[0.37454012, 0.37454012, 0.37454012, 4.37454012, 2.37454012, 2.37454012],
[0.37454012, 0.37454012, 0.37454012, 5.37454012, 1.37454012, 1.37454012]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func,
cache_func=cache_func
).run(ts, [0, 1]).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func_nb,
cache_func=cache_func_nb
).run(ts, [0, 1]).out,
target
)
cache = F.from_apply_func(
apply_func,
cache_func=cache_func
).run(ts, [0, 1], return_cache=True)
assert cache == 0.3745401188473625
cache = F.from_apply_func(
apply_func_nb,
cache_func=cache_func_nb
).run(ts, [0, 1], return_cache=True)
assert cache == 0.3745401188473625
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func
).run(ts, [0, 1], use_cache=cache).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func_nb
).run(ts, [0, 1], use_cache=cache).out,
target
)
def cache_func(col, ts, ps):
np.random.seed(seed + col)
return np.random.uniform(0, 1)
@njit
def cache_func_nb(col, ts, ps):
np.random.seed(seed + col)
return np.random.uniform(0, 1)
cache = F.from_apply_func(
apply_func,
cache_func=cache_func,
pass_col=True
).run(ts, [0, 1, 2], return_cache=True, per_column=True)
assert cache == [0.3745401188473625, 0.11505456638977896, 0.8348421486656494]
cache = F.from_apply_func(
apply_func_nb,
cache_func=cache_func_nb,
pass_col=True
).run(ts, [0, 1, 2], return_cache=True, per_column=True)
assert cache == [0.3745401188473625, 0.11505456638977896, 0.8348421486656494]
target = pd.DataFrame(
np.array([
[0.37454012, 5.115054566389779, 2.8348421486656497],
[0.37454012, 4.115054566389779, 4.8348421486656497],
[0.37454012, 3.115054566389779, 6.8348421486656497],
[0.37454012, 2.115054566389779, 4.8348421486656497],
[0.37454012, 1.115054566389779, 2.8348421486656497]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(0, 'a'),
(1, 'b'),
(2, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func
).run(ts, [0, 1, 2], use_cache=cache, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func_nb
).run(ts, [0, 1, 2], use_cache=cache, per_column=True).out,
target
)
def test_raw(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def apply_func(ts, p, a, b=10):
return ts * p + a + b
@njit
def apply_func_nb(ts, p, a, b):
return ts * p + a + b
target = np.array([
[110., 110., 110., 111., 115., 111.],
[110., 110., 110., 112., 114., 112.],
[110., 110., 110., 113., 113., 113.],
[110., 110., 110., 114., 112., 112.],
[110., 110., 110., 115., 111., 111.]
])
np.testing.assert_array_equal(
F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1], 10, b=100, return_raw=True)[0][0],
target
)
np.testing.assert_array_equal(
F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1], 10, 100, return_raw=True)[0][0],
target
)
np.testing.assert_array_equal(
F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1], 10, b=100, return_raw=True)[1],
[(0,), (1,)]
)
np.testing.assert_array_equal(
F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1], 10, 100, return_raw=True)[1],
[(0,), (1,)]
)
assert F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1], 10, b=100, return_raw=True)[2] == 3
assert F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1], 10, 100, return_raw=True)[2] == 3
assert F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1], 10, b=100, return_raw=True)[3] == []
assert F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1], 10, 100, return_raw=True)[3] == []
raw_results = F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1, 2], 10, b=100, return_raw=True)
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1], 10, b=100, use_raw=raw_results).out,
F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1], 10, 100).out
)
target = np.array([
[110., 115., 112.],
[110., 114., 114.],
[110., 113., 116.],
[110., 112., 114.],
[110., 111., 112.]
])
np.testing.assert_array_equal(
F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1, 2], 10, b=100, return_raw=True, per_column=True)[0][0],
target
)
np.testing.assert_array_equal(
F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1, 2], 10, 100, return_raw=True, per_column=True)[0][0],
target
)
np.testing.assert_array_equal(
F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1, 2], 10, b=100, return_raw=True, per_column=True)[1],
[(0,), (1,), (2,)]
)
np.testing.assert_array_equal(
F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1, 2], 10, 100, return_raw=True, per_column=True)[1],
[(0,), (1,), (2,)]
)
assert F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1, 2], 10, b=100, return_raw=True)[2] == 3
assert F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1, 2], 10, 100, return_raw=True)[2] == 3
assert F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1, 2], 10, b=100, return_raw=True)[3] == []
assert F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 1, 2], 10, 100, return_raw=True)[3] == []
raw_results = F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 1, 2], 10, b=100, return_raw=True)
pd.testing.assert_frame_equal(
F.from_apply_func(
apply_func, var_args=True
).run(ts, [0, 0, 0], 10, b=100, use_raw=raw_results).out,
F.from_apply_func(
apply_func_nb, var_args=True
).run(ts, [0, 0, 0], 10, 100).out
)
@pytest.mark.parametrize(
"test_to_2d,test_keep_pd",
[
(False, False),
(False, True),
(True, False),
(True, True)
]
)
def test_to_2d_and_keep_pd(self, test_to_2d, test_keep_pd):
F = vbt.IndicatorFactory(input_names=['ts'], in_output_names=['in_out'], output_names=['out'])
def custom_func(_ts, _in_out):
if test_to_2d:
assert _ts.ndim == 2
for __in_out in _in_out:
assert __in_out.ndim == 2
if test_keep_pd:
pd.testing.assert_frame_equal(_ts, ts[['a']].vbt.wrapper.wrap(_ts.values))
for __in_out in _in_out:
pd.testing.assert_frame_equal(__in_out, ts[['a']].vbt.wrapper.wrap(__in_out.values))
else:
assert _ts.ndim == 1
for __in_out in _in_out:
assert __in_out.ndim == 1
if test_keep_pd:
pd.testing.assert_series_equal(_ts, ts['a'].vbt.wrapper.wrap(_ts.values))
for __in_out in _in_out:
pd.testing.assert_series_equal(__in_out, ts['a'].vbt.wrapper.wrap(__in_out.values))
return _ts
def apply_func(_ts, _in_out):
if test_to_2d:
assert _ts.ndim == 2
assert _in_out.ndim == 2
if test_keep_pd:
pd.testing.assert_frame_equal(_ts, ts[['a']].vbt.wrapper.wrap(_ts.values))
pd.testing.assert_frame_equal(_in_out, ts[['a']].vbt.wrapper.wrap(_in_out.values))
else:
assert _ts.ndim == 1
assert _in_out.ndim == 1
if test_keep_pd:
pd.testing.assert_series_equal(_ts, ts['a'].vbt.wrapper.wrap(_ts.values))
pd.testing.assert_series_equal(_in_out, ts['a'].vbt.wrapper.wrap(_in_out.values))
return _ts
_ = F.from_custom_func(custom_func, to_2d=test_to_2d, keep_pd=test_keep_pd, var_args=True) \
.run(ts['a'])
_ = F.from_apply_func(apply_func, to_2d=test_to_2d, keep_pd=test_keep_pd, var_args=True) \
.run(ts['a'])
def custom_func(_ts, _in_out, col=None):
if test_to_2d:
assert _ts.ndim == 2
for __in_out in _in_out:
assert __in_out.ndim == 2
if test_keep_pd:
pd.testing.assert_frame_equal(_ts, ts.iloc[:, [col]].vbt.wrapper.wrap(_ts.values))
for __in_out in _in_out:
pd.testing.assert_frame_equal(__in_out, ts.iloc[:, [col]].vbt.wrapper.wrap(__in_out.values))
else:
assert _ts.ndim == 1
for __in_out in _in_out:
assert __in_out.ndim == 1
if test_keep_pd:
pd.testing.assert_series_equal(_ts, ts.iloc[:, col].vbt.wrapper.wrap(_ts.values))
for __in_out in _in_out:
pd.testing.assert_series_equal(__in_out, ts.iloc[:, col].vbt.wrapper.wrap(__in_out.values))
return _ts
def apply_func(col, _ts, _in_out):
if test_to_2d:
assert _ts.ndim == 2
assert _in_out.ndim == 2
if test_keep_pd:
pd.testing.assert_frame_equal(_ts, ts.iloc[:, [col]].vbt.wrapper.wrap(_ts.values))
pd.testing.assert_frame_equal(_in_out, ts.iloc[:, [col]].vbt.wrapper.wrap(_in_out.values))
else:
assert _ts.ndim == 1
assert _in_out.ndim == 1
if test_keep_pd:
pd.testing.assert_series_equal(_ts, ts.iloc[:, col].vbt.wrapper.wrap(_ts.values))
pd.testing.assert_series_equal(_in_out, ts.iloc[:, col].vbt.wrapper.wrap(_in_out.values))
return _ts
_ = F.from_custom_func(custom_func, to_2d=test_to_2d, keep_pd=test_keep_pd, var_args=True) \
.run(ts['a'], per_column=True, pass_col=True)
_ = F.from_apply_func(apply_func, to_2d=test_to_2d, keep_pd=test_keep_pd, var_args=True) \
.run(ts['a'], per_column=True, pass_col=True)
def test_as_lists(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out'])
def custom_func(input_list, in_output_list, param_list):
return input_list[0] * param_list[0][0]
@njit
def custom_func_nb(input_list, in_output_list, param_list):
return input_list[0] * param_list[0][0]
target = pd.DataFrame(
ts.values * 2,
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(2, 'a'),
(2, 'b'),
(2, 'c')
], names=['custom_p', None])
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func, as_lists=True).run(ts, 2).out,
target
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func_nb, as_lists=True).run(ts, 2).out,
target
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func, as_lists=True).run(ts, 2, per_column=True).out,
target
)
pd.testing.assert_frame_equal(
F.from_custom_func(custom_func_nb, as_lists=True).run(ts, 2, per_column=True).out,
target
)
def test_other(self):
F = vbt.IndicatorFactory(input_names=['ts'], output_names=['o1', 'o2'])
def custom_func(ts):
return ts, ts + 1, ts + 2
@njit
def custom_func_nb(ts):
return ts, ts + 1, ts + 2
obj, other = F.from_custom_func(custom_func).run(ts)
np.testing.assert_array_equal(other, ts + 2)
obj, other = F.from_custom_func(custom_func_nb).run(ts)
np.testing.assert_array_equal(other, ts + 2)
obj, *others = F.from_custom_func(custom_func).run(ts, per_column=True)
for i, other in enumerate(others):
np.testing.assert_array_equal(other[0], ts.iloc[:, [i]] + 2)
obj, *others = F.from_custom_func(custom_func_nb).run(ts, per_column=True)
for i, other in enumerate(others):
np.testing.assert_array_equal(other[0], ts.iloc[:, [i]] + 2)
def test_run_unique(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
def apply_func(ts, p1, p2):
return ts * (p1 + p2)
pd.testing.assert_series_equal(
F.from_apply_func(apply_func).run(ts['a'], 2, 3, run_unique=True).out,
F.from_apply_func(apply_func).run(ts['a'], 2, 3, run_unique=False).out
)
raw = F.from_apply_func(apply_func).run(ts['a'], [2, 2, 2], [3, 3, 3], run_unique=True, return_raw=True)
np.testing.assert_array_equal(
raw[0][0],
np.array([[5.], [10.], [15.], [20.], [25.]])
)
assert raw[1] == [(2, 3)]
assert raw[2] == 1
assert raw[3] == []
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts['a'], [2, 2, 2], [3, 3, 3], run_unique=True).out,
F.from_apply_func(apply_func).run(ts['a'], [2, 2, 2], [3, 3, 3], run_unique=False).out
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, 2, 3, run_unique=True).out,
F.from_apply_func(apply_func).run(ts, 2, 3, run_unique=False).out
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [2, 2, 2], [3, 3, 3], run_unique=True).out,
F.from_apply_func(apply_func).run(ts, [2, 2, 2], [3, 3, 3], run_unique=False).out
)
pd.testing.assert_frame_equal(
F.from_apply_func(apply_func).run(ts, [2, 3, 4], [4, 3, 2], run_unique=True).out,
F.from_apply_func(apply_func).run(ts, [2, 3, 4], [4, 3, 2], run_unique=False).out
)
def test_run_combs(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
ind1 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run(ts, [2, 2, 3], [10, 10, 11], short_name='custom_1')
ind2 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run(ts, [3, 4, 4], [11, 12, 12], short_name='custom_2')
ind1_1, ind2_1 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run_combs(ts, [2, 3, 4], [10, 11, 12], r=2, run_unique=False)
ind1_2, ind2_2 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run_combs(ts, [2, 3, 4], [10, 11, 12], r=2, run_unique=True)
pd.testing.assert_frame_equal(
ind1.out,
ind1_1.out
)
pd.testing.assert_frame_equal(
ind2.out,
ind2_1.out
)
pd.testing.assert_frame_equal(
ind1.out,
ind1_2.out
)
pd.testing.assert_frame_equal(
ind2.out,
ind2_2.out
)
ind3 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run(ts, [2, 2, 2, 3, 3, 3, 4, 4, 4], [10, 10, 10, 11, 11, 11, 12, 12, 12], short_name='custom_1')
ind4 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run(ts, [2, 3, 4, 2, 3, 4, 2, 3, 4], [10, 11, 12, 10, 11, 12, 10, 11, 12], short_name='custom_2')
ind3_1, ind4_1 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run_combs(ts, [2, 3, 4], [10, 11, 12], r=2, comb_func=product, run_unique=False)
ind3_2, ind4_2 = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2) \
.run_combs(ts, [2, 3, 4], [10, 11, 12], r=2, comb_func=product, run_unique=True)
pd.testing.assert_frame_equal(
ind3.out,
ind3_1.out
)
pd.testing.assert_frame_equal(
ind4.out,
ind4_1.out
)
pd.testing.assert_frame_equal(
ind3.out,
ind3_2.out
)
pd.testing.assert_frame_equal(
ind4.out,
ind4_2.out
)
def test_wrapper(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
obj = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2).run(ts['a'], 0, 1)
assert obj.wrapper.ndim == 1
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 1, 'a')
], names=['custom_p1', 'custom_p2', None])
)
obj = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2).run(ts['a'], [0, 1], 2)
assert obj.wrapper.ndim == 2
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 2),
(1, 2),
], names=['custom_p1', 'custom_p2'])
)
obj = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2).run(ts, 0, 1)
assert obj.wrapper.ndim == 2
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 1, 'a'),
(0, 1, 'b'),
(0, 1, 'c')
], names=['custom_p1', 'custom_p2', None])
)
obj = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2).run(ts, [1, 2], 3)
assert obj.wrapper.ndim == 2
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(1, 3, 'a'),
(1, 3, 'b'),
(1, 3, 'c'),
(2, 3, 'a'),
(2, 3, 'b'),
(2, 3, 'c')
], names=['custom_p1', 'custom_p2', None])
)
obj = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2).run(ts['a'], 0, 1, per_column=True)
assert obj.wrapper.ndim == 1
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 1, 'a')
], names=['custom_p1', 'custom_p2', None])
)
obj = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2).run(ts[['a']], 0, 1, per_column=True)
assert obj.wrapper.ndim == 2
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 1, 'a')
], names=['custom_p1', 'custom_p2', None])
)
obj = F.from_apply_func(lambda ts, p1, p2: ts * p1 * p2).run(ts, 0, 1, per_column=True)
assert obj.wrapper.ndim == 2
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 1, 'a'),
(0, 1, 'b'),
(0, 1, 'c')
], names=['custom_p1', 'custom_p2', None])
)
@pytest.mark.parametrize(
"test_config",
[
lambda F, shape, *args, **kwargs: F.from_apply_func(
lambda input_shape, p1, p2: np.empty(input_shape) * p1 * p2, require_input_shape=True)
.run(shape, *args, **kwargs),
lambda F, shape, *args, **kwargs: F.from_apply_func(
lambda p1, p2: np.full(shape, p1 + p2))
.run(*args, **kwargs)
]
)
def test_no_inputs_wrapper(self, test_config):
F = vbt.IndicatorFactory(param_names=['p1', 'p2'], output_names=['out'])
obj = test_config(F, (5,), 0, 1)
assert obj.wrapper.ndim == 1
pd.testing.assert_index_equal(obj.wrapper.index, pd.RangeIndex(start=0, stop=5, step=1))
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 1),
], names=['custom_p1', 'custom_p2'])
)
obj = test_config(F, (5,), [0, 1], 2)
assert obj.wrapper.ndim == 2
pd.testing.assert_index_equal(obj.wrapper.index, pd.RangeIndex(start=0, stop=5, step=1))
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 2),
(1, 2)
], names=['custom_p1', 'custom_p2'])
)
obj = test_config(F, (5, 3), [0, 1], 2)
assert obj.wrapper.ndim == 2
pd.testing.assert_index_equal(obj.wrapper.index, pd.RangeIndex(start=0, stop=5, step=1))
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 2, 0),
(0, 2, 1),
(0, 2, 2),
(1, 2, 0),
(1, 2, 1),
(1, 2, 2)
], names=['custom_p1', 'custom_p2', None])
)
obj = test_config(F, ts.shape, [0, 1], 2, input_index=ts.index, input_columns=ts.columns)
assert obj.wrapper.ndim == ts.ndim
pd.testing.assert_index_equal(obj.wrapper.index, ts.index)
pd.testing.assert_index_equal(
obj.wrapper.columns,
pd.MultiIndex.from_tuples([
(0, 2, 'a'),
(0, 2, 'b'),
(0, 2, 'c'),
(1, 2, 'a'),
(1, 2, 'b'),
(1, 2, 'c')
], names=['custom_p1', 'custom_p2', None])
)
def test_mappers(self):
F = vbt.IndicatorFactory(input_names=['ts'], param_names=['p1', 'p2'], output_names=['out'])
obj = F.from_apply_func(lambda ts, p1, p2: ts * (p1 + p2)) \
.run(ts, 0, 2)
np.testing.assert_array_equal(
obj._input_mapper,
np.array([0, 1, 2])
)
np.testing.assert_array_equal(
obj._p1_mapper,
np.array([0, 0, 0])
)
np.testing.assert_array_equal(
obj._p2_mapper,
np.array([2, 2, 2])
)
assert obj._tuple_mapper == [(0, 2), (0, 2), (0, 2)]
obj = F.from_apply_func(lambda ts, p1, p2: ts * (p1 + p2)) \
.run(ts, [0, 1], [1, 2])
np.testing.assert_array_equal(
obj._input_mapper,
np.array([0, 1, 2, 0, 1, 2])
)
np.testing.assert_array_equal(
obj._p1_mapper,
np.array([0, 0, 0, 1, 1, 1])
)
np.testing.assert_array_equal(
obj._p2_mapper,
np.array([1, 1, 1, 2, 2, 2])
)
assert obj._tuple_mapper == [(0, 1), (0, 1), (0, 1), (1, 2), (1, 2), (1, 2)]
obj = F.from_apply_func(lambda ts, p1, p2: ts * (p1 + p2)) \
.run(ts, [0, 1, 2], 3, per_column=True)
np.testing.assert_array_equal(
obj._input_mapper,
np.array([0, 1, 2])
)
np.testing.assert_array_equal(
obj._p1_mapper,
np.array([0, 1, 2])
)
np.testing.assert_array_equal(
obj._p2_mapper,
np.array([3, 3, 3])
)
assert obj._tuple_mapper == [(0, 3), (1, 3), (2, 3)]
def test_properties(self):
I = vbt.IndicatorFactory(
input_names=['ts1', 'ts2'],
param_names=['p1', 'p2'],
output_names=['o1', 'o2'],
in_output_names=['in_o1', 'in_o2'],
output_flags={'o1': 'Hello'}
).from_apply_func(lambda ts1, ts2, p1, p2, in_o1, in_o2: (ts1, ts2))
obj = I.run(ts, ts, [0, 1], 2)
assert I.input_names == ('ts1', 'ts2')
assert I.param_names == ('p1', 'p2')
assert I.output_names == ('o1', 'o2')
assert I.in_output_names == ('in_o1', 'in_o2')
assert I.output_flags == {'o1': 'Hello'}
assert obj.input_names == ('ts1', 'ts2')
assert obj.param_names == ('p1', 'p2')
assert obj.output_names == ('o1', 'o2')
assert obj.in_output_names == ('in_o1', 'in_o2')
assert obj.output_flags == {'o1': 'Hello'}
assert obj.short_name == 'custom'
assert obj.level_names == ('custom_p1', 'custom_p2')
assert obj.p1_list == [0, 1]
assert obj.p2_list == [2, 2]
@pytest.mark.parametrize(
"test_attr",
['ts1', 'ts2', 'o1', 'o2', 'in_o1', 'in_o2', 'co1', 'co2']
)
def test_indexing(self, test_attr):
obj = vbt.IndicatorFactory(
input_names=['ts1', 'ts2'],
param_names=['p1', 'p2'],
output_names=['o1', 'o2'],
in_output_names=['in_o1', 'in_o2'],
custom_output_props={
'co1': lambda self: self.ts1 + self.ts2,
'co2': lambda self: self.o1 + self.o2
}
).from_apply_func(lambda ts1, ts2, p1, p2, in_o1, in_o2: (ts1, ts2)).run(ts, ts + 1, [1, 2], 3)
pd.testing.assert_frame_equal(
getattr(obj.iloc[np.arange(3), np.arange(3)], test_attr),
getattr(obj, test_attr).iloc[np.arange(3), np.arange(3)]
)
pd.testing.assert_series_equal(
getattr(obj.loc[:, (1, 3, 'a')], test_attr),
getattr(obj, test_attr).loc[:, (1, 3, 'a')]
)
pd.testing.assert_frame_equal(
getattr(obj.loc[:, (1, 3)], test_attr),
getattr(obj, test_attr).loc[:, (1, 3)]
)
pd.testing.assert_frame_equal(
getattr(obj[(1, 3)], test_attr),
getattr(obj, test_attr)[(1, 3)]
)
pd.testing.assert_frame_equal(
getattr(obj.xs(1, axis=1, level=0), test_attr),
getattr(obj, test_attr).xs(1, axis=1, level=0)
)
pd.testing.assert_frame_equal(
getattr(obj.p1_loc[2], test_attr),
getattr(obj, test_attr).xs(2, level='custom_p1', axis=1)
)
pd.testing.assert_frame_equal(
getattr(obj.p1_loc[1:2], test_attr),
pd.concat((
getattr(obj, test_attr).xs(1, level='custom_p1', drop_level=False, axis=1),
getattr(obj, test_attr).xs(2, level='custom_p1', drop_level=False, axis=1)
), axis=1)
)
pd.testing.assert_frame_equal(
getattr(obj.p1_loc[[1, 1, 1]], test_attr),
pd.concat((
getattr(obj, test_attr).xs(1, level='custom_p1', drop_level=False, axis=1),
getattr(obj, test_attr).xs(1, level='custom_p1', drop_level=False, axis=1),
getattr(obj, test_attr).xs(1, level='custom_p1', drop_level=False, axis=1)
), axis=1)
)
pd.testing.assert_frame_equal(
getattr(obj.tuple_loc[(1, 3)], test_attr),
getattr(obj, test_attr).xs((1, 3), level=('custom_p1', 'custom_p2'), axis=1)
)
pd.testing.assert_frame_equal(
getattr(obj.tuple_loc[(1, 3):(2, 3)], test_attr),
pd.concat((
getattr(obj, test_attr).xs((1, 3), level=('custom_p1', 'custom_p2'), drop_level=False, axis=1),
getattr(obj, test_attr).xs((2, 3), level=('custom_p1', 'custom_p2'), drop_level=False, axis=1)
), axis=1)
)
pd.testing.assert_frame_equal(
getattr(obj.tuple_loc[[(1, 3), (1, 3), (1, 3)]], test_attr),
pd.concat((
getattr(obj, test_attr).xs((1, 3), level=('custom_p1', 'custom_p2'), drop_level=False, axis=1),
getattr(obj, test_attr).xs((1, 3), level=('custom_p1', 'custom_p2'), drop_level=False, axis=1),
getattr(obj, test_attr).xs((1, 3), level=('custom_p1', 'custom_p2'), drop_level=False, axis=1)
), axis=1)
)
def test_numeric_attr(self):
obj = vbt.IndicatorFactory(input_names=['ts'], param_names=['p'], output_names=['out']) \
.from_apply_func(lambda ts, p: ts * p).run(ts, 1)
pd.testing.assert_frame_equal(obj.out_above(2), obj.out > 2)
target = pd.DataFrame(
np.array([
[False, True, False, False, True, False],
[False, True, False, False, True, False],
[True, True, True, False, False, False],
[True, False, False, True, False, False],
[True, False, False, True, False, False]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(2, 1, 'a'),
(2, 1, 'b'),
(2, 1, 'c'),
(3, 1, 'a'),
(3, 1, 'b'),
(3, 1, 'c'),
], names=['custom_out_above', 'custom_p', None])
)
pd.testing.assert_frame_equal(
obj.out_above([2, 3]),
target
)
columns = target.columns.set_names('my_above', level=0)
pd.testing.assert_frame_equal(
obj.out_above([2, 3], level_name='my_above'),
pd.DataFrame(
target.values,
index=target.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
obj.out_crossed_above(2),
pd.DataFrame(
np.array([
[False, False, False],
[False, False, False],
[True, False, True],
[False, False, False],
[False, False, False]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(1, 'a'),
(1, 'b'),
(1, 'c'),
], names=['custom_p', None])
)
)
pd.testing.assert_series_equal(
obj.out_stats(),
pd.Series([
pd.Timestamp('2018-01-01 00:00:00'),
pd.Timestamp('2018-01-05 00:00:00'),
pd.Timedelta('5 days 00:00:00'),
5.0, 2.6, 1.3329792289008184, 1.0, 2.6666666666666665, 4.333333333333333
],
index=pd.Index([
'Start', 'End', 'Period', 'Count', 'Mean', 'Std', 'Min', 'Median', 'Max'
], dtype='object'),
name='agg_func_mean'
)
)
def test_boolean_attr(self):
obj = vbt.IndicatorFactory(
input_names=['ts'], param_names=['p'], output_names=['out'],
attr_settings=dict(out=dict(dtype=np.bool_))) \
.from_apply_func(lambda ts, p: ts > p).run(ts, 2)
pd.testing.assert_frame_equal(obj.out_and(True), obj.out)
target = pd.DataFrame(
np.array([
[False, False, False, False, True, False],
[False, False, False, False, True, False],
[False, False, False, True, True, True],
[False, False, False, True, False, False],
[False, False, False, True, False, False]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(False, 2, 'a'),
(False, 2, 'b'),
(False, 2, 'c'),
(True, 2, 'a'),
(True, 2, 'b'),
(True, 2, 'c'),
], names=['custom_out_and', 'custom_p', None])
)
pd.testing.assert_frame_equal(
obj.out_and([False, True]),
target
)
columns = target.columns.set_names('my_and', level=0)
pd.testing.assert_frame_equal(
obj.out_and([False, True], level_name='my_and'),
pd.DataFrame(
target.values,
index=target.index,
columns=columns
)
)
pd.testing.assert_series_equal(
obj.out_stats(),
pd.Series([
pd.Timestamp('2018-01-01 00:00:00'), pd.Timestamp('2018-01-05 00:00:00'),
pd.Timedelta('5 days 00:00:00'), 2.3333333333333335, 46.666666666666664,
pd.Timestamp('2018-01-02 08:00:00'), pd.Timestamp('2018-01-03 16:00:00'), 0.0,
pd.Timedelta('1 days 00:00:00'), pd.Timedelta('1 days 00:00:00'),
pd.Timedelta('1 days 00:00:00'), pd.Timedelta('0 days 00:00:00'),
1.0, 55.55555555555555, pd.Timedelta('2 days 08:00:00'),
pd.Timedelta('2 days 08:00:00'), pd.Timedelta('2 days 08:00:00'),
pd.NaT, pd.NaT, pd.NaT, pd.NaT, pd.NaT
],
index=pd.Index([
'Start', 'End', 'Period', 'Total', 'Rate [%]', 'First Index',
'Last Index', 'Norm Avg Index [-1, 1]', 'Distance: Min',
'Distance: Max', 'Distance: Mean', 'Distance: Std', 'Total Partitions',
'Partition Rate [%]', 'Partition Length: Min', 'Partition Length: Max',
'Partition Length: Mean', 'Partition Length: Std',
'Partition Distance: Min', 'Partition Distance: Max',
'Partition Distance: Mean', 'Partition Distance: Std'
], dtype='object'),
name='agg_func_mean'
)
)
def test_mapping_attr(self):
TestEnum = namedtuple('TestEnum', ['Hello', 'World'])(0, 1)
obj = vbt.IndicatorFactory(
output_names=['out'],
attr_settings=dict(out=dict(dtype=TestEnum))) \
.from_apply_func(lambda: np.array([[0, 1], [1, -1]])).run()
pd.testing.assert_frame_equal(
obj.out_readable,
pd.DataFrame([
['Hello', 'World'],
['World', None]
])
)
pd.testing.assert_series_equal(
obj.out_stats(),
pd.Series([
0.0, 1.0, 2.0, 0.5, 0.5, 1.0
],
index=pd.Index([
'Start', 'End', 'Period', 'Value Counts: None', 'Value Counts: Hello', 'Value Counts: World'
], dtype='object'),
name='agg_func_mean'
)
)
def test_stats(self):
@njit
def apply_func_nb(ts):
return ts ** 2, ts ** 3
MyInd = vbt.IndicatorFactory(
input_names=['ts'],
output_names=['out1', 'out2'],
metrics=dict(
sum_diff=dict(
calc_func=lambda self, const: self.out2.sum() * self.out1.sum() + const
)
),
stats_defaults=dict(settings=dict(const=1000))
).from_apply_func(
apply_func_nb
)
myind = MyInd.run(ts)
pd.testing.assert_series_equal(
myind.stats(),
pd.Series([9535.0], index=['sum_diff'], name='agg_func_mean')
)
def test_dir(self):
TestEnum = namedtuple('TestEnum', ['Hello', 'World'])(0, 1)
F = vbt.IndicatorFactory(
input_names=['ts'], output_names=['o1', 'o2'], in_output_names=['in_out'], param_names=['p1', 'p2'],
attr_settings={
'ts': {'dtype': None},
'o1': {'dtype': np.float64},
'o2': {'dtype': np.bool_},
'in_out': {'dtype': TestEnum}
}
)
ind = F.from_apply_func(lambda ts, in_out, p1, p2: (ts + in_out, ts + in_out)).run(ts, 100, 200)
test_attr_list = dir(ind)
assert test_attr_list == [
'__annotations__',
'__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'_config',
'_iloc',
'_in_out',
'_in_output_names',
'_indexing_kwargs',
'_input_mapper',
'_input_names',
'_level_names',
'_loc',
'_metrics',
'_o1',
'_o2',
'_output_flags',
'_output_names',
'_p1_list',
'_p1_loc',
'_p1_mapper',
'_p2_list',
'_p2_loc',
'_p2_mapper',
'_param_names',
'_run',
'_run_combs',
'_short_name',
'_subplots',
'_ts',
'_tuple_loc',
'_tuple_mapper',
'_wrapper',
'apply_func',
'build_metrics_doc',
'build_subplots_doc',
'config',
'copy',
'custom_func',
'deep_getattr',
'dumps',
'iloc',
'in_out',
'in_out_readable',
'in_out_stats',
'in_output_names',
'indexing_func',
'indexing_kwargs',
'input_names',
'level_names',
'load',
'loads',
'loc',
'metrics',
'o1',
'o1_above',
'o1_below',
'o1_crossed_above',
'o1_crossed_below',
'o1_equal',
'o1_stats',
'o2',
'o2_and',
'o2_or',
'o2_stats',
'o2_xor',
'output_flags',
'output_names',
'override_metrics_doc',
'override_subplots_doc',
'p1_list',
'p1_loc',
'p2_list',
'p2_loc',
'param_names',
'plots',
'plots_defaults',
'post_resolve_attr',
'pre_resolve_attr',
'regroup',
'replace',
'resolve_attr',
'resolve_self',
'run',
'run_combs',
'save',
'select_one',
'select_one_from_obj',
'self_aliases',
'short_name',
'stats',
'stats_defaults',
'subplots',
'to_doc',
'ts',
'ts_above',
'ts_below',
'ts_crossed_above',
'ts_crossed_below',
'ts_equal',
'ts_stats',
'tuple_loc',
'update_config',
'wrapper',
'writeable_attrs',
'xs'
]
def test_get_talib_indicators(self):
if talib_available:
assert len(vbt.IndicatorFactory.get_talib_indicators()) > 0
def test_from_talib(self):
if talib_available:
target = pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan],
[2.5, 5.5, 2.5],
[3.5, 4.5, 3.5],
[4.5, 3.5, 3.5],
[5.5, 2.5, 2.5]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(2, 2, 2, 'a'),
(2, 2, 2, 'b'),
(2, 2, 2, 'c')
], names=['bbands_timeperiod', 'bbands_nbdevup', 'bbands_nbdevdn', None])
)
BBANDS = vbt.talib('BBANDS')
pd.testing.assert_frame_equal(
BBANDS.run(ts, timeperiod=2, nbdevup=2, nbdevdn=2).upperband,
target
)
pd.testing.assert_frame_equal(
BBANDS.run(ts, timeperiod=2, nbdevup=2, nbdevdn=2).middleband,
target - 1
)
pd.testing.assert_frame_equal(
BBANDS.run(ts, timeperiod=2, nbdevup=2, nbdevdn=2).lowerband,
target - 2
)
target = pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
[2.5, 5.5, 2.5, 2.5, 5.5, 2.5],
[3.5, 4.5, 3.5, 3.5, 4.5, 3.5],
[4.5, 3.5, 3.5, 4.5, 3.5, 3.5],
[5.5, 2.5, 2.5, 5.5, 2.5, 2.5]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(2, 2, 2, 'a'),
(2, 2, 2, 'b'),
(2, 2, 2, 'c'),
(2, 2, 2, 'a'),
(2, 2, 2, 'b'),
(2, 2, 2, 'c')
], names=['bbands_timeperiod', 'bbands_nbdevup', 'bbands_nbdevdn', None])
)
BBANDS = vbt.talib('BBANDS')
pd.testing.assert_frame_equal(
BBANDS.run(ts, timeperiod=[2, 2], nbdevup=2, nbdevdn=2).upperband,
target
)
pd.testing.assert_frame_equal(
BBANDS.run(ts, timeperiod=[2, 2], nbdevup=2, nbdevdn=2).middleband,
target - 1
)
pd.testing.assert_frame_equal(
BBANDS.run(ts, timeperiod=[2, 2], nbdevup=2, nbdevdn=2).lowerband,
target - 2
)
OBV = vbt.talib('OBV')
pd.testing.assert_frame_equal(
OBV.run(ts, ts * 2).real,
pd.DataFrame(
np.array([
[2., 10., 2.],
[6., 2., 6.],
[12., -4., 12.],
[20., -8., 8.],
[30., -10., 6.]
]),
index=ts.index,
columns=ts.columns
)
)
def test_get_pandas_ta_indicators(self):
if pandas_ta_available:
assert len(vbt.IndicatorFactory.get_pandas_ta_indicators()) > 0
def test_from_pandas_ta(self):
if pandas_ta_available:
pd.testing.assert_frame_equal(
vbt.pandas_ta('SMA').run(ts, 2).sma,
pd.DataFrame(
ts.rolling(2).mean().values,
index=ts.index,
columns=pd.MultiIndex.from_tuples([(2, 'a'), (2, 'b'), (2, 'c')], names=['sma_length', None])
)
)
pd.testing.assert_frame_equal(
vbt.pandas_ta('SMA').run(ts['a'], [2, 3, 4]).sma,
pd.DataFrame(
np.column_stack((
ts['a'].rolling(2).mean().values,
ts['a'].rolling(3).mean().values,
ts['a'].rolling(4).mean().values
)),
index=ts.index,
columns=pd.Index([2, 3, 4], dtype='int64', name='sma_length')
)
)
def test_get_ta_indicators(self):
if ta_available:
assert len(vbt.IndicatorFactory.get_ta_indicators()) > 0
def test_from_ta(self):
if ta_available:
pd.testing.assert_frame_equal(
vbt.ta('SMAIndicator').run(ts, 2).sma_indicator,
pd.DataFrame(
ts.rolling(2).mean().values,
index=ts.index,
columns=pd.MultiIndex.from_tuples([(2, 'a'), (2, 'b'), (2, 'c')],
names=['smaindicator_window', None])
)
)
pd.testing.assert_frame_equal(
vbt.ta('SMAIndicator').run(ts['a'], [2, 3, 4]).sma_indicator,
pd.DataFrame(
np.column_stack((
ts['a'].rolling(2).mean().values,
ts['a'].rolling(3).mean().values,
ts['a'].rolling(4).mean().values
)),
index=ts.index,
columns=pd.Index([2, 3, 4], dtype='int64', name='smaindicator_window')
)
)
target = pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan],
[2.5, 5.5, 2.5],
[3.5, 4.5, 3.5],
[4.5, 3.5, 3.5],
[5.5, 2.5, 2.5]
]),
index=ts.index,
columns=pd.MultiIndex.from_tuples([
(2, 2, 'a'),
(2, 2, 'b'),
(2, 2, 'c')
], names=['bollingerbands_window', 'bollingerbands_window_dev', None])
)
BollingerBands = vbt.ta('BollingerBands')
pd.testing.assert_frame_equal(
BollingerBands.run(ts, window=2, window_dev=2).bollinger_hband,
target
)
pd.testing.assert_frame_equal(
BollingerBands.run(ts, window=2, window_dev=2).bollinger_mavg,
target - 1
)
pd.testing.assert_frame_equal(
BollingerBands.run(ts, window=2, window_dev=2).bollinger_lband,
target - 2
)
close_ts = pd.Series([1, 2, 3, 4, 3, 2, 1], index=pd.DatetimeIndex([
datetime(2018, 1, 1),
datetime(2018, 1, 2),
datetime(2018, 1, 3),
datetime(2018, 1, 4),
datetime(2018, 1, 5),
datetime(2018, 1, 6),
datetime(2018, 1, 7)
]))
high_ts = close_ts * 1.1
low_ts = close_ts * 0.9
volume_ts = pd.Series([4, 3, 2, 1, 2, 3, 4], index=close_ts.index)
class TestBasic:
def test_MA(self):
pd.testing.assert_frame_equal(
vbt.MA.run(close_ts, window=(2, 3), ewm=(False, True), param_product=True).ma,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan],
[1.5, 1.66666667, np.nan, np.nan],
[2.5, 2.55555556, 2., 2.25],
[3.5, 3.51851852, 3., 3.125],
[3.5, 3.17283951, 3.33333333, 3.0625],
[2.5, 2.3909465, 3., 2.53125],
[1.5, 1.46364883, 2., 1.765625]
]),
index=close_ts.index,
columns=pd.MultiIndex.from_tuples([
(2, False),
(2, True),
(3, False),
(3, True)
], names=['ma_window', 'ma_ewm'])
)
)
def test_MSTD(self):
pd.testing.assert_frame_equal(
vbt.MSTD.run(close_ts, window=(2, 3), ewm=(False, True), param_product=True).mstd,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan],
[0.5, 0.70710678, np.nan, np.nan],
[0.5, 0.97467943, 0.81649658, 1.04880885],
[0.5, 1.11434207, 0.81649658, 1.30018314],
[0.5, 0.73001838, 0.47140452, 0.91715673],
[0.5, 0.88824841, 0.81649658, 0.9182094],
[0.5, 1.05965735, 0.81649658, 1.14049665]
]),
index=close_ts.index,
columns=pd.MultiIndex.from_tuples([
(2, False),
(2, True),
(3, False),
(3, True)
], names=['mstd_window', 'mstd_ewm'])
)
)
def test_BBANDS(self):
columns = pd.MultiIndex.from_tuples([
(2, False, 2.0),
(2, False, 3.0),
(2, True, 2.0),
(2, True, 3.0),
(3, False, 2.0),
(3, False, 3.0),
(3, True, 2.0),
(3, True, 3.0)
], names=['bb_window', 'bb_ewm', 'bb_alpha'])
pd.testing.assert_frame_equal(
vbt.BBANDS.run(
close_ts,
window=(2, 3),
alpha=(2., 3.),
ewm=(False, True),
param_product=True
).middle,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[1.5, 1.5, 1.66666667, 1.66666667, np.nan,
np.nan, np.nan, np.nan],
[2.5, 2.5, 2.55555556, 2.55555556, 2.,
2., 2.25, 2.25],
[3.5, 3.5, 3.51851852, 3.51851852, 3.,
3., 3.125, 3.125],
[3.5, 3.5, 3.17283951, 3.17283951, 3.33333333,
3.33333333, 3.0625, 3.0625],
[2.5, 2.5, 2.3909465, 2.3909465, 3.,
3., 2.53125, 2.53125],
[1.5, 1.5, 1.46364883, 1.46364883, 2.,
2., 1.765625, 1.765625]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.BBANDS.run(
close_ts,
window=(2, 3),
alpha=(2., 3.),
ewm=(False, True),
param_product=True
).upper,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[2.5, 3., 3.08088023, 3.78798701, np.nan,
np.nan, np.nan, np.nan],
[3.5, 4., 4.50491442, 5.47959386, 3.63299316,
4.44948974, 4.3476177, 5.39642654],
[4.5, 5., 5.74720265, 6.86154472, 4.63299316,
5.44948974, 5.72536627, 7.02554941],
[4.5, 5., 4.63287626, 5.36289463, 4.27614237,
4.7475469, 4.89681346, 5.8139702],
[3.5, 4., 4.16744332, 5.05569172, 4.63299316,
5.44948974, 4.3676688, 5.2858782],
[2.5, 3., 3.58296354, 4.64262089, 3.63299316,
4.44948974, 4.04661829, 5.18711494]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.BBANDS.run(
close_ts,
window=(2, 3),
alpha=(2., 3.),
ewm=(False, True),
param_product=True
).lower,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[0.5, 0., 0.2524531, -0.45465368, np.nan,
np.nan, np.nan, np.nan],
[1.5, 1., 0.60619669, -0.36848275, 0.36700684,
-0.44948974, 0.1523823, -0.89642654],
[2.5, 2., 1.28983438, 0.17549232, 1.36700684,
0.55051026, 0.52463373, -0.77554941],
[2.5, 2., 1.71280275, 0.98278438, 2.39052429,
1.91911977, 1.22818654, 0.3110298],
[1.5, 1., 0.61444969, -0.27379872, 1.36700684,
0.55051026, 0.6948312, -0.2233782],
[0.5, 0., -0.65566587, -1.71532322, 0.36700684,
-0.44948974, -0.51536829, -1.65586494]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.BBANDS.run(
close_ts,
window=(2, 3),
alpha=(2., 3.),
ewm=(False, True),
param_product=True
).percent_b,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[0.75, 0.66666667, 0.61785113, 0.57856742, np.nan,
np.nan, np.nan, np.nan],
[0.75, 0.66666667, 0.61399759, 0.5759984, 0.80618622,
0.70412415, 0.67877424, 0.61918282],
[0.75, 0.66666667, 0.60801923, 0.57201282, 0.80618622,
0.70412415, 0.66824553, 0.61216369],
[0.25, 0.33333333, 0.44080988, 0.46053992, 0.3232233,
0.38214887, 0.48296365, 0.48864244],
[0.25, 0.33333333, 0.38996701, 0.42664468, 0.19381378,
0.29587585, 0.35535707, 0.40357138],
[0.25, 0.33333333, 0.3906135, 0.42707567, 0.19381378,
0.29587585, 0.3321729, 0.38811526]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.BBANDS.run(
close_ts,
window=(2, 3),
alpha=(2., 3.),
ewm=(False, True),
param_product=True
).bandwidth,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[1.33333333, 2., 1.69705627, 2.54558441, np.nan,
np.nan, np.nan, np.nan],
[0.8, 1.2, 1.5255852, 2.2883778, 1.63299316,
2.44948974, 1.86454906, 2.7968236],
[0.57142857, 0.85714286, 1.26683098, 1.90024647, 1.08866211,
1.63299316, 1.66423442, 2.49635162],
[0.57142857, 0.85714286, 0.92033445, 1.38050168, 0.56568542,
0.84852814, 1.197919, 1.79687849],
[0.8, 1.2, 1.48601971, 2.22902956, 1.08866211,
1.63299316, 1.45099757, 2.17649636],
[1.33333333, 2., 2.8959333, 4.34389996, 1.63299316,
2.44948974, 2.58378001, 3.87567002]
]),
index=close_ts.index,
columns=columns
)
)
def test_RSI(self):
pd.testing.assert_frame_equal(
vbt.RSI.run(close_ts, window=(2, 3), ewm=(False, True), param_product=True).rsi,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan],
[100., 100., np.nan, np.nan],
[100., 100., 100., 100.],
[50., 33.33333333, 66.66666667, 50.],
[0., 11.11111111, 33.33333333, 25.],
[0., 3.7037037, 0., 12.5]
]),
index=close_ts.index,
columns=pd.MultiIndex.from_tuples([
(2, False),
(2, True),
(3, False),
(3, True)
], names=['rsi_window', 'rsi_ewm'])
)
)
def test_STOCH(self):
columns = pd.MultiIndex.from_tuples([
(2, 2, False),
(2, 2, True),
(2, 3, False),
(2, 3, True),
(3, 2, False),
(3, 2, True),
(3, 3, False),
(3, 3, True)
], names=['stoch_k_window', 'stoch_d_window', 'stoch_d_ewm'])
pd.testing.assert_frame_equal(
vbt.STOCH.run(
high_ts,
low_ts,
close_ts,
k_window=(2, 3),
d_window=(2, 3),
d_ewm=(False, True),
param_product=True
).percent_k,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[84.61538462, 84.61538462, 84.61538462, 84.61538462, np.nan,
np.nan, np.nan, np.nan],
[80., 80., 80., 80., 87.5,
87.5, 87.5, 87.5],
[76.47058824, 76.47058824, 76.47058824, 76.47058824, 84.61538462,
84.61538462, 84.61538462, 84.61538462],
[17.64705882, 17.64705882, 17.64705882, 17.64705882, 17.64705882,
17.64705882, 17.64705882, 17.64705882],
[13.33333333, 13.33333333, 13.33333333, 13.33333333, 7.69230769,
7.69230769, 7.69230769, 7.69230769],
[7.69230769, 7.69230769, 7.69230769, 7.69230769, 4.16666667,
4.16666667, 4.16666667, 4.16666667]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.STOCH.run(
high_ts,
low_ts,
close_ts,
k_window=(2, 3),
d_window=(2, 3),
d_ewm=(False, True),
param_product=True
).percent_d,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[82.30769231, 81.53846154, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan],
[78.23529412, 78.15987934, 80.36199095, 79.38914027, 86.05769231,
85.57692308, np.nan, np.nan],
[47.05882353, 37.81799899, 58.03921569, 48.51809955, 51.13122172,
40.29034691, 63.25414781, 51.85237557],
[15.49019608, 21.49488855, 35.81699346, 30.92571644, 12.66968326,
18.55832076, 36.65158371, 29.77234163],
[10.51282051, 12.29316798, 12.89089995, 19.30901207, 5.92948718,
8.9638847, 9.83534439, 16.96950415]
]),
index=close_ts.index,
columns=columns
)
)
def test_MACD(self):
columns = pd.MultiIndex.from_tuples([
(2, 3, 2, False, False),
(2, 3, 2, False, True),
(2, 3, 2, True, False),
(2, 3, 2, True, True),
(2, 3, 3, False, False),
(2, 3, 3, False, True),
(2, 3, 3, True, False),
(2, 3, 3, True, True),
(2, 4, 2, False, False),
(2, 4, 2, False, True),
(2, 4, 2, True, False),
(2, 4, 2, True, True),
(2, 4, 3, False, False),
(2, 4, 3, False, True),
(2, 4, 3, True, False),
(2, 4, 3, True, True),
(3, 3, 2, False, False),
(3, 3, 2, False, True),
(3, 3, 2, True, False),
(3, 3, 2, True, True),
(3, 3, 3, False, False),
(3, 3, 3, False, True),
(3, 3, 3, True, False),
(3, 3, 3, True, True),
(3, 4, 2, False, False),
(3, 4, 2, False, True),
(3, 4, 2, True, False),
(3, 4, 2, True, True),
(3, 4, 3, False, False),
(3, 4, 3, False, True),
(3, 4, 3, True, False),
(3, 4, 3, True, True)
], names=['macd_fast_window', 'macd_slow_window', 'macd_signal_window', 'macd_macd_ewm', 'macd_signal_ewm'])
pd.testing.assert_frame_equal(
vbt.MACD.run(
close_ts,
fast_window=(2, 3),
slow_window=(3, 4),
signal_window=(2, 3),
macd_ewm=(False, True),
signal_ewm=(False, True),
param_product=True
).macd,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[0.5, 0.5, 0.30555556, 0.30555556, 0.5,
0.5, 0.30555556, 0.30555556, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, 0., 0., 0., 0.,
0., 0., 0., 0., np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[0.5, 0.5, 0.39351852, 0.39351852, 0.5,
0.5, 0.39351852, 0.39351852, 1., 1.,
0.69451852, 0.69451852, 1., 1., 0.69451852,
0.69451852, 0., 0., 0., 0.,
0., 0., 0., 0., 0.5,
0.5, 0.301, 0.301, 0.5, 0.5,
0.301, 0.301],
[0.16666667, 0.16666667, 0.11033951, 0.11033951, 0.16666667,
0.16666667, 0.11033951, 0.11033951, 0.5, 0.5,
0.27843951, 0.27843951, 0.5, 0.5, 0.27843951,
0.27843951, 0., 0., 0., 0.,
0., 0., 0., 0., 0.33333333,
0.33333333, 0.1681, 0.1681, 0.33333333, 0.33333333,
0.1681, 0.1681],
[-0.5, -0.5, -0.1403035, -0.1403035, -0.5,
-0.5, -0.1403035, -0.1403035, -0.5, -0.5,
-0.1456935, -0.1456935, -0.5, -0.5, -0.1456935,
-0.1456935, 0., 0., 0., 0.,
0., 0., 0., 0., 0.,
0., -0.00539, -0.00539, 0., 0.,
-0.00539, -0.00539],
[-0.5, -0.5, -0.30197617, -0.30197617, -0.5,
-0.5, -0.30197617, -0.30197617, -1., -1.,
-0.45833517, -0.45833517, -1., -1., -0.45833517,
-0.45833517, 0., 0., 0., 0.,
0., 0., 0., 0., -0.5,
-0.5, -0.156359, -0.156359, -0.5, -0.5,
-0.156359, -0.156359]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.MACD.run(
close_ts,
fast_window=(2, 3),
slow_window=(3, 4),
signal_window=(2, 3),
macd_ewm=(False, True),
signal_ewm=(False, True),
param_product=True
).signal,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[0.5, 0.5, 0.34953704, 0.36419753, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, 0., 0., 0., 0.,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[0.33333333, 0.27777778, 0.25192901, 0.19495885, 0.38888889,
0.33333333, 0.26980453, 0.22993827, 0.75, 0.66666667,
0.48647901, 0.41713251, np.nan, np.nan, np.nan,
np.nan, 0., 0., 0., 0.,
0., 0., 0., 0., 0.41666667,
0.38888889, 0.23455, 0.2124, np.nan, np.nan,
np.nan, np.nan],
[-0.16666667, -0.24074074, -0.014982, -0.02854938, 0.05555556,
-0.08333333, 0.12118484, 0.04481739, 0., -0.11111111,
0.066373, 0.04191517, 0.33333333, 0.125, 0.27575484,
0.17039276, 0., 0., 0., 0.,
0., 0., 0., 0., 0.16666667,
0.12962963, 0.081355, 0.06720667, 0.27777778, 0.20833333,
0.15457, 0.11458],
[-0.5, -0.41358025, -0.22113983, -0.2108339, -0.27777778,
-0.29166667, -0.11064672, -0.12857939, -0.75, -0.7037037,
-0.30201433, -0.29158505, -0.33333333, -0.4375, -0.10852972,
-0.1439712, 0., 0., 0., 0.,
0., 0., 0., 0., -0.25,
-0.29012346, -0.0808745, -0.08183711, -0.05555556, -0.14583333,
0.002117, -0.0208895]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.MACD.run(
close_ts,
fast_window=(2, 3),
slow_window=(3, 4),
signal_window=(2, 3),
macd_ewm=(False, True),
signal_ewm=(False, True),
param_product=True
).hist,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[0., 0., 0.04398148, 0.02932099, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, 0., 0., 0., 0.,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan, np.nan, np.nan, np.nan,
np.nan, np.nan],
[-0.16666667, -0.11111111, -0.14158951, -0.08461934, -0.22222222,
-0.16666667, -0.15946502, -0.11959877, -0.25, -0.16666667,
-0.20803951, -0.138693, np.nan, np.nan, np.nan,
np.nan, 0., 0., 0., 0.,
0., 0., 0., 0., -0.08333333,
-0.05555556, -0.06645, -0.0443, np.nan, np.nan,
np.nan, np.nan],
[-0.33333333, -0.25925926, -0.1253215, -0.11175412, -0.55555556,
-0.41666667, -0.26148834, -0.18512088, -0.5, -0.38888889,
-0.2120665, -0.18760867, -0.83333333, -0.625, -0.42144834,
-0.31608626, 0., 0., 0., 0.,
0., 0., 0., 0., -0.16666667,
-0.12962963, -0.086745, -0.07259667, -0.27777778, -0.20833333,
-0.15996, -0.11997],
[0., -0.08641975, -0.08083633, -0.09114226, -0.22222222,
-0.20833333, -0.19132945, -0.17339678, -0.25, -0.2962963,
-0.15632083, -0.16675011, -0.66666667, -0.5625, -0.34980545,
-0.31436396, 0., 0., 0., 0.,
0., 0., 0., 0., -0.25,
-0.20987654, -0.0754845, -0.07452189, -0.44444444, -0.35416667,
-0.158476, -0.1354695]
]),
index=close_ts.index,
columns=columns
)
)
def test_ATR(self):
columns = pd.MultiIndex.from_tuples([
(2, False),
(2, True),
(3, False),
(3, True)
], names=['atr_window', 'atr_ewm'])
pd.testing.assert_frame_equal(
vbt.ATR.run(high_ts, low_ts, close_ts, window=(2, 3), ewm=(False, True), param_product=True).tr,
pd.DataFrame(
np.array([
[0.2, 0.2, 0.2, 0.2],
[1.2, 1.2, 1.2, 1.2],
[1.3, 1.3, 1.3, 1.3],
[1.4, 1.4, 1.4, 1.4],
[1.3, 1.3, 1.3, 1.3],
[1.2, 1.2, 1.2, 1.2],
[1.1, 1.1, 1.1, 1.1]
]),
index=close_ts.index,
columns=columns
)
)
pd.testing.assert_frame_equal(
vbt.ATR.run(high_ts, low_ts, close_ts, window=(2, 3), ewm=(False, True), param_product=True).atr,
pd.DataFrame(
np.array([
[np.nan, np.nan, np.nan, np.nan],
[0.7, 0.86666667, np.nan, np.nan],
[1.25, 1.15555556, 0.9, 1.],
[1.35, 1.31851852, 1.3, 1.2],
[1.35, 1.30617284, 1.33333333, 1.25],
[1.25, 1.23539095, 1.3, 1.225],
[1.15, 1.14513032, 1.2, 1.1625]
]),
index=close_ts.index,
columns=columns
)
)
def test_OBV(self):
pd.testing.assert_series_equal(
vbt.OBV.run(close_ts, volume_ts).obv,
pd.Series(
np.array([4, 7, 9, 10, 8, 5, 1]),
index=close_ts.index,
name=close_ts.name
)
)