pub struct PaperExchange<E: Exchange> { /* private fields */ }Expand description
Paper Exchange - wraps a real exchange for quotes, simulates fills locally.
Uses FillSimulator for shared fill matching logic.
§Usage
let real_exchange = HyperliquidExchange::new(config);
let paper = PaperExchange::new(real_exchange, initial_balances);
// Use paper as the exchange - strategies see no differenceImplementations§
Source§impl<E: Exchange> PaperExchange<E>
impl<E: Exchange> PaperExchange<E>
Sourcepub fn new(quote_source: E, initial_balances: HashMap<AssetId, Decimal>) -> Self
pub fn new(quote_source: E, initial_balances: HashMap<AssetId, Decimal>) -> Self
Create a new paper exchange wrapping a real quote source
Sourcepub async fn set_balance(&self, asset: AssetId, amount: Decimal)
pub async fn set_balance(&self, asset: AssetId, amount: Decimal)
Set a balance directly (for testing)
Sourcepub async fn register_instrument_meta(&self, meta: &InstrumentMeta)
pub async fn register_instrument_meta(&self, meta: &InstrumentMeta)
Register instrument metadata for quote-aware paper/backtest accounting.
Sourcepub async fn register_instrument_metas(&self, metas: &[InstrumentMeta])
pub async fn register_instrument_metas(&self, metas: &[InstrumentMeta])
Register several instrument metadata records.
Sourcepub async fn pending_orders_count(&self) -> usize
pub async fn pending_orders_count(&self) -> usize
Get pending orders count
Sourcepub async fn set_fee_rate(&self, fee_rate: Decimal)
pub async fn set_fee_rate(&self, fee_rate: Decimal)
Set fee rate for fill simulation (e.g., 0.0004 = 0.04%) For spot BUY orders, fee is deducted from base asset
Sourcepub async fn get_balances(&self) -> HashMap<AssetId, Decimal>
pub async fn get_balances(&self) -> HashMap<AssetId, Decimal>
Get current balances (for testing)
Sourcepub async fn get_position(&self, instrument: &InstrumentId) -> Decimal
pub async fn get_position(&self, instrument: &InstrumentId) -> Decimal
Get position for an instrument (for testing) Returns the net position qty (positive = long, negative = short)
Sourcepub async fn set_instrument_leverage(
&self,
instrument: &InstrumentId,
leverage: Decimal,
max_leverage: Decimal,
)
pub async fn set_instrument_leverage( &self, instrument: &InstrumentId, leverage: Decimal, max_leverage: Decimal, )
Set leverage for an instrument in the margin ledger
Sourcepub async fn enable_simulation_mode(&self)
pub async fn enable_simulation_mode(&self)
Enable simulation mode - quotes will come from injected_quotes instead of real exchange. This allows deterministic testing where you control the price feed.
Sourcepub async fn disable_simulation_mode(&self)
pub async fn disable_simulation_mode(&self)
Disable simulation mode - return to using real exchange quotes.
Sourcepub async fn is_simulation_mode(&self) -> bool
pub async fn is_simulation_mode(&self) -> bool
Check if simulation mode is enabled.
Sourcepub async fn inject_quote(
&self,
instrument: InstrumentId,
bid: Decimal,
ask: Decimal,
)
pub async fn inject_quote( &self, instrument: InstrumentId, bid: Decimal, ask: Decimal, )
Inject a quote for simulation testing. When simulation mode is enabled, poll_quotes will return these instead of real quotes.
Sourcepub async fn queue_quotes(&self, quotes: Vec<Quote>)
pub async fn queue_quotes(&self, quotes: Vec<Quote>)
Queue multiple quotes for batch backtesting (FIFO). When quotes are queued, poll_quotes will pop from this queue first. This enables fast-forward backtesting with realistic price-crossing fills.
Sourcepub async fn has_queued_quotes(&self) -> bool
pub async fn has_queued_quotes(&self) -> bool
Check if there are still queued quotes remaining. Use this to detect when backtesting is complete.
Sourcepub async fn clear_quote_queue(&self)
pub async fn clear_quote_queue(&self)
Clear all queued quotes.
Sourcepub async fn advance_time(&self, delta_ms: i64)
pub async fn advance_time(&self, delta_ms: i64)
Advance simulated time by delta milliseconds.
Sourcepub async fn current_time(&self) -> i64
pub async fn current_time(&self) -> i64
Get current simulated time.