mirror of
https://github.com/polakowo/vectorbt.git
synced 2022-03-22 01:31:39 +03:00
Small fixes
[ci deploy-pages] [ci test-cov]
This commit is contained in:
@@ -31,7 +31,7 @@ from talib._ta_lib import (
|
||||
from vectorbt import settings
|
||||
from vectorbt.utils.config import merge_dicts
|
||||
from vectorbt.utils.colors import adjust_opacity
|
||||
from vectorbt.portfolio.enums import Direction, ConflictMode
|
||||
from vectorbt.portfolio.enums import Direction, DirectionConflictMode
|
||||
from vectorbt.portfolio.base import Portfolio
|
||||
|
||||
USE_CACHING = os.environ.get(
|
||||
@@ -80,7 +80,7 @@ intervals = ['1m', '2m', '5m', '15m', '30m', '60m', '90m', '1d', '5d', '1wk', '1
|
||||
patterns = talib.get_function_groups()['Pattern Recognition']
|
||||
stats_table_columns = ["Metric", "Buy & Hold", "Random (Median)", "Strategy", "Z-Score"]
|
||||
directions = Direction._fields
|
||||
conflict_modes = ConflictMode._fields
|
||||
conflict_modes = DirectionConflictMode._fields
|
||||
plot_types = ['OHLC', 'Candlestick']
|
||||
|
||||
# Colors
|
||||
@@ -1295,7 +1295,7 @@ def simulate_portfolio(df, interval, date_range, selected_data, entry_patterns,
|
||||
price=df['Open'],
|
||||
size=np.abs(size),
|
||||
direction=direction,
|
||||
conflict_mode=conflict_mode,
|
||||
upon_dir_conflict=conflict_mode,
|
||||
accumulate='allow_accumulate' in sim_options,
|
||||
init_cash=init_cash,
|
||||
fees=float(fees) / 100,
|
||||
|
||||
@@ -3451,37 +3451,39 @@ class TestFromRandomSignals:
|
||||
|
||||
@njit
|
||||
def order_func_nb(c, size):
|
||||
return nb.order_nb(size if c.i % 2 == 0 else -size)
|
||||
_size = nb.get_elem_nb(c, size)
|
||||
return nb.order_nb(_size if c.i % 2 == 0 else -_size)
|
||||
|
||||
|
||||
@njit
|
||||
def log_order_func_nb(c, size):
|
||||
return nb.order_nb(size if c.i % 2 == 0 else -size, log=True)
|
||||
_size = nb.get_elem_nb(c, size)
|
||||
return nb.order_nb(_size if c.i % 2 == 0 else -_size, log=True)
|
||||
|
||||
|
||||
@njit
|
||||
def flex_order_func_nb(c, size):
|
||||
if c.call_idx < c.group_len:
|
||||
return c.from_col + c.call_idx, nb.order_nb(size if c.i % 2 == 0 else -size)
|
||||
_size = nb.get_col_elem_nb(c, c.from_col + c.call_idx, size)
|
||||
return c.from_col + c.call_idx, nb.order_nb(_size if c.i % 2 == 0 else -_size)
|
||||
return -1, nb.order_nothing_nb()
|
||||
|
||||
|
||||
@njit
|
||||
def log_flex_order_func_nb(c, size):
|
||||
if c.call_idx < c.group_len:
|
||||
return c.from_col + c.call_idx, nb.order_nb(size if c.i % 2 == 0 else -size, log=True)
|
||||
_size = nb.get_col_elem_nb(c, c.from_col + c.call_idx, size)
|
||||
return c.from_col + c.call_idx, nb.order_nb(_size if c.i % 2 == 0 else -_size, log=True)
|
||||
return -1, nb.order_nothing_nb()
|
||||
|
||||
|
||||
class TestFromOrderFunc:
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_one_column(self, test_row_wise, test_flexible):
|
||||
order_func = flex_order_func_nb if test_flexible else order_func_nb
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price.tolist(), order_func, np.inf, row_wise=test_row_wise, flexible=test_flexible)
|
||||
price.tolist(), order_func, np.asarray(np.inf), row_wise=test_row_wise, flexible=test_flexible)
|
||||
record_arrays_close(
|
||||
pf.order_records,
|
||||
np.array([
|
||||
@@ -3491,7 +3493,7 @@ class TestFromOrderFunc:
|
||||
], dtype=order_dt)
|
||||
)
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price, order_func, np.inf, row_wise=test_row_wise, flexible=test_flexible)
|
||||
price, order_func, np.asarray(np.inf), row_wise=test_row_wise, flexible=test_flexible)
|
||||
record_arrays_close(
|
||||
pf.order_records,
|
||||
np.array([
|
||||
@@ -3512,40 +3514,34 @@ class TestFromOrderFunc:
|
||||
assert pf.wrapper.freq == day_dt
|
||||
assert pf.wrapper.grouper.group_by is None
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
def test_multiple_columns(self, test_row_wise, test_flexible):
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
@pytest.mark.parametrize("test_use_numba", [False, True])
|
||||
def test_multiple_columns(self, test_row_wise, test_flexible, test_use_numba):
|
||||
order_func = flex_order_func_nb if test_flexible else order_func_nb
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, np.inf, row_wise=test_row_wise, flexible=test_flexible)
|
||||
price_wide, order_func, vbt.Rep('size'), broadcast_named_args=dict(size=[0, 1, np.inf]),
|
||||
row_wise=test_row_wise, flexible=test_flexible, use_numba=test_use_numba)
|
||||
if test_row_wise:
|
||||
record_arrays_close(
|
||||
pf.order_records,
|
||||
np.array([
|
||||
(0, 0, 0, 100.0, 1.0, 0.0, 0), (1, 1, 0, 100.0, 1.0, 0.0, 0),
|
||||
(2, 2, 0, 100.0, 1.0, 0.0, 0), (3, 0, 1, 200.0, 2.0, 0.0, 1),
|
||||
(4, 1, 1, 200.0, 2.0, 0.0, 1), (5, 2, 1, 200.0, 2.0, 0.0, 1),
|
||||
(6, 0, 2, 133.33333333333334, 3.0, 0.0, 0), (7, 1, 2, 133.33333333333334, 3.0, 0.0, 0),
|
||||
(8, 2, 2, 133.33333333333334, 3.0, 0.0, 0), (9, 0, 3, 66.66666666666669, 4.0, 0.0, 1),
|
||||
(10, 1, 3, 66.66666666666669, 4.0, 0.0, 1), (11, 2, 3, 66.66666666666669, 4.0, 0.0, 1),
|
||||
(12, 0, 4, 53.33333333333335, 5.0, 0.0, 0), (13, 1, 4, 53.33333333333335, 5.0, 0.0, 0),
|
||||
(14, 2, 4, 53.33333333333335, 5.0, 0.0, 0)
|
||||
(0, 1, 0, 1.0, 1.0, 0.0, 0), (1, 2, 0, 100.0, 1.0, 0.0, 0),
|
||||
(2, 1, 1, 1.0, 2.0, 0.0, 1), (3, 2, 1, 200.0, 2.0, 0.0, 1),
|
||||
(4, 1, 2, 1.0, 3.0, 0.0, 0), (5, 2, 2, 133.33333333333334, 3.0, 0.0, 0),
|
||||
(6, 1, 3, 1.0, 4.0, 0.0, 1), (7, 2, 3, 66.66666666666669, 4.0, 0.0, 1),
|
||||
(8, 1, 4, 1.0, 5.0, 0.0, 0), (9, 2, 4, 53.33333333333335, 5.0, 0.0, 0)
|
||||
], dtype=order_dt)
|
||||
)
|
||||
else:
|
||||
record_arrays_close(
|
||||
pf.order_records,
|
||||
np.array([
|
||||
(0, 0, 0, 100.0, 1.0, 0.0, 0), (1, 0, 1, 200.0, 2.0, 0.0, 1),
|
||||
(2, 0, 2, 133.33333333333334, 3.0, 0.0, 0), (3, 0, 3, 66.66666666666669, 4.0, 0.0, 1),
|
||||
(4, 0, 4, 53.33333333333335, 5.0, 0.0, 0), (5, 1, 0, 100.0, 1.0, 0.0, 0),
|
||||
(6, 1, 1, 200.0, 2.0, 0.0, 1), (7, 1, 2, 133.33333333333334, 3.0, 0.0, 0),
|
||||
(8, 1, 3, 66.66666666666669, 4.0, 0.0, 1), (9, 1, 4, 53.33333333333335, 5.0, 0.0, 0),
|
||||
(10, 2, 0, 100.0, 1.0, 0.0, 0), (11, 2, 1, 200.0, 2.0, 0.0, 1),
|
||||
(12, 2, 2, 133.33333333333334, 3.0, 0.0, 0), (13, 2, 3, 66.66666666666669, 4.0, 0.0, 1),
|
||||
(14, 2, 4, 53.33333333333335, 5.0, 0.0, 0)
|
||||
(0, 1, 0, 1.0, 1.0, 0.0, 0), (1, 1, 1, 1.0, 2.0, 0.0, 1),
|
||||
(2, 1, 2, 1.0, 3.0, 0.0, 0), (3, 1, 3, 1.0, 4.0, 0.0, 1),
|
||||
(4, 1, 4, 1.0, 5.0, 0.0, 0), (5, 2, 0, 100.0, 1.0, 0.0, 0),
|
||||
(6, 2, 1, 200.0, 2.0, 0.0, 1), (7, 2, 2, 133.33333333333334, 3.0, 0.0, 0),
|
||||
(8, 2, 3, 66.66666666666669, 4.0, 0.0, 1), (9, 2, 4, 53.33333333333335, 5.0, 0.0, 0)
|
||||
], dtype=order_dt)
|
||||
)
|
||||
pd.testing.assert_index_equal(
|
||||
@@ -3560,14 +3556,12 @@ class TestFromOrderFunc:
|
||||
assert pf.wrapper.freq == day_dt
|
||||
assert pf.wrapper.grouper.group_by is None
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_group_by(self, test_row_wise, test_flexible):
|
||||
order_func = flex_order_func_nb if test_flexible else order_func_nb
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, np.inf,
|
||||
price_wide, order_func, np.asarray(np.inf),
|
||||
group_by=np.array([0, 0, 1]), row_wise=test_row_wise, flexible=test_flexible)
|
||||
if test_row_wise:
|
||||
record_arrays_close(
|
||||
@@ -3607,14 +3601,12 @@ class TestFromOrderFunc:
|
||||
)
|
||||
assert not pf.cash_sharing
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_cash_sharing(self, test_row_wise, test_flexible):
|
||||
order_func = flex_order_func_nb if test_flexible else order_func_nb
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, np.inf,
|
||||
price_wide, order_func, np.asarray(np.inf),
|
||||
group_by=np.array([0, 0, 1]), cash_sharing=True, row_wise=test_row_wise, flexible=test_flexible)
|
||||
if test_row_wise:
|
||||
record_arrays_close(
|
||||
@@ -3654,7 +3646,7 @@ class TestFromOrderFunc:
|
||||
)
|
||||
def test_call_seq(self, test_row_wise):
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1]),
|
||||
price_wide, order_func_nb, np.asarray(np.inf), group_by=np.array([0, 0, 1]),
|
||||
cash_sharing=True, row_wise=test_row_wise)
|
||||
if test_row_wise:
|
||||
record_arrays_close(
|
||||
@@ -3689,7 +3681,7 @@ class TestFromOrderFunc:
|
||||
])
|
||||
)
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1]),
|
||||
price_wide, order_func_nb, np.asarray(np.inf), group_by=np.array([0, 0, 1]),
|
||||
cash_sharing=True, call_seq='reversed', row_wise=test_row_wise)
|
||||
if test_row_wise:
|
||||
record_arrays_close(
|
||||
@@ -3724,7 +3716,7 @@ class TestFromOrderFunc:
|
||||
])
|
||||
)
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1]),
|
||||
price_wide, order_func_nb, np.asarray(np.inf), group_by=np.array([0, 0, 1]),
|
||||
cash_sharing=True, call_seq='random', seed=seed, row_wise=test_row_wise)
|
||||
if test_row_wise:
|
||||
record_arrays_close(
|
||||
@@ -3760,7 +3752,7 @@ class TestFromOrderFunc:
|
||||
)
|
||||
with pytest.raises(Exception):
|
||||
_ = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1]),
|
||||
price_wide, order_func_nb, np.asarray(np.inf), group_by=np.array([0, 0, 1]),
|
||||
cash_sharing=True, call_seq='auto', row_wise=test_row_wise
|
||||
)
|
||||
|
||||
@@ -3809,10 +3801,8 @@ class TestFromOrderFunc:
|
||||
target_hold_value
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_target_value(self, test_row_wise, test_flexible):
|
||||
@njit
|
||||
def target_val_pre_segment_func_nb(c, val_price):
|
||||
@@ -3870,10 +3860,8 @@ class TestFromOrderFunc:
|
||||
], dtype=order_dt)
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_target_percent(self, test_row_wise, test_flexible):
|
||||
@njit
|
||||
def target_pct_pre_segment_func_nb(c, val_price):
|
||||
@@ -3931,10 +3919,8 @@ class TestFromOrderFunc:
|
||||
], dtype=order_dt)
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_update_value(self, test_row_wise, test_flexible):
|
||||
if test_flexible:
|
||||
@njit
|
||||
@@ -4012,10 +3998,8 @@ class TestFromOrderFunc:
|
||||
])
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_states(self, test_row_wise, test_flexible):
|
||||
close = np.array([
|
||||
[1, 1, 1],
|
||||
@@ -4289,10 +4273,8 @@ class TestFromOrderFunc:
|
||||
pf.returns(in_sim_order=True, group_by=False).values
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_post_sim_ctx(self, test_row_wise, test_flexible):
|
||||
if test_flexible:
|
||||
def order_func(c):
|
||||
@@ -4579,10 +4561,8 @@ class TestFromOrderFunc:
|
||||
assert c.log_records[c.last_lidx[1]]['col'] == 1
|
||||
assert c.log_records[c.last_lidx[2]]['col'] == 2
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_free_cash(self, test_row_wise, test_flexible):
|
||||
if test_flexible:
|
||||
def order_func(c, size):
|
||||
@@ -4730,14 +4710,12 @@ class TestFromOrderFunc:
|
||||
pf.cash(free=True).values
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_init_cash(self, test_row_wise, test_flexible):
|
||||
order_func = flex_order_func_nb if test_flexible else order_func_nb
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, 10., row_wise=test_row_wise,
|
||||
price_wide, order_func, np.asarray(10.), row_wise=test_row_wise,
|
||||
init_cash=[1., 10., np.inf], flexible=test_flexible)
|
||||
if test_row_wise:
|
||||
record_arrays_close(
|
||||
@@ -4769,10 +4747,10 @@ class TestFromOrderFunc:
|
||||
)
|
||||
assert type(pf._init_cash) == np.ndarray
|
||||
base_pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, 10., row_wise=test_row_wise,
|
||||
price_wide, order_func, np.asarray(10.), row_wise=test_row_wise,
|
||||
init_cash=np.inf, flexible=test_flexible)
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, 10., row_wise=test_row_wise,
|
||||
price_wide, order_func, np.asarray(10.), row_wise=test_row_wise,
|
||||
init_cash=InitCashMode.Auto, flexible=test_flexible)
|
||||
record_arrays_close(
|
||||
pf.order_records,
|
||||
@@ -4780,7 +4758,7 @@ class TestFromOrderFunc:
|
||||
)
|
||||
assert pf._init_cash == InitCashMode.Auto
|
||||
pf = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, 10., row_wise=test_row_wise,
|
||||
price_wide, order_func, np.asarray(10.), row_wise=test_row_wise,
|
||||
init_cash=InitCashMode.AutoAlign, flexible=test_flexible)
|
||||
record_arrays_close(
|
||||
pf.order_records,
|
||||
@@ -5456,33 +5434,35 @@ class TestFromOrderFunc:
|
||||
assert list(order_lst) == [6, 8, 13, 15, 17, 22, 24, 26, 29, 31]
|
||||
assert list(post_order_lst) == [7, 14, 16, 23, 25, 30]
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_max_orders(self, test_row_wise, test_flexible):
|
||||
order_func = flex_order_func_nb if test_flexible else order_func_nb
|
||||
_ = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, np.inf, row_wise=test_row_wise, flexible=test_flexible)
|
||||
price_wide, order_func, np.asarray(np.inf),
|
||||
row_wise=test_row_wise, flexible=test_flexible)
|
||||
_ = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, np.inf, row_wise=test_row_wise, max_orders=15, flexible=test_flexible)
|
||||
price_wide, order_func, np.asarray(np.inf),
|
||||
row_wise=test_row_wise, max_orders=15, flexible=test_flexible)
|
||||
with pytest.raises(Exception):
|
||||
_ = vbt.Portfolio.from_order_func(
|
||||
price_wide, order_func, np.inf, row_wise=test_row_wise, max_orders=14, flexible=test_flexible)
|
||||
price_wide, order_func, np.asarray(np.inf),
|
||||
row_wise=test_row_wise, max_orders=14, flexible=test_flexible)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_row_wise,test_flexible",
|
||||
[[False, False], [False, True], [True, False], [True, True]],
|
||||
)
|
||||
@pytest.mark.parametrize("test_row_wise", [False, True])
|
||||
@pytest.mark.parametrize("test_flexible", [False, True])
|
||||
def test_max_logs(self, test_row_wise, test_flexible):
|
||||
log_order_func = log_flex_order_func_nb if test_flexible else log_order_func_nb
|
||||
_ = vbt.Portfolio.from_order_func(
|
||||
price_wide, log_order_func, np.inf, row_wise=test_row_wise, flexible=test_flexible)
|
||||
price_wide, log_order_func, np.asarray(np.inf),
|
||||
row_wise=test_row_wise, flexible=test_flexible)
|
||||
_ = vbt.Portfolio.from_order_func(
|
||||
price_wide, log_order_func, np.inf, row_wise=test_row_wise, max_logs=15, flexible=test_flexible)
|
||||
price_wide, log_order_func, np.asarray(np.inf),
|
||||
row_wise=test_row_wise, max_logs=15, flexible=test_flexible)
|
||||
with pytest.raises(Exception):
|
||||
_ = vbt.Portfolio.from_order_func(
|
||||
price_wide, log_order_func, np.inf, row_wise=test_row_wise, max_logs=14, flexible=test_flexible)
|
||||
price_wide, log_order_func, np.asarray(np.inf),
|
||||
row_wise=test_row_wise, max_logs=14, flexible=test_flexible)
|
||||
|
||||
|
||||
# ############# Portfolio ############# #
|
||||
@@ -7464,6 +7444,18 @@ class TestPortfolio:
|
||||
'Trades with PnL over $20'
|
||||
], name='a')
|
||||
)
|
||||
pd.testing.assert_frame_equal(
|
||||
pf.stats(metrics='total_trades', agg_func=None, settings=dict(trades_type='entry_trades')),
|
||||
pd.DataFrame([2, 2, 2], index=price_na.columns, columns=['Total Trades'])
|
||||
)
|
||||
pd.testing.assert_frame_equal(
|
||||
pf.stats(metrics='total_trades', agg_func=None, settings=dict(trades_type='exit_trades')),
|
||||
pd.DataFrame([2, 2, 2], index=price_na.columns, columns=['Total Trades'])
|
||||
)
|
||||
pd.testing.assert_frame_equal(
|
||||
pf.stats(metrics='total_trades', agg_func=None, settings=dict(trades_type='positions')),
|
||||
pd.DataFrame([2, 2, 2], index=price_na.columns, columns=['Total Trades'])
|
||||
)
|
||||
pd.testing.assert_series_equal(
|
||||
pf['c'].stats(),
|
||||
pf.stats(column='c')
|
||||
|
||||
@@ -2067,7 +2067,7 @@ class Portfolio(Wrapping, StatsBuilderMixin, PlotsBuilderMixin, metaclass=MetaPo
|
||||
|
||||
You have three options to provide signals:
|
||||
|
||||
1) `entries` and `exits`: The direction of each pair of signals is taken from `direction` argument.
|
||||
* `entries` and `exits`: The direction of each pair of signals is taken from `direction` argument.
|
||||
Best to use when the direction doesn't change throughout time.
|
||||
|
||||
Uses `vectorbt.portfolio.nb.dir_enex_signal_func_nb` as `signal_func_nb`.
|
||||
@@ -2078,12 +2078,14 @@ class Portfolio(Wrapping, StatsBuilderMixin, PlotsBuilderMixin, metaclass=MetaPo
|
||||
* (True, True, 'longonly') -> True, True, False, False
|
||||
* (True, True, 'shortonly') -> False, False, True, True
|
||||
* (True, True, 'both') -> True, False, True, False
|
||||
2) `entries` (acting as long), `exits` (acting as long), `short_entries`, and `short_exits`:
|
||||
|
||||
* `entries` (acting as long), `exits` (acting as long), `short_entries`, and `short_exits`:
|
||||
The direction is already built into the arrays. Best to use when the direction changes frequently
|
||||
(for example, if you have one indicator providing long signals and one providing short signals).
|
||||
|
||||
Uses `vectorbt.portfolio.nb.ls_enex_signal_func_nb` as `signal_func_nb`.
|
||||
3) `signal_func_nb` and `signal_args`: Custom signal function that returns direction-aware signals.
|
||||
|
||||
* `signal_func_nb` and `signal_args`: Custom signal function that returns direction-aware signals.
|
||||
Best to use when signals should be placed dynamically based on custom conditions.
|
||||
|
||||
Args:
|
||||
@@ -2150,10 +2152,8 @@ class Portfolio(Wrapping, StatsBuilderMixin, PlotsBuilderMixin, metaclass=MetaPo
|
||||
See `vectorbt.portfolio.enums.ConflictMode`. Will broadcast.
|
||||
upon_short_conflict (ConflictMode or array_like): Conflict mode for short signals.
|
||||
See `vectorbt.portfolio.enums.ConflictMode`. Will broadcast.
|
||||
upon_dir_conflict (DirectionConflictMode or array_like):
|
||||
See `vectorbt.portfolio.enums.DirectionConflictMode`. Will broadcast.
|
||||
upon_opposite_entry (OppositeEntryMode or array_like):
|
||||
See `vectorbt.portfolio.enums.OppositeEntryMode`. Will broadcast.
|
||||
upon_dir_conflict (DirectionConflictMode or array_like): See `vectorbt.portfolio.enums.DirectionConflictMode`. Will broadcast.
|
||||
upon_opposite_entry (OppositeEntryMode or array_like): See `vectorbt.portfolio.enums.OppositeEntryMode`. Will broadcast.
|
||||
direction (Direction or array_like): See `Portfolio.from_orders`.
|
||||
|
||||
Takes only effect if `short_entries` and `short_exits` are not set.
|
||||
@@ -3194,9 +3194,6 @@ class Portfolio(Wrapping, StatsBuilderMixin, PlotsBuilderMixin, metaclass=MetaPo
|
||||
cash_sharing (bool): Whether to share cash within the same group.
|
||||
|
||||
If `group_by` is None, `group_by` becomes True to form a single group with cash sharing.
|
||||
|
||||
!!! warning
|
||||
Introduces cross-asset dependencies.
|
||||
call_seq (CallSeqType or array_like): Default sequence of calls per row and group.
|
||||
|
||||
* Use `vectorbt.portfolio.enums.CallSeqType` to select a sequence type.
|
||||
|
||||
Reference in New Issue
Block a user