bsips/bsip-0038.md

250 lines
9.6 KiB
Markdown

BSIP: 0038
Title: Add target collateral ratio option to short positions
Author: Abit More <https://github.com/abitmore>
Status: Draft
Type: Protocol
Created: 2018-03-05
Discussion: https://bitsharestalk.org/index.php?topic=25924.0,
https://github.com/bitshares/bsips/issues/51
Replaces: 0035 (partly)
Worker: To be done
# Abstract
When a short position is margin called, some of its collateral will be sold
and some or all of its debt will be covered accordingly.
However, usually more collateral will be sold, in comparison to the minimum
amount required to be sold to maintain the maintenance collateral ratio (MCR)
requirement.
This BSIP proposes a protocol change to let shortes (borrowers) have control
over selling how much collateral when being margin called.
This BSIP depends on [BSIP 31](bsip-0031.md).
# Motivation
As discussed in [this forum
post](https://bitsharestalk.org/index.php?topic=25924.0), current process gives
manipulators big chance to short BTS and make money and increase the risk of
black swan, thus hurts the BTS ecosystem. Many participants in the discussion
agree that usually it's not really required to cover all debt (thus selling more
collateral) when being margin called.
After [BSIP 31](bsip-0031.md) is
in place, shorters will have more chance to not cover all debt on margin call,
but it's not 100% guaranteed, and they can only accept the result passively.
# Rationale
Different shorters have different expectations when being margin called:
* some want to close their short positions completely to cut losses;
* some want to sell as little collateral as possible to keep remaining short
positions as large as possible;
* some want to sell more than minimum required collateral to reduce the
possibility of being margin called again in the near future, but don't
want to close their short positions completely.
With a new "target collateral ratio" option, all these expectations can be met.
## The Definition of Target Collateral Ratio
"Target collateral ratio" is an optional value which can be set onto a short
position, when the position being automatically liquidized (margin called),
sell no more than required collateral until collateral ratio of the position
reaches this value.
* Default value: not set, which means to sell as much collateral as possible,
which is same to current behavior.
* When the value is set but below MCR, use MCR.
* When matching a margin call order with a force settle order, ignore this
option.
* When checking for black swan or globally settling, ignore this option.
## The Math
Let prices described below be in terms of `debt / collateral`,
e.g. how much CNY per BTS.
A margin call order can be matched with a limit order as either maker or taker,
in any case, there would be a matching price. We can solve an equation as
follows:
```
target_CR = new_collateral / ( new_debt / feed_price )
= ( collateral - max_amount_to_sell ) * feed_price
/ ( debt - amount_to_get )
= ( collateral - max_amount_to_sell ) * feed_price
/ ( debt - max_amount_to_sell * match_price )
=>
max_amount_to_sell = (debt * target_CR - collateral * feed_price)
/ (target_CR * match_price - feed_price)
```
The result is a rational number, need to be rounded up to an integer.
Then, the maximum debt it wants to cover can be calculated as:
```
max_debt_to_cover = max_amount_to_sell * match_price
```
It need to be rounded up to an integer as well.
Then adjust `max_amount_to_sell` to be more precise by:
```
max_amount_to_sell = round_down(max_debt_to_cover / match_price)
```
## Rounding and Edge Cases
Without `target_CR` option set, when a call order is partially filled, its
paid collateral will be rounded down, so its collateral ratio will increase.
With `target_CR` option set, when a call order is partially filled, it's
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
increase in collateral ratio.
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
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
intention of this BSIP. To solve this issue, when detected a decrease in
collateral ratio when matching, ignore the `target_CR` option of corresponding
call order, and re-evaluate the match.
## When and How To Use the Option
The `target_collateral_ratio` option can to be set, updated or cleared when
creating or updating a short position. When doing so, other rules still apply,
E.G. can't update a short position to have too small collateral ratio.
For one account, different short positions (for different assets) can be set
with different `target_collateral_ratio`.
For one short position,
* if want to close it completely to cut losses when being margin called,
* don't set or clear `target_collateral_ratio` option, because the option is
**optional** so can be unset or cleared;
* if want to sell as little collateral as possible when being margin called,
to keep the remaining short position as large as possible,
* set `target_collateral_ratio` to `MCR` or less;
* if want to sell more than minimum required collateral when being margin
called, to reduce the possibility of being margin called again in the near
future, but don't want to completely close the short position,
* set `target_collateral_ratio` to a value higher than `MCR`, E.G. `300%`.
The higher the value is, the more collateral will be listed for sale when
it's margin called.
# Specifications
## `call_order_object`
The `call_order_object` stores current status of a short position.
Need to add a new field into it:
* `optional<uint16_t> target_collateral_ratio;`
Same to other collateral ratios, the actual ratio is the value divided by
`GRAPHENE_COLLATERAL_RATIO_DENOM` aka `1000`.
Due to the `uint16_t` data type, the new field's maximum value is `65535`,
which means `6553.5%`.
## `call_order_update_operation`
The `call_order_update_operation` is used to open, update and close short
positions. It contains an `extensions` field:
* `extensions_type extensions;`
Need to override data type of this field so it can include the new "target
collateral ratio" option.
## `call_order_update_evaluator`
The `call_order_update_evaluator` is used to evaluate and apply the
`call_order_udpate_operation`. Need to add logic:
* only allow `target_collateral_ratio` to be set after the hard fork;
* set/update/clear `target_collateral_ratio` field of `call_order_object`
accordingly. Specifically,
* set or update the field if it presents in the operation and is valid,
* clear the field if it doesn't present in the operation or is not valid.
## `proposal_create_evaluator`
The `proposal_create_evaluator` is used to evaluate and apply the
`proposal_create_operation`, which can contain zero or more
`call_order_udpate_operation` objects. Need to add logic:
* only allow `target_collateral_ratio` to be set after the hard fork.
## Call Order Matching and Filling
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 set, compare it to `MCR`, use the bigger
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
equation described above, then process 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
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
is set, UI need to show exact amounts of collateral that another trader is able
to buy according to the equation described above.
# Discussion
With this BSIP, we provided a tool that can be used by shorters to keep their
positions, however, it's not always the best strategy to keep as large position
as possible, sometimes it's even more risky than just cutting losses.
Nevertheless, how to use the tool, is up to the traders to decide.
# Summary for Shareholders
"This is how it should work."
# Copyright
This document is placed in the public domain.
# See Also
* https://bitsharestalk.org/index.php?topic=25924.0
* https://github.com/bitshares/bsips/issues/51