Merge pull request #29 from chester1000/trader-cleanup

fix(trader): improved consolidation; readability improvements and cleanup
This commit is contained in:
Josh Harvey 2014-08-11 20:08:46 -04:00
commit cc63474357

View file

@ -8,6 +8,32 @@ var SATOSHI_FACTOR = 1e8;
// TODO: Define this somewhere more global // TODO: Define this somewhere more global
var SESSION_TIMEOUT = 60 * 60 * 1000; // an hour var SESSION_TIMEOUT = 60 * 60 * 1000; // an hour
function findExchange(name) {
try {
return require('lamassu-' + name);
} catch(_) {
throw new Error(name + ' module is not installed. Try running `npm install --save lamassu-' + name + '` first');
}
};
function findTicker (name) {
var exchange = findExchange(name);
return exchange.ticker || exchange;
};
function findTrader (name) {
var exchange = findExchange(name);
return exchange.trader || exchange;
};
function findWallet (name) {
var exchange = findExchange(name);
return exchange.wallet || exchange;
};
var Trader = module.exports = function (db) { var Trader = module.exports = function (db) {
if (!db) { if (!db) {
throw new Error('`db` is required'); throw new Error('`db` is required');
@ -20,49 +46,18 @@ var Trader = module.exports = function (db) {
this.rateInfo = null; this.rateInfo = null;
}; };
Trader.prototype._findExchange = function (name) {
try {
return require('lamassu-' + name);
} catch(_) {
throw new Error(name + ' module is not installed. Try running `npm install --save lamassu-' + name + '` first');
}
};
Trader.prototype._findTicker = function (name) {
var exchange = Trader.prototype._findExchange(name);
return exchange.ticker || exchange;
};
Trader.prototype._findTrader = function (name) {
var exchange = Trader.prototype._findExchange(name);
return exchange.trader || exchange;
};
Trader.prototype._findWallet = function (name) {
var exchange = Trader.prototype._findExchange(name);
return exchange.wallet || exchange;
};
Trader.prototype._consolidateTrades = function () { Trader.prototype._consolidateTrades = function () {
var queue = this._tradeQueue; var queue = this._tradeQueue;
var tradeRec = { // NOTE: value in satoshis stays the same no matter the currency
fiat: 0, var consolidatedTrade = {
satoshis: 0, currency: this.config.exchanges.settings.currency,
currency: this.config.exchanges.settings.currency satoshis: queue.reduce(function (prev, current) {
return prev + current.satoshis;
}, 0)
}; };
while (true) { return consolidatedTrade;
var lastRec = queue.shift();
if (!lastRec) {
break;
}
tradeRec.fiat += lastRec.fiat;
tradeRec.satoshis += lastRec.satoshis;
tradeRec.currency = lastRec.currency;
}
return tradeRec;
}; };
Trader.prototype._purchase = function (trade, cb) { Trader.prototype._purchase = function (trade, cb) {
@ -81,20 +76,25 @@ Trader.prototype.configure = function (config) {
throw new Error('`settings.lowBalanceMargin` has to be >= 1'); throw new Error('`settings.lowBalanceMargin` has to be >= 1');
} }
var tickerExchangeCode = config.exchanges.plugins.current.ticker; var plugins = config.exchanges.plugins
var tickerExchangeConfig = config.exchanges.plugins.settings[tickerExchangeCode] || {};
tickerExchangeConfig.currency = config.exchanges.settings.currency;
this.tickerExchange = this._findTicker(tickerExchangeCode).factory(tickerExchangeConfig);
var tradeExchangeCode = config.exchanges.plugins.current.trade; // source of current BTC price (init and configure)
if (tradeExchangeCode) { var tickerName = plugins.current.ticker;
var tradeExchangeConfig = config.exchanges.plugins.settings[tradeExchangeCode]; var tickerConfig = plugins.settings[tickerName] || {};
this.tradeExchange = this._findTrader(tradeExchangeCode).factory(tradeExchangeConfig); tickerConfig.currency = config.exchanges.settings.currency;
this.tickerExchange = findTicker(tickerName).factory(tickerConfig);
// Exchange used for trading (init and configure)
var traderName = plugins.current.trade;
if (traderName) {
var tradeConfig = plugins.settings[traderName];
this.tradeExchange = findTrader(traderName).factory(tradeConfig);
} }
var transferExchangeCode = config.exchanges.plugins.current.transfer; // Wallet (init and configure)
var transferExchangeConfig = config.exchanges.plugins.settings[transferExchangeCode]; var walletName = plugins.current.transfer;
this.transferExchange = this._findWallet(transferExchangeCode).factory(transferExchangeConfig); var walletConfig = plugins.settings[walletName];
this.transferExchange = findWallet(walletName).factory(walletConfig);
this.config = config; this.config = config;
@ -160,9 +160,7 @@ Trader.prototype.sendBitcoins = function (deviceFingerprint, tx, cb) {
var self = this; var self = this;
self.db.summonTransaction(deviceFingerprint, tx, function (err, txRec) { self.db.summonTransaction(deviceFingerprint, tx, function (err, txRec) {
if (err) { if (err) return cb(err);
return cb(err);
}
if (!txRec) { if (!txRec) {
self._clearSession(deviceFingerprint); self._clearSession(deviceFingerprint);
@ -214,7 +212,10 @@ Trader.prototype.trade = function (rec, deviceFingerprint) {
}, SESSION_TIMEOUT) }, SESSION_TIMEOUT)
}; };
} }
this._tradeQueue.push({fiat: rec.fiat, satoshis: rec.satoshis, currency: rec.currency}); this._tradeQueue.push({
satoshis: rec.satoshis,
currency: rec.currency
});
}; };
Trader.prototype.executeTrades = function () { Trader.prototype.executeTrades = function () {
@ -225,19 +226,12 @@ Trader.prototype.executeTrades = function () {
var trade = this._consolidateTrades(); var trade = this._consolidateTrades();
logger.debug('consolidated: ', JSON.stringify(trade)); logger.debug('consolidated: ', JSON.stringify(trade));
if (trade.fiat === 0) { if (trade.satoshis === 0) {
logger.debug('rejecting 0 trade'); logger.debug('rejecting 0 trade');
return; return;
} }
if (trade.fiat < this.config.exchanges.settings.minimumTradeFiat) { logger.debug('making a trade: %d', trade.satoshis / SATOSHI_FACTOR);
// throw it back in the water
logger.debug('reject fiat too small');
this._tradeQueue.unshift(trade);
return;
}
logger.debug('making a trade: %d', trade.satoshis / Math.pow(10, 8));
this._purchase(trade, function (err) { this._purchase(trade, function (err) {
if (err) logger.error(err); if (err) logger.error(err);
}); });
@ -276,16 +270,14 @@ Trader.prototype.stopPolling = function () {
Trader.prototype._tradeForexMultiplier = function _tradeForexMultiplier() { Trader.prototype._tradeForexMultiplier = function _tradeForexMultiplier() {
var deviceCurrency = this.config.exchanges.settings.currency; var deviceCurrency = this.config.exchanges.settings.currency;
var tradeCurrency = this.tradeExchange.currency(); var tradeCurrency = this.tradeExchange.currency();
if (deviceCurrency === tradeCurrency)
return 1;
var deviceRate = this._deviceRate(); var deviceRate = this._deviceRate();
var tradeRate = this._tradeRate(); var tradeRate = this._tradeRate();
return deviceRate && tradeRate ?
var forexMultiplier = deviceRate && tradeRate ?
deviceRate / tradeRate : deviceRate / tradeRate :
null; null;
return deviceCurrency === tradeCurrency ?
1 :
forexMultiplier;
}; };
Trader.prototype._tradeBalanceFunc = function _tradeBalanceFunc(callback) { Trader.prototype._tradeBalanceFunc = function _tradeBalanceFunc(callback) {