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 of the asset it
pays with (base for a sell, quote for a buy), or that asset’s
min_borrow if it is more, as Binance does. 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. What
a minimum borrow lends beyond the shortfall is not held: it is free balance, owed. 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. What a minimum borrow lent beyond the
shortfall is repaid with the rest if the order ends before it fills in full, and stays owed
once it does.
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. So is one whose asset’s min_borrow is more
than that, since the venue never lends less than the minimum, and its reason names the minimum
too. A max_leverage of one lends nothing, but still reports each balance’s loan.
It lends nothing while a liquidation is under way: see SpotMarginLiquidation.
§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.
§Liquidation
Off by default: an account whose debt grows past its equity keeps trading, and nothing closes
its positions. Configured with with_liquidation, the venue repays
every debt once the account’s margin level falls to the configured level, selling what the
account holds as needed. See SpotMarginLiquidation.
§What it does not model
- Isolated margin. One pool of balances backs every instrument.
- Per-asset borrow limits and the venue’s lending pool. Only the leverage limit, and each asset’s minimum borrow, apply.
- Interest, by this configuration alone. A venue given a
MarginInterestModelcharges it; see that trait.
new refuses a max_leverage below one, with_min_borrow
a negative minimum, with_liquidation a liquidation the leverage
limit could reach, and so does deserialising any of them, so a configuration that exists is
one the venue can apply. Serialised, max_leverage and each minimum borrow are decimal strings
("3"), as the crate writes decimals elsewhere, so no precision is lost to a float.
min_borrow is a map from asset to minimum, left out when empty, and liquidation is left out
when off.
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.
Sourcepub fn with_min_borrow(
self,
asset: AssetNameExchange,
min_borrow: Decimal,
) -> Result<Self, SpotMarginConfigError>
pub fn with_min_borrow( self, asset: AssetNameExchange, min_borrow: Decimal, ) -> Result<Self, SpotMarginConfigError>
This configuration, never lending less than min_borrow of asset: a loan of asset
below it is raised to it, as Binance raises a MARGIN_BUY loan to the asset’s
userMinBorrow. A minimum of zero removes it. Replaces any minimum asset had.
No asset has one by default, so each loan is exactly its order’s shortfall. An order its free balance covers borrows nothing, whatever the minimum.
§Errors
Returns SpotMarginConfigError::NegativeMinBorrow if min_borrow is negative.
Sourcepub fn min_borrow(&self, asset: &AssetNameExchange) -> Decimal
pub fn min_borrow(&self, asset: &AssetNameExchange) -> Decimal
The least the venue lends of asset in one loan, zero if it has no minimum. See
with_min_borrow.
Sourcepub fn with_liquidation(
self,
liquidation: SpotMarginLiquidation,
) -> Result<Self, SpotMarginConfigError>
pub fn with_liquidation( self, liquidation: SpotMarginLiquidation, ) -> Result<Self, SpotMarginConfigError>
This configuration, liquidating the account as liquidation says. Replaces any
liquidation it had.
§Errors
Returns SpotMarginConfigError::LiquidationWithinLeverage if a borrow the leverage limit
allows could leave the account at the liquidation level: if max_leverage is above one
and the level is at least max_leverage / (max_leverage − 1), the margin level of an
account borrowed to the limit.
Sourcepub fn liquidation(&self) -> Option<SpotMarginLiquidation>
pub fn liquidation(&self) -> Option<SpotMarginLiquidation>
When the venue liquidates the account, or None if it never does. See
with_liquidation.
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.