BSIP: 0032
Title: Always Match Orders At Maker Price
Author: Abit More <https://github.com/abitmore>
Status: Installed
Type: Protocol
Created: 2018-02-16
Discussion: https://github.com/bitshares/bitshares-core/issues/338
Replaces: -
Worker: 1.14.93
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.
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.
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.
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.
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.
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.
[to be added if any]
This document is placed in the public domain.