Skip to content

trades module

Base class for working with trade records.

Trade records capture information on trades.

In vectorbt, a trade is a sequence of orders that starts with an opening order and optionally ends with a closing order. Every pair of opposite orders can be represented by a trade. Each trade has a PnL info attached to quickly assess its performance. An interesting effect of this representation is the ability to aggregate trades: if two or more trades are happening one after another in time, they can be aggregated into a bigger trade. This way, for example, single-order trades can be aggregated into positions; but also multiple positions can be aggregated into a single blob that reflects the performance of the entire symbol.

Warning

All classes return both closed AND open trades/positions, which may skew your performance results. To only consider closed trades/positions, you should explicitly query the closed attribute.

Trade types

There are three main types of trades.

Entry trades

An entry trade is created from each order that opens or adds to a position.

For example, if we have a single large buy order and 100 smaller sell orders, we will see a single trade with the entry information copied from the buy order and the exit information being a size-weighted average over the exit information of all sell orders. On the other hand, if we have 100 smaller buy orders and a single sell order, we will see 100 trades, each with the entry information copied from the buy order and the exit information being a size-based fraction of the exit information of the sell order.

Use EntryTrades.from_orders() to build entry trades from orders. Also available as Portfolio.entry_trades.

Exit trades

An exit trade is created from each order that closes or removes from a position.

Use ExitTrades.from_orders() to build exit trades from orders. Also available as Portfolio.exit_trades.

Positions

A position is created from a sequence of entry or exit trades.

Use Positions.from_trades() to build positions from entry or exit trades. Also available as Portfolio.positions.

Example

  • Increasing position:
>>> import pandas as pd
>>> import numpy as np
>>> from datetime import datetime, timedelta
>>> import vectorbt as vbt

>>> # Entry trades
>>> pf_kwargs = dict(
...     close=pd.Series([1., 2., 3., 4., 5.]),
...     size=pd.Series([1., 1., 1., 1., -4.]),
...     fixed_fees=1.
... )
>>> entry_trades = vbt.Portfolio.from_orders(**pf_kwargs).entry_trades
>>> entry_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0         1.0
1         1       0   1.0                1              2.0         1.0
2         2       0   1.0                2              3.0         1.0
3         3       0   1.0                3              4.0         1.0

   Exit Timestamp  Avg Exit Price  Exit Fees   PnL  Return Direction  Status  \
0               4             5.0       0.25  2.75  2.7500      Long  Closed
1               4             5.0       0.25  1.75  0.8750      Long  Closed
2               4             5.0       0.25  0.75  0.2500      Long  Closed
3               4             5.0       0.25 -0.25 -0.0625      Long  Closed

   Parent Id
0          0
1          0
2          0
3          0

>>> # Exit trades
>>> exit_trades = vbt.Portfolio.from_orders(**pf_kwargs).exit_trades
>>> exit_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   4.0                0              2.5         4.0

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction  Status  \
0               4             5.0        1.0  5.0     0.5      Long  Closed

   Parent Id
0          0

>>> # Positions
>>> positions = vbt.Portfolio.from_orders(**pf_kwargs).positions
>>> positions.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   4.0                0              2.5         4.0

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction  Status  \
0               4             5.0        1.0  5.0     0.5      Long  Closed

   Parent Id
0          0

>>> entry_trades.pnl.sum() == exit_trades.pnl.sum() == positions.pnl.sum()
True
  • Decreasing position:
>>> # Entry trades
>>> pf_kwargs = dict(
...     close=pd.Series([1., 2., 3., 4., 5.]),
...     size=pd.Series([4., -1., -1., -1., -1.]),
...     fixed_fees=1.
... )
>>> entry_trades = vbt.Portfolio.from_orders(**pf_kwargs).entry_trades
>>> entry_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   4.0                0              1.0         1.0

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction  Status  \
0               4             3.5        4.0  5.0    1.25      Long  Closed

   Parent Id
0          0

>>> # Exit trades
>>> exit_trades = vbt.Portfolio.from_orders(**pf_kwargs).exit_trades
>>> exit_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0        0.25
1         1       0   1.0                0              1.0        0.25
2         2       0   1.0                0              1.0        0.25
3         3       0   1.0                0              1.0        0.25

   Exit Timestamp  Avg Exit Price  Exit Fees   PnL  Return Direction  Status  \
0               1             2.0        1.0 -0.25   -0.25      Long  Closed
1               2             3.0        1.0  0.75    0.75      Long  Closed
2               3             4.0        1.0  1.75    1.75      Long  Closed
3               4             5.0        1.0  2.75    2.75      Long  Closed

   Parent Id
0          0
1          0
2          0
3          0

>>> # Positions
>>> positions = vbt.Portfolio.from_orders(**pf_kwargs).positions
>>> positions.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   4.0                0              1.0         1.0

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction  Status  \
0               4             3.5        4.0  5.0    1.25      Long  Closed

   Parent Id
0          0

>>> entry_trades.pnl.sum() == exit_trades.pnl.sum() == positions.pnl.sum()
True
  • Multiple reversing positions:
>>> # Entry trades
>>> pf_kwargs = dict(
...     close=pd.Series([1., 2., 3., 4., 5.]),
...     size=pd.Series([1., -2., 2., -2., 1.]),
...     fixed_fees=1.
... )
>>> entry_trades = vbt.Portfolio.from_orders(**pf_kwargs).entry_trades
>>> entry_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0         1.0
1         1       0   1.0                1              2.0         0.5
2         2       0   1.0                2              3.0         0.5
3         3       0   1.0                3              4.0         0.5

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction  Status  \
0               1             2.0        0.5 -0.5  -0.500      Long  Closed
1               2             3.0        0.5 -2.0  -1.000     Short  Closed
2               3             4.0        0.5  0.0   0.000      Long  Closed
3               4             5.0        1.0 -2.5  -0.625     Short  Closed

   Parent Id
0          0
1          1
2          2
3          3

>>> # Exit trades
>>> exit_trades = vbt.Portfolio.from_orders(**pf_kwargs).exit_trades
>>> exit_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0         1.0
1         1       0   1.0                1              2.0         0.5
2         2       0   1.0                2              3.0         0.5
3         3       0   1.0                3              4.0         0.5

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction  Status  \
0               1             2.0        0.5 -0.5  -0.500      Long  Closed
1               2             3.0        0.5 -2.0  -1.000     Short  Closed
2               3             4.0        0.5  0.0   0.000      Long  Closed
3               4             5.0        1.0 -2.5  -0.625     Short  Closed

   Parent Id
0          0
1          1
2          2
3          3

>>> # Positions
>>> positions = vbt.Portfolio.from_orders(**pf_kwargs).positions
>>> positions.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0         1.0
1         1       0   1.0                1              2.0         0.5
2         2       0   1.0                2              3.0         0.5
3         3       0   1.0                3              4.0         0.5

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction  Status  \
0               1             2.0        0.5 -0.5  -0.500      Long  Closed
1               2             3.0        0.5 -2.0  -1.000     Short  Closed
2               3             4.0        0.5  0.0   0.000      Long  Closed
3               4             5.0        1.0 -2.5  -0.625     Short  Closed

   Parent Id
0          0
1          1
2          2
3          3

>>> entry_trades.pnl.sum() == exit_trades.pnl.sum() == positions.pnl.sum()
True
  • Open position:
>>> # Entry trades
>>> pf_kwargs = dict(
...     close=pd.Series([1., 2., 3., 4., 5.]),
...     size=pd.Series([1., 0., 0., 0., 0.]),
...     fixed_fees=1.
... )
>>> entry_trades = vbt.Portfolio.from_orders(**pf_kwargs).entry_trades
>>> entry_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0         1.0

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction Status  \
0               4             5.0        0.0  3.0     3.0      Long   Open

   Parent Id
0          0

>>> # Exit trades
>>> exit_trades = vbt.Portfolio.from_orders(**pf_kwargs).exit_trades
>>> exit_trades.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0         1.0

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction Status  \
0               4             5.0        0.0  3.0     3.0      Long   Open

   Parent Id
0          0

>>> # Positions
>>> positions = vbt.Portfolio.from_orders(**pf_kwargs).positions
>>> positions.records_readable
   Trade Id  Column  Size  Entry Timestamp  Avg Entry Price  Entry Fees  \
0         0       0   1.0                0              1.0         1.0

   Exit Timestamp  Avg Exit Price  Exit Fees  PnL  Return Direction Status  \
0               4             5.0        0.0  3.0     3.0      Long   Open

   Parent Id
0          0

>>> entry_trades.pnl.sum() == exit_trades.pnl.sum() == positions.pnl.sum()
True

Get trade count, trade PnL, and winning trade PnL:

>>> price = pd.Series([1., 2., 3., 4., 3., 2., 1.])
>>> size = pd.Series([1., -0.5, -0.5, 2., -0.5, -0.5, -0.5])
>>> trades = vbt.Portfolio.from_orders(price, size).trades

>>> trades.count()
6

>>> trades.pnl.sum()
-3.0

>>> trades.winning.count()
2

>>> trades.winning.pnl.sum()
1.5

Get count and PnL of trades with duration of more than 2 days:

>>> mask = (trades.records['exit_idx'] - trades.records['entry_idx']) > 2
>>> trades_filtered = trades.apply_mask(mask)
>>> trades_filtered.count()
2

>>> trades_filtered.pnl.sum()
-3.0

Stats

>>> np.random.seed(42)
>>> price = pd.DataFrame({
...     'a': np.random.uniform(1, 2, size=100),
...     'b': np.random.uniform(1, 2, size=100)
... }, index=[datetime(2020, 1, 1) + timedelta(days=i) for i in range(100)])
>>> size = pd.DataFrame({
...     'a': np.random.uniform(-1, 1, size=100),
...     'b': np.random.uniform(-1, 1, size=100),
... }, index=[datetime(2020, 1, 1) + timedelta(days=i) for i in range(100)])
>>> pf = vbt.Portfolio.from_orders(price, size, fees=0.01, freq='d')

>>> pf.trades['a'].stats()
Start                                2020-01-01 00:00:00
End                                  2020-04-09 00:00:00
Period                                 100 days 00:00:00
First Trade Start                    2020-01-01 00:00:00
Last Trade End                       2020-04-09 00:00:00
Coverage                               100 days 00:00:00
Overlap Coverage                        97 days 00:00:00
Total Records                                         48
Total Long Trades                                     22
Total Short Trades                                    26
Total Closed Trades                                   47
Total Open Trades                                      1
Open Trade PnL                                 -1.290981
Win Rate [%]                                    51.06383
Max Win Streak                                         3
Max Loss Streak                                        3
Best Trade [%]                                 43.326077
Worst Trade [%]                               -59.478304
Avg Winning Trade [%]                          21.418522
Avg Losing Trade [%]                          -18.856792
Avg Winning Trade Duration              22 days 22:00:00
Avg Losing Trade Duration     29 days 01:02:36.521739130
Profit Factor                                   0.976634
Expectancy                                     -0.001569
SQN                                            -0.064929
Name: a, dtype: object

Positions share almost identical metrics with trades:

>>> pf.positions['a'].stats()
Start                            2020-01-01 00:00:00
End                              2020-04-09 00:00:00
Period                             100 days 00:00:00
Coverage [%]                                   100.0
First Position Start             2020-01-01 00:00:00
Last Position End                2020-04-09 00:00:00
Total Records                                      3
Total Long Positions                               2
Total Short Positions                              1
Total Closed Positions                             2
Total Open Positions                               1
Open Position PnL                          -0.929746
Win Rate [%]                                    50.0
Max Win Streak                                     1
Max Loss Streak                                    1
Best Position [%]                          39.498421
Worst Position [%]                          -3.32533
Avg Winning Position [%]                   39.498421
Avg Losing Position [%]                     -3.32533
Avg Winning Position Duration        1 days 00:00:00
Avg Losing Position Duration        47 days 00:00:00
Profit Factor                               0.261748
Expectancy                                 -0.217492
SQN                                        -0.585103
Name: a, dtype: object

To also include open trades/positions when calculating metrics such as win rate, pass incl_open=True:

>>> pf.trades['a'].stats(settings=dict(incl_open=True))
Start                         2020-01-01 00:00:00
End                           2020-04-09 00:00:00
Period                          100 days 00:00:00
First Trade Start             2020-01-01 00:00:00
Last Trade End                2020-04-09 00:00:00
Coverage                        100 days 00:00:00
Overlap Coverage                 97 days 00:00:00
Total Records                                  48
Total Long Trades                              22
Total Short Trades                             26
Total Closed Trades                            47
Total Open Trades                               1
Open Trade PnL                          -1.290981
Win Rate [%]                             51.06383
Max Win Streak                                  3
Max Loss Streak                                 3
Best Trade [%]                          43.326077
Worst Trade [%]                        -59.478304
Avg Winning Trade [%]                   21.418522
Avg Losing Trade [%]                   -19.117677
Avg Winning Trade Duration       22 days 22:00:00
Avg Losing Trade Duration        30 days 00:00:00
Profit Factor                            0.693135
Expectancy                              -0.028432
SQN                                     -0.794284
Name: a, dtype: object

StatsBuilderMixin.stats() also supports (re-)grouping:

>>> pf.trades.stats(group_by=True)
Start                                2020-01-01 00:00:00
End                                  2020-04-09 00:00:00
Period                                 100 days 00:00:00
First Trade Start                    2020-01-01 00:00:00
Last Trade End                       2020-04-09 00:00:00
Coverage                               100 days 00:00:00
Overlap Coverage                       100 days 00:00:00
Total Records                                        104
Total Long Trades                                     32
Total Short Trades                                    72
Total Closed Trades                                  102
Total Open Trades                                      2
Open Trade PnL                                 -1.790938
Win Rate [%]                                   46.078431
Max Win Streak                                         5
Max Loss Streak                                        5
Best Trade [%]                                 43.326077
Worst Trade [%]                               -87.793448
Avg Winning Trade [%]                          19.023926
Avg Losing Trade [%]                          -20.605892
Avg Winning Trade Duration    24 days 08:40:51.063829787
Avg Losing Trade Duration     25 days 11:20:43.636363636
Profit Factor                                   0.909581
Expectancy                                     -0.006035
SQN                                            -0.365593
Name: group, dtype: object

Plots

Trades class has two subplots based on Trades.plot() and Trades.plot_pnl():

>>> pf.trades['a'].plots(settings=dict(plot_zones=False)).show_svg()


entry_trades_field_config Config

Field config for EntryTrades.

Config({
    "settings": {
        "id": {
            "title": "Entry Trade Id"
        },
        "idx": {
            "name": "entry_idx"
        }
    }
})

exit_trades_field_config Config

Field config for ExitTrades.

Config({
    "settings": {
        "id": {
            "title": "Exit Trade Id"
        }
    }
})

positions_field_config Config

Field config for Positions.

Config({
    "settings": {
        "id": {
            "title": "Position Id"
        },
        "parent_id": {
            "title": "Parent Id",
            "ignore": true
        }
    }
})

trades_attach_field_config Config

Config of fields to be attached to Trades.

Config({
    "return": {
        "attach": "returns"
    },
    "direction": {
        "attach_filters": true
    },
    "status": {
        "attach_filters": true,
        "on_conflict": "ignore"
    }
})

trades_field_config Config

Field config for Trades.

Config({
    "dtype": {
        "id": "int64",
        "col": "int64",
        "size": "float64",
        "entry_idx": "int64",
        "entry_price": "float64",
        "entry_fees": "float64",
        "exit_idx": "int64",
        "exit_price": "float64",
        "exit_fees": "float64",
        "pnl": "float64",
        "return": "float64",
        "direction": "int64",
        "status": "int64",
        "parent_id": "int64"
    },
    "settings": {
        "id": {
            "title": "Trade Id"
        },
        "idx": {
            "name": "exit_idx"
        },
        "start_idx": {
            "name": "entry_idx"
        },
        "end_idx": {
            "name": "exit_idx"
        },
        "size": {
            "title": "Size"
        },
        "entry_idx": {
            "title": "Entry Timestamp",
            "mapping": "index"
        },
        "entry_price": {
            "title": "Avg Entry Price"
        },
        "entry_fees": {
            "title": "Entry Fees"
        },
        "exit_idx": {
            "title": "Exit Timestamp",
            "mapping": "index"
        },
        "exit_price": {
            "title": "Avg Exit Price"
        },
        "exit_fees": {
            "title": "Exit Fees"
        },
        "pnl": {
            "title": "PnL"
        },
        "return": {
            "title": "Return"
        },
        "direction": {
            "title": "Direction",
            "mapping": {
                "Long": 0,
                "Short": 1
            }
        },
        "status": {
            "title": "Status",
            "mapping": {
                "Open": 0,
                "Closed": 1
            }
        },
        "parent_id": {
            "title": "Position Id"
        }
    }
})

EntryTrades class

EntryTrades(
    wrapper,
    records_arr,
    close,
    **kwargs
)

Extends Trades for working with entry trade records.

Superclasses

Inherited members


from_orders class method

EntryTrades.from_orders(
    orders,
    close=None,
    attach_close=True,
    **kwargs
)

Build EntryTrades from Orders.


ExitTrades class

ExitTrades(
    wrapper,
    records_arr,
    close,
    **kwargs
)

Extends Trades for working with exit trade records.

Superclasses

Inherited members


from_orders class method

ExitTrades.from_orders(
    orders,
    close=None,
    attach_close=True,
    **kwargs
)

Build ExitTrades from Orders.


Positions class

Positions(
    wrapper,
    records_arr,
    close,
    **kwargs
)

Extends Trades for working with position records.

Superclasses

Inherited members


from_trades class method

Positions.from_trades(
    trades,
    close=None,
    attach_close=True,
    **kwargs
)

Build Positions from Trades.


Trades class

Trades(
    wrapper,
    records_arr,
    close,
    **kwargs
)

Extends Ranges for working with trade-like records, such as entry trades, exit trades, and positions.

Superclasses

Inherited members

Subclasses


close property

Reference price such as close (optional).


direction method

Mapped array of the field direction.


entry_fees method

Mapped array of the field entry_fees.


entry_idx method

Mapped array of the field entry_idx.


entry_price method

Mapped array of the field entry_price.


exit_fees method

Mapped array of the field exit_fees.


exit_idx method

Mapped array of the field exit_idx.


exit_price method

Mapped array of the field exit_price.


expectancy method

Trades.expectancy(
    group_by=None,
    wrap_kwargs=None
)

Average profitability.


field_config class variable

Field config of Trades.

Config({
    "dtype": {
        "id": "int64",
        "col": "int64",
        "size": "float64",
        "entry_idx": "int64",
        "entry_price": "float64",
        "entry_fees": "float64",
        "exit_idx": "int64",
        "exit_price": "float64",
        "exit_fees": "float64",
        "pnl": "float64",
        "return": "float64",
        "direction": "int64",
        "status": "int64",
        "parent_id": "int64"
    },
    "settings": {
        "id": {
            "name": "id",
            "title": "Trade Id"
        },
        "col": {
            "name": "col",
            "title": "Column",
            "mapping": "columns"
        },
        "idx": {
            "name": "exit_idx",
            "title": "Timestamp",
            "mapping": "index"
        },
        "start_idx": {
            "title": "Start Timestamp",
            "mapping": "index",
            "name": "entry_idx"
        },
        "end_idx": {
            "title": "End Timestamp",
            "mapping": "index",
            "name": "exit_idx"
        },
        "status": {
            "title": "Status",
            "mapping": {
                "Open": 0,
                "Closed": 1
            }
        },
        "size": {
            "title": "Size"
        },
        "entry_idx": {
            "title": "Entry Timestamp",
            "mapping": "index"
        },
        "entry_price": {
            "title": "Avg Entry Price"
        },
        "entry_fees": {
            "title": "Entry Fees"
        },
        "exit_idx": {
            "title": "Exit Timestamp",
            "mapping": "index"
        },
        "exit_price": {
            "title": "Avg Exit Price"
        },
        "exit_fees": {
            "title": "Exit Fees"
        },
        "pnl": {
            "title": "PnL"
        },
        "return": {
            "title": "Return"
        },
        "direction": {
            "title": "Direction",
            "mapping": {
                "Long": 0,
                "Short": 1
            }
        },
        "parent_id": {
            "title": "Position Id"
        }
    }
})

indexing_func method

Trades.indexing_func(
    pd_indexing_func,
    **kwargs
)

Perform indexing on Trades.


long method

Records filtered by direction == 0.


losing method

Losing trades.


losing_streak method

Losing streak at each trade in the current column.

See trade_losing_streak_nb().


metrics class variable

Metrics supported by Trades.

Config({
    "start": {
        "title": "Start",
        "calc_func": "<function Trades.<lambda> at 0x7f954a866550>",
        "agg_func": null,
        "tags": "wrapper"
    },
    "end": {
        "title": "End",
        "calc_func": "<function Trades.<lambda> at 0x7f954a8665e0>",
        "agg_func": null,
        "tags": "wrapper"
    },
    "period": {
        "title": "Period",
        "calc_func": "<function Trades.<lambda> at 0x7f954a866670>",
        "apply_to_timedelta": true,
        "agg_func": null,
        "tags": "wrapper"
    },
    "first_trade_start": {
        "title": "First Trade Start",
        "calc_func": "entry_idx.nth",
        "n": 0,
        "wrap_kwargs": {
            "to_index": true
        },
        "tags": [
            "trades",
            "index"
        ]
    },
    "last_trade_end": {
        "title": "Last Trade End",
        "calc_func": "exit_idx.nth",
        "n": -1,
        "wrap_kwargs": {
            "to_index": true
        },
        "tags": [
            "trades",
            "index"
        ]
    },
    "coverage": {
        "title": "Coverage",
        "calc_func": "coverage",
        "overlapping": false,
        "normalize": false,
        "apply_to_timedelta": true,
        "tags": [
            "ranges",
            "coverage"
        ]
    },
    "overlap_coverage": {
        "title": "Overlap Coverage",
        "calc_func": "coverage",
        "overlapping": true,
        "normalize": false,
        "apply_to_timedelta": true,
        "tags": [
            "ranges",
            "coverage"
        ]
    },
    "total_records": {
        "title": "Total Records",
        "calc_func": "count",
        "tags": "records"
    },
    "total_long_trades": {
        "title": "Total Long Trades",
        "calc_func": "long.count",
        "tags": [
            "trades",
            "long"
        ]
    },
    "total_short_trades": {
        "title": "Total Short Trades",
        "calc_func": "short.count",
        "tags": [
            "trades",
            "short"
        ]
    },
    "total_closed_trades": {
        "title": "Total Closed Trades",
        "calc_func": "closed.count",
        "tags": [
            "trades",
            "closed"
        ]
    },
    "total_open_trades": {
        "title": "Total Open Trades",
        "calc_func": "open.count",
        "tags": [
            "trades",
            "open"
        ]
    },
    "open_trade_pnl": {
        "title": "Open Trade PnL",
        "calc_func": "open.pnl.sum",
        "tags": [
            "trades",
            "open"
        ]
    },
    "win_rate": {
        "title": "Win Rate [%]",
        "calc_func": "closed.win_rate",
        "post_calc_func": "<function Trades.<lambda> at 0x7f954a866700>",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags]\", mapping={})"
    },
    "winning_streak": {
        "title": "Max Win Streak",
        "calc_func": "RepEval(expression=\"'winning_streak.max' if incl_open else 'closed.winning_streak.max'\", mapping={})",
        "wrap_kwargs": {
            "dtype": "Int64"
        },
        "tags": "RepEval(expression=\"['trades', *incl_open_tags, 'streak']\", mapping={})"
    },
    "losing_streak": {
        "title": "Max Loss Streak",
        "calc_func": "RepEval(expression=\"'losing_streak.max' if incl_open else 'closed.losing_streak.max'\", mapping={})",
        "wrap_kwargs": {
            "dtype": "Int64"
        },
        "tags": "RepEval(expression=\"['trades', *incl_open_tags, 'streak']\", mapping={})"
    },
    "best_trade": {
        "title": "Best Trade [%]",
        "calc_func": "RepEval(expression=\"'returns.max' if incl_open else 'closed.returns.max'\", mapping={})",
        "post_calc_func": "<function Trades.<lambda> at 0x7f954a866790>",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags]\", mapping={})"
    },
    "worst_trade": {
        "title": "Worst Trade [%]",
        "calc_func": "RepEval(expression=\"'returns.min' if incl_open else 'closed.returns.min'\", mapping={})",
        "post_calc_func": "<function Trades.<lambda> at 0x7f954a866820>",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags]\", mapping={})"
    },
    "avg_winning_trade": {
        "title": "Avg Winning Trade [%]",
        "calc_func": "RepEval(expression=\"'winning.returns.mean' if incl_open else 'closed.winning.returns.mean'\", mapping={})",
        "post_calc_func": "<function Trades.<lambda> at 0x7f954a8668b0>",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags, 'winning']\", mapping={})"
    },
    "avg_losing_trade": {
        "title": "Avg Losing Trade [%]",
        "calc_func": "RepEval(expression=\"'losing.returns.mean' if incl_open else 'closed.losing.returns.mean'\", mapping={})",
        "post_calc_func": "<function Trades.<lambda> at 0x7f954a866940>",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags, 'losing']\", mapping={})"
    },
    "avg_winning_trade_duration": {
        "title": "Avg Winning Trade Duration",
        "calc_func": "RepEval(expression=\"'winning.avg_duration' if incl_open else 'closed.winning.avg_duration'\", mapping={})",
        "fill_wrap_kwargs": true,
        "tags": "RepEval(expression=\"['trades', *incl_open_tags, 'winning', 'duration']\", mapping={})"
    },
    "avg_losing_trade_duration": {
        "title": "Avg Losing Trade Duration",
        "calc_func": "RepEval(expression=\"'losing.avg_duration' if incl_open else 'closed.losing.avg_duration'\", mapping={})",
        "fill_wrap_kwargs": true,
        "tags": "RepEval(expression=\"['trades', *incl_open_tags, 'losing', 'duration']\", mapping={})"
    },
    "profit_factor": {
        "title": "Profit Factor",
        "calc_func": "RepEval(expression=\"'profit_factor' if incl_open else 'closed.profit_factor'\", mapping={})",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags]\", mapping={})"
    },
    "expectancy": {
        "title": "Expectancy",
        "calc_func": "RepEval(expression=\"'expectancy' if incl_open else 'closed.expectancy'\", mapping={})",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags]\", mapping={})"
    },
    "sqn": {
        "title": "SQN",
        "calc_func": "RepEval(expression=\"'sqn' if incl_open else 'closed.sqn'\", mapping={})",
        "tags": "RepEval(expression=\"['trades', *incl_open_tags]\", mapping={})"
    }
})

Returns Trades._metrics, which gets (deep) 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 Trades._metrics.


parent_id method

Mapped array of the field parent_id.


plot method

Trades.plot(
    column=None,
    plot_zones=True,
    close_trace_kwargs=None,
    entry_trace_kwargs=None,
    exit_trace_kwargs=None,
    exit_profit_trace_kwargs=None,
    exit_loss_trace_kwargs=None,
    active_trace_kwargs=None,
    profit_shape_kwargs=None,
    loss_shape_kwargs=None,
    add_trace_kwargs=None,
    xref='x',
    yref='y',
    fig=None,
    **layout_kwargs
)

Plot orders.

Args

column : str
Name of the column to plot.
plot_zones : bool

Whether to plot zones.

Set to False if there are many trades within one position.

close_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for Trades.close.
entry_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Entry" markers.
exit_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Exit" markers.
exit_profit_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Exit - Profit" markers.
exit_loss_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Exit - Loss" markers.
active_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Active" markers.
profit_shape_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Figure.add_shape for profit zones.
loss_shape_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Figure.add_shape for loss zones.
add_trace_kwargs : dict
Keyword arguments passed to add_trace.
xref : str
X coordinate axis.
yref : str
Y coordinate axis.
fig : Figure or FigureWidget
Figure to add traces to.
**layout_kwargs
Keyword arguments for layout.

Usage

>>> import pandas as pd
>>> from datetime import datetime, timedelta
>>> import vectorbt as vbt

>>> price = pd.Series([1., 2., 3., 4., 3., 2., 1.], name='Price')
>>> price.index = [datetime(2020, 1, 1) + timedelta(days=i) for i in range(len(price))]
>>> orders = pd.Series([1., -0.5, -0.5, 2., -0.5, -0.5, -0.5])
>>> pf = vbt.Portfolio.from_orders(price, orders)
>>> pf.trades.plot()


plot_pnl method

Trades.plot_pnl(
    column=None,
    pct_scale=True,
    marker_size_range=(7, 14),
    opacity_range=(0.75, 0.9),
    closed_profit_trace_kwargs=None,
    closed_loss_trace_kwargs=None,
    open_trace_kwargs=None,
    hline_shape_kwargs=None,
    add_trace_kwargs=None,
    xref='x',
    yref='y',
    fig=None,
    **layout_kwargs
)

Plot trade PnL and returns.

Args

column : str
Name of the column to plot.
pct_scale : bool
Whether to set y-axis to Trades.returns, otherwise to Trades.pnl.
marker_size_range : tuple
Range of marker size.
opacity_range : tuple
Range of marker opacity.
closed_profit_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Closed - Profit" markers.
closed_loss_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Closed - Loss" markers.
open_trace_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Scatter for "Open" markers.
hline_shape_kwargs : dict
Keyword arguments passed to plotly.graph_objects.Figure.add_shape for zeroline.
add_trace_kwargs : dict
Keyword arguments passed to add_trace.
xref : str
X coordinate axis.
yref : str
Y coordinate axis.
fig : Figure or FigureWidget
Figure to add traces to.
**layout_kwargs
Keyword arguments for layout.

Usage

>>> import pandas as pd
>>> from datetime import datetime, timedelta
>>> import vectorbt as vbt

>>> price = pd.Series([1., 2., 3., 4., 3., 2., 1.])
>>> price.index = [datetime(2020, 1, 1) + timedelta(days=i) for i in range(len(price))]
>>> orders = pd.Series([1., -0.5, -0.5, 2., -0.5, -0.5, -0.5])
>>> pf = vbt.Portfolio.from_orders(price, orders)
>>> pf.trades.plot_pnl()


plots_defaults property

Defaults for PlotsBuilderMixin.plots().

Merges Ranges.plots_defaults and trades.plots from settings.


pnl method

Mapped array of the field pnl.


profit_factor method

Trades.profit_factor(
    group_by=None,
    wrap_kwargs=None
)

Profit factor.


returns method

Mapped array of the field return.


short method

Records filtered by direction == 1.


size method

Mapped array of the field size.


sqn method

Trades.sqn(
    group_by=None,
    wrap_kwargs=None
)

System Quality Number (SQN).


stats_defaults property

Defaults for StatsBuilderMixin.stats().

Merges Ranges.stats_defaults and trades.stats from settings.


subplots class variable

Subplots supported by Trades.

Config({
    "plot": {
        "title": "Trades",
        "yaxis_kwargs": {
            "title": "Price"
        },
        "check_is_not_grouped": true,
        "plot_func": "plot",
        "tags": "trades"
    },
    "plot_pnl": {
        "title": "Trade PnL",
        "yaxis_kwargs": {
            "title": "Trade PnL"
        },
        "check_is_not_grouped": true,
        "plot_func": "plot_pnl",
        "tags": "trades"
    }
})

Returns Trades._subplots, which gets (deep) 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 Trades._subplots.


win_rate method

Trades.win_rate(
    group_by=None,
    wrap_kwargs=None
)

Rate of winning trades.


winning method

Winning trades.


winning_streak method

Winning streak at each trade in the current column.

See trade_winning_streak_nb().