diff --git a/exchanges.js b/exchanges.js index 7bdff7431..cac899858 100644 --- a/exchanges.js +++ b/exchanges.js @@ -300,6 +300,22 @@ var exchanges = [ // TODO: should be possible to enable this for Bitfinex? providesHistory: false // fetchTimespan: 60 + }, + { + name: 'LakeBTC', + slug: 'lakebtc', + direct: false, + infinityOrder: false, + currencies: ['USD'], + assets: ['BTC'], + markets: [ + { + pair: ['USD', 'BTC'], minimalOrder: { amount: 1, unit: 'currency' } + } + ], + requires: ['key', 'secret'], + providesHistory: false, + fetchTimespan: 60 } ]; diff --git a/exchanges/lakebtc.js b/exchanges/lakebtc.js new file mode 100755 index 000000000..ac1796dba --- /dev/null +++ b/exchanges/lakebtc.js @@ -0,0 +1,121 @@ +var Lakebtc = require("lakebtc_nodejs"); +var util = require('../core/util.js'); +var _ = require('lodash'); +var moment = require('moment'); +var log = require('../core/log'); + +var Trader = function(config) { + _.bindAll(this); + if(_.isObject(config)) { + this.key = config.key; + this.secret = config.secret; + this.clientID = config.username; + } + this.name = 'LakeBTC'; + this.balance; + this.price; + + this.lakebtc = new Lakebtc(this.key, this.secret); +} + +// if the exchange errors we try the same call again after +// waiting 10 seconds +Trader.prototype.retry = function(method, args) { + var wait = +moment.duration(10, 'seconds'); + log.debug(this.name, 'returned an error, retrying..'); + + var self = this; + + // make sure the callback (and any other fn) + // is bound to Trader + _.each(args, function(arg, i) { + if(_.isFunction(arg)) + args[i] = _.bind(arg, self); + }); + + // run the failed method again with the same + // arguments after wait + setTimeout( + function() { method.apply(self, args) }, + wait + ); +} + +Trader.prototype.getPortfolio = function(callback) { + var set = function(err, data) { + var portfolio = []; + _.map(data.balance, function(amount, asset) { + portfolio.push({name: asset, amount: parseFloat(amount)}); + }); + callback(err, portfolio); + } + this.lakebtc.getAccountInfo(_.bind(set, this)); +} + +Trader.prototype.getTicker = function(callback) { + this.lakebtc.ticker(callback); +} + +Trader.prototype.getFee = function(callback) { + callback(false, 0.002); +} + +Trader.prototype.buy = function(amount, price, callback) { + var set = function(err, result) { + if(err || result.error) + return log.error('unable to buy:', err, result); + + callback(null, result.id); + }; + + // TODO: fees are hardcoded here? + amount *= 0.998; // remove fees + // prevent: Ensure that there are no more than 4 digits in total. + amount *= 10000; + amount = Math.floor(amount); + amount /= 10000; + this.lakebtc.buyOrder(_.bind(set, this), [price, amount, 'USD']); +} + +Trader.prototype.sell = function(amount, price, callback) { + var set = function(err, result) { + if(err || result.error) + return log.error('unable to sell:', err, result); + + callback(null, result.id); + }; + + this.lakebtc.sell(_.bind(set, this), [price, amount, 'USD']); +} + +Trader.prototype.checkOrder = function(order, callback) { + var check = function(err, result) { + var stillThere = _.find(result, function(o) { return o.id === order }); + callback(err, !stillThere); + }; + + this.lakebtc.getOrders(_.bind(check, this)); +} + +Trader.prototype.cancelOrder = function(order, callback) { + var cancel = function(err, result) { + if(err || !result.result) + log.error('unable to cancel order', order, '(', err, result, ')'); + }; + + this.lakebtc.cancelOrder(_.bind(cancel, this), [order]); +} + +Trader.prototype.getTrades = function(since, callback, descending) { + var args = _.toArray(arguments); + var process = function(err, result) { + if(err) + return this.retry(this.getTrades, args); + callback(null, descending ? result.reverse() : result); + }; + since = since ? since.unix() : moment().subtract(5, 'minutes').unix(); + this.lakebtc.bctrades( _.bind(process, this), since); +} + + +module.exports = Trader; diff --git a/package.json b/package.json index 3000495ec..fc5afcf05 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "nedb": "0.9.4", "line-reader": "0.2.x", "semver": "2.2.1", - "kraken-api" :"0.1.x" + "kraken-api": "0.1.x", + "lakebtc_nodejs": "0.1.x" }, "devDependencies": { "nodeunit": "0.8.2"