Skip to main content

PaperExchange

Struct PaperExchange 

Source
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 difference

Implementations§

Source§

impl<E: Exchange> PaperExchange<E>

Source

pub fn new(quote_source: E, initial_balances: HashMap<AssetId, Decimal>) -> Self

Create a new paper exchange wrapping a real quote source

Source

pub async fn set_balance(&self, asset: AssetId, amount: Decimal)

Set a balance directly (for testing)

Source

pub async fn register_instrument_meta(&self, meta: &InstrumentMeta)

Register instrument metadata for quote-aware paper/backtest accounting.

Source

pub async fn register_instrument_metas(&self, metas: &[InstrumentMeta])

Register several instrument metadata records.

Source

pub async fn balance(&self, asset: &AssetId) -> Decimal

Get current balance

Source

pub async fn pending_orders_count(&self) -> usize

Get pending orders count

Source

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

Source

pub async fn get_balances(&self) -> HashMap<AssetId, Decimal>

Get current balances (for testing)

Source

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)

Source

pub async fn set_instrument_leverage( &self, instrument: &InstrumentId, leverage: Decimal, max_leverage: Decimal, )

Set leverage for an instrument in the margin ledger

Source

pub async fn free_usdc(&self) -> Decimal

Get the margin ledger’s free USDC (for testing)

Source

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.

Source

pub async fn disable_simulation_mode(&self)

Disable simulation mode - return to using real exchange quotes.

Source

pub async fn is_simulation_mode(&self) -> bool

Check if simulation mode is enabled.

Source

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.

Source

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.

Source

pub async fn has_queued_quotes(&self) -> bool

Check if there are still queued quotes remaining. Use this to detect when backtesting is complete.

Source

pub async fn queue_len(&self) -> usize

Get the number of queued quotes remaining.

Source

pub async fn clear_quote_queue(&self)

Clear all queued quotes.

Source

pub async fn set_time(&self, time_ms: i64)

Set simulated time (for deterministic testing).

Source

pub async fn advance_time(&self, delta_ms: i64)

Advance simulated time by delta milliseconds.

Source

pub async fn current_time(&self) -> i64

Get current simulated time.

Source

pub async fn fills(&self) -> Vec<Fill>

Get all simulated fills (for testing).

Trait Implementations§

Source§

impl<E: Exchange + Send + Sync> Exchange for PaperExchange<E>

Source§

fn exchange_id(&self) -> &ExchangeId

Get the exchange ID
Source§

fn environment(&self) -> Environment

Get the environment (mainnet/testnet)
Source§

fn place_orders<'life0, 'life1, 'async_trait>( &'life0 self, orders: &'life1 [OrderInput], ) -> Pin<Box<dyn Future<Output = Result<Vec<PlaceOrderResult>, ExchangeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Place multiple limit orders in a single batch API call. Returns a Vec of results, one for each order in the same order as the input.
Source§

fn cancel_order<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, _instrument: &'life1 InstrumentId, _market_index: &'life2 MarketIndex, client_id: &'life3 ClientOrderId, _exchange_order_id: Option<&'life4 ExchangeOrderId>, ) -> Pin<Box<dyn Future<Output = Result<(), ExchangeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Cancel an order by client_id or exchange_order_id.
Source§

fn cancel_all_orders<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, instrument: &'life1 InstrumentId, _market_index: &'life2 MarketIndex, ) -> Pin<Box<dyn Future<Output = Result<u32, ExchangeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Cancel all orders for an instrument. Returns number of orders canceled.
Source§

fn poll_user_fills<'life0, 'life1, 'async_trait>( &'life0 self, _cursor: Option<&'life1 str>, ) -> Pin<Box<dyn Future<Output = Result<Vec<Fill>, ExchangeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Poll user fills since cursor. This is the primary execution event source. cursor is opaque string (implementation-specific).
Source§

fn poll_quotes<'life0, 'life1, 'async_trait>( &'life0 self, instruments: &'life1 [InstrumentId], ) -> Pin<Box<dyn Future<Output = Result<Vec<Quote>, ExchangeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Poll current quotes/prices.
Source§

fn poll_account_state<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<AccountState, ExchangeError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Poll account state (absolute). Used for snapshot-based synchronization.
Source§

fn instance(&self) -> ExchangeInstance

Get the exchange instance key
Source§

fn init<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<(), ExchangeError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Initialize the exchange connection and perform startup validations. Called by the runner before entering the main loop. Implementations can validate: connectivity, vault ownership, account balance, etc.

Auto Trait Implementations§

§

impl<E> !RefUnwindSafe for PaperExchange<E>

§

impl<E> !UnwindSafe for PaperExchange<E>

§

impl<E> Freeze for PaperExchange<E>
where E: Freeze,

§

impl<E> Send for PaperExchange<E>

§

impl<E> Sync for PaperExchange<E>

§

impl<E> Unpin for PaperExchange<E>
where E: Unpin,

§

impl<E> UnsafeUnpin for PaperExchange<E>
where E: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more