Skip to content
This repository was archived by the owner on Feb 21, 2019. It is now read-only.

Commit c07cf63

Browse files
market_engine: Reflow three-way choice between called, expired and inactive margin positions
1 parent a165663 commit c07cf63

File tree

2 files changed

+23
-24
lines changed

2 files changed

+23
-24
lines changed

libraries/blockchain/include/bts/blockchain/market_engine.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ namespace bts { namespace blockchain { namespace detail {
4242
return BTS_BLOCKCHAIN_MAX_SHORT_PERIOD_SEC - (*_current_ask->expiration - _pending_state->now()).to_seconds();
4343
}
4444

45-
price minimum_ask()const
45+
price minimum_cover_ask_price()const
4646
{
4747
FC_ASSERT( _feed_price.valid() );
4848
price min_ask = *_feed_price;

libraries/blockchain/market_engine.cpp

+22-23
Original file line numberDiff line numberDiff line change
@@ -151,39 +151,38 @@ namespace bts { namespace blockchain { namespace detail {
151151
if( _current_ask->type == cover_order )
152152
{
153153
FC_ASSERT( quote_asset->is_market_issued() );
154-
if( !_feed_price.valid() ) { _current_ask.reset(); continue; }
154+
// get_next_ask() shouldn't return covers if there's no feed
155+
FC_ASSERT( _feed_price.valid() );
155156

156157
/**
157-
* If call price is not reached AND cover has not expired, he lives to fight another day.
158-
* Also don't allow margin calls to be executed too far below
158+
* Don't allow margin calls to be executed too far below
159159
* the minimum ask, this could lead to an attack where someone
160160
* walks the whole book to steal the collateral.
161161
*/
162-
if( (mtrx.ask_price < mtrx.bid_price && _current_collat_record.expiration > _pending_state->now()) ||
163-
mtrx.bid_price < minimum_ask() )
162+
if( mtrx.bid_price < minimum_cover_ask_price() )
164163
{
165-
_current_ask.reset(); continue;
164+
ilog("terminating cover match iteration because bid doesn't meet minimum_cover_ask_price()");
165+
break;
166166
}
167-
/**
168-
* Protect expired cover orders from over-paying to exit their position. If there are no bids at
169-
* or above the price feed then the expired cover creates a buy wall at the price feed. No
170-
* need to punish them.
171-
*/
172-
if( _current_collat_record.expiration < _pending_state->now() && mtrx.bid_price < *_feed_price )
173-
{
174-
/** make sure that expired *AND* margin called orders don't get skipped */
175167

176-
// if the call price < feed price then no margin call has occurred yet
177-
// so we can skip it.
178-
if( _current_ask->get_price() < *_feed_price )
179-
_current_ask.reset(); continue;
168+
if( mtrx.ask_price > *_feed_price )
169+
{
170+
// margin called cover
171+
mtrx.ask_price = mtrx.bid_price;
172+
ilog("cover is margin call executing at price ${p}", ("p",mtrx.ask_price));
173+
}
174+
else if( (*_current_ask->expiration) <= _pending_state->now() )
175+
{
176+
// expired cover which has not been margin called
177+
mtrx.ask_price = *_feed_price;
178+
ilog("cover is executing at feed price ${p}", ("p",mtrx.ask_price));
179+
}
180+
else
181+
{
182+
// inactive cover
183+
FC_ASSERT(false, "get_next_ask() returned inactive cover");
180184
}
181-
//This is a forced cover. He's gonna sell at whatever price a buyer wants. No choice.
182-
mtrx.ask_price = mtrx.bid_price;
183185
}
184-
// get_next_ask() will return all covers first after checking expiration... which means
185-
// if it is not a cover then we can stop matching orders as soon as there exists a spread
186-
//// The ask price hasn't been reached
187186
else if( mtrx.bid_price < mtrx.ask_price )
188187
{
189188
wlog( "bid_price ${b} < ask_price ${a}; exit market loop", ("b",mtrx.bid_price)("a",mtrx.ask_price) );

0 commit comments

Comments
 (0)