Skip to content

Commit

Permalink
Update market history for SMTs steemit#3599
Browse files Browse the repository at this point in the history
  • Loading branch information
mvandeberg committed Feb 11, 2020
1 parent 2d99d6a commit d5a6127
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ void blockchain_statistics_plugin_impl::on_block( const signed_block& b )
for( const auto& bucket : _tracked_buckets )
{
auto open = fc::time_point_sec( ( db.head_block_time().sec_since_epoch() / bucket ) * bucket );
auto itr = bucket_idx.find( boost::make_tuple( bucket, open ) );
auto itr = bucket_idx.find( boost::make_tuple( SBD_SYMBOL, bucket, open ) );

if( itr == bucket_idx.end() )
{
Expand Down
8 changes: 4 additions & 4 deletions libraries/plugins/apis/condenser_api/condenser_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1877,15 +1877,15 @@ namespace detail
FC_ASSERT( args.size() == 0 || args.size() == 1, "Expected 0-1 arguments, was ${n}", ("n", args.size()) );
FC_ASSERT( _market_history_api, "market_history_api_plugin not enabled." );
return get_order_book_return( _market_history_api->get_order_book( { args.size() == 1 ? args[0].as< uint32_t >() : 500 } ) );
return get_order_book_return( _market_history_api->get_order_book( { SBD_SYMBOL, args.size() == 1 ? args[0].as< uint32_t >() : 500 } ) );
}
DEFINE_API_IMPL( condenser_api_impl, get_trade_history )
{
FC_ASSERT( args.size() == 2 || args.size() == 3, "Expected 2-3 arguments, was ${n}", ("n", args.size()) );
FC_ASSERT( _market_history_api, "market_history_api_plugin not enabled." );
const auto& trades = _market_history_api->get_trade_history( { args[0].as< time_point_sec >(), args[1].as< time_point_sec >(), args.size() == 3 ? args[2].as< uint32_t >() : 1000 } ).trades;
const auto& trades = _market_history_api->get_trade_history( { SBD_SYMBOL, args[0].as< time_point_sec >(), args[1].as< time_point_sec >(), args.size() == 3 ? args[2].as< uint32_t >() : 1000 } ).trades;
get_trade_history_return result;
for( const auto& t : trades ) result.push_back( market_trade( t ) );
Expand All @@ -1898,7 +1898,7 @@ namespace detail
FC_ASSERT( args.size() == 0 || args.size() == 1, "Expected 0-1 arguments, was ${n}", ("n", args.size()) );
FC_ASSERT( _market_history_api, "market_history_api_plugin not enabled." );
const auto& trades = _market_history_api->get_recent_trades( { args.size() == 1 ? args[0].as< uint32_t >() : 1000 } ).trades;
const auto& trades = _market_history_api->get_recent_trades( { SBD_SYMBOL, args.size() == 1 ? args[0].as< uint32_t >() : 1000 } ).trades;
get_trade_history_return result;
for( const auto& t : trades ) result.push_back( market_trade( t ) );
Expand All @@ -1911,7 +1911,7 @@ namespace detail
CHECK_ARG_SIZE( 3 )
FC_ASSERT( _market_history_api, "market_history_api_plugin not enabled." );
return _market_history_api->get_market_history( { args[0].as< uint32_t >(), args[1].as< time_point_sec >(), args[2].as< time_point_sec >() } ).buckets;
return _market_history_api->get_market_history( { SBD_SYMBOL, args[0].as< uint32_t >(), args[1].as< time_point_sec >(), args[2].as< time_point_sec >() } ).buckets;
}
DEFINE_API_IMPL( condenser_api_impl, get_market_history_buckets )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,7 @@ DEFINE_API_ARGS( get_order_book, vector< variant >, or
DEFINE_API_ARGS( get_trade_history, vector< variant >, vector< market_trade > )
DEFINE_API_ARGS( get_recent_trades, vector< variant >, vector< market_trade > )
DEFINE_API_ARGS( get_market_history, vector< variant >, vector< market_history::bucket_object > )
DEFINE_API_ARGS( get_market_history_buckets, vector< variant >, flat_set< uint32_t > )
DEFINE_API_ARGS( get_market_history_buckets, vector< variant >, vector< uint32_t > )
DEFINE_API_ARGS( list_proposals, vector< variant >, vector< api_proposal_object > )
DEFINE_API_ARGS( find_proposals, vector< variant >, vector< api_proposal_object > )
DEFINE_API_ARGS( list_proposal_votes, vector< variant >, vector< database_api::api_proposal_vote_object > )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ using fc::time_point_sec;
using json_rpc::void_type;


typedef void_type get_ticker_args;
struct get_ticker_args
{
asset_symbol_type market = SBD_SYMBOL;
};

struct get_ticker_return
{
Expand All @@ -30,7 +33,7 @@ struct get_ticker_return
asset sbd_volume = asset( 0, SBD_SYMBOL );
};

typedef void_type get_volume_args;
typedef get_ticker_args get_volume_args;

struct get_volume_return
{
Expand All @@ -49,7 +52,8 @@ struct order

struct get_order_book_args
{
uint32_t limit = 500;
asset_symbol_type market = SBD_SYMBOL;
uint32_t limit = 500;
};

struct get_order_book_return
Expand All @@ -67,9 +71,10 @@ struct market_trade

struct get_trade_history_args
{
time_point_sec start;
time_point_sec end;
uint32_t limit = 1000;
asset_symbol_type market = SBD_SYMBOL;
time_point_sec start;
time_point_sec end;
uint32_t limit = 1000;
};

struct get_trade_history_return
Expand All @@ -79,28 +84,30 @@ struct get_trade_history_return

struct get_recent_trades_args
{
uint32_t limit = 1000;
asset_symbol_type market = SBD_SYMBOL;
uint32_t limit = 1000;
};

typedef get_trade_history_return get_recent_trades_return;

struct get_market_history_args
{
uint32_t bucket_seconds;
time_point_sec start;
time_point_sec end;
asset_symbol_type market = SBD_SYMBOL;
uint32_t bucket_seconds;
time_point_sec start;
time_point_sec end;
};

struct get_market_history_return
{
std::vector< market_history::bucket_object > buckets;
};

typedef void_type get_market_history_buckets_args;
typedef get_ticker_args get_market_history_buckets_args;

struct get_market_history_buckets_return
{
flat_set< uint32_t > bucket_sizes;
vector< uint32_t > bucket_sizes;
};


Expand Down Expand Up @@ -129,6 +136,9 @@ class market_history_api

} } } // steem::plugins::market_history

FC_REFLECT( steem::plugins::market_history::get_ticker_args,
(market) )

FC_REFLECT( steem::plugins::market_history::get_ticker_return,
(latest)(lowest_ask)(highest_bid)(percent_change)(steem_volume)(sbd_volume) )

Expand All @@ -139,7 +149,7 @@ FC_REFLECT( steem::plugins::market_history::order,
(order_price)(real_price)(steem)(sbd)(created) )

FC_REFLECT( steem::plugins::market_history::get_order_book_args,
(limit) )
(market)(limit) )

FC_REFLECT( steem::plugins::market_history::get_order_book_return,
(bids)(asks) )
Expand All @@ -148,16 +158,16 @@ FC_REFLECT( steem::plugins::market_history::market_trade,
(date)(current_pays)(open_pays) )

FC_REFLECT( steem::plugins::market_history::get_trade_history_args,
(start)(end)(limit) )
(market)(start)(end)(limit) )

FC_REFLECT( steem::plugins::market_history::get_trade_history_return,
(trades) )

FC_REFLECT( steem::plugins::market_history::get_recent_trades_args,
(limit) )
(market)(limit) )

FC_REFLECT( steem::plugins::market_history::get_market_history_args,
(bucket_seconds)(start)(end) )
(market)(bucket_seconds)(start)(end) )

FC_REFLECT( steem::plugins::market_history::get_market_history_return,
(buckets) )
Expand Down
91 changes: 58 additions & 33 deletions libraries/plugins/apis/market_history_api/market_history_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,24 @@ DEFINE_API_IMPL( market_history_api_impl, get_ticker )
get_ticker_return result;

const auto& bucket_idx = _db.get_index< bucket_index, by_bucket >();
auto itr = bucket_idx.lower_bound( boost::make_tuple( 0, _db.head_block_time() - 86400 ) );
auto itr = bucket_idx.lower_bound( boost::make_tuple( args.market, 0, _db.head_block_time() - 86400 ) );

if( itr != bucket_idx.end() )
{
auto open = ASSET_TO_REAL( asset( itr->non_steem.open, SBD_SYMBOL ) ) / ASSET_TO_REAL( asset( itr->steem.open, STEEM_SYMBOL ) );
itr = bucket_idx.lower_bound( boost::make_tuple( 0, _db.head_block_time() ) );
result.latest = ASSET_TO_REAL( asset( itr->non_steem.close, SBD_SYMBOL ) ) / ASSET_TO_REAL( asset( itr->steem.close, STEEM_SYMBOL ) );
auto open = ASSET_TO_REAL( asset( itr->non_steem.open, args.market ) ) / ASSET_TO_REAL( asset( itr->steem.open, STEEM_SYMBOL ) );
itr = bucket_idx.lower_bound( boost::make_tuple( args.market, 0, _db.head_block_time() ) );
result.latest = ASSET_TO_REAL( asset( itr->non_steem.close, args.market ) ) / ASSET_TO_REAL( asset( itr->steem.close, STEEM_SYMBOL ) );
result.percent_change = ( (result.latest - open ) / open ) * 100;
}

auto orders = get_order_book( get_order_book_args{ 1 } );
if( orders.bids.empty() == false)
auto orders = get_order_book( get_order_book_args{ args.market, 1 } );
if( orders.bids.empty() == false )
result.highest_bid = orders.bids[0].real_price;
if( orders.asks.empty() == false)
if( orders.asks.empty() == false )
result.lowest_ask = orders.asks[0].real_price;

auto volume = get_volume( get_volume_args() );

auto volume = get_volume( { args.market } );
result.steem_volume = volume.steem_volume;
result.sbd_volume = volume.sbd_volume;

Expand All @@ -59,21 +60,38 @@ DEFINE_API_IMPL( market_history_api_impl, get_ticker )

DEFINE_API_IMPL( market_history_api_impl, get_volume )
{
const auto& tracked_buckets = appbase::app().get_plugin< steem::plugins::market_history::market_history_plugin >().get_tracked_buckets();
const auto& bucket_idx = _db.get_index< bucket_index, by_bucket >();
auto itr = bucket_idx.lower_bound( boost::make_tuple( 0, _db.head_block_time() - 86400 ) );
get_volume_return result;

if( itr == bucket_idx.end() )
return result;
get_volume_return result;
fc::time_point_sec earliest_time = _db.head_block_time();
fc::time_point_sec latest_time = _db.head_block_time() - 86400;

uint32_t bucket_size = itr->seconds;
do
for( const auto bucket_size : tracked_buckets )
{
result.steem_volume.amount += itr->steem.volume;
result.sbd_volume.amount += itr->non_steem.volume;
auto itr = bucket_idx.lower_bound( boost::make_tuple( args.market, bucket_size, latest_time ) );

++itr;
} while( itr != bucket_idx.end() && itr->seconds == bucket_size );
while( itr != bucket_idx.end() && itr->symbol == args.market )
{
result.steem_volume.amount += itr->steem.volume;
result.sbd_volume.amount += itr->non_steem.volume;
if( itr->open < latest_time ) latest_time = itr->open;
if( itr->open > earliest_time ) earliest_time = itr->open;

++itr;
}

itr = bucket_idx.lower_bound( boost::make_tuple( args.market, bucket_size, earliest_time ) );

while( itr->open < earliest_time )
{
result.steem_volume.amount += itr->steem.volume;
result.sbd_volume.amount += itr->non_steem.volume;
if( itr->open > earliest_time ) earliest_time = itr->open;

++itr;
}
}

return result;
}
Expand All @@ -83,23 +101,23 @@ DEFINE_API_IMPL( market_history_api_impl, get_order_book )
FC_ASSERT( args.limit <= 500 );

const auto& order_idx = _db.get_index< chain::limit_order_index, chain::by_price >();
auto itr = order_idx.lower_bound( price::max( SBD_SYMBOL, STEEM_SYMBOL ) );
auto itr = order_idx.lower_bound( price::max( args.market, STEEM_SYMBOL ) );

get_order_book_return result;

while( itr != order_idx.end() && itr->sell_price.base.symbol == SBD_SYMBOL && result.bids.size() < args.limit )
while( itr != order_idx.end() && itr->sell_price.base.symbol == args.market && result.bids.size() < args.limit )
{
order cur;
cur.order_price = itr->sell_price;
cur.real_price = ASSET_TO_REAL( itr->sell_price.base ) / ASSET_TO_REAL( itr->sell_price.quote );
cur.steem = ( asset( itr->for_sale, SBD_SYMBOL ) * itr->sell_price ).amount;
cur.steem = ( asset( itr->for_sale, args.market ) * itr->sell_price ).amount;
cur.sbd = itr->for_sale;
cur.created = itr->created;
result.bids.push_back( cur );
++itr;
}

itr = order_idx.lower_bound( price::max( STEEM_SYMBOL, SBD_SYMBOL ) );
itr = order_idx.lower_bound( price::max( STEEM_SYMBOL, args.market ) );

while( itr != order_idx.end() && itr->sell_price.base.symbol == STEEM_SYMBOL && result.asks.size() < args.limit )
{
Expand All @@ -120,7 +138,7 @@ DEFINE_API_IMPL( market_history_api_impl, get_trade_history )
{
FC_ASSERT( args.limit <= 1000 );
const auto& bucket_idx = _db.get_index< order_history_index, by_time >();
auto itr = bucket_idx.lower_bound( args.start );
auto itr = bucket_idx.lower_bound( boost::make_tuple( args.market, args.start ) );

get_trade_history_return result;

Expand All @@ -141,27 +159,34 @@ DEFINE_API_IMPL( market_history_api_impl, get_recent_trades )
{
FC_ASSERT( args.limit <= 1000 );
const auto& order_idx = _db.get_index< order_history_index, by_time >();
auto itr = order_idx.rbegin();
auto itr = order_idx.upper_bound( args.market );
auto begin = order_idx.begin();

get_recent_trades_return result;

while( itr != order_idx.rend() && result.trades.size() < args.limit )
if( order_idx.size() == 0 ) return result;

do
{
market_trade trade;
trade.date = itr->time;
trade.current_pays = itr->op.current_pays;
trade.open_pays = itr->op.open_pays;
result.trades.push_back( trade );
++itr;
}
--itr;

if( itr->market() == args.market )
{
market_trade trade;
trade.date = itr->time;
trade.current_pays = itr->op.current_pays;
trade.open_pays = itr->op.open_pays;
result.trades.push_back( trade );
}
} while( itr != begin );

return result;
}

DEFINE_API_IMPL( market_history_api_impl, get_market_history )
{
const auto& bucket_idx = _db.get_index< bucket_index, by_bucket >();
auto itr = bucket_idx.lower_bound( boost::make_tuple( args.bucket_seconds, args.start ) );
auto itr = bucket_idx.lower_bound( boost::make_tuple( args.market, args.bucket_seconds, args.start ) );

get_market_history_return result;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class market_history_plugin : public plugin< market_history_plugin >

static const std::string& name() { static std::string name = STEEM_MARKET_HISTORY_PLUGIN_NAME; return name; }

flat_set< uint32_t > get_tracked_buckets() const;
uint32_t get_max_history_per_bucket() const;
const vector< uint32_t >& get_tracked_buckets() const;
uint32_t get_max_history_track_time() const;

virtual void set_program_options(
options_description& cli,
Expand Down Expand Up @@ -122,6 +122,12 @@ struct order_history_object : public object< order_history_object_type, order_hi

fc::time_point_sec time;
protocol::fill_order_operation op;

asset_symbol_type market() const
{
return op.current_pays.symbol == STEEM_SYMBOL ?
op.open_pays.symbol : op.current_pays.symbol;
}
};

typedef oid< order_history_object > order_history_id_type;
Expand All @@ -134,10 +140,11 @@ typedef multi_index_container<
ordered_unique< tag< by_id >, member< bucket_object, bucket_id_type, &bucket_object::id > >,
ordered_unique< tag< by_bucket >,
composite_key< bucket_object,
member< bucket_object, asset_symbol_type, &bucket_object::symbol >,
member< bucket_object, uint32_t, &bucket_object::seconds >,
member< bucket_object, fc::time_point_sec, &bucket_object::open >
>,
composite_key_compare< std::less< uint32_t >, std::less< fc::time_point_sec > >
composite_key_compare< std::less< asset_symbol_type >, std::less< uint32_t >, std::less< fc::time_point_sec > >
>
>,
allocator< bucket_object >
Expand All @@ -150,6 +157,7 @@ typedef multi_index_container<
ordered_unique< tag< by_id >, member< order_history_object, order_history_id_type, &order_history_object::id > >,
ordered_unique< tag< by_time >,
composite_key< order_history_object,
const_mem_fun< order_history_object, asset_symbol_type, &order_history_object::market >,
member< order_history_object, time_point_sec, &order_history_object::time >,
member< order_history_object, order_history_id_type, &order_history_object::id >
>
Expand Down
Loading

0 comments on commit d5a6127

Please sign in to comment.