bsip38: update rounding rules and reorganize

This commit is contained in:
abitmore 2018-04-11 07:25:28 -04:00
parent 4bd4e6febc
commit 44818ec0b6

View file

@ -48,12 +48,15 @@ Different shorters have different expectations when being margin called:
With a new "target collateral ratio" option, all these expectations can be met. With a new "target collateral ratio" option, all these expectations can be met.
In sections below, both a "margin call order" and a "call order" mean a short
position in margin call territory.
## The Definition of Target Collateral Ratio ## The Definition of Target Collateral Ratio
"Target collateral ratio" is an optional value which can be set onto a short "Target collateral ratio" is an optional value which can be set onto a short
position, when the position being automatically liquidized (margin called), position, when the position being automatically liquidized (margin called),
sell no more than required collateral until collateral ratio of the position sell no more than required collateral until collateral ratio of the position
reaches this value. is **higher than** this value.
* Default value: not set, which means to sell as much collateral as possible, * Default value: not set, which means to sell as much collateral as possible,
which is same to current behavior. which is same to current behavior.
* When the value is set but below MCR, use MCR. * When the value is set but below MCR, use MCR.
@ -61,6 +64,10 @@ reaches this value.
option. option.
* When checking for black swan or globally settling, ignore this option. * When checking for black swan or globally settling, ignore this option.
Why to use "higher than" but not "equal to", is due to an existing rule:
if a short position's collateral ratio is equal to MCR, it will still be
margin called.
## The Math ## The Math
Let prices described below be in terms of `debt / collateral`, Let prices described below be in terms of `debt / collateral`,
@ -81,7 +88,7 @@ max_amount_to_sell = (debt * target_CR - collateral * feed_price)
/ (target_CR * match_price - feed_price) / (target_CR * match_price - feed_price)
``` ```
The result is a rational number, need to be rounded up to an integer. The result is a rational number.
Then, the maximum debt it wants to cover can be calculated as: Then, the maximum debt it wants to cover can be calculated as:
@ -89,31 +96,77 @@ Then, the maximum debt it wants to cover can be calculated as:
max_debt_to_cover = max_amount_to_sell * match_price max_debt_to_cover = max_amount_to_sell * match_price
``` ```
It need to be rounded up to an integer as well. The result is a rational number as well.
Then adjust `max_amount_to_sell` to be more precise by: ## Rounding on Maximums Calculation
``` As described in [BSIP 35](bsip-0035.md), at last we need to convert the
max_amount_to_sell = round_down(max_debt_to_cover / match_price) rational numbers to integers, so rounding is involved.
```
## Rounding and Edge Cases Since maximum debt to cover is primarily used in order matching algorithm, we
will only focus on it here.
Without `target_CR` option set, when a call order is partially filled, its When calculating maximum debt to cover, the goal is to go over the specified
paid collateral will be rounded down, so its collateral ratio will increase. target but not go too far beyond.
That said, if a short position got matched with a big limit order, after
partially filled, its collateral ratio should be **just** higher than specified
target collateral ratio. Which means if `max_debt_to_cover` has no
fraction, need to plus it by one Satoshi; otherwise, need to round it up.
An effectively same approach is to round down then add one Satoshi onto the
result.
With `target_CR` option set, when a call order is partially filled, it's ## Rounding on Order Matching, and Edge Cases
possible that its paid collateral will be rounded up. If the call order's
collateral ratio is not too low, partially filling will likely leads to an Rounding rules about order matching are defined in [BSIP 35](bsip-0035.md).
Generally, when two orders got matched, the order matching engine will favor
the larger order while rounding.
When a call order got matched with a limit order, if the call order has no
`target_CR` option set, or has `target_CR` option set but covering debt is
smaller than maximum debt to cover, both means the call order is larger,
so its paid collateral will be rounded down, so its collateral ratio will
increase after partially filled.
If the call order has `target_CR` option set and is covering the whole "maximum
debt to cover", to be fair, we should consider that part of call order to be
smaller and favor the limit order while rounding, otherwise the limit order may
suffer an overall loss.
That means the call order will be partially filled and its paid
collateral will be rounded up, in this case, if the call order's collateral
ratio was not too low, usually, partially filling will still lead to an
increase in collateral ratio. increase in collateral ratio.
However, there are edge cases: if the call order's collateral ratio is already However, there are edge cases: if the call order's collateral ratio is already
low, or its debt or collateral amount is tiny, rounding up paid collateral on low, or its debt or collateral amount is tiny, rounding up paid collateral on
partially filling will probably lead to a decrease in collateral ratio, partially filling will probably lead to a decrease in collateral ratio,
in extreme cases it may even lead to a black swan event. This is against the in an extreme case it may even lead to a black swan event. This is against the
intention of this BSIP. To solve this issue, when detected a decrease in intention of this BSIP. To solve this issue, if detected a decrease in
collateral ratio when matching, ignore the `target_CR` option of corresponding collateral ratio when matching, we propose to ignore the `target_CR` option of
call order, and re-evaluate the match. corresponding call order, and re-evaluate the match.
## The Revised Rounding Rules on Order Matching
So the rule for matching a limit order with a call order will be revised as
follows with new rules **in bold**:
* if the call order is receiving the whole debt amount, which means it's
smaller and the short position will be closed after the match, round up its
paying amount;
* **otherwise,**
* **if the call order has `target_collateral_ratio` set and is receiving the
maximum debt amount calculated with `target_collateral_ratio`, see the call
order as smaller, try to round up its paying amount;**
* **for edge cases, if the call order's collateral ratio would not increase
after being partially filled due to the round-up (which may even cause a
black swan event in an extreme scenario), see its `target_collateral_ratio`
as "not set" for this time, re-apply the filling rules for this match.**
* otherwise, the call order is larger, round down its paying amount.
* if the limit order would receive nothing, cancel it (it's smaller,
so safe to cancel);
* otherwise, calculate the amount that the limit order would pay as
`round_up(receiving_amount * match_price)`. After filled both orders,
if the limit order still exists, the remaining amount might be too small,
so cancel it.
## When and How To Use the Option ## When and How To Use the Option
@ -191,42 +244,17 @@ After a call order get matched with a limit order and about to fill,
* if `target_collateral_ratio` is not set, process as before; * if `target_collateral_ratio` is not set, process as before;
* if `target_collateral_ratio` is set, compare it to `MCR`, use the bigger * if `target_collateral_ratio` is set, compare it to `MCR`, use the bigger
one (aka `max(target_collateral_ratio,MCR)`) to calculate maximum amount of one (aka `max(target_collateral_ratio,MCR)`) to calculate maximum amount of
collateral for sale and maximum amount of debt to cover according to the debt to cover according to the equation described above, and apply the
equation described above, then process as before. revised rounding rules, then process other logic as before.
### Rounding
Rules about rounding are defined in [BSIP 35](bsip-0035.md).
The rule for matching a limit order with a call order need to be revised as
(new rules **in bold**):
* if the call order is receiving the whole debt amount, which means it's
smaller and the short position will be closed after the match, round up its
paying amount;
* **otherwise,**
* **if the call order has `target_collateral_ratio` set and is receiving the
maximum debt amount calculated with `target_collateral_ratio`, see the call
order as smaller, try to round up its paying amount;**
* **for edge cases, if the call order's collateral ratio would not increase
after being partially filled due to the round-up (which may even cause a
black swan event in an extreme scenario), see its `target_collateral_ratio`
as "not set" for this time, re-apply the filling rules for this match.**
* otherwise, the call order is larger, round down its paying amount.
* if the limit order would receive nothing, cancel it (it's smaller,
so safe to cancel);
* otherwise, calculate the amount that the limit order would pay as
`round_up(receiving_amount * match_price)`. After filled both orders,
if the limit order still exists, the remaining amount might be too small,
so cancel it.
## UI/UX ## UI/UX
The new option need to be presented and can be used in UI after the hard fork. The new option need to be presented and can be used in UI after the hard fork.
When there are call orders to be filled, if `target_collateral_ratio` option When there are call orders to be filled, if `target_collateral_ratio` option
is set, UI need to show exact amounts of collateral that another trader is able is set, UI need to show exact amount of collateral that another trader is able
to buy according to the equation described above. to buy and exact amount of debt that need to pay according to the equation
described above.
# Discussion # Discussion