Core components

class qtrade.core.Broker(data: DataFrame | dict[str, DataFrame], cash: float, commission: Commission | None, margin_ratio: float | dict[str, float], trade_on_close: bool, contract_multiplier: float | dict[str, float] | None = None)[source]

Bases: object

The Broker class is responsible for executing orders and managing positions.

Internally Broker tracks positions and OHLCV data per asset (keyed by string symbol); a single-asset DataFrame passed to the constructor is wrapped under the key "default" for backwards compatibility, so existing single-asset workflows continue to use the same external API (broker.data, broker.position).

Variables:
  • cash (float) – Current shared cash balance across all assets.

  • commission (Optional[Commission]) – Instance for calculating trade commissions. If None, no commission is applied.

  • margin_ratio (float) – Margin ratio (0 < margin_ratio ≤ 1).

  • trade_on_close (bool) – If True, orders are filled at the current close price. Otherwise, at the next open price.

  • current_time (pd.Timestamp) – Timestamp of the current bar.

  • _pending_orders (List[Order]) – Pending orders (e.g., stop/limit orders) awaiting execution.

  • _executing_orders (List[Order]) – Orders to be executed at the next bar’s open price if trade_on_close is False.

  • _filled_orders (List[Order]) – List of filled orders.

  • _closed_orders (List[Order]) – List of rejected/canceled orders.

  • _equity_history (pd.Series) – Portfolio-level historical record of account equity.

Parameters:
  • data (pd.DataFrame | dict[str, pd.DataFrame]) – Market data with [‘Open’, ‘High’, ‘Low’, ‘Close’] columns. Pass a single DataFrame for a single-asset backtest (wrapped internally as {"default": data}) or a dict of DataFrames keyed by asset symbol for multi-asset.

  • cash (float) – Initial cash balance. Must be positive.

  • commission (Optional[Commission]) – Commission calculator instance.

  • margin_ratio (float | dict[str, float]) – Margin requirement. Pass a scalar to apply uniformly, or a dict keyed by asset for per-asset settings (e.g. 1.0 for stocks, 0.05 for futures). Each value must be in (0, 1].

  • trade_on_close (bool) – Execution mode for orders.

  • contract_multiplier (float | dict[str, float] | None, optional) – Contract size for futures-style instruments. 100 for COMEX gold (1 price tick = $100 P&L per contract), 50 for E-mini S&P. Pass a dict keyed by asset for portfolios mixing stocks and futures of different categories. Defaults to None (multiplier of 1.0 — stock semantics).

Raises:
  • AssertionError – If cash is not positive or any margin_ratio is out of bounds.

  • ValueError – If a per-asset dict is missing keys or has unknown keys.

property assets: list[str]

List of asset symbols this broker tracks.

property available_margin: float

Available margin for new trades, summed across all assets.

Per-asset margin = abs(size) × multiplier × current_price × margin_ratio[asset].

close_all_positions() None[source]

Close all open positions across every asset at the current bar’s close.

property closed_orders: tuple[Order, ...]

Get a tuple of all closed orders.

property closed_trades: tuple[Trade, ...]

Closed trades across all assets (concatenated; per-asset access via positions).

property cumulative_returns: float

Cumulative returns (equity / initial equity).

property data: DataFrame

Single-asset access. For multi-asset, use data_by_asset.

property data_by_asset: dict[str, DataFrame]

Per-asset OHLCV data.

property equity: float

Calculate the current equity of the account (cash + total unrealized P&L).

property equity_history: Series

Get a copy of the equity history (portfolio-level).

property filled_orders: tuple[Order, ...]

Get a tuple of all filled orders.

get_trade_history() DataFrame[source]

Trade-by-trade DataFrame across all assets.

property margin_ratio: float

Single-asset margin ratio. For multi-asset, use margin_ratio_by_asset.

property margin_ratio_by_asset: dict[str, float]

Per-asset margin ratios.

property multiplier_by_asset: dict[str, float]

Per-asset contract multipliers (1.0 = stock semantics).

place_orders(orders: Order | list[Order]) None[source]

Submit one or multiple orders.

Parameters:

orders (Union[Order, List[Order]]) – A single order or a list of orders.

Raises:

TypeError – If orders is neither an Order instance nor a list of Orders.

property position: Position

Single-asset access. For multi-asset, use positions.

property positions: dict[str, Position]

Per-asset Position objects.

process_bar(current_time: Timestamp) None[source]

Process the trading logic for the current bar.

property realized_pnl: float

Sum of realized P&L from all closed trades across all assets.

property unrealized_pnl: float

Sum of unrealized P&L across all active trades on every asset.

Per-trade P&L = size × multiplier × (current_price entry_price).

property unrealized_pnl_pct: float

Unrealized P&L as a percentage of total initial margin (across all assets).

class qtrade.core.Commission[source]

Bases: ABC

Abstract base class for different commission schemes.

abstract calculate_commission(order_size: int, fill_price: float) float[source]

Calculate the commission for an order.

Parameters:
  • order_size – Order size (positive for buy, negative for sell)

  • fill_price – Order fill price

Returns:

Commission fee

class qtrade.core.FixedCommission(fixed_fee: float)[source]

Bases: Commission

Commission scheme with a fixed fee per order.

Parameters:

fixed_fee – Fixed commission fee per order

Raises:

ValueError – If fixed_fee is negative.

calculate_commission(order_size: int, fill_price: float) float[source]

Calculate commission as a fixed fee per order.

Parameters:
  • order_size – Order size (positive for buy, negative for sell)

  • fill_price – Order fill price

Returns:

Fixed commission fee

class qtrade.core.NoCommission[source]

Bases: Commission

Commission scheme with no fees.

calculate_commission(order_size: int, fill_price: float) float[source]

Returns zero commission.

Parameters:
  • order_size – Order size (positive for buy, negative for sell)

  • fill_price – Order fill price

Returns:

0.0

class qtrade.core.Order(size: int, limit: float | None = None, stop: float | None = None, sl: float | None = None, tp: float | None = None, tag: object | None = None, asset: str = 'default', *, trail_percent: float | None = None, trail_amount: float | None = None)[source]

Bases: object

Represents a trading order with optional limit, stop, stop loss, and take profit prices.

Variables:
  • size (int) – Order size (positive for buy, negative for sell).

  • limit (Optional[float]) – Limit price for limit orders.

  • stop (Optional[float]) – Stop price for stop orders.

  • sl (Optional[float]) – Stop loss price.

  • tp (Optional[float]) – Take profit price.

  • tag (Optional[object]) – Tag for identifying the order.

  • is_filled (bool) – Indicates if the order has been filled.

  • is_closed (bool) – Indicates if the order has been canceled or rejected.

  • fill_price (Optional[float]) – Price at which the order was filled.

  • fill_date (Optional[pd.Timestamp]) – Date when the order was filled.

Parameters:
  • size (int) – Order size (positive for buy, negative for sell).

  • limit (Optional[float], optional) – Limit price for limit orders. Defaults to None.

  • stop (Optional[float], optional) – Stop price for stop orders. Defaults to None.

  • sl (Optional[float], optional) – Stop loss price. Defaults to None.

  • tp (Optional[float], optional) – Take profit price. Defaults to None.

  • trail_percent (Optional[float], optional) – Trailing-stop distance as a fraction of the high-water mark (e.g. 0.05 = 5%). Mutually exclusive with trail_amount. The Broker auto-bumps the SL each bar so it ratchets in the trade’s favor only.

  • trail_amount (Optional[float], optional) – Trailing-stop distance as an absolute price gap (account currency). Mutually exclusive with trail_percent.

  • tag (Optional[object], optional) – Tag for identification. Defaults to None.

  • asset (str, optional) – Asset symbol this order targets. Defaults to “default” for single-asset backtests. Multi-asset support is layered on this field.

Raises:
  • AssertionError – If the order size is zero.

  • ValueError – If both trail_percent and trail_amount are set, or either is non-positive.

property asset: str

Asset symbol this order targets.

Type:

str

cancel() None[source]

Cancel the order.

property fill_date: Timestamp | None

Fill date.

Type:

Optional[pd.Timestamp]

property fill_price: float | None

Fill price.

Type:

Optional[float]

property is_closed: bool

Indicates if the order is canceled or rejected.

Type:

bool

property is_filled: bool

Indicates if the order is filled.

Type:

bool

property is_long: bool

True if the order is a long position.

Type:

bool

property is_short: bool

True if the order is a short position.

Type:

bool

property limit: float | None

Limit price.

Type:

Optional[float]

property size: int

Order size.

Type:

int

property sl: float | None

Stop loss price.

Type:

Optional[float]

property stop: float | None

Stop price.

Type:

Optional[float]

property tag: object | None

Order tag.

Type:

Optional[object]

property tp: float | None

Take profit price.

Type:

Optional[float]

property trail_amount: float | None

Trailing-stop absolute distance.

Type:

Optional[float]

property trail_percent: float | None

Trailing-stop fraction (e.g. 0.05 for 5%).

Type:

Optional[float]

class qtrade.core.PercentageCommission(percentage: float)[source]

Bases: Commission

Commission scheme based on a percentage of the order value.

Parameters:

percentage – Commission percentage (e.g., 0.001 for 0.1%)

Raises:

ValueError – If percentage is negative.

calculate_commission(order_size: int, fill_price: float) float[source]

Calculate commission as a percentage of the order value.

Parameters:
  • order_size – Order size (positive for buy, negative for sell)

  • fill_price – Order fill price

Returns:

Calculated commission fee

class qtrade.core.Position[source]

Bases: object

Represents a trading position containing active and closed trades.

Initialize the Position with empty lists for active and closed trades.

property active_trades: tuple[Trade, ...]

Get a tuple of all active trades.

Returns:

Tuple[Trade, …] – Active trades.

property closed_trades: tuple[Trade, ...]

Get a tuple of all closed trades.

Returns:

Tuple[Trade, …] – Closed trades.

property size: int

Calculates the total size of all active trades.

class qtrade.core.SlippageCommission(slippage_percentage: float)[source]

Bases: Commission

Commission scheme that accounts for slippage as a percentage of the order value.

Parameters:

slippage_percentage – Slippage percentage (e.g., 0.001 for 0.1%)

Raises:

ValueError – If slippage_percentage is negative.

calculate_commission(order_size: int, fill_price: float) float[source]

Calculate slippage as a percentage of the order value.

Parameters:
  • order_size – Order size (positive for buy, negative for sell)

  • fill_price – Order fill price

Returns:

Calculated slippage fee

class qtrade.core.Trade(entry_price: float, entry_date: Timestamp, entry_index: int, size: int, sl: float | None = None, tp: float | None = None, tag: object | None = None, asset: str = 'default', multiplier: float = 1.0, *, trail_percent: float | None = None, trail_amount: float | None = None)[source]

Bases: object

Represents an individual trade with entry and exit details, profit calculations, and trade status.

Variables:
  • _size (int) – Trade size (positive for long, negative for short).

  • _entry_price (float) – Price at which the trade was entered.

  • _entry_date (pd.Timestamp) – Date when the trade was entered.

  • _sl (Optional[float]) – Stop loss price.

  • _tp (Optional[float]) – Take profit price.

  • _trail_percent (Optional[float]) – Trailing-stop fraction (e.g. 0.05 for 5%).

  • _trail_amount (Optional[float]) – Trailing-stop absolute distance.

  • _trail_high (Optional[float]) – High-water mark for long trailing stops.

  • _trail_low (Optional[float]) – Low-water mark for short trailing stops.

  • _tag (Optional[object]) – Tag for identifying the trade.

  • _exit_price (Optional[float]) – Price at which the trade was exited.

  • _exit_date (Optional[pd.Timestamp]) – Date when the trade was exited.

  • _profit (Optional[float]) – Profit or loss from the trade.

  • _exit_reason (Optional[str]) – Reason for exiting the trade (‘signal’, ‘sl’, ‘tp’, ‘end’).

Parameters:
  • entry_price (float) – Price at which the trade was entered.

  • entry_date (pd.Timestamp) – Date when the trade was entered.

  • size (int) – Trade size (positive for long, negative for short).

  • sl (Optional[float], optional) – Stop loss price. Defaults to None.

  • tp (Optional[float], optional) – Take profit price. Defaults to None.

  • trail_percent (Optional[float], optional) – Trailing-stop distance as a fraction of the current high-water mark (e.g. 0.05 = 5%). Mutually exclusive with trail_amount. Defaults to None.

  • trail_amount (Optional[float], optional) – Trailing-stop distance as an absolute price gap (in account currency). Mutually exclusive with trail_percent. Defaults to None.

  • tag (Optional[object], optional) – Tag for identifying the trade. Defaults to None.

  • asset (str, optional) – Asset symbol this trade is on. Defaults to “default” for single-asset backtests. Multi-asset support is layered on this field.

  • multiplier (float, optional) – Contract multiplier for futures-style instruments (e.g. 100 for COMEX gold, 50 for E-mini S&P). 1 share = 1 unit of price for stocks. Profit and margin both scale with this. Defaults to 1.0.

Raises:

ValueError – If the trade size is zero, or both trail_percent and trail_amount are set, or either trail value is non-positive.

property asset: str

Asset symbol this trade is on.

Type:

str

close(size: int | None, exit_price: float, exit_date: Timestamp, exit_index: int, exit_reason: str) Trade[source]

Closes a portion or full of the trade and records exit details.

Parameters:
  • size (int) – Size to close (must not exceed current trade size).

  • exit_price (float) – Price at which the trade is closed.

  • exit_date (pd.Timestamp) – Date when the trade is closed.

  • exit_reason (str) – Reason for closing (‘signal’, ‘sl’, ‘tp’, ‘end’).

Returns:

Trade – A new Trade instance representing the closed portion.

Raises:

ValueError – If attempting to close more than the current trade size or if the trade is already fully closed.

property entry_date: Timestamp

Date when the trade was entered.

Type:

pd.Timestamp

property entry_index: int

Index when the trade was entered.

Type:

int

property entry_price: float

Price at which the trade was entered.

Type:

float

property exit_date: Timestamp | None

Date when the trade was exited.

Type:

Optional[pd.Timestamp]

property exit_index: int | None

Index when the trade was exited.

Type:

Optional[int]

property exit_price: float | None

Price at which the trade was exited.

Type:

Optional[float]

property exit_reason: str | None

Reason for exiting the trade.

Returns:

Optional[str] – Exit reason if the trade is closed, otherwise None.

Type:

Optional[str]

property is_closed: bool

True if the trade has been fully closed.

Type:

bool

property is_long: bool

True if the trade is a long position.

Type:

bool

property is_short: bool

True if the trade is a short position.

Type:

bool

property multiplier: float

Contract multiplier (1.0 for stocks, e.g. 100 for COMEX GC).

Type:

float

property profit: float | None

Profit or loss from the trade.

Returns:

Optional[float] – Profit if the trade is closed, otherwise None.

Type:

Optional[float]

property size: int

Current size of the trade.

Type:

int

property sl: float | None

Stop loss price (modifiable).

Type:

Optional[float]

property tag: object | None

Tag for identifying the trade.

Type:

Optional[object]

property tp: float | None

Take profit price (modifiable).

Type:

Optional[float]

property trail_amount: float | None

Trailing-stop absolute distance, or None if not trailing.

Type:

Optional[float]

property trail_high: float | None

High-water mark for long trailing stop.

Type:

Optional[float]

property trail_low: float | None

Low-water mark for short trailing stop.

Type:

Optional[float]

property trail_percent: float | None

Trailing-stop fraction, or None if not trailing.

Type:

Optional[float]

update_exit_levels(sl: float | None = _UNSET, tp: float | None = _UNSET) None[source]

Modify SL / TP on an open trade.

Pass None to clear a level; omit a parameter to leave it unchanged. Useful for hand-rolled trailing logic, ratcheting up a stop after a profit threshold, or moving TP further out.

Parameters:
  • sl – New stop-loss price. Pass None to clear the existing SL.

  • tp – New take-profit price. Pass None to clear the existing TP.

Example

>>> trade.update_exit_levels(sl=110)        # set/move SL only
>>> trade.update_exit_levels(tp=None)       # clear TP
>>> trade.update_exit_levels(sl=110, tp=130)  # both at once