Portfolio#

tradeexecutor.state.portfolio.Portfolio class.

class Portfolio[source]#

Bases: object

Represents a trading portfolio on DEX markets.

Multiple trading pair issue: We do not identify the actual assets we have purchased, but the trading pairs that we used to purchase them. Thus, each position marks “openness” in a certain trading pair. For example open position of WBNB-BUSD means we have bought X BNB tokens through WBNB-BUSD trading pair. But because this is DEX market, we could enter and exit through WBNB-USDT, WBNB-ETH, etc. and our position is not really tied to a trading pair. However, because all TradFi trading view the world through trading pairs, we keep the tradition here.

__init__(next_position_id=1, next_trade_id=1, open_positions=<factory>, reserves=<factory>, closed_positions=<factory>, frozen_positions=<factory>)#
Parameters
Return type

None

Methods

__init__([next_position_id, next_trade_id, ...])

adjust_reserves(asset, amount)

Remove currency from reserved

check_for_nonce_reuse(nonce)

A helper assert to see we are not generating invalid transactions somewhere.

create_trade(ts, pair, quantity, reserve, ...)

Create a trade.

find_position_for_trade(trade)

Find a position tha trade belongs for.

from_dict(kvs, *[, infer_missing])

from_json(s, *[, parse_float, parse_int, ...])

get_all_positions()

Get open, closed and frozen, positions.

get_all_trades()

Iterate through all trades: completed, failed and in progress

get_closed_profit_usd()

Get the value of the portfolio based on the latest pricing.

get_current_cash()

Get how much reserve stablecoins we have.

get_default_reserve_currency()

Gets the default reserve currency associated with this state.

get_equity_for_pair(pair)

Return how much equity allocation we have in a certain trading pair.

get_executed_positions()

Get all positions with already executed trades.

get_existing_open_position_by_trading_pair(pair)

Get a position by a trading pair smart contract address identifier.

get_first_and_last_executed_trade()

Get first and last trades overall.

get_frozen_position_equity()

Get the value of trading positions that are frozen currently.

get_initial_deposit()

How much we invested at the beginning of a backtest.

get_live_position_equity()

Get the value of current trading positions plus unexecuted trades.

get_open_position_equity()

Get the value of current trading positions.

get_open_position_for_pair(pair)

get_open_positions()

Get currently open positions.

get_open_quantities_by_internal_id()

Return the current holdings in different trading pairs.

get_open_quantities_by_position_id()

Return the current ownerships.

get_position_by_id(position_id)

Get any position open/closed/frozen by id.

get_position_by_trading_pair(pair)

Get open position by a trading pair smart contract address identifier.

get_positions_closed_at(ts)

Get positions that were closed at a specific timestamp.

get_reserve_position(asset)

get_total_equity()

Get the value of the portfolio based on the latest pricing.

get_unrealised_profit_usd()

Get the profit of currently open positions.

has_unexecuted_trades()

Do we have any trades that have capital allocated, but not executed yet.

is_empty()

This portfolio has no open or past trades or any reserves.

move_capital_from_reserves_to_trade(trade[, ...])

Allocate capital from reserves to trade instance.

open_new_position(ts, pair, assumed_price, ...)

return_capital_to_reserves(trade[, ...])

Return capital to reserves after a sell.

revalue_positions(ts, valuation_method[, ...])

Revalue all open positions in the portfolio.

schema(*[, infer_missing, only, exclude, ...])

to_dict([encode_json])

to_json(*[, skipkeys, ensure_ascii, ...])

update_reserves(new_reserves)

Update current reserves.

Attributes

next_position_id

Each position gets it unique running counter id.

next_trade_id

Each trade gets it unique id as a running counter.

open_positions

Currently open trading positions

reserves

Currently held reserve assets Token address -> reserve position mapping.

closed_positions

Trades completed in the past

frozen_positions

Positions that have failed sells, or otherwise immovable and need manual clean up.

next_position_id: int = 1#

Each position gets it unique running counter id.

next_trade_id: int = 1#

Each trade gets it unique id as a running counter. Trade ids are unique across different positions.

open_positions: Dict[int, TradingPosition]#

Currently open trading positions

reserves: Dict[str, ReservePosition]#

Currently held reserve assets Token address -> reserve position mapping.

closed_positions: Dict[int, TradingPosition]#

Trades completed in the past

frozen_positions: Dict[int, TradingPosition]#

Positions that have failed sells, or otherwise immovable and need manual clean up. Failure reasons could include - blockchain halted - ERC-20 token tax fees - rug pull token - transfer disabled

is_empty()[source]#

This portfolio has no open or past trades or any reserves.

get_position_by_id(position_id)[source]#

Get any position open/closed/frozen by id.

Parameters

position_id (int) – Internal running counter id for the position inside this portfolio.

Returns

Always returns or fails with py:class:AssertionError.

Return type

TradingPosition

get_all_positions()[source]#

Get open, closed and frozen, positions.

Return type

Iterable[TradingPosition]

get_open_positions()[source]#

Get currently open positions.

Return type

Iterable[TradingPosition]

get_executed_positions()[source]#

Get all positions with already executed trades.

Ignore positions that are still pending - they have only planned trades.

Return type

Iterable[TradingPosition]

get_open_quantities_by_position_id()[source]#

Return the current ownerships.

Keyed by position id -> quantity.

Return type

Dict[str, Decimal]

get_open_quantities_by_internal_id()[source]#

Return the current holdings in different trading pairs.

Keyed by trading pair internal id -> quantity.

Return type

Dict[int, Decimal]

get_position_by_trading_pair(pair)[source]#

Get open position by a trading pair smart contract address identifier.

For Uniswap-likes we use the pool address as the persistent identifier for each trading pair.

Parameters

pair (TradingPairIdentifier) –

Return type

Optional[TradingPosition]

get_existing_open_position_by_trading_pair(pair)[source]#

Get a position by a trading pair smart contract address identifier.

The position must have already executed trades (cannot be planned position(.

Parameters

pair (TradingPairIdentifier) –

Return type

Optional[TradingPosition]

get_positions_closed_at(ts)[source]#

Get positions that were closed at a specific timestamp.

Useful to display closed positions after the rebalance.

Parameters

ts (datetime) –

Return type

Iterable[TradingPosition]

create_trade(ts, pair, quantity, reserve, assumed_price, trade_type, reserve_currency, reserve_currency_price, notes=None)[source]#

Create a trade.

Trade can be opened by knowing how much you want to buy (quantity) or how much cash you have to buy (reserve).

Parameters
Return type

Tuple[TradingPosition, TradeExecution, bool]

get_current_cash()[source]#

Get how much reserve stablecoins we have.

Return type

USDollarAmount

get_open_position_equity()[source]#

Get the value of current trading positions.

Return type

USDollarAmount

get_frozen_position_equity()[source]#

Get the value of trading positions that are frozen currently.

Return type

USDollarAmount

get_live_position_equity()[source]#

Get the value of current trading positions plus unexecuted trades.

Return type

USDollarAmount

get_total_equity()[source]#

Get the value of the portfolio based on the latest pricing.

This is

  • Value of the positions

plus

  • Cash in the hand

Return type

USDollarAmount

get_unrealised_profit_usd()[source]#

Get the profit of currently open positions.

Return type

USDollarAmount

get_closed_profit_usd()[source]#

Get the value of the portfolio based on the latest pricing.

Return type

USDollarAmount

find_position_for_trade(trade)[source]#

Find a position tha trade belongs for.

Return type

Optional[TradingPosition]

get_equity_for_pair(pair)[source]#

Return how much equity allocation we have in a certain trading pair.

Parameters

pair (TradingPairIdentifier) –

Return type

Decimal

adjust_reserves(asset, amount)[source]#

Remove currency from reserved

Parameters
move_capital_from_reserves_to_trade(trade, underflow_check=True)[source]#

Allocate capital from reserves to trade instance.

Total equity of the porfolio stays the same.

Parameters

trade (TradeExecution) –

return_capital_to_reserves(trade, underflow_check=True)[source]#

Return capital to reserves after a sell.

Parameters

trade (TradeExecution) –

has_unexecuted_trades()[source]#

Do we have any trades that have capital allocated, but not executed yet.

Return type

bool

update_reserves(new_reserves)[source]#

Update current reserves.

Overrides current amounts of reserves.

E.g. in the case users have deposited more capital.

Parameters

new_reserves (List[ReservePosition]) –

check_for_nonce_reuse(nonce)[source]#

A helper assert to see we are not generating invalid transactions somewhere.

Raise

AssertionError

Parameters

nonce (int) –

revalue_positions(ts, valuation_method, revalue_frozen=True)[source]#

Revalue all open positions in the portfolio.

Reserves are not revalued.

Parameters
  • revalue_frozen – Revalue frozen positions as well

  • ts (datetime) –

  • valuation_method (Callable) –

get_default_reserve_currency()[source]#

Gets the default reserve currency associated with this state.

For strategies that use only one reserve currency. This is the first in the reserve currency list.

Returns

Tuple (Reserve currency asset, its latest US dollar exchanage rate)

Return type

Tuple[AssetIdentifier, USDollarAmount]

get_all_trades()[source]#

Iterate through all trades: completed, failed and in progress

Return type

Iterable[TradeExecution]

get_first_and_last_executed_trade()[source]#

Get first and last trades overall.

Return type

Tuple[Optional[TradeExecution], Optional[TradeExecution]]

get_initial_deposit()[source]#

How much we invested at the beginning of a backtest.

  • Assumes we track the performance against the US dollar

  • Assume there has been only one deposit event

  • This deposit happened at the start of the backtest

Return type

Optional[USDollarAmount]

__init__(next_position_id=1, next_trade_id=1, open_positions=<factory>, reserves=<factory>, closed_positions=<factory>, frozen_positions=<factory>)#
Parameters
Return type

None