Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
polakowo
GitHub Repository: polakowo/vectorbt
Path: blob/master/tests/notebooks/portfolio.ipynb
1073 views
Kernel: Python 3 (ipykernel)
import vectorbt as vbt from vectorbt.portfolio.enums import * import numpy as np import pandas as pd from numba import njit from datetime import datetime, timedelta seed = 42 price = pd.Series([1., 2., 3., 4., 5.], index=pd.Index([ datetime(2020, 1, 1), datetime(2020, 1, 2), datetime(2020, 1, 3), datetime(2020, 1, 4), datetime(2020, 1, 5) ])) price_wide = price.vbt.tile(3, keys=['a', 'b', 'c']) print(price.shape, price_wide.shape) big_price = pd.DataFrame(np.random.uniform(0.9, 1.1, size=(1000,))) big_price.index = [datetime(2018, 1, 1) + timedelta(days=i) for i in range(1000)] big_price_wide = big_price.vbt.tile(1000) print(big_price.shape, big_price_wide.shape) # Disable caching for performance testing # NOTE: Expect waterfall of executions, since some attributes depend on other attributes # that have to be calculated again and again vbt.settings.caching['enabled'] = False vbt.settings.portfolio['attach_call_seq'] = True
(5,) (5, 3) (1000, 1) (1000, 1000)

from_orders

order_size = pd.Series([np.inf, -np.inf, np.nan, np.inf, -np.inf], index=price.index) order_size_wide = order_size.vbt.tile(3, keys=['a', 'b', 'c']) big_order_size = pd.DataFrame.vbt.empty((1000,), 1, dtype=np.float64) big_order_size.iloc[1::2] = -1 big_order_size_wide = big_order_size.vbt.tile(1000)
%timeit vbt.Portfolio.from_orders(big_price, big_order_size, init_cash=np.inf)
2.24 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vbt.Portfolio.from_orders(big_price_wide, big_order_size_wide, init_cash=np.inf)
67 ms ± 2.3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_orders(\ big_price_wide, big_order_size_wide, init_cash=np.inf, \ group_by=np.repeat(np.arange(500), 2))
64.3 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_orders(\ big_price_wide, big_order_size_wide, init_cash=np.inf, \ group_by=np.repeat(np.arange(500), 2), cash_sharing=True)
65.9 ms ± 1.68 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_orders(\ big_price_wide, big_order_size_wide, init_cash=np.inf, \ group_by=np.repeat(np.arange(500), 2), cash_sharing=True, call_seq=CallSeqType.Auto)
71.7 ms ± 510 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_orders(\ big_price_wide, big_order_size_wide, init_cash=np.inf, \ group_by=np.full(1000, 0))
66.3 ms ± 285 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_orders(\ big_price_wide, big_order_size_wide, init_cash=np.inf, \ group_by=np.full(1000, 0), cash_sharing=True)
63.7 ms ± 728 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vbt.Portfolio.from_orders(\ big_price_wide, big_order_size_wide, init_cash=np.inf, \ group_by=np.full(1000, 0), cash_sharing=True, call_seq=CallSeqType.Auto)
68.3 ms ± 443 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
def test_per_direction(price=price, size=order_size, **kwargs): print('Both') try: portfolio = vbt.Portfolio.from_orders(price, size, direction='both', **kwargs) print(portfolio.orders.records) except Exception as e: print(e) print('LongOnly') try: portfolio = vbt.Portfolio.from_orders(price, size, direction='longonly', **kwargs) print(portfolio.orders.records) except Exception as e: print(e) print('ShortOnly') try: portfolio = vbt.Portfolio.from_orders(price, size, direction='shortonly', **kwargs) print(portfolio.orders.records) except Exception as e: print(e)
test_per_direction()
All id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 200.0 2.0 0.0 1 2 2 3 0 100.0 4.0 0.0 0 LongOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 100.0 2.0 0.0 1 2 2 3 0 50.0 4.0 0.0 0 3 3 4 0 50.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 1 1 1 1 0 100.0 2.0 0.0 0
test_per_direction(price=price_wide)
All id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 200.0 2.0 0.0 1 2 2 3 0 100.0 4.0 0.0 0 3 3 0 1 100.0 1.0 0.0 0 4 4 1 1 200.0 2.0 0.0 1 5 5 3 1 100.0 4.0 0.0 0 6 6 0 2 100.0 1.0 0.0 0 7 7 1 2 200.0 2.0 0.0 1 8 8 3 2 100.0 4.0 0.0 0 LongOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 100.0 2.0 0.0 1 2 2 3 0 50.0 4.0 0.0 0 3 3 4 0 50.0 5.0 0.0 1 4 4 0 1 100.0 1.0 0.0 0 5 5 1 1 100.0 2.0 0.0 1 6 6 3 1 50.0 4.0 0.0 0 7 7 4 1 50.0 5.0 0.0 1 8 8 0 2 100.0 1.0 0.0 0 9 9 1 2 100.0 2.0 0.0 1 10 10 3 2 50.0 4.0 0.0 0 11 11 4 2 50.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 1 1 1 1 0 100.0 2.0 0.0 0 2 2 0 1 100.0 1.0 0.0 1 3 3 1 1 100.0 2.0 0.0 0 4 4 0 2 100.0 1.0 0.0 1 5 5 1 2 100.0 2.0 0.0 0
test_per_direction(size=[[np.inf, -np.inf]])
All id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 1 100.0 1.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 ShortOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 1
order_size_one = pd.Series([1, -1, np.nan, 1, -1], index=price.index)
test_per_direction(price=price * 1.01)
All id idx col size price fees side 0 0 0 0 99.009901 1.01 0.0 0 1 1 1 0 198.019802 2.02 0.0 1 2 2 3 0 99.009901 4.04 0.0 0 LongOnly id idx col size price fees side 0 0 0 0 99.009901 1.01 0.0 0 1 1 1 0 99.009901 2.02 0.0 1 2 2 3 0 49.504950 4.04 0.0 0 3 3 4 0 49.504950 5.05 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 99.009901 1.01 0.0 1 1 1 1 0 99.009901 2.02 0.0 0
test_per_direction(size=order_size_one, fees=[[0., 0.1, 1.]])
All id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.0 0.1 0 5 5 1 1 1.0 2.0 0.2 1 6 6 3 1 1.0 4.0 0.4 0 7 7 4 1 1.0 5.0 0.5 1 8 8 0 2 1.0 1.0 1.0 0 9 9 1 2 1.0 2.0 2.0 1 10 10 3 2 1.0 4.0 4.0 0 11 11 4 2 1.0 5.0 5.0 1 LongOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.0 0.1 0 5 5 1 1 1.0 2.0 0.2 1 6 6 3 1 1.0 4.0 0.4 0 7 7 4 1 1.0 5.0 0.5 1 8 8 0 2 1.0 1.0 1.0 0 9 9 1 2 1.0 2.0 2.0 1 10 10 3 2 1.0 4.0 4.0 0 11 11 4 2 1.0 5.0 5.0 1 ShortOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 1 0 1.0 2.0 0.0 0 2 2 3 0 1.0 4.0 0.0 1 3 3 4 0 1.0 5.0 0.0 0 4 4 0 1 1.0 1.0 0.1 1 5 5 1 1 1.0 2.0 0.2 0 6 6 3 1 1.0 4.0 0.4 1 7 7 4 1 1.0 5.0 0.5 0 8 8 0 2 1.0 1.0 1.0 1 9 9 1 2 1.0 2.0 2.0 0 10 10 3 2 1.0 4.0 4.0 1 11 11 4 2 1.0 5.0 5.0 0
test_per_direction(size=order_size_one, fixed_fees=[[0., 0.1, 1.]])
All id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.0 0.1 0 5 5 1 1 1.0 2.0 0.1 1 6 6 3 1 1.0 4.0 0.1 0 7 7 4 1 1.0 5.0 0.1 1 8 8 0 2 1.0 1.0 1.0 0 9 9 1 2 1.0 2.0 1.0 1 10 10 3 2 1.0 4.0 1.0 0 11 11 4 2 1.0 5.0 1.0 1 LongOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.0 0.1 0 5 5 1 1 1.0 2.0 0.1 1 6 6 3 1 1.0 4.0 0.1 0 7 7 4 1 1.0 5.0 0.1 1 8 8 0 2 1.0 1.0 1.0 0 9 9 1 2 1.0 2.0 1.0 1 10 10 3 2 1.0 4.0 1.0 0 11 11 4 2 1.0 5.0 1.0 1 ShortOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 1 0 1.0 2.0 0.0 0 2 2 3 0 1.0 4.0 0.0 1 3 3 4 0 1.0 5.0 0.0 0 4 4 0 1 1.0 1.0 0.1 1 5 5 1 1 1.0 2.0 0.1 0 6 6 3 1 1.0 4.0 0.1 1 7 7 4 1 1.0 5.0 0.1 0 8 8 0 2 1.0 1.0 1.0 1 9 9 1 2 1.0 2.0 1.0 0 10 10 3 2 1.0 4.0 1.0 1 11 11 4 2 1.0 5.0 1.0 0
test_per_direction(size=order_size_one, slippage=[[0., 0.1, 1.]])
All id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.1 0.0 0 5 5 1 1 1.0 1.8 0.0 1 6 6 3 1 1.0 4.4 0.0 0 7 7 4 1 1.0 4.5 0.0 1 8 8 0 2 1.0 2.0 0.0 0 9 9 1 2 1.0 0.0 0.0 1 10 10 3 2 1.0 8.0 0.0 0 11 11 4 2 1.0 0.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.1 0.0 0 5 5 1 1 1.0 1.8 0.0 1 6 6 3 1 1.0 4.4 0.0 0 7 7 4 1 1.0 4.5 0.0 1 8 8 0 2 1.0 2.0 0.0 0 9 9 1 2 1.0 0.0 0.0 1 10 10 3 2 1.0 8.0 0.0 0 11 11 4 2 1.0 0.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 1 0 1.0 2.0 0.0 0 2 2 3 0 1.0 4.0 0.0 1 3 3 4 0 1.0 5.0 0.0 0 4 4 0 1 1.0 0.9 0.0 1 5 5 1 1 1.0 2.2 0.0 0 6 6 3 1 1.0 3.6 0.0 1 7 7 4 1 1.0 5.5 0.0 0 8 8 0 2 1.0 0.0 0.0 1 9 9 1 2 1.0 4.0 0.0 0 10 10 3 2 1.0 0.0 0.0 1 11 11 4 2 1.0 10.0 0.0 0
test_per_direction(size=order_size_one, min_size=[[0., 1., 2.]])
All id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.0 0.0 0 5 5 1 1 1.0 2.0 0.0 1 6 6 3 1 1.0 4.0 0.0 0 7 7 4 1 1.0 5.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 0 1 1.0 1.0 0.0 0 5 5 1 1 1.0 2.0 0.0 1 6 6 3 1 1.0 4.0 0.0 0 7 7 4 1 1.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 1 0 1.0 2.0 0.0 0 2 2 3 0 1.0 4.0 0.0 1 3 3 4 0 1.0 5.0 0.0 0 4 4 0 1 1.0 1.0 0.0 1 5 5 1 1 1.0 2.0 0.0 0 6 6 3 1 1.0 4.0 0.0 1 7 7 4 1 1.0 5.0 0.0 0
test_per_direction(size=order_size_one, max_size=[[0.5, 1., np.inf]])
All id idx col size price fees side 0 0 0 0 0.5 1.0 0.0 0 1 1 1 0 0.5 2.0 0.0 1 2 2 3 0 0.5 4.0 0.0 0 3 3 4 0 0.5 5.0 0.0 1 4 4 0 1 1.0 1.0 0.0 0 5 5 1 1 1.0 2.0 0.0 1 6 6 3 1 1.0 4.0 0.0 0 7 7 4 1 1.0 5.0 0.0 1 8 8 0 2 1.0 1.0 0.0 0 9 9 1 2 1.0 2.0 0.0 1 10 10 3 2 1.0 4.0 0.0 0 11 11 4 2 1.0 5.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 0.5 1.0 0.0 0 1 1 1 0 0.5 2.0 0.0 1 2 2 3 0 0.5 4.0 0.0 0 3 3 4 0 0.5 5.0 0.0 1 4 4 0 1 1.0 1.0 0.0 0 5 5 1 1 1.0 2.0 0.0 1 6 6 3 1 1.0 4.0 0.0 0 7 7 4 1 1.0 5.0 0.0 1 8 8 0 2 1.0 1.0 0.0 0 9 9 1 2 1.0 2.0 0.0 1 10 10 3 2 1.0 4.0 0.0 0 11 11 4 2 1.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 0.5 1.0 0.0 1 1 1 1 0 0.5 2.0 0.0 0 2 2 3 0 0.5 4.0 0.0 1 3 3 4 0 0.5 5.0 0.0 0 4 4 0 1 1.0 1.0 0.0 1 5 5 1 1 1.0 2.0 0.0 0 6 6 3 1 1.0 4.0 0.0 1 7 7 4 1 1.0 5.0 0.0 0 8 8 0 2 1.0 1.0 0.0 1 9 9 1 2 1.0 2.0 0.0 0 10 10 3 2 1.0 4.0 0.0 1 11 11 4 2 1.0 5.0 0.0 0
test_per_direction(size=order_size_one, reject_prob=[[0., 0.5, 1.]], seed=42)
All id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 1 1 1.0 2.0 0.0 1 5 5 3 1 1.0 4.0 0.0 0 6 6 4 1 1.0 5.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 1 0 1.0 2.0 0.0 1 2 2 3 0 1.0 4.0 0.0 0 3 3 4 0 1.0 5.0 0.0 1 4 4 3 1 1.0 4.0 0.0 0 5 5 4 1 1.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 1 0 1.0 2.0 0.0 0 2 2 3 0 1.0 4.0 0.0 1 3 3 4 0 1.0 5.0 0.0 0 4 4 3 1 1.0 4.0 0.0 1 5 5 4 1 1.0 5.0 0.0 0
test_per_direction(size=pd.Series([np.inf, -np.inf, -np.inf, np.inf, np.inf]), close_first=[[False, True]])
All __init__() got an unexpected keyword argument 'close_first' LongOnly __init__() got an unexpected keyword argument 'close_first' ShortOnly __init__() got an unexpected keyword argument 'close_first'
test_per_direction(size=order_size_one * 1000, allow_partial=[[True, False]]) test_per_direction(size=order_size, allow_partial=[[True, False]])
All id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 1000.0 2.0 0.0 1 2 2 3 0 500.0 4.0 0.0 0 3 3 4 0 1000.0 5.0 0.0 1 4 4 1 1 1000.0 2.0 0.0 1 5 5 4 1 1000.0 5.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 100.0 2.0 0.0 1 2 2 3 0 50.0 4.0 0.0 0 3 3 4 0 50.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 1000.0 1.0 0.0 1 1 1 1 0 550.0 2.0 0.0 0 2 2 3 0 1000.0 4.0 0.0 1 3 3 4 0 800.0 5.0 0.0 0 4 4 0 1 1000.0 1.0 0.0 1 5 5 3 1 1000.0 4.0 0.0 1 6 6 4 1 1000.0 5.0 0.0 0 All id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 200.0 2.0 0.0 1 2 2 3 0 100.0 4.0 0.0 0 3 3 0 1 100.0 1.0 0.0 0 4 4 1 1 200.0 2.0 0.0 1 5 5 3 1 100.0 4.0 0.0 0 LongOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 100.0 2.0 0.0 1 2 2 3 0 50.0 4.0 0.0 0 3 3 4 0 50.0 5.0 0.0 1 4 4 0 1 100.0 1.0 0.0 0 5 5 1 1 100.0 2.0 0.0 1 6 6 3 1 50.0 4.0 0.0 0 7 7 4 1 50.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 1 1 1 1 0 100.0 2.0 0.0 0 2 2 0 1 100.0 1.0 0.0 1 3 3 1 1 100.0 2.0 0.0 0
test_per_direction(size=order_size_one * 1000, allow_partial=True, raise_reject=True) test_per_direction(size=order_size_one * 1000, allow_partial=False, raise_reject=True)
All id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 1000.0 2.0 0.0 1 2 2 3 0 500.0 4.0 0.0 0 3 3 4 0 1000.0 5.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 100.0 2.0 0.0 1 2 2 3 0 50.0 4.0 0.0 0 3 3 4 0 50.0 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 1000.0 1.0 0.0 1 1 1 1 0 550.0 2.0 0.0 0 2 2 3 0 1000.0 4.0 0.0 1 3 3 4 0 800.0 5.0 0.0 0 All Final size is less than requested LongOnly Final size is less than requested ShortOnly Final size is less than requested
portfolio = vbt.Portfolio.from_orders(price, order_size, log=True, direction='both') print(portfolio.logs.records)
id idx col group cash position debt free_cash val_price value \ 0 0 0 0 0 100.0 0.0 0.0 100.0 1.0 100.0 1 1 1 0 0 0.0 100.0 0.0 0.0 2.0 200.0 2 2 2 0 0 400.0 -100.0 200.0 0.0 3.0 100.0 3 3 3 0 0 400.0 -100.0 200.0 0.0 4.0 0.0 4 4 4 0 0 0.0 0.0 0.0 0.0 5.0 0.0 ... new_free_cash new_val_price new_value res_size res_price \ 0 ... 0.0 1.0 100.0 100.0 1.0 1 ... 0.0 2.0 200.0 200.0 2.0 2 ... 0.0 3.0 100.0 NaN NaN 3 ... 0.0 4.0 0.0 100.0 4.0 4 ... 0.0 5.0 0.0 NaN NaN res_fees res_side res_status res_status_info order_id 0 0.0 0 0 -1 0 1 0.0 1 0 -1 1 2 NaN -1 1 0 -1 3 0.0 0 0 -1 2 4 NaN -1 2 6 -1 [5 rows x 37 columns]
portfolio = vbt.Portfolio.from_orders( price_wide, order_size, group_by=np.array([0, 0, 1]), direction='both') print(portfolio.orders.records)
id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 200.0 2.0 0.0 1 2 2 3 0 100.0 4.0 0.0 0 3 3 0 1 100.0 1.0 0.0 0 4 4 1 1 200.0 2.0 0.0 1 5 5 3 1 100.0 4.0 0.0 0 6 6 0 2 100.0 1.0 0.0 0 7 7 1 2 200.0 2.0 0.0 1 8 8 3 2 100.0 4.0 0.0 0
portfolio = vbt.Portfolio.from_orders( price_wide, order_size, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both') print(portfolio.orders.records) print(portfolio.call_seq)
id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 200.0 2.0 0.0 1 2 2 3 0 100.0 4.0 0.0 0 3 3 0 2 100.0 1.0 0.0 0 4 4 1 2 200.0 2.0 0.0 1 5 5 3 2 100.0 4.0 0.0 0 a b c 2020-01-01 0 1 0 2020-01-02 0 1 0 2020-01-03 0 1 0 2020-01-04 0 1 0 2020-01-05 0 1 0
portfolio = vbt.Portfolio.from_orders( price_wide, order_size, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='reversed') print(portfolio.orders.records) print(portfolio.call_seq)
id idx col size price fees side 0 0 0 1 100.0 1.0 0.0 0 1 1 1 1 200.0 2.0 0.0 1 2 2 3 1 100.0 4.0 0.0 0 3 3 0 2 100.0 1.0 0.0 0 4 4 1 2 200.0 2.0 0.0 1 5 5 3 2 100.0 4.0 0.0 0 a b c 2020-01-01 1 0 0 2020-01-02 1 0 0 2020-01-03 1 0 0 2020-01-04 1 0 0 2020-01-05 1 0 0
portfolio = vbt.Portfolio.from_orders( price_wide, order_size, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random') print(portfolio.orders.records) print(portfolio.call_seq) portfolio = vbt.Portfolio.from_orders( price_wide, order_size, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random', seed=42) print(portfolio.orders.records) print(portfolio.call_seq)
id idx col size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 1 0 200.0 2.0 0.0 1 2 2 3 1 100.0 4.0 0.0 0 3 3 4 1 120.0 5.0 0.0 1 4 4 0 2 100.0 1.0 0.0 0 5 5 1 2 200.0 2.0 0.0 1 6 6 3 2 100.0 4.0 0.0 0 a b c 2020-01-01 0 1 0 2020-01-02 0 1 0 2020-01-03 0 1 0 2020-01-04 1 0 0 2020-01-05 0 1 0 id idx col size price fees side 0 0 0 1 100.0 1.0 0.0 0 1 1 1 1 200.0 2.0 0.0 1 2 2 3 1 100.0 4.0 0.0 0 3 3 0 2 100.0 1.0 0.0 0 4 4 1 2 200.0 2.0 0.0 1 5 5 3 2 100.0 4.0 0.0 0 a b c 2020-01-01 1 0 0 2020-01-02 0 1 0 2020-01-03 1 0 0 2020-01-04 1 0 0 2020-01-05 1 0 0
for direction in ('Both', 'LongOnly', 'ShortOnly'): print(direction) portfolio = vbt.Portfolio.from_orders(1., pd.DataFrame([ [0., 0., np.inf], [0., np.inf, -np.inf], [np.inf, -np.inf, 0.], [-np.inf, 0., np.inf], [0., np.inf, -np.inf], ]), group_by=np.array([0, 0, 0]), cash_sharing=True, call_seq='auto', direction=direction) print(portfolio.orders.records) print(portfolio.call_seq) print(portfolio.assets()) print(portfolio.value()) # notice how shorting with np.inf only accounts for current cash, not for other assets!
All id idx col size price fees side 0 0 0 2 100.0 1.0 0.0 0 1 1 1 2 200.0 1.0 0.0 1 2 2 1 1 200.0 1.0 0.0 0 3 3 2 1 200.0 1.0 0.0 1 4 4 2 0 200.0 1.0 0.0 0 5 5 3 0 200.0 1.0 0.0 1 6 6 3 2 200.0 1.0 0.0 0 7 7 4 2 200.0 1.0 0.0 1 8 8 4 1 200.0 1.0 0.0 0 0 1 2 0 0 1 2 1 2 0 1 2 1 2 0 3 0 1 2 4 2 0 1 0 1 2 0 0.0 0.0 100.0 1 0.0 200.0 -100.0 2 200.0 0.0 -100.0 3 0.0 0.0 100.0 4 0.0 200.0 -100.0 0 100.0 1 100.0 2 100.0 3 100.0 4 100.0 dtype: float64 LongOnly id idx col size price fees side 0 0 0 2 100.0 1.0 0.0 0 1 1 1 2 100.0 1.0 0.0 1 2 2 1 1 100.0 1.0 0.0 0 3 3 2 1 100.0 1.0 0.0 1 4 4 2 0 100.0 1.0 0.0 0 5 5 3 0 100.0 1.0 0.0 1 6 6 3 2 100.0 1.0 0.0 0 7 7 4 2 100.0 1.0 0.0 1 8 8 4 1 100.0 1.0 0.0 0 0 1 2 0 0 1 2 1 2 0 1 2 1 2 0 3 0 1 2 4 2 0 1 0 1 2 0 0.0 0.0 100.0 1 0.0 100.0 0.0 2 100.0 0.0 0.0 3 0.0 0.0 100.0 4 0.0 100.0 0.0 0 100.0 1 100.0 2 100.0 3 100.0 4 100.0 dtype: float64 ShortOnly id idx col size price fees side 0 0 0 2 100.0 1.0 0.0 1 1 1 1 2 100.0 1.0 0.0 0 2 2 2 0 100.0 1.0 0.0 1 3 3 3 0 100.0 1.0 0.0 0 4 4 4 1 100.0 1.0 0.0 1 0 1 2 0 2 0 1 1 1 0 2 2 0 2 1 3 2 1 0 4 1 0 2 0 1 2 0 0.0 0.0 -100.0 1 0.0 0.0 0.0 2 -100.0 0.0 0.0 3 0.0 0.0 0.0 4 0.0 -100.0 0.0 0 100.0 1 100.0 2 100.0 3 100.0 4 100.0 dtype: float64
test_per_direction(size=[[75., -75.]], size_type=SizeType.TargetAmount) portfolio = vbt.Portfolio.from_orders( price, [[75., -75.]], size_type=SizeType.TargetAmount, direction='both') print(portfolio.assets()) portfolio = vbt.Portfolio.from_orders( price_wide, 75., size_type=SizeType.TargetAmount, group_by=np.array([0, 0, 0]), cash_sharing=True, direction='both') print(portfolio.orders.records) print(portfolio.assets())
All id idx col size price fees side 0 0 0 0 75.0 1.0 0.0 0 1 1 0 1 75.0 1.0 0.0 1 LongOnly id idx col size price fees side 0 0 0 0 75.0 1.0 0.0 0 ShortOnly id idx col size price fees side 0 0 0 0 75.0 1.0 0.0 1 0 1 2020-01-01 75.0 -75.0 2020-01-02 75.0 -75.0 2020-01-03 75.0 -75.0 2020-01-04 75.0 -75.0 2020-01-05 75.0 -75.0 id idx col size price fees side 0 0 0 0 75.0 1.0 0.0 0 1 1 0 1 25.0 1.0 0.0 0 a b c 2020-01-01 75.0 25.0 0.0 2020-01-02 75.0 25.0 0.0 2020-01-03 75.0 25.0 0.0 2020-01-04 75.0 25.0 0.0 2020-01-05 75.0 25.0 0.0
test_per_direction(size=[[50., -50.]], size_type=SizeType.TargetValue) portfolio = vbt.Portfolio.from_orders( price, [[50., -50.]], size_type=SizeType.TargetValue, direction='both') print(portfolio.asset_value()) portfolio = vbt.Portfolio.from_orders( price_wide, 50., size_type=SizeType.TargetValue, group_by=np.array([0, 0, 0]), cash_sharing=True, direction='both') print(portfolio.orders.records) print(portfolio.asset_value(group_by=False))
All id idx col size price fees side 0 0 0 0 50.000000 1.0 0.0 0 1 1 1 0 25.000000 2.0 0.0 1 2 2 2 0 8.333333 3.0 0.0 1 3 3 3 0 4.166667 4.0 0.0 1 4 4 4 0 2.500000 5.0 0.0 1 5 5 0 1 50.000000 1.0 0.0 1 6 6 1 1 25.000000 2.0 0.0 0 7 7 2 1 8.333333 3.0 0.0 0 8 8 3 1 4.166667 4.0 0.0 0 9 9 4 1 2.500000 5.0 0.0 0 LongOnly id idx col size price fees side 0 0 0 0 50.000000 1.0 0.0 0 1 1 1 0 25.000000 2.0 0.0 1 2 2 2 0 8.333333 3.0 0.0 1 3 3 3 0 4.166667 4.0 0.0 1 4 4 4 0 2.500000 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 50.000000 1.0 0.0 1 1 1 1 0 25.000000 2.0 0.0 0 2 2 2 0 8.333333 3.0 0.0 0 3 3 3 0 4.166667 4.0 0.0 0 4 4 4 0 2.500000 5.0 0.0 0 0 1 2020-01-01 50.0 -50.0 2020-01-02 50.0 -50.0 2020-01-03 50.0 -50.0 2020-01-04 50.0 -50.0 2020-01-05 50.0 -50.0 id idx col size price fees side 0 0 0 0 50.000000 1.0 0.0 0 1 1 0 1 50.000000 1.0 0.0 0 2 2 1 0 25.000000 2.0 0.0 1 3 3 1 1 25.000000 2.0 0.0 1 4 4 1 2 25.000000 2.0 0.0 0 5 5 2 0 8.333333 3.0 0.0 1 6 6 2 1 8.333333 3.0 0.0 1 7 7 2 2 8.333333 3.0 0.0 1 8 8 3 0 4.166667 4.0 0.0 1 9 9 3 1 4.166667 4.0 0.0 1 10 10 3 2 4.166667 4.0 0.0 1 11 11 4 0 2.500000 5.0 0.0 1 12 12 4 1 2.500000 5.0 0.0 1 13 13 4 2 2.500000 5.0 0.0 1 a b c 2020-01-01 50.0 50.0 0.0 2020-01-02 50.0 50.0 50.0 2020-01-03 50.0 50.0 50.0 2020-01-04 50.0 50.0 50.0 2020-01-05 50.0 50.0 50.0
test_per_direction(size=[[0.5, -0.5]], size_type=SizeType.TargetPercent) portfolio = vbt.Portfolio.from_orders( price, [[0.5, -0.5]], size_type=SizeType.TargetPercent, direction='both') print(portfolio.asset_value() / portfolio.value()) portfolio = vbt.Portfolio.from_orders( price_wide, 0.5, size_type=SizeType.TargetPercent, group_by=np.array([0, 0, 0]), cash_sharing=True, direction='both') print(portfolio.orders.records) print(portfolio.asset_value(group_by=False) / portfolio.value(group_by=False))
All id idx col size price fees side 0 0 0 0 50.000000 1.0 0.0 0 1 1 1 0 12.500000 2.0 0.0 1 2 2 2 0 6.250000 3.0 0.0 1 3 3 3 0 3.906250 4.0 0.0 1 4 4 4 0 2.734375 5.0 0.0 1 5 5 0 1 50.000000 1.0 0.0 1 6 6 1 1 37.500000 2.0 0.0 0 7 7 2 1 6.250000 3.0 0.0 0 8 8 3 1 2.343750 4.0 0.0 0 9 9 4 1 1.171875 5.0 0.0 0 LongOnly id idx col size price fees side 0 0 0 0 50.000000 1.0 0.0 0 1 1 1 0 12.500000 2.0 0.0 1 2 2 2 0 6.250000 3.0 0.0 1 3 3 3 0 3.906250 4.0 0.0 1 4 4 4 0 2.734375 5.0 0.0 1 ShortOnly id idx col size price fees side 0 0 0 0 50.000000 1.0 0.0 1 1 1 1 0 37.500000 2.0 0.0 0 2 2 2 0 6.250000 3.0 0.0 0 3 3 3 0 2.343750 4.0 0.0 0 4 4 4 0 1.171875 5.0 0.0 0 0 1 2020-01-01 0.5 -0.5 2020-01-02 0.5 -0.5 2020-01-03 0.5 -0.5 2020-01-04 0.5 -0.5 2020-01-05 0.5 -0.5 id idx col size price fees side 0 0 0 0 50.0 1.0 0.0 0 1 1 0 1 50.0 1.0 0.0 0 a b c 2020-01-01 0.500000 0.500000 0.0 2020-01-02 0.666667 0.666667 0.0 2020-01-03 0.750000 0.750000 0.0 2020-01-04 0.800000 0.800000 0.0 2020-01-05 0.833333 0.833333 0.0
price_one = pd.Series([1., 1., 1., 1., 1.], index=price.index) target_hold_value = pd.DataFrame({ 'a': [0., 70., 30., 0., 70.], 'b': [30., 0., 70., 30., 30.], 'c': [70., 30., 0., 70., 0.] }, index=price.index) print(target_hold_value)
a b c 2020-01-01 0.0 30.0 70.0 2020-01-02 70.0 0.0 30.0 2020-01-03 30.0 70.0 0.0 2020-01-04 0.0 30.0 70.0 2020-01-05 70.0 30.0 0.0
portfolio = vbt.Portfolio.from_orders( price_one, target_hold_value, size_type=SizeType.TargetValue, group_by=np.array([0, 0, 0]), cash_sharing=True, call_seq='random', seed=43) print(portfolio.orders.records) print(portfolio.asset_flow()) print(portfolio.asset_value(group_by=False)) # order fixed -> cannot rebalance properly print(portfolio.call_seq)
id idx col size price fees side 0 0 0 1 30.0 1.0 0.0 0 1 1 0 2 70.0 1.0 0.0 0 2 2 1 2 40.0 1.0 0.0 1 3 3 1 1 30.0 1.0 0.0 1 4 4 2 1 70.0 1.0 0.0 0 5 5 2 2 30.0 1.0 0.0 1 6 6 3 2 30.0 1.0 0.0 0 7 7 3 1 40.0 1.0 0.0 1 8 8 4 0 40.0 1.0 0.0 0 9 9 4 2 30.0 1.0 0.0 1 a b c 2020-01-01 0.0 30.0 70.0 2020-01-02 0.0 -30.0 -40.0 2020-01-03 0.0 70.0 -30.0 2020-01-04 0.0 -40.0 30.0 2020-01-05 40.0 0.0 -30.0 a b c 2020-01-01 0.0 30.0 70.0 2020-01-02 0.0 0.0 30.0 2020-01-03 0.0 70.0 0.0 2020-01-04 0.0 30.0 30.0 2020-01-05 40.0 30.0 0.0 a b c 2020-01-01 1 2 0 2020-01-02 0 2 1 2020-01-03 1 0 2 2020-01-04 0 2 1 2020-01-05 1 0 2
portfolio = vbt.Portfolio.from_orders( price_one, target_hold_value, size_type=SizeType.TargetValue, group_by=np.array([0, 0, 0]), cash_sharing=True, call_seq='auto') print(portfolio.orders.records) print(portfolio.asset_flow()) print(portfolio.asset_value(group_by=False)) # order dynamic -> can rebalance print(portfolio.call_seq)
id idx col size price fees side 0 0 0 1 30.0 1.0 0.0 0 1 1 0 2 70.0 1.0 0.0 0 2 2 1 2 40.0 1.0 0.0 1 3 3 1 1 30.0 1.0 0.0 1 4 4 1 0 70.0 1.0 0.0 0 5 5 2 0 40.0 1.0 0.0 1 6 6 2 2 30.0 1.0 0.0 1 7 7 2 1 70.0 1.0 0.0 0 8 8 3 1 40.0 1.0 0.0 1 9 9 3 0 30.0 1.0 0.0 1 10 10 3 2 70.0 1.0 0.0 0 11 11 4 2 70.0 1.0 0.0 1 12 12 4 0 70.0 1.0 0.0 0 a b c 2020-01-01 0.0 30.0 70.0 2020-01-02 70.0 -30.0 -40.0 2020-01-03 -40.0 70.0 -30.0 2020-01-04 -30.0 -40.0 70.0 2020-01-05 70.0 0.0 -70.0 a b c 2020-01-01 0.0 30.0 70.0 2020-01-02 70.0 0.0 30.0 2020-01-03 30.0 70.0 0.0 2020-01-04 0.0 30.0 70.0 2020-01-05 70.0 30.0 0.0 a b c 2020-01-01 0 1 2 2020-01-02 2 1 0 2020-01-03 0 2 1 2020-01-04 1 0 2 2020-01-05 2 1 0
portfolio = vbt.Portfolio.from_orders( price_one, target_hold_value / 100., size_type=SizeType.TargetPercent, group_by=np.array([0, 0, 0]), cash_sharing=True, call_seq='auto') print(portfolio.orders.records) print(portfolio.asset_flow()) print(portfolio.asset_value(group_by=False)) print(portfolio.call_seq)
id idx col size price fees side 0 0 0 1 30.0 1.0 0.0 0 1 1 0 2 70.0 1.0 0.0 0 2 2 1 2 40.0 1.0 0.0 1 3 3 1 1 30.0 1.0 0.0 1 4 4 1 0 70.0 1.0 0.0 0 5 5 2 0 40.0 1.0 0.0 1 6 6 2 2 30.0 1.0 0.0 1 7 7 2 1 70.0 1.0 0.0 0 8 8 3 1 40.0 1.0 0.0 1 9 9 3 0 30.0 1.0 0.0 1 10 10 3 2 70.0 1.0 0.0 0 11 11 4 2 70.0 1.0 0.0 1 12 12 4 0 70.0 1.0 0.0 0 a b c 2020-01-01 0.0 30.0 70.0 2020-01-02 70.0 -30.0 -40.0 2020-01-03 -40.0 70.0 -30.0 2020-01-04 -30.0 -40.0 70.0 2020-01-05 70.0 0.0 -70.0 a b c 2020-01-01 0.0 30.0 70.0 2020-01-02 70.0 0.0 30.0 2020-01-03 30.0 70.0 0.0 2020-01-04 0.0 30.0 70.0 2020-01-05 70.0 30.0 0.0 a b c 2020-01-01 0 1 2 2020-01-02 2 1 0 2020-01-03 0 2 1 2020-01-04 1 0 2 2020-01-05 2 1 0

from_signals

entries = pd.Series([True, True, True, False, False], index=price.index) entries_wide = entries.vbt.tile(3, keys=['a', 'b', 'c']) print(entries.shape, entries_wide.shape) exits = pd.Series([False, False, True, True, True], index=price.index) exits_wide = exits.vbt.tile(3, keys=['a', 'b', 'c']) print(exits.shape, exits_wide.shape) big_entries = pd.DataFrame.vbt.signals.empty((1000,), index=big_price.index) big_entries.iloc[0::2] = True big_entries_wide = big_entries.vbt.tile(1000) print(big_entries.shape, big_entries_wide.shape) big_exits = pd.DataFrame.vbt.signals.empty((1000,), index=big_price.index) big_exits.iloc[1::2] = True big_exits_wide = big_exits.vbt.tile(1000) print(big_exits.shape, big_exits_wide.shape)
(5,) (5, 3) (5,) (5, 3) (1000,) (1000, 1000) (1000,) (1000, 1000)
%timeit vbt.Portfolio.from_signals(\ big_price, big_entries, big_exits,\ size=1., init_cash=np.inf, accumulate=True)
2.72 ms ± 238 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=1., init_cash=np.inf, accumulate=True)
95.1 ms ± 2.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=1., init_cash=np.inf, sl_stop=np.inf, tp_stop=np.inf, accumulate=True)
104 ms ± 1.87 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=1., init_cash=np.inf, accumulate=True, log=True)
171 ms ± 6.43 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=1., init_cash=np.inf, accumulate=True,\ group_by=np.repeat(np.arange(500), 2))
98.4 ms ± 250 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=1., init_cash=np.inf, accumulate=True,\ group_by=np.repeat(np.arange(500), 2), cash_sharing=True)
100 ms ± 564 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# worst case %timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=np.arange(1000)[::-1], init_cash=np.inf, accumulate=True,\ group_by=np.repeat(np.arange(500), 2), cash_sharing=True, call_seq=CallSeqType.Auto)
101 ms ± 191 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=1., init_cash=np.inf, accumulate=True,\ group_by=np.full(1000, 0))
98.6 ms ± 848 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=1., init_cash=np.inf, accumulate=True,\ group_by=np.full(1000, 0), cash_sharing=True)
96 ms ± 501 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
# worst case %timeit vbt.Portfolio.from_signals(\ big_price_wide, big_entries_wide, big_exits_wide,\ size=np.arange(1000)[::-1], init_cash=np.inf, accumulate=True,\ group_by=np.full(1000, 0), cash_sharing=True, call_seq=CallSeqType.Auto)
279 ms ± 1.83 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
def test_per_direction(price=price, entries=entries, exits=exits, **kwargs): print('Both') try: portfolio = vbt.Portfolio.from_signals(price, entries, exits, direction='both', **kwargs) print(portfolio.orders.records) except Exception as e: print(e) print('LongOnly') try: portfolio = vbt.Portfolio.from_signals(price, entries, exits, direction='longonly', **kwargs) print(portfolio.orders.records) except Exception as e: print(e) print('ShortOnly') try: portfolio = vbt.Portfolio.from_signals(price, entries, exits, direction='shortonly', **kwargs) print(portfolio.orders.records) except Exception as e: print(e)
test_per_direction()
Both id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 200.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 100.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 1 1 1 0 3 50.0 4.0 0.0 0
test_per_direction(size=[[0, 1, np.inf]])
Both id col idx size price fees side 0 0 1 0 1.0 1.0 0.0 0 1 1 1 3 2.0 4.0 0.0 1 2 2 2 0 100.0 1.0 0.0 0 3 3 2 3 200.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 1 0 1.0 1.0 0.0 0 1 1 1 3 1.0 4.0 0.0 1 2 2 2 0 100.0 1.0 0.0 0 3 3 2 3 100.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 1 0 1.0 1.0 0.0 1 1 1 1 3 1.0 4.0 0.0 0 2 2 2 0 100.0 1.0 0.0 1 3 3 2 3 50.0 4.0 0.0 0
test_per_direction(size=0.5, size_type='percent')
Both SizeType.Percent does not support position reversal using signals LongOnly id col idx size price fees side 0 0 0 0 50.0 1.0 0.0 0 1 1 0 3 50.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 50.0 1.0 0.0 1 1 1 0 3 37.5 4.0 0.0 0
test_per_direction(size=0.5, size_type='percent', accumulate=True)
Both id col idx size price fees side 0 0 0 0 50.000 1.0 0.0 0 1 1 0 1 12.500 2.0 0.0 0 2 2 0 3 65.625 4.0 0.0 1 3 3 0 4 26.250 5.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 50.000 1.0 0.0 0 1 1 0 1 12.500 2.0 0.0 0 2 2 0 3 31.250 4.0 0.0 1 3 3 0 4 15.625 5.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 50.000 1.0 0.0 1 1 1 0 1 12.500 2.0 0.0 1 2 2 0 3 21.875 4.0 0.0 0 3 3 0 4 8.750 5.0 0.0 0
test_per_direction(price=price * 1.01)
Both id col idx size price fees side 0 0 0 0 99.009901 1.01 0.0 0 1 1 0 3 198.019802 4.04 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 99.009901 1.01 0.0 0 1 1 0 3 99.009901 4.04 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 99.009901 1.01 0.0 1 1 1 0 3 49.504950 4.04 0.0 0
test_per_direction(size=1, fees=[[0., 0.1, 1.]])
Both id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 2.0 4.0 0.0 1 2 2 1 0 1.0 1.0 0.1 0 3 3 1 3 2.0 4.0 0.8 1 4 4 2 0 1.0 1.0 1.0 0 5 5 2 3 2.0 4.0 8.0 1 LongOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 1.0 4.0 0.0 1 2 2 1 0 1.0 1.0 0.1 0 3 3 1 3 1.0 4.0 0.4 1 4 4 2 0 1.0 1.0 1.0 0 5 5 2 3 1.0 4.0 4.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 0 3 1.0 4.0 0.0 0 2 2 1 0 1.0 1.0 0.1 1 3 3 1 3 1.0 4.0 0.4 0 4 4 2 0 1.0 1.0 1.0 1 5 5 2 3 1.0 4.0 4.0 0
test_per_direction(size=1, fixed_fees=[[0., 0.1, 1.]])
Both id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 2.0 4.0 0.0 1 2 2 1 0 1.0 1.0 0.1 0 3 3 1 3 2.0 4.0 0.1 1 4 4 2 0 1.0 1.0 1.0 0 5 5 2 3 2.0 4.0 1.0 1 LongOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 1.0 4.0 0.0 1 2 2 1 0 1.0 1.0 0.1 0 3 3 1 3 1.0 4.0 0.1 1 4 4 2 0 1.0 1.0 1.0 0 5 5 2 3 1.0 4.0 1.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 0 3 1.0 4.0 0.0 0 2 2 1 0 1.0 1.0 0.1 1 3 3 1 3 1.0 4.0 0.1 0 4 4 2 0 1.0 1.0 1.0 1 5 5 2 3 1.0 4.0 1.0 0
test_per_direction(size=1, slippage=[[0., 0.1, 1.]])
Both id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 2.0 4.0 0.0 1 2 2 1 0 1.0 1.1 0.0 0 3 3 1 3 2.0 3.6 0.0 1 4 4 2 0 1.0 2.0 0.0 0 5 5 2 3 2.0 0.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 1.0 4.0 0.0 1 2 2 1 0 1.0 1.1 0.0 0 3 3 1 3 1.0 3.6 0.0 1 4 4 2 0 1.0 2.0 0.0 0 5 5 2 3 1.0 0.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 0 3 1.0 4.0 0.0 0 2 2 1 0 1.0 0.9 0.0 1 3 3 1 3 1.0 4.4 0.0 0 4 4 2 0 1.0 0.0 0.0 1 5 5 2 3 1.0 8.0 0.0 0
test_per_direction(size=1, min_size=[[0., 1., 2.]])
Both id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 2.0 4.0 0.0 1 2 2 1 0 1.0 1.0 0.0 0 3 3 1 3 2.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 1.0 4.0 0.0 1 2 2 1 0 1.0 1.0 0.0 0 3 3 1 3 1.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 0 3 1.0 4.0 0.0 0 2 2 1 0 1.0 1.0 0.0 1 3 3 1 3 1.0 4.0 0.0 0
test_per_direction(size=1, max_size=[[0.5, 1., np.inf]])
Both id col idx size price fees side 0 0 0 0 0.5 1.0 0.0 0 1 1 0 3 0.5 4.0 0.0 1 2 2 0 4 0.5 5.0 0.0 1 3 3 1 0 1.0 1.0 0.0 0 4 4 1 3 1.0 4.0 0.0 1 5 5 1 4 1.0 5.0 0.0 1 6 6 2 0 1.0 1.0 0.0 0 7 7 2 3 2.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 0.5 1.0 0.0 0 1 1 0 3 0.5 4.0 0.0 1 2 2 1 0 1.0 1.0 0.0 0 3 3 1 3 1.0 4.0 0.0 1 4 4 2 0 1.0 1.0 0.0 0 5 5 2 3 1.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 0.5 1.0 0.0 1 1 1 0 3 0.5 4.0 0.0 0 2 2 1 0 1.0 1.0 0.0 1 3 3 1 3 1.0 4.0 0.0 0 4 4 2 0 1.0 1.0 0.0 1 5 5 2 3 1.0 4.0 0.0 0
test_per_direction(size=1., reject_prob=[[0., 0.5, 1.]], seed=42)
Both id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 2.0 4.0 0.0 1 2 2 1 1 1.0 2.0 0.0 0 3 3 1 3 2.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 3 1.0 4.0 0.0 1 2 2 1 1 1.0 2.0 0.0 0 3 3 1 3 1.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 0 3 1.0 4.0 0.0 0 2 2 1 1 1.0 2.0 0.0 1 3 3 1 3 1.0 4.0 0.0 0
portfolio = vbt.Portfolio.from_signals( price, entries, exits, direction='both', upon_opposite_entry=[['reverse', 'close']] ) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_signals( pd.Series(price.values[::-1], index=price.index), pd.Series(entries.values[::-1], index=price.index), pd.Series(exits.values[::-1], index=price.index), direction='both', upon_opposite_entry=[['reverse', 'close']] ) print(portfolio.orders.records)
id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 200.0 4.0 0.0 1 2 2 1 0 100.0 1.0 0.0 0 3 3 1 3 100.0 4.0 0.0 1 4 4 1 4 80.0 5.0 0.0 1 id col idx size price fees side 0 0 0 0 20.0 5.0 0.0 1 1 1 0 3 100.0 2.0 0.0 0 2 2 1 0 20.0 5.0 0.0 1 3 3 1 3 20.0 2.0 0.0 0 4 4 1 4 160.0 1.0 0.0 0
test_per_direction(size=1000, allow_partial=[[True, False]]) test_per_direction(size=np.inf, allow_partial=[[True, False]])
Both id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 1100.0 4.0 0.0 1 2 2 1 3 1000.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 100.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1000.0 1.0 0.0 1 1 1 0 3 275.0 4.0 0.0 0 2 2 1 0 1000.0 1.0 0.0 1 Both id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 200.0 4.0 0.0 1 2 2 1 0 100.0 1.0 0.0 0 3 3 1 3 200.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 100.0 4.0 0.0 1 2 2 1 0 100.0 1.0 0.0 0 3 3 1 3 100.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 1 1 1 0 3 50.0 4.0 0.0 0 2 2 1 0 100.0 1.0 0.0 1
test_per_direction(size=1000, allow_partial=True, raise_reject=True) test_per_direction(size=1000, allow_partial=False, raise_reject=True)
Both id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 1100.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 100.0 4.0 0.0 1 ShortOnly Not enough cash to cover fees Both Final size is less than requested LongOnly Final size is less than requested ShortOnly Final size is less than requested
test_per_direction(size=1, accumulate=True)
Both id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 1 1.0 2.0 0.0 0 2 2 0 3 1.0 4.0 0.0 1 3 3 0 4 1.0 5.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 0 1 1.0 2.0 0.0 0 2 2 0 3 1.0 4.0 0.0 1 3 3 0 4 1.0 5.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1.0 1.0 0.0 1 1 1 0 1 1.0 2.0 0.0 1 2 2 0 3 1.0 4.0 0.0 0 3 3 0 4 1.0 5.0 0.0 0
portfolio = vbt.Portfolio.from_signals(price, entries, exits, log=True, direction='both') print(portfolio.orders.records) print(portfolio.logs.records)
id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 200.0 4.0 0.0 1 id group col idx cash position debt free_cash val_price value \ 0 0 0 0 0 100.0 0.0 0.0 100.0 1.0 100.0 1 1 0 0 3 0.0 100.0 0.0 0.0 4.0 400.0 ... new_free_cash new_val_price new_value res_size res_price \ 0 ... 0.0 1.0 100.0 100.0 1.0 1 ... 0.0 4.0 400.0 200.0 4.0 res_fees res_side res_status res_status_info order_id 0 0.0 0 0 -1 0 1 0.0 1 0 -1 1 [2 rows x 37 columns]
test_per_direction(price=price.iloc[:3], entries=pd.DataFrame([ [True, True, True, True, True], [True, True, True, True, False], [True, True, True, True, True] ]), exits=pd.DataFrame([ [True, True, True, True, True], [False, False, False, False, True], [True, True, True, True, True] ]), size=1., upon_long_conflict=[[ 'ignore', 'entry', 'exit', 'opposite', 'opposite' ]], upon_short_conflict=[[ 'ignore', 'entry', 'exit', 'opposite', 'opposite' ]])
Both id col idx size price fees side 0 0 0 1 1.0 2.0 0.0 0 1 1 1 1 1.0 2.0 0.0 0 2 2 2 1 1.0 2.0 0.0 0 3 3 3 1 1.0 2.0 0.0 0 4 4 4 1 1.0 2.0 0.0 1 LongOnly id col idx size price fees side 0 0 0 1 1.0 2.0 0.0 0 1 1 1 0 1.0 1.0 0.0 0 2 2 2 1 1.0 2.0 0.0 0 3 3 2 2 1.0 3.0 0.0 1 4 4 3 1 1.0 2.0 0.0 0 5 5 3 2 1.0 3.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 1 1.0 2.0 0.0 1 1 1 1 0 1.0 1.0 0.0 1 2 2 2 1 1.0 2.0 0.0 1 3 3 2 2 1.0 3.0 0.0 0 4 4 3 1 1.0 2.0 0.0 1 5 5 3 2 1.0 3.0 0.0 0
test_per_direction(price=price.iloc[:3], entries=pd.DataFrame([ [True, True, True, True, True], [True, True, True, True, False], [True, True, True, True, True] ]), exits=pd.DataFrame([ [True, True, True, True, True], [False, False, False, False, True], [True, True, True, True, True] ]), size=1., upon_dir_conflict=[[ 'ignore', 'long', 'short', 'opposite', 'opposite' ]])
Both id col idx size price fees side 0 0 0 1 1.0 2.0 0.0 0 1 1 1 0 1.0 1.0 0.0 0 2 2 2 0 1.0 1.0 0.0 1 3 3 2 1 2.0 2.0 0.0 0 4 4 2 2 2.0 3.0 0.0 1 5 5 3 1 1.0 2.0 0.0 0 6 6 3 2 2.0 3.0 0.0 1 7 7 4 1 1.0 2.0 0.0 1 8 8 4 2 2.0 3.0 0.0 0 LongOnly id col idx size price fees side 0 0 0 1 1.0 2.0 0.0 0 1 1 1 1 1.0 2.0 0.0 0 2 2 2 1 1.0 2.0 0.0 0 3 3 3 1 1.0 2.0 0.0 0 ShortOnly id col idx size price fees side 0 0 0 1 1.0 2.0 0.0 1 1 1 1 1 1.0 2.0 0.0 1 2 2 2 1 1.0 2.0 0.0 1 3 3 3 1 1.0 2.0 0.0 1
test_per_direction(price=price_wide, size=1., init_cash=[0., 1., 100.]) test_per_direction(init_cash=np.inf)
Both id col idx size price fees side 0 0 0 3 1.0 4.0 0.0 1 1 1 1 0 1.0 1.0 0.0 0 2 2 1 3 2.0 4.0 0.0 1 3 3 2 0 1.0 1.0 0.0 0 4 4 2 3 2.0 4.0 0.0 1 LongOnly id col idx size price fees side 0 0 1 0 1.0 1.0 0.0 0 1 1 1 3 1.0 4.0 0.0 1 2 2 2 0 1.0 1.0 0.0 0 3 3 2 3 1.0 4.0 0.0 1 ShortOnly id col idx size price fees side 0 0 0 0 1.00 1.0 0.0 1 1 1 0 3 0.25 4.0 0.0 0 2 2 1 0 1.00 1.0 0.0 1 3 3 1 3 0.50 4.0 0.0 0 4 4 2 0 1.00 1.0 0.0 1 5 5 2 3 1.00 4.0 0.0 0 Both Attempt to go in long direction infinitely LongOnly Attempt to go in long direction infinitely ShortOnly Attempt to go in short direction infinitely
portfolio = vbt.Portfolio.from_signals( price_wide, entries, exits, group_by=np.array([0, 0, 1]), direction='both') print(portfolio.orders.records)
id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 200.0 4.0 0.0 1 2 2 1 0 100.0 1.0 0.0 0 3 3 1 3 200.0 4.0 0.0 1 4 4 2 0 100.0 1.0 0.0 0 5 5 2 3 200.0 4.0 0.0 1
portfolio = vbt.Portfolio.from_signals( price_wide, entries, exits, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both') print(portfolio.orders.records) print(portfolio.call_seq) try: print(portfolio.regroup(group_by=False)) except Exception as e: print(e)
id col idx size price fees side 0 0 0 0 100.0 1.0 0.0 0 1 1 0 3 200.0 4.0 0.0 1 2 2 2 0 100.0 1.0 0.0 0 3 3 2 3 200.0 4.0 0.0 1 a b c 2020-01-01 0 1 0 2020-01-02 0 1 0 2020-01-03 0 1 0 2020-01-04 0 1 0 2020-01-05 0 1 0 Cannot modify grouping globally when cash_sharing=True
portfolio = vbt.Portfolio.from_signals( price_wide, entries, exits, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='reversed') print(portfolio.orders.records) print(portfolio.call_seq)
id col idx size price fees side 0 0 1 0 100.0 1.0 0.0 0 1 1 1 3 200.0 4.0 0.0 1 2 2 2 0 100.0 1.0 0.0 0 3 3 2 3 200.0 4.0 0.0 1 a b c 2020-01-01 1 0 0 2020-01-02 1 0 0 2020-01-03 1 0 0 2020-01-04 1 0 0 2020-01-05 1 0 0
portfolio = vbt.Portfolio.from_signals( price_wide, entries, exits, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random') print(portfolio.orders.records) print(portfolio.call_seq) portfolio = vbt.Portfolio.from_signals( price_wide, entries, exits, group_by=np.array([0, 0, 1]), cash_sharing=True, direction='both', call_seq='random', seed=42) print(portfolio.orders.records) print(portfolio.call_seq)
id col idx size price fees side 0 0 1 0 100.0 1.0 0.0 0 1 1 1 3 200.0 4.0 0.0 1 2 2 2 0 100.0 1.0 0.0 0 3 3 2 3 200.0 4.0 0.0 1 a b c 2020-01-01 1 0 0 2020-01-02 1 0 0 2020-01-03 1 0 0 2020-01-04 1 0 0 2020-01-05 0 1 0 id col idx size price fees side 0 0 1 0 100.0 1.0 0.0 0 1 1 1 3 200.0 4.0 0.0 1 2 2 2 0 100.0 1.0 0.0 0 3 3 2 3 200.0 4.0 0.0 1 a b c 2020-01-01 1 0 0 2020-01-02 0 1 0 2020-01-03 1 0 0 2020-01-04 1 0 0 2020-01-05 1 0 0
for direction in ('Both', 'LongOnly', 'ShortOnly'): print(direction) portfolio = vbt.Portfolio.from_signals(1., pd.DataFrame([ [False, False, True], [False, True, False], [True, False, False], [False, False, True], [False, True, False], ]), pd.DataFrame([ [False, False, False], [False, False, True], [False, True, False], [True, False, False], [False, False, True], ]), group_by=np.array([0, 0, 0]), cash_sharing=True, call_seq='auto', direction=direction) print(portfolio.orders.records) print(portfolio.call_seq) print(portfolio.assets()) print(portfolio.value()) # notice how shorting with np.inf only accounts for current cash, not for other assets!
Both id col idx size price fees side 0 0 2 0 100.0 1.0 0.0 0 1 1 2 1 200.0 1.0 0.0 1 2 2 1 1 200.0 1.0 0.0 0 3 3 1 2 200.0 1.0 0.0 1 4 4 0 2 200.0 1.0 0.0 0 5 5 0 3 200.0 1.0 0.0 1 6 6 2 3 200.0 1.0 0.0 0 7 7 2 4 200.0 1.0 0.0 1 8 8 1 4 200.0 1.0 0.0 0 0 1 2 0 0 1 2 1 2 0 1 2 1 2 0 3 0 1 2 4 2 0 1 0 1 2 0 0.0 0.0 100.0 1 0.0 200.0 -100.0 2 200.0 0.0 -100.0 3 0.0 0.0 100.0 4 0.0 200.0 -100.0 0 100.0 1 100.0 2 100.0 3 100.0 4 100.0 dtype: float64 LongOnly id col idx size price fees side 0 0 2 0 100.0 1.0 0.0 0 1 1 2 1 100.0 1.0 0.0 1 2 2 1 1 100.0 1.0 0.0 0 3 3 1 2 100.0 1.0 0.0 1 4 4 0 2 100.0 1.0 0.0 0 5 5 0 3 100.0 1.0 0.0 1 6 6 2 3 100.0 1.0 0.0 0 7 7 2 4 100.0 1.0 0.0 1 8 8 1 4 100.0 1.0 0.0 0 0 1 2 0 0 1 2 1 2 0 1 2 1 2 0 3 0 1 2 4 2 0 1 0 1 2 0 0.0 0.0 100.0 1 0.0 100.0 0.0 2 100.0 0.0 0.0 3 0.0 0.0 100.0 4 0.0 100.0 0.0 0 100.0 1 100.0 2 100.0 3 100.0 4 100.0 dtype: float64 ShortOnly id col idx size price fees side 0 0 2 0 100.0 1.0 0.0 1 1 1 2 1 100.0 1.0 0.0 0 2 2 0 2 100.0 1.0 0.0 1 3 3 0 3 100.0 1.0 0.0 0 4 4 1 4 100.0 1.0 0.0 1 0 1 2 0 2 0 1 1 1 0 2 2 0 1 2 3 2 1 0 4 1 0 2 0 1 2 0 0.0 0.0 -100.0 1 0.0 0.0 0.0 2 -100.0 0.0 0.0 3 0.0 0.0 0.0 4 0.0 -100.0 0.0 0 100.0 1 100.0 2 100.0 3 100.0 4 100.0 dtype: float64

from_order_func

from vectorbt.portfolio.nb import order_nb, order_nothing_nb @njit def order_func_nb(c, size): return order_nb(size if c.i % 2 == 0 else -size) @njit def flex_order_func_nb(c, size): if c.call_idx < c.group_len: return c.from_col + c.call_idx, order_nb(size if c.i % 2 == 0 else -size) return -1, order_nothing_nb()
%timeit vbt.Portfolio.from_order_func(\ big_price, order_func_nb, 1., init_cash=np.inf) %timeit vbt.Portfolio.from_order_func(\ big_price, order_func_nb, 1., init_cash=np.inf, row_wise=True) %timeit vbt.Portfolio.from_order_func(\ big_price, flex_order_func_nb, 1., init_cash=np.inf, flexible=True) %timeit vbt.Portfolio.from_order_func(\ big_price, flex_order_func_nb, 1., init_cash=np.inf, row_wise=True, flexible=True)
1.92 ms ± 156 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 2.02 ms ± 189 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 1.85 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 1.85 ms ± 145 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf, row_wise=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, flexible=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, row_wise=True, flexible=True)
95 ms ± 181 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 101 ms ± 2.48 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 90.9 ms ± 489 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 89.1 ms ± 1.69 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf, fill_pos_record=False) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf, row_wise=True, fill_pos_record=False) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, fill_pos_record=False, flexible=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, row_wise=True, fill_pos_record=False, flexible=True)
76.4 ms ± 217 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 84.2 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 71.5 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 71.1 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), init_cash=np.inf) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), init_cash=np.inf, row_wise=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), init_cash=np.inf, flexible=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), init_cash=np.inf, row_wise=True, flexible=True)
89.1 ms ± 851 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 93.5 ms ± 692 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 86.2 ms ± 287 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 86.3 ms ± 131 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf, row_wise=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf, flexible=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., \ group_by=np.repeat(np.arange(500), 2), cash_sharing=True, init_cash=np.inf, row_wise=True, flexible=True)
88.7 ms ± 763 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 93 ms ± 686 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 85.4 ms ± 39.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 85.7 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0)) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0), row_wise=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0), flexible=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0), row_wise=True, flexible=True)
87 ms ± 487 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 86.2 ms ± 369 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 83.4 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 83.3 ms ± 153 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0), cash_sharing=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0), cash_sharing=True, row_wise=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0), cash_sharing=True, flexible=True) %timeit vbt.Portfolio.from_order_func(\ big_price_wide, flex_order_func_nb, 1., init_cash=np.inf, \ group_by=np.full(1000, 0), cash_sharing=True, row_wise=True, flexible=True)
83.6 ms ± 622 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 82.7 ms ± 192 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 82.3 ms ± 927 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 82 ms ± 680 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
def test_call_seq(call_seq, **kwargs): return vbt.Portfolio.from_order_func( price_wide, order_func_nb, 1., group_by=np.array([0, 0, 0]), call_seq=call_seq, **kwargs ).call_seq def big_test_call_seq(call_seq, **kwargs): return vbt.Portfolio.from_order_func( big_price_wide, order_func_nb, 1., group_by=np.repeat(np.arange(500), 2), call_seq=call_seq, **kwargs ).call_seq
print(test_call_seq(CallSeqType.Default)) %timeit big_test_call_seq(CallSeqType.Default) print(test_call_seq(CallSeqType.Reversed)) %timeit big_test_call_seq(CallSeqType.Reversed) print(test_call_seq(CallSeqType.Random)) %timeit big_test_call_seq(CallSeqType.Random)
a b c 2020-01-01 0 1 2 2020-01-02 0 1 2 2020-01-03 0 1 2 2020-01-04 0 1 2 2020-01-05 0 1 2 46.2 ms ± 838 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) a b c 2020-01-01 2 1 0 2020-01-02 2 1 0 2020-01-03 2 1 0 2020-01-04 2 1 0 2020-01-05 2 1 0 46.4 ms ± 683 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) a b c 2020-01-01 0 1 2 2020-01-02 2 1 0 2020-01-03 1 0 2 2020-01-04 2 0 1 2020-01-05 2 1 0 55.1 ms ± 849 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
@njit def pre_segment_func1_nb(c, *args): c.call_seq_now[:] = np.arange(c.to_col - c.from_col - 1, -1, -1) return () @njit def pre_segment_func2_nb(c, *args): c.call_seq_now[:] = np.copy(c.call_seq_now[::-1]) return () @njit def pre_segment_func3_nb(c, *args): call_seq_now = c.call_seq_now n_cols = c.to_col - c.from_col for k in range(n_cols): call_seq_now[k] = n_cols - k - 1 return () @njit def pre_segment_func4_nb(c, *args): np.random.shuffle(c.call_seq_now) return ()
print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func1_nb)) %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func1_nb) %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func1_nb, row_wise=True) print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func2_nb)) %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func2_nb) %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func2_nb, row_wise=True) print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func3_nb)) %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func3_nb) %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func3_nb, row_wise=True) print(test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func4_nb)) %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func4_nb) # in-place fastest %timeit big_test_call_seq(CallSeqType.Default, pre_segment_func_nb=pre_segment_func4_nb, row_wise=True)
a b c 2020-01-01 2 1 0 2020-01-02 2 1 0 2020-01-03 2 1 0 2020-01-04 2 1 0 2020-01-05 2 1 0 262 ms ± 109 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 206 ms ± 2.16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) a b c 2020-01-01 2 1 0 2020-01-02 2 1 0 2020-01-03 2 1 0 2020-01-04 2 1 0 2020-01-05 2 1 0 209 ms ± 1.67 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 211 ms ± 1.97 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) a b c 2020-01-01 2 1 0 2020-01-02 2 1 0 2020-01-03 2 1 0 2020-01-04 2 1 0 2020-01-05 2 1 0 94.2 ms ± 1.26 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 99.2 ms ± 394 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) a b c 2020-01-01 1 2 0 2020-01-02 0 1 2 2020-01-03 1 0 2 2020-01-04 1 0 2 2020-01-05 2 1 0 148 ms ± 2.78 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 148 ms ± 3.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
portfolio = vbt.Portfolio.from_order_func( price, order_func_nb, np.inf, target_shape=(5,)) print(portfolio.wrapper.columns) print(portfolio.wrapper.ndim) portfolio = vbt.Portfolio.from_order_func( price, order_func_nb, np.inf, target_shape=(5, 1)) print(portfolio.wrapper.columns) print(portfolio.wrapper.ndim) portfolio = vbt.Portfolio.from_order_func( price, order_func_nb, np.inf, target_shape=(5, 1), keys=pd.Index(['first'], name='custom')) print(portfolio.wrapper.columns) print(portfolio.wrapper.ndim) portfolio = vbt.Portfolio.from_order_func( price, order_func_nb, np.inf, target_shape=(5, 3)) print(portfolio.wrapper.columns) print(portfolio.wrapper.ndim) portfolio = vbt.Portfolio.from_order_func( price, order_func_nb, np.inf, target_shape=(5, 3), keys=pd.Index(['first', 'second', 'third'], name='custom')) print(portfolio.wrapper.columns) print(portfolio.wrapper.ndim)
Index([0], dtype='int64') 1 Index([0], dtype='int64', name='iteration_idx') 2 Index(['first'], dtype='object', name='custom') 2 Index([0, 1, 2], dtype='int64', name='iteration_idx') 2 Index(['first', 'second', 'third'], dtype='object', name='custom') 2
portfolio = vbt.Portfolio.from_order_func(price, order_func_nb, np.inf) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func(price, order_func_nb, np.inf, row_wise=True) print(portfolio.orders.records)
id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 1 0 200.000000 2.0 0.0 1 2 2 2 0 133.333333 3.0 0.0 0 3 3 3 0 66.666667 4.0 0.0 1 4 4 4 0 53.333333 5.0 0.0 0 id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 1 0 200.000000 2.0 0.0 1 2 2 2 0 133.333333 3.0 0.0 0 3 3 3 0 66.666667 4.0 0.0 1 4 4 4 0 53.333333 5.0 0.0 0
portfolio = vbt.Portfolio.from_order_func(price_wide, order_func_nb, np.inf) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func(price_wide, order_func_nb, np.inf, row_wise=True) print(portfolio.orders.records)
id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 1 0 200.000000 2.0 0.0 1 2 2 2 0 133.333333 3.0 0.0 0 3 3 3 0 66.666667 4.0 0.0 1 4 4 4 0 53.333333 5.0 0.0 0 5 5 0 1 100.000000 1.0 0.0 0 6 6 1 1 200.000000 2.0 0.0 1 7 7 2 1 133.333333 3.0 0.0 0 8 8 3 1 66.666667 4.0 0.0 1 9 9 4 1 53.333333 5.0 0.0 0 10 10 0 2 100.000000 1.0 0.0 0 11 11 1 2 200.000000 2.0 0.0 1 12 12 2 2 133.333333 3.0 0.0 0 13 13 3 2 66.666667 4.0 0.0 1 14 14 4 2 53.333333 5.0 0.0 0 id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 0 1 100.000000 1.0 0.0 0 2 2 0 2 100.000000 1.0 0.0 0 3 3 1 0 200.000000 2.0 0.0 1 4 4 1 1 200.000000 2.0 0.0 1 5 5 1 2 200.000000 2.0 0.0 1 6 6 2 0 133.333333 3.0 0.0 0 7 7 2 1 133.333333 3.0 0.0 0 8 8 2 2 133.333333 3.0 0.0 0 9 9 3 0 66.666667 4.0 0.0 1 10 10 3 1 66.666667 4.0 0.0 1 11 11 3 2 66.666667 4.0 0.0 1 12 12 4 0 53.333333 5.0 0.0 0 13 13 4 1 53.333333 5.0 0.0 0 14 14 4 2 53.333333 5.0 0.0 0
portfolio = vbt.Portfolio.from_order_func( price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1])) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func( price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1]), row_wise=True) print(portfolio.orders.records)
id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 0 1 100.000000 1.0 0.0 0 2 2 1 0 200.000000 2.0 0.0 1 3 3 1 1 200.000000 2.0 0.0 1 4 4 2 0 133.333333 3.0 0.0 0 5 5 2 1 133.333333 3.0 0.0 0 6 6 3 0 66.666667 4.0 0.0 1 7 7 3 1 66.666667 4.0 0.0 1 8 8 4 0 53.333333 5.0 0.0 0 9 9 4 1 53.333333 5.0 0.0 0 10 10 0 2 100.000000 1.0 0.0 0 11 11 1 2 200.000000 2.0 0.0 1 12 12 2 2 133.333333 3.0 0.0 0 13 13 3 2 66.666667 4.0 0.0 1 14 14 4 2 53.333333 5.0 0.0 0 id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 0 1 100.000000 1.0 0.0 0 2 2 0 2 100.000000 1.0 0.0 0 3 3 1 0 200.000000 2.0 0.0 1 4 4 1 1 200.000000 2.0 0.0 1 5 5 1 2 200.000000 2.0 0.0 1 6 6 2 0 133.333333 3.0 0.0 0 7 7 2 1 133.333333 3.0 0.0 0 8 8 2 2 133.333333 3.0 0.0 0 9 9 3 0 66.666667 4.0 0.0 1 10 10 3 1 66.666667 4.0 0.0 1 11 11 3 2 66.666667 4.0 0.0 1 12 12 4 0 53.333333 5.0 0.0 0 13 13 4 1 53.333333 5.0 0.0 0 14 14 4 2 53.333333 5.0 0.0 0
portfolio = vbt.Portfolio.from_order_func( price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1]), cash_sharing=True) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func( price_wide, order_func_nb, np.inf, group_by=np.array([0, 0, 1]), cash_sharing=True, row_wise=True) print(portfolio.orders.records)
id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 1 0 200.000000 2.0 0.0 1 2 2 2 0 133.333333 3.0 0.0 0 3 3 3 0 66.666667 4.0 0.0 1 4 4 4 0 53.333333 5.0 0.0 0 5 5 0 2 100.000000 1.0 0.0 0 6 6 1 2 200.000000 2.0 0.0 1 7 7 2 2 133.333333 3.0 0.0 0 8 8 3 2 66.666667 4.0 0.0 1 9 9 4 2 53.333333 5.0 0.0 0 id idx col size price fees side 0 0 0 0 100.000000 1.0 0.0 0 1 1 0 2 100.000000 1.0 0.0 0 2 2 1 0 200.000000 2.0 0.0 1 3 3 1 2 200.000000 2.0 0.0 1 4 4 2 0 133.333333 3.0 0.0 0 5 5 2 2 133.333333 3.0 0.0 0 6 6 3 0 66.666667 4.0 0.0 1 7 7 3 2 66.666667 4.0 0.0 1 8 8 4 0 53.333333 5.0 0.0 0 9 9 4 2 53.333333 5.0 0.0 0
@njit def target_val_pre_segment_func_nb(c, val_price): c.last_val_price[c.from_col:c.to_col] = val_price[c.i] return () @njit def target_val_order_func_nb(c): print(c.last_val_price[c.from_col:c.to_col], 50. / c.close[c.i, c.col] - c.position_now) return order_nb(size=50., size_type=SizeType.TargetValue, price=c.close[c.i, c.col]) portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_val_order_func_nb, pre_segment_func_nb=target_val_pre_segment_func_nb, pre_segment_args=(price.values[:-1],) # lagged valuation price ) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_val_order_func_nb, pre_segment_func_nb=target_val_pre_segment_func_nb, pre_segment_args=(price.values[:-1],), row_wise=True ) print(portfolio.orders.records)
[1.] 25.0 [2.] -33.33333333333333 [3.] -12.5 [4.] -6.666666666666668 id idx col size price fees side 0 0 0 0 50.000000 2.0 0.0 0 1 1 1 0 25.000000 3.0 0.0 1 2 2 2 0 8.333333 4.0 0.0 1 3 3 3 0 4.166667 5.0 0.0 1 [1.] 25.0 [2.] -33.33333333333333 [3.] -12.5 [4.] -6.666666666666668 id idx col size price fees side 0 0 0 0 50.000000 2.0 0.0 0 1 1 1 0 25.000000 3.0 0.0 1 2 2 2 0 8.333333 4.0 0.0 1 3 3 3 0 4.166667 5.0 0.0 1
portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_val_order_func_nb, pre_segment_func_nb=target_val_pre_segment_func_nb, pre_segment_args=(price.values[1:],) # current order price ) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_val_order_func_nb, pre_segment_func_nb=target_val_pre_segment_func_nb, pre_segment_args=(price.values[1:],), row_wise=True ) print(portfolio.orders.records)
[2.] 25.0 [3.] -8.333333333333332 [4.] -4.166666666666668 [5.] -2.5 id idx col size price fees side 0 0 0 0 25.000000 2.0 0.0 0 1 1 1 0 8.333333 3.0 0.0 1 2 2 2 0 4.166667 4.0 0.0 1 3 3 3 0 2.500000 5.0 0.0 1 [2.] 25.0 [3.] -8.333333333333332 [4.] -4.166666666666668 [5.] -2.5 id idx col size price fees side 0 0 0 0 25.000000 2.0 0.0 0 1 1 1 0 8.333333 3.0 0.0 1 2 2 2 0 4.166667 4.0 0.0 1 3 3 3 0 2.500000 5.0 0.0 1
@njit def target_pct_pre_segment_func_nb(c, val_price): c.last_val_price[c.from_col:c.to_col] = val_price[c.i] return () @njit def target_pct_order_func_nb(c): print(c.last_val_price[c.from_col:c.to_col], 0.5 * c.value_now / c.close[c.i, c.col] - c.position_now) return order_nb(size=0.5, size_type=SizeType.TargetPercent, price=c.close[c.i, c.col]) portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_pct_order_func_nb, pre_segment_func_nb=target_pct_pre_segment_func_nb, pre_segment_args=(price.values[:-1],) # lagged valuation price ) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_pct_order_func_nb, pre_segment_func_nb=target_pct_pre_segment_func_nb, pre_segment_args=(price.values[:-1],), row_wise=True ) print(portfolio.orders.records)
[1.] 25.0 [2.] -33.33333333333333 [3.] -6.25 [4.] -7.5 id idx col size price fees side 0 0 0 0 50.000 2.0 0.0 0 1 1 1 0 25.000 3.0 0.0 1 2 2 3 0 3.125 5.0 0.0 1 [1.] 25.0 [2.] -33.33333333333333 [3.] -6.25 [4.] -7.5 id idx col size price fees side 0 0 0 0 50.000 2.0 0.0 0 1 1 1 0 25.000 3.0 0.0 1 2 2 3 0 3.125 5.0 0.0 1
portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_pct_order_func_nb, pre_segment_func_nb=target_pct_pre_segment_func_nb, pre_segment_args=(price.values[1:],) # current order price ) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func( price.iloc[1:], target_pct_order_func_nb, pre_segment_func_nb=target_pct_pre_segment_func_nb, pre_segment_args=(price.values[1:],), row_wise=True ) print(portfolio.orders.records)
[2.] 25.0 [3.] -4.166666666666668 [4.] -2.604166666666668 [5.] -1.8229166666666643 id idx col size price fees side 0 0 0 0 25.000000 2.0 0.0 0 1 1 1 0 4.166667 3.0 0.0 1 2 2 2 0 2.604167 4.0 0.0 1 3 3 3 0 1.822917 5.0 0.0 1 [2.] 25.0 [3.] -4.166666666666668 [4.] -2.604166666666668 [5.] -1.8229166666666643 id idx col size price fees side 0 0 0 0 25.000000 2.0 0.0 0 1 1 1 0 4.166667 3.0 0.0 1 2 2 2 0 2.604167 4.0 0.0 1 3 3 3 0 1.822917 5.0 0.0 1
portfolio = vbt.Portfolio.from_order_func( price, order_func_nb, 1., segment_mask=pd.Series([True, False, True, False, True])) print(portfolio.orders.records) portfolio = vbt.Portfolio.from_order_func( price, order_func_nb, 1., segment_mask=pd.Series([True, False, True, False, True]), row_wise=True) print(portfolio.orders.records)
id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 2 0 1.0 3.0 0.0 0 2 2 4 0 1.0 5.0 0.0 0 id idx col size price fees side 0 0 0 0 1.0 1.0 0.0 0 1 1 2 0 1.0 3.0 0.0 0 2 2 4 0 1.0 5.0 0.0 0
@njit def pre_sim_func_nb(c, sim_i): print('preparing simulation') sim_i[0] += 1 return sim_i, @njit def group_pre_sim_func_nb(c, sim_i, group_i): print('\tpreparing group', c.group) group_i[0] += 1 return sim_i, group_i @njit def pre_segment_func_nb(c, sim_i, group_i, segment_i): print('\t\tpreparing segment', c.i, '(row)') segment_i[0] += 1 return sim_i, group_i, segment_i @njit def order_func_nb(c, sim_i, group_i, segment_i, order_i): print('\t\t\tprocessing order', c.call_idx, 'at column', c.col) order_i[0] += 1 return NoOrder sim_i = np.array([0]) group_i = np.array([0]) segment_i = np.array([0]) order_i = np.array([0]) portfolio = vbt.Portfolio.from_order_func( price_wide, order_func_nb, order_i, group_by=np.array([0, 0, 1]), pre_sim_func_nb=pre_sim_func_nb, pre_sim_args=(sim_i,), pre_group_func_nb=group_pre_sim_func_nb, pre_group_args=(group_i,), pre_segment_func_nb=pre_segment_func_nb, pre_segment_args=(segment_i,) ) print(sim_i, group_i, segment_i, order_i)
preparing simulation preparing group 0 preparing segment 0 (row) processing order 0 at column 0 processing order 1 at column 1 preparing segment 1 (row) processing order 0 at column 0 processing order 1 at column 1 preparing segment 2 (row) processing order 0 at column 0 processing order 1 at column 1 preparing segment 3 (row) processing order 0 at column 0 processing order 1 at column 1 preparing segment 4 (row) processing order 0 at column 0 processing order 1 at column 1 preparing group 1 preparing segment 0 (row) processing order 0 at column 2 preparing segment 1 (row) processing order 0 at column 2 preparing segment 2 (row) processing order 0 at column 2 preparing segment 3 (row) processing order 0 at column 2 preparing segment 4 (row) processing order 0 at column 2 [1] [2] [10] [15]
@njit def pre_sim_func_nb(c, sim_i): print('preparing simulation') sim_i[0] += 1 return sim_i, @njit def row_pre_sim_func_nb(c, sim_i, row_i): print('\tpreparing row', c.i) row_i[0] += 1 return sim_i, row_i @njit def pre_segment_func_nb(c, sim_i, row_i, segment_i): print('\t\tpreparing segment', c.group, '(group)') segment_i[0] += 1 return sim_i, row_i, segment_i @njit def order_func_nb(c, sim_i, row_i, segment_i, order_i): print('\t\t\tprocessing order', c.call_idx, 'at column', c.col) order_i[0] += 1 return NoOrder sim_i = np.array([0]) row_i = np.array([0]) segment_i = np.array([0]) order_i = np.array([0]) portfolio = vbt.Portfolio.from_order_func( price_wide, order_func_nb, order_i, group_by=np.array([0, 0, 1]), pre_sim_func_nb=pre_sim_func_nb, pre_sim_args=(sim_i,), pre_row_func_nb=row_pre_sim_func_nb, pre_row_args=(row_i,), pre_segment_func_nb=pre_segment_func_nb, pre_segment_args=(segment_i,), row_wise=True ) print(sim_i, row_i, segment_i, order_i)
preparing simulation preparing row 0 preparing segment 0 (group) processing order 0 at column 0 processing order 1 at column 1 preparing segment 1 (group) processing order 0 at column 2 preparing row 1 preparing segment 0 (group) processing order 0 at column 0 processing order 1 at column 1 preparing segment 1 (group) processing order 0 at column 2 preparing row 2 preparing segment 0 (group) processing order 0 at column 0 processing order 1 at column 1 preparing segment 1 (group) processing order 0 at column 2 preparing row 3 preparing segment 0 (group) processing order 0 at column 0 processing order 1 at column 1 preparing segment 1 (group) processing order 0 at column 2 preparing row 4 preparing segment 0 (group) processing order 0 at column 0 processing order 1 at column 1 preparing segment 1 (group) processing order 0 at column 2 [1] [5] [10] [15]

methods and properties

price_na = pd.DataFrame({ 'a': [np.nan, 2., 3., 4., 5.], 'b': [1., 2., np.nan, 4., 5.], 'c': [1., 2., 3., 4., np.nan] }, index=price.index) order_size = pd.Series([1., 0.1, -1., -0.1, 1.]) directions = ['longonly', 'shortonly', 'both'] group_by = pd.Index(['first', 'first', 'second'], name='group')
portfolio = vbt.Portfolio.from_orders( price_na, order_size, size_type='amount', direction=directions, fees=0.01, fixed_fees=0.1, slippage=0.01, log=True, call_seq='reversed', group_by=None, init_cash=[100., 100., 100.], freq='1D' ) # independent print(portfolio.orders.records) portfolio_grouped = vbt.Portfolio.from_orders( price_na, order_size, size_type='amount', direction=directions, fees=0.01, fixed_fees=0.1, slippage=0.01, log=True, call_seq='reversed', group_by=group_by, cash_sharing=False, init_cash=[100., 100., 100.], freq='1D' ) # grouped print(portfolio_grouped.orders.records) portfolio_shared = vbt.Portfolio.from_orders( price_na, order_size, size_type='amount', direction=directions, fees=0.01, fixed_fees=0.1, slippage=0.01, log=True, call_seq='reversed', group_by=group_by, cash_sharing=True, init_cash=[200., 100.], freq='1D' ) # shared print(portfolio_shared.orders.records)
id col idx size price fees side 0 0 0 1 0.1 2.02 0.10202 0 1 1 0 2 0.1 2.97 0.10297 1 2 2 0 4 1.0 5.05 0.15050 0 3 3 1 0 1.0 0.99 0.10990 1 4 4 1 1 0.1 1.98 0.10198 1 5 5 1 3 0.1 4.04 0.10404 0 6 6 1 4 1.0 4.95 0.14950 1 7 7 2 0 1.0 1.01 0.11010 0 8 8 2 1 0.1 2.02 0.10202 0 9 9 2 2 1.0 2.97 0.12970 1 10 10 2 3 0.1 3.96 0.10396 1 id col idx size price fees side 0 0 0 1 0.1 2.02 0.10202 0 1 1 0 2 0.1 2.97 0.10297 1 2 2 0 4 1.0 5.05 0.15050 0 3 3 1 0 1.0 0.99 0.10990 1 4 4 1 1 0.1 1.98 0.10198 1 5 5 1 3 0.1 4.04 0.10404 0 6 6 1 4 1.0 4.95 0.14950 1 7 7 2 0 1.0 1.01 0.11010 0 8 8 2 1 0.1 2.02 0.10202 0 9 9 2 2 1.0 2.97 0.12970 1 10 10 2 3 0.1 3.96 0.10396 1 id col idx size price fees side 0 0 1 0 1.0 0.99 0.10990 1 1 1 1 1 0.1 1.98 0.10198 1 2 2 0 1 0.1 2.02 0.10202 0 3 3 0 2 0.1 2.97 0.10297 1 4 4 1 3 0.1 4.04 0.10404 0 5 5 1 4 1.0 4.95 0.14950 1 6 6 0 4 1.0 5.05 0.15050 0 7 7 2 0 1.0 1.01 0.11010 0 8 8 2 1 0.1 2.02 0.10202 0 9 9 2 2 1.0 2.97 0.12970 1 10 10 2 3 0.1 3.96 0.10396 1
big_group_by = np.repeat(np.arange(500), 2) big_portfolio = vbt.Portfolio.from_orders( big_price_wide, big_order_size) print(big_portfolio.orders.values.shape) big_portfolio_grouped = vbt.Portfolio.from_orders( big_price_wide, big_order_size, group_by=big_group_by) print(big_portfolio_grouped.orders.values.shape) big_portfolio_shared = vbt.Portfolio.from_orders( big_price_wide, big_order_size, group_by=big_group_by, cash_sharing=True) print(big_portfolio_shared.orders.values.shape)
(1000000,) (1000000,) (1000000,)
print(portfolio.wrapper.index) print(portfolio.wrapper.columns) print(portfolio.wrapper.ndim) print(portfolio.wrapper.grouper.group_by) print(portfolio.wrapper.grouper.allow_enable) print(portfolio.wrapper.grouper.allow_disable) print(portfolio.wrapper.grouper.allow_modify) print(portfolio_grouped.wrapper.index) print(portfolio_grouped.wrapper.columns) print(portfolio_grouped.wrapper.ndim) print(portfolio_grouped.wrapper.grouper.group_by) print(portfolio_grouped.wrapper.grouper.allow_enable) print(portfolio_grouped.wrapper.grouper.allow_disable) print(portfolio_grouped.wrapper.grouper.allow_modify) print(portfolio_shared.wrapper.index) print(portfolio_shared.wrapper.columns) print(portfolio_shared.wrapper.ndim) print(portfolio_shared.wrapper.grouper.group_by) print(portfolio_shared.wrapper.grouper.allow_enable) print(portfolio_shared.wrapper.grouper.allow_disable) print(portfolio_shared.wrapper.grouper.allow_modify)
DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05'], dtype='datetime64[ns]', freq=None) Index(['a', 'b', 'c'], dtype='object') 2 None True True True DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05'], dtype='datetime64[ns]', freq=None) Index(['a', 'b', 'c'], dtype='object') 2 Index(['first', 'first', 'second'], dtype='object', name='group') True True True DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05'], dtype='datetime64[ns]', freq=None) Index(['a', 'b', 'c'], dtype='object') 2 Index(['first', 'first', 'second'], dtype='object', name='group') False True False
print(portfolio.orders.records) print(portfolio.orders.count()) print(portfolio.logs.count()) print(portfolio.close) print(portfolio.init_cash) print(portfolio.value()) print(portfolio.final_value())
id idx col size price fees side 0 0 1 0 0.1 2.02 0.10202 0 1 1 2 0 0.1 2.97 0.10297 1 2 2 4 0 1.0 5.05 0.15050 0 3 3 0 1 1.0 0.99 0.10990 1 4 4 1 1 0.1 1.98 0.10198 1 5 5 3 1 0.1 4.04 0.10404 0 6 6 4 1 1.0 4.95 0.14950 1 7 7 0 2 1.0 1.01 0.11010 0 8 8 1 2 0.1 2.02 0.10202 0 9 9 2 2 1.0 2.97 0.12970 1 10 10 3 2 0.1 3.96 0.10396 1 a 3 b 4 c 4 Name: count, dtype: int64 a 5 b 5 c 5 Name: count, dtype: int64 a b c 2020-01-01 NaN 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 NaN 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 NaN a 100.0 b 100.0 c 100.0 Name: init_cash, dtype: float64 a b c 2020-01-01 100.00000 99.88010 99.87990 2020-01-02 99.89598 98.77612 100.77588 2020-01-03 99.89001 98.77612 101.71618 2020-01-04 99.89001 96.46808 101.70822 2020-01-05 99.68951 95.26858 101.70822 a 99.68951 b 95.26858 c 101.70822 Name: final_value, dtype: float64
print(portfolio['a'].orders.records) print(portfolio['a'].orders.count()) print(portfolio['a'].logs.count()) print(portfolio['a'].close) print(portfolio['a'].init_cash) print(portfolio['a'].value()) print(portfolio['a'].final_value())
id idx col size price fees side 0 0 1 0 0.1 2.02 0.10202 0 1 1 2 0 0.1 2.97 0.10297 1 2 2 4 0 1.0 5.05 0.15050 0 3 5 2020-01-01 NaN 2020-01-02 2.0 2020-01-03 3.0 2020-01-04 4.0 2020-01-05 5.0 Name: a, dtype: float64 100.0 2020-01-01 100.00000 2020-01-02 99.89598 2020-01-03 99.89001 2020-01-04 99.89001 2020-01-05 99.68951 Name: a, dtype: float64 99.68951
print(portfolio['c'].orders.records) print(portfolio['c'].orders.count()) print(portfolio['c'].logs.count()) print(portfolio['c'].close) print(portfolio['c'].init_cash) print(portfolio['c'].value()) print(portfolio['c'].final_value())
id idx col size price fees side 0 7 0 0 1.0 1.01 0.11010 0 1 8 1 0 0.1 2.02 0.10202 0 2 9 2 0 1.0 2.97 0.12970 1 3 10 3 0 0.1 3.96 0.10396 1 4 5 2020-01-01 1.0 2020-01-02 2.0 2020-01-03 3.0 2020-01-04 4.0 2020-01-05 NaN Name: c, dtype: float64 100.0 2020-01-01 99.87990 2020-01-02 100.77588 2020-01-03 101.71618 2020-01-04 101.70822 2020-01-05 101.70822 Name: c, dtype: float64 101.70822
print(portfolio[['c']].orders.records) print(portfolio[['c']].orders.count()) print(portfolio[['c']].logs.count()) print(portfolio[['c']].close) print(portfolio[['c']].init_cash) print(portfolio[['c']].value()) print(portfolio[['c']].final_value())
id idx col size price fees side 0 7 0 0 1.0 1.01 0.11010 0 1 8 1 0 0.1 2.02 0.10202 0 2 9 2 0 1.0 2.97 0.12970 1 3 10 3 0 0.1 3.96 0.10396 1 c 4 Name: count, dtype: int64 c 5 Name: count, dtype: int64 c 2020-01-01 1.0 2020-01-02 2.0 2020-01-03 3.0 2020-01-04 4.0 2020-01-05 NaN c 100.0 Name: init_cash, dtype: float64 c 2020-01-01 99.87990 2020-01-02 100.77588 2020-01-03 101.71618 2020-01-04 101.70822 2020-01-05 101.70822 c 101.70822 Name: final_value, dtype: float64
print(portfolio_grouped.orders.records) print(portfolio_grouped.orders.count()) print(portfolio_grouped.logs.count()) print(portfolio_grouped.close) print(portfolio_grouped.init_cash) print(portfolio_grouped.value()) print(portfolio_grouped.final_value())
id idx col size price fees side 0 0 1 0 0.1 2.02 0.10202 0 1 1 2 0 0.1 2.97 0.10297 1 2 2 4 0 1.0 5.05 0.15050 0 3 3 0 1 1.0 0.99 0.10990 1 4 4 1 1 0.1 1.98 0.10198 1 5 5 3 1 0.1 4.04 0.10404 0 6 6 4 1 1.0 4.95 0.14950 1 7 7 0 2 1.0 1.01 0.11010 0 8 8 1 2 0.1 2.02 0.10202 0 9 9 2 2 1.0 2.97 0.12970 1 10 10 3 2 0.1 3.96 0.10396 1 group first 7 second 4 Name: count, dtype: int64 group first 10 second 5 Name: count, dtype: int64 a b c 2020-01-01 NaN 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 NaN 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 NaN group first 200.0 second 100.0 Name: init_cash, dtype: float64 group first second 2020-01-01 199.88010 99.87990 2020-01-02 198.67210 100.77588 2020-01-03 198.66613 101.71618 2020-01-04 196.35809 101.70822 2020-01-05 194.95809 101.70822 group first 194.95809 second 101.70822 Name: final_value, dtype: float64
print(portfolio_grouped['first'].orders.records) print(portfolio_grouped['first'].orders.count()) print(portfolio_grouped['first'].logs.count()) print(portfolio_grouped['first'].close) print(portfolio_grouped['first'].init_cash) print(portfolio_grouped['first'].value()) print(portfolio_grouped['first'].final_value())
id idx col size price fees side 0 0 1 0 0.1 2.02 0.10202 0 1 1 2 0 0.1 2.97 0.10297 1 2 2 4 0 1.0 5.05 0.15050 0 3 3 0 1 1.0 0.99 0.10990 1 4 4 1 1 0.1 1.98 0.10198 1 5 5 3 1 0.1 4.04 0.10404 0 6 6 4 1 1.0 4.95 0.14950 1 7 10 a b 2020-01-01 NaN 1.0 2020-01-02 2.0 2.0 2020-01-03 3.0 NaN 2020-01-04 4.0 4.0 2020-01-05 5.0 5.0 200.0 2020-01-01 199.88010 2020-01-02 198.67210 2020-01-03 196.46613 2020-01-04 196.35809 2020-01-05 194.95809 Name: first, dtype: float64 194.95809
print(portfolio_grouped['second'].orders.records) print(portfolio_grouped['second'].orders.count()) print(portfolio_grouped['second'].logs.count()) print(portfolio_grouped['second'].close) print(portfolio_grouped['second'].init_cash) print(portfolio_grouped['second'].value()) print(portfolio_grouped['second'].final_value())
id idx col size price fees side 0 7 0 0 1.0 1.01 0.11010 0 1 8 1 0 0.1 2.02 0.10202 0 2 9 2 0 1.0 2.97 0.12970 1 3 10 3 0 0.1 3.96 0.10396 1 4 5 2020-01-01 1.0 2020-01-02 2.0 2020-01-03 3.0 2020-01-04 4.0 2020-01-05 NaN Name: c, dtype: float64 100.0 2020-01-01 99.87990 2020-01-02 100.77588 2020-01-03 101.71618 2020-01-04 101.70822 2020-01-05 101.70822 Name: second, dtype: float64 101.70822
print(portfolio_grouped[['second']].orders.records) print(portfolio_grouped[['second']].orders.count()) print(portfolio_grouped[['second']].logs.count()) print(portfolio_grouped[['second']].close) print(portfolio_grouped[['second']].init_cash) print(portfolio_grouped[['second']].value()) print(portfolio_grouped[['second']].final_value())
id idx col size price fees side 0 7 0 0 1.0 1.01 0.11010 0 1 8 1 0 0.1 2.02 0.10202 0 2 9 2 0 1.0 2.97 0.12970 1 3 10 3 0 0.1 3.96 0.10396 1 group second 4 Name: count, dtype: int64 group second 5 Name: count, dtype: int64 c 2020-01-01 1.0 2020-01-02 2.0 2020-01-03 3.0 2020-01-04 4.0 2020-01-05 NaN group second 100.0 Name: init_cash, dtype: float64 group second 2020-01-01 99.87990 2020-01-02 100.77588 2020-01-03 101.71618 2020-01-04 101.70822 2020-01-05 101.70822 group second 101.70822 Name: final_value, dtype: float64
%timeit big_portfolio.iloc[0] %timeit big_portfolio.iloc[:] %timeit big_portfolio_grouped.iloc[0] %timeit big_portfolio_grouped.iloc[:] %timeit big_portfolio_shared.iloc[0] %timeit big_portfolio_shared.iloc[:]
3.42 ms ± 283 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) The slowest run took 17.43 times longer than the fastest. This could mean that an intermediate result is being cached. 111 ms ± 89.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 3.37 ms ± 46.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 14.3 ms ± 1.99 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 6.41 ms ± 139 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 18.1 ms ± 366 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.cash_sharing) print(portfolio_grouped.cash_sharing) print(portfolio_shared.cash_sharing)
False False True
print(portfolio.call_seq) print(portfolio_grouped.call_seq) print(portfolio_shared.call_seq)
a b c 2020-01-01 0 0 0 2020-01-02 0 0 0 2020-01-03 0 0 0 2020-01-04 0 0 0 2020-01-05 0 0 0 a b c 2020-01-01 1 0 0 2020-01-02 1 0 0 2020-01-03 1 0 0 2020-01-04 1 0 0 2020-01-05 1 0 0 a b c 2020-01-01 1 0 0 2020-01-02 1 0 0 2020-01-03 1 0 0 2020-01-04 1 0 0 2020-01-05 1 0 0
print(portfolio.orders.count()) print(portfolio_grouped.get_orders(group_by=False).count()) print(portfolio_shared.get_orders(group_by=False).count()) print(portfolio.get_orders(group_by=group_by).count()) print(portfolio_grouped.orders.count()) print(portfolio_shared.orders.count())
a 3 b 4 c 4 Name: count, dtype: int64 a 3 b 4 c 4 Name: count, dtype: int64 a 3 b 4 c 4 Name: count, dtype: int64 group first 7 second 4 Name: count, dtype: int64 group first 7 second 4 Name: count, dtype: int64 group first 7 second 4 Name: count, dtype: int64
print(portfolio.logs.count()) print(portfolio_grouped.get_logs(group_by=False).count()) print(portfolio_shared.get_logs(group_by=False).count()) print(portfolio.get_logs(group_by=group_by).count()) print(portfolio_grouped.logs.count()) print(portfolio_shared.logs.count())
a 5 b 5 c 5 Name: count, dtype: int64 a 5 b 5 c 5 Name: count, dtype: int64 a 5 b 5 c 5 Name: count, dtype: int64 group first 10 second 5 Name: count, dtype: int64 group first 10 second 5 Name: count, dtype: int64 group first 10 second 5 Name: count, dtype: int64
print(portfolio.entry_trades.count()) print(portfolio_grouped.get_entry_trades(group_by=False).count()) print(portfolio_shared.get_entry_trades(group_by=False).count()) print(portfolio.get_entry_trades(group_by=group_by).count()) print(portfolio_grouped.entry_trades.count()) print(portfolio_shared.entry_trades.count())
a 2 b 3 c 2 Name: count, dtype: int64 a 2 b 3 c 2 Name: count, dtype: int64 a 2 b 3 c 2 Name: count, dtype: int64 group first 5 second 2 Name: count, dtype: int64 group first 5 second 2 Name: count, dtype: int64 group first 5 second 2 Name: count, dtype: int64
%timeit big_portfolio.entry_trades
397 ms ± 3.87 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
print(portfolio.exit_trades.count()) print(portfolio_grouped.get_exit_trades(group_by=False).count()) print(portfolio_shared.get_exit_trades(group_by=False).count()) print(portfolio.get_exit_trades(group_by=group_by).count()) print(portfolio_grouped.exit_trades.count()) print(portfolio_shared.exit_trades.count())
a 2 b 2 c 2 Name: count, dtype: int64 a 2 b 2 c 2 Name: count, dtype: int64 a 2 b 2 c 2 Name: count, dtype: int64 group first 4 second 2 Name: count, dtype: int64 group first 4 second 2 Name: count, dtype: int64 group first 4 second 2 Name: count, dtype: int64
%timeit big_portfolio.exit_trades
13.8 ms ± 607 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
print(portfolio.positions.count()) print(portfolio_grouped.get_positions(group_by=False).count()) print(portfolio_shared.get_positions(group_by=False).count()) print(portfolio.get_positions(group_by=group_by).count()) print(portfolio_grouped.positions.count()) print(portfolio_shared.positions.count())
a 2 b 1 c 1 Name: count, dtype: int64 a 2 b 1 c 1 Name: count, dtype: int64 a 2 b 1 c 1 Name: count, dtype: int64 group first 3 second 1 Name: count, dtype: int64 group first 3 second 1 Name: count, dtype: int64 group first 3 second 1 Name: count, dtype: int64
%timeit big_portfolio.positions
28.4 ms ± 3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.drawdowns.count()) print(portfolio_grouped.get_drawdowns(group_by=False).count()) print(portfolio_shared.get_drawdowns(group_by=False).count()) print(portfolio.get_drawdowns(group_by=group_by).count()) print(portfolio_grouped.drawdowns.count()) print(portfolio_shared.drawdowns.count())
a 1 b 1 c 1 Name: count, dtype: int64 a 1 b 1 c 1 Name: count, dtype: int64 a 1 b 1 c 1 Name: count, dtype: int64 group first 1 second 1 Name: count, dtype: int64 group first 1 second 1 Name: count, dtype: int64 group first 1 second 1 Name: count, dtype: int64
%timeit big_portfolio.drawdowns
39.9 ms ± 907 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
print(portfolio.close) print(portfolio_grouped.close) print(portfolio_shared.close)
a b c 2020-01-01 NaN 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 NaN 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 NaN a b c 2020-01-01 NaN 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 NaN 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 NaN a b c 2020-01-01 NaN 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 NaN 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 NaN
print(portfolio.fill_close(ffill=False, bfill=False)) print(portfolio.fill_close(ffill=True, bfill=False)) print(portfolio.fill_close(ffill=False, bfill=True)) print(portfolio.fill_close(ffill=True, bfill=True))
a b c 2020-01-01 NaN 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 NaN 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 NaN a b c 2020-01-01 NaN 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 2.0 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 4.0 a b c 2020-01-01 2.0 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 4.0 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 NaN a b c 2020-01-01 2.0 1.0 1.0 2020-01-02 2.0 2.0 2.0 2020-01-03 3.0 2.0 3.0 2020-01-04 4.0 4.0 4.0 2020-01-05 5.0 5.0 4.0
%timeit big_portfolio.fill_close()
67.6 µs ± 1.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
print(portfolio.asset_flow(direction='longonly')) print(portfolio.asset_flow(direction='shortonly')) print(portfolio.asset_flow()) print(portfolio_grouped.asset_flow()) print(portfolio_shared.asset_flow())
a b c 2020-01-01 0.0 0.0 1.0 2020-01-02 0.1 0.0 0.1 2020-01-03 -0.1 0.0 -1.0 2020-01-04 0.0 0.0 -0.1 2020-01-05 1.0 0.0 0.0 a b c 2020-01-01 0.0 1.0 0.0 2020-01-02 0.0 0.1 0.0 2020-01-03 0.0 0.0 0.0 2020-01-04 0.0 -0.1 0.0 2020-01-05 0.0 1.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.1 -0.1 0.1 2020-01-03 -0.1 0.0 -1.0 2020-01-04 0.0 0.1 -0.1 2020-01-05 1.0 -1.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.1 -0.1 0.1 2020-01-03 -0.1 0.0 -1.0 2020-01-04 0.0 0.1 -0.1 2020-01-05 1.0 -1.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.1 -0.1 0.1 2020-01-03 -0.1 0.0 -1.0 2020-01-04 0.0 0.1 -0.1 2020-01-05 1.0 -1.0 0.0
%timeit big_portfolio.asset_flow() %timeit big_portfolio_grouped.asset_flow() %timeit big_portfolio_shared.asset_flow()
11 ms ± 539 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 10.6 ms ± 276 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 10.5 ms ± 148 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio.assets(direction='longonly')) print(portfolio.assets(direction='shortonly')) print(portfolio.assets()) print(portfolio_grouped.assets()) print(portfolio_shared.assets())
a b c 2020-01-01 0.0 0.0 1.0 2020-01-02 0.1 0.0 1.1 2020-01-03 0.0 0.0 0.1 2020-01-04 0.0 0.0 0.0 2020-01-05 1.0 0.0 0.0 a b c 2020-01-01 0.0 1.0 0.0 2020-01-02 0.0 1.1 0.0 2020-01-03 0.0 1.1 0.0 2020-01-04 0.0 1.0 0.0 2020-01-05 0.0 2.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.1 -1.1 1.1 2020-01-03 0.0 -1.1 0.1 2020-01-04 0.0 -1.0 0.0 2020-01-05 1.0 -2.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.1 -1.1 1.1 2020-01-03 0.0 -1.1 0.1 2020-01-04 0.0 -1.0 0.0 2020-01-05 1.0 -2.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.1 -1.1 1.1 2020-01-03 0.0 -1.1 0.1 2020-01-04 0.0 -1.0 0.0 2020-01-05 1.0 -2.0 0.0
%timeit big_portfolio.assets() %timeit big_portfolio_grouped.assets() %timeit big_portfolio_shared.assets()
14.4 ms ± 539 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 14.6 ms ± 265 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 14 ms ± 50.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio.position_mask(direction='longonly')) print(portfolio.position_mask(direction='shortonly')) print(portfolio.position_mask()) print(portfolio_grouped.position_mask(group_by=False)) print(portfolio_shared.position_mask(group_by=False)) print(portfolio.position_mask(group_by=group_by)) print(portfolio_grouped.position_mask()) print(portfolio_shared.position_mask())
a b c 2020-01-01 False False True 2020-01-02 True False True 2020-01-03 False False True 2020-01-04 False False False 2020-01-05 True False False a b c 2020-01-01 False True False 2020-01-02 False True False 2020-01-03 False True False 2020-01-04 False True False 2020-01-05 False True False a b c 2020-01-01 False True True 2020-01-02 True True True 2020-01-03 False True True 2020-01-04 False True False 2020-01-05 True True False a b c 2020-01-01 False True True 2020-01-02 True True True 2020-01-03 False True True 2020-01-04 False True False 2020-01-05 True True False a b c 2020-01-01 False True True 2020-01-02 True True True 2020-01-03 False True True 2020-01-04 False True False 2020-01-05 True True False group first second 2020-01-01 True True 2020-01-02 True True 2020-01-03 True True 2020-01-04 True False 2020-01-05 True False group first second 2020-01-01 True True 2020-01-02 True True 2020-01-03 True True 2020-01-04 True False 2020-01-05 True False group first second 2020-01-01 True True 2020-01-02 True True 2020-01-03 True True 2020-01-04 True False 2020-01-05 True False
%timeit big_portfolio.position_mask() %timeit big_portfolio_grouped.position_mask(group_by=False) %timeit big_portfolio_shared.position_mask(group_by=False) %timeit big_portfolio.position_mask(group_by=big_group_by) %timeit big_portfolio_grouped.position_mask() %timeit big_portfolio_shared.position_mask()
14.8 ms ± 113 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 15.1 ms ± 462 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 15.6 ms ± 299 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 31.4 ms ± 275 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 31 ms ± 198 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 32 ms ± 208 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.position_coverage(direction='longonly')) print(portfolio.position_coverage(direction='shortonly')) print(portfolio.position_coverage()) print(portfolio_grouped.position_coverage(group_by=False)) print(portfolio_shared.position_coverage(group_by=False)) print(portfolio.position_coverage(group_by=group_by)) print(portfolio_grouped.position_coverage()) print(portfolio_shared.position_coverage())
a 0.4 b 0.0 c 0.6 Name: position_coverage, dtype: float64 a 0.0 b 1.0 c 0.0 Name: position_coverage, dtype: float64 a 0.4 b 1.0 c 0.6 Name: position_coverage, dtype: float64 a 0.4 b 1.0 c 0.6 Name: position_coverage, dtype: float64 a 0.4 b 1.0 c 0.6 Name: position_coverage, dtype: float64 group first 0.7 second 0.6 Name: position_coverage, dtype: float64 group first 0.7 second 0.6 Name: position_coverage, dtype: float64 group first 0.7 second 0.6 Name: position_coverage, dtype: float64
%timeit big_portfolio.position_coverage() %timeit big_portfolio_grouped.position_coverage(group_by=False) %timeit big_portfolio_shared.position_coverage(group_by=False) %timeit big_portfolio.position_coverage(group_by=big_group_by) %timeit big_portfolio_grouped.position_coverage() %timeit big_portfolio_shared.position_coverage()
16.6 ms ± 1.51 ms per loop (mean ± std. dev. of 7 runs, 100 loops each) 14.8 ms ± 104 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 15 ms ± 116 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 34.1 ms ± 1.49 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 32.2 ms ± 1.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 33.4 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.cash_flow(free=True)) print(portfolio.cash_flow()) print(portfolio_grouped.cash_flow(group_by=False)) print(portfolio_shared.cash_flow(group_by=False)) print(portfolio.cash_flow(group_by=group_by)) print(portfolio_grouped.cash_flow()) print(portfolio_shared.cash_flow())
a b c 2020-01-01 0.00000 -1.09990 -1.12010 2020-01-02 -0.30402 -0.29998 -0.30402 2020-01-03 0.19403 0.00000 2.84030 2020-01-04 0.00000 -0.29204 0.29204 2020-01-05 -5.20050 -5.09950 0.00000 a b c 2020-01-01 0.00000 0.88010 -1.12010 2020-01-02 -0.30402 0.09602 -0.30402 2020-01-03 0.19403 0.00000 2.84030 2020-01-04 0.00000 -0.50804 0.29204 2020-01-05 -5.20050 4.80050 0.00000 a b c 2020-01-01 0.00000 0.88010 -1.12010 2020-01-02 -0.30402 0.09602 -0.30402 2020-01-03 0.19403 0.00000 2.84030 2020-01-04 0.00000 -0.50804 0.29204 2020-01-05 -5.20050 4.80050 0.00000 a b c 2020-01-01 0.00000 0.88010 -1.12010 2020-01-02 -0.30402 0.09602 -0.30402 2020-01-03 0.19403 0.00000 2.84030 2020-01-04 0.00000 -0.50804 0.29204 2020-01-05 -5.20050 4.80050 0.00000 group first second 2020-01-01 0.88010 -1.12010 2020-01-02 -0.20800 -0.30402 2020-01-03 0.19403 2.84030 2020-01-04 -0.50804 0.29204 2020-01-05 -0.40000 0.00000 group first second 2020-01-01 0.88010 -1.12010 2020-01-02 -0.20800 -0.30402 2020-01-03 0.19403 2.84030 2020-01-04 -0.50804 0.29204 2020-01-05 -0.40000 0.00000 group first second 2020-01-01 0.88010 -1.12010 2020-01-02 -0.20800 -0.30402 2020-01-03 0.19403 2.84030 2020-01-04 -0.50804 0.29204 2020-01-05 -0.40000 0.00000
%timeit big_portfolio.cash_flow() %timeit big_portfolio.cash_flow(free=True) %timeit big_portfolio_grouped.cash_flow(group_by=False) %timeit big_portfolio_shared.cash_flow(group_by=False) %timeit big_portfolio.cash_flow(group_by=big_group_by) %timeit big_portfolio_grouped.cash_flow() %timeit big_portfolio_shared.cash_flow()
14.4 ms ± 912 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 20.4 ms ± 144 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 14.6 ms ± 88.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 16.3 ms ± 81.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 17.9 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 16.7 ms ± 118 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 20.1 ms ± 155 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio.get_init_cash()) print(portfolio_grouped.get_init_cash(group_by=False)) print(portfolio_shared.get_init_cash(group_by=False)) print(portfolio.get_init_cash(group_by=group_by)) print(portfolio_grouped.get_init_cash()) print(portfolio_shared.get_init_cash())
a 100.0 b 100.0 c 100.0 Name: init_cash, dtype: float64 a 100.0 b 100.0 c 100.0 Name: init_cash, dtype: float64 a 200.0 b 200.0 c 100.0 Name: init_cash, dtype: float64 group first 200.0 second 100.0 Name: init_cash, dtype: float64 group first 200.0 second 100.0 Name: init_cash, dtype: float64 group first 200.0 second 100.0 Name: init_cash, dtype: float64
%timeit big_portfolio.get_init_cash() %timeit big_portfolio_grouped.get_init_cash(group_by=False) %timeit big_portfolio_shared.get_init_cash(group_by=False) %timeit big_portfolio.get_init_cash(group_by=big_group_by) %timeit big_portfolio_grouped.get_init_cash() %timeit big_portfolio_shared.get_init_cash()
53.9 µs ± 387 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 53.6 µs ± 187 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 870 µs ± 2.61 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 912 µs ± 2.62 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 57.9 µs ± 1.76 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each) 1.26 ms ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit big_portfolio.get_init_cash() %timeit big_portfolio_grouped.get_init_cash(group_by=False) %timeit big_portfolio_shared.get_init_cash(group_by=False) %timeit big_portfolio.get_init_cash(group_by=big_group_by) %timeit big_portfolio_grouped.get_init_cash() %timeit big_portfolio_shared.get_init_cash()
43.2 µs ± 125 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 42.9 µs ± 611 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 533 µs ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 737 µs ± 44.3 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 46.6 µs ± 617 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 850 µs ± 37.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
print(vbt.Portfolio.from_orders( price_na, 1000., init_cash=InitCashMode.Auto, group_by=None).init_cash) print(vbt.Portfolio.from_orders( price_na, 1000., init_cash=InitCashMode.Auto, group_by=group_by).init_cash) print(vbt.Portfolio.from_orders( price_na, 1000., init_cash=InitCashMode.Auto, group_by=group_by, cash_sharing=True).init_cash) print(vbt.Portfolio.from_orders( price_na, 1000., init_cash=InitCashMode.AutoAlign, group_by=None).init_cash) print(vbt.Portfolio.from_orders( price_na, 1000., init_cash=InitCashMode.AutoAlign, group_by=group_by).init_cash) print(vbt.Portfolio.from_orders( price_na, 1000., init_cash=InitCashMode.AutoAlign, group_by=group_by, cash_sharing=True).init_cash)
a 14000.0 b 12000.0 c 10000.0 Name: init_cash, dtype: float64 group first 26000.0 second 10000.0 Name: init_cash, dtype: float64 group first 26000.0 second 10000.0 Name: init_cash, dtype: float64 a 14000.0 b 14000.0 c 14000.0 Name: init_cash, dtype: float64 group first 26000.0 second 26000.0 Name: init_cash, dtype: float64 group first 26000.0 second 26000.0 Name: init_cash, dtype: float64
print(portfolio.cash(free=True)) print(portfolio.cash()) print(portfolio_grouped.cash(group_by=False)) print(portfolio_shared.cash(group_by=False)) print(portfolio_shared.cash(group_by=False, in_sim_order=True)) print(portfolio.cash(group_by=group_by)) print(portfolio_grouped.cash()) print(portfolio_shared.cash())
a b c 2020-01-01 100.00000 98.90010 98.87990 2020-01-02 99.69598 98.60012 98.57588 2020-01-03 99.89001 98.60012 101.41618 2020-01-04 99.89001 98.30808 101.70822 2020-01-05 94.68951 93.20858 101.70822 a b c 2020-01-01 100.00000 100.88010 98.87990 2020-01-02 99.69598 100.97612 98.57588 2020-01-03 99.89001 100.97612 101.41618 2020-01-04 99.89001 100.46808 101.70822 2020-01-05 94.68951 105.26858 101.70822 a b c 2020-01-01 100.00000 100.88010 98.87990 2020-01-02 99.69598 100.97612 98.57588 2020-01-03 99.89001 100.97612 101.41618 2020-01-04 99.89001 100.46808 101.70822 2020-01-05 94.68951 105.26858 101.70822 a b c 2020-01-01 200.00000 200.88010 98.87990 2020-01-02 199.69598 200.97612 98.57588 2020-01-03 199.89001 200.97612 101.41618 2020-01-04 199.89001 200.46808 101.70822 2020-01-05 194.68951 205.26858 101.70822 a b c 2020-01-01 200.88010 200.88010 98.87990 2020-01-02 200.67210 200.97612 98.57588 2020-01-03 200.86613 200.67210 101.41618 2020-01-04 200.35809 200.35809 101.70822 2020-01-05 199.95809 205.15859 101.70822 group first second 2020-01-01 200.88010 98.87990 2020-01-02 200.67210 98.57588 2020-01-03 200.86613 101.41618 2020-01-04 200.35809 101.70822 2020-01-05 199.95809 101.70822 group first second 2020-01-01 200.88010 98.87990 2020-01-02 200.67210 98.57588 2020-01-03 200.86613 101.41618 2020-01-04 200.35809 101.70822 2020-01-05 199.95809 101.70822 group first second 2020-01-01 200.88010 98.87990 2020-01-02 200.67210 98.57588 2020-01-03 200.86613 101.41618 2020-01-04 200.35809 101.70822 2020-01-05 199.95809 101.70822
%timeit big_portfolio.cash() %timeit big_portfolio.cash(free=True) %timeit big_portfolio_grouped.cash(group_by=False) %timeit big_portfolio_shared.cash(group_by=False) %timeit big_portfolio_shared.cash(group_by=False, in_sim_order=True) %timeit big_portfolio.cash(group_by=big_group_by) %timeit big_portfolio_grouped.cash() %timeit big_portfolio_shared.cash()
19.4 ms ± 920 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 18.3 ms ± 470 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 18.4 ms ± 2.12 ms per loop (mean ± std. dev. of 7 runs, 100 loops each) 17.6 ms ± 201 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 18.7 ms ± 303 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 18.3 ms ± 292 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 19.6 ms ± 1.75 ms per loop (mean ± std. dev. of 7 runs, 100 loops each) 21.7 ms ± 1.76 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
print(portfolio.asset_value(direction='longonly')) print(portfolio.asset_value(direction='shortonly')) print(portfolio.asset_value()) print(portfolio_grouped.asset_value(group_by=False)) print(portfolio_shared.asset_value(group_by=False)) print(portfolio.asset_value(group_by=group_by)) print(portfolio_grouped.asset_value()) print(portfolio_shared.asset_value())
a b c 2020-01-01 0.0 0.0 1.0 2020-01-02 0.2 0.0 2.2 2020-01-03 0.0 0.0 0.3 2020-01-04 0.0 0.0 0.0 2020-01-05 5.0 0.0 0.0 a b c 2020-01-01 0.0 1.0 0.0 2020-01-02 0.0 2.2 0.0 2020-01-03 0.0 2.2 0.0 2020-01-04 0.0 4.0 0.0 2020-01-05 0.0 10.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.2 -2.2 2.2 2020-01-03 0.0 -2.2 0.3 2020-01-04 0.0 -4.0 0.0 2020-01-05 5.0 -10.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.2 -2.2 2.2 2020-01-03 0.0 -2.2 0.3 2020-01-04 0.0 -4.0 0.0 2020-01-05 5.0 -10.0 0.0 a b c 2020-01-01 0.0 -1.0 1.0 2020-01-02 0.2 -2.2 2.2 2020-01-03 0.0 -2.2 0.3 2020-01-04 0.0 -4.0 0.0 2020-01-05 5.0 -10.0 0.0 group first second 2020-01-01 -1.0 1.0 2020-01-02 -2.0 2.2 2020-01-03 -2.2 0.3 2020-01-04 -4.0 0.0 2020-01-05 -5.0 0.0 group first second 2020-01-01 -1.0 1.0 2020-01-02 -2.0 2.2 2020-01-03 -2.2 0.3 2020-01-04 -4.0 0.0 2020-01-05 -5.0 0.0 group first second 2020-01-01 -1.0 1.0 2020-01-02 -2.0 2.2 2020-01-03 -2.2 0.3 2020-01-04 -4.0 0.0 2020-01-05 -5.0 0.0
%timeit big_portfolio.asset_value() %timeit big_portfolio_grouped.asset_value(group_by=False) %timeit big_portfolio_shared.asset_value(group_by=False) %timeit big_portfolio.asset_value(group_by=big_group_by) %timeit big_portfolio_grouped.asset_value() %timeit big_portfolio_shared.asset_value()
16.7 ms ± 331 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 19.4 ms ± 2.51 ms per loop (mean ± std. dev. of 7 runs, 100 loops each) 18.4 ms ± 1.48 ms per loop (mean ± std. dev. of 7 runs, 100 loops each) 34.4 ms ± 308 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 33.6 ms ± 428 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 34.7 ms ± 213 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.gross_exposure(direction='longonly')) print(portfolio.gross_exposure(direction='shortonly')) print(portfolio.gross_exposure()) print(portfolio_grouped.gross_exposure(group_by=False)) print(portfolio_shared.gross_exposure(group_by=False)) print(portfolio.gross_exposure(group_by=group_by)) print(portfolio_grouped.gross_exposure()) print(portfolio_shared.gross_exposure())
a b c 2020-01-01 0.000000 0.0 0.010012 2020-01-02 0.002002 0.0 0.021831 2020-01-03 0.000000 0.0 0.002949 2020-01-04 0.000000 0.0 0.000000 2020-01-05 0.050156 0.0 0.000000 a b c 2020-01-01 0.0 0.010010 0.0 2020-01-02 0.0 0.021825 0.0 2020-01-03 0.0 0.021825 0.0 2020-01-04 0.0 0.039098 0.0 2020-01-05 0.0 0.096891 0.0 a b c 2020-01-01 0.000000 -0.010214 0.010012 2020-01-02 0.002002 -0.022822 0.021831 2020-01-03 0.000000 -0.022822 0.002949 2020-01-04 0.000000 -0.042414 0.000000 2020-01-05 0.050156 -0.120180 0.000000 a b c 2020-01-01 0.000000 -0.010214 0.010012 2020-01-02 0.002002 -0.022822 0.021831 2020-01-03 0.000000 -0.022822 0.002949 2020-01-04 0.000000 -0.042414 0.000000 2020-01-05 0.050156 -0.120180 0.000000 a b c 2020-01-01 0.000000 -0.005053 0.010012 2020-01-02 0.001001 -0.011202 0.021831 2020-01-03 0.000000 -0.011202 0.002949 2020-01-04 0.000000 -0.020586 0.000000 2020-01-05 0.025039 -0.054583 0.000000 group first second 2020-01-01 -0.005053 0.010012 2020-01-02 -0.010189 0.021831 2020-01-03 -0.011208 0.002949 2020-01-04 -0.020598 0.000000 2020-01-05 -0.027338 0.000000 group first second 2020-01-01 -0.005053 0.010012 2020-01-02 -0.010189 0.021831 2020-01-03 -0.011208 0.002949 2020-01-04 -0.020598 0.000000 2020-01-05 -0.027338 0.000000 group first second 2020-01-01 -0.005053 0.010012 2020-01-02 -0.010189 0.021831 2020-01-03 -0.011208 0.002949 2020-01-04 -0.020598 0.000000 2020-01-05 -0.027338 0.000000
%timeit big_portfolio.gross_exposure() %timeit big_portfolio_grouped.gross_exposure(group_by=False) %timeit big_portfolio_shared.gross_exposure(group_by=False) %timeit big_portfolio.gross_exposure(group_by=big_group_by) %timeit big_portfolio_grouped.gross_exposure() %timeit big_portfolio_shared.gross_exposure()
54.6 ms ± 5.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 44.3 ms ± 1.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 44.2 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 58.8 ms ± 2.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 55 ms ± 1.09 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 60.9 ms ± 1.87 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.net_exposure()) print(portfolio_grouped.net_exposure(group_by=False)) print(portfolio_shared.net_exposure(group_by=False)) print(portfolio.net_exposure(group_by=group_by)) print(portfolio_grouped.net_exposure()) print(portfolio_shared.net_exposure())
a b c 2020-01-01 0.000000 -0.010010 0.010012 2020-01-02 0.002002 -0.021825 0.021831 2020-01-03 0.000000 -0.021825 0.002949 2020-01-04 0.000000 -0.039098 0.000000 2020-01-05 0.050156 -0.096891 0.000000 a b c 2020-01-01 0.000000 -0.010010 0.010012 2020-01-02 0.002002 -0.021825 0.021831 2020-01-03 0.000000 -0.021825 0.002949 2020-01-04 0.000000 -0.039098 0.000000 2020-01-05 0.050156 -0.096891 0.000000 a b c 2020-01-01 0.000000 -0.005002 0.010012 2020-01-02 0.001001 -0.010956 0.021831 2020-01-03 0.000000 -0.010956 0.002949 2020-01-04 0.000000 -0.019772 0.000000 2020-01-05 0.025039 -0.049211 0.000000 group first second 2020-01-01 -0.005002 0.010012 2020-01-02 -0.009965 0.021831 2020-01-03 -0.010962 0.002949 2020-01-04 -0.019783 0.000000 2020-01-05 -0.024611 0.000000 group first second 2020-01-01 -0.005002 0.010012 2020-01-02 -0.009965 0.021831 2020-01-03 -0.010962 0.002949 2020-01-04 -0.019783 0.000000 2020-01-05 -0.024611 0.000000 group first second 2020-01-01 -0.005002 0.010012 2020-01-02 -0.009965 0.021831 2020-01-03 -0.010962 0.002949 2020-01-04 -0.019783 0.000000 2020-01-05 -0.024611 0.000000
%timeit big_portfolio.net_exposure() %timeit big_portfolio_grouped.net_exposure(group_by=False) %timeit big_portfolio_shared.net_exposure(group_by=False) %timeit big_portfolio.net_exposure(group_by=big_group_by) %timeit big_portfolio_grouped.net_exposure() %timeit big_portfolio_shared.net_exposure()
91.5 ms ± 1.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 90.4 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 95.4 ms ± 4.26 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 129 ms ± 3.21 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 119 ms ± 1.51 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 127 ms ± 1.85 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.value()) print(portfolio_grouped.value(group_by=False)) print(portfolio_shared.value(group_by=False)) print(portfolio_shared.value(group_by=False, in_sim_order=True)) print(portfolio.value(group_by=group_by)) print(portfolio_grouped.value()) print(portfolio_shared.value())
a b c 2020-01-01 100.00000 99.88010 99.87990 2020-01-02 99.89598 98.77612 100.77588 2020-01-03 99.89001 98.77612 101.71618 2020-01-04 99.89001 96.46808 101.70822 2020-01-05 99.68951 95.26858 101.70822 a b c 2020-01-01 100.00000 99.88010 99.87990 2020-01-02 99.89598 98.77612 100.77588 2020-01-03 99.89001 98.77612 101.71618 2020-01-04 99.89001 96.46808 101.70822 2020-01-05 99.68951 95.26858 101.70822 a b c 2020-01-01 200.00000 199.88010 99.87990 2020-01-02 199.89598 198.77612 100.77588 2020-01-03 199.89001 198.77612 101.71618 2020-01-04 199.89001 196.46808 101.70822 2020-01-05 199.68951 195.26858 101.70822 a b c 2020-01-01 199.88010 199.88010 99.87990 2020-01-02 198.67210 198.77612 100.77588 2020-01-03 198.66613 198.67210 101.71618 2020-01-04 196.35809 196.35809 101.70822 2020-01-05 194.95809 195.15859 101.70822 group first second 2020-01-01 199.88010 99.87990 2020-01-02 198.67210 100.77588 2020-01-03 198.66613 101.71618 2020-01-04 196.35809 101.70822 2020-01-05 194.95809 101.70822 group first second 2020-01-01 199.88010 99.87990 2020-01-02 198.67210 100.77588 2020-01-03 198.66613 101.71618 2020-01-04 196.35809 101.70822 2020-01-05 194.95809 101.70822 group first second 2020-01-01 199.88010 99.87990 2020-01-02 198.67210 100.77588 2020-01-03 198.66613 101.71618 2020-01-04 196.35809 101.70822 2020-01-05 194.95809 101.70822
%timeit big_portfolio.value() %timeit big_portfolio_grouped.value(group_by=False) %timeit big_portfolio_shared.value(group_by=False) %timeit big_portfolio_shared.value(group_by=False, in_sim_order=True) %timeit big_portfolio.value(group_by=big_group_by) %timeit big_portfolio_grouped.value() %timeit big_portfolio_shared.value()
36.9 ms ± 1.21 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 35 ms ± 210 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 35.8 ms ± 81.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 46 ms ± 152 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 53.9 ms ± 626 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 50.4 ms ± 722 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 55.3 ms ± 941 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.total_profit()) print(portfolio_grouped.total_profit(group_by=False)) print(portfolio_shared.total_profit(group_by=False)) print(portfolio.total_profit(group_by=group_by)) print(portfolio_grouped.total_profit()) print(portfolio_shared.total_profit())
a -0.31049 b -4.73142 c 1.70822 Name: total_profit, dtype: float64 a -0.31049 b -4.73142 c 1.70822 Name: total_profit, dtype: float64 a -0.31049 b -4.73142 c 1.70822 Name: total_profit, dtype: float64 group first -5.04191 second 1.70822 Name: total_profit, dtype: float64 group first -5.04191 second 1.70822 Name: total_profit, dtype: float64 group first -5.04191 second 1.70822 Name: total_profit, dtype: float64
%timeit big_portfolio.total_profit() %timeit big_portfolio_grouped.total_profit(group_by=False) %timeit big_portfolio_shared.total_profit(group_by=False) %timeit big_portfolio.total_profit(group_by=big_group_by) %timeit big_portfolio_grouped.total_profit() %timeit big_portfolio_shared.total_profit()
12.3 ms ± 79.7 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 12.5 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12.5 ms ± 225 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 13.2 ms ± 224 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12.6 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 13.4 ms ± 217 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio.final_value()) print(portfolio_grouped.final_value(group_by=False)) print(portfolio_shared.final_value(group_by=False)) print(portfolio.final_value(group_by=group_by)) print(portfolio_grouped.final_value()) print(portfolio_shared.final_value())
a 99.68951 b 95.26858 c 101.70822 Name: final_value, dtype: float64 a 99.68951 b 95.26858 c 101.70822 Name: final_value, dtype: float64 a 199.68951 b 195.26858 c 101.70822 Name: final_value, dtype: float64 group first 194.95809 second 101.70822 Name: final_value, dtype: float64 group first 194.95809 second 101.70822 Name: final_value, dtype: float64 group first 194.95809 second 101.70822 Name: final_value, dtype: float64
%timeit big_portfolio.final_value() %timeit big_portfolio_grouped.final_value(group_by=False) %timeit big_portfolio_shared.final_value(group_by=False) %timeit big_portfolio.final_value(group_by=big_group_by) %timeit big_portfolio_grouped.final_value() %timeit big_portfolio_shared.final_value()
12.3 ms ± 159 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12.2 ms ± 122 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12.9 ms ± 128 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 14.1 ms ± 280 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12 ms ± 145 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 14.1 ms ± 231 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio.total_return()) print(portfolio_grouped.total_return(group_by=False)) print(portfolio_shared.total_return(group_by=False)) print(portfolio.total_return(group_by=group_by)) print(portfolio_grouped.total_return()) print(portfolio_shared.total_return())
a -0.003105 b -0.047314 c 0.017082 Name: total_return, dtype: float64 a -0.003105 b -0.047314 c 0.017082 Name: total_return, dtype: float64 a -0.001552 b -0.023657 c 0.017082 Name: total_return, dtype: float64 group first -0.025210 second 0.017082 Name: total_return, dtype: float64 group first -0.025210 second 0.017082 Name: total_return, dtype: float64 group first -0.025210 second 0.017082 Name: total_return, dtype: float64
%timeit big_portfolio.total_return() %timeit big_portfolio_grouped.total_return(group_by=False) %timeit big_portfolio_shared.total_return(group_by=False) %timeit big_portfolio.total_return(group_by=big_group_by) %timeit big_portfolio_grouped.total_return() %timeit big_portfolio_shared.total_return()
12.5 ms ± 200 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12.4 ms ± 207 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12.8 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 14 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 12.6 ms ± 199 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 14.2 ms ± 122 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio.returns()) print(portfolio_grouped.returns(group_by=False)) print(portfolio_shared.returns(group_by=False)) print(portfolio_shared.returns(group_by=False, in_sim_order=True)) print(portfolio.returns(group_by=group_by)) print(portfolio_grouped.returns()) print(portfolio_shared.returns())
a b c 2020-01-01 0.000000 -0.001199 -0.001201 2020-01-02 -0.001040 -0.011053 0.008971 2020-01-03 -0.000060 0.000000 0.009331 2020-01-04 0.000000 -0.023366 -0.000078 2020-01-05 -0.002007 -0.012434 0.000000 a b c 2020-01-01 0.000000 -0.001199 -0.001201 2020-01-02 -0.001040 -0.011053 0.008971 2020-01-03 -0.000060 0.000000 0.009331 2020-01-04 0.000000 -0.023366 -0.000078 2020-01-05 -0.002007 -0.012434 0.000000 a b c 2020-01-01 0.000000 -0.000600 -0.001201 2020-01-02 -0.000520 -0.005523 0.008971 2020-01-03 -0.000030 0.000000 0.009331 2020-01-04 0.000000 -0.011611 -0.000078 2020-01-05 -0.001003 -0.006105 0.000000 a b c 2020-01-01 0.000000 -0.000600 -0.001201 2020-01-02 -0.000523 -0.005523 0.008971 2020-01-03 -0.000030 0.000000 0.009331 2020-01-04 0.000000 -0.011618 -0.000078 2020-01-05 -0.001027 -0.006109 0.000000 group first second 2020-01-01 -0.000600 -0.001201 2020-01-02 -0.006044 0.008971 2020-01-03 -0.000030 0.009331 2020-01-04 -0.011618 -0.000078 2020-01-05 -0.007130 0.000000 group first second 2020-01-01 -0.000600 -0.001201 2020-01-02 -0.006044 0.008971 2020-01-03 -0.000030 0.009331 2020-01-04 -0.011618 -0.000078 2020-01-05 -0.007130 0.000000 group first second 2020-01-01 -0.000600 -0.001201 2020-01-02 -0.006044 0.008971 2020-01-03 -0.000030 0.009331 2020-01-04 -0.011618 -0.000078 2020-01-05 -0.007130 0.000000
%timeit big_portfolio.returns() %timeit big_portfolio_grouped.returns(group_by=False) %timeit big_portfolio_shared.returns(group_by=False) %timeit big_portfolio_shared.returns(group_by=False, in_sim_order=True) %timeit big_portfolio.returns(group_by=big_group_by) %timeit big_portfolio_grouped.returns() %timeit big_portfolio_shared.returns()
39.5 ms ± 2.59 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 37.4 ms ± 313 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 39.4 ms ± 226 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 52.3 ms ± 149 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 55.6 ms ± 310 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 50.9 ms ± 276 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 63.5 ms ± 4.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.active_returns()) print(portfolio_grouped.active_returns(group_by=False)) print(portfolio_shared.active_returns(group_by=False)) print(portfolio.active_returns(group_by=group_by)) print(portfolio_grouped.active_returns()) print(portfolio_shared.active_returns())
a b c 2020-01-01 0.00000 -inf -inf 2020-01-02 -inf -1.103980 0.895980 2020-01-03 -0.02985 0.000000 0.427409 2020-01-04 0.00000 -1.049109 -0.026533 2020-01-05 -inf -0.299875 0.000000 a b c 2020-01-01 0.00000 -inf -inf 2020-01-02 -inf -1.103980 0.895980 2020-01-03 -0.02985 0.000000 0.427409 2020-01-04 0.00000 -1.049109 -0.026533 2020-01-05 -inf -0.299875 0.000000 a b c 2020-01-01 0.00000 -inf -inf 2020-01-02 -inf -1.103980 0.895980 2020-01-03 -0.02985 0.000000 0.427409 2020-01-04 0.00000 -1.049109 -0.026533 2020-01-05 -inf -0.299875 0.000000 group first second 2020-01-01 -inf -inf 2020-01-02 -1.208000 0.895980 2020-01-03 -0.002985 0.427409 2020-01-04 -1.049109 -0.026533 2020-01-05 -0.350000 0.000000 group first second 2020-01-01 -inf -inf 2020-01-02 -1.208000 0.895980 2020-01-03 -0.002985 0.427409 2020-01-04 -1.049109 -0.026533 2020-01-05 -0.350000 0.000000 group first second 2020-01-01 -inf -inf 2020-01-02 -1.208000 0.895980 2020-01-03 -0.002985 0.427409 2020-01-04 -1.049109 -0.026533 2020-01-05 -0.350000 0.000000
%timeit big_portfolio.active_returns() %timeit big_portfolio_grouped.active_returns(group_by=False) %timeit big_portfolio_shared.active_returns(group_by=False) %timeit big_portfolio.active_returns(group_by=big_group_by) %timeit big_portfolio_grouped.active_returns() %timeit big_portfolio_shared.active_returns()
40.2 ms ± 5.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 36.9 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 37.4 ms ± 193 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 51.7 ms ± 195 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 49.8 ms ± 220 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 52.4 ms ± 264 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
print(portfolio.market_value()) print(portfolio_grouped.market_value(group_by=False)) print(portfolio_shared.market_value(group_by=False)) print(portfolio.market_value(group_by=group_by)) print(portfolio_grouped.market_value()) print(portfolio_shared.market_value())
a b c 2020-01-01 100.0 100.0 100.0 2020-01-02 100.0 200.0 200.0 2020-01-03 150.0 200.0 300.0 2020-01-04 200.0 400.0 400.0 2020-01-05 250.0 500.0 400.0 a b c 2020-01-01 100.0 100.0 100.0 2020-01-02 100.0 200.0 200.0 2020-01-03 150.0 200.0 300.0 2020-01-04 200.0 400.0 400.0 2020-01-05 250.0 500.0 400.0 a b c 2020-01-01 200.0 200.0 100.0 2020-01-02 200.0 400.0 200.0 2020-01-03 300.0 400.0 300.0 2020-01-04 400.0 800.0 400.0 2020-01-05 500.0 1000.0 400.0 group first second 2020-01-01 200.0 100.0 2020-01-02 300.0 200.0 2020-01-03 350.0 300.0 2020-01-04 600.0 400.0 2020-01-05 750.0 400.0 group first second 2020-01-01 200.0 100.0 2020-01-02 300.0 200.0 2020-01-03 350.0 300.0 2020-01-04 600.0 400.0 2020-01-05 750.0 400.0 group first second 2020-01-01 200.0 100.0 2020-01-02 300.0 200.0 2020-01-03 350.0 300.0 2020-01-04 600.0 400.0 2020-01-05 750.0 400.0
%timeit big_portfolio.market_value() %timeit big_portfolio_grouped.market_value(group_by=False) %timeit big_portfolio_shared.market_value(group_by=False) %timeit big_portfolio.market_value(group_by=big_group_by) %timeit big_portfolio_grouped.market_value() %timeit big_portfolio_shared.market_value()
909 µs ± 51.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 967 µs ± 34.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 1.81 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 4.86 ms ± 415 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 2.82 ms ± 35.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 5.2 ms ± 387 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
print(portfolio.market_returns()) print(portfolio_grouped.market_returns(group_by=False)) print(portfolio_shared.market_returns(group_by=False)) print(portfolio.market_returns(group_by=group_by)) print(portfolio_grouped.market_returns()) print(portfolio_shared.market_returns())
a b c 2020-01-01 0.000000 0.00 0.000000 2020-01-02 0.000000 1.00 1.000000 2020-01-03 0.500000 0.00 0.500000 2020-01-04 0.333333 1.00 0.333333 2020-01-05 0.250000 0.25 0.000000 a b c 2020-01-01 0.000000 0.00 0.000000 2020-01-02 0.000000 1.00 1.000000 2020-01-03 0.500000 0.00 0.500000 2020-01-04 0.333333 1.00 0.333333 2020-01-05 0.250000 0.25 0.000000 a b c 2020-01-01 0.000000 0.00 0.000000 2020-01-02 0.000000 1.00 1.000000 2020-01-03 0.500000 0.00 0.500000 2020-01-04 0.333333 1.00 0.333333 2020-01-05 0.250000 0.25 0.000000 group first second 2020-01-01 0.000000 0.000000 2020-01-02 0.500000 1.000000 2020-01-03 0.166667 0.500000 2020-01-04 0.714286 0.333333 2020-01-05 0.250000 0.000000 group first second 2020-01-01 0.000000 0.000000 2020-01-02 0.500000 1.000000 2020-01-03 0.166667 0.500000 2020-01-04 0.714286 0.333333 2020-01-05 0.250000 0.000000 group first second 2020-01-01 0.000000 0.000000 2020-01-02 0.500000 1.000000 2020-01-03 0.166667 0.500000 2020-01-04 0.714286 0.333333 2020-01-05 0.250000 0.000000
%timeit big_portfolio.market_returns() %timeit big_portfolio_grouped.market_returns(group_by=False) %timeit big_portfolio_shared.market_returns(group_by=False) %timeit big_portfolio.market_returns(group_by=big_group_by) %timeit big_portfolio_grouped.market_returns() %timeit big_portfolio_shared.market_returns()
3.7 ms ± 67.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 3.72 ms ± 66.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 5.11 ms ± 5.82 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 7.2 ms ± 618 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 4.1 ms ± 52.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 7.28 ms ± 40.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio.total_market_return()) print(portfolio_grouped.total_market_return(group_by=False)) print(portfolio_shared.total_market_return(group_by=False)) print(portfolio.total_market_return(group_by=group_by)) print(portfolio_grouped.total_market_return()) print(portfolio_shared.total_market_return())
a 1.5 b 4.0 c 3.0 Name: total_market_return, dtype: float64 a 1.5 b 4.0 c 3.0 Name: total_market_return, dtype: float64 a 1.5 b 4.0 c 3.0 Name: total_market_return, dtype: float64 group first 2.75 second 3.00 Name: total_market_return, dtype: float64 group first 2.75 second 3.00 Name: total_market_return, dtype: float64 group first 2.75 second 3.00 Name: total_market_return, dtype: float64
%timeit big_portfolio.total_market_return() %timeit big_portfolio_grouped.total_market_return(group_by=False) %timeit big_portfolio_shared.total_market_return(group_by=False) %timeit big_portfolio.total_market_return(group_by=big_group_by) %timeit big_portfolio_grouped.total_market_return() %timeit big_portfolio_shared.total_market_return()
975 µs ± 61.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 937 µs ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 1.83 ms ± 7.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 4.77 ms ± 30 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 2.85 ms ± 11.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 5.21 ms ± 79.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
print(portfolio_shared.cumulative_returns()) print(portfolio_shared.cumulative_returns(group_by=False))
group first second 2020-01-01 -0.000599 -0.001201 2020-01-02 -0.006639 0.007759 2020-01-03 -0.006669 0.017162 2020-01-04 -0.018210 0.017082 2020-01-05 -0.025210 0.017082 a b c 2020-01-01 0.000000 -0.000599 -0.001201 2020-01-02 -0.000520 -0.006119 0.007759 2020-01-03 -0.000550 -0.006119 0.017162 2020-01-04 -0.000550 -0.017660 0.017082 2020-01-05 -0.001552 -0.023657 0.017082
print(portfolio_shared.sharpe_ratio()) print(portfolio_shared.sharpe_ratio(risk_free=0.01)) print(portfolio_shared.sharpe_ratio(year_freq='252D')) print(portfolio_shared.sharpe_ratio(group_by=False))
group first -20.095907 second 12.345065 Name: sharpe_ratio, dtype: float64 group first -59.622588 second -23.917188 Name: sharpe_ratio, dtype: float64 group first -16.697884 second 10.257635 Name: sharpe_ratio, dtype: float64 a -13.309506 b -19.278625 c 12.345065 Name: sharpe_ratio, dtype: float64
print(portfolio.stats()) # mean statistics
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Start Value 100.0 End Value 98.88877 Total Return [%] -1.11123 Benchmark Return [%] 283.333333 Max Gross Exposure [%] 2.059062 Total Fees Paid 0.42223 Max Drawdown [%] 1.645124 Max Drawdown Duration 3 days 08:00:00 Total Trades 2.0 Total Closed Trades 1.333333 Total Open Trades 0.666667 Open Trade PnL -1.504206 Win Rate [%] 33.333333 Best Trade [%] -98.380588 Worst Trade [%] -100.803855 Avg Winning Trade [%] 143.916254 Avg Losing Trade [%] -221.34646 Avg Winning Trade Duration 2 days 12:00:00 Avg Losing Trade Duration 2 days 00:00:00 Profit Factor inf Expectancy 0.108273 Sharpe Ratio -6.751008 Calmar Ratio 10378.930331 Omega Ratio 4.7687 Sortino Ratio 31.599761 Name: agg_func_mean, dtype: object
/Users/olegpolakow/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: UserWarning: Object has multiple columns. Aggregating using <function mean at 0x7ff110b83620>. Pass column to select a single column/group. """Entry point for launching an IPython kernel.
print(portfolio['a'].stats())
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Start Value 100.0 End Value 99.68951 Total Return [%] -0.31049 Benchmark Return [%] 150.0 Max Gross Exposure [%] 5.015573 Total Fees Paid 0.35549 Max Drawdown [%] 0.31049 Max Drawdown Duration 4 days 00:00:00 Total Trades 2 Total Closed Trades 1 Total Open Trades 1 Open Trade PnL -0.2005 Win Rate [%] 0.0 Best Trade [%] -54.450495 Worst Trade [%] -54.450495 Avg Winning Trade [%] NaN Avg Losing Trade [%] -54.450495 Avg Winning Trade Duration NaT Avg Losing Trade Duration 1 days 00:00:00 Profit Factor 0.0 Expectancy -0.10999 Sharpe Ratio -13.308045 Calmar Ratio -65.408686 Omega Ratio 0.0 Sortino Ratio -11.738865 Name: a, dtype: object
print(portfolio['a'].stats(settings=dict(required_return=0.1, risk_free=0.01))) # test kwargs
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Start Value 100.0 End Value 99.68951 Total Return [%] -0.31049 Benchmark Return [%] 150.0 Max Gross Exposure [%] 5.015573 Total Fees Paid 0.35549 Max Drawdown [%] 0.31049 Max Drawdown Duration 4 days 00:00:00 Total Trades 2 Total Closed Trades 1 Total Open Trades 1 Open Trade PnL -0.2005 Win Rate [%] 0.0 Best Trade [%] -54.450495 Worst Trade [%] -54.450495 Avg Winning Trade [%] NaN Avg Losing Trade [%] -54.450495 Avg Winning Trade Duration NaT Avg Losing Trade Duration 1 days 00:00:00 Profit Factor 0.0 Expectancy -0.10999 Sharpe Ratio -227.458628 Calmar Ratio -65.408686 Omega Ratio 0.0 Sortino Ratio -19.104372 Name: a, dtype: object
print(portfolio['a'].stats(settings=dict(incl_open=True))) # test incl_open
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Start Value 100.0 End Value 99.68951 Total Return [%] -0.31049 Benchmark Return [%] 150.0 Max Gross Exposure [%] 5.015573 Total Fees Paid 0.35549 Max Drawdown [%] 0.31049 Max Drawdown Duration 4 days 00:00:00 Total Trades 2 Total Closed Trades 1 Total Open Trades 1 Open Trade PnL -0.2005 Win Rate [%] 0.0 Best Trade [%] -3.970297 Worst Trade [%] -54.450495 Avg Winning Trade [%] NaN Avg Losing Trade [%] -29.210396 Avg Winning Trade Duration NaT Avg Losing Trade Duration 1 days 00:00:00 Profit Factor 0.0 Expectancy -0.155245 Sharpe Ratio -13.308045 Calmar Ratio -65.408686 Omega Ratio 0.0 Sortino Ratio -11.738865 Name: a, dtype: object
portfolio_grouped['first'].stats()
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Start Value 200.0 End Value 194.95809 Total Return [%] -2.520955 Benchmark Return [%] 275.0 Max Gross Exposure [%] -0.505305 Total Fees Paid 0.82091 Max Drawdown [%] 2.462481 Max Drawdown Duration 4 days 00:00:00 Total Trades 4 Total Closed Trades 2 Total Open Trades 2 Open Trade PnL -4.512618 Win Rate [%] 0.0 Best Trade [%] -54.450495 Worst Trade [%] -388.242424 Avg Winning Trade [%] NaN Avg Losing Trade [%] -221.34646 Avg Winning Trade Duration NaT Avg Losing Trade Duration 2 days 00:00:00 Profit Factor 0.0 Expectancy -0.264646 Sharpe Ratio -20.095907 Calmar Ratio -34.312217 Omega Ratio 0.0 Sortino Ratio -14.554512 Name: first, dtype: object
pd.testing.assert_series_equal(portfolio['c'].stats(), portfolio.stats(column='c')) pd.testing.assert_series_equal(portfolio['c'].stats(), portfolio_grouped.stats(column='c', group_by=False)) pd.testing.assert_series_equal(portfolio_grouped['second'].stats(), portfolio_grouped.stats(column='second'))
# Calculates stats for one column %timeit big_portfolio.iloc[0].stats() %timeit big_portfolio_grouped.iloc[0].stats(group_by=False, column=0) %timeit big_portfolio_shared.iloc[0].stats(group_by=False, column=0) %timeit big_portfolio.iloc[0].stats(group_by=np.array([0])) %timeit big_portfolio_grouped.iloc[0].stats() %timeit big_portfolio_shared.iloc[0].stats()
64.9 ms ± 525 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 76 ms ± 478 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 145 ms ± 588 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 101 ms ± 87.9 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 72.4 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 158 ms ± 1.02 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
big_portfolio_one = big_portfolio.iloc[0]
for metric in big_portfolio_one.metrics: print(metric) %timeit -n 10 big_portfolio_one.stats(metrics=metric)
start 1.72 ms ± 643 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) end 1.17 ms ± 25.3 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) period 1.18 ms ± 33.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) start_value 1.23 ms ± 51.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) end_value 2.43 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_return 2.38 ms ± 7.53 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) benchmark_return 1.56 ms ± 12.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) max_gross_exposure 5.51 ms ± 22.4 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_fees_paid 2.11 ms ± 132 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) max_dd 5.3 ms ± 22.5 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) max_dd_duration 5.39 ms ± 49.2 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_trades 2.68 ms ± 320 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_closed_trades 4.07 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_open_trades 3.24 ms ± 28.8 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) open_trade_pnl 3.72 ms ± 136 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) win_rate 4.19 ms ± 128 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) best_trade 3.62 ms ± 44.6 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) worst_trade 3.71 ms ± 178 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_winning_trade 4.54 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_losing_trade 4.46 ms ± 122 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_winning_trade_duration 4.5 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_losing_trade_duration 4.99 ms ± 224 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) profit_factor 5.82 ms ± 86.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) expectancy 7.09 ms ± 288 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) sharpe_ratio 8.79 ms ± 613 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) calmar_ratio 8.56 ms ± 527 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) omega_ratio 8.38 ms ± 215 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) sortino_ratio 8.15 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
metrics = [] for metric in big_portfolio_one.metrics: print(metric) metrics.append(metric) %timeit -n 10 big_portfolio_one.stats(metrics=metrics)
start 1.51 ms ± 362 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) end 1.54 ms ± 74 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) period 1.92 ms ± 19.8 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) start_value 2.46 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) end_value 4.1 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_return 5.67 ms ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) benchmark_return 6.59 ms ± 46.7 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) max_gross_exposure 11.4 ms ± 33.9 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_fees_paid 12.8 ms ± 232 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) max_dd 17.6 ms ± 281 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) max_dd_duration 19.1 ms ± 833 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_trades 20.6 ms ± 434 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_closed_trades 22.5 ms ± 234 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) total_open_trades 23.9 ms ± 228 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) open_trade_pnl 25.7 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) win_rate 28 ms ± 246 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) best_trade 30.3 ms ± 710 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) worst_trade 31.9 ms ± 606 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_winning_trade 35.8 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_losing_trade 36.8 ms ± 183 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_winning_trade_duration 39.5 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) avg_losing_trade_duration 41.7 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) profit_factor 45.8 ms ± 240 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) expectancy 50.6 ms ± 425 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) sharpe_ratio 58 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) calmar_ratio 58.5 ms ± 182 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) omega_ratio 59.1 ms ± 227 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) sortino_ratio 60 ms ± 144 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Calculates stats for one column with caching enabled vbt.settings.caching.enabled = True %timeit big_portfolio.iloc[0].stats() %timeit big_portfolio_grouped.iloc[0].stats(group_by=False, column=0) %timeit big_portfolio_shared.iloc[0].stats(group_by=False, column=0) %timeit big_portfolio.iloc[0].stats(group_by=np.array([0])) %timeit big_portfolio_grouped.iloc[0].stats() %timeit big_portfolio_shared.iloc[0].stats() vbt.settings.caching.enabled = False
38 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 47.3 ms ± 852 µs per loop (mean ± std. dev. of 7 runs, 1 loop each) 94.6 ms ± 237 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 68.4 ms ± 511 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 40.1 ms ± 161 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) 90.3 ms ± 1.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Calculates stats for all columns and selects one, takes advantage of caching (which is disabled here) # Thus some series are re-calculated multiple times, such as records and returns %timeit big_portfolio.stats(column=0) %timeit big_portfolio_grouped.stats(group_by=False, column=0) %timeit big_portfolio_shared.stats(group_by=False, column=0) %timeit big_portfolio.stats(group_by=big_group_by, column=0) %timeit big_portfolio_grouped.stats(column=0) %timeit big_portfolio_shared.stats(column=0)
560 ms ± 29.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 554 ms ± 13.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 609 ms ± 4.04 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 676 ms ± 10.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 635 ms ± 12.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 741 ms ± 14.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
print(portfolio.returns_stats()) # mean statistics
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Total Return [%] -1.11123 Benchmark Return [%] 283.333333 Annualized Return [%] 42.313666 Annualized Volatility [%] 9.984895 Max Drawdown [%] 1.645124 Max Drawdown Duration 3 days 08:00:00 Sharpe Ratio -6.751008 Calmar Ratio 10378.930331 Omega Ratio 4.7687 Sortino Ratio 31.599761 Skew -0.399797 Kurtosis -1.202541 Tail Ratio 3.164402 Common Sense Ratio 10.883528 Value at Risk -0.00799 Alpha -0.35365 Beta -0.001234 Name: agg_func_mean, dtype: object
/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/portfolio/base.py:4618: UserWarning: Object has multiple columns. Aggregating using <function mean at 0x7ffd1144a620>. Pass column to select a single column/group. return getattr(returns_acc, 'stats')(settings=settings, **kwargs)
print(portfolio['a'].returns_stats())
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Total Return [%] -0.31049 Benchmark Return [%] 150.0 Annualized Return [%] -20.308743 Annualized Volatility [%] 1.704408 Max Drawdown [%] 0.31049 Max Drawdown Duration 4 days 00:00:00 Sharpe Ratio -13.308045 Calmar Ratio -65.408686 Omega Ratio 0.0 Sortino Ratio -11.738865 Skew -1.219107 Kurtosis 0.122976 Tail Ratio 0.0 Common Sense Ratio 0.0 Value at Risk -0.001814 Alpha -0.248883 Beta 0.000749 Name: a, dtype: object
print(portfolio_grouped['first'].returns_stats())
Start 2020-01-01 00:00:00 End 2020-01-05 00:00:00 Period 5 days 00:00:00 Total Return [%] -2.520955 Benchmark Return [%] 275.0 Annualized Return [%] -84.493192 Annualized Volatility [%] 9.234269 Max Drawdown [%] 2.462481 Max Drawdown Duration 4 days 00:00:00 Sharpe Ratio -20.095907 Calmar Ratio -34.312217 Omega Ratio 0.0 Sortino Ratio -14.554512 Skew -0.254782 Kurtosis -1.363876 Tail Ratio 0.013427 Common Sense Ratio 0.002082 Value at Risk -0.01072 Alpha -0.053947 Beta -0.015121 Name: first, dtype: object
pd.testing.assert_series_equal( portfolio['c'].returns_stats(), portfolio.returns_stats(column='c')) pd.testing.assert_series_equal( portfolio['c'].returns_stats(), portfolio_grouped.returns_stats(column='c', group_by=False)) pd.testing.assert_series_equal( portfolio_grouped['second'].returns_stats(), portfolio_grouped.returns_stats(column='second'))
portfolio['a'].plot().show_svg()
Image in a Jupyter notebook
portfolio_shared['first'].plot().show_svg()
/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'orders' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'trade_pnl' does not support grouped data
Image in a Jupyter notebook
portfolio['a'].plot(subplots='all').show_svg()
Image in a Jupyter notebook
portfolio_shared['first'].plot(subplots='all').show_svg()
/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'orders' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'trades' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'trade_pnl' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'asset_flow' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'assets' does not support grouped data
Image in a Jupyter notebook
portfolio_shared.plot(subplots='all', column='first').show_svg()
/Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'orders' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'trades' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'trade_pnl' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'asset_flow' does not support grouped data /Users/olegpolakow/Documents/SourceTree/vectorbt/vectorbt/generic/plots_builder.py:340: UserWarning: Subplot 'assets' does not support grouped data
Image in a Jupyter notebook
portfolio_shared.plot(subplots='all', column='a', group_by=False).show_svg()
Image in a Jupyter notebook
from vectorbt.utils.colors import adjust_opacity portfolio['a'].plot( subplots=['drawdowns', 'underwater'], subplot_settings=dict( drawdowns=dict(top_n=3), underwater=dict( trace_kwargs=dict( line_color='#FF6F00', fillcolor=adjust_opacity('#FF6F00', 0.3) ) ) ) ).show_svg()
Image in a Jupyter notebook
from vectorbt import settings color_schema = settings['plotting']['color_schema'] fig = portfolio['a'].plot(subplots=[ 'orders', ('order_size', dict(title='Order Size', check_is_not_grouped=True)) # placeholder ]) order_size.vbt.plot(trace_kwargs=dict(name='Order Size'), add_trace_kwargs=dict(row=2, col=1), fig=fig).show_svg()
Image in a Jupyter notebook