Skip to content

Account snapshots and execution events

View Markdown

Use snapshots to inspect current account state and callbacks to react to actual order changes. These values are created by the framework and are read-only.

AccountSnapshot · PositionSnapshot · ClosedTradeStats · OrderSnapshot · OrderSizingSnapshot · OrderEvent · Fill · TradeAllocation · RunSummary

Log an execution and inspect the account

from openbacktesting import Backtest, Strategy
from openbacktesting.test import GOOG

class ObserveExecution(Strategy):
    def init(self):
        self.fill_prices = []

    def next(self):
        if self.bar_index == 0:
            self.buy(qty=1)
        elif self.bar_index == 5:
            self.position.close()

    def on_order(self, event):
        order = event.snapshot
        self.log.info(f"{order.order_id}: {order.status}; {order.reason}")

    def on_fill(self, fill):
        self.fill_prices.append(fill.price)
        self.log.info(f"Executed {fill.qty} at {fill.price}; fee {fill.fee}")

    def on_finish(self, summary):
        self.log.info(f"Finished: {summary.reason}; equity {summary.account.equity}")

bt = Backtest(GOOG.iloc[:20], ObserveExecution)
result = bt.run()
print(result["_strategy"].fill_prices)
print(bt.get_logs()[-1])

on_order receives an event whose snapshot contains the order ID/status/reason. on_fill receives the actual execution directly. on_finish receives the final account and termination reason. A saved snapshot does not change when another fill occurs. Orders submitted in notifications cannot match recursively; on_start and on_finish do not permit trading.

Read the current state

Inside next(), read self.account.equity, .margin_available, or .fees_paid; use self.position.snapshot.long_qty/short_qty for two-sided exposure. self.closed_trade_stats.win_rate is a fraction (0.5 means 50%) and is None before any closure. These counts describe closed portions, including partial exits.

Values returned by trading and callbacks

These are read-only records, not objects you need to construct. Order.snapshot and .sizing describe status and the original sizing decision. on_order(event) receives an OrderEvent; on_fill(fill) receives a Fill. on_finish(summary) receives a RunSummary. Result ledgers expose the same facts as plain tables. Timestamps/bar positions identify when something happened; IDs join orders, fills, and trade allocations.

AccountSnapshot

Single-currency linear margin account; balance is not securities settlement cash.

Attribute Type Meaning
balance float Initial balance plus realized gross P/L minus paid fees.
equity float Balance plus unrealized gross P/L.
realized_pnl_gross float Realized price P/L before fees.
unrealized_pnl_gross float Unrealized price P/L before fees.
fees_paid float Total actual fees charged.
margin_used float Gross notional multiplied by the margin fraction.
margin_available float Remaining nonnegative margin capacity.
gross_notional float Absolute notional across both directions.
net_notional float Signed net notional at the observation price.

PositionSnapshot

Net position, two-sided gross exposure, and explicit gross and net profit or loss.

Attribute Type Meaning
net_qty float Signed net asset quantity.
gross_qty float Total absolute quantity across open lots.
long_qty float Total long quantity.
short_qty float Total short quantity.
long_avg_price float \| None Average entry price of the long leg, or None.
short_avg_price float \| None Average entry price of the short leg, or None.
avg_price float \| None Common entry basis, or None for flat/hedged exposure.
gross_notional float Absolute notional across both directions.
net_notional float Signed net notional at the observation price.
unrealized_pnl_gross float Unrealized price P/L before fees.
unrealized_pnl_net float Unrealized P/L after remaining entry fees.
entry_fees_remaining float Entry fees allocated to still-open quantity.
return_fraction float \| None Net return as a fraction; None if no common basis exists.

Attributes

Attribute Meaning
has_exposure A two-sided net-zero position still has gross exposure.

ClosedTradeStats

Cumulative closed portions as of the read; fees are allocated, and unrealized profit or loss is excluded.

Attribute Type Meaning
closed_count int Number of closed fragments, including partial exits.
win_count int Closed fragments with positive net P/L.
loss_count int Closed fragments with negative net P/L.
even_count int Closed fragments with exactly zero net P/L.
winning_profit float Sum of positive closed-fragment net P/L.
losing_amount float Absolute sum of negative closed-fragment net P/L.
net_profit float Total closed-fragment net P/L.
average_profit float \| None Mean net P/L per closed fragment, or None without closures.
win_rate float \| None Winning fraction from 0 to 1, or None without closures.

OrderSnapshot

Frozen order values at a state transition.

Attribute Type Meaning
order_id str Order identifier within the run.
status OrderStatus Current OrderStatus value.
filled_qty float Executed quantity so far.
remaining_qty float Quantity still awaiting execution.
avg_fill_price float \| None Average execution price, or None before a fill.
reason str \| None Reason for the recorded decision or termination.
triggered bool Whether the stop trigger has activated.

OrderSizingSnapshot

Sizing basis frozen at submission; budgets do not guarantee actual fill notional or fees.

Attribute Type Meaning
mode Literal['qty', 'amount', 'percent'] qty, amount, or percent.
source Literal['explicit', 'default'] Whether sizing was explicit or supplied by the default.
value float Original size value; percent uses percentage points (20 means 20%).
equity float Balance plus unrealized gross P/L.
reference_price float Price used to calculate the requested quantity.
budget float \| None Notional or risk budget; None for a pure quantity request.
qty float Asset quantity in native units.

OrderEvent

Immutable order event with time and phase.

Attribute Type Meaning
sequence int Monotonically ordered event position within the run.
bar_index int Zero-based input bar position.
timestamp object Market-data index value at the event.
phase str Execution phase that produced the event.
snapshot OrderSnapshot Frozen OrderSnapshot containing order_id, status, and reason.

Fill

An actual execution; fees are recorded exactly once here.

Attribute Type Meaning
fill_id str Actual execution identifier.
order_id str Order identifier within the run.
sequence int Monotonically ordered event position within the run.
side str Buy or sell direction.
qty float Asset quantity in native units.
price float Actual execution price.
fee float Fee charged or allocated to this execution.
bar_index int Zero-based input bar position.
timestamp object Market-data index value at the event.
phase str Execution phase that produced the event.
reason str Reason for the recorded decision or termination.

TradeAllocation

Allocation of an execution quantity to entry lots or closed portions.

Attribute Type Meaning
allocation_id str Identifier of this allocation between a fill and a trade.
fill_id str Actual execution identifier.
trade_id str Lot identifier shared by its partial exits.
entry_fill_id str Execution that opened the lot.
kind str Whether the fill allocation opens or closes a lot.
qty float Asset quantity in native units.
fee float Fee charged or allocated to this execution.
entry_fee float Entry fee allocated to this closed portion.
realized_pnl_gross float Realized price P/L before fees.

RunSummary

Frozen summary for the finish hook; error text does not replace the original exception.

Attribute Type Meaning
reason str Reason for the recorded decision or termination.
account AccountSnapshot Final AccountSnapshot for the run.
error str \| None Failure text, or None when no error was recorded.

Orders and positions · Strategy · Results