-
Notifications
You must be signed in to change notification settings - Fork 87
BSIP73: Match force-settlement orders with margin calls and limit orders #200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
7424c3f
Add BSIP about settle order changes
abitmore f6e556a
Update BSIP number to 73
abitmore e388b12
Update wording, specs and discussion points
abitmore 126bd5b
Add specification related to BSIP71 (GSP)
abitmore a2abda1
Fix typo, update wording about UI
abitmore 4f9569c
Add non-technical summary
abitmore File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,271 @@ | ||
| BSIP: 0073 | ||
| Title: Match force-settlement orders with margin calls and limit orders | ||
| Author: Abit More <https://github.com/abitmore> | ||
| Status: Draft | ||
| Type: Protocol | ||
| Created: 2019-06-09 | ||
| Discussion: https://github.com/bitshares/bsips/issues/181 | ||
| Worker: TBD | ||
|
|
||
| # Abstract | ||
|
|
||
| This BSIP proposes a protocol change to improve user experience (UX) of | ||
| force-settlements by trying to fill force-settlement orders | ||
| (*settle orders* in short) at a better price | ||
| and optionally fill them before expiration when certain conditions are met. | ||
|
|
||
| # Motivation | ||
|
|
||
| Force-settlements were designed for debt asset holders to convert an amount | ||
| of the debt asset into corresponding collateral asset at a fair price *when | ||
| there is nobody willing to buy back the debt at a fair price*. | ||
|
|
||
| To mitigate malious behavior and market manipulation, a *delay* and a *price | ||
| offset* were designed. But the mechanism has flaws. | ||
| * If a positive *offset* is configured in the debt asset's options, | ||
| force-settlement requesters will always "buy expensive" even when there are | ||
| orders "selling low". This also leads to occasional spikes in the market | ||
| history charts. | ||
| * Force-settlement requesters have to wait for the *delay* even when there | ||
| appear traders buying the debt asset at a fair price in the market. | ||
|
|
||
| These flaws have led to certain confusion and anger among market participants. | ||
|
|
||
| # Rationale | ||
|
|
||
| Actually, when a margin call appears, it means there is somebody | ||
| willing to buy back the debt. Thus, it makes sense to fill the margin calls | ||
| with the settle orders. | ||
|
|
||
| Similarly, if there are limit orders selling the debt asset | ||
| below the feed price, | ||
| it makes sense to match the limit orders with the settle orders as well. | ||
|
|
||
| When one of these opportunities appears, it makes sense to fill certain | ||
| settle orders immediately if it's desired by the owners of the settle orders. | ||
|
|
||
| These changes would improve user experience (UX). | ||
|
|
||
| # Specifications | ||
|
|
||
| ## Hard fork | ||
|
|
||
| Since this is a protocol change, a hard fork is needed. A time will need to be | ||
| scheduled for applying the change, which is commonly known as "hard fork time". | ||
| In this document, terms "before the hard fork", "at the hard fork" and | ||
| "after the hard fork" may or may not be used to indicate things happen before | ||
| the scheduled time, at the scheduled time and after the scheduled time. | ||
|
|
||
| ## `settle_order_object` | ||
|
|
||
| The `settle_order_object` stores current status of a force-settlement order. | ||
|
|
||
| A new field is needed within it: | ||
|
|
||
| * `bool fill_asap;` | ||
|
|
||
| By default this field is set to `false`, which means the order will be | ||
| processed after the *delay* defined in the asset's options, which is current | ||
| behavior. | ||
|
|
||
| If this field is set to `true`, the order will be filled or partially filled | ||
| when a debt position enters margin call territory. It will also be filled or | ||
| partially filled when someone places a limit order selling the collateral | ||
| asset below the feed price. | ||
|
|
||
| If multiple settle orders with this field as `true` exist in the market, | ||
| when filling before the *delay*, the order which was created first will be | ||
| filled first. | ||
|
|
||
| ## `asset_settle_operation` | ||
|
|
||
| The `asset_settle_operation` is used to request a force-settlement. It has | ||
| an `extensions` field: | ||
|
|
||
| * `extensions_type extensions;` | ||
|
|
||
| The data type of this field needs to be overridden so that it can include the | ||
| new `fill_asap` option. | ||
|
|
||
| ## `asset_settle_evaluator` | ||
|
|
||
| The `asset_settle_evaluator` is used to evaluate and apply the | ||
| `asset_settle_operation`. New logic is needed: | ||
| * only allow `fill_asap` option to be set after the hard fork; | ||
| * if the `fill_asap` option is specified in an `asset_settle_operation`, when | ||
| creating a `settle_order_object` (note: it implies some conditions are met, | ||
| E.G. the asset is not globally settled), assign the value of the operation's | ||
| `fill_asap` field to the object's `fill_asap` field. | ||
| * if the `fill_asap` option is set to `true`, and if the feed price is valid, | ||
| after creation of the settle order object, try to match it against the order | ||
| book immediately. In other words, treat it as a taker limit order buying | ||
| at the feed price. | ||
|
|
||
| ## `proposal_create_evaluator` | ||
|
|
||
| The `proposal_create_evaluator` is used to evaluate and apply the | ||
| `proposal_create_operation`, which can contain zero or more | ||
| `asset_settle_operation` objects. New logic is needed: | ||
| * only allow `fill_asap` to be set after the hard fork. | ||
|
|
||
| ## Matching and filling settle orders whose `fill_asap` field is `true` | ||
|
|
||
| ### When a new limit order is created | ||
|
|
||
| If the new limit order is selling the collateral asset for the debt asset, and | ||
| its price is below the feed price (which implies the feed price is valid), | ||
| * current logic is to only match it with the limit orders on the opposite side | ||
| of the market; | ||
| * after the hard fork, the new logic would be: | ||
| * firstly match it with the limit orders on the opposite side whose buy | ||
| prices are higher than the feed price; | ||
| * secondly match it with the settle orders whose `fill_asap` options were | ||
| set to `true`. The matching price would be the feed price. In other words, | ||
| treat the settle orders as maker limit orders buying at the feed price; | ||
| * lastly match it with remaining limit orders on the opposite side. | ||
|
|
||
| ### When a debt position enters margin call territory | ||
|
|
||
| If a margin call order appears, either due to the feed price changing, or due | ||
| to the amount of collateral or the amount of debt changing (which implies the | ||
| feed price is valid), | ||
| * current logic is to only match it with the limit orders on the opposite | ||
| side of the market and conditionally trigger a black swan event; | ||
| * after the hard fork, the new logic would be: | ||
| * firstly match it with the limit orders on the opposite side whose buy | ||
| prices are higher than the feed price; if this step triggers a black swan | ||
| event, apply the corresponding black swan processing logic to the market; | ||
| * secondly match it with the settle orders whose `fill_asap` options were | ||
| set to `true`. The matching price would be the feed price. In other words, | ||
| treat the settle orders as maker limit orders buying at the feed price; | ||
| * lastly match it with remaining limit orders on the opposite side (which | ||
| would possibly trigger a black swan event as well, but it's out of this | ||
| document's scope). | ||
|
|
||
| ### When the feed price changes | ||
|
|
||
| When the feed price changes, either due to a new price being published, or due | ||
| to an old price expiring, or due to the asset's options changing, if the new | ||
| feed price is valid, and if the new feed price in the direction of "X debt | ||
| asset per collateral asset" is higher than the old feed price or the old feed | ||
| price was invalid, | ||
| * current logic doesn't handle settle orders, | ||
| * after the hard fork, the new logic would be: | ||
| * if there are limit orders selling the collateral asset below the new feed | ||
| price, and there are settle orders whose `fill_asap` options were `true`, | ||
| match the settle orders with the limit orders. In other words, treat | ||
| those settle orders as taker limit orders buying at the new feed price. | ||
|
|
||
| ### Do not update `force_settled_volume` when filling the `fill_asap` orders | ||
|
|
||
| When a settle order is filled or partially filled due to having the | ||
| `fill_asap` option set to `true`, | ||
| it doesn't affect `force_settled_volume` (which indicates how much of the debt | ||
| asset has been force-settled in the current maintenance interval). | ||
|
|
||
| ## Processing settle orders after the delay | ||
|
|
||
| Currently, when filling a settle order after the delay (note: it implies | ||
| some conditions are met, E.G. the feed price is valid and total settled volume | ||
| in the current maintenance interval doesn't exceed the maximum allowed volume), | ||
| the settle order will be matched against the debt position with the least | ||
| collateral ratio, the fill price in the direction of "X debt asset | ||
| per collateral asset" would be | ||
| `fill_price = feed_price * (1 + foce_settlement_offset)`. | ||
|
|
||
| After the hard fork, when processing a settle order after the delay, | ||
| * firstly try to match it with the margin calls and the limit orders selling | ||
| below `fill_price`. In other words, treat it as a taker limit order buying | ||
| at `fill_price`. | ||
| Note: this step doesn't affect `force_settled_volume`. | ||
| * if the settle order still exists, process it with the logic before the | ||
| hard fork. | ||
| Note: this step does affect `force_settled_volume` as before. | ||
|
|
||
| ## Logic related to BSIP 71 (Prevent Global Settlement) | ||
|
|
||
| The behaviors proposed in this BSIP would be impacted by BSIP 71. | ||
|
|
||
| In general, this BSIP proposes that | ||
| * the settle orders whose `fill_asap` field is `true` will be treated as | ||
| limit orders buying at feed price when the market engine processing | ||
| limit orders or margin calls, and | ||
| * when processing a settle order after the delay, it will "buy the way up" | ||
| before being matched with a debt position that need to apply | ||
| `force_settlement_offset`. | ||
|
|
||
| ## API | ||
|
|
||
| APIs which return `settle_order_object` need to return the new `fill_asap` | ||
| field in the `settle_order_object`. | ||
|
|
||
| APIs which return a combined order book can combine settle orders whose | ||
| `fill_asap` is true with the limit orders on the same side of the market. | ||
|
|
||
| ## CLI | ||
|
|
||
| Currently there is a `settle_asset` command in CLI which can be used to | ||
| create force-settlement orders. After the hard fork, we need a command in | ||
| CLI for users to create force-settlement orders with the new `fill_asap` | ||
| option. | ||
|
|
||
| One option is to add an optional boolean parameter to the parameter list of | ||
| the existing `settle_asset` command, if it doesn't break existing client | ||
| applications which rely on that wallet API. Otherwise, a new command is | ||
| needed, E.G. `settle_asset_ext`. | ||
|
|
||
| ## GUI/UX | ||
|
|
||
| Note: GUI changes here are only suggestions, formally they're not part of the | ||
| specification. | ||
|
|
||
| The new `fill_asap` option needs to be presented and can be used in GUI after | ||
| the hard fork. | ||
|
|
||
| When there are settle orders with `fill_asap` option set to `true`, the UI | ||
| can show them | ||
| as special buy orders which are buying at the feed price in the order book. | ||
|
|
||
| # Discussion | ||
|
|
||
| * With this BSIP, we provided a tool that can be used by debt asset holders to | ||
| convert their debt asset holdings into corresponding collateral asset more | ||
| conveniently and flexibly. | ||
| However, it's not guaranteed that a settle order will be filled at a better | ||
| price if the owner choose to fill it "as soon as possible". Market paticipants | ||
| should always make their own decisions on whether to use the new tool. | ||
|
|
||
pmconrad marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * From the perspective of the debt asset owners (note: "asset owners" and | ||
| "asset holders" have different meanings), for the performance of the debt | ||
| assets, it could be more desirable to execute force-settlements against margin | ||
| calls than against market orders, because it would improve the overall | ||
| collateral ratio of the asset (although it's in the price of worse experience | ||
| for force-settlement requesters). In that sense it contradicts the goals of | ||
| BSIP 71 (Prevent Global Settlement). | ||
|
|
||
| * The proposed functionality is mostly convenience for users. Manual selling on | ||
| the market is (almost) always available when it would be used automatically | ||
| by this proposal (exception: new incoming limit orders). | ||
|
|
||
| * The proposed functionality complicates the market engine and possibly the | ||
| `get_order_book` call (see [bitshares/bitshares-core#1958]( | ||
| https://github.com/bitshares/bitshares-core/issues/1958)). | ||
| It is probably harmful for performance in the long run, which is particularly | ||
| undesirable for functionality that can mostly be emulated client-side. | ||
|
|
||
| # Non-Technical Summary | ||
|
|
||
| When force-settling a SmartCoin, the user currently has to wait for the | ||
| *settlement delay* before her tokens are exchanged for the collateral asset. | ||
| This BSIP introduces a new flag that allows settlement requests to be matched | ||
| with market orders during the waiting period, potentially resulting in faster | ||
| settlement and a better price. | ||
|
|
||
| # Copyright | ||
|
|
||
| This document is placed in the public domain. | ||
|
|
||
| # See Also | ||
|
|
||
| * https://github.com/bitshares/bsips/issues/181 | ||
| * https://github.com/bitshares/bitshares-ui/issues/1711 | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.