Skip to content

Broker

Broker

Broker class for managing trading positions and order execution.

This class simulates a brokerage environment, handling position management, order processing, commission calculations, and P&L tracking. It provides the core trading infrastructure for backtesting strategies.

The broker manages: - Current position and average price - Cash/balance management (realized P&L + commissions) - Order execution (market and limit orders) - Commission calculations - Stop loss and take profit order management - P&L record tracking - Leverage for amplified position sizing - Margin tracking separate from equity

Accounting Model: - balance: Realized account balance after P&L and commissions - used_margin = abs(position) * mark_price / leverage - unrealized_pnl = position * (mark_price - position_avg_price) - equity = balance + unrealized_pnl - free_cash = equity - used_margin

Example

source = CSVDataSource("data.csv")
broker = Broker(source)
broker.buy(quantity=0.1) # Buy 10% of available cash
broker.sell(quantity=0.5) # Sell 50% of available position

__init__(source)

Initialize the broker with a data source.

Parameters:

Name Type Description Default
source DataSource

The data source providing market data (OHLCV prices and timestamps) for the broker to operate on.

required

buy(quantity=1, limit=None, amount=None, stop_loss=None, take_profit=None)

Place a buy order for a specified quantity.

This method creates a buy order with optional limit price, stop loss, and take profit conditions. The quantity can be specified as a percentage of available cash or as an absolute amount.

Parameters:

Name Type Description Default
quantity float

Quantity to buy as fraction of available cash (0 < quantity <= 1). Defaults to 1 (full cash amount). For example: 0.5 = buy with 50% of available cash.

1
limit float64 | None

Limit price for the order. If None, creates a market order. Defaults to None.

None
amount float64 | None

Absolute number of shares to buy. If provided, overrides quantity calculation. Defaults to None.

None
stop_loss float64 | None

Stop loss price. If provided, creates a stop loss order that executes when price falls to this level. Defaults to None.

None
take_profit float64 | None

Take profit price. If provided, creates a take profit order that executes when price rises to this level. Defaults to None.

None

Raises:

Type Description
ValueError

If quantity is not in (0, 1] range.

ValueError

If limit price is negative.

ValueError

If amount is negative.

ValueError

If attempting to buy more than available cash balance.

Note
  • If both quantity and amount are provided, amount takes precedence.
  • Orders are added to the broker's order queue and processed during the next iteration.
  • Market orders execute immediately at current open price.
  • Limit orders only execute when price reaches the specified level.
  • Leverage amplifies position size - with 2x leverage and quantity=1, you control 2x the shares while only using 1x cash as margin.
  • Opening positions deducts only commission from cash; equity remains continuous because unrealized P&L is properly tracked.
Example

broker = Broker(source)

Buy with 25% of available cash

broker.buy(quantity=0.25)

Buy exactly 100 shares at limit price $50

broker.buy(amount=100, limit=50.0)

Buy with stop loss and take profit

broker.buy(quantity=0.1, stop_loss=45.0, take_profit=55.0)

close()

Close all current positions with market orders.

This method creates market orders to liquidate the entire current position, regardless of whether it's long or short. It's commonly used at the end of a backtest or when exiting all positions.

The method creates: - A sell order if holding a long position (positive shares) - A buy order if holding a short position (negative shares)

Note
  • This method only creates orders; they are executed during the next iteration cycle.
  • No parameters are required as it closes the entire position.
  • Commission and slippage will apply to the closing trades.
  • Existing stop loss and take profit orders remain active unless explicitly cancelled.
Example

broker = Broker(source)
broker.buy(quantity=1) # Open long position

Later, close all positions

broker.close()

is_closed()

Check if currently not holding any position.

Returns:

Name Type Description
bool

True if position is zero (no open position), False otherwise.

Example

broker.close()
broker.is_closed()
True

is_long()

Check if currently holding a long position.

Returns:

Name Type Description
bool

True if position is positive (long), False otherwise.

Example

broker.buy(quantity=0.5)
broker.is_long()
True

is_short()

Check if currently holding a short position.

Returns:

Name Type Description
bool

True if position is negative (short), False otherwise.

Example

broker.sell(quantity=0.5)
broker.is_short()
True

sell(quantity=1, limit=None, amount=None, stop_loss=None, take_profit=None)

Place a sell order for a specified quantity.

This method creates a sell order with optional limit price, stop loss, and take profit conditions. The quantity can be specified as a percentage of available cash or as an absolute amount.

Parameters:

Name Type Description Default
quantity float

Quantity to sell as fraction of available cash (0 < quantity <= 1). Defaults to 1 (full cash amount). For example: 0.5 = sell shares worth 50% of available cash.

1
limit optional

Limit price for the order (same as limit parameter in buy method). If None, creates a market order. Defaults to None.

None
amount float64 | None

Absolute number of shares to sell. If provided, overrides quantity calculation. Defaults to None.

None
stop_loss float64 | None

Stop loss price for the position. Defaults to None.

None
take_profit float64 | None

Take profit price for the position. Defaults to None.

None

Raises:

Type Description
ValueError

If quantity is not in (0, 1] range.

ValueError

If limit price is negative.

ValueError

If amount is negative.

ValueError

If attempting to sell more shares than currently held.

Note
  • If both quantity and amount are provided, amount takes precedence.
  • Orders are added to the broker's order queue and processed during the next iteration.
  • Selling reduces the current position and increases cash balance.
  • Stop loss and take profit apply to remaining position after sale.
  • Realized P&L is credited to cash immediately on close.
  • Leverage amplifies short position size - with 2x leverage and quantity=1, you can short 2x the shares while only using 1x cash as margin.
Example

broker = Broker(source)
broker.buy(quantity=1) # First buy full position

Sell 50% of position

broker.sell(quantity=0.5)

Sell exactly 100 shares at limit price $52

broker.sell(amount=100, limit=52.0)

CommissionType

Bases: Enum

Enumeration for commission calculation types.

This enum defines how commissions are calculated for trades in the backtesting framework.

Attributes:

Name Type Description
PERCENTAGE int

Commission calculated as percentage of trade value (0). Commission = trade_value * commission_rate

CASH int

Commission calculated as fixed cash amount per lot (1). Commission = quantity * commission_rate / lot_size

Order dataclass

Dataclass representing a trading order.

This class encapsulates all the information needed to define and track a trading order, including its side, quantity, type, execution conditions, and current status.

Attributes:

Name Type Description
side OrderSide

Whether this is a buy or sell order.

quantity float64

Number of shares/contracts to trade.

type OrderType

Order execution type (market or limit).

price float64 | None

Limit price for limit orders, None for market orders.

stop_loss float64 | None

Stop loss price, if any.

take_profit float64 | None

Take profit price, if any.

status OrderStatus

Current status of the order.

timestamp datetime

Time when the order was created.

OrderSide

Bases: Enum

Enumeration for order side (buy/sell direction).

This enum defines whether an order is a buy (long) or sell (short) order.

Attributes:

Name Type Description
BUY int

Represents a buy order (1).

SELL int

Represents a sell order (-1).

OrderStatus

Bases: Enum

Enumeration for order execution status.

This enum tracks the current state of an order during its lifecycle.

Attributes:

Name Type Description
ACTIVE int

Order is active with stop loss or take profit conditions (0).

COMPLETE int

Order has been fully executed and no further actions needed (1).

PENDING int

Order is pending execution, waiting for price or time trigger (2).

OrderType

Bases: Enum

Enumeration for order execution types.

This enum defines how an order should be executed in the market.

Attributes:

Name Type Description
MARKET int

Market order that executes immediately at current market price (0).

LIMIT int

Limit order that executes only at specified price or better (1).

Source code

The broker module handles order execution and position management: