pub struct SpotMarginConfig(/* private fields */);Expand description
Spot margin on the simulated venue: what it lends a spot order, how much, and what it repays.
Off by default: MockExecutionConfig::spot_margin is None, and the venue is a cash account
whose spot orders must be paid for with what it holds. With a configuration, it is a cross
margin account, with one pool of balances shared by every instrument, which lends a spot order
what it lacks and reports each balance’s loan as Binance’s margin account does.
§What it lends, and when
Each spot order has a MarginEffect: its request’s margin_effect, else this
configuration’s margin_effect. An order with MarginEffect::Borrow
that the account cannot pay for with its free balance borrows the shortfall, and only the
shortfall, of the asset it pays with: base for a sell, quote for a buy. It borrows when the
venue accepts the order, as Binance does, so a resting limit order or a held market order is
lent its shortfall at once, and the venue holds it against the order as it holds any other
balance. An asset the account has never held is opened with the loan.
An order that is cancelled, expires or is refused at its fill before it fills repays what it
borrowed, interest first, and a held market order that fills for less than was held repays the
part of its loan it no longer needs, if auto_repay_at_cancel
is on (the default, as on Binance). One that fills in part and rests the remainder pays for the
part that filled with the account’s own balance first, so the loan is held against the
remainder and repaid if the remainder is cancelled.
An order with MarginEffect::NoSideEffect or MarginEffect::Repay lends nothing: one it
cannot pay for is rejected as on a cash account. A loan already in the venue’s initial state
is left as it is, and balances still report their loans.
Only spot orders borrow. A CFD’s margin is posted from the quote asset’s free balance, as
without this configuration, and a CFD order carrying MarginEffect::Borrow or
MarginEffect::Repay is refused with
OrderError::UnsupportedMarginEffect.
§How much it lends
A borrow is allowed while the account’s debt, after it, is at most max_leverage − 1 times
the account’s equity. Both are valued in valuation_asset:
- Each asset is valued at the mid of an instrument on the venue that pairs it with the
valuation asset, else that market’s last price, in either direction (
BTC/USDT, or the inverse ofUSDT/BTC). The valuation asset is worth one. A market priced at zero values nothing. - Equity is the sum over assets of
total − borrowed − interest, valued that way. An asset the venue cannot value counts as no equity, which understates what the account can borrow rather than overstating it. - Debt is the sum over assets of
borrowed + interest, valued the same way. The venue lends nothing while it cannot value a debt, and never lends an asset it cannot value.
An order that needs more than that is rejected as unaffordable, with a reason that says how
much the venue would lend. A max_leverage of one lends nothing, but still reports each
balance’s loan.
§What it repays
Under MarginEffect::Repay, whatever a fill delivers into an asset the account owes repays
that asset’s loan, interest first, then principal, and only the rest becomes free balance. What
a buy delivers is its quantity less any fee charged in base, so a buy of exactly what is owed,
with a base fee, leaves a fee-sized loan. Gross the buy up by the fee to clear it. Under the
other two effects a fill repays nothing: as on Binance, a repay is per order, and nothing
repays a loan automatically.
§What it does not model
- Liquidation. An account whose debt grows past its equity keeps trading; nothing closes its positions.
- Isolated margin. One pool of balances backs every instrument.
- Per-asset borrow limits and the venue’s lending pool. Only the leverage limit applies.
- Interest, by this configuration alone. A venue given a
MarginInterestModelcharges it; see that trait.
new refuses a max_leverage below one, and so does deserialising one, so a
configuration that exists is one the venue can apply. Serialised, max_leverage is a decimal
string ("3"), as the crate writes decimals elsewhere, so no precision is lost to a float.
Implementations§
Source§impl SpotMarginConfig
impl SpotMarginConfig
Sourcepub fn new(
valuation_asset: AssetNameExchange,
max_leverage: Decimal,
margin_effect: MarginEffect,
) -> Result<Self, SpotMarginConfigError>
pub fn new( valuation_asset: AssetNameExchange, max_leverage: Decimal, margin_effect: MarginEffect, ) -> Result<Self, SpotMarginConfigError>
Spot margin applying margin_effect to each order that does not carry its own, up to
max_leverage over the account’s equity, valued in valuation_asset.
The effect has no default, so that a configuration says whether the venue may take on debt
for an order. Unused loans are repaid when their order ends unfilled; see
with_auto_repay_at_cancel.
§Errors
Returns SpotMarginConfigError if max_leverage is below one.
Sourcepub fn with_auto_repay_at_cancel(self, auto_repay_at_cancel: bool) -> Self
pub fn with_auto_repay_at_cancel(self, auto_repay_at_cancel: bool) -> Self
This configuration, repaying a loan its order no longer needs (the order was cancelled,
expired or refused at its fill, or a held market order filled for less than was held) when
auto_repay_at_cancel is true, and leaving it owed when false.
On by default, as Binance’s autoRepayAtCancel is. With it off, an unused loan stays owed
until a MarginEffect::Repay order repays it.
Sourcepub fn valuation_asset(&self) -> &AssetNameExchange
pub fn valuation_asset(&self) -> &AssetNameExchange
The asset equity and debt are valued in.
Sourcepub fn max_leverage(&self) -> Decimal
pub fn max_leverage(&self) -> Decimal
The most the account may hold, as a multiple of its equity: its debt may reach
max_leverage − 1 times its equity.
Sourcepub fn margin_effect(&self) -> MarginEffect
pub fn margin_effect(&self) -> MarginEffect
The effect of an order whose request carries none.
Sourcepub fn auto_repay_at_cancel(&self) -> bool
pub fn auto_repay_at_cancel(&self) -> bool
Whether a loan its order no longer needs is repaid. See
with_auto_repay_at_cancel.
Trait Implementations§
Source§impl Clone for SpotMarginConfig
impl Clone for SpotMarginConfig
Source§impl Debug for SpotMarginConfig
impl Debug for SpotMarginConfig
Source§impl<'de> Deserialize<'de> for SpotMarginConfig
impl<'de> Deserialize<'de> for SpotMarginConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for SpotMarginConfig
Source§impl Hash for SpotMarginConfig
impl Hash for SpotMarginConfig
Source§impl Ord for SpotMarginConfig
impl Ord for SpotMarginConfig
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
1.21.0 (const: unstable) · Source§fn min(self, other: Self) -> Selfwhere
Self: Sized,
fn min(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialEq for SpotMarginConfig
impl PartialEq for SpotMarginConfig
Source§impl PartialOrd for SpotMarginConfig
impl PartialOrd for SpotMarginConfig
Source§impl Serialize for SpotMarginConfig
impl Serialize for SpotMarginConfig
impl StructuralPartialEq for SpotMarginConfig
Auto Trait Implementations§
impl Freeze for SpotMarginConfig
impl RefUnwindSafe for SpotMarginConfig
impl Send for SpotMarginConfig
impl Sync for SpotMarginConfig
impl Unpin for SpotMarginConfig
impl UnsafeUnpin for SpotMarginConfig
impl UnwindSafe for SpotMarginConfig
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.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.