Skip to content

PaperBroker and Paper Execution

PaperBroker is AQE’s execution simulator for:

  • backtesting
  • paper trading
  • validating insight lifecycle behaviour

It handles:

  • order submission
  • fills
  • cancels
  • close requests
  • bracket legs
  • trailing stop execution
  • trade event emission
  • account and equity state

It is also responsible for preventing invalid paper account states, such as orders that would exceed available buying power.

YahooFinanceDataFeed provides:

  • ticker metadata
  • historical bars
  • latest quotes
  • latest bars
  • live bar stream subscription

That is the default market-data path used for historical research and paper-oriented runtime workflows.

AQE models asset fees separately from gross trade PnL. Asset.fees contains:

  • commission.entry.long and commission.entry.short for opening long and short positions
  • commission.exit.long and commission.exit.short for closing long and short positions
  • swap.long and swap.short for overnight financing or credit on long and short positions

Long and short refer to the position side, not just the immediate order action. A buy order that opens exposure uses the long entry fee. A sell order that opens exposure uses the short entry fee. When a position closes, AQE applies the exit fee and swap for the original position side, so commission.exit.short is the close fee for a short position even though the close action is a buy.

Commission and swap use the same public fee kind enum, AssetFee. The available fee kinds are:

  • AssetFee::None
  • AssetFee::Points(points), used for point-based swap calculation
  • AssetFee::PercentageFee(rate), where 0.001 means 0.1% of traded notional
  • AssetFee::FixedFee(amount), a fixed amount per fill
  • AssetFee::PerContractFee(amount), multiplied by traded quantity
  • AssetFee::PercentagePerContractFee(rate), applied as price * contract_size * quantity * rate

Commission calculations accept positive PercentageFee, FixedFee, PerContractFee, and PercentagePerContractFee values. Points is present on the shared enum because swap needs it; if used in a commission field, AQE treats it as zero.

Swap values may be positive or negative. A positive swap increases PnL and a negative swap reduces PnL. On paper execution, AQE calculates net close PnL as:

gross PnL + swap - entry commission - exit commission

Use with_asset_fees(...) when creating the paper execution broker. Backtests generated by AQS use the same path.

use aq_engine::core::broker::paper_broker::PaperBroker;
use aq_engine::core::broker::types::{
AccountType, AssetCommissionFees, AssetFee, AssetFees, AssetSideFees, AssetSwapFees,
};
let fees = AssetFees {
commission: AssetCommissionFees {
entry: AssetSideFees {
long: AssetFee::PercentageFee(0.0005),
short: AssetFee::PercentageFee(0.0007),
},
exit: AssetSideFees {
long: AssetFee::FixedFee(1.0),
short: AssetFee::FixedFee(1.0),
},
},
swap: AssetSwapFees {
long: AssetFee::PerContractFee(-3.25),
short: AssetFee::PercentagePerContractFee(0.000041),
},
..AssetFees::default()
};
let execution = PaperBroker::new(AccountType::Paper, 100_000.0, 1).with_asset_fees(fees);

The legacy entry and exit fields on AssetFees are still accepted as a compatibility fallback when the side-specific commission object is empty. New configurations should use the commission and swap objects.

  • aq-engine/src/core/broker/paper_broker.rs
  • aq-engine/src/core/broker/types/mod.rs
  • aq-engine/src/core/broker/data_feeds/yahoo.rs