Skip to content
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

BSIP73: Match Force-Settlement Orders with Margin Calls and Limit Orders #181

Closed
abitmore opened this issue Jul 17, 2019 · 23 comments
Closed
Labels

Comments

@abitmore
Copy link
Member

abitmore commented Jul 17, 2019

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

Protocol upgrade

A time will need to be scheduled for applying the change. In this document,
terms "before the protocol upgrade", "at the protocol upgrade" and "after
the protocol upgrade" 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 protocol upgrade;
  • 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 protocol upgrade.

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 protocol upgrade, 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 protocol upgrade, 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 protocol upgrade, 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 protocol upgrade, 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
    protocol upgrade.
    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 protocol upgrade,
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 protocol upgrade.

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.

  • 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).
    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. It complicates the market engine thus will
impact performance.

Copyright

This document is placed in the public domain.

See Also

@froooze
Copy link

froooze commented Jul 17, 2019

Good idea, looking in the same direction.
#182

@Inmortak
Copy link

Inmortak commented Jul 17, 2019

I thought this was already implemented and I thought that the problem is that not enough force-settlements are coming in.

@abitmore
Copy link
Member Author

@Inmortak currently it's implemented that if there is a margin call, you can place a limit order to buy into the margin call which will fill immediately, but if you request a force settlement, it will execute after 24 hours (configurable by asset owner).

@abitmore abitmore changed the title New BSIP: Match force-settlement orders with margin calls immediately New BSIP: Match force-settlement orders with margin calls and limit orders immediately Jul 18, 2019
@abitmore
Copy link
Member Author

Added limit orders to title and OP.

@pmconrad
Copy link
Contributor

IMO we should keep the usual settlement delay, but upon settlement match with better orders first if there are any. I think user experience will suffer if forced settlement happens immediately sometimes, and sometimes with a delay. It would be particularly confusing if the settlement can only be partially filled at once, and the rest would have to wait for the delay.

@abitmore
Copy link
Member Author

@pmconrad I think the confusion can be mitigated by properly-done documentation and UI/UX. The fact is most of people in the past who chose to force-settle did actually misunderstand it but expected something else (UI/UX was a factor). See bitshares/bitshares-ui#2520.

We can even add an option in asset_force_settle_operation, so that the user can decide whether she is willing to fill her settle order earlier if possible.

@pmconrad
Copy link
Contributor

That said, the proposed functionality can be implemented client-side. UI could/should check if market order would be filled at a better price than current settlement price, and if so offer both options, i. e. sell on market or settle. User can choose, confusion should not arise.

@abitmore
Copy link
Member Author

Essentially you're talking about taker orders, but the proposed functionality includes maker orders as well. Settle orders have the advantage that its price is floating with feed price, while price of limit order can only be fixed so far.

@abitmore
Copy link
Member Author

abitmore commented Aug 9, 2019

Here is a bot taking advantage of the somewhat unfair rules of force-settlements: https://cryptofresh.com/u/sdr.m01, its strategy is possible to fail if there are competitions, but at least worked so far.

@pmconrad
Copy link
Contributor

pmconrad commented Aug 9, 2019

Please explain.

@abitmore
Copy link
Member Author

abitmore commented Aug 9, 2019

The story:

  • there was a force-settlement order scheduled to execute at block 39,900,413, settling 100K bitCNY;
  • exactly on that block, the bot created a debt position which has 100K bitCNY of debt, and the collateral ratio was a little bit higher than MCR, made sure it would have lowest CR among all debt positions, thus it would match the settle order;
  • the bot sold the newly-created 100K bitCNY to buyers, with price no lower than feed_price/(1+offset), enabled fill_or_kill;
  • after processed all transactions in the block, the force-settlement executed at the price feed_price/(1+offset), the bot's debt position got closed.

The result: the bot earned around 1% of profit.

This is some kind of front running.

IMO we should ... upon settlement match with better orders first if there are any.

This approach would make the front-running harder, although still possible.

@pmconrad
Copy link
Contributor

Thanks.

IMO that is not a problem. Market participants are free to choose if they want to sell or settle. If they choose settle they are settled in terms of feed price and offset. The bot doesn't change this.

The front-running is only possible if the market is in a healthy state, i. e. there are no margin calls open. Therefore the bot behaviour does not damage overall market health.

@abitmore
Copy link
Member Author

It's true that everyone who participated in the market were acting by the rule, but it doesn't mean the rule is perfect or is fair, because you don't know how many people didn't participate due to the potential imperfect or unfairness. We're here to improve things, to make good things even better, not only fix stupid things.

@ryanRfox
Copy link
Contributor

Assigned BSIP73. @abitmore please create a PR and reference this Issue for further discussion.

@ryanRfox ryanRfox changed the title New BSIP: Match force-settlement orders with margin calls and limit orders immediately BSIP73: Match Force-Settlement Orders with Margin Calls and Limit Orders Immediately Aug 26, 2019
@abitmore abitmore changed the title BSIP73: Match Force-Settlement Orders with Margin Calls and Limit Orders Immediately BSIP73: Match Force-Settlement Orders with Margin Calls and Limit Orders Aug 26, 2019
@abitmore
Copy link
Member Author

See PR #200. Updated OP of this issue.

@sschiessl-bcp
Copy link
Collaborator

Can the wording please updated to not talk about hard fork (which is confusing since it implies a different meaning in common publications). Suggestion: Replace with "protocol upgrade".

@abitmore
Copy link
Member Author

@sschiessl-bcp see #225.

@sschiessl-bcp
Copy link
Collaborator

What is the current flow when we close issues to respective BSIPs? The PRs are merged now.

@clockworkgr
Copy link
Member

what margin calls?

@ryanRfox
Copy link
Contributor

ryanRfox commented Oct 1, 2019

@sschiessl-bcp we leave the Issue open during the voting period to facilitate ongoing discussion. After the vote period concludes, both the README and BSIP will have the status field updated to reflect the outcome and the Issue then closed.

@shulthz
Copy link

shulthz commented Nov 13, 2019

I think we maybe need to charge fees as the market trading fees from Force-Settlement.

@abitmore
Copy link
Member Author

charge fees as the market trading fees from Force-Settlement.

It's implementation details and is described in other BSIPs, so no need to redundantly describe it in this BSIP.

@abitmore abitmore added the DEX label Feb 13, 2020
@abitmore
Copy link
Member Author

abitmore commented Apr 21, 2020

Draft merged in #200 and updated with #225. Closing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants