38 namespace graphene {
namespace market_history {
78 :_plugin(mhp),_now(n),_meta(meta) {}
91 const auto& history_idx = order_his_idx.get<by_key>();
92 const auto& his_time_idx = order_his_idx.get<by_market_time>();
98 if( hkey.base > hkey.quote )
99 std::swap( hkey.base, hkey.quote );
100 hkey.sequence = std::numeric_limits<int64_t>::min();
102 auto itr = history_idx.lower_bound( hkey );
104 if( itr != history_idx.end() && itr->key.base == hkey.base && itr->key.quote == hkey.quote )
105 hkey.sequence = itr->key.sequence - 1;
116 if( _meta ==
nullptr )
119 if( meta_idx.size() == 0 )
125 _meta = &( *meta_idx.begin() );
130 hkey.sequence += max_records;
131 itr = history_idx.lower_bound( hkey );
132 if( itr != history_idx.end() && itr->key.base == hkey.base && itr->key.quote == hkey.quote )
136 if( min_time + max_seconds < _now )
137 min_time = _now - max_seconds;
138 auto time_itr = his_time_idx.lower_bound( std::make_tuple( hkey.base, hkey.quote, min_time ) );
139 if( time_itr != his_time_idx.end() && time_itr->key.base == hkey.base && time_itr->key.quote == hkey.quote )
141 if( itr->key.sequence >= time_itr->key.sequence )
143 while( itr != history_idx.end() && itr->key.base == hkey.base && itr->key.quote == hkey.quote )
147 db.remove( *old_itr );
152 while( time_itr != his_time_idx.end() && time_itr->key.base == hkey.base && time_itr->key.quote == hkey.quote )
154 auto old_itr = time_itr;
156 db.remove( *old_itr );
175 trade_price = ~trade_price;
180 fill_price = ~fill_price;
184 auto ticker_itr = ticker_idx.find( std::make_tuple( key.
base, key.
quote ) );
185 if( ticker_itr == ticker_idx.end() )
189 mt.quote = key.
quote;
190 mt.last_day_base = 0;
191 mt.last_day_quote = 0;
210 if( max_history == 0 )
return;
213 if( buckets.size() == 0 )
return;
215 const auto& bucket_idx = db.get_index_type<
bucket_index>();
216 for(
auto bucket : buckets )
220 if( bucket_num > max_history )
221 cutoff = cutoff + ( bucket * ( bucket_num - max_history ) );
226 const auto& by_key_idx = bucket_idx.indices().get<by_key>();
227 auto bucket_itr = by_key_idx.find( key );
228 if( bucket_itr == by_key_idx.end() )
239 b.high_base = b.close_base;
240 b.high_quote = b.close_quote;
241 b.low_base = b.close_base;
242 b.low_quote = b.close_quote;
252 }
catch( fc::overflow_exception& ) {
253 b.
base_volume = std::numeric_limits<int64_t>::max();
257 }
catch( fc::overflow_exception& ) {
262 if( b.
high() < fill_price )
267 if( b.
low() > fill_price )
278 bucket_itr = by_key_idx.lower_bound( key );
280 while( bucket_itr != by_key_idx.end() &&
281 bucket_itr->key.base == key.
base &&
282 bucket_itr->key.quote == key.
quote &&
283 bucket_itr->key.seconds == bucket &&
284 bucket_itr->key.open < cutoff )
287 auto old_bucket_itr = bucket_itr;
289 db.remove( *old_bucket_itr );
302 if( meta_idx.size() > 0 )
303 _meta = &( *meta_idx.begin() );
307 if( lp_meta_idx.size() > 0 )
308 _lp_meta = &( *lp_meta_idx.begin() );
325 if( _meta !=
nullptr )
327 time_point_sec last_day = b.timestamp - 86400;
334 while( history_itr != history_idx.end() && history_itr->time < last_day )
350 trade_price = ~trade_price;
355 fill_price = ~fill_price;
357 auto ticker_itr = ticker_idx.find( std::make_tuple( key.
base, key.
quote ) );
358 if( ticker_itr != ticker_idx.end() )
368 last_min_his_id = history_itr->id;
372 if( history_itr != history_idx.end() )
395 if( _lp_meta !=
nullptr )
397 time_point_sec last_day = b.timestamp - 86400;
403 while( history_itr != history_idx.end() && history_itr->time < last_day )
411 if( ticker !=
nullptr )
446 auto amount_in = op.amount_to_sell.amount - result.fees.front().amount;
447 auto amount_out = result.received.front().amount + result.fees.at(1).amount;
448 if( op.amount_to_sell.asset_id < op.min_to_receive.asset_id )
470 last_min_his_id = history_itr->id;
474 if( history_itr != history_idx.end() )
537 uint64_t sequence = 0;
552 const auto& his_seq_idx = his_index.get<by_pool_seq>();
553 const auto& his_time_idx = his_index.get<by_pool_time>();
557 auto itr = his_seq_idx.lower_bound( *pool );
558 if( itr != his_seq_idx.end() && itr->pool == *pool )
559 sequence = itr->sequence + 1;
575 if( lp_meta ==
nullptr )
578 if( lp_meta_idx.size() == 0 )
584 lp_meta = &( *lp_meta_idx.begin() );
591 auto itr = his_seq_idx.lower_bound( std::make_tuple( *pool, min_seq ) );
592 if( itr != his_seq_idx.end() && itr->pool == *pool )
597 auto time_itr = his_time_idx.lower_bound( std::make_tuple( *pool, min_time ) );
598 if( time_itr != his_time_idx.end() && time_itr->pool == *pool )
600 if( itr->sequence <= time_itr->sequence )
602 while( itr != his_seq_idx.end() && itr->pool == *pool )
606 db.remove( *old_itr );
611 while( time_itr != his_time_idx.end() && time_itr->pool == *pool )
613 auto old_itr = time_itr;
615 db.remove( *old_itr );
629 }
while( ticker->
id.
instance() < pool->instance );
635 if( ticker !=
nullptr )
684 auto amount_in = op.amount_to_sell.amount - result.fees.front().amount;
685 auto amount_out = result.received.front().amount + result.fees.at(1).amount;
686 if( op.amount_to_sell.asset_id < op.min_to_receive.asset_id )
738 return "market_history";
742 boost::program_options::options_description& cli,
743 boost::program_options::options_description& cfg
747 (
"bucket-size", boost::program_options::value<string>()->default_value(
"[60,300,900,1800,3600,14400,86400]"),
748 "Track market history by grouping orders into buckets of equal size measured " 749 "in seconds specified as a JSON array of numbers")
750 (
"history-per-size", boost::program_options::value<uint32_t>()->default_value(1000),
751 "How far back in time to track history for each bucket size, " 752 "measured in the number of buckets (default: 1000)")
753 (
"max-order-his-records-per-market", boost::program_options::value<uint32_t>()->default_value(1000),
754 "Will only store this amount of matched orders for each market in order history for querying, " 755 "or those meet the other option, which has more data (default: 1000). " 756 "This parameter is reused for liquidity pools as maximum operations per pool in history.")
757 (
"max-order-his-seconds-per-market", boost::program_options::value<uint32_t>()->default_value(259200),
758 "Will only store matched orders in last X seconds for each market in order history for querying, " 759 "or those meet the other option, which has more data (default: 259200 (3 days)). " 760 "This parameter is reused for liquidity pools as operations in last X seconds per pool in history. " 761 "Note: this parameter need to be greater than 24 hours to be able to serve market ticker data correctly.")
780 if( options.count(
"bucket-size" ) > 0 )
782 const std::string& buckets = options[
"bucket-size"].as<
string>();
784 my->_tracked_buckets.erase( 0 );
786 if( options.count(
"history-per-size" ) > 0 )
787 my->_maximum_history_per_bucket_size = options[
"history-per-size"].as<uint32_t>();
788 if( options.count(
"max-order-his-records-per-market" ) > 0 )
789 my->_max_order_his_records_per_market = options[
"max-order-his-records-per-market"].as<uint32_t>();
790 if( options.count(
"max-order-his-seconds-per-market" ) > 0 )
791 my->_max_order_his_seconds_per_market = options[
"max-order-his-seconds-per-market"].as<uint32_t>();
800 return my->_tracked_buckets;
805 return my->_maximum_history_per_bucket_size;
810 return my->_max_order_his_records_per_market;
815 return my->_max_order_his_seconds_per_market;
void operator()(const fill_order_operation &o) const
bool skip_min_order_his_id
object_id_type rolling_min_lp_his_id
void modify(const T &obj, const Lambda &m)
liquidity_pool_id_type pool
ID of the liquidity pool.
market_history_plugin_impl(market_history_plugin &_plugin)
fc::uint128_t _24h_deposit_share_amount
liquidity_pool_id_type pool
ID of the liquidity pool.
Wraps a derived index to intercept calls to create, modify, and remove so that callbacks may be fired...
~market_history_plugin() override
fc::uint128_t _24h_withdrawal_share_amount
Create a new liquidity pool.
void plugin_set_program_options(boost::program_options::options_description &cli, boost::program_options::options_description &cfg) override
Fill in command line parameters used by the plugin.
fc::uint128_t total_deposit_amount_a
fc::signal< void(const signed_block &)> applied_block
A simple index uses a vector<unique_ptr<T>> to store data.
share_type _24h_balance_delta_b
tracks the history of all logical operations on blockchain stateAll operations and virtual operations...
tracks the blockchain state in an extensible manner
share_type last_day_quote
const IndexType & get_index_type() const
fc::uint128_t _24h_exchange_a2b_amount_a
liquidity_pool_id_type pool
ID of the liquidity pool.
fc::uint128_t _24h_withdrawal_fee_b
fc::uint128_t _24h_deposit_amount_a
const market_ticker_meta_object *& _meta
result_type operator()(const liquidity_pool_withdraw_operation &o) const
graphene::chain::database & database()
const flat_set< uint32_t > & tracked_buckets() const
visitor::result_type visit(visitor &v)
fc::uint128_t total_withdrawal_share_amount
const vector< optional< operation_history_object > > & get_applied_operations() const
uint32_t _24h_exchange_a2b_count
#define FC_CAPTURE_AND_LOG(...)
uint64_t instance() const
uint32_t _max_order_his_records_per_market
provides stack-based nullable value similar to boost::optional
fc::uint128_t total_deposit_amount_b
fc::uint128_t _24h_exchange_b2a_amount_b
result_type operator()(const T &) const
fc::uint128_t _24h_exchange_b2a_amount_a
fc::uint128_t _24h_deposit_amount_b
void plugin_startup() override
Begin normal runtime operations.
uint32_t max_order_his_seconds_per_market() const
fc::uint128_t total_withdrawal_amount_a
fc::uint128_t total_exchange_fee_b
chain::database & database()
const T * find(const object_id_type &id) const
fc::uint128_t total_withdrawal_fee_b
fc::uint128_t _24h_exchange_a2b_amount_b
The price struct stores asset prices in the BitShares system.
market_history_plugin & _self
const object & get(object_id_type id) const
void plugin_initialize(const boost::program_options::variables_map &options) override
Perform early startup routines and register plugin indexes, callbacks, etc.
liquidity_pool_id_type pool
ID of the liquidity pool.
Withdraw from a liquidity pool.
void update_liquidity_pool_histories(time_point_sec time, const operation_history_object &oho, const lp_ticker_meta_object *&lp_meta)
process all operations related to liquidity pools
#define FC_CAPTURE_AND_RETHROW(...)
fc::uint128_t base_volume
std::string plugin_name() const override
Get the name of the plugin.
T as(uint32_t max_depth) const
Exchange with a liquidity pool.
uint32_t _24h_exchange_b2a_count
result_type operator()(const liquidity_pool_exchange_operation &o) const
uint64_t total_deposit_count
fc::uint128_t _24h_withdrawal_amount_b
fc::uint128_t _24h_exchange_fee_b
uint32_t _maximum_history_per_bucket_size
fc::uint128_t total_exchange_fee_a
fc::uint128_t total_exchange_b2a_amount_b
fc::uint128_t total_exchange_a2b_amount_a
uint64_t total_exchange_b2a_count
fc::uint128_t quote_volume
uint32_t max_order_his_records_per_market() const
result_type operator()(const liquidity_pool_deposit_operation &o) const
market_history_plugin & _plugin
Stores meta data for liquidity pool tickers.
uint64_t total_exchange_a2b_count
static variant from_string(const string &utf8_str, parse_type ptype=legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
uint32_t _max_order_his_seconds_per_market
fc::uint128_t total_deposit_share_amount
market_history_plugin(graphene::app::application &app)
share_type _24h_balance_delta_a
fc::uint128_t total_exchange_b2a_amount_a
result_type operator()(const liquidity_pool_delete_operation &o) const
uint32_t sec_since_epoch() const
optional< liquidity_pool_id_type > result_type
uint32_t _24h_deposit_count
fc::uint128_t _24h_withdrawal_amount_a
uint64_t total_withdrawal_count
uint32_t _24h_withdrawal_count
fc::uint128_t _24h_exchange_fee_a
flat_set< uint32_t > _tracked_buckets
operation_process_fill_order(market_history_plugin &mhp, fc::time_point_sec n, const market_ticker_meta_object *&meta)
void update_market_histories(const signed_block &b)
fc::uint128_t total_withdrawal_fee_a
object_id_type rolling_min_order_his_id
fc::uint128_t _24h_withdrawal_fee_a
fc::uint128_t total_exchange_a2b_amount_b
uint32_t max_history() const
void operator()(const T &) const
Deposit to a liquidity pool.
fc::uint128_t total_withdrawal_amount_b
Stores ticker data for liquidity pools.