# ################################## HOW TO USE #################################### # # # # This is a Jupyter notebook formatted as a script # # Format: https://jupytext.readthedocs.io/en/latest/formats.html#the-percent-format # # # # Save this file and remove the '.txt' extension # # In Jupyter Lab, right click on the Python file -> Open With -> Jupytext Notebook # # Make sure to have Jupytext installed: https://github.com/mwouts/jupytext # # # # ################################################################################## # # %% [markdown] # # From orders # ## Numba # ### Order fields # %% from vectorbtpro import * sim_out = vbt.pf_nb.from_orders_nb( target_shape=(3, 1), group_lens=np.array([1]), size=np.array([[0.1], [-0.1], [np.nan]]), price=np.array([[11], [10], [12]]) ) sim_out.order_records # %% print(vbt.prettify(sim_out)) # %% def print_orders(target_shape, order_records): wrapper = vbt.ArrayWrapper.from_shape(target_shape) print(vbt.Orders(wrapper, order_records).readable) print_orders((3, 1), sim_out.order_records) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(3, 1), group_lens=np.array([1]), size=np.array([0.1, -0.1, np.nan]), price=np.array([11, 10, 12]), fees=0.01 ) print_orders((3, 1), sim_out.order_records) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(3, 3), group_lens=np.array([1, 1, 1]), size=np.array([[np.inf, np.nan, -np.inf]]), price=np.array([11, 10, 12]), fees=0.01 ) print_orders((3, 3), sim_out.order_records) # %% size, price, fees = vbt.broadcast_arrays( np.array([[np.inf, np.nan, -np.inf]]), np.array([11, 10, 12]), 0.01 ) size # %% price # %% fees # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=size.shape, group_lens=np.full(size.shape[1], 1), size=size, price=price, fees=fees ) print_orders(size.shape, sim_out.order_records) # %% [markdown] # ### Grouping # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(1, 2), group_lens=np.array([2]), size=np.array([[np.inf, np.inf]]), price=np.array([[10, 5]]) ) print_orders((1, 2), sim_out.order_records) # %% [markdown] # ### Call sequence # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(2, 2), group_lens=np.array([2]), size=np.array([[0, 1], [1, 0]]), size_type=vbt.pf_enums.SizeType.TargetPercent, price=np.array([[10, 5], [11, 4]]) ) print_orders((2, 2), sim_out.order_records) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(2, 2), group_lens=np.array([2]), size=np.array([[0, 1], [1, 0]]), size_type=vbt.pf_enums.SizeType.TargetPercent, price=np.array([[10, 5], [11, 4]]), call_seq=np.array([[0, 1], [1, 0]]) ) print_orders((2, 2), sim_out.order_records) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(2, 2), group_lens=np.array([2]), size=np.array([[0, 1], [1, 0]]), size_type=vbt.pf_enums.SizeType.TargetPercent, price=np.array([[10, 5], [11, 4]]), auto_call_seq=True ) print_orders((2, 2), sim_out.order_records) # %% from vectorbtpro.portfolio.call_seq import build_call_seq call_seq = build_call_seq( target_shape=(2, 2), group_lens=np.array([2]), call_seq_type=vbt.pf_enums.CallSeqType.Default ) sim_out = vbt.pf_nb.from_orders_nb( target_shape=(2, 2), group_lens=np.array([2]), size=np.array([[0, 1], [1, 0]]), size_type=vbt.pf_enums.SizeType.TargetPercent, price=np.array([[10, 5], [11, 4]]), call_seq=call_seq, auto_call_seq=True ) sim_out.call_seq # %% [markdown] # ### Filling returns # %% data = vbt.YFData.pull("BTC-USD", end="2022-01-01") symbol_wrapper = data.get_symbol_wrapper() sim_out = vbt.pf_nb.from_orders_nb( target_shape=symbol_wrapper.shape_2d, group_lens=np.array([1]), open=data.get("Open").values, high=data.get("High").values, low=data.get("Low").values, close=data.get("Close").values, save_returns=True ) returns = symbol_wrapper.wrap(sim_out.in_outputs.returns) returns # %% data.get("Close").vbt.to_returns() # %% mult_data = vbt.YFData.pull( ["BTC-USD", "ETH-USD"], end="2022-01-01", missing_index="drop" ) mult_symbol_wrapper = mult_data.get_symbol_wrapper() sim_out = vbt.pf_nb.from_orders_nb( target_shape=mult_symbol_wrapper.shape_2d, group_lens=np.array([2]), close=mult_data.get("Close").values, size=np.array([[0.5, 0.5]]), size_type=vbt.pf_enums.SizeType.TargetPercent, save_returns=True ) returns = mult_symbol_wrapper\ .replace(columns=["group"], ndim=1)\ .wrap(sim_out.in_outputs.returns) returns # %% [markdown] # ### Initial state # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(1, 4), group_lens=np.array([2, 1, 1]), init_cash=100, size=np.array([[0.5, 0.5, 1.0, 1.0]]), size_type=vbt.pf_enums.SizeType.TargetPercent, price=np.array([[10, 11, 10, 11]]), ) print_orders((1, 4), sim_out.order_records) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=(1, 4), group_lens=np.array([2, 1, 1]), init_cash=np.array([200, 100, 100]), size=np.array([[0.5, 0.5, 1.0, 1.0]]), size_type=vbt.pf_enums.SizeType.TargetPercent, price=np.array([[10, 11, 10, 11]]), ) print_orders((1, 4), sim_out.order_records) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=mult_symbol_wrapper.shape_2d, group_lens=np.array([1, 1]), init_position=np.array([1, 1]), close=mult_data.get("Close").values, save_returns=True ) returns = mult_symbol_wrapper.wrap(sim_out.in_outputs.returns) returns # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=mult_symbol_wrapper.shape_2d, group_lens=np.array([1, 1]), init_position=np.array([1, 1]), init_price=mult_data.get("Open").values[0], close=mult_data.get("Close").values, save_returns=True ) returns = mult_symbol_wrapper.wrap(sim_out.in_outputs.returns) returns # %% [markdown] # ### Cash deposits # %% cash_deposits = symbol_wrapper.fill(0) cash_deposits.vbt.set(100, every="Y", inplace=True) sim_out = vbt.pf_nb.from_orders_nb( target_shape=symbol_wrapper.shape_2d, group_lens=np.array([1]), cash_deposits=cash_deposits.values, close=data.get("Close").values ) print_orders(symbol_wrapper.shape_2d, sim_out.order_records) # %% cash_deposits = mult_symbol_wrapper\ .replace(columns=["group"], ndim=1)\ .fill(0) cash_deposits.vbt.set(100, every="Y", inplace=True) size = mult_symbol_wrapper.fill(np.nan) size.vbt.set(0.5, every="Y", inplace=True) size.iloc[0] = 0.5 sim_out = vbt.pf_nb.from_orders_nb( target_shape=mult_symbol_wrapper.shape_2d, group_lens=np.array([2]), cash_deposits=cash_deposits.values, close=mult_data.get("Close").values, size=size.values, size_type=vbt.pf_enums.SizeType.TargetPercent ) print_orders(mult_symbol_wrapper.shape_2d, sim_out.order_records) # %% size = symbol_wrapper.fill(np.nan) size.vbt.set(-0.1, every="Y", inplace=True) sim_out = vbt.pf_nb.from_orders_nb( target_shape=symbol_wrapper.shape_2d, group_lens=np.array([1]), init_position=1, cash_deposits=-np.inf, close=data.get("Close").values, size=size.values, size_type=vbt.pf_enums.SizeType.Percent, direction=vbt.pf_enums.Direction.LongOnly ) print_orders(symbol_wrapper.shape_2d, sim_out.order_records) # %% cash_deposits = symbol_wrapper.wrap(sim_out.cash_deposits) print(cash_deposits[cash_deposits != 0]) # %% [markdown] # ### Cash earnings # %% aapl_data = vbt.YFData.pull("AAPL", end="2022-01-01") aapl_wrapper = aapl_data.get_symbol_wrapper() size = aapl_wrapper.fill() size.iloc[0] = np.inf sim_out = vbt.pf_nb.from_orders_nb( target_shape=aapl_wrapper.shape_2d, group_lens=np.array([1]), close=aapl_data.get("Close").values, cash_dividends=aapl_data.get("Dividends").values, size=size.values ) print_orders(aapl_wrapper.shape_2d, sim_out.order_records) # %% cash_earnings = aapl_wrapper.wrap(sim_out.cash_earnings) print(cash_earnings[cash_earnings != 0]) # %% [markdown] # ### Max record count # %% target_shape = (1000000, 1) np.random.seed(42) rand_price = np.random.randint(8, 12, size=target_shape) size = np.full(target_shape, np.nan) size[0] = np.inf size[-1] = -np.inf sim_out = vbt.pf_nb.from_orders_nb( target_shape=target_shape, group_lens=np.array([1]), price=rand_price, size=size, max_order_records=2 ) print_orders(target_shape, sim_out.order_records) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=target_shape, group_lens=np.array([1]), price=rand_price, size=size, max_order_records=1 ) # %% sim_out = vbt.pf_nb.from_orders_nb( target_shape=target_shape, group_lens=np.array([1]), price=rand_price, size=size, max_order_records=0 ) print_orders(target_shape, sim_out.order_records) # %% [markdown] # ### Jitting # %% f_py = vbt.jit_reg.resolve_option( task_id=vbt.pf_nb.from_orders_nb, option=False ) # %% f_no_cache = vbt.jit_reg.resolve_option( task_id=vbt.pf_nb.from_orders_nb, option=dict(cache=False) ) # %% f_parallel = vbt.jit_reg.resolve_option( task_id=vbt.pf_nb.from_orders_nb, option=dict(parallel=True) ) # %% [markdown] # ### Chunking # %% f_chunked = vbt.ch_reg.resolve_option( setup_id_or_func=vbt.pf_nb.from_orders_nb, option=True ) print(vbt.prettify(f_chunked.options)) # %% sim_out = f_chunked( target_shape=mult_symbol_wrapper.shape_2d, group_lens=np.array([1, 1]), close=mult_data.get("Close").values, _n_chunks=2, _execute_kwargs=dict(engine="dask") ) print_orders(mult_symbol_wrapper.shape_2d, sim_out.order_records) # %% [markdown] # ## Class method # %% pf = vbt.Portfolio.from_orders( close=[11, 10, 12], size=[0.1, -0.1, np.nan] ) pf.orders.readable # %% pf = vbt.Portfolio.from_orders(10, 1) pf.orders.readable # %% [markdown] # ### Close price # ### Defaults # %% vbt.phelp(vbt.Portfolio.from_orders, incl_doc=False) # %% vbt.settings.portfolio["price"] # %% vbt.settings.portfolio["fixed_fees"] = 1 pf = vbt.Portfolio.from_orders( close=pd.Series([11, 10, 12]), size=pd.Series([0.1, -0.1, np.nan]) ) pf.orders.readable # %% vbt.settings.portfolio.reset() vbt.settings.portfolio["fixed_fees"] # %% [markdown] # ### Enums # %% print(vbt.prettify(vbt.pf_enums.SizeType)) # %% vbt.map_enum_fields("targetamount", vbt.pf_enums.SizeType) # %% vbt.map_enum_fields([ "amount", "targetamount", "targetpercent" ], vbt.pf_enums.SizeType) # %% vbt.map_enum_fields(3, vbt.pf_enums.SizeType) # %% vbt.map_enum_fields("Target Amount", vbt.pf_enums.SizeType) # %% pf = vbt.Portfolio.from_orders( close=pd.Series([10, 11]), size=pd.Series([1, -0.5]), size_type=pd.Series(["amount", "percent"]), direction="longonly" ) pf.orders.readable # %% [markdown] # ### Broadcasting # %% close = pd.Series( [11, 10, 12], index=vbt.date_range("2020-01-01", periods=3) ) size = pd.DataFrame( [[-np.inf, np.nan, np.inf]], columns=pd.Index(["short", "nan", "long"], name="size") ) fees = 0.01 broadcasted = vbt.broadcast(dict( close=close, size=size, fees=0.01 )) broadcasted["close"] # %% broadcasted["size"] # %% broadcasted["fees"] # %% broadcasted, wrapper = vbt.broadcast(dict( close=close, size=size, fees=0.01 ), keep_flex=True, return_wrapper=True) broadcasted["close"] # %% broadcasted["size"] # %% broadcasted["fees"] # %% wrapper.fill() # %% init_position = 1 new_init_position = vbt.broadcast_array_to(init_position, wrapper.shape_2d[1]) new_init_position # %% pf = vbt.Portfolio.from_orders( close=close, size=size, fees=fees, init_position=init_position ) pf.orders.readable # %% pf.value # %% pf = vbt.Portfolio.from_orders( close=close, size=size, fees=fees, init_position=init_position, broadcast_kwargs=dict(columns_from=["a", "b", "c"]) ) pf.value # %% pf = vbt.Portfolio.from_orders( close=close, size=vbt.Param([-np.inf, np.inf]), fees=vbt.Param([0, 0.01]), init_position=init_position ) pf.value # %% mult_close = mult_data.get("Close") mult_close # %% mult_price = pd.concat(( mult_data.get("Open"), mult_data.get("Close") ), axis=1, keys=pd.Index(["open", "close"], name="price")) mult_price # %% pf = vbt.Portfolio.from_orders(close=mult_close, price=mult_price) pf.value # %% print(vbt.prettify(f_chunked.options["arg_take_spec"]["close"])) # %% print(vbt.prettify(f_chunked.options["arg_take_spec"]["cash_deposits"])) # %% [markdown] # ### Grouping # %% pf = vbt.Portfolio.from_orders( close=mult_data.get("Close") ) pf.value # %% pf = vbt.Portfolio.from_orders( close=mult_data.get("Close"), group_by=True ) pf.value # %% pf = vbt.Portfolio.from_orders( close=mult_data.get("Close"), group_by=True, cash_sharing=True ) pf.value # %% pf = vbt.Portfolio.from_orders( close=mult_close, price=mult_price, group_by=pd.Index(["group1", "group1", "group2", "group2"]) ) pf.value # %% pf = vbt.Portfolio.from_orders( close=mult_close, price=mult_price, group_by=["price"] ) pf.value # %% pf = vbt.Portfolio.from_orders( close=mult_close, price=mult_price, group_by=vbt.ExceptLevel("symbol") ) pf.value # %% [markdown] # ### Call sequence # %% size = mult_symbol_wrapper.fill(np.nan) size.vbt.set(0.5, every="M", inplace=True) size.iloc[0] = 0.5 pf = vbt.Portfolio.from_orders( close=mult_data.get("Close"), size=size, size_type="targetpercent", group_by=vbt.ExceptLevel("symbol"), cash_sharing=True, call_seq="auto" ) allocations = pf.get_asset_value(group_by=False).vbt / pf.value allocations.vbt.plot( trace_kwargs=dict(stackgroup="one"), use_gl=False ).show() # %% pf = vbt.Portfolio.from_orders( close=mult_data.get("Close"), size=size, size_type="targetpercent", group_by=vbt.ExceptLevel("symbol"), cash_sharing=True, call_seq="auto", attach_call_seq=True ) pf.call_seq # %% [markdown] # ### Unlimited cash # %% size = mult_symbol_wrapper.fill(np.nan) size.vbt.set(1, every="Y", inplace=True) size.iloc[0] = 1 pf = vbt.Portfolio.from_orders( close=mult_data.get("Close"), size=size, init_cash="auto" ) pf.init_cash # %% pf2 = vbt.Portfolio.from_orders( close=mult_data.get("Close"), size=size, init_cash=pf.init_cash ) pf2.cash.loc[~size.isnull().all(axis=1)] # %% pf2.orders.readable # %% [markdown] # ### Output arrays # %% size = symbol_wrapper.fill(np.nan) size.vbt.set(-0.1, every="Y", inplace=True) pf = vbt.Portfolio.from_orders( close=data.get("Close"), size=size, size_type="percent", direction="longonly", init_position=1, cash_deposits=-np.inf ) pf.cash_deposits[pf.cash_deposits != 0] # %% [markdown] # ### Max record count # ### Data type checks # %% vbt.Portfolio.from_orders(True) # %% [markdown] # ### Jitting # %% big_target_shape = (1000, 1000) big_rand_price = np.random.randint(8, 12, size=big_target_shape) big_size = np.full(big_target_shape, 1) big_size[1::2] = -1 # %% %%timeit vbt.Portfolio.from_orders( close=big_rand_price, size=big_size ) # %% %%timeit vbt.Portfolio.from_orders( close=big_rand_price, size=big_size, jitted=dict(parallel=True) ) # %% [markdown] # ### Chunking # %% %%timeit vbt.Portfolio.from_orders( close=big_rand_price, size=big_size, chunked=dict(engine="dask", n_chunks=4) ) # %% [markdown] # ### Use cases # %% trade1 = dict( timestamp="2022-01-22 12:39:26", price=0.0027702, size=4.99, fixed_fees=1.01571e-05 ) trade2 = dict( timestamp="2022-01-29 02:12:50", price=0.00243, size=-1.72, fixed_fees=3.0549e-06 ) trade3 = dict( timestamp="2022-01-29 02:52:54", price=0.0024299, size=-3.27, fixed_fees=5.8102e-06 ) trades = pd.DataFrame([trade1, trade2, trade3]) trades["timestamp"] = pd.to_datetime(trades["timestamp"], utc=True) trades.set_index("timestamp", inplace=True) trades # %% solbtc_data = vbt.BinanceData.pull( "SOLBTC", start=trades.index[0] - pd.Timedelta(days=1), end=trades.index[-1] + pd.Timedelta(days=1), timeframe="1h" ) resampler = vbt.Resampler( source_index=trades.index, target_index=solbtc_data.wrapper.index, source_freq=None, target_freq="1h" ) # (6)! @njit def avg_price_reduce_meta_nb(from_i, to_i, col, size, price): _size = size[from_i:to_i, col] _price = price[from_i:to_i, col] return np.sum(_price * _size) / np.sum(_size) price = pd.Series.vbt.resample_to_index( resampler, avg_price_reduce_meta_nb, vbt.to_2d_array(trades["size"]), vbt.to_2d_array(trades["price"]), wrapper=trades["price"].vbt.wrapper, ) price.loc[~price.isnull()] # %% size = trades["size"].vbt.resample_to_index( resampler, vbt.nb.sum_reduce_nb ) size.loc[~size.isnull()] # %% fixed_fees = trades["fixed_fees"].vbt.resample_to_index( resampler, vbt.nb.sum_reduce_nb ) fixed_fees.loc[~fixed_fees.isnull()] # %% pf = vbt.Portfolio.from_orders( open=solbtc_data.get("Open"), high=solbtc_data.get("High"), low=solbtc_data.get("Low"), close=solbtc_data.get("Close"), price=price, size=size, fixed_fees=fixed_fees, init_cash=0.1, ffill_val_price=False, skipna=True ) pf.orders.readable # %% pf.plot().show() # %%