Add makerExchangeRate (quality) to orders, and maker to account orders

This commit is contained in:
Chris Clark
2015-07-07 14:39:28 -07:00
parent 73020fb8ae
commit 1309b58592
9 changed files with 132 additions and 52 deletions

View File

@@ -12,7 +12,7 @@ const getTrustlines = require('./ledger/trustlines');
const getBalances = require('./ledger/balances'); const getBalances = require('./ledger/balances');
const getPathFind = require('./ledger/pathfind'); const getPathFind = require('./ledger/pathfind');
const getOrders = require('./ledger/orders'); const getOrders = require('./ledger/orders');
const getOrderBook = require('./ledger/orderbook'); const getOrderbook = require('./ledger/orderbook');
const getSettings = require('./ledger/settings'); const getSettings = require('./ledger/settings');
const preparePayment = require('./transaction/payment'); const preparePayment = require('./transaction/payment');
const prepareTrustline = require('./transaction/trustline'); const prepareTrustline = require('./transaction/trustline');
@@ -41,7 +41,7 @@ RippleAPI.prototype = {
getBalances, getBalances,
getPathFind, getPathFind,
getOrders, getOrders,
getOrderBook, getOrderbook,
getSettings, getSettings,
preparePayment, preparePayment,

View File

@@ -49,7 +49,7 @@ function formatBidsAndAsks(orderbook, offers) {
return {bids, asks, flipped}; return {bids, asks, flipped};
} }
function getOrderBook(account, orderbook, options, callback) { function getOrderbook(account, orderbook, options, callback) {
validate.address(account); validate.address(account);
validate.orderbook(orderbook); validate.orderbook(orderbook);
validate.options(options); validate.options(options);
@@ -63,4 +63,4 @@ function getOrderBook(account, orderbook, options, callback) {
callback)); callback));
} }
module.exports = utils.wrapCatch(getOrderBook); module.exports = utils.wrapCatch(getOrderbook);

View File

@@ -15,7 +15,7 @@ function requestAccountOffers(remote, address, ledgerVersion, options,
}, },
composeAsync((data) => ({ composeAsync((data) => ({
marker: data.marker, marker: data.marker,
results: data.offers.map(parseAccountOrder) results: data.offers.map(_.partial(parseAccountOrder, address))
}), callback)); }), callback));
} }

View File

@@ -2,25 +2,38 @@
const utils = require('./utils'); const utils = require('./utils');
const flags = utils.core.Remote.flags.offer; const flags = utils.core.Remote.flags.offer;
const parseAmount = require('./amount'); const parseAmount = require('./amount');
const BigNumber = require('bignumber.js');
// TODO: remove this function once rippled provides quality directly
function computeQuality(takerGets, takerPays) {
const quotient = new BigNumber(takerPays.value).dividedBy(takerGets.value);
return quotient.toDigits(16, BigNumber.ROUND_HALF_UP).toString();
}
// rippled 'account_offers' returns a different format for orders than 'tx' // rippled 'account_offers' returns a different format for orders than 'tx'
// the flags are also different // the flags are also different
function parseAccountOrder(order: Object): Object { function parseAccountOrder(address: string, order: Object): Object {
const direction = (order.flags & flags.Sell) === 0 ? 'buy' : 'sell'; const direction = (order.flags & flags.Sell) === 0 ? 'buy' : 'sell';
const takerGetsAmount = parseAmount(order.taker_gets); const takerGetsAmount = parseAmount(order.taker_gets);
const takerPaysAmount = parseAmount(order.taker_pays); const takerPaysAmount = parseAmount(order.taker_pays);
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount; const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount;
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount; const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount;
// note: immediateOrCancel and fillOrKill orders cannot enter the order book
// so we can omit those flags here
const specification = utils.removeUndefined({ const specification = utils.removeUndefined({
direction: direction, direction: direction,
quantity: quantity, quantity: quantity,
totalPrice: totalPrice, totalPrice: totalPrice,
passive: ((order.flags & flags.Passive) !== 0) || undefined passive: ((order.flags & flags.Passive) !== 0) || undefined
}); });
const properties = { const properties = {
sequence: order.seq maker: address,
sequence: order.seq,
makerExchangeRate: computeQuality(takerGetsAmount, takerPaysAmount)
}; };
return {specification, properties}; return {specification, properties};
} }

View File

@@ -11,19 +11,22 @@ function parseOrderbookOrder(order: Object): Object {
const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount; const quantity = (direction === 'buy') ? takerPaysAmount : takerGetsAmount;
const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount; const totalPrice = (direction === 'buy') ? takerGetsAmount : takerPaysAmount;
// note: immediateOrCancel and fillOrKill orders cannot enter the order book
// so we can omit those flags here
const specification = utils.removeUndefined({ const specification = utils.removeUndefined({
direction: direction, direction: direction,
quantity: quantity, quantity: quantity,
totalPrice: totalPrice, totalPrice: totalPrice,
passive: ((order.Flags & flags.Passive) !== 0) || undefined passive: ((order.Flags & flags.Passive) !== 0) || undefined
}); });
// "quality" is omitted intentionally as it corresponds to
// either price or inverse price, and it is better to avoid
// inverting floats where precision issues can arise
const properties = { const properties = {
maker: order.Account, maker: order.Account,
sequence: order.Sequence sequence: order.Sequence,
makerExchangeRate: utils.adjustQualityForXRP(order.quality,
takerGetsAmount.currency, takerPaysAmount.currency)
}; };
const takerGetsFunded = order.taker_gets_funded ? const takerGetsFunded = order.taker_gets_funded ?
parseAmount(order.taker_gets_funded) : undefined; parseAmount(order.taker_gets_funded) : undefined;
const takerPaysFunded = order.taker_pays_funded ? const takerPaysFunded = order.taker_pays_funded ?

View File

@@ -4,6 +4,15 @@ const _ = require('lodash');
const transactionParser = require('ripple-lib-transactionparser'); const transactionParser = require('ripple-lib-transactionparser');
const toTimestamp = require('../../../core/utils').toTimestamp; const toTimestamp = require('../../../core/utils').toTimestamp;
const utils = require('../utils'); const utils = require('../utils');
const BigNumber = require('bignumber.js');
function adjustQualityForXRP(quality: string, takerGetsCurrency: string,
takerPaysCurrency: string) {
const shift = (takerGetsCurrency === 'XRP' ? 6 : 0)
- (takerPaysCurrency === 'XRP' ? 6 : 0);
return shift === 0 ? quality :
(new BigNumber(quality)).shift(shift).toString();
}
function parseTimestamp(tx: {date: string}): string | void { function parseTimestamp(tx: {date: string}): string | void {
return tx.date ? (new Date(toTimestamp(tx.date))).toISOString() : undefined; return tx.date ? (new Date(toTimestamp(tx.date))).toISOString() : undefined;
@@ -58,6 +67,7 @@ function parseOutcome(tx: Object): ?Object {
module.exports = { module.exports = {
parseOutcome, parseOutcome,
removeUndefined, removeUndefined,
adjustQualityForXRP,
dropsToXrp: utils.common.dropsToXrp, dropsToXrp: utils.common.dropsToXrp,
constants: utils.common.constants, constants: utils.common.constants,
core: utils.common.core core: utils.common.core

View File

@@ -28,7 +28,7 @@ const trustlinesResponse = require('./fixtures/trustlines-response');
const walletResponse = require('./fixtures/wallet.json'); const walletResponse = require('./fixtures/wallet.json');
const getSettingsResponse = require('./fixtures/get-settings-response'); const getSettingsResponse = require('./fixtures/get-settings-response');
const getOrdersResponse = require('./fixtures/get-orders-response'); const getOrdersResponse = require('./fixtures/get-orders-response');
const getOrderBookResponse = require('./fixtures/get-orderbook-response'); const getOrderbookResponse = require('./fixtures/get-orderbook-response');
const getServerInfoResponse = require('./fixtures/get-server-info-response'); const getServerInfoResponse = require('./fixtures/get-server-info-response');
const getPathFindResponse = require('./fixtures/get-pathfind-response'); const getPathFindResponse = require('./fixtures/get-pathfind-response');
const address = addresses.ACCOUNT; const address = addresses.ACCOUNT;
@@ -142,7 +142,7 @@ describe('RippleAPI', function() {
_.partial(checkResult, getOrdersResponse, done)); _.partial(checkResult, getOrdersResponse, done));
}); });
it('getOrderBook', function(done) { it('getOrderbook', function(done) {
const orderbook = { const orderbook = {
base: { base: {
currency: 'USD', currency: 'USD',
@@ -153,8 +153,8 @@ describe('RippleAPI', function() {
counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' counterparty: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'
} }
}; };
this.api.getOrderBook(address, orderbook, {}, this.api.getOrderbook(address, orderbook, {},
_.partial(checkResult, getOrderBookResponse, done)); _.partial(checkResult, getOrderbookResponse, done));
}); });
it('getServerInfo', function(done) { it('getServerInfo', function(done) {

View File

@@ -16,7 +16,8 @@
}, },
"properties": { "properties": {
"maker": "r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ", "maker": "r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ",
"sequence": 434 "sequence": 434,
"makerExchangeRate": "0.003120027456241615"
} }
}, },
{ {
@@ -35,7 +36,8 @@
}, },
"properties": { "properties": {
"maker": "rDYCRhpahKEhCFV25xScg67Bwf4W9sTYAm", "maker": "rDYCRhpahKEhCFV25xScg67Bwf4W9sTYAm",
"sequence": 233 "sequence": 233,
"makerExchangeRate": "0.003125"
} }
}, },
{ {
@@ -54,7 +56,8 @@
}, },
"properties": { "properties": {
"maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk", "maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk",
"sequence": 110104 "sequence": 110104,
"makerExchangeRate": "0.003144542101755081"
}, },
"state": { "state": {
"availableQuantity": { "availableQuantity": {
@@ -85,7 +88,8 @@
}, },
"properties": { "properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE", "maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
"sequence": 35625 "sequence": 35625,
"makerExchangeRate": "0.003145529403882357"
}, },
"state": { "state": {
"availableQuantity": { "availableQuantity": {
@@ -116,7 +120,8 @@
}, },
"properties": { "properties": {
"maker": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J", "maker": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J",
"sequence": 387756 "sequence": 387756,
"makerExchangeRate": "0.003155743848271834"
} }
}, },
{ {
@@ -135,7 +140,8 @@
}, },
"properties": { "properties": {
"maker": "rwjsRktX1eguUr1pHTffyHnC4uyrvX58V1", "maker": "rwjsRktX1eguUr1pHTffyHnC4uyrvX58V1",
"sequence": 208927 "sequence": 208927,
"makerExchangeRate": "0.003160328237957649"
} }
}, },
{ {
@@ -154,7 +160,8 @@
}, },
"properties": { "properties": {
"maker": "r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ", "maker": "r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ",
"sequence": 429 "sequence": 429,
"makerExchangeRate": "0.003174603174603175"
} }
}, },
{ {
@@ -173,7 +180,8 @@
}, },
"properties": { "properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE", "maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
"sequence": 35627 "sequence": 35627,
"makerExchangeRate": "0.003222279177208227"
}, },
"state": { "state": {
"availableQuantity": { "availableQuantity": {
@@ -204,7 +212,8 @@
}, },
"properties": { "properties": {
"maker": "r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ", "maker": "r49y2xKuKVG2dPkNHgWQAV61cjxk8gryjQ",
"sequence": 431 "sequence": 431,
"makerExchangeRate": "0.003222687721559781"
} }
} }
], ],
@@ -225,7 +234,8 @@
}, },
"properties": { "properties": {
"maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk", "maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk",
"sequence": 110103 "sequence": 110103,
"makerExchangeRate": "331.1338298016111"
} }
}, },
{ {
@@ -244,7 +254,8 @@
}, },
"properties": { "properties": {
"maker": "rPyYxUGK8L4dgEvjPs3aRc1B1jEiLr3Hx5", "maker": "rPyYxUGK8L4dgEvjPs3aRc1B1jEiLr3Hx5",
"sequence": 392 "sequence": 392,
"makerExchangeRate": "332"
}, },
"state": { "state": {
"availableQuantity": { "availableQuantity": {
@@ -275,7 +286,8 @@
}, },
"properties": { "properties": {
"maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk", "maker": "raudnGKfTK23YKfnS7ixejHrqGERTYNFXk",
"sequence": 110105 "sequence": 110105,
"makerExchangeRate": "337.7996295968016"
} }
}, },
{ {
@@ -294,7 +306,8 @@
}, },
"properties": { "properties": {
"maker": "rDbsCJr5m8gHDCNEHCZtFxcXHsD4S9jH83", "maker": "rDbsCJr5m8gHDCNEHCZtFxcXHsD4S9jH83",
"sequence": 110061 "sequence": 110061,
"makerExchangeRate": "347.2306949944844"
} }
}, },
{ {
@@ -313,7 +326,8 @@
}, },
"properties": { "properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE", "maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
"sequence": 35788 "sequence": 35788,
"makerExchangeRate": "352.7092203179974"
} }
}, },
{ {
@@ -332,7 +346,8 @@
}, },
"properties": { "properties": {
"maker": "rN6jbxx4H6NxcnmkzBxQnbCWLECNKrgSSf", "maker": "rN6jbxx4H6NxcnmkzBxQnbCWLECNKrgSSf",
"sequence": 491 "sequence": 491,
"makerExchangeRate": "358.96"
}, },
"state": { "state": {
"availableQuantity": { "availableQuantity": {
@@ -363,7 +378,8 @@
}, },
"properties": { "properties": {
"maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE", "maker": "rDVBvAQScXrGRGnzrxRrcJPeNLeLeUTAqE",
"sequence": 35789 "sequence": 35789,
"makerExchangeRate": "360.9637829743709"
} }
} }
], ],
@@ -385,7 +401,8 @@
}, },
"properties": { "properties": {
"maker": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J", "maker": "rwBYyfufTzk77zUSKEu4MvixfarC35av1J",
"sequence": 386940 "sequence": 386940,
"makerExchangeRate": "326.5003614141928"
} }
}, },
{ {
@@ -404,7 +421,8 @@
}, },
"properties": { "properties": {
"maker": "rwjsRktX1eguUr1pHTffyHnC4uyrvX58V1", "maker": "rwjsRktX1eguUr1pHTffyHnC4uyrvX58V1",
"sequence": 207855 "sequence": 207855,
"makerExchangeRate": "330.6364334177034"
} }
}, },
{ {
@@ -423,7 +441,8 @@
}, },
"properties": { "properties": {
"maker": "rUeCeioKJkbYhv4mRGuAbZpPcqkMCoYq6N", "maker": "rUeCeioKJkbYhv4mRGuAbZpPcqkMCoYq6N",
"sequence": 5255 "sequence": 5255,
"makerExchangeRate": "365.9629780181032"
}, },
"state": { "state": {
"availableQuantity": { "availableQuantity": {
@@ -456,7 +475,8 @@
}, },
"properties": { "properties": {
"maker": "rDbsCJr5m8gHDCNEHCZtFxcXHsD4S9jH83", "maker": "rDbsCJr5m8gHDCNEHCZtFxcXHsD4S9jH83",
"sequence": 110099 "sequence": 110099,
"makerExchangeRate": "0.003193013959408667"
} }
} }
] ]

View File

@@ -14,7 +14,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 719930 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 719930,
"makerExchangeRate": "63.44025128030504"
} }
}, },
{ {
@@ -32,7 +34,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 756999 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 756999,
"makerExchangeRate": "39.23215583132338"
} }
}, },
{ {
@@ -50,7 +54,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 757002 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 757002,
"makerExchangeRate": "1.056334989703257"
} }
}, },
{ {
@@ -68,7 +74,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 757003 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 757003,
"makerExchangeRate": "100.3518240218094"
} }
}, },
{ {
@@ -86,7 +94,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 782148 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 782148,
"makerExchangeRate": "81.7121820757743"
} }
}, },
{ {
@@ -104,7 +114,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 787368 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 787368,
"makerExchangeRate": "50.26296114247091"
} }
}, },
{ {
@@ -122,7 +134,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 787408 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 787408,
"makerExchangeRate": "1000.519693952099"
} }
}, },
{ {
@@ -140,7 +154,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 803438 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 803438,
"makerExchangeRate": "1356.054621894598"
} }
}, },
{ {
@@ -158,7 +174,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 807858 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 807858,
"makerExchangeRate": "123763.8630020459"
} }
}, },
{ {
@@ -176,7 +194,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 807896 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 807896,
"makerExchangeRate": "123646.6837435794"
} }
}, },
{ {
@@ -193,7 +213,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 814018 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 814018,
"makerExchangeRate": "16922.62953364839"
} }
}, },
{ {
@@ -211,7 +233,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 827522 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 827522,
"makerExchangeRate": "62.63032241192674"
} }
}, },
{ {
@@ -229,7 +253,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 833591 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 833591,
"makerExchangeRate": "160.8325363767064"
} }
}, },
{ {
@@ -247,7 +273,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 833592 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 833592,
"makerExchangeRate": "1608.325363767062"
} }
}, },
{ {
@@ -265,7 +293,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 838954 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 838954,
"makerExchangeRate": "162.9564891233845"
} }
}, },
{ {
@@ -282,7 +312,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 843730 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 843730,
"makerExchangeRate": "0.0004485854972648762"
} }
}, },
{ {
@@ -300,7 +332,9 @@
} }
}, },
"properties": { "properties": {
"sequence": 844068 "maker": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"sequence": 844068,
"makerExchangeRate": "42.19320561670911"
} }
} }
] ]