Skip to content
New: Star-import, signal unraveling, Python 3.12 support, and more

#
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'>
        ),
        orders=dict(
            obj_type='records',
            field_aliases=(
                'order_records'
            ),
            wrap_func=<function <lambda> at 0x7ff35a4a4ca0>,
            indexing_func=functools.partial(<function records_indexing_func at 0x7ff35a4a49d0>, cls='orders_cls'),
            resample_func=functools.partial(<function records_resample_func at 0x7ff35a4a4af0>, cls='orders_cls')
        ),
        logs=dict(
            obj_type='records',
            field_aliases=(
                'log_records'
            ),
            wrap_func=<function <lambda> at 0x7ff35a4a4d30>,
            indexing_func=functools.partial(<function records_indexing_func at 0x7ff35a4a49d0>, cls='logs_cls'),
            resample_func=functools.partial(<function records_resample_func at 0x7ff35a4a4af0>, cls='logs_cls')
        ),
        entry_trades=dict(
            obj_type='records',
            field_aliases=(
                'entry_trade_records'
            ),
            wrap_func=<function <lambda> at 0x7ff35a4a4dc0>,
            indexing_func=functools.partial(<function records_indexing_func at 0x7ff35a4a49d0>, cls='entry_trades_cls'),
            resample_func=functools.partial(<function records_resample_func at 0x7ff35a4a4af0>, cls='entry_trades_cls')
        ),
        exit_trades=dict(
            obj_type='records',
            field_aliases=(
                'exit_trade_records'
            ),
            wrap_func=<function <lambda> at 0x7ff35a4a4e50>,
            indexing_func=functools.partial(<function records_indexing_func at 0x7ff35a4a49d0>, cls='exit_trades_cls'),
            resample_func=functools.partial(<function records_resample_func at 0x7ff35a4a4af0>, cls='exit_trades_cls')
        ),
        trades=dict(
            obj_type='records',
            field_aliases=(
                'trade_records'
            ),
            wrap_func=<function <lambda> at 0x7ff35a4a4ee0>,
            indexing_func=functools.partial(<function records_indexing_func at 0x7ff35a4a49d0>, cls='trades_cls'),
            resample_func=functools.partial(<function records_resample_func at 0x7ff35a4a4af0>, cls='trades_cls')
        ),
        trade_history=dict(),
        positions=dict(
            obj_type='records',
            field_aliases=(
                'position_records'
            ),
            wrap_func=<function <lambda> at 0x7ff35a4a4f70>,
            indexing_func=functools.partial(<function records_indexing_func at 0x7ff35a4a49d0>, cls='positions_cls'),
            resample_func=functools.partial(<function records_resample_func at 0x7ff35a4a4af0>, cls='positions_cls')
        ),
        drawdowns=dict(
            obj_type='records',
            field_aliases=(
                'drawdown_records'
            ),
            wrap_func=<function <lambda> at 0x7ff35a4a5000>,
            indexing_func=functools.partial(<function records_indexing_func at 0x7ff35a4a49d0>, cls='drawdowns_cls', groups_only=True),
            resample_func=functools.partial(<function records_resample_func at 0x7ff35a4a4af0>, 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
                )
            )
        ),
        cash_earnings=dict(
            resample_func='sum',
            resample_kwargs=dict(
                wrap_kwargs=dict(
                    fillna=0.0
                )
            )
        ),
        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',
            group_by_aware=False
        ),
        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 0x7ff35a4a4c10>
        ),
        log_returns=dict(
            method_name='get_returns',
            method_kwargs=dict(
                log_returns=True
            ),
            resample_func=functools.partial(<function returns_resample_func at 0x7ff35a4a4c10>, 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 0x7ff35a4a4c10>, 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 0x7ff35a4a4c10>
        ),
        market_value=dict(),
        market_returns=dict(
            resample_func=<function returns_resample_func at 0x7ff35a4a4c10>
        ),
        bm_value=dict(),
        bm_returns=dict(
            resample_func=<function returns_resample_func at 0x7ff35a4a4c10>
        ),
        total_market_return=dict(
            obj_type='red_array'
        ),
        daily_returns=dict(
            resample_func=<function returns_resample_func at 0x7ff35a4a4c10>
        ),
        annual_returns=dict(
            resample_func=<function returns_resample_func at 0x7ff35a4a4c10>
        ),
        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

- MetaPortfolio

### in_output_config property

In-output config.

## MetaPortfolio class

    MetaPortfolio(
        *args,
        **kwargs
    )

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

Superclasses

- MetaAnalyzable
- MetaInOutputs
- MetaPlotsBuilderMixin
- MetaStatsBuilderMixin
- `builtins.type`

Inherited members

- MetaAnalyzable.metrics
- MetaAnalyzable.subplots
- MetaInOutputs.in_output_config

## 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,
        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,
        **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.

`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().

`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

- Analyzable
- AttrResolverMixin
- Cacheable
- Chainable
- Comparable
- Configured
- ExtPandasIndexer
- HasSettings
- IndexingBase
- PandasIndexer
- Pickleable
- PlotsBuilderMixin
- PortfolioWithInOutputs
- Prettified
- StatsBuilderMixin
- Wrapping

Inherited members

- Analyzable.cls_dir
- Analyzable.column_only_select
- Analyzable.config
- Analyzable.group_select
- Analyzable.iloc
- Analyzable.indexing_kwargs
- Analyzable.loc
- Analyzable.range_only_select
- Analyzable.rec_state
- Analyzable.self_aliases
- Analyzable.wrapper
- Analyzable.xloc
- AttrResolverMixin.deep_getattr()
- AttrResolverMixin.resolve_attr()
- Cacheable.get_ca_setup()
- Chainable.pipe()
- Configured.copy()
- Configured.equals()
- Configured.get_writeable_attrs()
- Configured.prettify()
- Configured.replace()
- Configured.resolve_merge_kwargs()
- Configured.update_config()
- HasSettings.get_path_setting()
- HasSettings.get_path_settings()
- HasSettings.get_setting()
- HasSettings.get_settings()
- HasSettings.has_path_setting()
- HasSettings.has_path_settings()
- HasSettings.has_setting()
- HasSettings.has_settings()
- HasSettings.reset_settings()
- HasSettings.resolve_setting()
- HasSettings.resolve_settings_paths()
- HasSettings.set_settings()
- IndexingBase.indexing_setter_func()
- PandasIndexer.xs()
- Pickleable.decode_config()
- Pickleable.decode_config_node()
- Pickleable.dumps()
- Pickleable.encode_config()
- Pickleable.encode_config_node()
- Pickleable.file_exists()
- Pickleable.getsize()
- Pickleable.load()
- Pickleable.loads()
- Pickleable.modify_state()
- Pickleable.resolve_file_path()
- Pickleable.save()
- PlotsBuilderMixin.build_subplots_doc()
- PlotsBuilderMixin.override_subplots_doc()
- PlotsBuilderMixin.plots()
- StatsBuilderMixin.build_metrics_doc()
- StatsBuilderMixin.override_metrics_doc()
- StatsBuilderMixin.stats()
- Wrapping.resolve_column_stack_kwargs()
- Wrapping.resolve_row_stack_kwargs()
- Wrapping.resolve_self()
- Wrapping.resolve_stack_kwargs()
- Wrapping.select_col()
- Wrapping.select_col_from_obj()
- Wrapping.split()

### 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.

### 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.

### column_stack class method

    Portfolio.column_stack(
        *objs,
        group_by=None,
        wrapper_kwargs=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.

### 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,
        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:

- `pre_segment_func_nb` is def_flex_pre_segment_func_nb()
- `flex_order_func_nb` is def_flex_order_func_nb()

If `flexible` is False:

- `pre_segment_func_nb` is def_pre_segment_func_nb()
- `order_func_nb` is def_order_func_nb()

Prepared by FDOFPreparer.

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

Usage

- Working with Portfolio.from_def_order_func() is a similar experience as working with Portfolio.from_orders():

    >>> 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,
        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:

- `order_func_nb`: See from_order_func_nb()
- `order_func_nb` and `row_wise`: See from_order_func_rw_nb()
- `flex_order_func_nb`: See from_flex_order_func_nb()
- `flex_order_func_nb` and `row_wise`: See from_flex_order_func_rw_nb()

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.

`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

- Equal-weighted portfolio as in the example under from_order_func_nb():

    >>> @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.records_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,
        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!

`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`.

- If `n` is set, see RANDNX.
- If `prob` is set, see RPROBNX.

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,
        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,
        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.

`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.

`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`
  Mapping to replace 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',
        group_by=None,
        asset_value=None,
        value=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get portfolio allocation series per column.

### get_alpha method

    Portfolio.get_alpha(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.alpha().

### get_annual_returns method

    Portfolio.get_annual_returns(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.annual().

### get_annualized_return method

    Portfolio.get_annualized_return(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.annualized().

### get_annualized_volatility method

    Portfolio.get_annualized_volatility(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.annualized_volatility().

### get_asset_flow class method

    Portfolio.get_asset_flow(
        direction='both',
        orders=None,
        init_position=None,
        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(
        group_by=None,
        init_position_value=None,
        asset_value=None,
        cash_flow=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

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

### get_asset_returns class method

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

Get asset return series per column/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',
        group_by=None,
        close=None,
        assets=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get asset value series per column/group.

### get_assets class method

    Portfolio.get_assets(
        direction='both',
        asset_flow=None,
        init_position=None,
        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(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.beta().

### get_bm_returns class method

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

Get benchmark return series per column/group.

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

### get_bm_value class method

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

Get benchmark value series per column/group.

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

### get_calmar_ratio method

    Portfolio.get_calmar_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.calmar_ratio().

### get_capture_ratio method

    Portfolio.get_capture_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.capture_ratio().

### get_cash class method

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

Get cash balance series per column/group.

For `free`, see Portfolio.get_cash_flow().

### get_cash_deposits class method

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

Get cash deposit series per column/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(
        group_by=None,
        cash_earnings_raw=None,
        keep_flex=False,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get earnings in cash series per column/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(
        group_by=None,
        free=False,
        orders=None,
        cash_earnings=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get cash flow series per column/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(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.cond_value_at_risk().

### get_cumulative_returns method

    Portfolio.get_cumulative_returns(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.cumulative().

### get_daily_returns method

    Portfolio.get_daily_returns(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.daily().

### get_deflated_sharpe_ratio method

    Portfolio.get_deflated_sharpe_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.deflated_sharpe_ratio().

### get_down_capture_ratio method

    Portfolio.get_down_capture_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.down_capture_ratio().

### get_downside_risk method

    Portfolio.get_downside_risk(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.downside_risk().

### get_drawdown method

    Portfolio.get_drawdown(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.drawdown().

### get_drawdowns class method

    Portfolio.get_drawdowns(
        value=None,
        drawdowns_cls=None,
        group_by=None,
        wrapper_kwargs=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,
        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,
        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(
        group_by=None,
        input_value=None,
        total_profit=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get total profit per column/group.

### get_gross_exposure class method

    Portfolio.get_gross_exposure(
        direction='both',
        group_by=None,
        asset_value=None,
        value=None,
        jitted=None,
        chunked=None,
        wrapper=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,
        group_by=None,
        wrapper=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(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.information_ratio().

### get_init_cash class method

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

Get initial amount of cash per column/group.

### get_init_position class method

    Portfolio.get_init_position(
        init_position_raw=None,
        wrapper=None,
        wrap_kwargs=None
    )

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,
        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
    )

Get initial price per column.

### get_init_value class method

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

Get initial value per column/group.

Includes initial cash and the value of initial position.

### get_input_value class method

    Portfolio.get_input_value(
        group_by=None,
        cash_sharing=None,
        init_value=None,
        cash_deposits_raw=None,
        split_shared=False,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get total input value per column/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,
        group_by=None,
        wrapper=None,
        **kwargs
    )

Get log records.

See Logs.

### get_market_returns class method

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

Get market return series per column/group.

### get_market_value class method

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

Get market value series per column/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(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.max_drawdown().

### get_net_exposure class method

    Portfolio.get_net_exposure(
        group_by=None,
        long_exposure=None,
        short_exposure=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get net exposure.

### get_omega_ratio method

    Portfolio.get_omega_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=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,
        group_by=None,
        wrapper=None,
        **kwargs
    )

Get order records.

See Orders.

### get_position_coverage class method

    Portfolio.get_position_coverage(
        direction='both',
        group_by=None,
        position_mask=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get position coverage per column/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,
        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,
        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',
        group_by=None,
        assets=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get position mask per column/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,
        group_by=None,
        **kwargs
    )

Get position records.

See Positions.

### get_prob_sharpe_ratio method

    Portfolio.get_prob_sharpe_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.prob_sharpe_ratio().

### get_qs class method

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

Get quantstats adapter of type QSAdapter.

`**kwargs` are passed to the adapter constructor.

### get_returns class method

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

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

### get_returns_acc class method

    Portfolio.get_returns_acc(
        group_by=None,
        returns=None,
        use_asset_returns=False,
        bm_returns=None,
        log_returns=False,
        daily_returns=False,
        freq=None,
        year_freq=None,
        defaults=None,
        jitted=None,
        chunked=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(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.sharpe_ratio().

### get_sharpe_ratio_std method

    Portfolio.get_sharpe_ratio_std(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.sharpe_ratio_std().

### get_sortino_ratio method

    Portfolio.get_sortino_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.sortino_ratio().

### get_tail_ratio method

    Portfolio.get_tail_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.tail_ratio().

### get_total_market_return class method

    Portfolio.get_total_market_return(
        group_by=None,
        input_value=None,
        market_value=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get total market return.

### get_total_profit class method

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

Get total profit per column/group.

Calculated directly from order records (fast).

### get_total_return class method

    Portfolio.get_total_return(
        group_by=None,
        input_value=None,
        total_profit=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get total return per column/group.

### get_trade_history method

    Portfolio.get_trade_history(
        orders=None,
        entry_trades_cls=None,
        exit_trades_cls=None,
        **kwargs
    )

Get (entry and exit) trade history as a DataFrame.

### get_trades method

    Portfolio.get_trades(
        group_by=None,
        **kwargs
    )

Get trade/position records depending upon Portfolio.trades_type.

### get_up_capture_ratio method

    Portfolio.get_up_capture_ratio(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.up_capture_ratio().

### get_value class method

    Portfolio.get_value(
        group_by=None,
        cash=None,
        asset_value=None,
        jitted=None,
        chunked=None,
        wrapper=None,
        wrap_kwargs=None
    )

Get portfolio value series per column/group.

By default, will generate portfolio value for each asset based on cash flows and thus independent from 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(
        *,
        group_by=None,
        bm_returns=None,
        freq=None,
        year_freq=None,
        log_returns=False,
        daily_returns=False,
        use_asset_returns=False,
        jitted=None,
        **kwargs
    )

See ReturnsAccessor.value_at_risk().

### gross_exposure property

Portfolio.get_gross_exposure() with default arguments.

### high property

High price of each bar.

### 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,
        group_by=None,
        wrapper=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'}`.

### low property

Low price of each bar.

### 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,
        group_by=None,
        wrapper=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=dict(
            title='Start',
            calc_func=<function Portfolio.<lambda> at 0x7ff35a4b0ee0>,
            agg_func=None,
            tags='wrapper'
        ),
        end=dict(
            title='End',
            calc_func=<function Portfolio.<lambda> at 0x7ff35a4b0f70>,
            agg_func=None,
            tags='wrapper'
        ),
        period=dict(
            title='Period',
            calc_func=<function Portfolio.<lambda> at 0x7ff35a4b1000>,
            apply_to_timedelta=True,
            agg_func=None,
            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='Cash Deposits',
            calc_func='cash_deposits.vbt.sum',
            check_has_cash_deposits=True,
            tags='portfolio'
        ),
        cash_earnings=dict(
            title='Cash Earnings',
            calc_func='cash_earnings.vbt.sum',
            check_has_cash_earnings=True,
            tags='portfolio'
        ),
        total_return=dict(
            title='Total Return [%]',
            calc_func='total_return',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b1090>,
            tags='portfolio'
        ),
        bm_return=dict(
            title='Benchmark Return [%]',
            calc_func='bm_returns.vbt.returns.total',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b1120>,
            check_has_bm_returns=True,
            tags='portfolio'
        ),
        total_time_exposure=dict(
            title='Total Time Exposure [%]',
            calc_func='position_mask.vbt.mean',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b11b0>,
            tags='portfolio'
        ),
        max_gross_exposure=dict(
            title='Max Gross Exposure [%]',
            calc_func='gross_exposure.vbt.max',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b1240>,
            tags='portfolio'
        ),
        max_dd=dict(
            title='Max Drawdown [%]',
            calc_func='drawdowns.max_drawdown',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b12d0>,
            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 0x7ff35a4b1360>,
            tags=RepEval(
                template="['portfolio', 'trades', *incl_open_tags]",
                context=None,
                strict=None,
                sub_id=None,
                context_merge_kwargs=None
            )
        ),
        best_trade=dict(
            title='Best Trade [%]',
            calc_func='trades.returns.max',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b13f0>,
            tags=RepEval(
                template="['portfolio', 'trades', *incl_open_tags]",
                context=None,
                strict=None,
                sub_id=None,
                context_merge_kwargs=None
            )
        ),
        worst_trade=dict(
            title='Worst Trade [%]',
            calc_func='trades.returns.min',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b1480>,
            tags=RepEval(
                template="['portfolio', 'trades', *incl_open_tags]",
                context=None,
                strict=None,
                sub_id=None,
                context_merge_kwargs=None
            )
        ),
        avg_winning_trade=dict(
            title='Avg Winning Trade [%]',
            calc_func='trades.winning.returns.mean',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b1510>,
            tags=RepEval(
                template="['portfolio', 'trades', *incl_open_tags, 'winning']",
                context=None,
                strict=None,
                sub_id=None,
                context_merge_kwargs=None
            )
        ),
        avg_losing_trade=dict(
            title='Avg Losing Trade [%]',
            calc_func='trades.losing.returns.mean',
            post_calc_func=<function Portfolio.<lambda> at 0x7ff35a4b15a0>,
            tags=RepEval(
                template="['portfolio', 'trades', *incl_open_tags, 'losing']",
                context=None,
                strict=None,
                sub_id=None,
                context_merge_kwargs=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,
                sub_id=None,
                context_merge_kwargs=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,
                sub_id=None,
                context_merge_kwargs=None
            )
        ),
        profit_factor=dict(
            title='Profit Factor',
            calc_func='trades.profit_factor',
            tags=RepEval(
                template="['portfolio', 'trades', *incl_open_tags]",
                context=None,
                strict=None,
                sub_id=None,
                context_merge_kwargs=None
            )
        ),
        expectancy=dict(
            title='Expectancy',
            calc_func='trades.expectancy',
            tags=RepEval(
                template="['portfolio', 'trades', *incl_open_tags]",
                context=None,
                strict=None,
                sub_id=None,
                context_merge_kwargs=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.

### 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/group (time series)
- '_1d': element per column/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 method

    Portfolio.plot_allocations(
        column=None,
        line_shape='hv',
        group_by=None,
        jitted=None,
        chunked=None,
        **kwargs
    )

Plot one group of allocations.

### plot_asset_flow method

    Portfolio.plot_asset_flow(
        column=None,
        direction='both',
        jitted=None,
        chunked=None,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column of asset flow.

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

### plot_asset_value method

    Portfolio.plot_asset_value(
        column=None,
        group_by=None,
        direction='both',
        jitted=None,
        chunked=None,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column/group of asset value.

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

### plot_assets method

    Portfolio.plot_assets(
        column=None,
        direction='both',
        jitted=None,
        chunked=None,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column of assets.

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

### plot_cash method

    Portfolio.plot_cash(
        column=None,
        group_by=None,
        jitted=None,
        chunked=None,
        free=False,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column/group of cash balance.

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

### plot_cash_flow method

    Portfolio.plot_cash_flow(
        column=None,
        group_by=None,
        jitted=None,
        chunked=None,
        free=False,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column/group of cash flow.

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

### plot_cum_returns method

    Portfolio.plot_cum_returns(
        column=None,
        group_by=None,
        use_asset_returns=False,
        bm_returns=None,
        log_returns=False,
        pct_scale=False,
        jitted=None,
        chunked=None,
        **kwargs
    )

Plot one column/group of cumulative returns.

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

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

### plot_drawdowns method

    Portfolio.plot_drawdowns(
        column=None,
        group_by=None,
        **kwargs
    )

Plot one column/group of drawdowns.

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

### plot_gross_exposure method

    Portfolio.plot_gross_exposure(
        column=None,
        group_by=None,
        direction='both',
        jitted=None,
        chunked=None,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column/group of gross exposure.

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

### plot_net_exposure method

    Portfolio.plot_net_exposure(
        column=None,
        group_by=None,
        jitted=None,
        chunked=None,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column/group of net exposure.

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

### plot_trade_signals method

    Portfolio.plot_trade_signals(
        column=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,
        **kwargs
    )

Plot one column/group of trade signals.

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

### plot_underwater method

    Portfolio.plot_underwater(
        column=None,
        group_by=None,
        jitted=None,
        chunked=None,
        pct_scale=True,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column/group of underwater.

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

### plot_value method

    Portfolio.plot_value(
        column=None,
        group_by=None,
        jitted=None,
        chunked=None,
        xref='x',
        yref='y',
        hline_shape_kwargs=None,
        **kwargs
    )

Plot one column/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,
        group_by=None,
        wrapper=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(
        group_by=None,
        use_asset_returns=False,
        bm_returns=None,
        log_returns=False,
        daily_returns=False,
        freq=None,
        year_freq=None,
        defaults=None,
        chunked=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,
        group_by=None,
        wrapper_kwargs=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'}`.

### 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='orders.plot',
            tags=[
                'portfolio',
                'orders'
            ]
        ),
        trades=dict(
            title='Trades',
            yaxis_kwargs=dict(
                title='Price'
            ),
            check_is_not_grouped=True,
            plot_func='trades.plot',
            tags=[
                'portfolio',
                'trades'
            ]
        ),
        trade_pnl=dict(
            title='Trade PnL',
            yaxis_kwargs=dict(
                title='Trade PnL'
            ),
            check_is_not_grouped=True,
            plot_func='trades.plot_pnl',
            pct_scale=True,
            tags=[
                'portfolio',
                'trades'
            ]
        ),
        trade_signals=dict(
            title='Trade Signals',
            yaxis_kwargs=dict(
                title='Trade Signals'
            ),
            check_is_not_grouped=True,
            plot_func='plot_trade_signals',
            tags=[
                'portfolio',
                'trades'
            ]
        ),
        asset_flow=dict(
            title='Asset Flow',
            yaxis_kwargs=dict(
                title='Asset flow'
            ),
            check_is_not_grouped=True,
            plot_func='plot_asset_flow',
            pass_add_trace_kwargs=True,
            tags=[
                'portfolio',
                'assets'
            ]
        ),
        cash_flow=dict(
            title='Cash Flow',
            yaxis_kwargs=dict(
                title='Cash flow'
            ),
            plot_func='plot_cash_flow',
            pass_add_trace_kwargs=True,
            tags=[
                'portfolio',
                'cash'
            ]
        ),
        assets=dict(
            title='Assets',
            yaxis_kwargs=dict(
                title='Assets'
            ),
            check_is_not_grouped=True,
            plot_func='plot_assets',
            pass_add_trace_kwargs=True,
            tags=[
                'portfolio',
                'assets'
            ]
        ),
        cash=dict(
            title='Cash',
            yaxis_kwargs=dict(
                title='Cash'
            ),
            plot_func='plot_cash',
            pass_add_trace_kwargs=True,
            tags=[
                'portfolio',
                'cash'
            ]
        ),
        asset_value=dict(
            title='Asset Value',
            yaxis_kwargs=dict(
                title='Asset 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 returns'
            ),
            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='Gross exposure'
            ),
            plot_func='plot_gross_exposure',
            pass_add_trace_kwargs=True,
            tags=[
                'portfolio',
                'exposure'
            ]
        ),
        net_exposure=dict(
            title='Net Exposure',
            yaxis_kwargs=dict(
                title='Net exposure'
            ),
            plot_func='plot_net_exposure',
            pass_add_trace_kwargs=True,
            tags=[
                'portfolio',
                'exposure'
            ]
        )
    )

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_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.

### wrap_obj method

    Portfolio.wrap_obj(
        obj,
        obj_name=None,
        grouping='columns_or_groups',
        obj_type=None,
        group_by=None,
        wrapper=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

- Portfolio

### in_output_config function

In-output config of `${cls_name}`.

    ${in_output_config}

#### Cookie consent

We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better.

- Google Analytics
- GitHub

Manage settings