From 259fbe05ac0993f0eada80fa2fab1b954b7e364f Mon Sep 17 00:00:00 2001 From: abitmore Date: Thu, 22 Feb 2018 14:35:23 +0000 Subject: [PATCH] bsip35: add definition of smaller order --- bsip-0035.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/bsip-0035.md b/bsip-0035.md index 576ded7..17b7058 100644 --- a/bsip-0035.md +++ b/bsip-0035.md @@ -155,7 +155,38 @@ filled at a less favorable price. It's the least bad compromise since it has the most efficiency (highest traded volume while not hard to implement) among the solutions. -However, when filling a small order at a less favorable price, the receiving +The algorithm can be described as follows (sample code is +[here](https://github.com/bitshares/bitshares-core/blob/2.0.171105a/libraries/chain/db_market.cpp#L311-L324)): + +Assuming the maker order is selling amount `X` of asset A, with price +`maker_price = maker_b_amount / maker_a_amount`; assuming the taker is buying +asset A with amount `Y` of asset B, with price +`taker_price = taker_b_amount / taker_a_amount`. Anyway, since the two orders +will be matched at maker price, the taker price doesn't matter here as long +as it's higher than or equal to maker price. Note: currently all limit orders +are implemented as sell limit orders, so in the example, the taker order can +only specify amount of asset B but not amount of asset A. + +Now compare `X * maker_price` with `Y`. To be accurate (avoid rounding), +compare `X' = X * maker_b_amount` with `Y' = Y * maker_a_amount`. +* The best scenario is when `X' == Y'`, which means both orders can be + completely filled at `maker_price`. +* If `X' < Y'`, it means the maker order can be completely filled but the + taker order can't, aka the maker order is smaller. + In this case, maker pay amount `X` of asset A to taker, taker pay amount + `Y" = round_down( X' / maker_a_amount )` of asset B to maker. + Note: after rounded down, `Y"` may be smaller than the rational number + `X * maker_price`, which means `Y" / X` may be lower than `maker_price`, + that said, the maker order may has been filled at a less favorable price. +* If `X' > Y'`, it means the taker order can be completely filled but the + maker order can't, aka the taker order is smaller. + In this case, taker pay amount `Y` of asset B to maker, maker pay amount + `X" = round_down( Y' / maker_b_amount )` of asset A to taker. + Note: after rounded down, `X"` may be smaller than the rational number + `Y / taker_price`, which means `Y / X"` may be higher than `taker_price`, + that said, the taker order may has been filled at a less favorable price. + +When filling a small order at a less favorable price, the receiving amount is often rounded down to zero, thus causes the something-for-nothing issue. Current code tried to solve the issue by cancelling the smaller order when it would receive nothing, but only applied this rule in a few senarios