TradingPairSignal#

API documentation for tradeexecutor.strategy.alpha_model.TradingPairSignal Python class in Trading Strategy framework.

class TradingPairSignal[source]#

Bases: object

Present one asset in alpha model weighting.

  • The life cycle of the instance is one strategy cycle and it is part of AlphaModel

  • Asset is represented as a trading pair, as that is how we internally present assets

  • We capture all the calculations and intermediate values for a single asset in one instance (row) per each trading strategy cycle, making investigations for alpha model strategies easy

  • Required variables (pair, signal) are =input from decide_trades() function in a strategy

  • Optional variables are calculated and filled in the various phases of alpha model processing, as the model moves from abstract weightings to actual trade execution and dollar amounts

  • When we need to close old positions, we automatically generate old_weight and negative position_adjust for them

  • Data here is serialisable for visualisation a a part of the strategy state visualisation and also for console logging diagnostics

__init__(pair, signal, signal_id=<factory>, stop_loss=None, take_profit=None, trailing_stop_loss=None, raw_weight=0.0, normalised_weight=0.0, old_weight=0.0, old_value=0.0, old_pair=None, position_target=0.0, position_adjust_usd=0.0, position_adjust_quantity=0.0, position_id=None, position_adjust_ignored=False, profit_before_trades=0, profit_before_trades_pct=0, synthetic_pair=None, leverage=None)#
Parameters:
Return type:

None

Methods

__init__(pair, signal[, signal_id, ...])

from_dict(kvs, *[, infer_missing])

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

get_flip_label()

Get flip label

has_trades()

Did/should this signal cause any trades to be executed.

is_closing()

is_flipping()

On this cycle, are we flipping between long and short.

is_new()

The asset did not have any trades (long/short) open on the previous cycle.

is_short()

Is the underlying trading activity for this signal to short the asset.

is_spot()

Is the underlying trading activity for this signal buy spot asset.

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

to_dict([encode_json])

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

Attributes

pair

For which pair is this alpha weight.

signal

Raw signal.

signal_id

Running counter signal ids

stop_loss

Stop loss for this position.

take_profit

Take profit for this position

trailing_stop_loss

Trailing stop loss for this position

raw_weight

Raw portfolio weight

normalised_weight

Weight 0...1 so that all portfolio weights sum to 1

old_weight

Old weight of this pair from the previous cycle.

old_value

Old US Dollar value of this value from the previous cycle.

old_pair

Which trading pair this signal was using before.

position_target

How many dollars we plan to invest on trading pair.

position_adjust_usd

How much we are going to increase/decrease the position on this strategy cycle.

position_adjust_quantity

How much we are going to increase/decrease the position on this strategy cycle.

position_id

Trading position that is controlled by this signal.

position_adjust_ignored

No rebalancing trades was executed for this position adjust.

profit_before_trades

What was the profit of the position of this signal.

profit_before_trades_pct

What was the profit of the position of this signal.

synthetic_pair

For leveraged and spot positions, the pair we use to construct the position.

leverage

How much leverage we dare to take with this signal

pair: TradingPairIdentifier#

For which pair is this alpha weight.

Always the spot pair, the determines the asset price. For lending protocol leveraged trading this is the underlying trading pair.

See also :py:attr`leveraged_pair`.

signal: float#

Raw signal.

E.g. raw value of the momentum.

Negative signal indicates short.

Can be any number between ]-inf, inf[

Set zero for pairs that are discarded, e.g. due to risk assessment.

signal_id: int#

Running counter signal ids

  • Useful for internal debugging onyl

  • Signal ids are not stable - only for single process debugging

stop_loss: Optional[float]#

Stop loss for this position.

Used for the risk management.

0.98 means 2% stop loss over mid price at open.

Set to None to disable stop loss.

take_profit: Optional[float]#

Take profit for this position

Used for the risk management.

1.02 means 2% take profit over mid price at open.

Set to None to disable stop loss.

trailing_stop_loss: Optional[float]#

Trailing stop loss for this position

See tradeexecutor.state.position.TradingPosition.trailing_stop_loss_pct for details.

raw_weight: float#

Raw portfolio weight

Represents USD allocated to this position.

Each raw signal is assigned to a weight based on some methodology, e.g. 1/N where the highest signal gets 50% of portfolio weight.

Negative signals have positive weight.

normalised_weight: float#

Weight 0…1 so that all portfolio weights sum to 1

Represents USD allocated to this position.

Negative signals have positive weight.

old_weight: float#

Old weight of this pair from the previous cycle.

If this asset was part of the portfolio at previous strategy cycle then this is the value of the previous cycle weight. The old weight is always normalised.

This can be dynamically calculated from the tradeexecutor.state.portfolio.Portfolio state.

old_value: float#

Old US Dollar value of this value from the previous cycle.

If this asset was part of the portfolio at previous strategy cycle then this is the value of the previous cycle weight.

old_pair: tradeexecutor.state.identifier.TradingPairIdentifier | None#

Which trading pair this signal was using before.

Allows us to switch between spot, leveraged long, leveraged short.

position_target: float#

How many dollars we plan to invest on trading pair.

Calculated by portfolio total investment equity * normalised weight * price.

position_adjust_usd: float#

How much we are going to increase/decrease the position on this strategy cycle.

Used when the position increases and we need to know how many dollars we need to spend to buy more.

If this is a positive, then we need to make a buy trade for this amount to reach out target position for this cycle. If negative then we need to decrease our position.

position_adjust_quantity: float#

How much we are going to increase/decrease the position on this strategy cycle.

Used when the position decreases and we need to know how many units of asset we need to sell to get to the position_target.

At the momeny always negative and available only when decreasing a position.

Note that this value is not used when closing position (weight=0), due to rounding and epsilon errors.

position_id: Optional[int]#

Trading position that is controlled by this signal.

Query with tradeexecutor.state.portfolio.Portfolio.get_position_by_id()

After open, any position will live until it is fully closed. After that a new position will be opened.

position_adjust_ignored: bool#

No rebalancing trades was executed for this position adjust.

This is because the resulting trade is under the minimum trade threshold.

profit_before_trades: float#

What was the profit of the position of this signal.

Record the historical profit as the part of the signal model. Makes building alpha model visualisation easier later, so that we can show the profitability of the position of the signal.

Calculate the position profit before any trades were executed.

profit_before_trades_pct: float#

What was the profit of the position of this signal.

Record the historical profit as the part of the signal model. Makes building alpha model visualisation easier later, so that we can show the profitability of the position of the signal.

Calculate the position profit before any trades were executed.

synthetic_pair: tradeexecutor.state.identifier.TradingPairIdentifier | None#

For leveraged and spot positions, the pair we use to construct the position.

This is the leveraged pair derived from pair. Can be leveraged long, leveraged shor or directly the underlying spot pair.

This information is not available until the trades have been calculated in AlphaModel.generate_rebalance_trades_and_triggers().

For spot pairs, this is the pair itself.

leverage: float | None#

How much leverage we dare to take with this signal

Unset for spot.

has_trades()[source]#

Did/should this signal cause any trades to be executed.

  • We have trades if we need to rebalance (old weight != new weight)

  • Even if the weight does not change we might still rebalance because the prices change

  • Some adjustments might be too small and then we just ignore any trades and have :py:attr:position_adjust_ignored` flag set

Return type:

bool

is_short()[source]#

Is the underlying trading activity for this signal to short the asset.

See also py:attr:leveraged_pair.

Return type:

bool

is_spot()[source]#

Is the underlying trading activity for this signal buy spot asset.

See also py:attr:is_short.

Return type:

bool

is_new()[source]#

The asset did not have any trades (long/short) open on the previous cycle.

Return type:

bool

is_flipping()[source]#

On this cycle, are we flipping between long and short.

  • Closing the position to zero does not count as flipping

  • If there was no signal on the previous signal, it’s not flipping either

Returns:

True if the pair is going to flip

Return type:

bool

get_flip_label()[source]#

Get flip label

Return type:

str

__init__(pair, signal, signal_id=<factory>, stop_loss=None, take_profit=None, trailing_stop_loss=None, raw_weight=0.0, normalised_weight=0.0, old_weight=0.0, old_value=0.0, old_pair=None, position_target=0.0, position_adjust_usd=0.0, position_adjust_quantity=0.0, position_id=None, position_adjust_ignored=False, profit_before_trades=0, profit_before_trades_pct=0, synthetic_pair=None, leverage=None)#
Parameters:
Return type:

None