Fixed to follow QUOTE:BASE semantics. Cleanup and added in wallet calls that were missed in last merge. #592
This commit is contained in:
parent
a675023b9f
commit
4b346579a8
4 changed files with 286 additions and 126 deletions
|
|
@ -31,6 +31,8 @@
|
|||
#include <fc/crypto/hex.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/rational.hpp>
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
#include <cctype>
|
||||
|
||||
|
|
@ -1025,56 +1027,37 @@ market_ticker database_api_impl::get_ticker( const string& base, const string& q
|
|||
try {
|
||||
if( base_id > quote_id ) std::swap(base_id, quote_id);
|
||||
|
||||
const auto& bidx = _db.get_index_type<bucket_index>();
|
||||
const auto& by_key_idx = bidx.indices().get<by_key>();
|
||||
uint32_t bucket_size = 86400;
|
||||
uint32_t day = 86400;
|
||||
auto now = fc::time_point_sec( fc::time_point::now() );
|
||||
|
||||
auto itr = by_key_idx.lower_bound( bucket_key( base_id, quote_id, bucket_size,
|
||||
now - bucket_size ) );
|
||||
|
||||
auto orders = get_order_book( base, quote, 1 );
|
||||
auto trades = get_trade_history( base, quote, now, fc::time_point_sec( now.sec_since_epoch() - day ), 100 );
|
||||
|
||||
if( itr != by_key_idx.end() && itr->key.base == base_id && itr->key.quote == quote_id && itr->key.seconds == bucket_size )
|
||||
{
|
||||
auto trades = get_trade_history( base, quote, now, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );
|
||||
|
||||
if (assets[0]->id == base_id)
|
||||
{
|
||||
result.latest = trades[0].price;
|
||||
result.percent_change = ( result.latest / ( price_to_real( itr->open_quote, assets[1]->precision ) / price_to_real( itr->open_base, assets[0]->precision ) ) - 1 ) * 100;
|
||||
//result.lowest_ask = price_to_real( itr->low_quote, assets[1]->precision ) / price_to_real( itr->low_base, assets[0]->precision );
|
||||
//result.highest_bid = price_to_real( itr->high_quote, assets[1]->precision ) / price_to_real( itr->high_base, assets[0]->precision );
|
||||
result.lowest_ask = orders.asks[0].first;
|
||||
result.highest_bid = orders.bids[0].first;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.latest = trades[0].price;
|
||||
result.percent_change = ( result.latest / ( price_to_real( itr->open_base, assets[1]->precision ) / price_to_real( itr->open_quote, assets[0]->precision ) ) - 1) * 100;
|
||||
//result.lowest_ask = price_to_real( itr->low_base, assets[1]->precision ) / price_to_real( itr->low_quote, assets[0]->precision );
|
||||
//result.highest_bid = price_to_real( itr->high_base, assets[1]->precision ) / price_to_real( itr->high_quote, assets[0]->precision );
|
||||
result.lowest_ask = orders.bids[0].first;
|
||||
result.highest_bid = orders.asks[0].first;
|
||||
}
|
||||
|
||||
for ( market_trade t: trades )
|
||||
{
|
||||
result.base_volume += t.amount;
|
||||
result.quote_volume += t.value;
|
||||
result.base_volume += t.value;
|
||||
result.quote_volume += t.amount;
|
||||
}
|
||||
|
||||
while (trades.size() == 100)
|
||||
{
|
||||
trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - day ), 100 );
|
||||
|
||||
for ( market_trade t: trades )
|
||||
{
|
||||
result.base_volume += t.amount;
|
||||
result.quote_volume += t.value;
|
||||
result.base_volume += t.value;
|
||||
result.quote_volume += t.amount;
|
||||
}
|
||||
}
|
||||
|
||||
trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );
|
||||
}
|
||||
trades = get_trade_history( base, quote, trades.back().date, fc::time_point_sec(), 1 );
|
||||
result.percent_change = trades.size() > 0 ? ( ( result.latest / trades.back().price ) - 1 ) * 100 : 0;
|
||||
|
||||
//if (assets[0]->id == base_id)
|
||||
{
|
||||
result.lowest_ask = orders.asks[0].price;
|
||||
result.highest_bid = orders.bids[0].price;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -1111,19 +1094,19 @@ market_volume database_api_impl::get_24_volume( const string& base, const string
|
|||
|
||||
for ( market_trade t: trades )
|
||||
{
|
||||
result.base_volume += t.amount;
|
||||
result.quote_volume += t.value;
|
||||
result.base_volume += t.value;
|
||||
result.quote_volume += t.amount;
|
||||
}
|
||||
|
||||
while (trades.size() == 100)
|
||||
{
|
||||
trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );
|
||||
|
||||
for ( market_trade t: trades )
|
||||
{
|
||||
result.base_volume += t.amount;
|
||||
result.quote_volume += t.value;
|
||||
result.base_volume += t.value;
|
||||
result.quote_volume += t.amount;
|
||||
}
|
||||
|
||||
trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -1137,6 +1120,7 @@ order_book database_api::get_order_book( const string& base, const string& quote
|
|||
|
||||
order_book database_api_impl::get_order_book( const string& base, const string& quote, unsigned limit )const
|
||||
{
|
||||
using boost::multiprecision::uint128_t;
|
||||
FC_ASSERT( limit <= 50 );
|
||||
|
||||
order_book result;
|
||||
|
|
@ -1156,21 +1140,28 @@ order_book database_api_impl::get_order_book( const string& base, const string&
|
|||
auto price_to_real = [&]( const price& p )
|
||||
{
|
||||
if( p.base.asset_id == base_id )
|
||||
return asset_to_real( p.quote, assets[1]->precision ) / asset_to_real( p.base, assets[0]->precision );
|
||||
return asset_to_real( p.base, assets[0]->precision ) / asset_to_real( p.quote, assets[1]->precision );
|
||||
else
|
||||
return asset_to_real( p.base, assets[1]->precision ) / asset_to_real( p.quote, assets[0]->precision );
|
||||
return asset_to_real( p.quote, assets[0]->precision ) / asset_to_real( p.base, assets[1]->precision );
|
||||
};
|
||||
|
||||
for( const auto& o : orders ) {
|
||||
for( const auto& o : orders )
|
||||
{
|
||||
if( o.sell_price.base.asset_id == base_id )
|
||||
{
|
||||
result.asks.push_back( std::make_pair( price_to_real(o.sell_price),
|
||||
asset_to_real(o.sell_price.base, assets[0]->precision)) );
|
||||
order ord;
|
||||
ord.price = price_to_real( o.sell_price );
|
||||
ord.quote = asset_to_real( share_type( ( uint128_t( o.for_sale.value ) * o.sell_price.quote.amount.value ) / o.sell_price.base.amount.value ), assets[1]->precision );
|
||||
ord.base = asset_to_real( o.for_sale, assets[0]->precision );
|
||||
result.bids.push_back( ord );
|
||||
}
|
||||
else
|
||||
{
|
||||
result.bids.push_back( std::make_pair( price_to_real(o.sell_price),
|
||||
asset_to_real(o.sell_price.quote, assets[0]->precision ) ) );
|
||||
order ord;
|
||||
ord.price = price_to_real( o.sell_price );
|
||||
ord.quote = asset_to_real( o.for_sale, assets[1]->precision );
|
||||
ord.base = asset_to_real( share_type( ( uint64_t( o.for_sale.value ) * o.sell_price.quote.amount.value ) / o.sell_price.base.amount.value ), assets[0]->precision );
|
||||
result.asks.push_back( ord );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1225,13 +1216,13 @@ vector<market_trade> database_api_impl::get_trade_history( const string& base,
|
|||
|
||||
if( assets[0]->id == itr->op.receives.asset_id )
|
||||
{
|
||||
trade.amount = price_to_real( itr->op.receives.amount, assets[0]->precision );
|
||||
trade.value = price_to_real( itr->op.pays.amount, assets[1]->precision );
|
||||
trade.amount = price_to_real( itr->op.pays.amount, assets[1]->precision );
|
||||
trade.value = price_to_real( itr->op.receives.amount, assets[0]->precision );
|
||||
}
|
||||
else
|
||||
{
|
||||
trade.amount = price_to_real( itr->op.pays.amount, assets[0]->precision );
|
||||
trade.value = price_to_real( itr->op.receives.amount, assets[1]->precision );
|
||||
trade.amount = price_to_real( itr->op.receives.amount, assets[1]->precision );
|
||||
trade.value = price_to_real( itr->op.pays.amount, assets[0]->precision );
|
||||
}
|
||||
|
||||
trade.date = itr->time;
|
||||
|
|
|
|||
|
|
@ -64,12 +64,19 @@ using namespace std;
|
|||
|
||||
class database_api_impl;
|
||||
|
||||
struct order
|
||||
{
|
||||
double price;
|
||||
double quote;
|
||||
double base;
|
||||
};
|
||||
|
||||
struct order_book
|
||||
{
|
||||
string base;
|
||||
string quote;
|
||||
vector< pair<double,double> > bids;
|
||||
vector< pair<double,double> > asks;
|
||||
vector< order > bids;
|
||||
vector< order > asks;
|
||||
};
|
||||
|
||||
struct market_ticker
|
||||
|
|
@ -553,6 +560,8 @@ class database_api
|
|||
};
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT( graphene::app::order, (price)(quote)(base) );
|
||||
FC_REFLECT( graphene::app::order_book, (base)(quote)(bids)(asks) );
|
||||
FC_REFLECT( graphene::app::market_ticker, (base)(quote)(latest)(lowest_ask)(highest_bid)(percent_change)(base_volume)(quote_volume) );
|
||||
FC_REFLECT( graphene::app::market_volume, (base)(quote)(base_volume)(quote_volume) );
|
||||
|
|
|
|||
|
|
@ -850,6 +850,51 @@ class wallet_api
|
|||
bool fill_or_kill = false,
|
||||
bool broadcast = false);
|
||||
|
||||
/** Place a limit order attempting to sell one asset for another.
|
||||
*
|
||||
* This API call abstracts away some of the details of the sell_asset call to be more
|
||||
* user friendly. All orders placed with sell never timeout and will not be killed if they
|
||||
* cannot be filled immediately. If you wish for one of these parameters to be different,
|
||||
* then sell_asset should be used instead.
|
||||
*
|
||||
* @param seller_account the account providing the asset being sold, and which will
|
||||
* receive the processed of the sale.
|
||||
* @param base The name or id of the asset to sell.
|
||||
* @param quote The name or id of the asset to recieve.
|
||||
* @param rate The rate in base:quote at which you want to sell.
|
||||
* @param amount The amount of base you want to sell.
|
||||
* @param broadcast true to broadcast the transaction on the network.
|
||||
* @returns The signed transaction selling the funds.
|
||||
*/
|
||||
signed_transaction sell( string seller_account,
|
||||
string base,
|
||||
string quote,
|
||||
double rate,
|
||||
double amount,
|
||||
bool broadcast );
|
||||
|
||||
/** Place a limit order attempting to buy one asset with another.
|
||||
*
|
||||
* This API call abstracts away some of the details of the sell_asset call to be more
|
||||
* user friendly. All orders placed with buy never timeout and will not be killed if they
|
||||
* cannot be filled immediately. If you wish for one of these parameters to be different,
|
||||
* then sell_asset should be used instead.
|
||||
*
|
||||
* @param buyer_account The account buying the asset for another asset.
|
||||
* @param base The name or id of the asset to buy.
|
||||
* @param quote The name or id of the assest being offered as payment.
|
||||
* @param rate The rate in base:quote at which you want to buy.
|
||||
* @param amount the amount of base you want to buy.
|
||||
* @param broadcast true to broadcast the transaction on the network.
|
||||
* @param The signed transaction selling the funds.
|
||||
*/
|
||||
signed_transaction buy( string buyer_account,
|
||||
string base,
|
||||
string quote,
|
||||
double rate,
|
||||
double amount,
|
||||
bool broadcast );
|
||||
|
||||
/** Borrow an asset or update the debt/collateral ratio for the loan.
|
||||
*
|
||||
* This is the first step in shorting an asset. Call \c sell_asset() to complete the short.
|
||||
|
|
@ -1402,6 +1447,8 @@ class wallet_api
|
|||
bool broadcast /* = false */
|
||||
);
|
||||
|
||||
order_book get_order_book( const string& base, const string& quote, unsigned limit = 50);
|
||||
|
||||
void dbg_make_uia(string creator, string symbol);
|
||||
void dbg_make_mia(string creator, string symbol);
|
||||
void flood_network(string prefix, uint32_t number_of_transactions);
|
||||
|
|
@ -1517,6 +1564,8 @@ FC_API( graphene::wallet::wallet_api,
|
|||
(upgrade_account)
|
||||
(create_account_with_brain_key)
|
||||
(sell_asset)
|
||||
(sell)
|
||||
(buy)
|
||||
(borrow_asset)
|
||||
(cancel_order)
|
||||
(transfer)
|
||||
|
|
@ -1589,4 +1638,5 @@ FC_API( graphene::wallet::wallet_api,
|
|||
(blind_transfer)
|
||||
(blind_history)
|
||||
(receive_blind_transfer)
|
||||
(get_order_book)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2166,6 +2166,89 @@ public:
|
|||
}
|
||||
return ss.str();
|
||||
};
|
||||
m["get_order_book"] = [this](variant result, const fc::variants& a)
|
||||
{
|
||||
auto orders = result.as<order_book>();
|
||||
auto bids = orders.bids;
|
||||
auto asks = orders.asks;
|
||||
std::stringstream ss;
|
||||
std::stringstream sum_stream;
|
||||
sum_stream << "Sum(" << orders.base << ')';
|
||||
double bid_sum = 0;
|
||||
double ask_sum = 0;
|
||||
const int spacing = 20;
|
||||
|
||||
auto prettify_num = [&]( double n )
|
||||
{
|
||||
//ss << n;
|
||||
if (abs( round( n ) - n ) < 0.00000000001 )
|
||||
{
|
||||
ss << setiosflags( !ios::fixed ) << (int) n;
|
||||
}
|
||||
else if (n - floor(n) < 0.000001)
|
||||
{
|
||||
ss << setiosflags( ios::fixed ) << setprecision(10) << n;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << setiosflags( ios::fixed ) << setprecision(6) << n;
|
||||
}
|
||||
};
|
||||
|
||||
ss << setprecision( 8 ) << setiosflags( ios::fixed ) << setiosflags( ios::left );
|
||||
|
||||
ss << ' ' << setw( (spacing * 4) + 6 ) << "BUY ORDERS" << "SELL ORDERS\n"
|
||||
<< ' ' << setw( spacing + 1 ) << "Price" << setw( spacing ) << orders.quote << ' ' << setw( spacing )
|
||||
<< orders.base << ' ' << setw( spacing ) << sum_stream.str()
|
||||
<< " " << setw( spacing + 1 ) << "Price" << setw( spacing ) << orders.quote << ' ' << setw( spacing )
|
||||
<< orders.base << ' ' << setw( spacing ) << sum_stream.str()
|
||||
<< "\n====================================================================================="
|
||||
<< "|=====================================================================================\n";
|
||||
|
||||
for (int i = 0; i < bids.size() || i < asks.size() ; i++)
|
||||
{
|
||||
if ( i < bids.size() )
|
||||
{
|
||||
bid_sum += bids[i].base;
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( bids[i].price );
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( bids[i].quote );
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( bids[i].base );
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( bid_sum );
|
||||
ss << ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << setw( (spacing * 4) + 5 ) << ' ';
|
||||
}
|
||||
|
||||
ss << '|';
|
||||
|
||||
if ( i < asks.size() )
|
||||
{
|
||||
ask_sum += asks[i].base;
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( asks[i].price );
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( asks[i].quote );
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( asks[i].base );
|
||||
ss << ' ' << setw( spacing );
|
||||
prettify_num( ask_sum );
|
||||
}
|
||||
|
||||
ss << '\n';
|
||||
}
|
||||
|
||||
ss << endl
|
||||
<< "Buy Total: " << bid_sum << ' ' << orders.base << endl
|
||||
<< "Sell Total: " << ask_sum << ' ' << orders.base << endl;
|
||||
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
return m;
|
||||
}
|
||||
|
|
@ -3552,6 +3635,28 @@ signed_transaction wallet_api::sell_asset(string seller_account,
|
|||
symbol_to_receive, expiration, fill_or_kill, broadcast);
|
||||
}
|
||||
|
||||
signed_transaction wallet_api::sell( string seller_account,
|
||||
string base,
|
||||
string quote,
|
||||
double rate,
|
||||
double amount,
|
||||
bool broadcast )
|
||||
{
|
||||
return my->sell_asset( seller_account, std::to_string( amount ), base,
|
||||
std::to_string( rate * amount ), quote, 0, false, broadcast );
|
||||
}
|
||||
|
||||
signed_transaction wallet_api::buy( string buyer_account,
|
||||
string base,
|
||||
string quote,
|
||||
double rate,
|
||||
double amount,
|
||||
bool broadcast )
|
||||
{
|
||||
return my->sell_asset( buyer_account, std::to_string( rate * amount ), quote,
|
||||
std::to_string( amount ), base, 0, false, broadcast );
|
||||
}
|
||||
|
||||
signed_transaction wallet_api::borrow_asset(string seller_name, string amount_to_sell,
|
||||
string asset_symbol, string amount_of_collateral, bool broadcast)
|
||||
{
|
||||
|
|
@ -4091,6 +4196,11 @@ vector<blind_receipt> wallet_api::blind_history( string key_or_account )
|
|||
return result;
|
||||
}
|
||||
|
||||
order_book wallet_api::get_order_book( const string& base, const string& quote, unsigned limit )
|
||||
{
|
||||
return( my->_remote_db->get_order_book( base, quote, limit ) );
|
||||
}
|
||||
|
||||
signed_block_with_info::signed_block_with_info( const signed_block& block )
|
||||
: signed_block( block )
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue