State#
API documentation for tradeexecutor.state.state.State Python class in Trading Strategy framework.
- class State[source]#
Bases:
object
The current state of the trading strategy execution.
It tells the current and past state of a single trading strategy execution: positions, their trades and related valuations, metrics and such data.
This class is the root object of the serialisable state tree for a trading strategy.
Can be serialised as JSON
Contains one
Portfolio
object that contains all positions, trades and underlying blockchain transactionsContains one
Visualisation
object that contains run-time calculated and stored visualisation about the portfolioContains one
Statistics
object that contains run-time calculated and stored metrics about the portfolio
Uses of this class include
Backtest fills in the state when simulating the trades
The live execution environment keeps its internal state on a disk as a serialised
State
objectAnalysis and performance metrics read the state
The web frontend reads the state
- __init__(created_at=<factory>, last_updated_at=None, cycle=1, name=None, portfolio=<factory>, stats=<factory>, asset_blacklist=<factory>, visualisation=<factory>, uptime=<factory>, sync=<factory>, backtest_data=None, other_data=<factory>)#
- Parameters:
created_at (datetime) –
cycle (int) –
portfolio (Portfolio) –
stats (Statistics) –
visualisation (Visualisation) –
uptime (Uptime) –
sync (Sync) –
backtest_data (tradeexecutor.state.state.BacktestData | None) –
- Return type:
None
Methods
__init__
([created_at, last_updated_at, ...])blacklist_asset
(asset)Add a asset to the blacklist.
Check that the state data is intact.
create_trade
(strategy_cycle_at, pair, ...[, ...])Creates a request for a new trade.
from_dict
(kvs, *[, infer_missing])from_json
(s, *[, parse_float, parse_int, ...])Get the age of the strategy execution in human-readable format.
Get the age of the strategy execution.
Get the time range for which the strategy should have data.
Get the time range for which the strategy should have data.
Get the time range when the strategy could have made trades.
is_empty
()This state has no open or past trades or reserves.
is_good_pair
(pair)Check if the trading pair is blacklisted.
mark_broadcasted
(broadcasted_at, trade)mark_ready
(timestamp)Mark that the strategy has enough (backtest) data to decide the first trade.
mark_trade_failed
(failed_at, trade)Unroll the allocated capital.
mark_trade_success
(executed_at, trade, ...)After trade has been successfully executed, update the state of our internal ledged to reflect this.
Check that we are not reusing any trade or position ids and counters are correct.
read_json_blob
(text)Parse state from JSON blob.
read_json_file
(path)Read state from the JSON file.
revalue_positions
(ts, valuation_method)Revalue all open positions in the portfolio.
schema
(*[, infer_missing, only, exclude, ...])start_execution
(ts, trade[, txid, nonce, ...])Update our balances and mark the trade execution as started.
start_execution_all
(ts, trades[, ...])Mark a bunch of trades ready to go.
supply_credit
(strategy_cycle_at, pair, ...)Create or adjust credit supply position.
to_dict
([encode_json])to_json
(*[, skipkeys, ensure_ascii, ...])Serialise to JSON format with helpful validation and error messages.
trade_short
(strategy_cycle_at, pair, ...[, ...])Creates a trade for a short position.
update_reserves
(new_reserves)write_json_file
(path)Write JSON to a file.
Attributes
When this state was created
When this state was saved
The next cycle.
The name of this strategy.
Portfolio of this strategy.
Portfolio and position performance records over time.
Assets that the strategy is not allowed to touch, or have failed to trade in the past, resulting to a frozen position.
Strategy visualisation and debug messages to show how the strategy is thinking.
Trade execution uptime and success statistcis]
sync
Backtest data related to this backtest result
Misc.
- last_updated_at: Optional[datetime]#
When this state was saved
UTC timestamp. Set by by
tradeexecutor.state.store.StateStore.sync()
- cycle: int#
The next cycle.
How many strategy thinking and execution cycles we have completed successfully.
Starts with 1 (no cycles completed)
- stats: Statistics#
Portfolio and position performance records over time.
- asset_blacklist: Set[str]#
Assets that the strategy is not allowed to touch, or have failed to trade in the past, resulting to a frozen position. Besides this internal black list, the executor can have other blacklists based on the trading universe and these are not part of the state. The main motivation of this list is to avoid assets that caused a freeze in the future. Key is Ethereum address, lowercased.
- visualisation: Visualisation#
Strategy visualisation and debug messages to show how the strategy is thinking.
- uptime: Uptime#
Trade execution uptime and success statistcis]
Contains statistics about trade execution having to manage to run its internal functions.
- backtest_data: tradeexecutor.state.state.BacktestData | None#
Backtest data related to this backtest result
Data that is relevant only for backtest results, not live trading.
- is_good_pair(pair)[source]#
Check if the trading pair is blacklisted.
- Parameters:
pair (TradingPairIdentifier) –
- Return type:
- mark_ready(timestamp)[source]#
Mark that the strategy has enough (backtest) data to decide the first trade.
This marks the difference between the backtesting data availability period, and actual tradeable period when all indicators have enough data.
See
BacktestData.ready_at
for more informationCan be called multiple times, only the first time counts
See
get_trading_time_range()
for readingIf you do not call this method in decide_trades(), nothing bad happens, but backtest benchmark indices (buy and hold BTC, etc.) might have biases results to a direction or another
- Parameters:
timestamp (datetime.datetime | pandas._libs.tslibs.timestamps.Timestamp) –
- get_strategy_time_range()[source]#
Get the time range for which the strategy should have data.
If this is a backtest, return backtesting range
If this is a live execution, return created - last updated
See also
get_trading_time_range()
- get_trading_time_range()[source]#
Get the time range when the strategy could have made trades.
If live trading same as
get_strategy_time_range()
See
mark_ready()
for settingSee
get_strategy_time_range()
to get the full data availability range of a backtest
- get_strategy_duration()[source]#
Get the age of the strategy execution. If backtest, return backtest range, if live, return created - last updated
See
get_strategy_time_range()
for details.- Returns:
Age of the strategy execution, or None if the age cannot be calculated.
- Return type:
datetime.timedelta | None
- get_formatted_strategy_duration()[source]#
Get the age of the strategy execution in human-readable format.
See
get_strategy_duration()
for details.- Returns:
Age of the strategy execution in human-readable format.
- Return type:
- create_trade(strategy_cycle_at, pair, quantity, reserve, assumed_price, trade_type, reserve_currency, reserve_currency_price, notes=None, pair_fee=None, lp_fees_estimated=None, planned_mid_price=None, price_structure=None, position=None, slippage_tolerance=None, leverage=None, closing=False, planned_collateral_consumption=None, planned_collateral_allocation=None, flags=None, pending=False)[source]#
Creates a request for a new trade.
If there is no open position, marks a position open.
Trade can be opened by knowing how much you want to buy (quantity) or how much cash you have to buy (reserve).
To open a spot buy, fill in reseve amount you wish to use for the buy
To open a spot sell, fill in quoantity amount you wish to use for the buy, as a negative number
- Parameters:
strategy_cycle_at (datetime) – The strategy cycle timestamp for which this trade was executed.
trade_id – Trade id allocated by the portfolio
quantity (Optional[Decimal]) –
How many units this trade does.
Positive for buys, negative for sells in the spot market.
For short positions, negative quantity means increase the position of this much, positive quantity means decrease the position.
Any fees have been already reduced away from this quantity, as
PriceModel
gives the planned price that includes fees.assumed_price (float) –
The planned execution price.
This is the price we expect to pay per quantity unit after the execution. This is the mid price + any LP fees included.
trade_type (TradeType) – What kind of a trade is this.
reserve_currency (AssetIdentifier) –
Which portfolio reserve we use for this trade.
- param reserve_currency_price:
If the quote token is not USD, then the exchange rate between USD and quote token we assume we have.
Actual exchange rate may depend on the execution.
notes (Optional[str]) – Any human-readable remarks we want to tell about this trade.
pair_fee (Optional[float]) – The fee tier from the trading pair / overriden fee.
lp_fees_estimated (Optional[float]) – HOw much we estimate to pay in LP fees (dollar)
planned_mid_price (Optional[float]) – What was the mid-price of the trading pair when we started to plan this trade.
How many reserve units this trade produces/consumes.
I.e. dollar amount for buys/sells.
price_structure (Optional[TradePricing]) –
The full planned price structure for this trade.
The state of the market at the time of planning the trade, and what fees we assumed we are going to get.
position (Optional[TradingPosition]) –
Override the position for the trade.
Use for close trades (you need to explicitly tell which position to close as there might be two positions with the same pair)
Use for repair trades.
notes – Human-readable string to show on the trade.
slippage_tolerance (Optional[float]) –
Slippage tolerance for this trade.
See
tradeexecutor.state.trade.TradeExecution.slippage_tolerance
for details.This trade should close the position entirely.
A flag used with leveraged positions.
pending –
Do not generate a new open position.
Used when adding take profit triggers to market limit position.
pair (TradingPairIdentifier) –
reserve_currency_price (float) –
- Returns:
Tuple of entries
Trade position (old/new)
New trade
True if a a new position was opened
- Return type:
- trade_short(strategy_cycle_at, pair, borrowed_asset_price, trade_type, reserve_currency, collateral_asset_price, borrowed_quantity=None, collateral_quantity=None, notes=None, pair_fee=None, lp_fees_estimated=None, planned_mid_price=None, price_structure=None, position=None, slippage_tolerance=None, closing=False, planned_collateral_consumption=None, planned_collateral_allocation=None, flags=None)[source]#
Creates a trade for a short position.
Opens, increases or decreases short position size.
For argument and return value documentation see
create_trade()
.See also
supply_credit()
.- Parameters:
borrowed_quantity (Optional[Decimal]) –
How much we are going to borrow and increase/decrease our exposure.
Our short position size in the target token.
Negative for increasing short position size
Positive for reducing the short position size
See
test_short_increase_size
andtest_short_decrease_size
for an example.collateral_quantity (Optional[Decimal]) –
How much reserve currency we are going to use as a collateral for loans.
This is moved from cash reserves to lending protocol deposit.
Always positive when opening
Can be zero and in this case, the shorted token is bought or sold and this will affect the underlying loan health factor
For releasing collateral see
planned_collateral_allocation
argument. Seetest_short_decrease_size
for an example.borrowed_asset_price (float) –
What is the assumed price of the token we are going to borrow.
We estimate fees and value selling it short.
This trade should close any remaining exposure and return the collateral after the trade.
If set, norrowed quantity and collateral quantity are automatically calculated.
planned_collateral_consumption (Optional[Decimal]) – See
tradeexecutor.state.trade.TradeExecution.planned_collateral_consumption
.planned_collateral_allocation (Optional[Decimal]) – See
tradeexecutor.state.trade.TradeExecution.planned_collateral_allocation
.strategy_cycle_at (datetime) –
pair (TradingPairIdentifier) –
trade_type (TradeType) –
reserve_currency (AssetIdentifier) –
collateral_asset_price (float) –
price_structure (Optional[TradePricing]) –
position (Optional[TradingPosition]) –
- Returns:
Trading position, trade execution and created flag.
TradeExecution.planned_loan
is set.After the trade succeeds,
TradingPosition.loan
is set.If the trade does not succeed loan data remains unchanged.
- Return type:
- supply_credit(strategy_cycle_at, pair, trade_type, reserve_currency, collateral_asset_price, collateral_quantity=None, notes=None, pair_fee=None, lp_fees_estimated=None, planned_mid_price=None, price_structure=None, position=None, slippage_tolerance=None, closing=False, flags=None)[source]#
Create or adjust credit supply position.
Credit supply position trades are modelled as following
You BUY aToken using the reserve. Like buying aUSDC with USDC.
You SELL aToken and get back reserve + interest, with the trade size reserve + interest
Reserve is USDC, always positive
The modelling is different from trade_short/trade_long
See also
trade_short()
- Parameters:
collateral_quantity (Optional[Decimal]) – Positive for supplying credit, negative of recalling reserves.
strategy_cycle_at (datetime) –
pair (TradingPairIdentifier) –
trade_type (TradeType) –
reserve_currency (AssetIdentifier) –
collateral_asset_price (float) –
price_structure (Optional[TradePricing]) –
position (Optional[TradingPosition]) –
- Return type:
- start_execution(ts, trade, txid=None, nonce=None, underflow_check=False, triggered=False)[source]#
Update our balances and mark the trade execution as started.
Called before a transaction is broadcasted.
Updates internal accounting and moves capital from the reserve account locked on a trade
See also
start_execution_all()
.- Parameters:
trade (TradeExecution) – Trade to
underflow_check –
Raise exception if we have not enough cash to allocate.
The check disabled by default. Might be legit for portfolio strats that need to sell old assets before buying new assets.
txid (str | None) – Legacy. Do not use.
nonce (int | None) – Legacy. Do not use.
triggered – True if this execution is from stop loss trigger checks, otherwise from decision trades cycle.
ts (datetime) –
- mark_trade_success(executed_at, trade, executed_price, executed_amount, executed_reserve, lp_fees, native_token_price, cost_of_gas=None, executed_collateral_consumption=None, executed_collateral_allocation=None, force=False)[source]#
After trade has been successfully executed, update the state of our internal ledged to reflect this.
Trade is marked as successfully complete
All position sizes are updated to match executed values (instead of planned values)
Mark any LP and gas fees from the trade
If this was the final trade of the position, mark the position closed
- mark_trade_failed(failed_at, trade)[source]#
Unroll the allocated capital.
- Parameters:
failed_at (datetime) –
trade (TradeExecution) –
- revalue_positions(ts, valuation_method)[source]#
Revalue all open positions in the portfolio.
Reserves are not revalued.
- blacklist_asset(asset)[source]#
Add a asset to the blacklist.
- Parameters:
asset (AssetIdentifier) –
- perform_integrity_check()[source]#
Check that we are not reusing any trade or position ids and counters are correct.
- Raise:
Assertion error in the case internal data structures are damaged
- start_execution_all(ts, trades, max_slippage=None, underflow_check=False, rebroadcast=False, triggered=False)[source]#
Mark a bunch of trades ready to go.
Update any internal accounting of capital allocation from reseves to trades.
Sets the execution model specific parameters like max_slippage on the trades.
See also
start_execution()
- Parameters:
ts (datetime) – Strategy cycle timestamp
trades (List[TradeExecution]) – List of trades to prepare
max_slippage (float) –
Legacy. Do not use.
The slippage allowed for this trade before it fails in execution. 0.01 is 1%.
underflow_check –
Legacy. Do not use.
If true warn us if we do not have enough reserves to perform the trades. This does not consider new reserves released from the closed positions in this cycle.
- check_if_clean()[source]#
Check that the state data is intact.
Check for the issues that could be caused e.g. trade-executor unclean shutdown or a blockchain node crash.
One of a typical issue would be
A trade that failed to execute
A trade that was broadcasted, but we did not get a confirmation back in time, causing the trade executor to crash
Call this when you restart a trade execution to ensure the old state is intact. For any unfinished trades, run a repair command or manually repair the database.
- Raises:
UncleanState – In the case we detect unclean stuff
- to_json_safe()[source]#
Serialise to JSON format with helpful validation and error messages.
Extra validation adds performance overhead.
- Returns:
The full strategy execution state as JSON string.
The strategy can be saved on a disk, resumed, or server to the web frontend using this JSON blob.
- Return type:
- write_json_file(path)[source]#
Write JSON to a file.
Validates state before writing it out
Work around any serialisation quirks
- Parameters:
path (pathlib.Path | str) –
- get_strategy_start_and_end()[source]#
Get the time range for which the strategy should have data.
TODO: Clean up this. In the future, each strategy must record its start (launched at) and end (last run) dates on the state itself.
- Return type:
tuple[pandas._libs.tslibs.timestamps.Timestamp | None, pandas._libs.tslibs.timestamps.Timestamp | None]
- static read_json_file(path)[source]#
Read state from the JSON file.
Deal with all serialisation quirks
- Parameters:
path (pathlib.Path | str) –
- Return type:
- __init__(created_at=<factory>, last_updated_at=None, cycle=1, name=None, portfolio=<factory>, stats=<factory>, asset_blacklist=<factory>, visualisation=<factory>, uptime=<factory>, sync=<factory>, backtest_data=None, other_data=<factory>)#
- Parameters:
created_at (datetime) –
cycle (int) –
portfolio (Portfolio) –
stats (Statistics) –
visualisation (Visualisation) –
uptime (Uptime) –
sync (Sync) –
backtest_data (tradeexecutor.state.state.BacktestData | None) –
- Return type:
None