Merge branch 'master' into bsip35

bsip53
abitmore 2018-02-22 11:32:44 +00:00
commit a52ca3919f
6 changed files with 485 additions and 0 deletions

View File

@ -37,3 +37,8 @@ Number | Title |
[27](bsip-0027.md) | Asset Issuer Reclaim Fee Pool Funds | Abit More | Protocol | Accepted
[28](bsip-0028.md) | Worker Proposal Improvements | Bill Butler | Protocol | Draft
[29](bsip-0029.md) | Asset issue change to require owner authority | Fabian Schuh | Protocol | Draft
[30](bsip-0030.md) | Always Allow Increasing Collateral Ratio If Debt Not Increased | Abit More | Protocol | Draft
[31](bsip-0031.md) | Update Short Position's Margin Call Price After Partially Called Or Settled | Abit More | Protocol | Draft
[32](bsip-0032.md) | Always Match Orders At Maker Price | Abit More | Protocol | Draft
[33](bsip-0033.md) | Maker Orders With Better Prices Take Precedence | Abit More | Protocol | Draft
[34](bsip-0034.md) | Always Trigger Margin Call When Call Price Above Or At Price Feed | Abit More | Protocol | Draft

71
bsip-0030.md Normal file
View File

@ -0,0 +1,71 @@
BSIP: 0030
Title: Always Allow Increasing Collateral Ratio If Debt Not Increased
Author: Abit More <https://github.com/abitmore>
Status: Draft
Type: Protocol
Created: 2018-02-16
Discussion: https://github.com/bitshares/bitshares-core/issues/583,
https://github.com/bitshares/bitshares-core/issues/672
Replaces: -
Worker: To be done
# Abstract
Currently, when a short position's collateral ratio is below MCR (a parameter
in price feed: `maintenance_collateral_ratio`) but is not completely filled
immediately due to a lack of enough volume on the opposite side of the market,
it will hang in the market and be waiting for being margin called.
The owner then can adjust the order's collateral ratio **only if**
* to close the position, or
* the new collateral ratio is above MCR, or
* the call order get completely filled (margin called) immediately.
While this prevents shorters from maliciously reducing collateral ratio (to
increase possibility of black swan event), it also prevents shorters from
slightly increasing collateral ratio (to decrease possibility of black swan
event).
This BSIP proposes a mechanism to improve this situation.
# Motivation
Make the exchange system more user-friendly.
# Rationale
The ecosystem would get benefit if shorters are allowed to reduce risks to
themselves while reducing risks to the system at same time.
Current rules are a bit too strict, which can be loosed to:
A shorter can adjust the position's collateral ratio **only if**
* to close the position, or
* the new collateral ratio is above MCR, or
* the call order get completely filled (margin called) immediately, or
* **the new ratio is higher than old ratio and debt is not increased**
# Specifications
In `do_apply()` function of `call_order_update_evaluator` class, if
finally found the call order still in margin call territory,
* don't throw an exception if `call_obj->collateralization()` is reduced, and
* require `delta_debt` of `call_order_update_operation` to be non-positive.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/583
* https://github.com/bitshares/bitshares-core/issues/672
* https://bitsharestalk.org/index.php?topic=25926.0

65
bsip-0031.md Normal file
View File

@ -0,0 +1,65 @@
BSIP: 0031
Title: Update Short Position's Margin Call Price After Partially Called Or Settled
Author: Abit More <https://github.com/abitmore>
Status: Draft
Type: Protocol
Created: 2018-02-16
Discussion: https://github.com/bitshares/bitshares-core/issues/343,
https://github.com/bitshares/bitshares-core/issues/649
Replaces: -
Worker: To be done
# Abstract
Currently, when a short position get partially called or settled, the call
price won't change, that said, even if its actual collateral ratio is higher
than others, higher than minimum required, it will still be selling collateral
at a low price, taking precedence over other short positions.
This behavior is causing several issues:
* it's somehow unfair, thus brought bad experience to shorters, and
* it prevents black swan event from being triggered in time when needed,
because the collateral ratio of the 2nd even overall short positions may
be too low but not being checked, thus risks the pegging system.
This BSIP proposes a mechanism to improve this situation.
# Motivation
Make the exchange system more user-friendly.
# Rationale
To attract more users, the system should be fair, should be well balanced.
It's common sense that short positions with least collateral ratio should
get margin called first. This can be achieved if always update the margin
call price after every fill.
# Specifications
In `fill_order( const call_order_object& ...)` function of `database` class,
update `call_price` field of `call_order_object` after debt or collateral
changed to a non-zero value.
In addtion, after `call_price` get updated, the iterators initialized with
`by_price` index may be invalidated, so need to review / revise involved code,
E.G. `check_call_orders(...)` function of `database` class.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/343
* https://github.com/bitshares/bitshares-core/issues/649
* https://bitsharestalk.org/index.php?topic=25926.0

104
bsip-0032.md Normal file
View File

@ -0,0 +1,104 @@
BSIP: 0032
Title: Always Match Orders At Maker Price
Author: Abit More <https://github.com/abitmore>
Status: Draft
Type: Protocol
Created: 2018-02-16
Discussion: https://github.com/bitshares/bitshares-core/issues/338
Replaces: -
Worker: To be done
# Abstract
Currently, under most circumstances, when matching two orders, the maker price
will be used to calculate how much each order will pay and receive.
However, when matching a taker limit order with a maker margin call order,
the taker price is being used.
This BSIP proposes a principle: always match orders at maker price.
# Motivation
Generally, the order that is placed earlier (the maker) sets a price,
another order that is placed later (the taker) accepts the price, thus a match,
two orders pay to each other at that price.
Take the pure limit order matching mechanism in BitShares as an example:
If one person (A) placed a limit
order to sell 100 BTS at 0.1 USD per BTS, another person (B) then placed a new
limit order to buy 100 BTS at 0.105 USD per BTS, the two orders will match at
0.1 USD per BTS, so A will pay 100 BTS and get 10 USD, B will pay 10 USD and
get 100 BTS.
However, in BitShares, when matching a taker limit order with a maker margin
call order, the taker price is being used.
For example, if trader A's margin call order is
selling 100 BTS at no less than 0.1 USD per BTS, then trader B placed an order
that buys 100 BTS at 0.105 USD per BTS, the two order will match at 0.105 USD
per BTS, so A will pay 100 BTS and get 10.5 USD, B will pay 10.5 USD and get
100 BTS.
While not strictly a bug, this behavior is unexpected and irritating for users.
# Rationale
Matching orders at the maker price, with margin calls being inlined in the
order book, is an easy to understand rule and matches user expectations,
see [bitshares-core
issue #338](https://github.com/bitshares/bitshares-core/issues/338).
There is a parameter in price feed named MSSR, which stands for "maximum short
squeeze ratio". Maker price of margin call orders is MSSP, which stands for
"maximum short squeeze price", is calculated as `feed_price / MSSR`.
Note: `feed_price` here is in terms of debt/collateral, aka "how much debt per
collateral".
Currently a black swan event will occur when the call order with least
collateral ratio is going to be matched below 100% collateral ratio price
(name it `100CRP`). Because the call order will be matched with incoming limit
order at limit order's price (taker price),
which can be higher or lower than 100CRP, so even if MSSP is below 100CRP,
an incoming taker limit order may or may not trigger a black swan.
So it makes sense to check if a black swan event will occur every time when a
limit order is created.
After the behavior changed to always match at maker price, when MSSP is below
100CRP, an incoming taker limit order will always trigger a black swan event.
So it makes sense to trigger the black swan event when MSSP is below 100CRP
rather than waiting for an incoming limit order. That means it's no longer
needed to check for black swan event when a limit order is created.
Since checking for black swan event is somehow expensive, we'll gain a side
benefit on performance with the change.
# Specifications
Matching between a limit order and a call order is done in
`check_call_orders(...)` function of `database` class, price of limit order
is always used. It need to be changed to use MSSP when the call order is maker.
When triggering a black swan event when MSSP is below 100CRP,
sometimes the short
position with least collateral ratio may still have more than 100% collateral
ratio. In this case, the global settlement price is 100CRP but not the actual
collateral ratio of the short position with least collateral ratio.
This is current behavior, it's fair, no need to change.
# Discussion
It might seem unfair on the shorter to match at MSSP even if the incoming order
specifies a better price. However, in a rationally acting market users will not,
in the presence of margin calls, create limit orders below the MSSP.
Effectively the new rule doesn't change this situation.
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/338
* https://bitsharestalk.org/index.php?topic=25926.0

136
bsip-0033.md Normal file
View File

@ -0,0 +1,136 @@
BSIP: 0033
Title: Maker Orders With Better Prices Take Precedence
Author: Abit More <https://github.com/abitmore>
Status: Draft
Type: Protocol
Created: 2018-02-17
Discussion: https://github.com/bitshares/bitshares-core/issues/625,
https://github.com/bitshares/bitshares-core/issues/453
Replaces: -
Worker: To be done
# Abstract
Currently, in BitShares, under certian circumstances, a taker order may be
matched with a maker order which is not "on the top" of the order book.
This behavior is unexpected and irritating for users.
This BSIP proposes a principle: always match taker orders with maker orders
with the best prices (aka on the top of the order book) first.
# Motivation
As expected, when matching taker limit orders with maker limit orders, the maker
limit orders with better prices will always be matched first.
For example, if trader A has a limit order selling 100 BTS at
0.1 USD per BTS, trader B has a limit order selling 100 BTS at 0.09 USD per BTS,
which means B's limit order has a better price for the opposite side to buy.
Now if trader C placed an order that buys 10 BTS at 0.105 USD per BTS, B's
limit order will take precedence, A's limit order won't be matched.
However, when there are (maker) margin call orders in the market which have met
the requirements that to be matched (able to be margin called), they always
take precedence over the (maker) limit orders on the same side, no matter
whether the limit orders provided better price.
For example, if trader A's margin call order is selling 100 BTS at no less than
0.1 USD per BTS, trader B has a limit order selling 100 BTS at 0.09 USD per BTS,
which means B's limit order has a better price for the opposite side to buy.
Now if trader C placed an order that buys 10 BTS at 0.105 USD per BTS, A's
margin call order will take precedence, B's limit order won't be matched. That
means C is forced to "buy high" when have chance to "buy low", which is
unexpected.
Users have been confused by this behavior, as discussed in [bitshares-core
issue #625](https://github.com/bitshares/bitshares-core/issues/625) and other
threads.
Another scenario is described in [Bitshares-core
issue #453](https://github.com/bitshares/bitshares-core/issues/453)
that sometimes a taker margin call order may be matched with a maker limit order
which is not on the top of the order book. This can be seen as a bug.
# Rationale
Always matching taker order (e.g. a buy) with a maker order which offered best
price (aka lowest ask), is a simpler rule which most users would understand
easily.
There is a parameter in price feed named MSSR, which stands for "maximum short
squeeze ratio". Maker price of margin call orders is MSSP, which stands for
"maximum short squeeze price", is calculated as `feed_price / MSSR`.
Note: `feed_price` here is in terms of debt/collateral, aka "how much debt per
collateral".
That said, the price that margin call orders are offering is MSSP. The prices
those limit orders are offering are the limit prices.
When placing a limit (e.g. buy) order with a price beyond the lowest sell,
the order is expected to "walk the book", matching each order on the opposite
side in turn, at that order's price, until the new limit order is completely
filled, or there is no more sell order matching its price.
To meet the expectation,
* firstly, we need to match the limit buy order with the limit sell orders
whose prices are lower than MSSP and prices can match the new order;
* then, if the new limit buy order hasn't been completely filled, match it with
the margin calls if MSSP can match the new order's price;
* then, if the new limit buy order still hasn't been completely filled, match it
with the rest sell orders until it's completely filled or no more sell order
matching its price
# Specifications
## Matching a taker limit order
New limit order is being processed in `apply_order(...)` function of `database`
class.
Currently, in the function, firstly call orders will be checked and matched.
After that, limit orders on the opposite side will be checked and matched.
Need to change the logic to:
1. firstly, sort the limit orders on the opposite by `price`, best price first,
end at MSSP; check them one by one, calls `match(...)` function until the
return value is not `2` which means the new order is completely filled;
2. if reach the end (MSSP), which means the new order is still unfilled,
call `check_call_orders(..)` function or an equivalent;
3. check if `new_order_object` still exist, if yes, redo step one but set the
maximum possible price of the market as end price.
## Matching taker margin call orders
For [bitshares-core
issue #453](https://github.com/bitshares/bitshares-core/issues/453),
in `check_call_orders(...)` function of `database` class,
iterator `limit_itr` will move forward when variable `filled_limit` is `true`.
`filled_limit` will be set to `true` when a limit order get completely filled.
However, since `filled_limit` is declared out of the `while` block,
it doesn't get reset to `false` after `limit_itr` moved forward. That means
after the first limit order get completedly filled, `filled_limit` will always
be `true`, so `limit_itr` will always move forward no matter whether *current*
limit order got completedly filled, so a taker call order may match
with a limit order that is not on the top of the order book.
To fix this, need to change the code to make sure `limit_itr` always references
the limit order on the top of the order book when dereferencing.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/625
* https://github.com/bitshares/bitshares-core/issues/453
* https://bitsharestalk.org/index.php?topic=25926.0

104
bsip-0034.md Normal file
View File

@ -0,0 +1,104 @@
BSIP: 0034
Title: Always Trigger Margin Call When Call Price Above Or At Price Feed
Author: Abit More <https://github.com/abitmore>
Status: Draft
Type: Protocol
Created: 2018-02-18
Discussion: https://github.com/bitshares/bitshares-core/issues/606
Replaces: -
Worker: To be done
# Abstract
Currently, in BitShares, a short position may be margin called only when both
two requirements are met:
* call price is above or equal to median price feed
* no limit order on the book is buying collateral with price higher than the
short position's call price
This behavior has led to certain confusion and anger among market participants.
This BSIP proposes a new behavior to improve the situation: drop the second
requirement, trigger margin call when the first requirement is met.
# Motivation
To avoid ambiguity, in this article, all prices are in terms of
`debt asset / collateral asset`, aka how much debt asset per collateral
asset. A bid is an order to buy collateral asset with debt asset.
Generally, a short position may be margin called when its collateral ratio is
below or equal to maintenance collateral ratio (MCR).
However, to calculate collateral ratio, a fair collateral price is needed.
In BitShares, there are two data sources can be used to decide the fair
collateral price:
* the internal market
* the price feeds
Currently, both data sources are used. Specifically, collateral price is decided
as the higher one between the highest bid price on the internal market and the
median price feed. That said, when a short position's collateral ratio has
fallen to below or equal to MCR according to median price feed (in this case,
call price of the short position is above or equal to median price feed), if
there is a bid on the market with high price, the short position won't be margin
called.
This mechanism has led to certain confusion and anger among market participants.
* there are often orders with overlapping price on the book but didn't fill
* there are often short positions selling collaterals with low prices, but
traders are unable to buy at those prices
* it often causes borrowers to sell collaterals at a low price when have chances
to sell at higher price
* market manipulators / arbitrage traders have more chances to force borrowers
to sell collaterals at lower price
This BSIP effectively proposes a new behavior: derive the fair collateral price
only from price feeds.
# Rationale
Since price feeds are provided by a set of chosen producers, the median price
feed is usually considered trustworthy. On the other hand, instant market
price is not as reliable, especially for the markets with poor depth, so it's
a rather limited supplement for calculating collateral price.
At this moment, changing the rule to only use median price feed will clear away
the confusion the end users may have, while still keeping the derived collateral
price fair to an extent.
After this change is done, placing a new limit order will no longer trigger a
margin call, cancelling a limit order or expiring a limit order will no longer
trigger a margin call as well, that means we don't need to check for new margin
calls nor black swan events in those scenarios, so we'll gain a side benefit on
performance.
# Specifications
In `check_call_orders(...)` function of `database` class, when matching a call
order with a limit order, there is a check:
`if( match_price > ~call_itr->call_price )`, when the result is `true`,
processing will be ended and `margin_called` will be returned.
Need to skip the check and the following `return` action.
In `do_apply(...)` function of `limit_order_cancel_evaluator` class, and
similar code blocks after a limit order object is removed, no longer need to
call `check_call_orders(...)` function of `database` class.
# Discussion
[to be added if any]
# Summary for Shareholders
[to be added if any]
# Copyright
This document is placed in the public domain.
# See Also
* https://github.com/bitshares/bitshares-core/issues/606
* https://bitsharestalk.org/index.php?topic=25926.0