Last active
August 29, 2015 13:56
-
-
Save memeyou/9031171 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var Bter = require('bter'); | |
| var moment = require('moment'); | |
| var util = require('../core/util'); | |
| var _ = require('lodash'); | |
| var log = require('../core/log') | |
| var Trader = function(config) { | |
| this.key = config.key; | |
| this.secret = config.secret; | |
| this.pair = [config.asset, config.currency].join('_').toLowerCase(); | |
| this.asset = config.asset; | |
| this.currency = config.currency; | |
| this.name = 'Bter'; | |
| _.bindAll(this); | |
| this.bter = Bter; | |
| } | |
| Trader.prototype.round = function(amount) { | |
| // Prevent "You incorrectly entered one of fields." | |
| // because of more than 8 decimals. | |
| amount *= 100000000; | |
| amount = Math.floor(amount); | |
| amount /= 100000000; | |
| return amount; | |
| } | |
| Trader.prototype.buy = function(amount, price, callback) { | |
| amount = this.round(amount); | |
| var set = function(err, data) { | |
| if(err) | |
| return log.error('unable to buy:', err); | |
| callback(null, data.order_id); | |
| }; | |
| // workaround for nonce error | |
| setTimeout(_.bind(function() { | |
| this.bter.placeOrder({ API_KEY: this.key, SECRET_KEY: this.secret, PAIR: this.pair, TYPE: 'BUY', RATE: price, AMOUNT: amount }, _.bind(set, this)); | |
| }, this), 1000); | |
| } | |
| Trader.prototype.sell = function(amount, price, callback) { | |
| amount = this.round(amount); | |
| var set = function(err, data) { | |
| if(err) | |
| return log.error('unable to sell:\n\n', err); | |
| // returned order id is meaningless :( | |
| callback(null, data.order_id); | |
| }; | |
| // workaround for nonce error | |
| setTimeout(_.bind(function() { | |
| this.bter.placeOrder({ API_KEY: this.key, SECRET_KEY: this.secret, PAIR: this.pair, TYPE: 'SELL', RATE: price, AMOUNT: amount }, _.bind(set, this)); | |
| }, this), 1000); | |
| } | |
| // 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 calculate = function(err, data) { | |
| if(err) { | |
| if(err.message === 'invalid api key') | |
| util.die('Your ' + this.name + ' API keys are invalid'); | |
| return this.retry(this.bter.getFunds({ API_KEY: this.key, SECRET_KEY: this.secret}, _.bind(calculate, this))); | |
| } | |
| var portfolio = []; | |
| _.each(data.available_funds, function(amount, asset) { | |
| portfolio.push({name: asset.toUpperCase(), amount: amount}); | |
| }); | |
| callback(err, portfolio); | |
| } | |
| this.bter.getFunds({ API_KEY: this.key, SECRET_KEY: this.secret}, function(err, data) { | |
| if (err) | |
| throw err; | |
| }); | |
| this.bter.getFunds({ API_KEY: this.key, SECRET_KEY: this.secret}, _.bind(calculate, this)) | |
| } | |
| Trader.prototype.getTicker = function(callback) { | |
| var args = _.toArray(arguments); | |
| // Bter-e doesn't state asks and bids in its | |
| // ticker | |
| var set = function(err, data) { | |
| if (!data) { | |
| return this.retry(this.getTicker, args); | |
| } | |
| var ticker = _.extend(data, { | |
| ask: data.asks[data.asks.length - 1][0], | |
| bid: data.bids[0][0] | |
| }); | |
| callback(err, data); | |
| } | |
| var currs = this.pair.split('_'); | |
| this.bter.getDepth({ CURR_A: currs[0], CURR_B: currs[1] }, _.bind(set, this)); | |
| } | |
| Trader.prototype.getFee = function(callback) { | |
| // Bter doesn't have different fees based on orders | |
| // at this moment it is always 0.2% | |
| callback(false, 0.002); | |
| } | |
| Trader.prototype.checkOrder = function(order, callback) { | |
| var check = function(err, order_id) { | |
| callback(err, !(order_id)); | |
| }; | |
| this.getOrderId(order, _.bind(check, this)); | |
| } | |
| Trader.prototype.cancelOrder = function(order, callback) { | |
| var check = function(err, order_id) { | |
| if(order_id) { | |
| var set = function(err, result) { | |
| if(err || !result) | |
| log.error('unable to cancel order', order, '(', err, result, ')'); | |
| }; | |
| this.bter.cancelOrder({ API_KEY: this.key, SECRET_KEY: this.secret, ORDER_ID: order_id }, _.bind(set, this)); | |
| } | |
| }; | |
| this.getOrderId(order, _.bind(check, this)); | |
| } | |
| Trader.prototype.getOrderId = function(order, callback) { | |
| var order_id; | |
| var args = _.toArray(arguments); | |
| var get = function(err, result) { | |
| if (err || !result) { | |
| return this.retry(this.getOrderId, args); | |
| } else { | |
| for (var i = 0; i < result.orders.length; i++) { | |
| if ((result.orders[i].sell_type == this.asset | |
| && result.orders[i].buy_type == this.currency) | |
| || (result.orders[i].sell_type == this.currency | |
| && result.orders[i].buy_type == this.asset)) | |
| callback(err, result.orders[i].id); | |
| } | |
| } | |
| return false | |
| }; | |
| this.bter.getOrderList({ API_KEY: this.key, SECRET_KEY: this.secret}, _.bind(get, this)); | |
| } | |
| Trader.prototype.getTrades = function(since, callback, descending) { | |
| var args = _.toArray(arguments); | |
| var process = function(err, trades) { | |
| if(err) | |
| return this.retry(this.getTrades, args); | |
| if(!descending) | |
| callback(false, trades.data); | |
| else | |
| callback(false, trades.data.reverse()); | |
| } | |
| var currs = this.pair.split('_'); | |
| this.bter.getHistory({ CURR_A: currs[0], CURR_B: currs[1] }, _.bind(process, this)); | |
| } | |
| module.exports = Trader; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment