pub struct OpenOrders { /* private fields */ }Expand description
A venue’s open orders, indexed for lookup by id and for matching in price-time order.
§Why two indices
The two accesses want opposite things. Cancelling an order, and answering a snapshot, address
one order by ClientOrderId. Matching a tick walks an instrument’s orders from the best price
down, and must stop as soon as the price stops crossing.
Holding only the map makes matching a sort of every open order on every tick. Holding only the queues makes a cancel a scan. The map owns the orders, the queues hold ids.
§Why price-time and not “whatever the map yields”
A tick that crosses two resting orders with only enough balance to fill one fills whichever
comes first. Read off a hash map, that is an arbitrary choice which a rebuild or a different
ClientOrderId can silently reverse, so two runs of one backtest need not agree. Price-time
priority is both the reproducible rule and the one real venues use.
§Orders with no price
An order resting without a limit price cannot be ranked against one, and is not a thing a venue holds: an order with no price to wait at has nothing to wait for. Such an order is kept in the map — a snapshot must report everything the account holds — but is absent from the queues, so matching can never reach it. It arrives one of two ways:
- through a configured
initial_state, and then nothing matches it, ever; - through
hold: a market order the venue is holding until its instrument’s next bar, or its next fresh observation. Those are kept in a fourth index, per instrument and in arrival order, whichtake_heldempties when what they wait for arrives.
§Why a third index for deadlines
A TimeInForce::GoodTillDate order retires at a stated instant, and the venue sweeps for such
orders on every clock advance and every market tick. Neither of the other two indices can
answer “which orders are past their deadline”: a deadline is unrelated to price, so the
price-time queues cannot be walked with a take_while the way matching walks them, and the map
is unordered. Answering from either would mean scanning every open order on every tick.
A third index therefore holds only the orders that have a deadline, keyed by it. A sweep is
a range query that stops at the first order still working, so it costs nothing when nothing can
expire — which is every venue whose orders are all GoodUntilCancelled, including every
market-order-only backtest.
§Reservations, and the ones that are not there
An order the venue booked itself carries the Reservation the venue took for it, so a fill
settles and a cancel releases the same amount that was held — see RestingOrder.
An order seeded by a configured initial_state carries None, because the venue never took
anything for it. Cancelling such an order therefore releases nothing and restates no balance.
That is the honest answer rather than a convenient one: the snapshot says an order is resting
and says what the balances are, but not which order any held portion belongs to, so a venue
that credited a release would be inventing the amount.
Implementations§
Source§impl OpenOrders
impl OpenOrders
Sourcepub fn insert(
&mut self,
order: OpenOrder,
reservation: Option<Reservation>,
) -> Result<(), AlreadyResting>
pub fn insert( &mut self, order: OpenOrder, reservation: Option<Reservation>, ) -> Result<(), AlreadyResting>
Inserts order holding reservation against it, unless an order is already resting under
its ClientOrderId.
§Errors
AlreadyResting, carrying order and reservation back untouched, if an order is already
held under its id. The book is left exactly as it was: the order already resting keeps its
queue position, its deadline and its own reservation. reservation is handed back rather
than dropped because it may already be held against the account, and only the caller knows
the ledger to give it back to.
reservation is None only for an order the venue did not book itself — see the type’s
note on reservations. It is a parameter rather than a later setter so that an order cannot
reach the book in a state where what is held against it has not yet been decided.
Sourcepub fn hold(
&mut self,
order: OpenOrder,
reservation: Option<Reservation>,
) -> Result<(), AlreadyResting>
pub fn hold( &mut self, order: OpenOrder, reservation: Option<Reservation>, ) -> Result<(), AlreadyResting>
Holds order, a market order with no price, until its venue releases it, with
reservation held against it.
Kept in the map like any open order, so a snapshot reports it and a cancel finds it, and
queued behind every order already held on its instrument. Matching never reaches it: only
take_held does.
§Errors
AlreadyResting, as for insert, leaving the book exactly as it was.
§Panics
Panics if order carries a price. A priced order is queued for matching, which a held one
must never be, and would leave the held index out of step with the book.
Sourcepub fn holds(&self, instrument: &InstrumentNameExchange) -> bool
pub fn holds(&self, instrument: &InstrumentNameExchange) -> bool
Whether any order is held on instrument.
Sourcepub fn held_on(&self, instrument: &InstrumentNameExchange) -> &[ClientOrderId]
pub fn held_on(&self, instrument: &InstrumentNameExchange) -> &[ClientOrderId]
The orders held on instrument, earliest arrival first, still held.
For a caller that releases some of them and leaves the rest waiting: it
removes those it releases, which takes them out of the hold too.
Sourcepub fn take_held(
&mut self,
instrument: &InstrumentNameExchange,
) -> Vec<ClientOrderId>
pub fn take_held( &mut self, instrument: &InstrumentNameExchange, ) -> Vec<ClientOrderId>
The orders held on instrument, earliest arrival first, no longer held.
Each stays in the map until its caller removes it, which is what lets the
caller take its reservation with it.
Sourcepub fn held(&self) -> Vec<ClientOrderId>
pub fn held(&self) -> Vec<ClientOrderId>
Every order held, on any instrument: by instrument, then earliest arrival first. A total order, so whatever a caller does with them happens in the same order on every run.
Sourcepub fn contains(&self, cid: &ClientOrderId) -> bool
pub fn contains(&self, cid: &ClientOrderId) -> bool
Whether an order is resting under cid.
Sourcepub fn remove(&mut self, cid: &ClientOrderId) -> Option<RestingOrder>
pub fn remove(&mut self, cid: &ClientOrderId) -> Option<RestingOrder>
Removes and returns the order held under cid, with whatever is held against it.
Sourcepub fn expired_as_of(&self, now: DateTime<Utc>) -> Vec<ClientOrderId>
pub fn expired_as_of(&self, now: DateTime<Utc>) -> Vec<ClientOrderId>
Every order whose deadline has been reached by now, earliest deadline first.
“Reached” is inclusive: an order with a deadline of exactly now is returned, because a
TimeInForce::GoodTillDate order stops working at its stated instant rather than after
it. The venue relies on this to make a deadline an unconditional cutoff — see
SimulatedVenue::advance_time.
Returned rather than iterated because the caller retires each one, which borrows self
mutably. The walk stops at the first order still working, so it costs a single comparison
when nothing is due, whatever the size of the book.
Sourcepub fn next_expiry(&self) -> Option<DateTime<Utc>>
pub fn next_expiry(&self) -> Option<DateTime<Utc>>
The earliest deadline of any open order, or None if none has one.
pub fn get(&self, cid: &ClientOrderId) -> Option<&OpenOrder>
pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool
Sourcepub fn iter(&self) -> impl Iterator<Item = &OpenOrder> + '_
pub fn iter(&self) -> impl Iterator<Item = &OpenOrder> + '_
Every open order, in no particular order.
Callers that need a reproducible sequence must impose one — resting for
matching, or an explicit sort for a snapshot.
Sourcepub fn resting(
&self,
instrument: &InstrumentNameExchange,
side: Side,
) -> impl Iterator<Item = &OpenOrder> + '_
pub fn resting( &self, instrument: &InstrumentNameExchange, side: Side, ) -> impl Iterator<Item = &OpenOrder> + '_
One instrument’s resting orders on one side, best price first and earliest first within a price.
This is the order a venue matches in, so a caller filling against a crossing tick takes them as they come and stops at the first that does not cross.
Trait Implementations§
Source§impl Debug for OpenOrders
impl Debug for OpenOrders
Auto Trait Implementations§
impl Freeze for OpenOrders
impl RefUnwindSafe for OpenOrders
impl Send for OpenOrders
impl Sync for OpenOrders
impl Unpin for OpenOrders
impl UnsafeUnpin for OpenOrders
impl UnwindSafe for OpenOrders
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreimpl<T> JsonSchemaMaybe for T
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.