TradeExecution#
tradeexecutor.state.trade.TradeExecution Python class in Trading Strategy framework.
- class TradeExecution[source]#
Bases:
object
Trade execution tracker.
One TradeExecution instance can only represent one swap
Each trade has a reserve currency that we use to trade the token (usually USDC).
Each trade can be
Buy: swap quote token -> base token
Sell: swap base token -> quote token
When doing a buy planned_reserve (fiat) is the input. This yields to executed_quantity of tokens that may be different from planned_quantity.
When doing a sell planned_quantity (token) is the input. This yields to executed_reserve of fiat that might be different from `planned_reserve.
Trade execution has four states
Planning: The execution object is prepared
Capital allocation and transaction creation: We move reserve from out portfolio to the trade in internal accounting
Transaction broadcast: trade cannot be cancelled in this point
Resolving the trade: We check the Ethereum transaction receipt to see how well we succeeded in the trade
There trade state is resolved based on the market variables (usually timestamps).
- __init__(trade_id, position_id, trade_type, pair, opened_at, planned_quantity, planned_reserve, planned_price, reserve_currency, planned_mid_price=None, planned_max_slippage=None, started_at=None, reserve_currency_allocated=None, broadcasted_at=None, executed_at=None, failed_at=None, executed_price=None, executed_quantity=None, executed_reserve=None, fee_tier=<property object>, lp_fees_paid=None, lp_fees_estimated=<property object>, lp_fee_exchange_rate=None, native_token_price=None, retry_of=None, blockchain_transactions=<factory>, notes=None, repaired_at=None, price_structure=None)#
- Parameters:
trade_id (int) –
position_id (int) –
trade_type (TradeType) –
pair (TradingPairIdentifier) –
opened_at (datetime) –
planned_quantity (Decimal) –
planned_reserve (Decimal) –
planned_price (float) –
reserve_currency (AssetIdentifier) –
blockchain_transactions (List[BlockchainTransaction]) –
price_structure (Optional[TradePricing]) –
- Return type:
None
Methods
__init__
(trade_id, position_id, trade_type, ...)from_dict
(kvs, *[, infer_missing])from_json
(s, *[, parse_float, parse_int, ...])get_allocated_value
()Returns the token quantity and reserve currency quantity for this trade.
How long it took between strategy decision cycle starting and the strategy to make a decision.
Get the planned or executed quantity of the base token.
Get the planned or executed quantity of the quote token.
get_executed_value
()How long it took between strategy decision cycle starting and the trade executed.
When this trade should be executed.
Get total swap fees paid for trade.
get_full_debug_dump_str
()User friendly description for this trade
Get the maximum gas fee set to all transactions in this trade.
get_planned_reserve
()get_planned_value
()Get the planned or executed quantity of the base token.
Return the amount of USD token for the buy as raw token units.
Return the amount of USD token for the buy as raw token units.
Get the planned or executed quantity of the quote token.
get_status
()Get estimated or realised value of this trade.
Does this trade contribute towards the trading position equity.
is_buy
()This trade was succcessfully completed.
This trade was succcessfully completed.
This trade is still in planning, unallocated.
This trade is part of the normal strategy rebalance.
The automatic execution failed and this was later repaired.
is_sell
()This trade has a txid allocated.
This trade is made to close stop loss on a position.
This trade was succcessfully completed.
This trade is made to close take profit on a position.
Was this trade based on a trigger signal.
We could not confirm this trade back from the blockchain after broadcasting.
mark_broadcasted
(broadcasted_at)mark_failed
(failed_at)mark_success
(executed_at, executed_price, ...)Get diagnostics output for the trade.
schema
(*[, infer_missing, only, exclude, ...])Set the physical transactions needed to perform this trade.
to_dict
([encode_json])to_json
(*[, skipkeys, ensure_ascii, ...])Attributes
When this trade entered mempool
Timestamp of the block where the txid was first mined
What was the actual price we received
How much underlying token we traded, the actual realised amount.
How much reserves we spend for this traded, the actual realised amount.
The trade did not go through.
LP fee % recorded before the execution starts.
What is the conversation rate between quote token and US dollar used in LP fee conversion.
LP fees estimated in the USD
LP fees paid, currency convereted to the USD.
USD price per blockchain native currency unit, at the time of execution
Human readable notes about this trade
How much slippage we could initially tolerate, 0.01 is 1% slippage.
What we thought was the mid-price when we made the decision to tale this trade
Related TradePricing instance
Trade was manually repaird
How much reserves was moved on this trade before execution
retry_of
When this trade was decided
Alias for oepned_at
Trade id is unique among all trades in the same portfolio
Position id is unique among all trades in the same portfolio
Spot, margin, lending, etc.
Which trading pair this trade was for
What was the strategy cycle timestamp for it was created.
Positive for buy, negative for sell.
How many reserve tokens (USD) we use in this trade Always known accurately for buys.
What we thought the execution price for this trade would have been at the moment of strategy decision.
Which reserve currency we are going to take.
Associated blockchain transaction details.
- pair: TradingPairIdentifier#
Which trading pair this trade was for
- opened_at: datetime#
What was the strategy cycle timestamp for it was created.
Naive UTC timestamp.
If the trade was executed by a take profit/stop loss trigger then this is the trigger timestamp (not wall clock time)
See also
- planned_reserve: Decimal#
How many reserve tokens (USD) we use in this trade Always known accurately for buys. Expressed in reserve_currency.
- planned_price: float#
What we thought the execution price for this trade would have been at the moment of strategy decision.
This price includes any fees we pay for LPs, and should become executed_price if the execution is perfect.
For the market price see
planned_mid_price
.
- reserve_currency: AssetIdentifier#
Which reserve currency we are going to take. Note that pair.quote might be different from reserve currency. This is because we can do three-way trades like BUSD -> BNB -> Cake when our routing model supports this.
- planned_mid_price: Optional[float] = None#
What we thought was the mid-price when we made the decision to tale this trade
This is the market price of the asset at the time of the trade decision.
- planned_max_slippage: Optional[float] = None#
How much slippage we could initially tolerate, 0.01 is 1% slippage.
- started_at: Optional[datetime] = None#
When this trade was decided
Wall clock time.
For backtested trades, this is always set to opened_at.
- reserve_currency_allocated: Optional[Decimal] = None#
How much reserves was moved on this trade before execution
- failed_at: Optional[datetime] = None#
The trade did not go through. The timestamp when we figured this out.
- executed_quantity: Optional[Decimal] = None#
How much underlying token we traded, the actual realised amount. Positive for buy, negative for sell
- executed_reserve: Optional[Decimal] = None#
How much reserves we spend for this traded, the actual realised amount.
- lp_fees_paid: Optional[float] = None#
LP fees paid, currency convereted to the USD.
The value is read back from the realised trade. LP fee is usually % of the trade. For Uniswap style exchanges fees are always taken from amount in token and directly passed to the LPs as the part of the swap, these is no separate fee information.
- lp_fee_exchange_rate: Optional[float] = None#
What is the conversation rate between quote token and US dollar used in LP fee conversion.
We set this exchange rate before the trade is started. Both lp_fees_estimated and lp_fees_paid need to use the same exchange rate, even though it would not be timestamp accurte.
- native_token_price: Optional[float] = None#
USD price per blockchain native currency unit, at the time of execution
- blockchain_transactions: List[BlockchainTransaction]#
Associated blockchain transaction details. Each trade contains 1 … n blockchain transactions. Typically this is approve() + swap() for Uniswap v2 or just swap() if we have the prior approval and approve does not need to be done for the hot wallet anymore.
- notes: Optional[str] = None#
Human readable notes about this trade
Used to mark test trades from command line. Special case; not worth to display unless the field is filled in.
- repaired_at: Optional[datetime] = None#
Trade was manually repaird
E.g. failed broadcast issue was fixed. Marked when the repair command is called.
- price_structure: Optional[TradePricing] = None#
Related TradePricing instance
TradePricing instance can refer to more than one swap
- pretty_print()[source]#
Get diagnostics output for the trade.
Use Python pprint module.
- Return type:
- property strategy_cycle_at#
Alias for oepned_at
- property fee_tier: float | None#
LP fee % recorded before the execution starts.
Recorded as multiplier
Not available in the case this is ignored in backtesting or not supported by routers/trading pairs.
Used to calculate
lp_fees_estimated
.Sourced from Uniswap v2 router or Uniswap v3 pool information.
- property lp_fees_estimated: float#
LP fees estimated in the USD
This is set before the execution and is mostly useful for backtesting.
- is_accounted_for_equity()[source]#
Does this trade contribute towards the trading position equity.
Failed trades are reverted. Only their fees account.
- Return type:
- is_unfinished()[source]#
We could not confirm this trade back from the blockchain after broadcasting.
- Return type:
- is_repaired()[source]#
The automatic execution failed and this was later repaired.
A manual repair command was issued and it manaeged to correctly repair this trade and underlying transactions.
- Return type:
- get_raw_planned_reserve()[source]#
Return the amount of USD token for the buy as raw token units.
- Return type:
- get_raw_planned_quantity()[source]#
Return the amount of USD token for the buy as raw token units.
- Return type:
- get_position_quantity()[source]#
Get the planned or executed quantity of the base token.
Positive for buy, negative for sell.
- Return type:
- get_reserve_quantity()[source]#
Get the planned or executed quantity of the quote token.
Negative for buy, positive for sell.
- Return type:
- get_equity_for_position()[source]#
Get the planned or executed quantity of the base token.
Positive for buy, negative for sell.
- Return type:
- get_equity_for_reserve()[source]#
Get the planned or executed quantity of the quote token.
Negative for buy, positive for sell.
- Return type:
- get_value()[source]#
Get estimated or realised value of this trade.
Value is always a positive number.
- Return type:
- get_credit_debit()[source]#
Returns the token quantity and reserve currency quantity for this trade.
If buy this is (+trading position quantity/-reserve currency quantity).
If sell this is (-trading position quantity/-reserve currency quantity).
- get_fees_paid()[source]#
Get total swap fees paid for trade. Returns 0 instead of None
- Returns:
total amount of lp fees (swap fees) paid in US dollars
- Return type:
- get_execution_sort_position()[source]#
When this trade should be executed.
Lower, negative, trades should be executed first.
We need to execute sells first because we need to have cash in hand to execute buys.
- Return type:
- get_decision_lag()[source]#
How long it took between strategy decision cycle starting and the strategy to make a decision.
- Return type:
- get_execution_lag()[source]#
How long it took between strategy decision cycle starting and the trade executed.
- Return type:
- __init__(trade_id, position_id, trade_type, pair, opened_at, planned_quantity, planned_reserve, planned_price, reserve_currency, planned_mid_price=None, planned_max_slippage=None, started_at=None, reserve_currency_allocated=None, broadcasted_at=None, executed_at=None, failed_at=None, executed_price=None, executed_quantity=None, executed_reserve=None, fee_tier=<property object>, lp_fees_paid=None, lp_fees_estimated=<property object>, lp_fee_exchange_rate=None, native_token_price=None, retry_of=None, blockchain_transactions=<factory>, notes=None, repaired_at=None, price_structure=None)#
- Parameters:
trade_id (int) –
position_id (int) –
trade_type (TradeType) –
pair (TradingPairIdentifier) –
opened_at (datetime) –
planned_quantity (Decimal) –
planned_reserve (Decimal) –
planned_price (float) –
reserve_currency (AssetIdentifier) –
blockchain_transactions (List[BlockchainTransaction]) –
price_structure (Optional[TradePricing]) –
- Return type:
None
- set_blockchain_transactions(txs)[source]#
Set the physical transactions needed to perform this trade.
- Parameters:
txs (List[BlockchainTransaction]) –