From a45a69883ad0c843eda45827780a3720006f35fa Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Mon, 17 Sep 2018 15:24:50 +0800 Subject: [PATCH 01/19] [GB] make scientificToDecimal a global helper --- exchange/exchangeUtils.js | 30 +++++++++++++++++++++++++++++- exchange/wrappers/binance.js | 34 +++++----------------------------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/exchange/exchangeUtils.js b/exchange/exchangeUtils.js index 51c48ee37..f6532e9ff 100644 --- a/exchange/exchangeUtils.js +++ b/exchange/exchangeUtils.js @@ -89,8 +89,36 @@ const isValidOrder = ({api, market, amount, price}) => { } } + +// https://gist.github.com/jiggzson/b5f489af9ad931e3d186 +const scientificToDecimal = num => { + if(/\d+\.?\d*e[\+\-]*\d+/i.test(num)) { + const zero = '0'; + const parts = String(num).toLowerCase().split('e'); // split into coeff and exponent + const e = parts.pop(); // store the exponential part + const l = Math.abs(e); // get the number of zeros + const sign = e/l; + const coeff_array = parts[0].split('.'); + if(sign === -1) { + num = zero + '.' + new Array(l).join(zero) + coeff_array.join(''); + } else { + const dec = coeff_array[1]; + if(dec) { + l = l - dec.length; + } + num = coeff_array.join('') + new Array(l+1).join(zero); + } + } else { + // make sure we always cast to string + num = num + ''; + } + + return num; +} + module.exports = { retry: retryInstance, bindAll, - isValidOrder + isValidOrder, + scientificToDecimal } \ No newline at end of file diff --git a/exchange/wrappers/binance.js b/exchange/wrappers/binance.js index 9b3608008..5fc20f931 100644 --- a/exchange/wrappers/binance.js +++ b/exchange/wrappers/binance.js @@ -3,7 +3,9 @@ const _ = require('lodash'); const Errors = require('../exchangeErrors'); const marketData = require('./binance-markets.json'); -const retry = require('../exchangeUtils').retry; +const exchangeUtils = require('../exchangeUtils'); +const retry = exchangeUtils.retry; +const scientificToDecimal = exchangeUtils.scientificToDecimal; const Binance = require('binance'); @@ -264,37 +266,11 @@ Trader.prototype.round = function(amount, tickSize) { amount /= precision; // https://gist.github.com/jiggzson/b5f489af9ad931e3d186 - amount = this.scientificToDecimal(amount); + amount = scientificToDecimal(amount); return amount; }; -// https://gist.github.com/jiggzson/b5f489af9ad931e3d186 -Trader.prototype.scientificToDecimal = function(num) { - if(/\d+\.?\d*e[\+\-]*\d+/i.test(num)) { - const zero = '0'; - const parts = String(num).toLowerCase().split('e'); // split into coeff and exponent - const e = parts.pop(); // store the exponential part - const l = Math.abs(e); // get the number of zeros - const sign = e/l; - const coeff_array = parts[0].split('.'); - if(sign === -1) { - num = zero + '.' + new Array(l).join(zero) + coeff_array.join(''); - } else { - const dec = coeff_array[1]; - if(dec) { - l = l - dec.length; - } - num = coeff_array.join('') + new Array(l+1).join(zero); - } - } else { - // make sure we always cast to string - num = num + ''; - } - - return num; -} - Trader.prototype.roundAmount = function(amount) { return this.round(amount, this.market.minimalOrder.amount); } @@ -405,7 +381,7 @@ Trader.prototype.getOrder = function(order, callback) { const reqData = { symbol: this.pair, // if this order was not part of the last 500 trades we won't find it.. - limit: 500, + limit: 1000, }; const handler = cb => this.binance.myTrades(reqData, this.handleResponse('getOrder', cb)); From 9ed920d5b8fd4e2bbbbc94625ac24e9befd42314 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Mon, 17 Sep 2018 15:27:56 +0800 Subject: [PATCH 02/19] [GB] force decimal notation for kraken price rounding, see #2537 --- exchange/wrappers/kraken.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/exchange/wrappers/kraken.js b/exchange/wrappers/kraken.js index 7358902a0..1e84d71f8 100644 --- a/exchange/wrappers/kraken.js +++ b/exchange/wrappers/kraken.js @@ -1,7 +1,9 @@ const Kraken = require('kraken-api'); const moment = require('moment'); const _ = require('lodash'); -const retry = require('../exchangeUtils').retry; +const exchangeUtils = require('../exchangeUtils'); +const retry = exchangeUtils.retry; +const scientificToDecimal = exchangeUtils.scientificToDecimal; const marketData = require('./kraken-markets.json'); @@ -273,7 +275,7 @@ Trader.prototype.roundAmount = function(amount) { }; Trader.prototype.roundPrice = function(amount) { - return _.round(amount, this.market.pricePrecision); + return scientificToDecimal(_.round(amount, this.market.pricePrecision)); }; Trader.prototype.addOrder = function(tradeType, amount, price, callback) { From 28c466d85846846e89a022518ee728ff7021bdc4 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Tue, 18 Sep 2018 00:55:20 +0800 Subject: [PATCH 03/19] [GB] make sure roundPrice is used --- exchange/wrappers/kraken.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchange/wrappers/kraken.js b/exchange/wrappers/kraken.js index 1e84d71f8..64e488b43 100644 --- a/exchange/wrappers/kraken.js +++ b/exchange/wrappers/kraken.js @@ -279,7 +279,7 @@ Trader.prototype.roundPrice = function(amount) { }; Trader.prototype.addOrder = function(tradeType, amount, price, callback) { - price = this.roundAmount(price); // only round price, not amount + price = this.roundPrice(price); // only round price, not amount const handle = (err, data) => { if(err) { From 2271428aae6f568b8ce13f40dda38cc11172c833 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Tue, 18 Sep 2018 14:29:18 +0800 Subject: [PATCH 04/19] [GB] improve no trades edge case on binance --- exchange/wrappers/binance.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exchange/wrappers/binance.js b/exchange/wrappers/binance.js index 5fc20f931..19ecdac50 100644 --- a/exchange/wrappers/binance.js +++ b/exchange/wrappers/binance.js @@ -333,12 +333,17 @@ Trader.prototype.getOrder = function(order, callback) { const fees = {}; + if(!data.length) { + return callback(new Error('Binance did not return any trades')); + } + const trades = _.filter(data, t => { // note: the API returns a string after creating return t.orderId == order; }); if(!trades.length) { + console.log('cannot find trades!', { order, list: data.map(t => t.orderId) }); return callback(new Error('Trades not found')); } From 22fca6928a85ca407438338dbfb83ec94dff5bc1 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Thu, 20 Sep 2018 14:21:55 +0800 Subject: [PATCH 05/19] [GB] add more debug information on binance trade match fail, see #2518 --- exchange/wrappers/binance.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/exchange/wrappers/binance.js b/exchange/wrappers/binance.js index 19ecdac50..a89176a2e 100644 --- a/exchange/wrappers/binance.js +++ b/exchange/wrappers/binance.js @@ -343,8 +343,20 @@ Trader.prototype.getOrder = function(order, callback) { }); if(!trades.length) { - console.log('cannot find trades!', { order, list: data.map(t => t.orderId) }); - return callback(new Error('Trades not found')); + console.log('cannot find trades!', { order, list: data.map(t => t.orderId).reverse() }); + + const reqData = { + symbol: this.pair, + orderId: order, + }; + + this.binance.queryOrder(reqData, (err, resp) => { + console.log('couldnt find any trade for order, here is order:', {err, resp}); + + callback(new Error('Trades not found')); + }); + + return; } _.each(trades, trade => { From d676a6ed22728bc9b55db0a27cfe904456adcde2 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Sat, 22 Sep 2018 12:59:41 +0800 Subject: [PATCH 06/19] [GB] retry on non existing check order, see #2518 --- exchange/wrappers/binance.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/exchange/wrappers/binance.js b/exchange/wrappers/binance.js index a89176a2e..fa584b8b6 100644 --- a/exchange/wrappers/binance.js +++ b/exchange/wrappers/binance.js @@ -117,9 +117,8 @@ Trader.prototype.handleResponse = function(funcName, callback) { } if(funcName === 'checkOrder' && error.message.includes('Order does not exist.')) { - // order got filled in full before it could be - // cancelled, meaning it was NOT cancelled. - return callback(false, {filled: true}); + console.log(new Date, 'Binance doesnt know this order, retrying up to 10 times..'); + error.retry = 10; } if(funcName === 'addOrder' && error.message.includes('Account has insufficient balance')) { @@ -284,7 +283,6 @@ Trader.prototype.isValidPrice = function(price) { } Trader.prototype.isValidLot = function(price, amount) { - console.log('isValidLot', this.market.minimalOrder.order, amount * price >= this.market.minimalOrder.order) return amount * price >= this.market.minimalOrder.order; } @@ -464,8 +462,6 @@ Trader.prototype.cancelOrder = function(order, callback) { this.oldOrder = order; if(err) { - if(err.message.contains('')) - return callback(err); } From b60f2fdb29fa5771cf11cd4488dbea6503ff4c04 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Mon, 24 Sep 2018 03:58:17 +0800 Subject: [PATCH 07/19] [GB] update XLM minimum amount to 30, fix #2558 --- exchange/util/genMarketFiles/update-kraken.js | 2 +- exchange/wrappers/kraken-markets.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exchange/util/genMarketFiles/update-kraken.js b/exchange/util/genMarketFiles/update-kraken.js index 9bf11e658..8c4ae3277 100644 --- a/exchange/util/genMarketFiles/update-kraken.js +++ b/exchange/util/genMarketFiles/update-kraken.js @@ -52,7 +52,7 @@ let getMinTradeSize = asset => { minTradeSize = '30' break; case 'XXLM': - minTradeSize = '300' + minTradeSize = '30' break; case 'XZEC': minTradeSize = '0.03' diff --git a/exchange/wrappers/kraken-markets.json b/exchange/wrappers/kraken-markets.json index ea43f4b22..d2cd27e90 100644 --- a/exchange/wrappers/kraken-markets.json +++ b/exchange/wrappers/kraken-markets.json @@ -753,7 +753,7 @@ ], "book": "XXLMXXBT", "minimalOrder": { - "amount": "300", + "amount": "30", "unit": "asset" }, "pricePrecision": 8, @@ -770,7 +770,7 @@ ], "book": "XXLMZEUR", "minimalOrder": { - "amount": "300", + "amount": "30", "unit": "asset" }, "pricePrecision": 6, @@ -787,7 +787,7 @@ ], "book": "XXLMZUSD", "minimalOrder": { - "amount": "300", + "amount": "30", "unit": "asset" }, "pricePrecision": 6, From 8b3e696ed96cfbc97335d117f27886c77c0d19ea Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Mon, 24 Sep 2018 04:19:00 +0800 Subject: [PATCH 08/19] [GB] catch Kraken zero trailing price, fix #2560 --- exchange/wrappers/kraken.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchange/wrappers/kraken.js b/exchange/wrappers/kraken.js index 64e488b43..2c04b8b67 100644 --- a/exchange/wrappers/kraken.js +++ b/exchange/wrappers/kraken.js @@ -113,7 +113,7 @@ Trader.prototype.handleResponse = function(funcName, callback, nonMutating, payl } // string vs float - if(o.descr.price != price) { + if(+o.descr.price != price) { return false; } From 876b28602557c297bf1963b21fbffdd5a7463b6e Mon Sep 17 00:00:00 2001 From: Rowan Griffin Date: Wed, 19 Sep 2018 15:54:39 +0100 Subject: [PATCH 09/19] Add functionality to pushbullet plugin. Now gives trade information. --- plugins/pushbullet.js | 206 +++++++++++++++++++++++++++++++----------- sample-config.js | 22 +++-- 2 files changed, 166 insertions(+), 62 deletions(-) diff --git a/plugins/pushbullet.js b/plugins/pushbullet.js index aa3b961ab..2f09dadac 100644 --- a/plugins/pushbullet.js +++ b/plugins/pushbullet.js @@ -1,88 +1,188 @@ /** * Created by rocketman1337345 on 8/14/16. + * Extended by RJPGriffin (Gryphon) on 30/5/18 */ + +/** +Required Config: + +config.pushbullet = { + // sends pushbullets if true + enabled: true, + // Send 'Gekko starting' message if true + sendMessageOnStart: true, + // Send Message for advice? + sendOnAdvice: true, + // Send Message on Trade Completion? + sendOnTrade: true, + // disable advice printout if it's soft + muteSoft: true, + // your pushbullet API key + key: '', + // your email + email: 'jon_snow@westeros.com', + // Messages will start with this tag + tag: '[GEKKO]' +}; + + + **/ + var pushbullet = require("pushbullet"); var _ = require('lodash'); +const moment = require('moment'); var log = require('../core/log.js'); var util = require('../core/util.js'); var config = util.getConfig(); var pushbulletConfig = config.pushbullet; var Pushbullet = function(done) { - _.bindAll(this); + _.bindAll(this); - this.pusher; - this.price = 'N/A'; + this.pusher; + this.price = 'N/A'; - this.done = done; - this.setup(); + this.advicePrice = 0; + this.adviceTime = moment(); + + this.done = done; + this.setup(); }; -Pushbullet.prototype.setup = function(done){ - - var setupPushBullet = function (err, result) { - if(pushbulletConfig.sendMessageOnStart){ - var title = pushbulletConfig.tag; - var exchange = config.watch.exchange; - var currency = config.watch.currency; - var asset = config.watch.asset; - var body = "Gekko has started, Ive started watching " - +exchange - +" " - +currency - +" " - +asset - +" I'll let you know when I got some advice"; - this.mail(title, body); - }else{ - log.debug('Skipping Send message on startup') - } - }; - setupPushBullet.call(this) +Pushbullet.prototype.setup = function(done) { + + var setupPushBullet = function(err, result) { + if (pushbulletConfig.sendMessageOnStart) { + var title = pushbulletConfig.tag; + var exchange = config.watch.exchange; + var currency = config.watch.currency; + var asset = config.watch.asset; + var body = "Gekko has started watching " + + currency + + "/" + + asset + + " on " + + exchange + + "."; + + if(config.trader.enabled){ + body += "\nLive Trading is enabled" + } + if(config.paperTrader.enabled){ + body += "\nPaper Trading is enabled" + } + this.mail(title, body); + } else { + log.debug('Skipping Send message on startup') + } + }; + setupPushBullet.call(this) }; Pushbullet.prototype.processCandle = function(candle, done) { - this.price = candle.close; + this.price = candle.close; - done(); + done(); }; + Pushbullet.prototype.processAdvice = function(advice) { - if (advice.recommendation == "soft" && pushbulletConfig.muteSoft) return; - - var text = [ - 'Gekko is watching ', - config.watch.exchange, - ' and has detected a new trend, advice is to go ', - advice.recommendation, - '.\n\nThe current ', - config.watch.asset, - ' price is ', - this.price + if (advice.recommendation == "soft" && pushbulletConfig.muteSoft) return; + + this.advicePrice = this.price; + this.adviceTime = moment(); + + if (pushbulletConfig.sendOnAdvice) { + + var text = [ + 'Gekko has new advice for ', + config.watch.exchange, + ', advice is to go ', + advice.recommendation, + '.\n\nThe current ', + config.watch.asset, + ' price is ', + this.advicePrice ].join(''); - var subject = pushbulletConfig.tag+' New advice: go ' + advice.recommendation; + var subject = pushbulletConfig.tag + ' New advice: go ' + advice.recommendation; + + this.mail(subject, text); + } +}; + +Pushbullet.prototype.processTradeCompleted = function(trade) { + if (pushbulletConfig.sendOnTrade) { + var slip; + //Slip direction is opposite for buy and sell + if (trade.price === this.advicePrice) { + slip = 0; + } else if (trade.action === 'buy') { + slip = 100 * ((trade.price - this.advicePrice) / this.advicePrice); + } else if (trade.action === 'sell') { + slip = 100 * ((this.advicePrice - trade.price) / this.advicePrice); + } else { + slip = '1234'; + } + + let tradeTime = moment(); + let diff = tradeTime.diff(this.adviceTime); + let timeToComplete = moment.utc(diff).format("mm:ss"); + + + // timeToComplete = trade.date - this.adviceTime; + // timeToComplete.format('h:mm:ss'); + + var text = [ + config.watch.exchange, + ' ', + config.watch.asset, + '/', + config.watch.currency, + '\nAdvice Price: ', + this.advicePrice, + '\nTrade Price: ', + trade.price, + '\nSlip: ', + slip.toFixed(2), '%', + '\nAdvice Time: ', + this.adviceTime.format("h:mm:ss"), + 'UTC', + '\nTrade Time: ', + tradeTime.format("h:mm:ss"), + 'UTC', + '\nTime to Fill: ', + timeToComplete + + ].join(''); + + var subject = ''; + + + subject = pushbulletConfig.tag + ' ' + trade.action + ' Complete '; + this.mail(subject, text); + } }; Pushbullet.prototype.mail = function(subject, content, done) { - var pusher = new pushbullet(pushbulletConfig.key); - pusher.note(pushbulletConfig.email, subject, content, function(error, response) { - if(error || !response) { - log.error('Pushbullet ERROR:', error) - } else if(response && response.active){ - log.info('Pushbullet Message Sent') - } - }); + var pusher = new pushbullet(pushbulletConfig.key); + pusher.note(pushbulletConfig.email, subject, content, function(error, response) { + if (error || !response) { + log.error('Pushbullet ERROR:', error) + } else if (response && response.active) { + log.info('Pushbullet Message Sent') + } + }); }; Pushbullet.prototype.checkResults = function(err) { - if(err) - log.warn('error sending email', err); - else - log.info('Send advice via email.'); + if (err) + log.warn('error sending pushbullet message', err); + else + log.info('Send advice via pushbullet message.'); }; -module.exports = Pushbullet; \ No newline at end of file +module.exports = Pushbullet; diff --git a/sample-config.js b/sample-config.js index 3e5174622..1f15db1f1 100644 --- a/sample-config.js +++ b/sample-config.js @@ -149,17 +149,21 @@ config.mailer = { } config.pushbullet = { - // sends pushbullets if true - enabled: false, - // Send 'Gekko starting' message if true + // sends pushbullets if true + enabled: true, + // Send 'Gekko starting' message if true sendMessageOnStart: true, - // disable advice printout if it's soft + // Send Message for advice? + sendOnAdvice: true, + // Send Message on Trade Completion? + sendOnTrade: true, + // disable advice printout if it's soft muteSoft: true, - // your pushbullet API key - key: 'xxx', - // your email, change it unless you are Azor Ahai - email: 'jon_snow@westeros.org', - // will make Gekko messages start mit [GEKKO] + // your pushbullet API key + key: '', + // your email + email: 'jon_snow@westeros.com', + // Messages will start with this tag tag: '[GEKKO]' }; From 0b634b1144fb023b72299e3a810018b082279c03 Mon Sep 17 00:00:00 2001 From: Rowan Griffin Date: Wed, 19 Sep 2018 16:08:22 +0100 Subject: [PATCH 10/19] Revert default plugin enebled to false --- sample-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-config.js b/sample-config.js index 1f15db1f1..8a0ab611d 100644 --- a/sample-config.js +++ b/sample-config.js @@ -150,7 +150,7 @@ config.mailer = { config.pushbullet = { // sends pushbullets if true - enabled: true, + enabled: false, // Send 'Gekko starting' message if true sendMessageOnStart: true, // Send Message for advice? From 3756f6cba844968c6fa35753264f0dcd25ff8275 Mon Sep 17 00:00:00 2001 From: Rowan Griffin Date: Fri, 21 Sep 2018 15:29:56 +0100 Subject: [PATCH 11/19] Improved time source --- plugins/pushbullet.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/plugins/pushbullet.js b/plugins/pushbullet.js index 2f09dadac..5c5dc3128 100644 --- a/plugins/pushbullet.js +++ b/plugins/pushbullet.js @@ -66,10 +66,10 @@ Pushbullet.prototype.setup = function(done) { exchange + "."; - if(config.trader.enabled){ + if (config.trader.enabled) { body += "\nLive Trading is enabled" } - if(config.paperTrader.enabled){ + if (config.paperTrader.enabled) { body += "\nPaper Trading is enabled" } this.mail(title, body); @@ -91,7 +91,7 @@ Pushbullet.prototype.processAdvice = function(advice) { if (advice.recommendation == "soft" && pushbulletConfig.muteSoft) return; this.advicePrice = this.price; - this.adviceTime = moment(); + this.adviceTime = advice.date; if (pushbulletConfig.sendOnAdvice) { @@ -126,7 +126,7 @@ Pushbullet.prototype.processTradeCompleted = function(trade) { slip = '1234'; } - let tradeTime = moment(); + let tradeTime = trade.date; let diff = tradeTime.diff(this.adviceTime); let timeToComplete = moment.utc(diff).format("mm:ss"); @@ -148,10 +148,8 @@ Pushbullet.prototype.processTradeCompleted = function(trade) { slip.toFixed(2), '%', '\nAdvice Time: ', this.adviceTime.format("h:mm:ss"), - 'UTC', '\nTrade Time: ', tradeTime.format("h:mm:ss"), - 'UTC', '\nTime to Fill: ', timeToComplete @@ -185,4 +183,4 @@ Pushbullet.prototype.checkResults = function(err) { log.info('Send advice via pushbullet message.'); }; -module.exports = Pushbullet; +module.exports = Pushbullet; \ No newline at end of file From 8410a2596e4c041f17da883417de90d57f963aea Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Thu, 27 Sep 2018 19:05:16 +0800 Subject: [PATCH 12/19] fix trailingStop typo, fix #2562 --- plugins/paperTrader/paperTrader.js | 2 +- plugins/trader/trader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/paperTrader/paperTrader.js b/plugins/paperTrader/paperTrader.js index 5998417ef..bb6fb75f9 100644 --- a/plugins/paperTrader/paperTrader.js +++ b/plugins/paperTrader/paperTrader.js @@ -193,7 +193,7 @@ PaperTrader.prototype.createTrigger = function(advice) { this.deferredEmit('triggerCreated', { id: triggerId, at: advice.date, - type: 'trialingStop', + type: 'trailingStop', proprties: { trail: trigger.trailValue, initialPrice: this.price, diff --git a/plugins/trader/trader.js b/plugins/trader/trader.js index 2e21443da..1ee4b323f 100644 --- a/plugins/trader/trader.js +++ b/plugins/trader/trader.js @@ -340,7 +340,7 @@ Trader.prototype.createOrder = function(side, amount, advice, id) { this.deferredEmit('triggerCreated', { id: triggerId, at: advice.date, - type: 'trialingStop', + type: 'trailingStop', properties: { trail: trigger.trailValue, initialPrice: summary.price, From fb8a43a3c85c6240624a909c1e3ee31b892037c4 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Sun, 30 Sep 2018 15:09:22 +0800 Subject: [PATCH 13/19] [GB] set bfx interval to 4 seconds --- exchange/orders/order.js | 1 - exchange/wrappers/binance.js | 2 ++ exchange/wrappers/bitfinex.js | 7 ++++++- exchange/wrappers/poloniex.js | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/exchange/orders/order.js b/exchange/orders/order.js index 4a6d5ea2f..ecbfaaf77 100644 --- a/exchange/orders/order.js +++ b/exchange/orders/order.js @@ -15,7 +15,6 @@ class BaseOrder extends EventEmitter { this.api = api; this.checkInterval = api.interval || 1500; - this.status = states.INITIALIZING; this.completed = false; diff --git a/exchange/wrappers/binance.js b/exchange/wrappers/binance.js index fa584b8b6..ff76da92c 100644 --- a/exchange/wrappers/binance.js +++ b/exchange/wrappers/binance.js @@ -111,6 +111,7 @@ Trader.prototype.handleResponse = function(funcName, callback) { } if(funcName === 'cancelOrder' && error.message.includes('UNKNOWN_ORDER')) { + console.log(new Date, 'cancelOrder', 'UNKNOWN_ORDER'); // order got filled in full before it could be // cancelled, meaning it was NOT cancelled. return callback(false, {filled: true}); @@ -122,6 +123,7 @@ Trader.prototype.handleResponse = function(funcName, callback) { } if(funcName === 'addOrder' && error.message.includes('Account has insufficient balance')) { + console.log(new Date, 'insufficientFunds'); error.type = 'insufficientFunds'; } diff --git a/exchange/wrappers/bitfinex.js b/exchange/wrappers/bitfinex.js index d2bd5d6b6..cb82e70ab 100644 --- a/exchange/wrappers/bitfinex.js +++ b/exchange/wrappers/bitfinex.js @@ -22,7 +22,7 @@ var Trader = function(config) { this.pair = this.asset + this.currency; this.bitfinex = new Bitfinex.RESTv1({apiKey: this.key, apiSecret: this.secret, transform: true}); - this.interval = 2000; + this.interval = 4000; } const includes = (str, list) => { @@ -49,6 +49,7 @@ const recoverableErrors = [ Trader.prototype.handleResponse = function(funcName, callback) { return (error, data) => { + if(!error && _.isEmpty(data)) { error = new Error('Empty response'); } @@ -56,6 +57,8 @@ Trader.prototype.handleResponse = function(funcName, callback) { if(error) { const message = error.message; + console.log('handleResponse', funcName, message); + // in case we just cancelled our balances might not have // settled yet, retry. if( @@ -227,6 +230,8 @@ Trader.prototype.getOrder = function(order_id, callback) { var amount = parseFloat(data.executed_amount); var date = moment.unix(data.timestamp); + console.log('getOrder', data); + // TEMP: Thu May 31 14:49:34 CEST 2018 // the `past_trades` call is not returning // any data. diff --git a/exchange/wrappers/poloniex.js b/exchange/wrappers/poloniex.js index d6b771912..e5661cfde 100644 --- a/exchange/wrappers/poloniex.js +++ b/exchange/wrappers/poloniex.js @@ -45,7 +45,8 @@ const recoverableErrors = [ 'Connection timed out. Please try again.', // getaddrinfo EAI_AGAIN poloniex.com poloniex.com:443 'EAI_AGAIN', - 'ENETUNREACH' + 'ENETUNREACH', + 'socket hang up' ]; // errors that might mean From efdbd71de6255f1d3c441d4fbc5368184e2b43fa Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Mon, 1 Oct 2018 02:48:43 +0800 Subject: [PATCH 14/19] only log the error message in cp crash --- core/util.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/core/util.js b/core/util.js index e3b404e43..7d2cccd5c 100644 --- a/core/util.js +++ b/core/util.js @@ -78,23 +78,18 @@ var util = { + `\nNodejs version: ${process.version}`; }, die: function(m, soft) { - if(_gekkoEnv === 'standalone' || !_gekkoEnv) - var log = console.log.bind(console); - else if(_gekkoEnv === 'child-process') - var log = m => process.send({type: 'error', error: m}); - var instanceName; + if(_gekkoEnv === 'child-process') { + return process.send({type: 'error', error: '\n ERROR: ' + m + '\n'}); + } - if(util.gekkoEnv() === 'standalone') - instanceName = 'Gekko'; - else - instanceName = 'This Gekko instance'; + var log = console.log.bind(console); if(m) { if(soft) { log('\n ERROR: ' + m + '\n\n'); } else { - log(`\n${instanceName} encountered an error and can\'t continue`); + log(`\nGekko encountered an error and can\'t continue`); log('\nError:\n'); log(m, '\n\n'); log('\nMeta debug info:\n'); From bc5ac9550f3397e79ddd0f1a75ffc6a1eba244a2 Mon Sep 17 00:00:00 2001 From: Mike van Rossum Date: Mon, 1 Oct 2018 02:51:10 +0800 Subject: [PATCH 15/19] make sure the baseConfig uses the dist UIconfig --- web/routes/baseConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/routes/baseConfig.js b/web/routes/baseConfig.js index cce4eb17d..6e3a4ab6b 100644 --- a/web/routes/baseConfig.js +++ b/web/routes/baseConfig.js @@ -1,4 +1,4 @@ -var UIconfig = require('../vue/public/UIconfig'); +var UIconfig = require('../vue/dist/UIconfig'); var config = {}; From b57b44eef106c66957f3f0ba0d2bd246cbe789eb Mon Sep 17 00:00:00 2001 From: Richard King Date: Fri, 28 Sep 2018 19:36:59 +1200 Subject: [PATCH 16/19] Fix to importer dates --- core/markets/importer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/markets/importer.js b/core/markets/importer.js index c18aac225..e46bd3f9b 100644 --- a/core/markets/importer.js +++ b/core/markets/importer.js @@ -9,12 +9,12 @@ var gekkoEnv = util.gekkoEnv(); var adapter = config[config.adapter]; var daterange = config.importer.daterange; -var from = moment(daterange.from); +var from = moment.utc(daterange.from); if(daterange.to) { - var to = moment(daterange.to); + var to = moment.utc(daterange.to); } else { - var to = moment(); + var to = moment().utc(); log.debug( 'No end date specified for importing, setting to', to.format() @@ -74,7 +74,7 @@ var Market = function() { this.candleManager.on( 'candles', this.pushCandles - ); + ); Readable.call(this, {objectMode: true}); @@ -114,4 +114,4 @@ Market.prototype.processTrades = function(trades) { setTimeout(this.get, 1000); } -module.exports = Market; \ No newline at end of file +module.exports = Market; From f9b4357d3991e9d469b443f143783182f80d9001 Mon Sep 17 00:00:00 2001 From: eusorov Date: Sun, 30 Sep 2018 13:49:46 +0200 Subject: [PATCH 17/19] bugfix #2568 transforms commonjs modules to ES2015 --- web/vue/babel.config.js | 6 +++--- web/vue/package-lock.json | 19 +++++++------------ web/vue/package.json | 1 + 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/web/vue/babel.config.js b/web/vue/babel.config.js index 93c2e1480..e6d0107b0 100644 --- a/web/vue/babel.config.js +++ b/web/vue/babel.config.js @@ -4,6 +4,6 @@ module.exports = { ], ignore: [ 'node_modules', - '../state/reduceState.js' - ] -} \ No newline at end of file + ], + plugins : ["transform-commonjs-es2015-modules"] +} diff --git a/web/vue/package-lock.json b/web/vue/package-lock.json index bc1aacbfb..f877a6d03 100644 --- a/web/vue/package-lock.json +++ b/web/vue/package-lock.json @@ -1,6 +1,6 @@ { "name": "gekko-vue-ui", - "version": "0.2.2", + "version": "0.2.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1983,6 +1983,12 @@ "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", "dev": true }, + "babel-plugin-transform-commonjs-es2015-modules": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-commonjs-es2015-modules/-/babel-plugin-transform-commonjs-es2015-modules-4.0.1.tgz", + "integrity": "sha512-8h493ia3xNH5oQmckkQKl/Owtgk+wT6fCT0ZNAjos60YBNDu64UCAtd0mCWJg6N4lGvnmP++CIxWblxaJBdPwg==", + "dev": true + }, "babel-plugin-transform-vue-jsx": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-4.0.1.tgz", @@ -2972,11 +2978,6 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, - "component-ie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-ie/-/component-ie-1.0.0.tgz", - "integrity": "sha1-D5WCzLB4podZLMKetGsxhub+Y38=" - }, "compressible": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", @@ -12026,12 +12027,6 @@ } } }, - "superagent-no-cache": { - "version": "github:uditalias/superagent-no-cache#2b15f4366a4b45bbfb66b9a626265bf3a72d00e4", - "requires": { - "component-ie": "1.0.0" - } - }, "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", diff --git a/web/vue/package.json b/web/vue/package.json index 66ba7a827..c6c575b46 100644 --- a/web/vue/package.json +++ b/web/vue/package.json @@ -17,6 +17,7 @@ "devDependencies": { "@vue/cli-plugin-babel": "^3.0.0-beta.15", "@vue/cli-service": "^3.0.0-beta.15", + "babel-plugin-transform-commonjs-es2015-modules": "^4.0.1", "copy-webpack-plugin": "^4.5.2", "pug": "^2.0.3", "pug-plain-loader": "^1.0.0", From 827be892ec6cf18c18702a48ea5a455556487a8c Mon Sep 17 00:00:00 2001 From: Wei Ken Date: Sun, 7 Oct 2018 15:22:23 +0800 Subject: [PATCH 18/19] export useful info in backtestResultExporter (#2509) * add useful info to export * standardize naming --- plugins/backtestResultExporter.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/backtestResultExporter.js b/plugins/backtestResultExporter.js index 5cd9fdd49..12d8ecb74 100644 --- a/plugins/backtestResultExporter.js +++ b/plugins/backtestResultExporter.js @@ -89,6 +89,9 @@ BacktestResultExporter.prototype.processPerformanceReport = function(performance BacktestResultExporter.prototype.finalize = function(done) { const backtest = { + market: config.watch, + tradingAdvisor: config.tradingAdvisor, + strategyParameters: config[config.tradingAdvisor.method], performanceReport: this.performanceReport }; From 3a49d630c3880ebe3f8b81e9d8b363755a3d5eb3 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Mon, 8 Oct 2018 07:58:49 +0200 Subject: [PATCH 19/19] bugfix #2548 if no strategy.historySize found, than get it from tradingAdvisor (#2577) * bugfix #2548 if no strategy.historySize found, get from tradingAdvisor * check with _.isNumber --- plugins/tradingAdvisor/baseTradingMethod.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/tradingAdvisor/baseTradingMethod.js b/plugins/tradingAdvisor/baseTradingMethod.js index 7ff173755..190d35a4e 100644 --- a/plugins/tradingAdvisor/baseTradingMethod.js +++ b/plugins/tradingAdvisor/baseTradingMethod.js @@ -37,7 +37,6 @@ var Base = function(settings) { this.settings = settings; this.tradingAdvisor = config.tradingAdvisor; // defaults - this.requiredHistory = 0; this.priceValue = 'close'; this.indicators = {}; this.asyncTick = false; @@ -69,6 +68,11 @@ var Base = function(settings) { // let's run the implemented starting point this.init(); + //if no requiredHistory was provided, set default from tradingAdvisor + if (!_.isNumber(this.requiredHistory)){ + this.requiredHistory = config.tradingAdvisor.historySize; + } + if(!config.debug || !this.log) this.log = function() {};