Skip to content

base module

Base class for simulating a portfolio and measuring its performance.


returns_acc_config ReadonlyConfig

Config of returns accessor methods to be attached to Portfolio.

ReadonlyConfig(
    daily_returns=dict(
        source_name='daily'
    ),
    annual_returns=dict(
        source_name='annual'
    ),
    cumulative_returns=dict(
        source_name='cumulative'
    ),
    annualized_return=dict(
        source_name='annualized'
    ),
    annualized_volatility=dict(),
    calmar_ratio=dict(),
    omega_ratio=dict(),
    sharpe_ratio=dict(),
    sharpe_ratio_std=dict(),
    prob_sharpe_ratio=dict(),
    deflated_sharpe_ratio=dict(),
    downside_risk=dict(),
    sortino_ratio=dict(),
    information_ratio=dict(),
    beta=dict(),
    alpha=dict(),
    tail_ratio=dict(),
    value_at_risk=dict(),
    cond_value_at_risk=dict(),
    capture_ratio=dict(),
    up_capture_ratio=dict(),
    down_capture_ratio=dict(),
    drawdown=dict(),
    max_drawdown=dict()
)

shortcut_config ReadonlyConfig

Config of shortcut properties to be attached to Portfolio.

ReadonlyConfig(
    filled_close=dict(
        group_by_aware=False,
        decorator=<class 'vectorbtpro.utils.decorators.cached_property'>
    ),
    filled_bm_close=dict(
        group_by_aware=False,
        decorator=<class 'vectorbtpro.utils.decorators.cached_property'>
    ),
    weights=dict(
        group_by_aware=False,
        decorator=<class 'vectorbtpro.utils.decorators.cached_property'>,
        obj_type='red_array'
    ),
    long_view=dict(
        obj_type='portfolio'
    ),
    short_view=dict(
        obj_type='portfolio'
    ),
    orders=dict(
        obj_type='records',
        field_aliases=(
            'order_records'
        ),
        wrap_func=<function <lambda> at 0x1648a4fe0>,
        indexing_func=functools.partial(<function records_indexing_func at 0x164888b80>, cls='orders_cls'),
        resample_func=functools.partial(<function records_resample_func at 0x164888c20>, cls='orders_cls')
    ),
    logs=dict(
        obj_type='records',
        field_aliases=(
            'log_records'
        ),
        wrap_func=<function <lambda> at 0x1648a5080>,
        indexing_func=functools.partial(<function records_indexing_func at 0x164888b80>, cls='logs_cls'),
        resample_func=functools.partial(<function records_resample_func at 0x164888c20>, cls='logs_cls')
    ),
    entry_trades=dict(
        obj_type='records',
        field_aliases=(
            'entry_trade_records'
        ),
        wrap_func=<function <lambda> at 0x1648a5120>,
        indexing_func=functools.partial(<function records_indexing_func at 0x164888b80>, cls='entry_trades_cls'),
        resample_func=functools.partial(<function records_resample_func at 0x164888c20>, cls='entry_trades_cls')
    ),
    exit_trades=dict(
        obj_type='records',
        field_aliases=(
            'exit_trade_records'
        ),
        wrap_func=<function <lambda> at 0x1648a51c0>,
        indexing_func=functools.partial(<function records_indexing_func at 0x164888b80>, cls='exit_trades_cls'),
        resample_func=functools.partial(<function records_resample_func at 0x164888c20>, cls='exit_trades_cls')
    ),
    trades=dict(
        obj_type='records',
        field_aliases=(
            'trade_records'
        ),
        wrap_func=<function <lambda> at 0x1648a5260>,
        indexing_func=functools.partial(<function records_indexing_func at 0x164888b80>, cls='trades_cls'),
        resample_func=functools.partial(<function records_resample_func at 0x164888c20>, cls='trades_cls')
    ),
    trade_history=dict(),
    positions=dict(
        obj_type='records',
        field_aliases=(
            'position_records'
        ),
        wrap_func=<function <lambda> at 0x1648a5300>,
        indexing_func=functools.partial(<function records_indexing_func at 0x164888b80>, cls='positions_cls'),
        resample_func=functools.partial(<function records_resample_func at 0x164888c20>, cls='positions_cls')
    ),
    drawdowns=dict(
        obj_type='records',
        field_aliases=(
            'drawdown_records'
        ),
        wrap_func=<function <lambda> at 0x1648a53a0>,
        indexing_func=functools.partial(<function records_indexing_func at 0x164888b80>, cls='drawdowns_cls', groups_only=True),
        resample_func=functools.partial(<function records_resample_func at 0x164888c20>, cls='drawdowns_cls')
    ),
    init_position=dict(
        obj_type='red_array',
        group_by_aware=False
    ),
    asset_flow=dict(
        group_by_aware=False,
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    long_asset_flow=dict(
        method_name='get_asset_flow',
        group_by_aware=False,
        method_kwargs=dict(
            direction='longonly'
        ),
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    short_asset_flow=dict(
        method_name='get_asset_flow',
        group_by_aware=False,
        method_kwargs=dict(
            direction='shortonly'
        ),
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    assets=dict(
        group_by_aware=False
    ),
    long_assets=dict(
        method_name='get_assets',
        group_by_aware=False,
        method_kwargs=dict(
            direction='longonly'
        )
    ),
    short_assets=dict(
        method_name='get_assets',
        group_by_aware=False,
        method_kwargs=dict(
            direction='shortonly'
        )
    ),
    position_mask=dict(),
    long_position_mask=dict(
        method_name='get_position_mask',
        method_kwargs=dict(
            direction='longonly'
        )
    ),
    short_position_mask=dict(
        method_name='get_position_mask',
        method_kwargs=dict(
            direction='shortonly'
        )
    ),
    position_coverage=dict(
        obj_type='red_array'
    ),
    long_position_coverage=dict(
        method_name='get_position_coverage',
        obj_type='red_array',
        method_kwargs=dict(
            direction='longonly'
        )
    ),
    short_position_coverage=dict(
        method_name='get_position_coverage',
        obj_type='red_array',
        method_kwargs=dict(
            direction='shortonly'
        )
    ),
    position_entry_price=dict(
        group_by_aware=False
    ),
    position_exit_price=dict(
        group_by_aware=False
    ),
    init_cash=dict(
        obj_type='red_array'
    ),
    cash_deposits=dict(
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    total_cash_deposits=dict(
        obj_type='red_array'
    ),
    cash_earnings=dict(
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    total_cash_earnings=dict(
        obj_type='red_array'
    ),
    cash_flow=dict(
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    free_cash_flow=dict(
        method_name='get_cash_flow',
        method_kwargs=dict(
            free=True
        ),
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    cash=dict(),
    position=dict(
        method_name='get_assets',
        group_by_aware=False
    ),
    debt=dict(
        method_name=None,
        group_by_aware=False
    ),
    locked_cash=dict(
        method_name=None,
        group_by_aware=False
    ),
    free_cash=dict(
        method_name='get_cash',
        method_kwargs=dict(
            free=True
        )
    ),
    init_price=dict(
        obj_type='red_array',
        group_by_aware=False
    ),
    init_position_value=dict(
        obj_type='red_array'
    ),
    init_value=dict(
        obj_type='red_array'
    ),
    input_value=dict(
        obj_type='red_array'
    ),
    asset_value=dict(),
    long_asset_value=dict(
        method_name='get_asset_value',
        method_kwargs=dict(
            direction='longonly'
        )
    ),
    short_asset_value=dict(
        method_name='get_asset_value',
        method_kwargs=dict(
            direction='shortonly'
        )
    ),
    gross_exposure=dict(),
    long_gross_exposure=dict(
        method_name='get_gross_exposure',
        method_kwargs=dict(
            direction='longonly'
        )
    ),
    short_gross_exposure=dict(
        method_name='get_gross_exposure',
        method_kwargs=dict(
            direction='shortonly'
        )
    ),
    net_exposure=dict(),
    value=dict(),
    allocations=dict(
        group_by_aware=False
    ),
    long_allocations=dict(
        method_name='get_allocations',
        method_kwargs=dict(
            direction='longonly'
        ),
        group_by_aware=False
    ),
    short_allocations=dict(
        method_name='get_allocations',
        method_kwargs=dict(
            direction='shortonly'
        ),
        group_by_aware=False
    ),
    total_profit=dict(
        obj_type='red_array'
    ),
    final_value=dict(
        obj_type='red_array'
    ),
    total_return=dict(
        obj_type='red_array'
    ),
    returns=dict(
        resample_func=<function returns_resample_func at 0x1648a4b80>
    ),
    log_returns=dict(
        method_name='get_returns',
        method_kwargs=dict(
            log_returns=True
        ),
        resample_func=functools.partial(<function returns_resample_func at 0x1648a4b80>, log_returns=True)
    ),
    daily_log_returns=dict(
        method_name='get_returns',
        method_kwargs=dict(
            daily_returns=True,
            log_returns=True
        ),
        resample_func=functools.partial(<function returns_resample_func at 0x1648a4b80>, log_returns=True)
    ),
    asset_pnl=dict(
        resample_func='sum',
        resample_kwargs=dict(
            wrap_kwargs=dict(
                fillna=0.0
            )
        )
    ),
    asset_returns=dict(
        resample_func=<function returns_resample_func at 0x1648a4b80>
    ),
    market_value=dict(),
    market_returns=dict(
        resample_func=<function returns_resample_func at 0x1648a4b80>
    ),
    bm_value=dict(),
    bm_returns=dict(
        resample_func=<function returns_resample_func at 0x1648a4b80>
    ),
    total_market_return=dict(
        obj_type='red_array'
    ),
    daily_returns=dict(
        resample_func=<function returns_resample_func at 0x1648a4b80>
    ),
    annual_returns=dict(
        resample_func=<function returns_resample_func at 0x1648a4b80>
    ),
    cumulative_returns=dict(),
    annualized_return=dict(
        obj_type='red_array'
    ),
    annualized_volatility=dict(
        obj_type='red_array'
    ),
    calmar_ratio=dict(
        obj_type='red_array'
    ),
    omega_ratio=dict(
        obj_type='red_array'
    ),
    sharpe_ratio=dict(
        obj_type='red_array'
    ),
    sharpe_ratio_std=dict(
        obj_type='red_array'
    ),
    prob_sharpe_ratio=dict(
        obj_type='red_array'
    ),
    deflated_sharpe_ratio=dict(
        obj_type='red_array'
    ),
    downside_risk=dict(
        obj_type='red_array'
    ),
    sortino_ratio=dict(
        obj_type='red_array'
    ),
    information_ratio=dict(
        obj_type='red_array'
    ),
    beta=dict(
        obj_type='red_array'
    ),
    alpha=dict(
        obj_type='red_array'
    ),
    tail_ratio=dict(
        obj_type='red_array'
    ),
    value_at_risk=dict(
        obj_type='red_array'
    ),
    cond_value_at_risk=dict(
        obj_type='red_array'
    ),
    capture_ratio=dict(
        obj_type='red_array'
    ),
    up_capture_ratio=dict(
        obj_type='red_array'
    ),
    down_capture_ratio=dict(
        obj_type='red_array'
    ),
    drawdown=dict(),
    max_drawdown=dict(
        obj_type='red_array'
    )
)

fix_wrapper_for_records function

fix_wrapper_for_records(
    pf
)

Allow flags for records that were restricted for portfolio.


records_indexing_func function

records_indexing_func(
    obj,
    wrapper_meta,
    cls,
    groups_only=False,
    **kwargs
)

Apply indexing function on records.


records_resample_func function

records_resample_func(
    obj,
    resampler,
    wrapper,
    cls,
    **kwargs
)

Apply resampling function on records.


returns_resample_func function

returns_resample_func(
    obj,
    resampler,
    wrapper,
    fill_with_zero=True,
    log_returns=False,
    **kwargs
)

Apply resampling function on returns.


MetaInOutputs class

MetaInOutputs(
    *args,
    **kwargs
)

Meta class that exposes a read-only class property MetaFields.in_output_config.

Superclasses

  • builtins.type

Subclasses


in_output_config property

In-output config.


MetaPortfolio class

MetaPortfolio(
    *args,
    **kwargs
)

Meta class that exposes a read-only class property StatsBuilderMixin.metrics.

Superclasses

Inherited members


Portfolio class

Portfolio(
    wrapper,
    order_records,
    *,
    close,
    open=None,
    high=None,
    low=None,
    log_records=None,
    cash_sharing=False,
    init_cash='auto',
    init_position=0.0,
    init_price=nan,
    cash_deposits=0.0,
    cash_deposits_as_input=None,
    cash_earnings=0.0,
    sim_start=None,
    sim_end=None,
    call_seq=None,
    in_outputs=None,
    use_in_outputs=None,
    bm_close=None,
    fillna_close=None,
    year_freq=None,
    returns_acc_defaults=None,
    trades_type=None,
    orders_cls=None,
    logs_cls=None,
    trades_cls=None,
    entry_trades_cls=None,
    exit_trades_cls=None,
    positions_cls=None,
    drawdowns_cls=None,
    weights=None,
    **kwargs
)

Class for simulating a portfolio and measuring its performance.

Args

wrapper : ArrayWrapper

Array wrapper.

See ArrayWrapper.

close : array_like
Last asset price at each time step.
order_records : array_like
A structured NumPy array of order records.
open : array_like
Open price of each bar.
high : array_like
High price of each bar.
low : array_like
Low price of each bar.
log_records : array_like
A structured NumPy array of log records.
cash_sharing : bool
Whether to share cash within the same group.
init_cash : InitCashMode or array_like of float

Initial capital.

Can be provided in a format suitable for flexible indexing.

init_position : array_like of float

Initial position.

Can be provided in a format suitable for flexible indexing.

init_price : array_like of float

Initial position price.

Can be provided in a format suitable for flexible indexing.

cash_deposits : array_like of float

Cash deposited/withdrawn at each timestamp.

Can be provided in a format suitable for flexible indexing.

cash_earnings : array_like of float

Earnings added at each timestamp.

Can be provided in a format suitable for flexible indexing.

sim_start : int, datetime_like, or array_like
Simulation start per column. Defaults to None.
sim_end : int, datetime_like, or array_like
Simulation end per column. Defaults to None.
call_seq : array_like of int
Sequence of calls per row and group. Defaults to None.
in_outputs : namedtuple

Named tuple with in-output objects.

To substitute Portfolio attributes, provide already broadcasted and grouped objects. Also see Portfolio.in_outputs_indexing_func() on how in-output objects are indexed.

use_in_outputs : bool
Whether to return in-output objects when calling properties.
bm_close : array_like
Last benchmark asset price at each time step.
fillna_close : bool

Whether to forward and backward fill NaN values in close.

Applied after the simulation to avoid NaNs in asset value.

See Portfolio.get_filled_close().

weights : array_like

Asset weights.

Applied to the initial position, initial cash, cash deposits, cash earnings, and orders.

trades_type : str or int

Default Trades to use across Portfolio.

See TradesType.

orders_cls : type
Class for wrapping order records.
logs_cls : type
Class for wrapping log records.
trades_cls : type
Class for wrapping trade records.
entry_trades_cls : type
Class for wrapping entry trade records.
exit_trades_cls : type
Class for wrapping exit trade records.
positions_cls : type
Class for wrapping position records.
drawdowns_cls : type
Class for wrapping drawdown records.

For defaults, see portfolio.

Note

Use class methods with from_ prefix to build a portfolio. The __init__ method is reserved for indexing purposes.

Note

This class is meant to be immutable. To change any attribute, use Configured.replace().

Superclasses

Inherited members


allocations property

Portfolio.get_allocations() with default arguments.


alpha property

Portfolio.get_alpha() with default arguments.


annual_returns property

Portfolio.get_annual_returns() with default arguments.


annualized_return property

Portfolio.get_annualized_return() with default arguments.


annualized_volatility property

Portfolio.get_annualized_volatility() with default arguments.


apply_weights method

Portfolio.apply_weights(
    weights=None,
    rescale=False,
    group_by=None,
    apply_group_by=False,
    **kwargs
)

Get view of portfolio with asset weights applied and optionally rescaled.

If rescale is True, weights are rescaled in respect to other weights in the same group. For example, weights 0.5 and 0.5 are rescaled to 1.0 and 1.0 respectively, while weights 0.7 and 0.3 are rescaled to 1.4 (1.4 * 0.5 = 0.7) and 0.6 (0.6 * 0.5 = 0.3) respectively.


asset_flow property

Portfolio.get_asset_flow() with default arguments.


asset_pnl property

Portfolio.get_asset_pnl() with default arguments.


asset_returns property

Portfolio.get_asset_returns() with default arguments.


asset_value property

Portfolio.get_asset_value() with default arguments.


assets property

Portfolio.get_assets() with default arguments.


beta property

Portfolio.get_beta() with default arguments.


bm_close property

Benchmark price per unit series.


bm_returns property

Portfolio.get_bm_returns() with default arguments.


bm_value property

Portfolio.get_bm_value() with default arguments.


build_in_output_config_doc class method

Portfolio.build_in_output_config_doc(
    source_cls=None
)

Build in-output config documentation.


call_seq property

Sequence of calls per row and group.


calmar_ratio property

Portfolio.get_calmar_ratio() with default arguments.


capture_ratio property

Portfolio.get_capture_ratio() with default arguments.


cash property

Portfolio.get_cash() with default arguments.


cash_deposits property

Portfolio.get_cash_deposits() with default arguments.


cash_deposits_as_input property

Whether to add cash deposits to the input value when calculating returns.

Otherwise, will subtract them from the output value.


cash_earnings property

Portfolio.get_cash_earnings() with default arguments.


cash_flow property

Portfolio.get_cash_flow() with default arguments.


cash_sharing property

Whether to share cash within the same group.


close property

Last asset price at each time step.


close_flex property

Portfolio.close in a format suitable for flexible indexing.


column_stack class method

Portfolio.column_stack(
    *objs,
    wrapper_kwargs=None,
    group_by=None,
    ffill_close=False,
    fbfill_close=False,
    **kwargs
)

Stack multiple Portfolio instances along columns.

Uses ArrayWrapper.column_stack() to stack the wrappers.

Cash sharing must be the same among all objects.

Two-dimensional arrays are stacked using ArrayWrapper.column_stack_arrs() while one-dimensional arrays are stacked using ArrayWrapper.concat_arrs(). In-outputs are stacked using Portfolio.column_stack_in_outputs(). Records are stacked using Records.column_stack_records_arrs().


column_stack_in_outputs class method

Portfolio.column_stack_in_outputs(
    *objs,
    **kwargs
)

Stack Portfolio.in_outputs along columns.

All in-output tuples must be either None or have the same fields.

If the field can be found in the attributes of this Portfolio instance, reads the attribute's options to get requirements for the type and layout of the in-output object.

For each field in Portfolio.in_outputs, resolves the field's options by parsing its name with Portfolio.parse_field_options() and also looks for options in Portfolio.in_output_config. Performs stacking on the in-output objects of the same field using Portfolio.column_stack_objs().


column_stack_objs class method

Portfolio.column_stack_objs(
    objs,
    wrappers,
    grouping='columns_or_groups',
    obj_name=None,
    obj_type=None,
    wrapper=None,
    cash_sharing=False,
    column_stack_func=None,
    **kwargs
)

Stack (one and two-dimensional) objects along column.

column_stack_func must take the portfolio class, and all the arguments passed to this method. If you don't need any of the arguments, make column_stack_func accept them as **kwargs.

If all the objects are None, boolean, or empty, returns the first one.


cond_value_at_risk property

Portfolio.get_cond_value_at_risk() with default arguments.


cumulative_returns property

Portfolio.get_cumulative_returns() with default arguments.


daily_log_returns property

Portfolio.get_returns() with arguments {'daily_returns': True, 'log_returns': True}.


daily_returns property

Portfolio.get_daily_returns() with default arguments.


debt property

Portfolio.None with default arguments.


deflated_sharpe_ratio property

Portfolio.get_deflated_sharpe_ratio() with default arguments.


disable_weights method

Portfolio.disable_weights(
    **kwargs
)

Get view of portfolio with asset weights disabled.


down_capture_ratio property

Portfolio.get_down_capture_ratio() with default arguments.


downside_risk property

Portfolio.get_downside_risk() with default arguments.


drawdown property

Portfolio.get_drawdown() with default arguments.


drawdowns property

Portfolio.get_drawdowns() with default arguments.


drawdowns_cls property

Class for wrapping drawdown records.


entry_trades property

Portfolio.get_entry_trades() with default arguments.


entry_trades_cls property

Class for wrapping entry trade records.


exit_trades property

Portfolio.get_exit_trades() with default arguments.


exit_trades_cls property

Class for wrapping exit trade records.


filled_bm_close property

Portfolio.get_filled_bm_close() with default arguments.


filled_close property

Portfolio.get_filled_close() with default arguments.


fillna_close property

Whether to forward-backward fill NaN values in Portfolio.close.


final_value property

Portfolio.get_final_value() with default arguments.


free_cash property

Portfolio.get_cash() with arguments {'free': True}.


free_cash_flow property

Portfolio.get_cash_flow() with arguments {'free': True}.


from_def_order_func class method

Portfolio.from_def_order_func(
    close,
    size=None,
    size_type=None,
    direction=None,
    price=None,
    fees=None,
    fixed_fees=None,
    slippage=None,
    min_size=None,
    max_size=None,
    size_granularity=None,
    leverage=None,
    leverage_mode=None,
    reject_prob=None,
    price_area_vio_mode=None,
    allow_partial=None,
    raise_reject=None,
    log=None,
    pre_segment_func_nb=None,
    order_func_nb=None,
    flex_order_func_nb=None,
    val_price=None,
    sim_start=None,
    sim_end=None,
    call_seq=None,
    flexible=False,
    broadcast_named_args=None,
    broadcast_kwargs=None,
    chunked=None,
    return_preparer=False,
    return_prep_result=False,
    return_sim_out=False,
    **kwargs
)

Build portfolio from the default order function.

Default order function takes size, price, fees, and other available information, and issues an order at each column and time step. Additionally, it uses a segment preprocessing function that overrides the valuation price and sorts the call sequence. This way, it behaves similarly to Portfolio.from_orders(), but allows injecting pre- and postprocessing functions to have more control over the execution. It also knows how to chunk each argument. The only disadvantage is that Portfolio.from_orders() is more optimized towards performance (up to 5x).

If flexible is True:

If flexible is False:

Prepared by FDOFPreparer.

For details on other arguments, see Portfolio.from_orders() and Portfolio.from_order_func().

Usage

>>> close = pd.Series([1, 2, 3, 4, 5])
>>> pf = vbt.Portfolio.from_def_order_func(close, 10)

>>> pf.assets
0    10.0
1    20.0
2    30.0
3    40.0
4    40.0
dtype: float64
>>> pf.cash
0    90.0
1    70.0
2    40.0
3     0.0
4     0.0
dtype: float64
  • Equal-weighted portfolio as in the example under Portfolio.from_order_func() but much less verbose and with asset value pre-computed during the simulation (= faster):
>>> np.random.seed(42)
>>> close = np.random.uniform(1, 10, size=(5, 3))

>>> @njit
... def post_segment_func_nb(c):
...     for col in range(c.from_col, c.to_col):
...         c.in_outputs.asset_value_pc[c.i, col] = c.last_position[col] * c.last_val_price[col]

>>> pf = vbt.Portfolio.from_def_order_func(
...     close,
...     size=1/3,
...     size_type='targetpercent',
...     direction='longonly',
...     fees=0.001,
...     fixed_fees=1.,
...     slippage=0.001,
...     segment_mask=2,
...     cash_sharing=True,
...     group_by=True,
...     call_seq='auto',
...     post_segment_func_nb=post_segment_func_nb,
...     call_post_segment=True,
...     in_outputs=dict(asset_value_pc=vbt.RepEval('np.empty_like(close)'))
... )

>>> asset_value = pf.wrapper.wrap(pf.in_outputs.asset_value_pc, group_by=False)
>>> asset_value.vbt.plot().show()


from_holding class method

Portfolio.from_holding(
    close,
    direction=None,
    at_first_valid_in='close',
    close_at_end=None,
    dynamic_mode=False,
    **kwargs
)

Simulate portfolio from plain holding using signals.

If close_at_end is True, will place an opposite signal at the very end.

**kwargs are passed to the class method Portfolio.from_signals().


from_optimizer class method

Portfolio.from_optimizer(
    close,
    optimizer,
    pf_method='from_orders',
    squeeze_groups=True,
    dropna=None,
    fill_value=nan,
    size_type='targetpercent',
    direction=None,
    cash_sharing=True,
    call_seq='auto',
    group_by=None,
    **kwargs
)

Build portfolio from an optimizer of type PortfolioOptimizer.

Uses Portfolio.from_orders() as the base simulation method.

The size type is 'targetpercent'. If there are positive and negative values, the direction is automatically set to 'both', otherwise to 'longonly' for positive-only and shortonly for negative-only values. Also, the cash sharing is set to True, the call sequence is set to 'auto', and the grouper is set to the grouper of the optimizer by default.

Usage

>>> close = pd.DataFrame({
...     "MSFT": [1, 2, 3, 4, 5],
...     "GOOG": [5, 4, 3, 2, 1],
...     "AAPL": [1, 2, 3, 2, 1]
... }, index=pd.date_range(start="2020-01-01", periods=5))

>>> pfo = vbt.PortfolioOptimizer.from_random(
...     close.vbt.wrapper,
...     every="2D",
...     seed=42
... )
>>> pfo.fill_allocations()
                 MSFT      GOOG      AAPL
2020-01-01   0.182059  0.462129  0.355812
2020-01-02        NaN       NaN       NaN
2020-01-03   0.657381  0.171323  0.171296
2020-01-04        NaN       NaN       NaN
2020-01-05   0.038078  0.567845  0.394077

>>> pf = vbt.Portfolio.from_optimizer(close, pfo)
>>> pf.get_asset_value(group_by=False).vbt / pf.value
alloc_group                         group
                 MSFT      GOOG      AAPL
2020-01-01   0.182059  0.462129  0.355812  << rebalanced
2020-01-02   0.251907  0.255771  0.492322
2020-01-03   0.657381  0.171323  0.171296  << rebalanced
2020-01-04   0.793277  0.103369  0.103353
2020-01-05   0.038078  0.567845  0.394077  << rebalanced

from_order_func class method

Portfolio.from_order_func(
    close,
    *,
    init_cash=None,
    init_position=None,
    init_price=None,
    cash_deposits=None,
    cash_earnings=None,
    cash_sharing=None,
    sim_start=None,
    sim_end=None,
    call_seq=None,
    attach_call_seq=None,
    segment_mask=None,
    call_pre_segment=None,
    call_post_segment=None,
    pre_sim_func_nb=None,
    pre_sim_args=(),
    post_sim_func_nb=None,
    post_sim_args=(),
    pre_group_func_nb=None,
    pre_group_args=(),
    post_group_func_nb=None,
    post_group_args=(),
    pre_row_func_nb=None,
    pre_row_args=(),
    post_row_func_nb=None,
    post_row_args=(),
    pre_segment_func_nb=None,
    pre_segment_args=(),
    post_segment_func_nb=None,
    post_segment_args=(),
    order_func_nb=None,
    order_args=(),
    flex_order_func_nb=None,
    flex_order_args=(),
    post_order_func_nb=None,
    post_order_args=(),
    open=None,
    high=None,
    low=None,
    ffill_val_price=None,
    update_value=None,
    fill_pos_info=None,
    track_value=None,
    row_wise=None,
    max_order_records=None,
    max_log_records=None,
    in_outputs=None,
    seed=None,
    group_by=None,
    broadcast_named_args=None,
    broadcast_kwargs=None,
    template_context=None,
    keep_inout_flex=None,
    jitted=None,
    chunked=None,
    staticized=None,
    bm_close=None,
    records=None,
    return_preparer=False,
    return_prep_result=False,
    return_sim_out=False,
    **kwargs
)

Build portfolio from a custom order function.

Hint

See from_order_func_nb() for illustrations and argument definitions.

For more details on individual simulation functions:

Prepared by FOFPreparer.

Args

close : array_like, OHLCDataMixin, FOFPreparer, or PFPrepResult

Latest asset price at each time step. Will broadcast.

If an instance of OHLCDataMixin, will extract the open, high, low, and close price.

Used for calculating unrealized PnL and portfolio value.

init_cash : InitCashMode, float or array_like
See Portfolio.from_orders().
init_position : float or array_like
See Portfolio.from_orders().
init_price : float or array_like
See Portfolio.from_orders().
cash_deposits : float or array_like
See Portfolio.from_orders().
cash_earnings : float or array_like
See Portfolio.from_orders().
cash_sharing : bool

Whether to share cash within the same group.

If group_by is None, group_by becomes True to form a single group with cash sharing.

sim_start : int, datetime_like, or array_like
Simulation start row or index (inclusive).
sim_end : int, datetime_like, or array_like
Simulation end row or index (exclusive).
call_seq : CallSeqType or array_like

Default sequence of calls per row and group.

  • Use CallSeqType to select a sequence type.
  • Set to array to specify custom sequence. Will not broadcast.

Note

CallSeqType.Auto must be implemented manually. Use sort_call_seq_1d_nb() or sort_call_seq_out_1d_nb() in pre_segment_func_nb.

attach_call_seq : bool
See Portfolio.from_orders().
segment_mask : int or array_like of bool

Mask of whether a particular segment should be executed.

Supplying an integer will activate every n-th row. Supplying a boolean or an array of boolean will broadcast to the number of rows and groups.

Does not broadcast together with close and broadcast_named_args, only against the final shape.

call_pre_segment : bool
Whether to call pre_segment_func_nb regardless of segment_mask.
call_post_segment : bool
Whether to call post_segment_func_nb regardless of segment_mask.
pre_sim_func_nb : callable
Function called before simulation. Defaults to no_pre_func_nb().
pre_sim_args : tuple
Packed arguments passed to pre_sim_func_nb.
post_sim_func_nb : callable
Function called after simulation. Defaults to no_post_func_nb().
post_sim_args : tuple
Packed arguments passed to post_sim_func_nb.
pre_group_func_nb : callable

Function called before each group. Defaults to no_pre_func_nb().

Called only if row_wise is False.

pre_group_args : tuple
Packed arguments passed to pre_group_func_nb.
post_group_func_nb : callable

Function called after each group. Defaults to no_post_func_nb().

Called only if row_wise is False.

post_group_args : tuple
Packed arguments passed to post_group_func_nb.
pre_row_func_nb : callable

Function called before each row. Defaults to no_pre_func_nb().

Called only if row_wise is True.

pre_row_args : tuple
Packed arguments passed to pre_row_func_nb.
post_row_func_nb : callable

Function called after each row. Defaults to no_post_func_nb().

Called only if row_wise is True.

post_row_args : tuple
Packed arguments passed to post_row_func_nb.
pre_segment_func_nb : callable
Function called before each segment. Defaults to no_pre_func_nb().
pre_segment_args : tuple
Packed arguments passed to pre_segment_func_nb.
post_segment_func_nb : callable
Function called after each segment. Defaults to no_post_func_nb().
post_segment_args : tuple
Packed arguments passed to post_segment_func_nb.
order_func_nb : callable
Order generation function.
order_args
Packed arguments passed to order_func_nb.
flex_order_func_nb : callable
Flexible order generation function.
flex_order_args
Packed arguments passed to flex_order_func_nb.
post_order_func_nb : callable
Callback that is called after the order has been processed.
post_order_args : tuple
Packed arguments passed to post_order_func_nb.
open : array_like of float
See Portfolio.from_orders().
high : array_like of float
See Portfolio.from_orders().
low : array_like of float
See Portfolio.from_orders().
ffill_val_price : bool

Whether to track valuation price only if it's known.

Otherwise, unknown close will lead to NaN in valuation price at the next timestamp.

update_value : bool
Whether to update group value after each filled order.
fill_pos_info : bool

Whether to fill position record.

Disable this to make simulation faster for simple use cases.

track_value : bool

Whether to track value metrics such as the current valuation price, value, and return.

Disable this to make simulation faster for simple use cases.

row_wise : bool
Whether to iterate over rows rather than columns/groups.
max_order_records : int

The max number of order records expected to be filled at each column. Defaults to the number of rows in the broadcasted shape.

Set to a lower number if you run out of memory, to 0 to not fill, and to a higher number if there are more than one order expected at each timestamp.

max_log_records : int

The max number of log records expected to be filled at each column. Defaults to the number of rows in the broadcasted shape.

Set to a lower number if you run out of memory, to 0 to not fill, and to a higher number if there are more than one order expected at each timestamp.

in_outputs : mapping_like

Mapping with in-output objects.

Will be available via Portfolio.in_outputs as a named tuple.

To substitute Portfolio attributes, provide already broadcasted and grouped objects, for example, by using broadcast_named_args and templates. Also see Portfolio.in_outputs_indexing_func() on how in-output objects are indexed.

When chunking, make sure to provide the chunk taking specification and the merging function. See merge_sim_outs().

Note

When using Numba below 0.54, in_outputs cannot be a mapping, but must be a named tuple defined globally so Numba can introspect its attributes for pickling.

seed : int
See Portfolio.from_orders().
group_by : any
See Portfolio.from_orders().
broadcast_named_args : dict
See Portfolio.from_signals().
broadcast_kwargs : dict
See Portfolio.from_orders().
template_context : mapping
See Portfolio.from_signals().
keep_inout_flex : bool

Whether to keep arrays that can be edited in-place raw when broadcasting.

Disable this to be able to edit segment_mask, cash_deposits, and cash_earnings during the simulation.

jitted : any

See Portfolio.from_orders().

Note

Disabling jitting will not disable jitter (such as Numba) on other functions, only on the main (simulation) function. If neccessary, you should ensure that every other function is not compiled as well. For example, when working with Numba, you can do this by using the py_func attribute of that function. Or, you can disable Numba entirely by running os.environ['NUMBA_DISABLE_JIT'] = '1' before importing vectorbtpro.

Warning

Parallelization assumes that groups are independent and there is no data flowing between them.

chunked : any
See resolve_chunked_option().
staticized : bool, dict, hashable, or callable

Keyword arguments or task id for staticizing.

If True or dictionary, will be passed as keyword arguments to cut_and_save_func() to save a cacheable version of the simulator to a file. If a hashable or callable, will be used as a task id of an already registered jittable and chunkable simulator. Dictionary allows additional options override and reload to override and reload an already existing module respectively.

bm_close : array_like
See Portfolio.from_orders().
records : array_like
See Portfolio.from_orders().
return_preparer : bool
See Portfolio.from_orders().
return_prep_result : bool
See Portfolio.from_orders().
return_sim_out : bool
See Portfolio.from_orders().
**kwargs
Keyword arguments passed to the Portfolio constructor.

For defaults, see portfolio. Those defaults are not used to fill NaN values after reindexing: vectorbt uses its own sensible defaults, which are usually NaN for floating arrays and default flags for integer arrays. Use BCO with fill_value to override.

Note

All passed functions must be Numba-compiled if Numba is enabled.

Also see notes on Portfolio.from_orders().

Note

In contrast to other methods, the valuation price is previous close instead of the order price since the price of an order is unknown before the call (which is more realistic by the way). You can still override the valuation price in pre_segment_func_nb.

Usage

  • Buy 10 units each tick using closing price:
>>> @njit
... def order_func_nb(c, size):
...     return vbt.pf_nb.order_nb(size=size)

>>> close = pd.Series([1, 2, 3, 4, 5])
>>> pf = vbt.Portfolio.from_order_func(
...     close,
...     order_func_nb=order_func_nb,
...     order_args=(10,)
... )

>>> pf.assets
0    10.0
1    20.0
2    30.0
3    40.0
4    40.0
dtype: float64
>>> pf.cash
0    90.0
1    70.0
2    40.0
3     0.0
4     0.0
dtype: float64
  • Reverse each position by first closing it. Keep state of last position to determine which position to open next (just as an example, there are easier ways to do this):
>>> @njit
... def pre_group_func_nb(c):
...     last_pos_state = np.array([-1])
...     return (last_pos_state,)

>>> @njit
... def order_func_nb(c, last_pos_state):
...     if c.position_now != 0:
...         return vbt.pf_nb.close_position_nb()
...
...     if last_pos_state[0] == 1:
...         size = -np.inf  # open short
...         last_pos_state[0] = -1
...     else:
...         size = np.inf  # open long
...         last_pos_state[0] = 1
...     return vbt.pf_nb.order_nb(size=size)

>>> pf = vbt.Portfolio.from_order_func(
...     close,
...     order_func_nb=order_func_nb,
...     pre_group_func_nb=pre_group_func_nb
... )

>>> pf.assets
0    100.000000
1      0.000000
2    -66.666667
3      0.000000
4     26.666667
dtype: float64
>>> pf.cash
0      0.000000
1    200.000000
2    400.000000
3    133.333333
4      0.000000
dtype: float64
>>> @njit
... def pre_group_func_nb(c):
...     order_value_out = np.empty(c.group_len, dtype=np.float_)
...     return (order_value_out,)

>>> @njit
... def pre_segment_func_nb(c, order_value_out, size, price, size_type, direction):
...     for col in range(c.from_col, c.to_col):
...         c.last_val_price[col] = vbt.pf_nb.select_from_col_nb(c, col, price)
...     vbt.pf_nb.sort_call_seq_nb(c, size, size_type, direction, order_value_out)
...     return ()

>>> @njit
... def order_func_nb(c, size, price, size_type, direction, fees, fixed_fees, slippage):
...     return vbt.pf_nb.order_nb(
...         size=vbt.pf_nb.select_nb(c, size),
...         price=vbt.pf_nb.select_nb(c, price),
...         size_type=vbt.pf_nb.select_nb(c, size_type),
...         direction=vbt.pf_nb.select_nb(c, direction),
...         fees=vbt.pf_nb.select_nb(c, fees),
...         fixed_fees=vbt.pf_nb.select_nb(c, fixed_fees),
...         slippage=vbt.pf_nb.select_nb(c, slippage)
...     )

>>> np.random.seed(42)
>>> close = np.random.uniform(1, 10, size=(5, 3))
>>> size_template = vbt.RepEval('np.array([[1 / group_lens[0]]])')

>>> pf = vbt.Portfolio.from_order_func(
...     close,
...     order_func_nb=order_func_nb,
...     order_args=(
...         size_template,
...         vbt.Rep('price'),
...         vbt.Rep('size_type'),
...         vbt.Rep('direction'),
...         vbt.Rep('fees'),
...         vbt.Rep('fixed_fees'),
...         vbt.Rep('slippage'),
...     ),
...     segment_mask=2,  # rebalance every second tick
...     pre_group_func_nb=pre_group_func_nb,
...     pre_segment_func_nb=pre_segment_func_nb,
...     pre_segment_args=(
...         size_template,
...         vbt.Rep('price'),
...         vbt.Rep('size_type'),
...         vbt.Rep('direction')
...     ),
...     broadcast_named_args=dict(  # broadcast against each other
...         price=close,
...         size_type=vbt.pf_enums.SizeType.TargetPercent,
...         direction=vbt.pf_enums.Direction.LongOnly,
...         fees=0.001,
...         fixed_fees=1.,
...         slippage=0.001
...     ),
...     template_context=dict(np=np),  # required by size_template
...     cash_sharing=True, group_by=True,  # one group with cash sharing
... )

>>> pf.get_asset_value(group_by=False).vbt.plot().show()

Templates are a very powerful tool to prepare any custom arguments after they are broadcast and before they are passed to the simulation function. In the example above, we use broadcast_named_args to broadcast some arguments against each other and templates to pass those objects to callbacks. Additionally, we used an evaluation template to compute the size based on the number of assets in each group.

You may ask: why should we bother using broadcasting and templates if we could just pass size=1/3? Because of flexibility those features provide: we can now pass whatever parameter combinations we want and it will work flawlessly. For example, to create two groups of equally-allocated positions, we need to change only two parameters:

>>> close = np.random.uniform(1, 10, size=(5, 6))  # 6 columns instead of 3
>>> group_by = ['g1', 'g1', 'g1', 'g2', 'g2', 'g2']  # 2 groups instead of 1
>>> # Replace close and group_by in the example above

>>> pf['g1'].get_asset_value(group_by=False).vbt.plot().show()

>>> pf['g2'].get_asset_value(group_by=False).vbt.plot().show()

  • Combine multiple exit conditions. Exit early if the price hits some threshold before an actual exit:
>>> @njit
... def pre_sim_func_nb(c):
...     # We need to define stop price per column once
...     stop_price = np.full(c.target_shape[1], np.nan, dtype=np.float_)
...     return (stop_price,)

>>> @njit
... def order_func_nb(c, stop_price, entries, exits, size):
...     # Select info related to this order
...     entry_now = vbt.pf_nb.select_nb(c, entries)
...     exit_now = vbt.pf_nb.select_nb(c, exits)
...     size_now = vbt.pf_nb.select_nb(c, size)
...     price_now = vbt.pf_nb.select_nb(c, c.close)
...     stop_price_now = stop_price[c.col]
...
...     # Our logic
...     if entry_now:
...         if c.position_now == 0:
...             return vbt.pf_nb.order_nb(
...                 size=size_now,
...                 price=price_now,
...                 direction=vbt.pf_enums.Direction.LongOnly)
...     elif exit_now or price_now >= stop_price_now:
...         if c.position_now > 0:
...             return vbt.pf_nb.order_nb(
...                 size=-size_now,
...                 price=price_now,
...                 direction=vbt.pf_enums.Direction.LongOnly)
...     return vbt.pf_enums.NoOrder

>>> @njit
... def post_order_func_nb(c, stop_price, stop):
...     # Same broadcasting as for size
...     stop_now = vbt.pf_nb.select_nb(c, stop)
...
...     if c.order_result.status == vbt.pf_enums.OrderStatus.Filled:
...         if c.order_result.side == vbt.pf_enums.OrderSide.Buy:
...             # Position entered: Set stop condition
...             stop_price[c.col] = (1 + stop_now) * c.order_result.price
...         else:
...             # Position exited: Remove stop condition
...             stop_price[c.col] = np.nan

>>> def simulate(close, entries, exits, size, stop):
...     return vbt.Portfolio.from_order_func(
...         close,
...         order_func_nb=order_func_nb,
...         order_args=(vbt.Rep('entries'), vbt.Rep('exits'), vbt.Rep('size')),
...         pre_sim_func_nb=pre_sim_func_nb,
...         post_order_func_nb=post_order_func_nb,
...         post_order_args=(vbt.Rep('stop'),),
...         broadcast_named_args=dict(  # broadcast against each other
...             entries=entries,
...             exits=exits,
...             size=size,
...             stop=stop
...         )
...     )

>>> close = pd.Series([10, 11, 12, 13, 14])
>>> entries = pd.Series([True, True, False, False, False])
>>> exits = pd.Series([False, False, False, True, True])
>>> simulate(close, entries, exits, np.inf, 0.1).asset_flow
0    10.0
1     0.0
2   -10.0
3     0.0
4     0.0
dtype: float64

>>> simulate(close, entries, exits, np.inf, 0.2).asset_flow
0    10.0
1     0.0
2   -10.0
3     0.0
4     0.0
dtype: float64

>>> simulate(close, entries, exits, np.inf, np.nan).asset_flow
0    10.0
1     0.0
2     0.0
3   -10.0
4     0.0
dtype: float64

The reason why stop of 10% does not result in an order at the second time step is because it comes at the same time as entry, so it must wait until no entry is present. This can be changed by replacing the statement "elif" with "if", which would execute an exit regardless if an entry is present (similar to using ConflictMode.Opposite in Portfolio.from_signals()).

We can also test the parameter combinations above all at once (thanks to broadcasting using broadcast()):

>>> stop = pd.DataFrame([[0.1, 0.2, np.nan]])
>>> simulate(close, entries, exits, np.inf, stop).asset_flow
      0     1     2
0  10.0  10.0  10.0
1   0.0   0.0   0.0
2 -10.0 -10.0   0.0
3   0.0   0.0 -10.0
4   0.0   0.0   0.0

Or much simpler using Cartesian product:

>>> stop = vbt.Param([0.1, 0.2, np.nan])
>>> simulate(close, entries, exits, np.inf, stop).asset_flow
threshold   0.1   0.2   NaN
0          10.0  10.0  10.0
1           0.0   0.0   0.0
2         -10.0 -10.0   0.0
3           0.0   0.0 -10.0
4           0.0   0.0   0.0

This works because pd.Index automatically translates into BCO with product set to True.

  • Let's illustrate how to generate multiple orders per symbol and bar. For each bar, buy at open and sell at close:
>>> @njit
... def flex_order_func_nb(c, size):
...     if c.call_idx == 0:
...         return c.from_col, vbt.pf_nb.order_nb(size=size, price=c.open[c.i, c.from_col])
...     if c.call_idx == 1:
...         return c.from_col, vbt.pf_nb.close_position_nb(price=c.close[c.i, c.from_col])
...     return -1, vbt.pf_enums.NoOrder

>>> open = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
>>> close = pd.DataFrame({'a': [2, 3, 4], 'b': [3, 4, 5]})
>>> size = 1
>>> pf = vbt.Portfolio.from_order_func(
...     close,
...     flex_order_func_nb=flex_order_func_nb,
...     flex_order_args=(size,),
...     open=open,
...     max_order_records=close.shape[0] * 2
... )

>>> pf.orders.readable
    Order Id Column  Timestamp  Size  Price  Fees  Side
0          0      a          0   1.0    1.0   0.0   Buy
1          1      a          0   1.0    2.0   0.0  Sell
2          2      a          1   1.0    2.0   0.0   Buy
3          3      a          1   1.0    3.0   0.0  Sell
4          4      a          2   1.0    3.0   0.0   Buy
5          5      a          2   1.0    4.0   0.0  Sell
6          0      b          0   1.0    4.0   0.0   Buy
7          1      b          0   1.0    3.0   0.0  Sell
8          2      b          1   1.0    5.0   0.0   Buy
9          3      b          1   1.0    4.0   0.0  Sell
10         4      b          2   1.0    6.0   0.0   Buy
11         5      b          2   1.0    5.0   0.0  Sell

Warning

Each bar is effectively a black box - we don't know how the price moves in-between. Since trades should come in an order that closely replicates that of the real world, the only pieces of information that always remain in the correct order are the opening and closing price.


from_orders class method

Portfolio.from_orders(
    close,
    size=None,
    size_type=None,
    direction=None,
    price=None,
    fees=None,
    fixed_fees=None,
    slippage=None,
    min_size=None,
    max_size=None,
    size_granularity=None,
    leverage=None,
    leverage_mode=None,
    reject_prob=None,
    price_area_vio_mode=None,
    allow_partial=None,
    raise_reject=None,
    log=None,
    val_price=None,
    from_ago=None,
    open=None,
    high=None,
    low=None,
    init_cash=None,
    init_position=None,
    init_price=None,
    cash_deposits=None,
    cash_earnings=None,
    cash_dividends=None,
    cash_sharing=None,
    sim_start=None,
    sim_end=None,
    call_seq=None,
    attach_call_seq=None,
    ffill_val_price=None,
    update_value=None,
    save_state=None,
    save_value=None,
    save_returns=None,
    max_order_records=None,
    max_log_records=None,
    seed=None,
    group_by=None,
    broadcast_kwargs=None,
    jitted=None,
    chunked=None,
    bm_close=None,
    records=None,
    return_preparer=False,
    return_prep_result=False,
    return_sim_out=False,
    **kwargs
)

Simulate portfolio from orders - size, price, fees, and other information.

See from_orders_nb().

Prepared by FOPreparer.

Args

close : array_like, OHLCDataMixin, FOPreparer, or PFPrepResult

Latest asset price at each time step. Will broadcast.

Used for calculating unrealized PnL and portfolio value.

If an instance of OHLCDataMixin, will extract the open, high, low, and close price. If an instance of FOPreparer, will use it as a preparer. If an instance of PFPrepResult, will use it as a preparer result.

size : float or array_like
Size to order. See Order.size. Will broadcast.
size_type : SizeType or array_like
See SizeType and Order.size_type. Will broadcast.
direction : Direction or array_like
See Direction and Order.direction. Will broadcast.
price : array_like of float

Order price. Will broadcast.

See Order.price. Can be also provided as PriceType. Options PriceType.NextOpen and PriceType.NextClose are only applicable per column, that is, they cannot be used inside full arrays. In addition, they require the argument from_ago to be None.

fees : float or array_like
Fees in percentage of the order value. See Order.fees. Will broadcast.
fixed_fees : float or array_like
Fixed amount of fees to pay per order. See Order.fixed_fees. Will broadcast.
slippage : float or array_like
Slippage in percentage of price. See Order.slippage. Will broadcast.
min_size : float or array_like
Minimum size for an order to be accepted. See Order.min_size. Will broadcast.
max_size : float or array_like

Maximum size for an order. See Order.max_size. Will broadcast.

Will be partially filled if exceeded.

size_granularity : float or array_like
Granularity of the size. See Order.size_granularity. Will broadcast.
leverage : float or array_like
Leverage. See Order.leverage. Will broadcast.
leverage_mode : LeverageMode or array_like
Leverage mode. See Order.leverage_mode. Will broadcast.
reject_prob : float or array_like
Order rejection probability. See Order.reject_prob. Will broadcast.
price_area_vio_mode : PriceAreaVioMode or array_like
See PriceAreaVioMode. Will broadcast.
allow_partial : bool or array_like

Whether to allow partial fills. See Order.allow_partial. Will broadcast.

Does not apply when size is np.inf.

raise_reject : bool or array_like
Whether to raise an exception if order gets rejected. See Order.raise_reject. Will broadcast.
log : bool or array_like
Whether to log orders. See Order.log. Will broadcast.
val_price : array_like of float

Asset valuation price. Will broadcast.

Can be also provided as ValPriceType.

  • Any -np.inf element is replaced by the latest valuation price (open or the latest known valuation price if ffill_val_price).
  • Any np.inf element is replaced by the current order price.

Used at the time of decision making to calculate value of each asset in the group, for example, to convert target value into target amount.

Note

In contrast to Portfolio.from_order_func(), order price is known beforehand (kind of), thus val_price is set to the current order price (using np.inf) by default. To valuate using previous close, set it in the settings to -np.inf.

Note

Make sure to use timestamp for val_price that comes before timestamps of all orders in the group with cash sharing (previous close for example), otherwise you're cheating yourself.

open : array_like of float

First asset price at each time step. Defaults to np.nan. Will broadcast.

Used as a price boundary (see PriceArea).

high : array_like of float

Highest asset price at each time step. Defaults to np.nan. Will broadcast.

Used as a price boundary (see PriceArea).

low : array_like of float

Lowest asset price at each time step. Defaults to np.nan. Will broadcast.

Used as a price boundary (see PriceArea).

init_cash : InitCashMode, float or array_like

Initial capital.

By default, will broadcast to the final number of columns. But if cash sharing is enabled, will broadcast to the number of groups. See InitCashMode to find optimal initial cash.

Note

Mode InitCashMode.AutoAlign is applied after the portfolio is initialized to set the same initial cash for all columns/groups. Changing grouping will change the initial cash, so be aware when indexing.

init_position : float or array_like

Initial position.

By default, will broadcast to the final number of columns.

init_price : float or array_like

Initial position price.

By default, will broadcast to the final number of columns.

cash_deposits : float or array_like

Cash to be deposited/withdrawn at each timestamp. Will broadcast to the final shape. Must have the same number of columns as init_cash.

Applied at the beginning of each timestamp.

cash_earnings : float or array_like

Earnings in cash to be added at each timestamp. Will broadcast to the final shape.

Applied at the end of each timestamp.

cash_dividends : float or array_like

Dividends in cash to be added at each timestamp. Will broadcast to the final shape.

Gets multiplied by the position and saved into cash_earnings.

Applied at the end of each timestamp.

cash_sharing : bool

Whether to share cash within the same group.

If group_by is None and cash_sharing is True, group_by becomes True to form a single group with cash sharing.

Warning

Introduces cross-asset dependencies.

This method presumes that in a group of assets that share the same capital all orders will be executed within the same tick and retain their price regardless of their position in the queue, even though they depend upon each other and thus cannot be executed in parallel.

from_ago : int or array_like

Take order information from a number of bars ago. Will broadcast.

Negative numbers will be cast to positive to avoid the look-ahead bias. Defaults to 0. Remember to account of it if you're using a custom signal function!

sim_start : int, datetime_like, or array_like

Simulation start row or index (inclusive).

Can be "auto", which will be substituted by the index of the first non-NA size value.

sim_end : int, datetime_like, or array_like

Simulation end row or index (exclusive).

Can be "auto", which will be substituted by the index of the first non-NA size value.

call_seq : CallSeqType or array_like

Default sequence of calls per row and group.

Each value in this sequence must indicate the position of column in the group to call next. Processing of call_seq goes always from left to right. For example, [2, 0, 1] would first call column 'c', then 'a', and finally 'b'.

Supported are multiple options:

  • Set to None to generate the default call sequence on the fly. Will create a full array only if attach_call_seq is True.
  • Use CallSeqType to create a full array of a specific type.
  • Set to array to specify a custom call sequence.

If CallSeqType.Auto selected, rearranges calls dynamically based on order value. Calculates value of all orders per row and group, and sorts them by this value. Sell orders will be executed first to release funds for buy orders.

Warning

CallSeqType.Auto should be used with caution:

  • It not only presumes that order prices are known beforehand, but also that orders can be executed in arbitrary order and still retain their price. In reality, this is hardly the case: after processing one asset, some time has passed and the price for other assets might have already changed.
  • Even if you're able to specify a slippage large enough to compensate for this behavior, slippage itself should depend upon execution order. This method doesn't let you do that.
  • Orders in the same queue are executed regardless of whether previous orders have been filled, which can leave them without required funds.

For more control, use Portfolio.from_order_func().

attach_call_seq : bool

Whether to attach call_seq to the instance.

Makes sense if you want to analyze the simulation order. Otherwise, just takes memory.

ffill_val_price : bool

Whether to track valuation price only if it's known.

Otherwise, unknown close will lead to NaN in valuation price at the next timestamp.

update_value : bool
Whether to update group value after each filled order.
save_state : bool

Whether to save the state.

The arrays will be available as cash, position, debt, locked_cash, and free_cash in in-outputs.

save_value : bool

Whether to save the value.

The array will be available as value in in-outputs.

save_returns : bool

Whether to save the returns.

The array will be available as returns in in-outputs.

max_order_records : int

The max number of order records expected to be filled at each column. Defaults to the maximum number of non-NaN values across all columns of the size array.

Set to a lower number if you run out of memory, and to 0 to not fill.

max_log_records : int

The max number of log records expected to be filled at each column. Defaults to the maximum number of True values across all columns of the log array.

Set to a lower number if you run out of memory, and to 0 to not fill.

seed : int
Seed to be set for both call_seq and at the beginning of the simulation.
group_by : any
Group columns. See Grouper.
broadcast_kwargs : dict
Keyword arguments passed to broadcast().
jitted : any
See resolve_jitted_option().
chunked : any
See resolve_chunked_option().
bm_close : array_like

Latest benchmark price at each time step. Will broadcast.

If not provided, will use close. If False, will not use any benchmark.

records : array_like

Records to construct arrays from.

See IdxRecords.

return_preparer : bool

Whether to return the preparer of the type FOPreparer.

Note

Seed won't be set in this case, you need to explicitly call preparer.set_seed().

return_prep_result : bool
Whether to return the preparer result of the type PFPrepResult.
return_sim_out : bool
Whether to return the simulation output of the type SimulationOutput.
**kwargs
Keyword arguments passed to the Portfolio constructor.

All broadcastable arguments will broadcast using broadcast() but keep original shape to utilize flexible indexing and to save memory.

For defaults, see portfolio. Those defaults are not used to fill NaN values after reindexing: vectorbt uses its own sensible defaults, which are usually NaN for floating arrays and default flags for integer arrays. Use BCO with fill_value to override.

Note

When call_seq is not CallSeqType.Auto, at each timestamp, processing of the assets in a group goes strictly in order defined in call_seq. This order can't be changed dynamically.

This has one big implication for this particular method: the last asset in the call stack cannot be processed until other assets are processed. This is the reason why rebalancing cannot work properly in this setting: one has to specify percentages for all assets beforehand and then tweak the processing order to sell to-be-sold assets first in order to release funds for to-be-bought assets. This can be automatically done by using CallSeqType.Auto.

Hint

All broadcastable arguments can be set per frame, series, row, column, or element.

Usage

  • Buy 10 units each tick:
>>> close = pd.Series([1, 2, 3, 4, 5])
>>> pf = vbt.Portfolio.from_orders(close, 10)

>>> pf.assets
0    10.0
1    20.0
2    30.0
3    40.0
4    40.0
dtype: float64
>>> pf.cash
0    90.0
1    70.0
2    40.0
3     0.0
4     0.0
dtype: float64
  • Reverse each position by first closing it:
>>> size = [1, 0, -1, 0, 1]
>>> pf = vbt.Portfolio.from_orders(close, size, size_type='targetpercent')

>>> pf.assets
0    100.000000
1      0.000000
2    -66.666667
3      0.000000
4     26.666667
dtype: float64
>>> pf.cash
0      0.000000
1    200.000000
2    400.000000
3    133.333333
4      0.000000
dtype: float64
  • Regularly deposit cash at open and invest it within the same bar at close:
>>> close = pd.Series([1, 2, 3, 4, 5])
>>> cash_deposits = pd.Series([10., 0., 10., 0., 10.])
>>> pf = vbt.Portfolio.from_orders(
...     close,
...     size=cash_deposits,  # invest the amount deposited
...     size_type='value',
...     cash_deposits=cash_deposits
... )

>>> pf.cash
0    100.0
1    100.0
2    100.0
3    100.0
4    100.0
dtype: float64

>>> pf.asset_flow
0    10.000000
1     0.000000
2     3.333333
3     0.000000
4     2.000000
dtype: float64
  • Equal-weighted portfolio as in from_order_func_nb() example (it's more compact but has less control over execution):
>>> np.random.seed(42)
>>> close = pd.DataFrame(np.random.uniform(1, 10, size=(5, 3)))
>>> size = pd.Series(np.full(5, 1/3))  # each column 33.3%
>>> size[1::2] = np.nan  # skip every second tick

>>> pf = vbt.Portfolio.from_orders(
...     close,  # acts both as reference and order price here
...     size,
...     size_type='targetpercent',
...     direction='longonly',
...     call_seq='auto',  # first sell then buy
...     group_by=True,  # one group
...     cash_sharing=True,  # assets share the same cash
...     fees=0.001, fixed_fees=1., slippage=0.001  # costs
... )

>>> pf.get_asset_value(group_by=False).vbt.plot().show()

  • Test 10 random weight combinations:
>>> np.random.seed(42)
>>> close = pd.DataFrame(
...     np.random.uniform(1, 10, size=(5, 3)),
...     columns=pd.Index(['a', 'b', 'c'], name='asset'))

>>> # Generate random weight combinations
>>> rand_weights = []
>>> for i in range(10):
...     rand_weights.append(np.random.dirichlet(np.ones(close.shape[1]), size=1)[0])
>>> rand_weights
[array([0.15474873, 0.27706078, 0.5681905 ]),
 array([0.30468598, 0.18545189, 0.50986213]),
 array([0.15780486, 0.36292607, 0.47926907]),
 array([0.25697713, 0.64902589, 0.09399698]),
 array([0.43310548, 0.53836359, 0.02853093]),
 array([0.78628605, 0.15716865, 0.0565453 ]),
 array([0.37186671, 0.42150531, 0.20662798]),
 array([0.22441579, 0.06348919, 0.71209502]),
 array([0.41619664, 0.09338007, 0.49042329]),
 array([0.01279537, 0.87770864, 0.10949599])]

>>> # Bring close and rand_weights to the same shape
>>> rand_weights = np.concatenate(rand_weights)
>>> close = close.vbt.tile(10, keys=pd.Index(np.arange(10), name='weights_vector'))
>>> size = vbt.broadcast_to(weights, close).copy()
>>> size[1::2] = np.nan
>>> size
weights_vector                            0  ...                               9
asset                  a         b        c  ...           a         b         c
0               0.154749  0.277061  0.56819  ...    0.012795  0.877709  0.109496
1                    NaN       NaN      NaN  ...         NaN       NaN       NaN
2               0.154749  0.277061  0.56819  ...    0.012795  0.877709  0.109496
3                    NaN       NaN      NaN  ...         NaN       NaN       NaN
4               0.154749  0.277061  0.56819  ...    0.012795  0.877709  0.109496

[5 rows x 30 columns]

>>> pf = vbt.Portfolio.from_orders(
...     close,
...     size,
...     size_type='targetpercent',
...     direction='longonly',
...     call_seq='auto',
...     group_by='weights_vector',  # group by column level
...     cash_sharing=True,
...     fees=0.001, fixed_fees=1., slippage=0.001
... )

>>> pf.total_return
weights_vector
0   -0.294372
1    0.139207
2   -0.281739
3    0.041242
4    0.467566
5    0.829925
6    0.320672
7   -0.087452
8    0.376681
9   -0.702773
Name: total_return, dtype: float64

from_random_signals class method

Portfolio.from_random_signals(
    close,
    n=None,
    prob=None,
    entry_prob=None,
    exit_prob=None,
    param_product=False,
    seed=None,
    run_kwargs=None,
    **kwargs
)

Simulate portfolio from random entry and exit signals.

Generates signals based either on the number of signals n or the probability of encountering a signal prob.

Based on Portfolio.from_signals().

Note

To generate random signals, the shape of close is used. Broadcasting with other arrays happens after the generation.

Usage

  • Test multiple combinations of random entries and exits:
>>> close = pd.Series([1, 2, 3, 4, 5])
>>> pf = vbt.Portfolio.from_random_signals(close, n=[2, 1, 0], seed=42)
>>> pf.orders.count()
randnx_n
2    4
1    2
0    0
Name: count, dtype: int64
  • Test the Cartesian product of entry and exit encounter probabilities:
>>> pf = vbt.Portfolio.from_random_signals(
...     close,
...     entry_prob=[0, 0.5, 1],
...     exit_prob=[0, 0.5, 1],
...     param_product=True,
...     seed=42)
>>> pf.orders.count()
rprobnx_entry_prob  rprobnx_exit_prob
0.0                 0.0                  0
                    0.5                  0
                    1.0                  0
0.5                 0.0                  1
                    0.5                  4
                    1.0                  3
1.0                 0.0                  1
                    0.5                  4
                    1.0                  5
Name: count, dtype: int64

from_signals class method

Portfolio.from_signals(
    close,
    entries=None,
    exits=None,
    *,
    direction=None,
    long_entries=None,
    long_exits=None,
    short_entries=None,
    short_exits=None,
    adjust_func_nb=None,
    adjust_args=(),
    signal_func_nb=None,
    signal_args=(),
    post_segment_func_nb=None,
    post_segment_args=(),
    order_mode=False,
    size=None,
    size_type=None,
    price=None,
    fees=None,
    fixed_fees=None,
    slippage=None,
    min_size=None,
    max_size=None,
    size_granularity=None,
    leverage=None,
    leverage_mode=None,
    reject_prob=None,
    price_area_vio_mode=None,
    allow_partial=None,
    raise_reject=None,
    log=None,
    val_price=None,
    accumulate=None,
    upon_long_conflict=None,
    upon_short_conflict=None,
    upon_dir_conflict=None,
    upon_opposite_entry=None,
    order_type=None,
    limit_delta=None,
    limit_tif=None,
    limit_expiry=None,
    limit_reverse=None,
    limit_order_price=None,
    upon_adj_limit_conflict=None,
    upon_opp_limit_conflict=None,
    use_stops=None,
    stop_ladder=None,
    sl_stop=None,
    tsl_stop=None,
    tsl_th=None,
    tp_stop=None,
    td_stop=None,
    dt_stop=None,
    stop_entry_price=None,
    stop_exit_price=None,
    stop_exit_type=None,
    stop_order_type=None,
    stop_limit_delta=None,
    upon_stop_update=None,
    upon_adj_stop_conflict=None,
    upon_opp_stop_conflict=None,
    delta_format=None,
    time_delta_format=None,
    open=None,
    high=None,
    low=None,
    init_cash=None,
    init_position=None,
    init_price=None,
    cash_deposits=None,
    cash_earnings=None,
    cash_dividends=None,
    cash_sharing=None,
    from_ago=None,
    sim_start=None,
    sim_end=None,
    call_seq=None,
    attach_call_seq=None,
    ffill_val_price=None,
    update_value=None,
    fill_pos_info=None,
    save_state=None,
    save_value=None,
    save_returns=None,
    max_order_records=None,
    max_log_records=None,
    in_outputs=None,
    seed=None,
    group_by=None,
    broadcast_named_args=None,
    broadcast_kwargs=None,
    template_context=None,
    jitted=None,
    chunked=None,
    staticized=None,
    bm_close=None,
    records=None,
    return_preparer=False,
    return_prep_result=False,
    return_sim_out=False,
    **kwargs
)

Simulate portfolio from entry and exit signals.

Supports the following modes:

  1. entries and exits: Uses dir_signal_func_nb() as signal_func_nb if an adjustment function is provided (not cacheable), otherwise translates signals using dir_to_ls_signals_nb() then simulates statically (cacheable)
  2. entries (acting as long), exits (acting as long), short_entries, and short_exits: Uses ls_signal_func_nb() as signal_func_nb if an adjustment function is provided (not cacheable), otherwise simulates statically (cacheable)
  3. order_mode=True without signals: Uses order_signal_func_nb() as signal_func_nb (not cacheable)
  4. signal_func_nb and signal_args: Custom signal function (not cacheable)

Prepared by FSPreparer.

Args

close : array_like, OHLCDataMixin, FSPreparer, or PFPrepResult
See Portfolio.from_orders().
entries : array_like of bool

Boolean array of entry signals. Defaults to True if all other signal arrays are not set, otherwise False. Will broadcast.

  • If short_entries and short_exits are not set: Acts as a long signal if direction is 'all' or 'longonly', otherwise short.
  • If short_entries or short_exits are set: Acts as long_entries.
exits : array_like of bool

Boolean array of exit signals. Defaults to False. Will broadcast.

  • If short_entries and short_exits are not set: Acts as a short signal if direction is 'all' or 'longonly', otherwise long.
  • If short_entries or short_exits are set: Acts as long_exits.
direction : Direction or array_like

See Portfolio.from_orders().

Takes only effect if short_entries and short_exits are not set.

long_entries : array_like of bool
Boolean array of long entry signals. Defaults to False. Will broadcast.
long_exits : array_like of bool
Boolean array of long exit signals. Defaults to False. Will broadcast.
short_entries : array_like of bool
Boolean array of short entry signals. Defaults to False. Will broadcast.
short_exits : array_like of bool
Boolean array of short exit signals. Defaults to False. Will broadcast.
adjust_func_nb : path_like or callable

User-defined function to adjust the current simulation state. Defaults to no_adjust_func_nb().

Passed as argument to dir_signal_func_nb(), ls_signal_func_nb(), and order_signal_func_nb(). Has no effect when using other signal functions.

Can be a path to a module when using staticizing.

adjust_args : tuple
Packed arguments passed to adjust_func_nb.
signal_func_nb : path_like or callable

Function called to generate signals.

See from_signal_func_nb().

Can be a path to a module when using staticizing.

signal_args : tuple
Packed arguments passed to signal_func_nb.
post_segment_func_nb : path_like or callable

Post-segment function.

See from_signal_func_nb().

Can be a path to a module when using staticizing.

post_segment_args : tuple
Packed arguments passed to post_segment_func_nb.
order_mode : bool
Whether to simulate as orders without signals.
size : float or array_like

See Portfolio.from_orders().

Note

Negative size is not allowed. You must express direction using signals.

size_type : SizeType or array_like

See Portfolio.from_orders().

Only SizeType.Amount, SizeType.Value, SizeType.Percent(100), and SizeType.ValuePercent(100) are supported. Other modes such as target percentage are not compatible with signals since their logic may contradict the direction of the signal.

Note

SizeType.Percent(100) does not support position reversal. Switch to a single direction or use OppositeEntryMode.Close to close the position first.

See warning in Portfolio.from_orders().

price : array_like of float
See Portfolio.from_orders().
fees : float or array_like
See Portfolio.from_orders().
fixed_fees : float or array_like
See Portfolio.from_orders().
slippage : float or array_like
See Portfolio.from_orders().
min_size : float or array_like
See Portfolio.from_orders().
max_size : float or array_like

See Portfolio.from_orders().

Will be partially filled if exceeded. You might not be able to properly close the position if accumulation is enabled and max_size is too low.

size_granularity : float or array_like
See Portfolio.from_orders().
leverage : float or array_like
See Portfolio.from_orders().
leverage_mode : LeverageMode or array_like
See Portfolio.from_orders().
reject_prob : float or array_like
See Portfolio.from_orders().
price_area_vio_mode : PriceAreaVioMode or array_like
See Portfolio.from_orders().
allow_partial : bool or array_like
See Portfolio.from_orders().
raise_reject : bool or array_like
See Portfolio.from_orders().
log : bool or array_like
See Portfolio.from_orders().
val_price : array_like of float
See Portfolio.from_orders().
accumulate : bool, AccumulationMode or array_like

See AccumulationMode. If True, becomes 'both'. If False, becomes 'disabled'. Will broadcast.

When enabled, Portfolio.from_signals() behaves similarly to Portfolio.from_orders().

upon_long_conflict : ConflictMode or array_like
Conflict mode for long signals. See ConflictMode. Will broadcast.
upon_short_conflict : ConflictMode or array_like
Conflict mode for short signals. See ConflictMode. Will broadcast.
upon_dir_conflict : DirectionConflictMode or array_like
See DirectionConflictMode. Will broadcast.
upon_opposite_entry : OppositeEntryMode or array_like
See OppositeEntryMode. Will broadcast.
order_type : OrderType or array_like

See OrderType.

Only one active limit order is allowed at a time.

limit_delta : float or array_like

Delta from price to build the limit price. Will broadcast.

If NaN, price becomes the limit price. Otherwise, applied on top of price depending on the current direction: if the direction-aware size is positive (= buying), a positive delta will decrease the limit price; if the direction-aware size is negative (= selling), a positive delta will increase the limit price. Delta can be negative.

Set an element to np.nan to disable. Use delta_format to specify the format.

limit_tif : frequency_like or array_like

Time in force for limit signals. Will broadcast.

Any frequency-like object is converted using to_timedelta64(). Any array must either contain timedeltas or integers, and will be cast into integer format after broadcasting. If the object provided is of data type object, will be converted to timedelta automatically.

Measured in the distance after the open time of the signal bar. If the expiration time happens in the middle of the current bar, we pessimistically assume that the order has been expired. The check is performed at the beginning of the bar, and the first check is performed at the next bar after the signal. For example, if the format is TimeDeltaFormat.Rows, 0 or 1 means the order must execute at the same bar or not at all; 2 means the order must execute at the same or next bar or not at all.

Set an element to -1 to disable. Use time_delta_format to specify the format.

limit_expiry : frequency_like, datetime_like, or array_like

Expiration time. Will broadcast.

Any frequency-like object is used to build a period index, such that each timestamp in the original index is pointing to the timestamp where the period ends. For example, providing "d" will make any limit order expire on the next day. Any array must either contain timestamps or integers (not timedeltas!), and will be cast into integer format after broadcasting. If the object provided is of data type object, will be converted to datetime and its timezone will be removed automatically (as done on the index).

Behaves in a similar way as limit_tif.

Set an element to -1 or pd.Timestamp.max to disable. Use time_delta_format to specify the format.

limit_reverse : bool or array_like

Whether to reverse the price hit detection. Will broadcast.

If True, a buy/sell limit price will be checked against high/low (not low/high). Also, the limit delta will be applied above/below (not below/above) the initial price.

limit_order_price : LimitOrderPrice or array_like

See LimitOrderPrice. Will broadcast.

If provided on per-element basis, gets applied upon order creation. If a positive value is provided, used directly as a price, otherwise used as an enumerated value.

upon_adj_limit_conflict : PendingConflictMode or array_like
Conflict mode for limit and user-defined signals of adjacent sign. See PendingConflictMode. Will broadcast.
upon_opp_limit_conflict : PendingConflictMode or array_like
Conflict mode for limit and user-defined signals of opposite sign. See PendingConflictMode. Will broadcast.
use_stops : bool

Whether to use stops. Defaults to None, which becomes True if any of the stops are not NaN or the adjustment function is not the default one.

Disable this to make simulation a bit faster for simple use cases.

stop_ladder : bool or StopLadderMode

Whether and which kind of stop laddering to use. See StopLadderMode.

If so, rows in the supplied arrays will become ladder steps. Make sure that they are increasing. If one column should have less steps, pad it with NaN for price-based stops and -1 for time-based stops.

Rows in each array can be of an arbitrary length but columns must broadcast against the number of columns in the data. Applied on all stop types.

sl_stop : array_like of float

Stop loss. Will broadcast.

Set an element to np.nan to disable. Use delta_format to specify the format.

tsl_stop : array_like of float

Trailing stop loss for the trailing stop loss. Will broadcast.

Set an element to np.nan to disable. Use delta_format to specify the format.

tsl_th : array_like of float

Take profit threshold for the trailing stop loss. Will broadcast.

Set an element to np.nan to disable. Use delta_format to specify the format.

tp_stop : array_like of float

Take profit. Will broadcast.

Set an element to np.nan to disable. Use delta_format to specify the format.

td_stop : frequency_like or array_like

Timedelta-stop. Will broadcast.

Set an element to -1 to disable. Use time_delta_format to specify the format.

dt_stop : frequency_like, datetime_like, or array_like

Datetime-stop. Will broadcast.

Set an element to -1 to disable. Use time_delta_format to specify the format.

stop_entry_price : StopEntryPrice or array_like

See StopEntryPrice. Will broadcast.

If provided on per-element basis, gets applied upon entry. If a positive value is provided, used directly as a price, otherwise used as an enumerated value.

stop_exit_price : StopExitPrice or array_like

See StopExitPrice. Will broadcast.

If provided on per-element basis, gets applied upon entry. If a positive value is provided, used directly as a price, otherwise used as an enumerated value.

stop_exit_type : StopExitType or array_like

See StopExitType. Will broadcast.

If provided on per-element basis, gets applied upon entry.

stop_order_type : OrderType or array_like

Similar to order_type but for stop orders. Will broadcast.

If provided on per-element basis, gets applied upon entry.

stop_limit_delta : float or array_like
Similar to limit_delta but for stop orders. Will broadcast.
upon_stop_update : StopUpdateMode or array_like

See StopUpdateMode. Will broadcast.

Only has effect if accumulation is enabled.

If provided on per-element basis, gets applied upon repeated entry.

upon_adj_stop_conflict : PendingConflictMode or array_like
Conflict mode for stop and user-defined signals of adjacent sign. See PendingConflictMode. Will broadcast.
upon_opp_stop_conflict : PendingConflictMode or array_like
Conflict mode for stop and user-defined signals of opposite sign. See PendingConflictMode. Will broadcast.
delta_format : DeltaFormat or array_like
See DeltaFormat. Will broadcast.
time_delta_format : TimeDeltaFormat or array_like
See TimeDeltaFormat. Will broadcast.
open : array_like of float

See Portfolio.from_orders().

For stop signals, np.nan gets replaced by close.

high : array_like of float

See Portfolio.from_orders().

For stop signals, np.nan replaced by the maximum out of open and close.

low : array_like of float

See Portfolio.from_orders().

For stop signals, np.nan replaced by the minimum out of open and close.

init_cash : InitCashMode, float or array_like
See Portfolio.from_orders().
init_position : float or array_like
See Portfolio.from_orders().
init_price : float or array_like
See Portfolio.from_orders().
cash_deposits : float or array_like
See Portfolio.from_orders().
cash_earnings : float or array_like
See Portfolio.from_orders().
cash_dividends : float or array_like
See Portfolio.from_orders().
cash_sharing : bool
See Portfolio.from_orders().
from_ago : int or array_like

See Portfolio.from_orders().

Take effect only for user-defined signals, not for stop signals.

sim_start : int, datetime_like, or array_like

Simulation start row or index (inclusive).

Can be "auto", which will be substituted by the index of the first signal across long and short entries and long and short exits.

sim_end : int, datetime_like, or array_like

Simulation end row or index (exclusive).

Can be "auto", which will be substituted by the index of the last signal across long and short entries and long and short exits.

call_seq : CallSeqType or array_like
See Portfolio.from_orders().
attach_call_seq : bool
See Portfolio.from_orders().
ffill_val_price : bool
See Portfolio.from_orders().
update_value : bool
See Portfolio.from_orders().
fill_pos_info : bool

fill_pos_info (bool): Whether to fill position record.

Disable this to make simulation faster for simple use cases.

save_state : bool
See Portfolio.from_orders().
save_value : bool
See Portfolio.from_orders().
save_returns : bool
See Portfolio.from_orders().
max_order_records : int
See Portfolio.from_orders().
max_log_records : int
See Portfolio.from_orders().
in_outputs : mapping_like

Mapping with in-output objects. Only for flexible mode.

Will be available via Portfolio.in_outputs as a named tuple.

To substitute Portfolio attributes, provide already broadcasted and grouped objects, for example, by using broadcast_named_args and templates. Also see Portfolio.in_outputs_indexing_func() on how in-output objects are indexed.

When chunking, make sure to provide the chunk taking specification and the merging function. See merge_sim_outs().

Note

When using Numba below 0.54, in_outputs cannot be a mapping, but must be a named tuple defined globally so Numba can introspect its attributes for pickling.

seed : int
See Portfolio.from_orders().
group_by : any
See Portfolio.from_orders().
broadcast_named_args : dict

Dictionary with named arguments to broadcast.

You can then pass argument names wrapped with Rep and this method will substitute them by their corresponding broadcasted objects.

broadcast_kwargs : dict
See Portfolio.from_orders().
template_context : mapping
Context used to substitute templates in arguments.
jitted : any
See Portfolio.from_orders().
chunked : any
See Portfolio.from_orders().
staticized : bool, dict, hashable, or callable

Keyword arguments or task id for staticizing.

If True or dictionary, will be passed as keyword arguments to cut_and_save_func() to save a cacheable version of the simulator to a file. If a hashable or callable, will be used as a task id of an already registered jittable and chunkable simulator. Dictionary allows additional options override and reload to override and reload an already existing module respectively.

bm_close : array_like
See Portfolio.from_orders().
records : array_like
See Portfolio.from_orders().
return_preparer : bool
See Portfolio.from_orders().
return_prep_result : bool
See Portfolio.from_orders().
return_sim_out : bool
See Portfolio.from_orders().
**kwargs
Keyword arguments passed to the Portfolio constructor.

All broadcastable arguments will broadcast using broadcast() but keep original shape to utilize flexible indexing and to save memory.

For defaults, see portfolio. Those defaults are not used to fill NaN values after reindexing: vectorbt uses its own sensible defaults, which are usually NaN for floating arrays and default flags for integer arrays. Use BCO with fill_value to override.

Also see notes and hints for Portfolio.from_orders().

Usage

  • By default, if all signal arrays are None, entries becomes True, which opens a position at the very first tick and does nothing else:
>>> close = pd.Series([1, 2, 3, 4, 5])
>>> pf = vbt.Portfolio.from_signals(close, size=1)
>>> pf.asset_flow
0    1.0
1    0.0
2    0.0
3    0.0
4    0.0
dtype: float64
  • Entry opens long, exit closes long:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1,
...     direction='longonly'
... )
>>> pf.asset_flow
0    1.0
1    0.0
2    0.0
3   -1.0
4    0.0
dtype: float64

>>> # Using direction-aware arrays instead of `direction`
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),  # long_entries
...     exits=pd.Series([False, False, True, True, True]),  # long_exits
...     short_entries=False,
...     short_exits=False,
...     size=1
... )
>>> pf.asset_flow
0    1.0
1    0.0
2    0.0
3   -1.0
4    0.0
dtype: float64

Notice how both short_entries and short_exits are provided as constants - as any other broadcastable argument, they are treated as arrays where each element is False.

  • Entry opens short, exit closes short:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1,
...     direction='shortonly'
... )
>>> pf.asset_flow
0   -1.0
1    0.0
2    0.0
3    1.0
4    0.0
dtype: float64

>>> # Using direction-aware arrays instead of `direction`
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=False,  # long_entries
...     exits=False,  # long_exits
...     short_entries=pd.Series([True, True, True, False, False]),
...     short_exits=pd.Series([False, False, True, True, True]),
...     size=1
... )
>>> pf.asset_flow
0   -1.0
1    0.0
2    0.0
3    1.0
4    0.0
dtype: float64
  • Entry opens long and closes short, exit closes long and opens short:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1,
...     direction='both'
... )
>>> pf.asset_flow
0    1.0
1    0.0
2    0.0
3   -2.0
4    0.0
dtype: float64

>>> # Using direction-aware arrays instead of `direction`
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),  # long_entries
...     exits=False,  # long_exits
...     short_entries=pd.Series([False, False, True, True, True]),
...     short_exits=False,
...     size=1
... )
>>> pf.asset_flow
0    1.0
1    0.0
2    0.0
3   -2.0
4    0.0
dtype: float64
  • More complex signal combinations are best expressed using direction-aware arrays. For example, ignore opposite signals as long as the current position is open:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries      =pd.Series([True, False, False, False, False]),  # long_entries
...     exits        =pd.Series([False, False, True, False, False]),  # long_exits
...     short_entries=pd.Series([False, True, False, True, False]),
...     short_exits  =pd.Series([False, False, False, False, True]),
...     size=1,
...     upon_opposite_entry='ignore'
... )
>>> pf.asset_flow
0    1.0
1    0.0
2   -1.0
3   -1.0
4    1.0
dtype: float64
  • First opposite signal closes the position, second one opens a new position:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1,
...     direction='both',
...     upon_opposite_entry='close'
... )
>>> pf.asset_flow
0    1.0
1    0.0
2    0.0
3   -1.0
4   -1.0
dtype: float64
  • If both long entry and exit signals are True (a signal conflict), choose exit:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1.,
...     direction='longonly',
...     upon_long_conflict='exit')
>>> pf.asset_flow
0    1.0
1    0.0
2   -1.0
3    0.0
4    0.0
dtype: float64
  • If both long entry and short entry signal are True (a direction conflict), choose short:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1.,
...     direction='both',
...     upon_dir_conflict='short')
>>> pf.asset_flow
0    1.0
1    0.0
2   -2.0
3    0.0
4    0.0
dtype: float64

Note

Remember that when direction is set to 'both', entries become long_entries and exits become short_entries, so this becomes a conflict of directions rather than signals.

  • If there are both signal and direction conflicts:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=True,  # long_entries
...     exits=True,  # long_exits
...     short_entries=True,
...     short_exits=True,
...     size=1,
...     upon_long_conflict='entry',
...     upon_short_conflict='entry',
...     upon_dir_conflict='short'
... )
>>> pf.asset_flow
0   -1.0
1    0.0
2    0.0
3    0.0
4    0.0
dtype: float64
  • Turn on accumulation of signals. Entry means long order, exit means short order (acts similar to from_orders):
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1.,
...     direction='both',
...     accumulate=True)
>>> pf.asset_flow
0    1.0
1    1.0
2    0.0
3   -1.0
4   -1.0
dtype: float64
  • Allow increasing a position (of any direction), deny decreasing a position:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     size=1.,
...     direction='both',
...     accumulate='addonly')
>>> pf.asset_flow
0    1.0  << open a long position
1    1.0  << add to the position
2    0.0
3   -3.0  << close and open a short position
4   -1.0  << add to the position
dtype: float64
  • Test multiple parameters via regular broadcasting:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     direction=[list(Direction)],
...     broadcast_kwargs=dict(columns_from=pd.Index(vbt.pf_enums.Direction._fields, name='direction')))
>>> pf.asset_flow
direction  LongOnly  ShortOnly   Both
0             100.0     -100.0  100.0
1               0.0        0.0    0.0
2               0.0        0.0    0.0
3            -100.0       50.0 -200.0
4               0.0        0.0    0.0
  • Test multiple parameters via BCO:
>>> pf = vbt.Portfolio.from_signals(
...     close,
...     entries=pd.Series([True, True, True, False, False]),
...     exits=pd.Series([False, False, True, True, True]),
...     direction=vbt.Param(Direction))
>>> pf.asset_flow
direction  LongOnly  ShortOnly   Both
0             100.0     -100.0  100.0
1               0.0        0.0    0.0
2               0.0        0.0    0.0
3            -100.0       50.0 -200.0
4               0.0        0.0    0.0
  • Set risk/reward ratio by passing trailing stop loss and take profit thresholds:
>>> close = pd.Series([10, 11, 12, 11, 10, 9])
>>> entries = pd.Series([True, False, False, False, False, False])
>>> exits = pd.Series([False, False, False, False, False, True])
>>> pf = vbt.Portfolio.from_signals(
...     close, entries, exits,
...     tsl_stop=0.1, tp_stop=0.2)  # take profit hit
>>> pf.asset_flow
0    10.0
1     0.0
2   -10.0
3     0.0
4     0.0
5     0.0
dtype: float64

>>> pf = vbt.Portfolio.from_signals(
...     close, entries, exits,
...     tsl_stop=0.1, tp_stop=0.3)  # trailing stop loss hit
>>> pf.asset_flow
0    10.0
1     0.0
2     0.0
3     0.0
4   -10.0
5     0.0
dtype: float64

>>> pf = vbt.Portfolio.from_signals(
...     close, entries, exits,
...     tsl_stop=np.inf, tp_stop=np.inf)  # nothing hit, exit as usual
>>> pf.asset_flow
0    10.0
1     0.0
2     0.0
3     0.0
4     0.0
5   -10.0
dtype: float64
  • Test different stop combinations:
>>> pf = vbt.Portfolio.from_signals(
...     close, entries, exits,
...     tsl_stop=vbt.Param([0.1, 0.2]),
...     tp_stop=vbt.Param([0.2, 0.3])
... )
>>> pf.asset_flow
tsl_stop   0.1         0.2
tp_stop    0.2   0.3   0.2   0.3
0         10.0  10.0  10.0  10.0
1          0.0   0.0   0.0   0.0
2        -10.0   0.0 -10.0   0.0
3          0.0   0.0   0.0   0.0
4          0.0 -10.0   0.0   0.0
5          0.0   0.0   0.0 -10.0

This works because pd.Index automatically translates into BCO with product set to True.

  • We can implement our own stop loss or take profit, or adjust the existing one at each time step. Let's implement stepped stop-loss:
>>> @njit
... def adjust_func_nb(c):
...     val_price_now = c.last_val_price[c.col]
...     tsl_init_price = c.last_tsl_info["init_price"][c.col]
...     current_profit = (val_price_now - tsl_init_price) / tsl_init_price
...     if current_profit >= 0.40:
...         c.last_tsl_info["stop"][c.col] = 0.25
...     elif current_profit >= 0.25:
...         c.last_tsl_info["stop"][c.col] = 0.15
...     elif current_profit >= 0.20:
...         c.last_tsl_info["stop"][c.col] = 0.07

>>> close = pd.Series([10, 11, 12, 11, 10])
>>> pf = vbt.Portfolio.from_signals(close, adjust_func_nb=adjust_func_nb)
>>> pf.asset_flow
0    10.0
1     0.0
2     0.0
3   -10.0  # 7% from 12 hit
4    11.16
dtype: float64
  • Sometimes there is a need to provide or transform signals dynamically. For this, we can implement a custom signal function signal_func_nb. For example, let's implement a signal function that takes two numerical arrays - long and short one - and transforms them into 4 direction-aware boolean arrays that vectorbt understands:
>>> @njit
... def signal_func_nb(c, long_num_arr, short_num_arr):
...     long_num = vbt.pf_nb.select_nb(c, long_num_arr)
...     short_num = vbt.pf_nb.select_nb(c, short_num_arr)
...     is_long_entry = long_num > 0
...     is_long_exit = long_num < 0
...     is_short_entry = short_num > 0
...     is_short_exit = short_num < 0
...     return is_long_entry, is_long_exit, is_short_entry, is_short_exit

>>> pf = vbt.Portfolio.from_signals(
...     pd.Series([1, 2, 3, 4, 5]),
...     signal_func_nb=signal_func_nb,
...     signal_args=(vbt.Rep('long_num_arr'), vbt.Rep('short_num_arr')),
...     broadcast_named_args=dict(
...         long_num_arr=pd.Series([1, 0, -1, 0, 0]),
...         short_num_arr=pd.Series([0, 1, 0, 1, -1])
...     ),
...     size=1,
...     upon_opposite_entry='ignore'
... )
>>> pf.asset_flow
0    1.0
1    0.0
2   -1.0
3   -1.0
4    1.0
dtype: float64

Passing both arrays as broadcast_named_args broadcasts them internally as any other array, so we don't have to worry about their dimensions every time we change our data.


get_allocations class method

Portfolio.get_allocations(
    direction='both',
    asset_value=None,
    value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get portfolio allocation series per column.


get_alpha method

Portfolio.get_alpha(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.alpha().


get_annual_returns method

Portfolio.get_annual_returns(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.annual().


get_annualized_return method

Portfolio.get_annualized_return(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.annualized().


get_annualized_volatility method

Portfolio.get_annualized_volatility(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.annualized_volatility().


get_asset_flow class method

Portfolio.get_asset_flow(
    direction='both',
    orders=None,
    init_position=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    wrap_kwargs=None
)

Get asset flow series per column.

Returns the total transacted amount of assets at each time step.


get_asset_pnl class method

Portfolio.get_asset_pnl(
    init_position_value=None,
    asset_value=None,
    cash_flow=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get asset (realized and unrealized) PnL series per column or group.


get_asset_returns class method

Portfolio.get_asset_returns(
    init_position_value=None,
    asset_value=None,
    cash_flow=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get asset return series per column or group.

This type of returns is based solely on cash flows and asset value rather than portfolio value. It ignores passive cash and thus it will return the same numbers irrespective of the amount of cash currently available, even np.inf. The scale of returns is comparable to that of going all in and keeping available cash at zero.


get_asset_value class method

Portfolio.get_asset_value(
    direction='both',
    close=None,
    assets=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get asset value series per column or group.


get_assets class method

Portfolio.get_assets(
    direction='both',
    asset_flow=None,
    init_position=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    wrap_kwargs=None
)

Get asset series per column.

Returns the position at each time step.


get_beta method

Portfolio.get_beta(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.beta().


get_bm_returns class method

Portfolio.get_bm_returns(
    init_value=None,
    cash_deposits=None,
    bm_value=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get benchmark return series per column or group.

Based on Portfolio.bm_close and Portfolio.get_market_returns().


get_bm_value class method

Portfolio.get_bm_value(
    bm_close=None,
    init_value=None,
    cash_deposits=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get benchmark value series per column or group.

Based on Portfolio.bm_close and Portfolio.get_market_value().


get_calmar_ratio method

Portfolio.get_calmar_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.calmar_ratio().


get_capture_ratio method

Portfolio.get_capture_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.capture_ratio().


get_cash class method

Portfolio.get_cash(
    free=False,
    init_cash=None,
    cash_deposits=None,
    cash_flow=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get cash balance series per column or group.

For free, see Portfolio.get_cash_flow().


get_cash_deposits class method

Portfolio.get_cash_deposits(
    cash_deposits_raw=None,
    cash_sharing=None,
    split_shared=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    weights=None,
    keep_flex=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get cash deposit series per column or group.

Set keep_flex to True to keep format suitable for flexible indexing. This consumes less memory.


get_cash_earnings class method

Portfolio.get_cash_earnings(
    cash_earnings_raw=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    weights=None,
    keep_flex=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get earnings in cash series per column or group.

Set keep_flex to True to keep format suitable for flexible indexing. This consumes less memory.


get_cash_flow class method

Portfolio.get_cash_flow(
    free=False,
    orders=None,
    cash_earnings=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    weights=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get cash flow series per column or group.

Use free to return the flow of the free cash, which never goes above the initial level, because an operation always costs money.

Note

Does not include cash deposits, but includes earnings.

Using free yields the same result as during the simulation only when leverage=1. For anything else, prefill the state instead of reconstructing it.


get_cond_value_at_risk method

Portfolio.get_cond_value_at_risk(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.cond_value_at_risk().


get_cumulative_returns method

Portfolio.get_cumulative_returns(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.cumulative().


get_daily_returns method

Portfolio.get_daily_returns(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.daily().


get_deflated_sharpe_ratio method

Portfolio.get_deflated_sharpe_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.deflated_sharpe_ratio().


get_down_capture_ratio method

Portfolio.get_down_capture_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.down_capture_ratio().


get_downside_risk method

Portfolio.get_downside_risk(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.downside_risk().


get_drawdown method

Portfolio.get_drawdown(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.drawdown().


get_drawdowns class method

Portfolio.get_drawdowns(
    value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    drawdowns_cls=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get drawdown records from Portfolio.get_value().

See Drawdowns.


get_entry_trades class method

Portfolio.get_entry_trades(
    orders=None,
    init_position=None,
    init_price=None,
    entry_trades_cls=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get entry trade records.

See EntryTrades.


get_exit_trades class method

Portfolio.get_exit_trades(
    orders=None,
    init_position=None,
    init_price=None,
    exit_trades_cls=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get exit trade records.

See ExitTrades.


get_filled_bm_close class method

Portfolio.get_filled_bm_close(
    bm_close=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    wrap_kwargs=None
)

Get forward and backward filled benchmark closing price.

See fbfill_nb().


get_filled_close class method

Portfolio.get_filled_close(
    close=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    wrap_kwargs=None
)

Get forward and backward filled closing price.

See fbfill_nb().


get_final_value class method

Portfolio.get_final_value(
    input_value=None,
    total_profit=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get total profit per column or group.


get_gross_exposure class method

Portfolio.get_gross_exposure(
    direction='both',
    asset_value=None,
    value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get gross exposure.

Note

When both directions, asset_value must include the addition of the absolute long-only and short-only asset values.


get_in_output method

Portfolio.get_in_output(
    field,
    wrapper=None,
    group_by=None,
    **kwargs
)

Find and wrap an in-output object matching the field.

If the field can be found in the attributes of this Portfolio instance, reads the attribute's options to get requirements for the type and layout of the in-output object.

For each field in Portfolio.in_outputs, resolves the field's options by parsing its name with Portfolio.parse_field_options() and also looks for options in Portfolio.in_output_config. If field is not in Portfolio.in_outputs, searches for the field in aliases and options. In such case, to narrow down the number of candidates, options are additionally matched against the requirements using Portfolio.matches_field_options(). Finally, the matched in-output object is wrapped using Portfolio.wrap_obj().


get_information_ratio method

Portfolio.get_information_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.information_ratio().


get_init_cash class method

Portfolio.get_init_cash(
    init_cash_raw=None,
    cash_deposits=None,
    free_cash_flow=None,
    cash_sharing=None,
    split_shared=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    weights=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get initial amount of cash per column or group.


get_init_position class method

Portfolio.get_init_position(
    init_position_raw=None,
    weights=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None,
    keep_flex=False
)

Get initial position per column.


get_init_position_value class method

Portfolio.get_init_position_value(
    init_position=None,
    init_price=None,
    jitted=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get initial position value per column.


get_init_price class method

Portfolio.get_init_price(
    init_price_raw=None,
    wrapper=None,
    wrap_kwargs=None,
    keep_flex=False
)

Get initial price per column.


get_init_value class method

Portfolio.get_init_value(
    init_position_value=None,
    init_cash=None,
    split_shared=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get initial value per column or group.

Includes initial cash and the value of initial position.


get_input_value class method

Portfolio.get_input_value(
    total_cash_deposits=None,
    init_value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get total input value per column or group.

Includes initial value and any cash deposited at any point in time.


get_logs class method

Portfolio.get_logs(
    log_records=None,
    open=None,
    high=None,
    low=None,
    close=None,
    logs_cls=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get log records.

See Logs.


get_long_view method

Portfolio.get_long_view(
    orders=None,
    init_position=None,
    init_price=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    **kwargs
)

Get view of portfolio with long positions only.


get_market_returns class method

Portfolio.get_market_returns(
    init_value=None,
    cash_deposits=None,
    cash_deposits_as_input=None,
    market_value=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get market return series per column or group.


get_market_value class method

Portfolio.get_market_value(
    close=None,
    init_value=None,
    cash_deposits=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get market value series per column or group.

If grouped, evenly distributes the initial cash among assets in the group.

Note

Does not take into account fees and slippage. For this, create a separate portfolio.


get_max_drawdown method

Portfolio.get_max_drawdown(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.max_drawdown().


get_net_exposure class method

Portfolio.get_net_exposure(
    long_exposure=None,
    short_exposure=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get net exposure.


get_omega_ratio method

Portfolio.get_omega_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.omega_ratio().


get_orders class method

Portfolio.get_orders(
    order_records=None,
    open=None,
    high=None,
    low=None,
    close=None,
    orders_cls=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    weights=None,
    jitted=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get order records.

See Orders.


get_position_coverage class method

Portfolio.get_position_coverage(
    direction='both',
    assets=None,
    granular_groups=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get position coverage per column or group.

Position coverage is the number of time steps in the market divided by the total number of time steps.


get_position_entry_price class method

Portfolio.get_position_entry_price(
    orders=None,
    init_position=None,
    init_price=None,
    fill_closed_position=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    wrap_kwargs=None
)

Get the position's entry price at each time step.


get_position_exit_price class method

Portfolio.get_position_exit_price(
    orders=None,
    init_position=None,
    init_price=None,
    fill_closed_position=False,
    fill_exit_price=True,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    wrap_kwargs=None
)

Get the position's exit price at each time step.


get_position_mask class method

Portfolio.get_position_mask(
    direction='both',
    assets=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get position mask per column or group.

An element is True if there is a position at the given time step.


get_positions class method

Portfolio.get_positions(
    trades=None,
    positions_cls=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get position records.

See Positions.


get_prob_sharpe_ratio method

Portfolio.get_prob_sharpe_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.prob_sharpe_ratio().


get_qs class method

Portfolio.get_qs(
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get quantstats adapter of type QSAdapter.

**kwargs are passed to the adapter constructor.


get_returns class method

Portfolio.get_returns(
    init_value=None,
    cash_deposits=None,
    cash_deposits_as_input=None,
    value=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get return series per column or group based on portfolio value.


get_returns_acc class method

Portfolio.get_returns_acc(
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get returns accessor of type ReturnsAccessor.

Hint

You can find most methods of this accessor as (cacheable) attributes of this portfolio.


get_sharpe_ratio method

Portfolio.get_sharpe_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.sharpe_ratio().


get_sharpe_ratio_std method

Portfolio.get_sharpe_ratio_std(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.sharpe_ratio_std().


get_short_view method

Portfolio.get_short_view(
    orders=None,
    init_position=None,
    init_price=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    **kwargs
)

Get view of portfolio with short positions only.


get_sortino_ratio method

Portfolio.get_sortino_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.sortino_ratio().


get_tail_ratio method

Portfolio.get_tail_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.tail_ratio().


get_total_cash_deposits class method

Portfolio.get_total_cash_deposits(
    cash_deposits_raw=None,
    cash_sharing=None,
    split_shared=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    weights=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get total cash deposit series per column or group.


get_total_cash_earnings class method

Portfolio.get_total_cash_earnings(
    cash_earnings_raw=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    weights=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get total cash earning series per column or group.


get_total_market_return class method

Portfolio.get_total_market_return(
    input_value=None,
    market_value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get total market return.


get_total_profit class method

Portfolio.get_total_profit(
    close=None,
    orders=None,
    init_position=None,
    init_price=None,
    cash_earnings=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get total profit per column or group.

Calculated directly from order records (fast).


get_total_return class method

Portfolio.get_total_return(
    input_value=None,
    total_profit=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get total return per column or group.


get_trade_history class method

Portfolio.get_trade_history(
    orders=None,
    entry_trades=None,
    exit_trades=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get order history merged with entry and exit trades as a readable DataFrame.

Note

The P&L and return aggregated across the DataFrame may not match the actual total P&L and return, as this DataFrame annotates entry and exit orders with the performance relative to their respective trade types. To obtain accurate total statistics, aggregate only the statistics of either trade type. Additionally, entry orders include open statistics, whereas exit orders do not.


get_trades method

Portfolio.get_trades(
    trades_type=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    wrapper=None,
    group_by=None,
    **kwargs
)

Get trade/position records depending upon Portfolio.trades_type.


get_up_capture_ratio method

Portfolio.get_up_capture_ratio(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.up_capture_ratio().


get_value class method

Portfolio.get_value(
    cash=None,
    asset_value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    wrap_kwargs=None
)

Get portfolio value series per column or group.

By default, will generate portfolio value for each asset based on cash flows and thus independent of other assets, with the initial cash balance and position being that of the entire group. Useful for generating returns and comparing assets within the same group.


get_value_at_risk method

Portfolio.get_value_at_risk(
    *,
    returns=None,
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    freq=None,
    year_freq=None,
    defaults=None,
    jitted=None,
    chunked=None,
    wrapper=None,
    group_by=None,
    **kwargs
)

See ReturnsAccessor.value_at_risk().


get_weights class method

Portfolio.get_weights(
    weights=None,
    wrapper=None
)

Get asset weights.


gross_exposure property

Portfolio.get_gross_exposure() with default arguments.


high property

High price of each bar.


high_flex property

Portfolio.high in a format suitable for flexible indexing.


in_output_config class variable

In-output config of Portfolio.

HybridConfig(
    cash=dict(
        grouping='cash_sharing'
    ),
    position=dict(
        grouping='columns'
    ),
    debt=dict(
        grouping='columns'
    ),
    locked_cash=dict(
        grouping='columns'
    ),
    free_cash=dict(
        grouping='cash_sharing'
    ),
    returns=dict(
        grouping='cash_sharing'
    )
)

Returns Portfolio._in_output_config, which gets (hybrid-) copied upon creation of each instance. Thus, changing this config won't affect the class.

To change in_outputs, you can either change the config in-place, override this property, or overwrite the instance variable Portfolio._in_output_config.


in_outputs property

Named tuple with in-output objects.


in_outputs_indexing_func method

Portfolio.in_outputs_indexing_func(
    wrapper_meta,
    **kwargs
)

Perform indexing on Portfolio.in_outputs.

If the field can be found in the attributes of this Portfolio instance, reads the attribute's options to get requirements for the type and layout of the in-output object.

For each field in Portfolio.in_outputs, resolves the field's options by parsing its name with Portfolio.parse_field_options() and also looks for options in Portfolio.in_output_config. Performs indexing on the in-output object using Portfolio.index_obj().


index_obj method

Portfolio.index_obj(
    obj,
    wrapper_meta,
    obj_name=None,
    grouping='columns_or_groups',
    obj_type=None,
    wrapper=None,
    group_by=None,
    indexing_func=None,
    force_indexing=False,
    silence_warnings=False,
    **kwargs
)

Perform indexing on an object.

indexing_func must take the portfolio, all the arguments passed to this method, and **kwargs. If you don't need any of the arguments, make indexing_func accept them as **kwargs.

If the object is None, boolean, or empty, returns as-is.


indexing_func method

Portfolio.indexing_func(
    *args,
    in_output_kwargs=None,
    wrapper_meta=None,
    **kwargs
)

Perform indexing on Portfolio.

In-outputs are indexed using Portfolio.in_outputs_indexing_func().


information_ratio property

Portfolio.get_information_ratio() with default arguments.


init_cash property

Portfolio.get_init_cash() with default arguments.


init_position property

Portfolio.get_init_position() with default arguments.


init_position_value property

Portfolio.get_init_position_value() with default arguments.


init_price property

Portfolio.get_init_price() with default arguments.


init_value property

Portfolio.get_init_value() with default arguments.


input_value property

Portfolio.get_input_value() with default arguments.


locked_cash property

Portfolio.None with default arguments.


log_records property

A structured NumPy array of log records.


log_returns property

Portfolio.get_returns() with arguments {'log_returns': True}.


logs property

Portfolio.get_logs() with default arguments.


logs_cls property

Class for wrapping log records.


long_allocations property

Portfolio.get_allocations() with arguments {'direction': 'longonly'}.


long_asset_flow property

Portfolio.get_asset_flow() with arguments {'direction': 'longonly'}.


long_asset_value property

Portfolio.get_asset_value() with arguments {'direction': 'longonly'}.


long_assets property

Portfolio.get_assets() with arguments {'direction': 'longonly'}.


long_gross_exposure property

Portfolio.get_gross_exposure() with arguments {'direction': 'longonly'}.


long_position_coverage property

Portfolio.get_position_coverage() with arguments {'direction': 'longonly'}.


long_position_mask property

Portfolio.get_position_mask() with arguments {'direction': 'longonly'}.


long_view property

Portfolio.get_long_view() with default arguments.


low property

Low price of each bar.


low_flex property

Portfolio.low in a format suitable for flexible indexing.


market_returns property

Portfolio.get_market_returns() with default arguments.


market_value property

Portfolio.get_market_value() with default arguments.


matches_field_options method

Portfolio.matches_field_options(
    options,
    obj_type=None,
    group_by_aware=True,
    wrapper=None,
    group_by=None
)

Return whether options of a field match the requirements.

Requirements include the type of the object (array, reduced array, records), the grouping of the object (1/2 dimensions, group/column-wise layout). The current grouping and cash sharing of this portfolio object are also taken into account.

When an option is not in options, it's automatically marked as matching.


max_drawdown property

Portfolio.get_max_drawdown() with default arguments.


metrics class variable

Metrics supported by Portfolio.

HybridConfig(
    start_index=dict(
        title='Start Index',
        calc_func='sim_start_index',
        tags='wrapper'
    ),
    end_index=dict(
        title='End Index',
        calc_func='sim_end_index',
        tags='wrapper'
    ),
    total_duration=dict(
        title='Total Duration',
        calc_func='sim_duration',
        apply_to_timedelta=True,
        tags='wrapper'
    ),
    start_value=dict(
        title='Start Value',
        calc_func='init_value',
        tags='portfolio'
    ),
    min_value=dict(
        title='Min Value',
        calc_func='value.vbt.min',
        tags='portfolio'
    ),
    max_value=dict(
        title='Max Value',
        calc_func='value.vbt.max',
        tags='portfolio'
    ),
    end_value=dict(
        title='End Value',
        calc_func='final_value',
        tags='portfolio'
    ),
    cash_deposits=dict(
        title='Total Cash Deposits',
        calc_func='total_cash_deposits',
        check_has_cash_deposits=True,
        tags='portfolio'
    ),
    cash_earnings=dict(
        title='Total Cash Earnings',
        calc_func='total_cash_earnings',
        check_has_cash_earnings=True,
        tags='portfolio'
    ),
    total_return=dict(
        title='Total Return [%]',
        calc_func='total_return',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c2160>,
        tags='portfolio'
    ),
    bm_return=dict(
        title='Benchmark Return [%]',
        calc_func='bm_returns.vbt.returns.total',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c2200>,
        check_has_bm_returns=True,
        tags='portfolio'
    ),
    total_time_exposure=dict(
        title='Position Coverage [%]',
        calc_func='position_coverage',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c22a0>,
        tags='portfolio'
    ),
    max_gross_exposure=dict(
        title='Max Gross Exposure [%]',
        calc_func='gross_exposure.vbt.max',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c2340>,
        tags='portfolio'
    ),
    max_dd=dict(
        title='Max Drawdown [%]',
        calc_func='drawdowns.max_drawdown',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c23e0>,
        tags=[
            'portfolio',
            'drawdowns'
        ]
    ),
    max_dd_duration=dict(
        title='Max Drawdown Duration',
        calc_func='drawdowns.max_duration',
        fill_wrap_kwargs=True,
        tags=[
            'portfolio',
            'drawdowns',
            'duration'
        ]
    ),
    total_orders=dict(
        title='Total Orders',
        calc_func='orders.count',
        tags=[
            'portfolio',
            'orders'
        ]
    ),
    total_fees_paid=dict(
        title='Total Fees Paid',
        calc_func='orders.fees.sum',
        tags=[
            'portfolio',
            'orders'
        ]
    ),
    total_trades=dict(
        title='Total Trades',
        calc_func='trades.count',
        incl_open=True,
        tags=[
            'portfolio',
            'trades'
        ]
    ),
    win_rate=dict(
        title='Win Rate [%]',
        calc_func='trades.win_rate',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c2480>,
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags]",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    best_trade=dict(
        title='Best Trade [%]',
        calc_func='trades.returns.max',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c2520>,
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags]",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    worst_trade=dict(
        title='Worst Trade [%]',
        calc_func='trades.returns.min',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c25c0>,
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags]",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    avg_winning_trade=dict(
        title='Avg Winning Trade [%]',
        calc_func='trades.winning.returns.mean',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c2660>,
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags, 'winning']",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    avg_losing_trade=dict(
        title='Avg Losing Trade [%]',
        calc_func='trades.losing.returns.mean',
        post_calc_func=<function Portfolio.<lambda> at 0x1648c2700>,
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags, 'losing']",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    avg_winning_trade_duration=dict(
        title='Avg Winning Trade Duration',
        calc_func='trades.winning.duration.mean',
        apply_to_timedelta=True,
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags, 'winning', 'duration']",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    avg_losing_trade_duration=dict(
        title='Avg Losing Trade Duration',
        calc_func='trades.losing.duration.mean',
        apply_to_timedelta=True,
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags, 'losing', 'duration']",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    profit_factor=dict(
        title='Profit Factor',
        calc_func='trades.profit_factor',
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags]",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    expectancy=dict(
        title='Expectancy',
        calc_func='trades.expectancy',
        tags=RepEval(
            template="['portfolio', 'trades', *incl_open_tags]",
            context=None,
            strict=None,
            context_merge_kwargs=None,
            eval_id=None
        )
    ),
    sharpe_ratio=dict(
        title='Sharpe Ratio',
        calc_func='returns_acc.sharpe_ratio',
        check_has_freq=True,
        check_has_year_freq=True,
        tags=[
            'portfolio',
            'returns'
        ]
    ),
    calmar_ratio=dict(
        title='Calmar Ratio',
        calc_func='returns_acc.calmar_ratio',
        check_has_freq=True,
        check_has_year_freq=True,
        tags=[
            'portfolio',
            'returns'
        ]
    ),
    omega_ratio=dict(
        title='Omega Ratio',
        calc_func='returns_acc.omega_ratio',
        check_has_freq=True,
        check_has_year_freq=True,
        tags=[
            'portfolio',
            'returns'
        ]
    ),
    sortino_ratio=dict(
        title='Sortino Ratio',
        calc_func='returns_acc.sortino_ratio',
        check_has_freq=True,
        check_has_year_freq=True,
        tags=[
            'portfolio',
            'returns'
        ]
    )
)

Returns Portfolio._metrics, which gets (hybrid-) copied upon creation of each instance. Thus, changing this config won't affect the class.

To change metrics, you can either change the config in-place, override this property, or overwrite the instance variable Portfolio._metrics.


net_exposure property

Portfolio.get_net_exposure() with default arguments.


omega_ratio property

Portfolio.get_omega_ratio() with default arguments.


open property

Open price of each bar.


open_flex property

Portfolio.open in a format suitable for flexible indexing.


order_records property

A structured NumPy array of order records.


orders property

Portfolio.get_orders() with default arguments.


orders_cls property

Class for wrapping order records.


override_in_output_config_doc class method

Portfolio.override_in_output_config_doc(
    __pdoc__,
    source_cls=None
)

Call this method on each subclass that overrides Portfolio.in_output_config.


parse_field_options class method

Portfolio.parse_field_options(
    field
)

Parse options based on the name of a field.

Returns a dictionary with the parsed grouping, object type, and cleaned field name.

Grouping is parsed by looking for the following suffixes:

  • '_cs': per group if grouped with cash sharing, otherwise per column
  • '_pcg': per group if grouped, otherwise per column
  • '_pg': per group
  • '_pc': per column
  • '_records': records

Object type is parsed by looking for the following suffixes:

  • '_2d': element per timestamp and column or group (time series)
  • '_1d': element per column or group (reduced time series)

Those substrings are then removed to produce a clean field name.


plot method

PlotsBuilderMixin.plots(
    subplots=None,
    tags=None,
    column=None,
    group_by=None,
    silence_warnings=None,
    template_context=None,
    settings=None,
    filters=None,
    subplot_settings=None,
    show_titles=None,
    hide_id_labels=None,
    group_id_labels=None,
    make_subplots_kwargs=None,
    **layout_kwargs
)

See PlotsBuilderMixin.plots().


plot_allocations class method

Portfolio.plot_allocations(
    column=None,
    allocations=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    line_shape='hv',
    line_visible=True,
    colorway='Vivid',
    xref=None,
    yref=None,
    **kwargs
)

Plot one group of allocations.


plot_asset_flow class method

Portfolio.plot_asset_flow(
    column=None,
    direction='both',
    asset_flow=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    line_shape='hv',
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column of asset flow.

**kwargs are passed to GenericAccessor.plot().


plot_asset_value class method

Portfolio.plot_asset_value(
    column=None,
    direction='both',
    asset_value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    line_shape='hv',
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column or group of asset value.

**kwargs are passed to GenericAccessor.plot_against().


plot_assets class method

Portfolio.plot_assets(
    column=None,
    direction='both',
    assets=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    line_shape='hv',
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column of assets.

**kwargs are passed to GenericAccessor.plot_against().


plot_cash class method

Portfolio.plot_cash(
    column=None,
    free=False,
    init_cash=None,
    cash=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    line_shape='hv',
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column or group of cash balance.

**kwargs are passed to GenericAccessor.plot_against().


plot_cash_flow class method

Portfolio.plot_cash_flow(
    column=None,
    free=False,
    cash_flow=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    line_shape='hv',
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column or group of cash flow.

**kwargs are passed to GenericAccessor.plot().


plot_cum_returns class method

Portfolio.plot_cum_returns(
    column=None,
    returns_acc=None,
    use_asset_returns=False,
    bm_returns=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    pct_scale=False,
    **kwargs
)

Plot one column or group of cumulative returns.

If bm_returns is None, will use Portfolio.get_market_returns().

**kwargs are passed to ReturnsAccessor.plot_cumulative().


plot_drawdowns class method

Portfolio.plot_drawdowns(
    column=None,
    drawdowns=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    xref='x',
    yref='y',
    **kwargs
)

Plot one column or group of drawdowns.

**kwargs are passed to Drawdowns.plot().


plot_gross_exposure class method

Portfolio.plot_gross_exposure(
    column=None,
    direction='both',
    gross_exposure=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    line_shape='hv',
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column or group of gross exposure.

**kwargs are passed to GenericAccessor.plot_against().


plot_net_exposure class method

Portfolio.plot_net_exposure(
    column=None,
    net_exposure=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    line_shape='hv',
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column or group of net exposure.

**kwargs are passed to GenericAccessor.plot_against().


plot_orders class method

Portfolio.plot_orders(
    column=None,
    orders=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    xref=None,
    yref=None,
    **kwargs
)

Plot one column of orders.

**kwargs are passed to vectorbtpro.generic.orders.Orders.plot.


plot_trade_pnl class method

Portfolio.plot_trade_pnl(
    column=None,
    trades=None,
    trades_type=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    pct_scale=False,
    xref='x',
    yref='y',
    **kwargs
)

Plot one column of trade P&L.

**kwargs are passed to Trades.plot_pnl().


plot_trade_signals class method

Portfolio.plot_trade_signals(
    column=None,
    entry_trades=None,
    exit_trades=None,
    positions=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    plot_positions='zones',
    long_entry_trace_kwargs=None,
    short_entry_trace_kwargs=None,
    long_exit_trace_kwargs=None,
    short_exit_trace_kwargs=None,
    long_shape_kwargs=None,
    short_shape_kwargs=None,
    add_trace_kwargs=None,
    fig=None,
    xref=None,
    yref=None,
    **kwargs
)

Plot one column or group of trade signals.

Markers and shapes are colored by trade direction (green = long, red = short).


plot_trades class method

Portfolio.plot_trades(
    column=None,
    trades=None,
    trades_type=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    xref='x',
    yref='y',
    **kwargs
)

Plot one column of trades.

**kwargs are passed to Trades.plot().


plot_underwater class method

Portfolio.plot_underwater(
    column=None,
    init_value=None,
    returns_acc=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    pct_scale=True,
    xref='x',
    yref='y',
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column or group of underwater.

**kwargs are passed to GenericAccessor.plot().


plot_value class method

Portfolio.plot_value(
    column=None,
    init_value=None,
    value=None,
    sim_start=None,
    sim_end=None,
    rec_sim_range=False,
    fit_sim_range=True,
    wrapper=None,
    group_by=None,
    xref=None,
    yref=None,
    hline_shape_kwargs=None,
    **kwargs
)

Plot one column or group of value.

**kwargs are passed to GenericAccessor.plot_against().


plots_defaults property

Defaults for PlotsBuilderMixin.plots().

Merges PlotsBuilderMixin.plots_defaults and plots from portfolio.


position property

Portfolio.get_assets() with default arguments.


position_coverage property

Portfolio.get_position_coverage() with default arguments.


position_entry_price property

Portfolio.get_position_entry_price() with default arguments.


position_exit_price property

Portfolio.get_position_exit_price() with default arguments.


position_mask property

Portfolio.get_position_mask() with default arguments.


positions property

Portfolio.get_positions() with default arguments.


positions_cls property

Class for wrapping position records.


post_resolve_attr method

Portfolio.post_resolve_attr(
    attr,
    out,
    final_kwargs=None
)

Post-process an object after resolution.

Uses the following keys:

  • incl_open: Whether to include open trades/positions when resolving an argument that is an instance of Trades.

pre_resolve_attr method

Portfolio.pre_resolve_attr(
    attr,
    final_kwargs=None
)

Pre-process an attribute before resolution.

Uses the following keys:

  • use_asset_returns: Whether to use Portfolio.get_asset_returns() when resolving returns argument.
  • trades_type: Which trade type to use when resolving trades argument.

prob_sharpe_ratio property

Portfolio.get_prob_sharpe_ratio() with default arguments.


qs property

Portfolio.get_qs() with default arguments.


regroup method

Portfolio.regroup(
    group_by,
    **kwargs
)

Regroup this object.

See Wrapping.regroup().

Note

All cached objects will be lost.


resample method

Portfolio.resample(
    *args,
    ffill_close=False,
    fbfill_close=False,
    in_output_kwargs=None,
    wrapper_meta=None,
    **kwargs
)

Resample the Portfolio instance.

Warning

Downsampling is associated with information loss:

  • Cash deposits and earnings are assumed to be added/removed at the beginning of each time step. Imagine depositing $100 and using them up in the same bar, and then depositing another $100 and using them up. Downsampling both bars into a single bar will aggregate cash deposits and earnings, and put both of them at the beginning of the new bar, even though the second deposit was added later in time.
  • Market/benchmark returns are computed by applying the initial value on the close price of the first bar and by tracking the price change to simulate holding. Moving the close price of the first bar further into the future will affect this computation and almost certainly produce a different market value and returns. To mitigate this, make sure to downsample to an index with the first bar containing only the first bar from the origin timeframe.

resample_in_outputs method

Portfolio.resample_in_outputs(
    resampler,
    **kwargs
)

Resample Portfolio.in_outputs.

If the field can be found in the attributes of this Portfolio instance, reads the attribute's options to get requirements for the type and layout of the in-output object.

For each field in Portfolio.in_outputs, resolves the field's options by parsing its name with Portfolio.parse_field_options() and also looks for options in Portfolio.in_output_config. Performs indexing on the in-output object using Portfolio.resample_obj().


resample_obj method

Portfolio.resample_obj(
    obj,
    resampler,
    obj_name=None,
    obj_type=None,
    wrapper=None,
    group_by=None,
    resample_func=None,
    resample_kwargs=None,
    force_resampling=False,
    silence_warnings=False,
    **kwargs
)

Resample an object.

resample_func must take the portfolio, obj, resampler, all the arguments passed to this method, and **kwargs. If you don't need any of the arguments, make resample_func accept them as **kwargs. If resample_func is a string, will use it as reduce_func_nb in GenericAccessor.resample_apply(). Default is 'last'.

If the object is None, boolean, or empty, returns as-is.


resolve_shortcut_attr method

Portfolio.resolve_shortcut_attr(
    attr_name,
    *args,
    **kwargs
)

Resolve an attribute that may have shortcut properties.

If attr_name has a prefix get_, checks whether the respective shortcut property can be called. This way, complex call hierarchies can utilize cacheable properties.


returns property

Portfolio.get_returns() with default arguments.


returns_acc property

Portfolio.get_returns_acc() with default arguments.


returns_acc_defaults property

Defaults for ReturnsAccessor.


returns_stats method

Portfolio.returns_stats(
    use_asset_returns=False,
    bm_returns=None,
    log_returns=False,
    daily_returns=False,
    freq=None,
    year_freq=None,
    defaults=None,
    chunked=None,
    group_by=None,
    **kwargs
)

Compute various statistics on returns of this portfolio.

See Portfolio.returns_acc and ReturnsAccessor.metrics.

kwargs will be passed to StatsBuilderMixin.stats() method. If bm_returns is not set, uses Portfolio.get_market_returns().


row_stack class method

Portfolio.row_stack(
    *objs,
    wrapper_kwargs=None,
    group_by=None,
    combine_init_cash=False,
    combine_init_position=False,
    combine_init_price=False,
    **kwargs
)

Stack multiple Portfolio instances along rows.

Uses ArrayWrapper.row_stack() to stack the wrappers.

Cash sharing must be the same among all objects.

Close, benchmark close, cash deposits, cash earnings, call sequence, and other two-dimensional arrays are stacked using ArrayWrapper.row_stack_arrs(). In-outputs are stacked using Portfolio.row_stack_in_outputs(). Records are stacked using Records.row_stack_records_arrs().

If the initial cash of each object is one of the options in InitCashMode, it will be retained for the resulting object. Once any of the objects has the initial cash listed as an absolute amount or an array, the initial cash of the first object will be copied over to the final object, while the initial cash of all other objects will be resolved and used as cash deposits, unless they all are zero. Set combine_init_cash to True to simply sum all initial cash arrays.

If only the first object has an initial position greater than zero, it will be copied over to the final object. Otherwise, an error will be thrown, unless combine_init_position is enabled to sum all initial position arrays. The same goes for the initial price, which becomes a candidate for stacking only if any of the arrays are not NaN.

Note

When possible, avoid using initial position and price in objects to be stacked: there is currently no way of injecting them in the correct order, while simply taking the sum or weighted average may distort the reality since they weren't available prior to the actual simulation.


row_stack_in_outputs class method

Portfolio.row_stack_in_outputs(
    *objs,
    **kwargs
)

Stack Portfolio.in_outputs along rows.

All in-output tuples must be either None or have the same fields.

If the field can be found in the attributes of this Portfolio instance, reads the attribute's options to get requirements for the type and layout of the in-output object.

For each field in Portfolio.in_outputs, resolves the field's options by parsing its name with Portfolio.parse_field_options() and also looks for options in Portfolio.in_output_config. Performs stacking on the in-output objects of the same field using Portfolio.row_stack_objs().


row_stack_objs class method

Portfolio.row_stack_objs(
    objs,
    wrappers,
    grouping='columns_or_groups',
    obj_name=None,
    obj_type=None,
    wrapper=None,
    cash_sharing=False,
    row_stack_func=None,
    **kwargs
)

Stack (two-dimensional) objects along rows.

row_stack_func must take the portfolio class, and all the arguments passed to this method. If you don't need any of the arguments, make row_stack_func accept them as **kwargs.

If all the objects are None, boolean, or empty, returns the first one.


sharpe_ratio property

Portfolio.get_sharpe_ratio() with default arguments.


sharpe_ratio_std property

Portfolio.get_sharpe_ratio_std() with default arguments.


short_allocations property

Portfolio.get_allocations() with arguments {'direction': 'shortonly'}.


short_asset_flow property

Portfolio.get_asset_flow() with arguments {'direction': 'shortonly'}.


short_asset_value property

Portfolio.get_asset_value() with arguments {'direction': 'shortonly'}.


short_assets property

Portfolio.get_assets() with arguments {'direction': 'shortonly'}.


short_gross_exposure property

Portfolio.get_gross_exposure() with arguments {'direction': 'shortonly'}.


short_position_coverage property

Portfolio.get_position_coverage() with arguments {'direction': 'shortonly'}.


short_position_mask property

Portfolio.get_position_mask() with arguments {'direction': 'shortonly'}.


short_view property

Portfolio.get_short_view() with default arguments.


sortino_ratio property

Portfolio.get_sortino_ratio() with default arguments.


stats_defaults property

Defaults for StatsBuilderMixin.stats().

Merges StatsBuilderMixin.stats_defaults and stats from portfolio.


subplots class variable

Subplots supported by Portfolio.

HybridConfig(
    orders=dict(
        title='Orders',
        yaxis_kwargs=dict(
            title='Price'
        ),
        check_is_not_grouped=True,
        plot_func='plot_orders',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'orders'
        ]
    ),
    trades=dict(
        title='Trades',
        yaxis_kwargs=dict(
            title='Price'
        ),
        check_is_not_grouped=True,
        plot_func='plot_trades',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'trades'
        ]
    ),
    trade_pnl=dict(
        title='Trade PnL',
        yaxis_kwargs=dict(
            title='PnL'
        ),
        check_is_not_grouped=True,
        plot_func='plot_trade_pnl',
        pct_scale=True,
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'trades'
        ]
    ),
    trade_signals=dict(
        title='Trade Signals',
        yaxis_kwargs=dict(
            title='Price'
        ),
        check_is_not_grouped=True,
        plot_func='plot_trade_signals',
        tags=[
            'portfolio',
            'trades'
        ]
    ),
    cash_flow=dict(
        title='Cash Flow',
        yaxis_kwargs=dict(
            title='Amount'
        ),
        plot_func='plot_cash_flow',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'cash'
        ]
    ),
    cash=dict(
        title='Cash',
        yaxis_kwargs=dict(
            title='Amount'
        ),
        plot_func='plot_cash',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'cash'
        ]
    ),
    asset_flow=dict(
        title='Asset Flow',
        yaxis_kwargs=dict(
            title='Amount'
        ),
        check_is_not_grouped=True,
        plot_func='plot_asset_flow',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'assets'
        ]
    ),
    assets=dict(
        title='Assets',
        yaxis_kwargs=dict(
            title='Amount'
        ),
        check_is_not_grouped=True,
        plot_func='plot_assets',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'assets'
        ]
    ),
    asset_value=dict(
        title='Asset Value',
        yaxis_kwargs=dict(
            title='Value'
        ),
        plot_func='plot_asset_value',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'assets',
            'value'
        ]
    ),
    value=dict(
        title='Value',
        yaxis_kwargs=dict(
            title='Value'
        ),
        plot_func='plot_value',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'value'
        ]
    ),
    cum_returns=dict(
        title='Cumulative Returns',
        yaxis_kwargs=dict(
            title='Cumulative return'
        ),
        plot_func='plot_cum_returns',
        pass_hline_shape_kwargs=True,
        pass_add_trace_kwargs=True,
        pass_xref=True,
        pass_yref=True,
        tags=[
            'portfolio',
            'returns'
        ]
    ),
    drawdowns=dict(
        title='Drawdowns',
        yaxis_kwargs=dict(
            title='Value'
        ),
        plot_func='plot_drawdowns',
        pass_add_trace_kwargs=True,
        pass_xref=True,
        pass_yref=True,
        tags=[
            'portfolio',
            'value',
            'drawdowns'
        ]
    ),
    underwater=dict(
        title='Underwater',
        yaxis_kwargs=dict(
            title='Drawdown'
        ),
        plot_func='plot_underwater',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'value',
            'drawdowns'
        ]
    ),
    gross_exposure=dict(
        title='Gross Exposure',
        yaxis_kwargs=dict(
            title='Exposure'
        ),
        plot_func='plot_gross_exposure',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'exposure'
        ]
    ),
    net_exposure=dict(
        title='Net Exposure',
        yaxis_kwargs=dict(
            title='Exposure'
        ),
        plot_func='plot_net_exposure',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'exposure'
        ]
    ),
    allocations=dict(
        title='Allocations',
        yaxis_kwargs=dict(
            title='Allocation'
        ),
        plot_func='plot_allocations',
        pass_add_trace_kwargs=True,
        tags=[
            'portfolio',
            'allocations'
        ]
    )
)

Returns Portfolio._subplots, which gets (hybrid-) copied upon creation of each instance. Thus, changing this config won't affect the class.

To change subplots, you can either change the config in-place, override this property, or overwrite the instance variable Portfolio._subplots.


tail_ratio property

Portfolio.get_tail_ratio() with default arguments.


total_cash_deposits property

Portfolio.get_total_cash_deposits() with default arguments.


total_cash_earnings property

Portfolio.get_total_cash_earnings() with default arguments.


total_market_return property

Portfolio.get_total_market_return() with default arguments.


total_profit property

Portfolio.get_total_profit() with default arguments.


total_return property

Portfolio.get_total_return() with default arguments.


trade_history property

Portfolio.get_trade_history() with default arguments.


trades property

Portfolio.get_trades() with default arguments.


trades_cls property

Class for wrapping trade records.


trades_type property

Default Trades to use across Portfolio.


up_capture_ratio property

Portfolio.get_up_capture_ratio() with default arguments.


use_in_outputs property

Whether to return in-output objects when calling properties.


value property

Portfolio.get_value() with default arguments.


value_at_risk property

Portfolio.get_value_at_risk() with default arguments.


weights property

Portfolio.get_weights() with default arguments.


wrap_obj method

Portfolio.wrap_obj(
    obj,
    obj_name=None,
    grouping='columns_or_groups',
    obj_type=None,
    wrapper=None,
    group_by=None,
    wrap_func=None,
    wrap_kwargs=None,
    force_wrapping=False,
    silence_warnings=False,
    **kwargs
)

Wrap an object.

wrap_func must take the portfolio, obj, all the arguments passed to this method, and **kwargs. If you don't need any of the arguments, make indexing_func accept them as **kwargs.

If the object is None or boolean, returns as-is.


year_freq property

Year frequency.


PortfolioWithInOutputs class

PortfolioWithInOutputs()

Class exposes a read-only class property RecordsWithFields.field_config.

Subclasses


in_output_config function

In-output config of ${cls_name}.

${in_output_config}