diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index e3a15ea4d..0d97fefe8 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,17 +1,17 @@ -**Note: for support questions, please join our [Discord server](https://discord.gg/26wMygt)** +**Note: this is the technical bug tracker, please use other platforms for getting support and starting a (non technical) discussion. See the [getting help page](https://gekko.wizb.it/docs/introduction/getting-help.html) for details.** -* **I'm submitting a ...** +**I'm submitting a ...** [ ] bug report -[ ] feature request [ ] question about the decisions made in the repository -* **Action taken** (what you did) +**Action taken** (what you did) -* **Expected result** (what you hoped would happen) +**Expected result** (what you hoped would happen) -* **Actual result** (unexpected outcome) +**Actual result** (unexpected outcome) -* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc) +**Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc) + diff --git a/.gitignore b/.gitignore index fcc8694ca..b054f6d5b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,6 @@ TMP_* volumes config.js config-*.js +private-*.js +private-*.toml SECRET-api-keys.json \ No newline at end of file diff --git a/bin/gekko_launch.sh b/bin/gekko_launch.sh deleted file mode 100755 index 442f61aab..000000000 --- a/bin/gekko_launch.sh +++ /dev/null @@ -1,18 +0,0 @@ -#navigate to gekko folder, change this if your location is different -cd ~/gekko - -# zip previous log files for this config -now="`date +%Y%m%d%H%M%S`" -current_log=log/gekko_log.$1.txt -archive_log=log/gekko_log.$1.$now.txt - -if [ -f $current_log ]; then - mv log/gekko_log.$1.txt $archive_log - zip -vu log/gekko_logs.zip $archive_log - - # remove raw text files now that they're zipped - rm $archive_log -fi - -# finally launch gekko and log output to log file as well as stdout -node gekko config="config/user/$1.js" 2>&1 | tee $current_log diff --git a/bin/gekko_launch_screen.sh b/bin/gekko_launch_screen.sh deleted file mode 100755 index f1e88249c..000000000 --- a/bin/gekko_launch_screen.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -screen -dmS gekko_$1 ~/gekko/bin/gekko_launch.sh $1 - diff --git a/bin/gekko_log_grab.sh b/bin/gekko_log_grab.sh deleted file mode 100755 index bad586ca2..000000000 --- a/bin/gekko_log_grab.sh +++ /dev/null @@ -1 +0,0 @@ -tail -f ~/gekko/log/gekko_log.$1.txt diff --git a/bin/gekko_screen_grab.sh b/bin/gekko_screen_grab.sh deleted file mode 100755 index 88ff923ca..000000000 --- a/bin/gekko_screen_grab.sh +++ /dev/null @@ -1 +0,0 @@ -screen -dR gekko_$1 diff --git a/config/strategies/DEMA.toml b/config/strategies/DEMA.toml index d60549806..0916c41c8 100644 --- a/config/strategies/DEMA.toml +++ b/config/strategies/DEMA.toml @@ -1,6 +1,5 @@ -short = 10 -long = 21 +weight = 21 [thresholds] down = -0.025 -up = 0.025 \ No newline at end of file +up = 0.025 diff --git a/config/strategies/TMA.toml b/config/strategies/TMA.toml new file mode 100644 index 000000000..f91574168 --- /dev/null +++ b/config/strategies/TMA.toml @@ -0,0 +1,3 @@ +short = 7 +medium = 25 +long = 99 diff --git a/core/budfox/marketFetcher.js b/core/budfox/marketFetcher.js index 3097d98a6..d6700e54f 100644 --- a/core/budfox/marketFetcher.js +++ b/core/budfox/marketFetcher.js @@ -1,8 +1,8 @@ -// -// The fetcher is responsible for fetching new +// +// The fetcher is responsible for fetching new // market data at the exchange on interval. It will emit // the following events: -// +// // - `trades batch` - all new trades. // - `trade` - the most recent trade after every fetch @@ -21,13 +21,13 @@ var Fetcher = function(config) { if(!_.isObject(config)) throw 'TradeFetcher expects a config'; - var provider = config.watch.exchange.toLowerCase(); - var DataProvider = require(util.dirs().gekko + 'exchanges/' + provider); + var exchangeName = config.watch.exchange.toLowerCase(); + var DataProvider = require(util.dirs().gekko + 'exchanges/' + exchangeName); _.bindAll(this); - // Create a public dataProvider object which can retrieve live + // Create a public dataProvider object which can retrieve live // trade information from an exchange. - this.watcher = new DataProvider(config.watch); + this.exchangeTrader = new DataProvider(config.watch); this.exchange = exchangeChecker.settings(config.watch); @@ -72,7 +72,7 @@ Fetcher.prototype._fetch = function(since) { if(++this.tries >= this.limit) return; - this.watcher.getTrades(since, this.processTrades, false); + this.exchangeTrader.getTrades(since, this.processTrades, false); } Fetcher.prototype.fetch = function() { diff --git a/core/budfox/tradeBatcher.js b/core/budfox/tradeBatcher.js index 60b276a47..b6b5e13d1 100644 --- a/core/budfox/tradeBatcher.js +++ b/core/budfox/tradeBatcher.js @@ -1,5 +1,5 @@ // -// Small wrapper that only propogates new trades. +// Small wrapper that only propagates new trades. // // Expects trade batches to be written like: // [ diff --git a/core/exchangeChecker.js b/core/exchangeChecker.js index 79e3582b9..a4542b11e 100644 --- a/core/exchangeChecker.js +++ b/core/exchangeChecker.js @@ -3,6 +3,7 @@ var fs = require('fs'); var util = require('./util'); var config = util.getConfig(); var dirs = util.dirs(); +var moment = require('moment'); var Checker = function() { _.bindAll(this); @@ -72,6 +73,12 @@ Checker.prototype.cantFetchFullHistory = function(conf) { if(!exchange.providesFullHistory) return 'The exchange ' + name + ' does not provide full history (or Gekko doesn\'t support importing it)'; + + if ("exchangeMaxHistoryAge" in exchange) { + if (moment(config.importer.daterange.from) < moment().subtract(exchange.exchangeMaxHistoryAge, "days")) { + return 'Unsupported date from! ' + exchange.name + ' supports history of max ' + exchange.exchangeMaxHistoryAge + ' days..'; + } + } } // check if the exchange if configured correctly for real trading @@ -108,4 +115,4 @@ Checker.prototype.settings = function(conf) { } -module.exports = new Checker(); \ No newline at end of file +module.exports = new Checker(); diff --git a/core/markets/leech.js b/core/markets/leech.js index 2c8ed5149..11be19e97 100644 --- a/core/markets/leech.js +++ b/core/markets/leech.js @@ -1,6 +1,6 @@ // a leech market is "semi-realtime" and pulls out candles of a -// database (which is expected to be updated reguraly, like with a -// realtime market running in parralel). +// database (which is expected to be updated regularly, like with a +// realtime market running in parallel). const _ = require('lodash'); const moment = require('moment'); diff --git a/core/pipeline.js b/core/pipeline.js index 18a1ac43e..6590f23b3 100644 --- a/core/pipeline.js +++ b/core/pipeline.js @@ -6,7 +6,7 @@ all enabled plugins are actually supported by that market. Read more here: - @link https://github.com/askmike/gekko/blob/stable/docs/internals/architecture.md + https://gekko.wizbit/docs/internals/architecture.html */ diff --git a/core/talib.js b/core/talib.js index fdad18459..117da8b1f 100644 --- a/core/talib.js +++ b/core/talib.js @@ -1,7 +1,7 @@ var semver = require("semver"); var _ = require('lodash'); -// validate that talib is installed, if not we'll throw an excepion which will +// validate that talib is installed, if not we'll throw an exception which will // prevent further loading or out outside this module try { var talib = require("talib"); @@ -48,6 +48,933 @@ var verifyParams = (methodName, params) => { var methods = {}; + +//////////////////////////////Pattern Recognition////////////////////////////// +methods.cdl2crows = { + requires: [], + create: (params) => { + verifyParams('cdl2crows', params); + return (data, callback) => execute(callback, { + name: "CDL2CROWS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdl3blackcrows = { + requires: [], + create: (params) => { + verifyParams('cdl3blackcrows', params); + return (data, callback) => execute(callback, { + name: "CDL3BLACKCROWS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdl3inside = { + requires: [], + create: (params) => { + verifyParams('cdl3inside', params); + return (data, callback) => execute(callback, { + name: "CDL3INSIDE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdl3linestrike = { + requires: [], + create: (params) => { + verifyParams('cdl3linestrike', params); + return (data, callback) => execute(callback, { + name: "CDL3LINESTRIKE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdl3outside = { + requires: [], + create: (params) => { + verifyParams('cdl3outside', params); + return (data, callback) => execute(callback, { + name: "CDL3OUTSIDE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdl3starsinsouth = { + requires: [], + create: (params) => { + verifyParams('cdl3starsinsouth', params); + return (data, callback) => execute(callback, { + name: "CDL3STARSINSOUTH", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdl3whitesoldiers = { + requires: [], + create: (params) => { + verifyParams('cdl3whitesoldiers', params); + return (data, callback) => execute(callback, { + name: "CDL3WHITESOLDIERS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlabandonedbaby = { + requires: ['optInPenetration'], + create: (params) => { + verifyParams('cdlabandonedbaby', params); + return (data, callback) => execute(callback, { + name: "CDLABANDONEDBABY", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close, + optInPenetration: params.optInPenetration + }); + } +} +methods.cdladvanceblock = { + requires: [], + create: (params) => { + verifyParams('cdladvanceblock', params); + return (data, callback) => execute(callback, { + name: "CDLADVANCEBLOCK", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlbelthold = { + requires: [], + create: (params) => { + verifyParams('cdlbelthold', params); + return (data, callback) => execute(callback, { + name: "CDLBELTHOLD", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlbreakaway = { + requires: [], + create: (params) => { + verifyParams('cdlbreakaway', params); + return (data, callback) => execute(callback, { + name: "CDLBREAKAWAY", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlclosingmarubozu = { + requires: [], + create: (params) => { + verifyParams('cdlclosingmarubozu', params); + return (data, callback) => execute(callback, { + name: "CDLCLOSINGMARUBOZU", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlconcealbabyswall = { + requires: [], + create: (params) => { + verifyParams('cdlconcealbabyswall', params); + return (data, callback) => execute(callback, { + name: "CDLCONCEALBABYSWALL", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlcounterattack = { + requires: [], + create: (params) => { + verifyParams('cdlcounterattack', params); + return (data, callback) => execute(callback, { + name: "CDLCOUNTERATTACK", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdldarkcloudcover = { + requires: ['optInPenetration'], + create: (params) => { + verifyParams('cdldarkcloudcover', params); + return (data, callback) => execute(callback, { + name: "CDLDARKCLOUDCOVER", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close, + optInPenetration: params.optInPenetration + }); + } +} +methods.cdldoji = { + requires: [], + create: (params) => { + verifyParams('cdldoji', params); + return (data, callback) => execute(callback, { + name: "CDLDOJI", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdldojistar = { + requires: [], + create: (params) => { + verifyParams('cdldojistar', params); + return (data, callback) => execute(callback, { + name: "CDLDOJISTAR", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdldragonflydoji = { + requires: [], + create: (params) => { + verifyParams('cdldragonflydoji', params); + return (data, callback) => execute(callback, { + name: "CDLDRAGONFLYDOJI", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlengulfing = { + requires: [], + create: (params) => { + verifyParams('cdlengulfing', params); + return (data, callback) => execute(callback, { + name: "CDLENGULFING", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdleveningdojistar = { + requires: ['optInPenetration'], + create: (params) => { + verifyParams('cdleveningdojistar', params); + return (data, callback) => execute(callback, { + name: "CDLEVENINGDOJISTAR", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close, + optInPenetration: params.optInPenetration + }); + } +} +methods.cdleveningstar = { + requires: ['optInPenetration'], + create: (params) => { + verifyParams('cdleveningstar', params); + return (data, callback) => execute(callback, { + name: "CDLEVENINGSTAR", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close, + optInPenetration: params.optInPenetration + }); + } +} +methods.cdlgapsidesidewhite = { + requires: [], + create: (params) => { + verifyParams('cdlgapsidesidewhite', params); + return (data, callback) => execute(callback, { + name: "CDLGAPSIDESIDEWHITE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlgravestonedoji = { + requires: [], + create: (params) => { + verifyParams('cdlgravestonedoji', params); + return (data, callback) => execute(callback, { + name: "CDLGRAVESTONEDOJI", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlhammer = { + requires: [], + create: (params) => { + verifyParams('cdlhammer', params); + return (data, callback) => execute(callback, { + name: "CDLHAMMER", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlhangingman = { + requires: [], + create: (params) => { + verifyParams('cdlhangingman', params); + return (data, callback) => execute(callback, { + name: "CDLHANGINGMAN", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlharami = { + requires: [], + create: (params) => { + verifyParams('cdlharami', params); + return (data, callback) => execute(callback, { + name: "CDLHARAMI", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlharamicross = { + requires: [], + create: (params) => { + verifyParams('cdlharamicross', params); + return (data, callback) => execute(callback, { + name: "CDLHARAMICROSS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlhighwave = { + requires: [], + create: (params) => { + verifyParams('cdlhighwave', params); + return (data, callback) => execute(callback, { + name: "CDLHIGHWAVE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlhikkake = { + requires: [], + create: (params) => { + verifyParams('cdlhikkake', params); + return (data, callback) => execute(callback, { + name: "CDLHIKKAKE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlhikkakemod = { + requires: [], + create: (params) => { + verifyParams('cdlhikkakemod', params); + return (data, callback) => execute(callback, { + name: "CDLHIKKAKEMOD", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlhomingpigeon = { + requires: [], + create: (params) => { + verifyParams('cdlhomingpigeon', params); + return (data, callback) => execute(callback, { + name: "CDLHOMINGPIGEON", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlidentical3crows = { + requires: [], + create: (params) => { + verifyParams('cdlidentical3crows', params); + return (data, callback) => execute(callback, { + name: "CDLIDENTICAL3CROWS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlinneck = { + requires: [], + create: (params) => { + verifyParams('cdlinneck', params); + return (data, callback) => execute(callback, { + name: "CDLINNECK", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlinvertedhammer = { + requires: [], + create: (params) => { + verifyParams('cdlinvertedhammer', params); + return (data, callback) => execute(callback, { + name: "CDLINVERTEDHAMMER", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlkicking = { + requires: [], + create: (params) => { + verifyParams('cdlkicking', params); + return (data, callback) => execute(callback, { + name: "CDLKICKING", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlkickingbylength = { + requires: [], + create: (params) => { + verifyParams('cdlkickingbylength', params); + return (data, callback) => execute(callback, { + name: "CDLKICKINGBYLENGTH", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlladderbottom = { + requires: [], + create: (params) => { + verifyParams('cdlladderbottom', params); + return (data, callback) => execute(callback, { + name: "CDLLADDERBOTTOM", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdllongleggeddoji = { + requires: [], + create: (params) => { + verifyParams('cdllongleggeddoji', params); + return (data, callback) => execute(callback, { + name: "CDLLONGLEGGEDDOJI", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdllongline = { + requires: [], + create: (params) => { + verifyParams('cdllongline', params); + return (data, callback) => execute(callback, { + name: "CDLLONGLINE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlmarubozu = { + requires: [], + create: (params) => { + verifyParams('cdlmarubozu', params); + return (data, callback) => execute(callback, { + name: "CDLMARUBOZU", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlmatchinglow = { + requires: [], + create: (params) => { + verifyParams('cdlmatchinglow', params); + return (data, callback) => execute(callback, { + name: "CDLMATCHINGLOW", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlmathold = { + requires: ['optInPenetration'], + create: (params) => { + verifyParams('cdlmathold', params); + return (data, callback) => execute(callback, { + name: "CDLMATHOLD", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close, + optInPenetration: params.optInPenetration + }); + } +} +methods.cdlmorningdojistar = { + requires: ['optInPenetration'], + create: (params) => { + verifyParams('cdlmorningdojistar', params); + return (data, callback) => execute(callback, { + name: "CDLMORNINGDOJISTAR", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close, + optInPenetration: params.optInPenetration + }); + } +} +methods.cdlmorningstar = { + requires: ['optInPenetration'], + create: (params) => { + verifyParams('cdlmorningstar', params); + return (data, callback) => execute(callback, { + name: "CDLMORNINGSTAR", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close, + optInPenetration: params.optInPenetration + }); + } +} +methods.cdlonneck = { + requires: [], + create: (params) => { + verifyParams('cdlonneck', params); + return (data, callback) => execute(callback, { + name: "CDLONNECK", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlpiercing = { + requires: [], + create: (params) => { + verifyParams('cdlpiercing', params); + return (data, callback) => execute(callback, { + name: "CDLPIERCING", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlrickshawman = { + requires: [], + create: (params) => { + verifyParams('cdlrickshawman', params); + return (data, callback) => execute(callback, { + name: "CDLRICKSHAWMAN", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlrisefall3methods = { + requires: [], + create: (params) => { + verifyParams('cdlrisefall3methods', params); + return (data, callback) => execute(callback, { + name: "CDLRISEFALL3METHODS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlseparatinglines = { + requires: [], + create: (params) => { + verifyParams('cdlseparatinglines', params); + return (data, callback) => execute(callback, { + name: "CDLSEPARATINGLINES", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlshootingstar = { + requires: [], + create: (params) => { + verifyParams('cdlshootingstar', params); + return (data, callback) => execute(callback, { + name: "CDLSHOOTINGSTAR", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlshortline = { + requires: [], + create: (params) => { + verifyParams('cdlshortline', params); + return (data, callback) => execute(callback, { + name: "CDLSHORTLINE", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlspinningtop = { + requires: [], + create: (params) => { + verifyParams('cdlspinningtop', params); + return (data, callback) => execute(callback, { + name: "CDLSPINNINGTOP", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlstalledpattern = { + requires: [], + create: (params) => { + verifyParams('cdlstalledpattern', params); + return (data, callback) => execute(callback, { + name: "CDLSTALLEDPATTERN", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlsticksandwich = { + requires: [], + create: (params) => { + verifyParams('cdlsticksandwich', params); + return (data, callback) => execute(callback, { + name: "CDLSTICKSANDWICH", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdltakuri = { + requires: [], + create: (params) => { + verifyParams('cdltakuri', params); + return (data, callback) => execute(callback, { + name: "CDLTAKURI", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdltasukigap = { + requires: [], + create: (params) => { + verifyParams('cdltasukigap', params); + return (data, callback) => execute(callback, { + name: "CDLTASUKIGAP", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlthrusting = { + requires: [], + create: (params) => { + verifyParams('cdlthrusting', params); + return (data, callback) => execute(callback, { + name: "CDLTHRUSTING", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdltristar = { + requires: [], + create: (params) => { + verifyParams('cdltristar', params); + return (data, callback) => execute(callback, { + name: "CDLTRISTAR", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlunique3river = { + requires: [], + create: (params) => { + verifyParams('cdlunique3river', params); + return (data, callback) => execute(callback, { + name: "CDLUNIQUE3RIVER", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlupsidegap2crows = { + requires: [], + create: (params) => { + verifyParams('cdlupsidegap2crows', params); + return (data, callback) => execute(callback, { + name: "CDLUPSIDEGAP2CROWS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} +methods.cdlxsidegap3methods = { + requires: [], + create: (params) => { + verifyParams('cdlxsidegap3methods', params); + return (data, callback) => execute(callback, { + name: "CDLXSIDEGAP3METHODS", + startIdx: 0, + endIdx: data.close.length - 1, + open: data.open, + high: data.high, + low: data.low, + close: data.close + }); + } +} + +//////////////////////////////Pattern Recognition////////////////////////////// + methods.accbands = { requires: ['optInTimePeriod'], create: (params) => { diff --git a/core/tools/dataStitcher.js b/core/tools/dataStitcher.js index 840303a24..b9756826a 100644 --- a/core/tools/dataStitcher.js +++ b/core/tools/dataStitcher.js @@ -43,7 +43,7 @@ Stitcher.prototype.prepareHistoricalData = function(done) { var requiredHistory = config.tradingAdvisor.candleSize * config.tradingAdvisor.historySize; var Reader = require(dirs.plugins + config.adapter + '/reader'); - + this.reader = new Reader; log.info( @@ -63,6 +63,11 @@ Stitcher.prototype.prepareHistoricalData = function(done) { var idealExchangeStartTime = idealStartTime.clone(); var idealExchangeStartTimeTS = idealExchangeStartTime.unix(); } + else if (idealStartTime.unix() < localData.from) { + log.info('\tLocal data is still too recent, trying to get as much as possible from the exchange'); + var idealExchangeStartTime = idealStartTime.clone(); + var idealExchangeStartTimeTS = idealExchangeStartTime.unix(); + } else { log.debug('\tAvailable local data:'); log.debug('\t\tfrom:', this.ago(localData.from)); @@ -92,7 +97,7 @@ Stitcher.prototype.prepareHistoricalData = function(done) { log.info('\tPreventing Gekko from requesting', minutesAgo, 'minutes of history.'); idealExchangeStartTime = endTime.clone().subtract(maxMinutesAgo, 'minutes'); idealExchangeStartTimeTS = idealExchangeStartTime.unix(); - } + } log.debug('\tFetching exchange data since', this.ago(idealExchangeStartTimeTS)) this.checkExchangeTrades(idealExchangeStartTime, function(err, exchangeData) { diff --git a/core/tulind.js b/core/tulind.js index 52f2ffe3a..a46a5fb80 100644 --- a/core/tulind.js +++ b/core/tulind.js @@ -1,7 +1,7 @@ var semver = require("semver"); var _ = require('lodash'); -// validate that talib is installed, if not we'll throw an excepion which will +// validate that talib is installed, if not we'll throw an exception which will // prevent further loading or out outside this module try { var tulind = require("tulind"); diff --git a/core/util.js b/core/util.js index d59f4ea59..d4fac292d 100644 --- a/core/util.js +++ b/core/util.js @@ -183,8 +183,8 @@ var util = { minTimeout: 1 * 1000, maxTimeout: 3 * 1000 }; - - retryHelper(fn, operation, callback); + + retryHelper(fn, options, callback); }, retryCustom: function(options, fn, callback) { retryHelper(fn, options, callback); diff --git a/core/workers/datasetScan/parent.js b/core/workers/datasetScan/parent.js index 2e1d64181..edc08f9c9 100644 --- a/core/workers/datasetScan/parent.js +++ b/core/workers/datasetScan/parent.js @@ -1,6 +1,7 @@ var _ = require('lodash'); var moment = require('moment'); var async = require('async'); +var os = require('os'); var util = require('../../util'); var dirs = util.dirs(); @@ -19,7 +20,7 @@ module.exports = function(config, done) { if(err) return done(err); - async.each(markets, (market, next) => { + async.eachLimit(markets, os.cpus().length, (market, next) => { let marketConfig = _.clone(config); marketConfig.watch = market; diff --git a/docs/extending/add_an_exchange.md b/docs/extending/add_an_exchange.md index 0e7b133cc..d11754cb8 100644 --- a/docs/extending/add_an_exchange.md +++ b/docs/extending/add_an_exchange.md @@ -41,6 +41,14 @@ The callback needs to have the parameters of `err` and `fee`. Fee is a float tha The callback needs to have the parameters of `err` and `portfolio`. Portfolio needs to be an array of all currencies and assets combined in the form of objects, an example object looks like `{name: 'BTC', amount: 1.42131}` (name needs to be an uppercase string, amount needs to be a float). +### getLotSize + + this.exchange.getLotSize(tradeType, amount, size, callback) + +The callback needs to have the parameters of `err` and `lot`. Lot needs to be an object with `amount` and `purchase` size appropriately for the exchange. In the event that the lot is too small, return 0 to both fields and this will generate a lot size warning in the portfolioManager. + +Note: This function is currently optional. If not implemented `portfolioManager` will fallback to basic lot sizing mechanism it uses internally. However exchanges are not all the same in how rounding and lot sizing work, it is recommend to implement this function. + ### buy this.exchange.buy(amount, price, callback); diff --git a/docs/installation/installing_gekko_on_windows_with_bash_on_windows_10.md b/docs/installation/installing_gekko_on_windows_with_bash_on_windows_10.md index 22f4e00f6..2acbeba79 100644 --- a/docs/installation/installing_gekko_on_windows_with_bash_on_windows_10.md +++ b/docs/installation/installing_gekko_on_windows_with_bash_on_windows_10.md @@ -47,7 +47,7 @@ Open up bash and install node.js: (taken from [here](https://nodejs.org/en/downl ``` sudo apt-get update -curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - +curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install -y nodejs sudo apt-get install -y build-essential ``` diff --git a/docs/introduction/about_gekko.md b/docs/introduction/about_gekko.md index d2dda2cdb..1f5040b13 100644 --- a/docs/introduction/about_gekko.md +++ b/docs/introduction/about_gekko.md @@ -4,7 +4,7 @@ Gekko is a **free and open source** Bitcoin TA trading and backtesting platform *Use Gekko at your own risk.* -![screen shot of gekko backtesting](https://cloud.githubusercontent.com/assets/969743/24838718/8c790a86-1d45-11e7-99ae-e7e551cb40cb.png) +![screen shot of gekko backtesting](https://user-images.githubusercontent.com/969743/35054500-fc705b46-fbac-11e7-9652-306c468505a3.png) ## The gist diff --git a/docs/introduction/getting_help.md b/docs/introduction/getting_help.md new file mode 100644 index 000000000..7979889b0 --- /dev/null +++ b/docs/introduction/getting_help.md @@ -0,0 +1,25 @@ +# Getting Help + +Are you getting stuck installing or using Gekko? Are you struggling with understanding Gekko? Running into problems creating your own plugin or strategy? Do you want to discuss awesome things you want to do with Gekko? This page will explain what to do! + +## Online community + +If you have trouble with anything specific or you want to provide any type of feedback the online communty is the place to be. You can find the community at: + +1. [The online webforum](https://forum.gekko.wizb.it) +2. [The discord channel](https://discord.gg/26wMygt) + +These communities are the place for things like: + +- Solving installation problems + - Solving installation errors + - Helping set up Gekko on a server or embedded device +- Requesting/requesting new features and or changes such as: + - New exchanges to add + - New plugins to add + - General new features +- Getting clarity on what Gekko can do and how it works + +## Technical discussion + +The links above are always the first place to go to when discussing new features. But if you've found a clear bug or you want to **keep the complete discussion 100% technical (meaning completely code and architecture related)** you can use the [bug tracker on github](https://github.com/askmike/gekko/issues). Note that we are trying to keep all other discussions out of the bug tracker to keep the whole thing managable :) \ No newline at end of file diff --git a/docs/introduction/supported_exchanges.md b/docs/introduction/supported_exchanges.md index eb22b6064..6ae0e6458 100644 --- a/docs/introduction/supported_exchanges.md +++ b/docs/introduction/supported_exchanges.md @@ -8,6 +8,7 @@ Gekko is able to directly communicate with the APIs of a number of exchanges. Ho | Exchange | Monitoring | Live Trading | Importing | Notes | | -------------------- |:----------:|:------------:|:---------:| ------------------------ | +| [Binance][24] | ✓ | ✓ | ✓ | | | [Poloniex][2] | ✓ | ✓ | ✓ | | | [GDAX][3] | ✓ | ✓ | ✓ | | | [BTCC][4] | ✓ | ✓ | ✓ | (=BTCChina) | @@ -28,8 +29,7 @@ Gekko is able to directly communicate with the APIs of a number of exchanges. Ho | [lakeBTC][18] | ✓ | ✕ | ✕ | | | [bx.in.th][19] | ✓ | ✕ | ✕ | | | [bitcoin.co.id][22] | ✓ | ✓ | ✕ | | -| [Quadriga CX][23] | ✓ | ✓ | ✕ | | -| [Binance][24] | ✓ | ✓ | ✓ | | | +| [Quadriga CX][23] | ✓ | ✓ | ✕ | | | [1]: ../features/backtesting.md [2]: https://poloniex.com @@ -54,6 +54,7 @@ Gekko is able to directly communicate with the APIs of a number of exchanges. Ho [21]: https://github.com/askmike/gekko/issues/288#issuecomment-223810974 [22]: https://vip.bitcoin.co.id/ [23]: https://quadrigacx.com/ -[24]: https://binance.com/ -[25]: https://coinfalcon.com/ +[24]: https://www.binance.com/?ref=11236330 +[25]: https://coinfalcon.com/?ref=CFJSTEXJQFFE + diff --git a/exchanges/DEBUG_exchange-simulator.js b/exchanges/DEBUG_exchange-simulator.js new file mode 100644 index 000000000..2a6f05606 --- /dev/null +++ b/exchanges/DEBUG_exchange-simulator.js @@ -0,0 +1,73 @@ +// Fake exchanges: used to test purposes to develop Gekko (works without internet). + +const _ = require('lodash'); +const moment = require('moment'); +const log = require('../core/log'); + +const TREND_DURATION = 1000; + +const Trader = function() { + this.name = 'Exchange Simulator'; + this.at = moment().subtract(30, 'minutes'); + + + // fake data + this.price = 100; + this.trend = 'up'; + this.tid = 0; +} + +Trader.prototype.getTrades = function(since, cb) { + const amount = moment().diff(this.at, 'seconds'); + + const trades = _.range(amount).map(() => { + + this.tid++; + + if(this.tid % TREND_DURATION === 0) { + if(this.trend === 'up') + this.trend = 'down'; + else + this.trend = 'up'; + } + + if(this.trend === 'up') + this.price += Math.random(); + else + this.price -= Math.random(); + + return { + date: this.at.add(1, 'seconds').unix(), + price: this.price, + amount: Math.random() * 100, + tid: this.tid + } + }); + + console.log( + `[EXCHANGE SIMULATOR] emitted ${amount} fake trades, up until ${this.at.format('YYYY-MM-DD HH:mm:ss')}.` + ); + + cb(null, trades); +} + +Trader.getCapabilities = function () { + return { + name: 'Exchange Simulator', + slug: 'DEBUG_exchange-simulator', + currencies: ['USD'], + assets: ['BTC', 'BTC'], + maxTradesAge: 60, + maxHistoryFetch: null, + markets: [ + { pair: ['USD', 'BTC'], minimalOrder: { amount: 5, unit: 'currency' } }, + ], + requires: ['key', 'secret', 'username'], + fetchTimespan: 60, + tid: 'tid', + tradable: false + }; +} + +module.exports = Trader; + diff --git a/exchanges/binance-markets.json b/exchanges/binance-markets.json new file mode 100644 index 000000000..2538e8996 --- /dev/null +++ b/exchanges/binance-markets.json @@ -0,0 +1,3286 @@ +{ + "assets": [ + "NULS", + "VEN", + "BNB", + "CTR", + "NEO", + "LINK", + "SALT", + "IOTA", + "ETC", + "AST", + "KNC", + "WTC", + "SNGLS", + "EOS", + "SNT", + "MCO", + "BTC", + "OAX", + "OMG", + "GAS", + "BQX", + "QTUM", + "BNT", + "DNT", + "ICN", + "SNM", + "STRAT", + "ZRX", + "FUN", + "LTC", + "ETH", + "XVG", + "BCC", + "ADA", + "ADX", + "AE", + "AION", + "AMB", + "APPC", + "ARK", + "ARN", + "BAT", + "BCD", + "BCPT", + "BLZ", + "BRD", + "BTG", + "BTS", + "CDT", + "CHAT", + "CMT", + "CND", + "DASH", + "DGD", + "DLT", + "EDO", + "ELF", + "ENG", + "ENJ", + "EVX", + "FUEL", + "GTO", + "GVT", + "GXS", + "HSR", + "ICX", + "INS", + "IOST", + "KMD", + "LEND", + "LRC", + "LSK", + "LUN", + "MANA", + "MDA", + "MOD", + "MTH", + "MTL", + "NANO", + "NAV", + "NCASH", + "NEBL", + "ONT", + "OST", + "PIVX", + "POA", + "POE", + "POWR", + "PPT", + "QSP", + "RCN", + "RDN", + "REQ", + "RLC", + "RPX", + "STEEM", + "STORJ", + "STORM", + "SUB", + "TNB", + "TNT", + "TRIG", + "TRX", + "VIA", + "VIB", + "VIBE", + "WABI", + "WAVES", + "WINGS", + "XEM", + "XLM", + "XMR", + "XRP", + "XZC", + "YOYO", + "ZEC", + "ZIL" + ], + "currencies": [ + "BNB", + "BTC", + "ETH", + "USDT" + ], + "markets": [ + { + "pair": [ + "BNB", + "NULS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BNB", + "VEN" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.0001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "BNB" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "NULS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "CTR" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "NEO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "NULS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "LINK" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "SALT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "IOTA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "ETC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "AST" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "KNC" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "WTC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "SNGLS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "EOS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "SNT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "MCO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "USDT", + "BTC" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 0.01, + "order": 10 + } + }, + { + "pair": [ + "ETH", + "OAX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "OMG" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "GAS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BQX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "WTC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "QTUM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "BNT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "DNT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "ICN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "SNM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "SNM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "SNGLS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "BQX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "NEO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "KNC" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "STRAT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "ZRX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "QTUM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "FUN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "LTC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "LINK" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ETH" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "XVG" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "STRAT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "ZRX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "IOTA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "BCC" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "CTR" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "OMG" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "MCO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "SALT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ADA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ADA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "ADX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "ADX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ADX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "AE" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "AE" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "AE" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "AION" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "AION" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "AION" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "AMB" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "AMB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "AMB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "APPC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "APPC" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "APPC" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ARK" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ARK" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ARN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ARN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "AST" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BNB", + "BAT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "BAT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BAT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "BCC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.01, + "order": 1 + } + }, + { + "pair": [ + "ETH", + "BCC" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.00001, + "order": 0.01 + } + }, + { + "pair": [ + "USDT", + "BCC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.01, + "order": 10 + } + }, + { + "pair": [ + "BTC", + "BCD" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BCD" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.00001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "BCPT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "BCPT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BCPT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "BLZ" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "BLZ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BLZ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "BNB" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "BNT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BNB", + "BRD" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "BRD" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BRD" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "BTG" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BTG" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "BTS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "BTS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "BTS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "CDT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "CDT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "CHAT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "CHAT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "CMT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "CMT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "CMT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "CND" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "CND" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "CND" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "DASH" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "DASH" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.00001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "DGD" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "DGD" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.00001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "DLT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "DLT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "DLT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "DNT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "EDO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "EDO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ELF" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ELF" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ENG" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ENG" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ENJ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ENJ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "EOS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ETC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "EVX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "EVX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "FUEL" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "FUEL" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "FUN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BNB", + "GTO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "GTO" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "GTO" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "GVT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "GVT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "GXS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "GXS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "HSR" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "HSR" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ICN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BNB", + "ICX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "ICX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ICX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "INS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "INS" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "IOST" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "IOST" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "IOTA" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "KMD" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "KMD" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "LEND" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "LEND" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "LRC" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "LRC" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "LSK" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.0001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "LSK" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "LSK" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "LTC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.01, + "order": 1 + } + }, + { + "pair": [ + "ETH", + "LTC" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.00001, + "order": 0.01 + } + }, + { + "pair": [ + "USDT", + "LTC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.01, + "order": 10 + } + }, + { + "pair": [ + "BTC", + "LUN" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "LUN" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "MANA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "MANA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "MCO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "MDA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "MDA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "MOD" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "MOD" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "MTH" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "MTH" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "MTL" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "MTL" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "NANO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.0001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "NANO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "NANO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "NAV" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "NAV" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "NAV" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "NCASH" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "NCASH" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "NCASH" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "NEBL" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "NEBL" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "NEBL" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "NEO" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.001, + "order": 1 + } + }, + { + "pair": [ + "USDT", + "NEO" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.001, + "order": 10 + } + }, + { + "pair": [ + "BTC", + "OAX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BNB", + "ONT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "ONT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ONT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "OST" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "OST" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "OST" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "PIVX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "PIVX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "PIVX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "POA" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "POA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "POA" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "POE" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "POE" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "POWR" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "POWR" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "POWR" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "PPT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "PPT" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "QSP" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "QSP" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "QSP" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "QTUM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "USDT", + "QTUM" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.001, + "order": 10 + } + }, + { + "pair": [ + "BNB", + "RCN" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "RCN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "RCN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "RDN" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "RDN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "RDN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "REQ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "REQ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "RLC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "RLC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "RLC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "RPX" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "RPX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "RPX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "SNT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BNB", + "STEEM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "STEEM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "STEEM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "STORJ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "STORJ" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "STORM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "STORM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "STORM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "SUB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "SUB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "TNB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "TNB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "TNT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "TNT" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "TRIG" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "TRIG" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "TRIG" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "TRX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "TRX" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "VEN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "VEN" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "VIA" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "VIA" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "VIA" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "VIB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BTC", + "VIBE" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "VIBE" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "ETH", + "VIB" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "WABI" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "WABI" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "WABI" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "WAVES" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.0001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "WAVES" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-7, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "WAVES" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "WINGS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "WINGS" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-7, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "WTC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.0001, + "order": 1 + } + }, + { + "pair": [ + "BNB", + "XEM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "XEM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "XEM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "XLM" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "XLM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "XLM" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "XMR" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "XMR" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.00001, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "XRP" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "XRP" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "XVG" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "BNB", + "XZC" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "XZC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "XZC" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.000001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "YOYO" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "YOYO" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "YOYO" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "BTC", + "ZEC" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.000001, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ZEC" + ], + "minimalOrder": { + "amount": 0.001, + "price": 0.00001, + "order": 0.01 + } + }, + { + "pair": [ + "BNB", + "ZIL" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.00001, + "order": 1 + } + }, + { + "pair": [ + "BTC", + "ZIL" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.001 + } + }, + { + "pair": [ + "ETH", + "ZIL" + ], + "minimalOrder": { + "amount": 1, + "price": 1e-8, + "order": 0.01 + } + }, + { + "pair": [ + "USDT", + "BNB" + ], + "minimalOrder": { + "amount": 0.01, + "price": 0.0001, + "order": 10 + } + }, + { + "pair": [ + "USDT", + "ETH" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.01, + "order": 10 + } + } + ] +} \ No newline at end of file diff --git a/exchanges/binance.js b/exchanges/binance.js index 9cec0855d..3aebc7522 100644 --- a/exchanges/binance.js +++ b/exchanges/binance.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const util = require('../core/util'); const Errors = require('../core/error'); const log = require('../core/log'); +const marketData = require('./binance-markets.json'); const Binance = require('binance'); @@ -20,12 +21,17 @@ var Trader = function(config) { this.pair = this.asset + this.currency; this.name = 'binance'; + this.market = _.find(Trader.getCapabilities().markets, (market) => { + return market.pair[0] === this.currency && market.pair[1] === this.asset + }); + this.binance = new Binance.BinanceRest({ key: this.key, secret: this.secret, timeout: 15000, recvWindow: 60000, // suggested by binance - disableBeautification: false + disableBeautification: false, + handleDrift: true, }); }; @@ -43,17 +49,17 @@ var retryForever = { maxTimeout: 30 * 1000 }; -var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|Error -1021|Response code 429)/); +var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|Error -1021|Response code 429|Response code 5)/); Trader.prototype.processError = function(funcName, error) { if (!error) return undefined; if (!error.message || !error.message.match(recoverableErrors)) { - log.error(`[binance.js] (${funcName}) returned an irrecoverable error: ${error.message}`); + log.error(`[binance.js] (${funcName}) returned an irrecoverable error: ${error}`); return new Errors.AbortError('[binance.js] ' + error.message || error); } - log.debug(`[binance.js] (${funcName}) returned an error, retrying: ${error.message}`); + log.debug(`[binance.js] (${funcName}) returned an error, retrying: ${error}`); return new Errors.RetryError('[binance.js] ' + error.message || error); }; @@ -109,7 +115,7 @@ Trader.prototype.getTrades = function(since, callback, descending) { Trader.prototype.getPortfolio = function(callback) { var setBalance = function(err, data) { - log.debug(`[binance.js] entering "setBalance" callback after api call, err: ${err}, data: ${data}`) + log.debug(`[binance.js] entering "setBalance" callback after api call, err: ${err} data: ${JSON.stringify(data)}`) if (err) return callback(err); var findAsset = function(item) { @@ -156,7 +162,7 @@ Trader.prototype.getFee = function(callback) { Trader.prototype.getTicker = function(callback) { var setTicker = function(err, data) { - log.debug(`[binance.js] entering "getTicker" callback after api call, err: ${err} data: ${JSON.stringify(data)}`); + log.debug(`[binance.js] entering "getTicker" callback after api call, err: ${err} data: ${(data || []).length} symbols`); if (err) return callback(err); var findSymbol = function(ticker) { @@ -197,14 +203,22 @@ Trader.prototype.roundAmount = function(amount, tickSize) { return amount; }; -Trader.prototype.addOrder = function(tradeType, amount, price, callback) { - var findMarket = function(market) { - return market.pair[0] === this.currency && market.pair[1] === this.asset - } - var market = _.find(Trader.getCapabilities().markets, _.bind(findMarket, this)); - amount = Math.max(this.roundAmount(amount, market.minimalOrder.amount), market.minimalOrder.amount); - price = Math.max(this.roundAmount(price, market.precision), market.precision); +Trader.prototype.getLotSize = function(tradeType, amount, price, callback) { + amount = this.roundAmount(amount, this.market.minimalOrder.amount); + if (amount < this.market.minimalOrder.amount) + return callback(undefined, { amount: 0, price: 0 }); + + price = this.roundAmount(price, this.market.minimalOrder.price) + if (price < this.market.minimalOrder.price) + return callback(undefined, { amount: 0, price: 0 }); + if (amount * price < this.market.minimalOrder.order) + return callback(undefined, { amount: 0, price: 0}); + + callback(undefined, { amount: amount, price: price }); +} + +Trader.prototype.addOrder = function(tradeType, amount, price, callback) { log.debug(`[binance.js] (addOrder) ${tradeType.toUpperCase()} ${amount} ${this.asset} @${price} ${this.currency}`); var setOrder = function(err, data) { @@ -238,7 +252,10 @@ Trader.prototype.getOrder = function(order, callback) { var price = parseFloat(data.price); var amount = parseFloat(data.executedQty); - var date = moment.unix(data.time); + + // Data.time is a 13 digit millisecon unix time stamp. + // https://momentjs.com/docs/#/parsing/unix-timestamp-milliseconds/ + var date = moment(data.time); callback(undefined, { price, amount, date }); }.bind(this); @@ -266,7 +283,8 @@ Trader.prototype.checkOrder = function(order, callback) { if (err) return callback(err); var stillThere = data.status === 'NEW' || data.status === 'PARTIALLY_FILLED'; - callback(undefined, !stillThere); + var canceledManually = data.status === 'CANCELED' || data.status === 'REJECTED' || data.status === 'EXPIRED'; + callback(undefined, !stillThere && !canceledManually); }; let reqData = { @@ -279,10 +297,15 @@ Trader.prototype.checkOrder = function(order, callback) { }; Trader.prototype.cancelOrder = function(order, callback) { - var args = _.toArray(arguments); + // callback for cancelOrder should be true if the order was already filled, otherwise false var cancel = function(err, data) { log.debug(`[binance.js] entering "cancelOrder" callback after api call, err ${err} data: ${JSON.stringify(data)}`); - if (err) return callback(err); + if (err) { + if(data && data.msg === 'UNKNOWN_ORDER') { // this seems to be the response we get when an order was filled + return callback(true); // tell the thing the order was already filled + } + return callback(err); + } callback(undefined); }; @@ -295,1158 +318,17 @@ Trader.prototype.cancelOrder = function(order, callback) { util.retryCustom(retryForever, _.bind(handler, this), _.bind(cancel, this)); }; +Trader.prototype.initMarkets = function(callback) { + +} + Trader.getCapabilities = function() { return { name: 'Binance', slug: 'binance', - currencies: ['BTC', 'BNB', 'ETH', 'USDT'], - assets: [ - 'ADA', - 'ADX', - 'AMB', - 'ARK', - 'ARN', - 'AST', - 'BAT', - 'BCC', - 'BCD', - 'BCPT', - 'BNB', - 'BNT', - 'BTC', - 'BQX', - 'BTG', - 'BTS', - 'CDT', - 'CMT', - 'CND', - 'CTR', - 'DASH', - 'DGD', - 'DLT', - 'DNT', - 'ELF', - 'ENG', - 'ENJ', - 'EOS', - 'ETC', - 'ETH', - 'EVX', - 'FUEL', - 'FUN', - 'GAS', - 'GTO', - 'GVT', - 'GXS', - 'HSR', - 'ICN', - 'ICX', - 'IOTA', - 'KMD', - 'KNC', - 'LEND', - 'LINK', - 'LRC', - 'LSK', - 'LTC', - 'MANA', - 'MCO', - 'MDA', - 'MOD', - 'MTH', - 'MTL', - 'NEO', - 'NULS', - 'OAX', - 'OMG', - 'OST', - 'POE', - 'POWR', - 'PPT', - 'QSP', - 'QTUM', - 'RCN', - 'RDN', - 'REQ', - 'SALT', - 'SNGLS', - 'SNM', - 'SNT', - 'STORJ', - 'STRAT', - 'SUB', - 'TNB', - 'TNT', - 'TRX', - 'VEN', - 'VIB', - 'WABI', - 'WAVES', - 'WTC', - 'XLM', - 'XMR', - 'XRP', - 'XVG', - 'XZC', - 'YOYO', - 'ZEC', - 'ZRX', - ], - markets: [ - // https://www.binance.com/exchange/public/product - - //Tradeable againt BTC - { - pair: ['BTC', 'ETH'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'LTC'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'BNB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'NEO'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'GAS'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'BCC'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'MCO'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'WTC'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'QTUM'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'OMG'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'ZRX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'STRAT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'SNGLS'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'BQX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'KNC'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'FUN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'SNM'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'LINK'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'XVG'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'CTR'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'SALT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'IOTA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'MDA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'MTL'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'SUB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'EOS'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'SNT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'ETC'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'MTH'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'ENG'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'DNT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'BNT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'AST'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'DASH'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'ICN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'OAX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'BTG'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'EVX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'REQ'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'LRC'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'VIB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'HSR'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'TRX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'POWR'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'ARK'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'YOYO'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'XRP'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'MOD'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'ENJ'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'STORJ'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'VEN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'KMD'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'RCN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'NULS'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'RDN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'XMR'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'DLT'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'AMB'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'BAT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'ZEC'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'BCPT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'ARN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'GVT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'CDT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'GXS'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'POE'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'QSP'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'BTS'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'XZC'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'LSK'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'TNT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'FUEL'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'MANA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'BCD'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'DGD'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'ADX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'ADA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'PPT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'CMT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'XLM'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'CND'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'LEND'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'WABI'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'TNB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'WAVES'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['BTC', 'ICX'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['BTC', 'GTO'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'OST'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BTC', 'ELF'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'BNB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'QTUM'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'SNT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'BNT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'EOS'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'OAX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'DNT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'MCO'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'ICN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'WTC'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'OMG'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'ZRX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'STRAT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'SNGLS'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'BQX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'KNC'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'FUN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'SNM'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'NEO'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'LINK'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'XVG'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'CTR'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'SALT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'IOTA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'MDA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'MTL'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'SUB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'ETC'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'MTH'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'ENG'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'AST'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'DASH'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['ETH', 'BTG'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'EVX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'REQ'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'LRC'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'VIB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'HSR'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'TRX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'POWR'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'ARK'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'YOYO'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'XRP'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'MOD'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'ENJ'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'STORJ'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'VEN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'KMD'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'RCN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'NULS'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'RDN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'XMR'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['ETH', 'DLT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'AMB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'BCC'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['ETH', 'BAT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'ZEC'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['ETH', 'BCPT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'ARN'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'GVT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'CDT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'GXS'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'POE'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'QSP'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'BTS'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'XZC'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'LSK'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'TNT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'FUEL'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'MANA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'BCD'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['ETH', 'DGD'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['ETH', 'ADX'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.0000001, - }, - { - pair: ['ETH', 'ADA'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'PPT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'CMT'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'XLM'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'CND'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'LEND'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'WABI'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'LTC'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['ETH', 'TNB'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'WAVES'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'ICX'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.000001, - }, - { - pair: ['ETH', 'GTO'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'OST'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['ETH', 'ELF'], - minimalOrder: { amount: 1, unit: 'asset' }, - precision: 0.00000001, - }, - { - pair: ['BNB', 'VEN'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0001, - }, - { - pair: ['BNB', 'YOYO'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'POWR'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0001, - }, - { - pair: ['BNB', 'NULS'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'RCN'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'RDN'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'DLT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'WTC'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'AMB'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'BCC'], - minimalOrder: { amount: 0.00001, unit: 'asset' }, - precision: 0.01, - }, - { - pair: ['BNB', 'BAT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'BCPT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'NEO'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.001, - }, - { - pair: ['BNB', 'QSP'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'BTS'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'XZC'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.001, - }, - { - pair: ['BNB', 'LSK'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.0001, - }, - { - pair: ['BNB', 'IOTA'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'ADX'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'CMT'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'XLM'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'CND'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'WABI'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'LTC'], - minimalOrder: { amount: 0.00001, unit: 'asset' }, - precision: 0.01, - }, - { - pair: ['BNB', 'WAVES'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0001, - }, - { - pair: ['BNB', 'ICX'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'GTO'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['BNB', 'OST'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.00001, - }, - { - pair: ['USDT', 'BTC'], - minimalOrder: { amount: 0.000001, unit: 'asset' }, - precision: 0.01, - }, - { - pair: ['USDT', 'ETH'], - minimalOrder: { amount: 0.00001, unit: 'asset' }, - precision: 0.01, - }, - { - pair: ['USDT', 'BNB'], - minimalOrder: { amount: 0.01, unit: 'asset' }, - precision: 0.0001, - }, - { - pair: ['USDT', 'BCC'], - minimalOrder: { amount: 0.00001, unit: 'asset' }, - precision: 0.01, - }, - { - pair: ['USDT', 'NEO'], - minimalOrder: { amount: 0.001, unit: 'asset' }, - precision: 0.001, - }, - { - pair: ['USDT', 'LTC'], - minimalOrder: { amount: 0.00001, unit: 'asset' }, - precision: 0.01, - }, - ], + currencies: marketData.currencies, + assets: marketData.assets, + markets: marketData.markets, requires: ['key', 'secret'], providesHistory: 'date', providesFullHistory: true, diff --git a/exchanges/bitcoin-co-id.js b/exchanges/bitcoin-co-id.js index bda3696e8..d5eca6d78 100644 --- a/exchanges/bitcoin-co-id.js +++ b/exchanges/bitcoin-co-id.js @@ -1,4 +1,4 @@ -var Bitcoincoid = require('bitcoin-co-id'), +var Bitcoincoid = require('bitcoin-co-id-update'), _ = require('lodash'), moment = require('moment'), log = require('../core/log'); diff --git a/exchanges/bitfinex-markets.json b/exchanges/bitfinex-markets.json new file mode 100644 index 000000000..f8f0bb43e --- /dev/null +++ b/exchanges/bitfinex-markets.json @@ -0,0 +1,1100 @@ +{ + "assets": [ + "BTC", + "LTC", + "ETH", + "ETC", + "RRT", + "ZEC", + "XMR", + "DSH", + "XRP", + "IOT", + "EOS", + "SAN", + "OMG", + "BCH", + "NEO", + "ETP", + "QTM", + "AVT", + "EDO", + "BTG", + "DAT", + "QSH", + "YYW", + "GNT", + "SNT", + "BAT", + "MNA", + "FUN", + "ZRX", + "TNB", + "SPK", + "TRX", + "RCN", + "RLC", + "AID", + "SNG", + "REP", + "ELF" + ], + "currencies": [ + "USD", + "BTC", + "EUR", + "ETH" + ], + "markets": [ + { + "pair": [ + "USD", + "BTC" + ], + "minimalOrder": { + "amount": "0.002", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "LTC" + ], + "minimalOrder": { + "amount": "0.08", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "LTC" + ], + "minimalOrder": { + "amount": "0.08", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "ETH" + ], + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "ETH" + ], + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "ETC" + ], + "minimalOrder": { + "amount": "0.6", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "ETC" + ], + "minimalOrder": { + "amount": "0.6", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "RRT" + ], + "minimalOrder": { + "amount": "130.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "RRT" + ], + "minimalOrder": { + "amount": "130.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "ZEC" + ], + "minimalOrder": { + "amount": "0.04", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "ZEC" + ], + "minimalOrder": { + "amount": "0.04", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "XMR" + ], + "minimalOrder": { + "amount": "0.06", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "XMR" + ], + "minimalOrder": { + "amount": "0.06", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "DSH" + ], + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "DSH" + ], + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + } + }, + { + "pair": [ + "EUR", + "BTC" + ], + "minimalOrder": { + "amount": "0.002", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "XRP" + ], + "minimalOrder": { + "amount": "12.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "XRP" + ], + "minimalOrder": { + "amount": "12.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "IOT" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "IOT" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "IOT" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "EOS" + ], + "minimalOrder": { + "amount": "2.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "EOS" + ], + "minimalOrder": { + "amount": "2.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "EOS" + ], + "minimalOrder": { + "amount": "2.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "SAN" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "SAN" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "SAN" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "OMG" + ], + "minimalOrder": { + "amount": "1.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "OMG" + ], + "minimalOrder": { + "amount": "1.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "OMG" + ], + "minimalOrder": { + "amount": "1.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "BCH" + ], + "minimalOrder": { + "amount": "0.008", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "BCH" + ], + "minimalOrder": { + "amount": "0.008", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "BCH" + ], + "minimalOrder": { + "amount": "0.008", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "NEO" + ], + "minimalOrder": { + "amount": "0.2", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "NEO" + ], + "minimalOrder": { + "amount": "0.2", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "NEO" + ], + "minimalOrder": { + "amount": "0.2", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "ETP" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "ETP" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "ETP" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "QTM" + ], + "minimalOrder": { + "amount": "0.4", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "QTM" + ], + "minimalOrder": { + "amount": "0.4", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "QTM" + ], + "minimalOrder": { + "amount": "0.4", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "AVT" + ], + "minimalOrder": { + "amount": "4.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "AVT" + ], + "minimalOrder": { + "amount": "4.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "AVT" + ], + "minimalOrder": { + "amount": "4.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "EDO" + ], + "minimalOrder": { + "amount": "4.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "EDO" + ], + "minimalOrder": { + "amount": "4.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "EDO" + ], + "minimalOrder": { + "amount": "4.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "BTG" + ], + "minimalOrder": { + "amount": "0.08", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "BTG" + ], + "minimalOrder": { + "amount": "0.08", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "DAT" + ], + "minimalOrder": { + "amount": "80.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "DAT" + ], + "minimalOrder": { + "amount": "80.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "DAT" + ], + "minimalOrder": { + "amount": "80.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "QSH" + ], + "minimalOrder": { + "amount": "10.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "QSH" + ], + "minimalOrder": { + "amount": "10.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "QSH" + ], + "minimalOrder": { + "amount": "10.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "YYW" + ], + "minimalOrder": { + "amount": "62.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "YYW" + ], + "minimalOrder": { + "amount": "62.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "YYW" + ], + "minimalOrder": { + "amount": "62.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "GNT" + ], + "minimalOrder": { + "amount": "28.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "GNT" + ], + "minimalOrder": { + "amount": "28.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "GNT" + ], + "minimalOrder": { + "amount": "28.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "SNT" + ], + "minimalOrder": { + "amount": "56.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "SNT" + ], + "minimalOrder": { + "amount": "56.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "SNT" + ], + "minimalOrder": { + "amount": "56.0", + "unit": "asset" + } + }, + { + "pair": [ + "EUR", + "IOT" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "BAT" + ], + "minimalOrder": { + "amount": "24.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "BAT" + ], + "minimalOrder": { + "amount": "24.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "BAT" + ], + "minimalOrder": { + "amount": "24.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "MNA" + ], + "minimalOrder": { + "amount": "108.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "MNA" + ], + "minimalOrder": { + "amount": "108.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "MNA" + ], + "minimalOrder": { + "amount": "108.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "FUN" + ], + "minimalOrder": { + "amount": "190.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "FUN" + ], + "minimalOrder": { + "amount": "190.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "FUN" + ], + "minimalOrder": { + "amount": "190.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "ZRX" + ], + "minimalOrder": { + "amount": "8.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "ZRX" + ], + "minimalOrder": { + "amount": "8.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "ZRX" + ], + "minimalOrder": { + "amount": "8.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "TNB" + ], + "minimalOrder": { + "amount": "134.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "TNB" + ], + "minimalOrder": { + "amount": "134.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "TNB" + ], + "minimalOrder": { + "amount": "134.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "SPK" + ], + "minimalOrder": { + "amount": "48.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "SPK" + ], + "minimalOrder": { + "amount": "48.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "SPK" + ], + "minimalOrder": { + "amount": "48.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "TRX" + ], + "minimalOrder": { + "amount": "238.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "TRX" + ], + "minimalOrder": { + "amount": "238.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "TRX" + ], + "minimalOrder": { + "amount": "238.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "RCN" + ], + "minimalOrder": { + "amount": "52.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "RCN" + ], + "minimalOrder": { + "amount": "52.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "RCN" + ], + "minimalOrder": { + "amount": "52.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "RLC" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "RLC" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "RLC" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "AID" + ], + "minimalOrder": { + "amount": "38.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "AID" + ], + "minimalOrder": { + "amount": "38.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "AID" + ], + "minimalOrder": { + "amount": "38.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "SNG" + ], + "minimalOrder": { + "amount": "56.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "SNG" + ], + "minimalOrder": { + "amount": "56.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "SNG" + ], + "minimalOrder": { + "amount": "56.0", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "REP" + ], + "minimalOrder": { + "amount": "0.2", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "REP" + ], + "minimalOrder": { + "amount": "0.2", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "REP" + ], + "minimalOrder": { + "amount": "0.2", + "unit": "asset" + } + }, + { + "pair": [ + "USD", + "ELF" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "BTC", + "ELF" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + }, + { + "pair": [ + "ETH", + "ELF" + ], + "minimalOrder": { + "amount": "6.0", + "unit": "asset" + } + } + ] +} \ No newline at end of file diff --git a/exchanges/bitfinex.js b/exchanges/bitfinex.js index 0777e5e5e..bd22bd4ff 100644 --- a/exchanges/bitfinex.js +++ b/exchanges/bitfinex.js @@ -7,6 +7,8 @@ const util = require('../core/util'); const Errors = require('../core/error'); const log = require('../core/log'); +const marketData = require('./bitfinex-markets.json'); + var Trader = function(config) { _.bindAll(this); if(_.isObject(config)) { @@ -37,7 +39,7 @@ var retryForever = { }; // Probably we need to update these string -var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|StatusCodeError: 429|StatusCodeError: 5)/) +var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|429|443|5\d\d)/g); Trader.prototype.processError = function(funcName, error) { if (!error) return undefined; @@ -176,10 +178,10 @@ Trader.prototype.cancelOrder = function(order_id, callback) { let process = (err, data) => { if (err) return callback(err); - return callback(); + return callback(undefined); } - let handler = (cb) => this.bitfinex.order_status(order_id, this.handleResponse('cancelOrder', cb)); + let handler = (cb) => this.bitfinex.cancel_order(order_id, this.handleResponse('cancelOrder', cb)); util.retryCustom(retryForever, _.bind(handler, this), _.bind(process, this)); } @@ -211,57 +213,15 @@ Trader.getCapabilities = function () { return { name: 'Bitfinex', slug: 'bitfinex', - currencies: ['USD', 'BTC', 'ETH'], - assets: ['BTC', 'LTC', 'ETH', 'SAN', 'IOT', 'BCH', 'OMG', 'XMR', 'DSH', 'ZEC', 'EOS', 'ETC', 'XRP', 'NEO', 'ETP'], - markets: [ - - //Tradeable Pairs to USD - { pair: ['USD', 'BTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'BCH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'IOT'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'OMG'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'EOS'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'DSH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'SAN'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'ZEC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'XMR'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'ETC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'XRP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'NEO'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'ETP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - - //Tradeable Pairs to BTC - { pair: ['BTC', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'BCH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'IOT'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'OMG'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'DSH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'ZEC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'XMR'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'SAN'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'EOS'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'ETC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'XRP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'NEO'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'ETP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - - //Tradeable Pairs to ETH - { pair: ['ETH', 'BCH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['ETH', 'IOT'], minimalOrder: { amount: 6.00, unit: 'asset' } }, - { pair: ['ETH', 'OMG'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['ETH', 'SAN'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['ETH', 'EOS'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['ETH', 'NEO'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['ETH', 'ETP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - - ], + currencies: marketData.currencies, + assets: marketData.assets, + markets: marketData.markets, requires: ['key', 'secret'], tid: 'tid', providesFullHistory: true, - tradable: true + providesHistory: 'date', + tradable: true, + forceReorderDelay: true }; } diff --git a/exchanges/bitstamp.js b/exchanges/bitstamp.js index 99844b324..6c5717306 100644 --- a/exchanges/bitstamp.js +++ b/exchanges/bitstamp.js @@ -87,6 +87,9 @@ Trader.prototype.getFee = function(callback) { } Trader.prototype.buy = function(amount, price, callback) { + var findMarket = function(pair) { + return pair.pair[0].toLowerCase() === this.currency && pair.pair[1].toLowerCase() === this.asset + } var args = _.toArray(arguments); var set = function(err, result) { if(err || result.status === "error") { @@ -98,22 +101,19 @@ Trader.prototype.buy = function(amount, price, callback) { }.bind(this); //Decrease amount by 1% to avoid trying to buy more than balance allows. - amount -= amount / 100; - - amount *= 100000000; - amount = Math.floor(amount); - amount /= 100000000; + amount = Number(amount * 0.99).toFixed(8); - // prevent: - // 'Ensure that there are no more than 2 decimal places.' - price *= 100; - price = Math.floor(price); - price /= 100; + // Use proper precision by currency pair + var pair = _.find(Trader.getCapabilities().markets, _.bind(findMarket, this)); + price = Number(Number.parseFloat(price).toFixed(pair.precision)); this.bitstamp.buy(this.market, amount, price, undefined, set); } Trader.prototype.sell = function(amount, price, callback) { + var findMarket = function(pair) { + return pair.pair[0].toLowerCase() === this.currency && pair.pair[1].toLowerCase() === this.asset + } var args = _.toArray(arguments); var set = function(err, result) { if(err || result.status === "error") { @@ -126,15 +126,11 @@ Trader.prototype.sell = function(amount, price, callback) { // prevent: // 'Ensure that there are no more than 8 decimal places.' - amount *= 100000000; - amount = Math.floor(amount); - amount /= 100000000; + amount = Number(Number.parseFloat(amount)).toFixed(8); - // prevent: - // 'Ensure that there are no more than 2 decimal places.' - price *= 100; - price = Math.ceil(price); - price /= 100; + // Use proper precision by currency pair + var pair = _.find(Trader.getCapabilities().markets, _.bind(findMarket, this)); + price = Number(Number.parseFloat(price).toFixed(pair.precision)); this.bitstamp.sell(this.market, amount, price, undefined, set); } @@ -167,7 +163,7 @@ Trader.prototype.getOrder = function(id, callback) { }); } - var price = parseFloat( order[this.market] ); + var price = parseFloat( order[`${this.asset}_${this.currency}`] ); var amount = Math.abs(parseFloat( order[this.asset] )); var date = moment( order.datetime ); @@ -234,26 +230,26 @@ Trader.getCapabilities = function () { maxTradesAge: 60, maxHistoryFetch: null, markets: [ - { pair: ['USD', 'EUR'], minimalOrder: { amount: 5, unit: 'currency' } }, + { pair: ['USD', 'EUR'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, - { pair: ['USD', 'BTC'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['EUR', 'BTC'], minimalOrder: { amount: 5, unit: 'currency' } }, + { pair: ['USD', 'BTC'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, + { pair: ['EUR', 'BTC'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, - { pair: ['USD', 'BCH'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['EUR', 'BCH'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['BTC', 'BCH'], minimalOrder: { amount: 0.001, unit: 'currency' } }, + { pair: ['USD', 'BCH'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, + { pair: ['EUR', 'BCH'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, + { pair: ['BTC', 'BCH'], minimalOrder: { amount: 0.001, unit: 'currency'}, precision: 8 }, - { pair: ['USD', 'XRP'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['EUR', 'XRP'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['BTC', 'XRP'], minimalOrder: { amount: 0.001, unit: 'currency' } }, + { pair: ['USD', 'XRP'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 5 }, + { pair: ['EUR', 'XRP'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 5 }, + { pair: ['BTC', 'XRP'], minimalOrder: { amount: 0.001, unit: 'currency'}, precision: 8 }, - { pair: ['USD', 'LTC'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['EUR', 'LTC'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['BTC', 'LTC'], minimalOrder: { amount: 0.001, unit: 'currency' } }, + { pair: ['USD', 'LTC'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, + { pair: ['EUR', 'LTC'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, + { pair: ['BTC', 'LTC'], minimalOrder: { amount: 0.001, unit: 'currency'}, precision: 8 }, - { pair: ['USD', 'ETH'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['EUR', 'ETH'], minimalOrder: { amount: 5, unit: 'currency' } }, - { pair: ['BTC', 'ETH'], minimalOrder: { amount: 0.001, unit: 'currency' } }, + { pair: ['USD', 'ETH'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, + { pair: ['EUR', 'ETH'], minimalOrder: { amount: 5, unit: 'currency' }, precision: 2 }, + { pair: ['BTC', 'ETH'], minimalOrder: { amount: 0.001, unit: 'currency'}, precision: 8 }, ], requires: ['key', 'secret', 'username'], fetchTimespan: 60, diff --git a/exchanges/coinfalcon-markets.json b/exchanges/coinfalcon-markets.json new file mode 100644 index 000000000..ee1ae672c --- /dev/null +++ b/exchanges/coinfalcon-markets.json @@ -0,0 +1,669 @@ +{ + "assets": [ + "IOT", + "ETH", + "LTC", + "BTC", + "XRB", + "BCH", + "TAU", + "CRED", + "KIN", + "SPHTX", + "TRX", + "VEN", + "CRPT", + "GNT", + "DCN", + "REBL", + "VIU", + "EBTC", + "TRAC", + "CHSB", + "GRLC", + "ECA", + "XRP", + "WPR", + "XBY", + "WAX", + "DADI", + "REF", + "ADA", + "LDN", + "DOGE" + ], + "currencies": [ + "BTC", + "EUR", + "ETH" + ], + "markets": [ + { + "pair": [ + "BTC", + "IOT" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "ETH" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.00001, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "LTC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.00001, + "order": 0 + } + }, + { + "pair": [ + "EUR", + "BTC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.01, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "XRB" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "XRB" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "BCH" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 0.00001, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "TAU" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "TAU" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "CRED" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 0.000001, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "CRED" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 0.000001, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "KIN" + ], + "minimalOrder": { + "amount": 0.1, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "KIN" + ], + "minimalOrder": { + "amount": 0.1, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "SPHTX" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "SPHTX" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "TRX" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "TRX" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "VEN" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "VEN" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "CRPT" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "CRPT" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "GNT" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "GNT" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "DCN" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "DCN" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "REBL" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "REBL" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "VIU" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "EBTC" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "EBTC" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "TRAC" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "TRAC" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "CHSB" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "CHSB" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "GRLC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "GRLC" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "ECA" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "ECA" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "XRP" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "XRP" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "WPR" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "WPR" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "XBY" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "XBY" + ], + "minimalOrder": { + "amount": 0.01, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "WAX" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "WAX" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "DADI" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "DADI" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "REF" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "REF" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "ADA" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "ADA" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "LDN" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "LDN" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "BTC", + "DOGE" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "IOT" + ], + "minimalOrder": { + "amount": 0.000001, + "price": 1e-8, + "order": 0 + } + }, + { + "pair": [ + "ETH", + "DOGE" + ], + "minimalOrder": { + "amount": 0.00001, + "price": 1e-8, + "order": 0 + } + } + ] +} \ No newline at end of file diff --git a/exchanges/coinfalcon.js b/exchanges/coinfalcon.js index e7cc12dc4..6523e45b1 100644 --- a/exchanges/coinfalcon.js +++ b/exchanges/coinfalcon.js @@ -2,6 +2,7 @@ const moment = require('moment'); const util = require('../core/util'); const _ = require('lodash'); const log = require('../core/log'); +const marketData = require('./coinfalcon-markets.json'); const CoinFalcon = require('coinfalcon'); @@ -236,18 +237,9 @@ Trader.getCapabilities = function () { return { name: 'CoinFalcon', slug: 'coinfalcon', - currencies: ['EUR', 'BTC'], - assets: ['BTC', 'LTC', 'ETH', 'IOT', 'BCH'], - markets: [ - // Euro pairs - { pair: ['EUR', 'BTC'], minimalOrder: { amount: 0.0, unit: 'asset' } }, - { pair: ['EUR', 'ETH'], minimalOrder: { amount: 0.0, unit: 'asset' } }, - // Bitcoin pairs - { pair: ['BTC', 'ETH'], minimalOrder: { amount: 0.0, unit: 'asset' } }, - { pair: ['BTC', 'LTC'], minimalOrder: { amount: 0.0, unit: 'asset' } }, - { pair: ['BTC', 'IOT'], minimalOrder: { amount: 0.0, unit: 'asset' } }, - { pair: ['BTC', 'BCH'], minimalOrder: { amount: 0.0, unit: 'asset' } } - ], + assets: marketData.assets, + currencies: marketData.currencies, + markets: marketData.markets, requires: ['key', 'secret'], providesHistory: 'date', providesFullHistory: true, diff --git a/exchanges/coingi.js b/exchanges/coingi.js new file mode 100755 index 000000000..8ebd062c3 --- /dev/null +++ b/exchanges/coingi.js @@ -0,0 +1,283 @@ +var Coingi = require('coingi'); +var moment = require('moment'); +var _ = require('lodash'); + +var util = require('../core/util'); +var Errors = require('../core/error'); +var log = require('../core/log'); + + +var Trader = function (config) { + _.bindAll(this); + + if (_.isObject(config)) { + this.key = config.key; + this.secret = config.secret; + this.currency = config.currency.toUpperCase() + this.asset = config.asset.toUpperCase(); + } + + this.pair = this.asset + "-" + this.currency; + this.name = 'coingi'; + this.since = null; + + this.coingi = new Coingi( + this.key, + this.secret, + {timeout: +moment.duration(60, 'seconds')} + ); +} + +var retryCritical = { + retries: 10, + factor: 1.2, + minTimeout: 1 * 1000, + maxTimeout: 30 * 1000 +}; + +var retryForever = { + forever: true, + factor: 1.2, + minTimeout: 10, + maxTimeout: 30 +}; + +var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|API:Invalid nonce|Service:Unavailable|Request timed out|Response code 520|Response code 504|Response code 502)/) + +Trader.prototype.processError = function (funcName, error) { + if (!error) + return undefined; + + if (!error.message.match(recoverableErrors)) { + log.error(`[coingi.js] (${funcName}) returned an irrecoverable error: ${error.message}`); + return new Errors.AbortError('[coingi.js] ' + error.message); + } + + log.debug(`[coingi.js] (${funcName}) returned an error, retrying: ${error.message}`); + return new Errors.RetryError('[coingi.js] ' + error.message); +}; + +Trader.prototype.handleResponse = function (funcName, callback) { + return (error, body) => { + if (!error) { + if (_.isEmpty(body)) + error = new Error('NO DATA WAS RETURNED'); + + else if (!_.isEmpty(body.error)) + error = new Error(body.error); + } + + return callback(this.processError(funcName, error), body); + } +}; + + + + +/* PORTFOLIO MANAGER */ + +Trader.prototype.getTicker = function (callback) { + var setTicker = function (err, data) { + if (err) + return callback(err); + + var ticker = { + ask: data.asks[0].price, + bid: data.bids[0].price + }; + callback(undefined, ticker); + }; + + let handler = (cb) => this.coingi.api('order-book', "/" + this.pair + "/1/1/1", this.handleResponse('getTicker', cb)); + util.retryCustom(retryForever, _.bind(handler, this), _.bind(setTicker, this)); +}; + + +Trader.prototype.getTrades = function (since, callback, ascending) { + var startTs = since ? moment(since).valueOf() : null; + + var processResults = function (err, trades) { + if (err) { + return callback(err); + } + + var parsedTrades = []; + _.each(trades, function (trade) { + // Even when you supply 'since' you can still get more trades than you asked for, it needs to be filtered + if (_.isNull(startTs) || startTs < moment(trade.timestamp).valueOf()) { + parsedTrades.push({ + type: trade.type === 0 ? "sell" : "buy", + date: moment(trade.timestamp).unix(), + amount: String(trade.amount), + price: String(trade.price), + tid: trade.timestamp + }); + } + }, this); + + if(ascending) + callback(undefined, parsedTrades); + else + callback(undefined, parsedTrades.reverse()); + }; + + var optionalSince = ""; + if (since) { + optionalSince = "/" + startTs; + } + + let handler = (cb) => this.coingi.api('transactions', "/" + this.pair + "/512" + optionalSince, this.handleResponse('getTrades', cb)); + util.retryCustom(retryForever, _.bind(handler, this), _.bind(processResults, this)); +}; + +Trader.prototype.getPortfolio = function (callback) { + var setBalance = function (err, data) { + if (err) + return callback(err); + + log.debug('[coingi.js] entering "setBalance" callback after coingi-api call, data:', data); + + const portfolio = []; + for (var i = 0; i < data.length; i++) { + portfolio.push({ + name: data[i].currency.name.toUpperCase(), + amount: data[i].available + }); + } + + return callback(undefined, portfolio); + }; + + let handler = (cb) => this.coingi.api('balance', {currencies: this.asset + "," + this.currency}, this.handleResponse('getPortfolio', cb)); + util.retryCustom(retryForever, _.bind(handler, this), _.bind(setBalance, this)); +}; + +// Base fee is 0.2% +Trader.prototype.getFee = function (callback) { + const fee = 0.2; + callback(undefined, fee / 100); +}; + +Trader.prototype.addOrder = function (tradeType, amount, price, callback) { + log.debug('[coingi.js] (add-order)', tradeType.toUpperCase(), amount, this.asset, '@', price, this.currency); + + var setOrder = function (err, data) { + if (err) + return callback(err); + + var uuid = data.result; + log.debug('[coingi.js] (addOrder) added order with uuid:', uuid); + + callback(undefined, uuid); + }; + + let reqData = { + currencyPair: this.pair, + type: tradeType.toLowerCase() === "sell" ? 0 : 1, + price: price, + volume: amount.toString() + }; + + let handler = (cb) => this.coingi.api('add-order', reqData, this.handleResponse('addOrder', cb)); + util.retryCustom(retryCritical, _.bind(handler, this), _.bind(setOrder, this)); +}; + + +Trader.prototype.getOrder = function (orderId, callback) { + var getOrder = function (err, order) { + if (err) + return callback(err); + + if (order !== null) { + const price = parseFloat(order.price); + const amount = parseFloat(order.baseAmount); + const date = moment.unix(order.timestamp); + callback(undefined, {price, amount, date}); + } else { + log.error("Error! Order ID '" + orderId + "' couldn't be found in the result of get order!"); + } + }; + + let reqData = {ordeId: orderId}; + let handler = (cb) => this.coingi.api('get-order', reqData, this.handleResponse('getOrder', cb)); + util.retryCustom(retryCritical, _.bind(handler, this), _.bind(getOrder, this)); +} + +Trader.prototype.buy = function (amount, price, callback) { + this.addOrder('buy', amount, price, callback); +}; + +Trader.prototype.sell = function (amount, price, callback) { + this.addOrder('sell', amount, price, callback); +}; + +Trader.prototype.checkOrder = function (orderId, callback) { + var check = function (err, order) { + if (err) + return callback(err); + + if (order === null) { + log.error("Error! Order ID '" + orderId + "' couldn't be found in the result of get order!"); + } + // returns true when the order has been filled (processed in full), false otherwise + callback(undefined, order !== null && order.status === 2); + }; + + let reqData = {orderId: orderId}; + let handler = (cb) => this.coingi.api('get-order', reqData, this.handleResponse('checkOrder', cb)); + util.retryCustom(retryCritical, _.bind(handler, this), _.bind(check, this)); +}; + +Trader.prototype.cancelOrder = function (order, callback) { + let reqData = {orderId: order}; + let handler = (cb) => this.coingi.api('cancel-order', reqData, this.handleResponse('cancelOrder', cb)); + util.retryCustom(retryForever, _.bind(handler, this), callback); +}; + +Trader.getCapabilities = function () { + return { + name: 'Coingi', + slug: 'coingi', + currencies: ['EUR', 'USD', 'BTC'], + assets: ['BTC', 'DASH', 'DOGE', 'EUR', 'LTC', 'NMC', 'PPC', 'VTC'], + markets: [ + // Tradeable against BTC + {pair: ['USD', 'BTC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + {pair: ['EUR', 'BTC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + + // Tradeable against DASH + {pair: ['BTC', 'DASH'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + + // Tradeable against DOGE + {pair: ['BTC', 'DOGE'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + {pair: ['USD', 'DOGE'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + + // Tradeable against EUR + {pair: ['USD', 'EUR'], minimalOrder: {amount: 0.01, unit: 'asset'}, precision: 2}, + + // Tradeable against LTC + {pair: ['BTC', 'LTC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + {pair: ['EUR', 'LTC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + {pair: ['USD', 'LTC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + + // Tradeable against NMC + {pair: ['BTC', 'NMC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + + // Tradeable against PPC + {pair: ['USD', 'PPC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + {pair: ['EUR', 'PPC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + {pair: ['BTC', 'PPC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8}, + + // Tradeable against VTC + {pair: ['BTC', 'VTC'], minimalOrder: {amount: 0.00001, unit: 'asset'}, precision: 8} + ], + requires: ['key', 'secret'], + providesHistory: 'date', + providesFullHistory: true, + exchangeMaxHistoryAge: 30, + tid: 'date', + tradable: true + }; +} + +module.exports = Trader; diff --git a/exchanges/gdax.js b/exchanges/gdax.js index 341e040a4..0d0ded91f 100644 --- a/exchanges/gdax.js +++ b/exchanges/gdax.js @@ -7,6 +7,7 @@ const Errors = require('../core/error'); const log = require('../core/log'); const BATCH_SIZE = 100; +const QUERY_DELAY = 350; var Trader = function(config) { _.bindAll(this); @@ -20,6 +21,9 @@ var Trader = function(config) { this.asset = config.asset; this.currency = config.currency; + this.api_url = 'https://api.gdax.com'; + this.api_sandbox_url = 'https://api-public.sandbox.gdax.com'; + if (_.isObject(config)) { this.key = config.key; this.secret = config.secret; @@ -28,17 +32,22 @@ var Trader = function(config) { this.pair = [config.asset, config.currency].join('-').toUpperCase(); this.post_only = typeof config.post_only !== 'undefined' ? config.post_only : true; + + if (config.sandbox) { + this.use_sandbox = config.sandbox; + } + } this.gdax_public = new Gdax.PublicClient( this.pair, - this.use_sandbox ? 'https://api-public.sandbox.gdax.com' : undefined + this.use_sandbox ? this.api_sandbox_url : undefined ); this.gdax = new Gdax.AuthenticatedClient( this.key, this.secret, this.passphrase, - this.use_sandbox ? 'https://api-public.sandbox.gdax.com' : undefined + this.use_sandbox ? this.api_sandbox_url : undefined ); }; @@ -72,7 +81,7 @@ Trader.prototype.processError = function(funcName, error) { ); return new Errors.AbortError('[gdax.js] ' + error.message); } - + log.debug( `[gdax.js] (${funcName}) returned an error, retrying: ${error.message}` ); @@ -144,7 +153,8 @@ Trader.prototype.buy = function(amount, price, callback) { callback(undefined, data.id); }; - let handler = cb => this.gdax.buy(buyParams, this.handleResponse('buy', cb)); + let handler = cb => + this.gdax.buy(buyParams, this.handleResponse('buy', cb)); util.retryCustom(retryCritical, _.bind(handler, this), _.bind(result, this)); }; @@ -162,7 +172,7 @@ Trader.prototype.sell = function(amount, price, callback) { }; let handler = cb => - this.gdax.sell(sellParams, this.handleResponse('buy', cb)); + this.gdax.sell(sellParams, this.handleResponse('sell', cb)); util.retryCustom(retryCritical, _.bind(handler, this), _.bind(result, this)); }; @@ -203,9 +213,14 @@ Trader.prototype.getOrder = function(order, callback) { }; Trader.prototype.cancelOrder = function(order, callback) { + // callback for cancelOrder should be true if the order was already filled, otherwise false var result = function(err, data) { - // todo, verify result.. - callback(); + if(err) { + log.error('Error cancelling order:', err); + return callback(true); // need to catch the specific error but usually an error on cancel means it was filled + } + + return callback(false); }; let handler = cb => @@ -361,14 +376,14 @@ Trader.getCapabilities = function() { currencies: ['USD', 'EUR', 'GBP', 'BTC'], assets: ['BTC', 'LTC', 'ETH'], markets: [ - { pair: ['USD', 'BTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['USD', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, + { pair: ['USD', 'BTC'], minimalOrder: { amount: 0.001, unit: 'asset' } }, + { pair: ['USD', 'LTC'], minimalOrder: { amount: 0.1, unit: 'asset' } }, { pair: ['USD', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['EUR', 'BTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['EUR', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, + { pair: ['EUR', 'BTC'], minimalOrder: { amount: 0.001, unit: 'asset' } }, + { pair: ['EUR', 'ETH'], minimalOrder: { amount: 0.1, unit: 'asset' } }, { pair: ['EUR', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['GBP', 'BTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['BTC', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' } }, + { pair: ['GBP', 'BTC'], minimalOrder: { amount: 0.001, unit: 'asset' } }, + { pair: ['BTC', 'LTC'], minimalOrder: { amount: 0.1, unit: 'asset' } }, { pair: ['BTC', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, ], requires: ['key', 'secret', 'passphrase'], @@ -376,7 +391,7 @@ Trader.getCapabilities = function() { providesFullHistory: true, tid: 'tid', tradable: true, - forceReorderDelay: true, + forceReorderDelay: false }; }; diff --git a/exchanges/kraken-markets.json b/exchanges/kraken-markets.json new file mode 100644 index 000000000..52c15991d --- /dev/null +++ b/exchanges/kraken-markets.json @@ -0,0 +1,944 @@ +{ + "assets": [ + "BCH", + "DASH", + "EOS", + "GNO", + "USDT", + "ETC", + "ETH", + "ICN", + "LTC", + "MLN", + "REP", + "XBT", + "XDG", + "XLM", + "XMR", + "XRP", + "ZEC" + ], + "currencies": [ + "EUR", + "USD", + "XBT", + "ETH", + "CAD", + "GBP", + "JPY" + ], + "markets": [ + { + "pair": [ + "EUR", + "BCH" + ], + "prefixed": [ + "ZEUR", + "BCH" + ], + "book": "BCHEUR", + "minimalOrder": { + "amount": "0.002", + "unit": "asset" + }, + "precision": 1 + }, + { + "pair": [ + "USD", + "BCH" + ], + "prefixed": [ + "ZUSD", + "BCH" + ], + "book": "BCHUSD", + "minimalOrder": { + "amount": "0.002", + "unit": "asset" + }, + "precision": 1 + }, + { + "pair": [ + "XBT", + "BCH" + ], + "prefixed": [ + "XXBT", + "BCH" + ], + "book": "BCHXBT", + "minimalOrder": { + "amount": "0.002", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "EUR", + "DASH" + ], + "prefixed": [ + "ZEUR", + "DASH" + ], + "book": "DASHEUR", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "USD", + "DASH" + ], + "prefixed": [ + "ZUSD", + "DASH" + ], + "book": "DASHUSD", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "XBT", + "DASH" + ], + "prefixed": [ + "XXBT", + "DASH" + ], + "book": "DASHXBT", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "ETH", + "EOS" + ], + "prefixed": [ + "XETH", + "EOS" + ], + "book": "EOSETH", + "minimalOrder": { + "amount": "3.0", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "EUR", + "EOS" + ], + "prefixed": [ + "ZEUR", + "EOS" + ], + "book": "EOSEUR", + "minimalOrder": { + "amount": "3.0", + "unit": "asset" + }, + "precision": 4 + }, + { + "pair": [ + "USD", + "EOS" + ], + "prefixed": [ + "ZUSD", + "EOS" + ], + "book": "EOSUSD", + "minimalOrder": { + "amount": "3.0", + "unit": "asset" + }, + "precision": 4 + }, + { + "pair": [ + "XBT", + "EOS" + ], + "prefixed": [ + "XXBT", + "EOS" + ], + "book": "EOSXBT", + "minimalOrder": { + "amount": "3.0", + "unit": "asset" + }, + "precision": 7 + }, + { + "pair": [ + "ETH", + "GNO" + ], + "prefixed": [ + "XETH", + "GNO" + ], + "book": "GNOETH", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 4 + }, + { + "pair": [ + "EUR", + "GNO" + ], + "prefixed": [ + "ZEUR", + "GNO" + ], + "book": "GNOEUR", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "USD", + "GNO" + ], + "prefixed": [ + "ZUSD", + "GNO" + ], + "book": "GNOUSD", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "XBT", + "GNO" + ], + "prefixed": [ + "XXBT", + "GNO" + ], + "book": "GNOXBT", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "USD", + "USDT" + ], + "prefixed": [ + "ZUSD", + "USDT" + ], + "book": "USDTZUSD", + "minimalOrder": { + "amount": "5", + "unit": "asset" + }, + "precision": 4 + }, + { + "pair": [ + "ETH", + "ETC" + ], + "prefixed": [ + "XETH", + "XETC" + ], + "book": "XETCXETH", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "XBT", + "ETC" + ], + "prefixed": [ + "XXBT", + "XETC" + ], + "book": "XETCXXBT", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "EUR", + "ETC" + ], + "prefixed": [ + "ZEUR", + "XETC" + ], + "book": "XETCZEUR", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "USD", + "ETC" + ], + "prefixed": [ + "ZUSD", + "XETC" + ], + "book": "XETCZUSD", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "XBT", + "ETH" + ], + "prefixed": [ + "XXBT", + "XETH" + ], + "book": "XETHXXBT", + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "CAD", + "ETH" + ], + "prefixed": [ + "ZCAD", + "XETH" + ], + "book": "XETHZCAD", + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "EUR", + "ETH" + ], + "prefixed": [ + "ZEUR", + "XETH" + ], + "book": "XETHZEUR", + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "GBP", + "ETH" + ], + "prefixed": [ + "ZGBP", + "XETH" + ], + "book": "XETHZGBP", + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "JPY", + "ETH" + ], + "prefixed": [ + "ZJPY", + "XETH" + ], + "book": "XETHZJPY", + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + }, + "precision": 0 + }, + { + "pair": [ + "USD", + "ETH" + ], + "prefixed": [ + "ZUSD", + "XETH" + ], + "book": "XETHZUSD", + "minimalOrder": { + "amount": "0.02", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "ETH", + "ICN" + ], + "prefixed": [ + "XETH", + "XICN" + ], + "book": "XICNXETH", + "minimalOrder": { + "amount": "2.0", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "XBT", + "ICN" + ], + "prefixed": [ + "XXBT", + "XICN" + ], + "book": "XICNXXBT", + "minimalOrder": { + "amount": "2.0", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "XBT", + "LTC" + ], + "prefixed": [ + "XXBT", + "XLTC" + ], + "book": "XLTCXXBT", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "EUR", + "LTC" + ], + "prefixed": [ + "ZEUR", + "XLTC" + ], + "book": "XLTCZEUR", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "USD", + "LTC" + ], + "prefixed": [ + "ZUSD", + "XLTC" + ], + "book": "XLTCZUSD", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "ETH", + "MLN" + ], + "prefixed": [ + "XETH", + "XMLN" + ], + "book": "XMLNXETH", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "XBT", + "MLN" + ], + "prefixed": [ + "XXBT", + "XMLN" + ], + "book": "XMLNXXBT", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "ETH", + "REP" + ], + "prefixed": [ + "XETH", + "XREP" + ], + "book": "XREPXETH", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "XBT", + "REP" + ], + "prefixed": [ + "XXBT", + "XREP" + ], + "book": "XREPXXBT", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "EUR", + "REP" + ], + "prefixed": [ + "ZEUR", + "XREP" + ], + "book": "XREPZEUR", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "USD", + "REP" + ], + "prefixed": [ + "ZUSD", + "XREP" + ], + "book": "XREPZUSD", + "minimalOrder": { + "amount": "0.3", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "CAD", + "XBT" + ], + "prefixed": [ + "ZCAD", + "XXBT" + ], + "book": "XXBTZCAD", + "minimalOrder": { + "amount": 0.01, + "unit": "asset" + }, + "precision": 1 + }, + { + "pair": [ + "EUR", + "XBT" + ], + "prefixed": [ + "ZEUR", + "XXBT" + ], + "book": "XXBTZEUR", + "minimalOrder": { + "amount": 0.01, + "unit": "asset" + }, + "precision": 1 + }, + { + "pair": [ + "GBP", + "XBT" + ], + "prefixed": [ + "ZGBP", + "XXBT" + ], + "book": "XXBTZGBP", + "minimalOrder": { + "amount": 0.01, + "unit": "asset" + }, + "precision": 1 + }, + { + "pair": [ + "JPY", + "XBT" + ], + "prefixed": [ + "ZJPY", + "XXBT" + ], + "book": "XXBTZJPY", + "minimalOrder": { + "amount": 0.01, + "unit": "asset" + }, + "precision": 0 + }, + { + "pair": [ + "USD", + "XBT" + ], + "prefixed": [ + "ZUSD", + "XXBT" + ], + "book": "XXBTZUSD", + "minimalOrder": { + "amount": 0.01, + "unit": "asset" + }, + "precision": 1 + }, + { + "pair": [ + "XBT", + "XDG" + ], + "prefixed": [ + "XXBT", + "XXDG" + ], + "book": "XXDGXXBT", + "minimalOrder": { + "amount": 0.01, + "unit": "asset" + }, + "precision": 8 + }, + { + "pair": [ + "XBT", + "XLM" + ], + "prefixed": [ + "XXBT", + "XXLM" + ], + "book": "XXLMXXBT", + "minimalOrder": { + "amount": "300", + "unit": "asset" + }, + "precision": 8 + }, + { + "pair": [ + "EUR", + "XLM" + ], + "prefixed": [ + "ZEUR", + "XXLM" + ], + "book": "XXLMZEUR", + "minimalOrder": { + "amount": "300", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "USD", + "XLM" + ], + "prefixed": [ + "ZUSD", + "XXLM" + ], + "book": "XXLMZUSD", + "minimalOrder": { + "amount": "300", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "XBT", + "XMR" + ], + "prefixed": [ + "XXBT", + "XXMR" + ], + "book": "XXMRXXBT", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 6 + }, + { + "pair": [ + "EUR", + "XMR" + ], + "prefixed": [ + "ZEUR", + "XXMR" + ], + "book": "XXMRZEUR", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "USD", + "XMR" + ], + "prefixed": [ + "ZUSD", + "XXMR" + ], + "book": "XXMRZUSD", + "minimalOrder": { + "amount": "0.1", + "unit": "asset" + }, + "precision": 2 + }, + { + "pair": [ + "XBT", + "XRP" + ], + "prefixed": [ + "XXBT", + "XXRP" + ], + "book": "XXRPXXBT", + "minimalOrder": { + "amount": "30", + "unit": "asset" + }, + "precision": 8 + }, + { + "pair": [ + "CAD", + "XRP" + ], + "prefixed": [ + "ZCAD", + "XXRP" + ], + "book": "XXRPZCAD", + "minimalOrder": { + "amount": "30", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "EUR", + "XRP" + ], + "prefixed": [ + "ZEUR", + "XXRP" + ], + "book": "XXRPZEUR", + "minimalOrder": { + "amount": "30", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "JPY", + "XRP" + ], + "prefixed": [ + "ZJPY", + "XXRP" + ], + "book": "XXRPZJPY", + "minimalOrder": { + "amount": "30", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "USD", + "XRP" + ], + "prefixed": [ + "ZUSD", + "XXRP" + ], + "book": "XXRPZUSD", + "minimalOrder": { + "amount": "30", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "XBT", + "ZEC" + ], + "prefixed": [ + "XXBT", + "XZEC" + ], + "book": "XZECXXBT", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 5 + }, + { + "pair": [ + "EUR", + "ZEC" + ], + "prefixed": [ + "ZEUR", + "XZEC" + ], + "book": "XZECZEUR", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "JPY", + "ZEC" + ], + "prefixed": [ + "ZJPY", + "XZEC" + ], + "book": "XZECZJPY", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 3 + }, + { + "pair": [ + "USD", + "ZEC" + ], + "prefixed": [ + "ZUSD", + "XZEC" + ], + "book": "XZECZUSD", + "minimalOrder": { + "amount": "0.03", + "unit": "asset" + }, + "precision": 2 + } + ] +} \ No newline at end of file diff --git a/exchanges/kraken.js b/exchanges/kraken.js index 9adbc2de6..315a35330 100644 --- a/exchanges/kraken.js +++ b/exchanges/kraken.js @@ -5,75 +5,7 @@ const _ = require('lodash'); const util = require('../core/util'); const Errors = require('../core/error'); const log = require('../core/log'); - -var crypto_currencies = [ - "XBT", - "DASH", - "EOS", - "ETC", - "ETH", - "GNO", - "ICN", - "LTC", - "MLN", - "REP", - "USDT", - "XDG", - "XLM", - "XMR", - "XRP", - "ZEC", - "BCH" -]; - -var fiat_currencies = [ - "EUR", - "GBP", - "USD", - "JPY", - "CAD", -]; - -var assets_without_prefix = [ - 'BCH', - 'DASH', - 'EOS', - 'GNO', - 'USDT' -] - -// Method to check if asset/currency is a crypto currency -var isCrypto = function(value) { - return _.contains(crypto_currencies, value); -}; - -// Method to check if asset/currency is a fiat currency -var isFiat = function(value) { - return _.contains(fiat_currencies, value); -}; - -var addPrefix = function(value) { - var fiatPrefix = "Z"; - var cryptoPrefix = "X"; - - if(isFiat(value)) - return fiatPrefix + value; - else if(isCrypto(value)) - return cryptoPrefix + value; - else - return value; -} - -// Some currencies in Kraken don't use the prefix, not clearly documented -var getAssetPair = function(asset, currency) { - if (asset === 'USDT') - return 'USDTZUSD'; // Yet another kraken inconsistency - - if (_.contains(assets_without_prefix, asset)) - return asset + currency; - else - return addPrefix(asset) + addPrefix(currency); -} +const marketData = require('./kraken-markets.json'); var Trader = function(config) { _.bindAll(this); @@ -85,9 +17,13 @@ var Trader = function(config) { this.asset = config.asset.toUpperCase(); } - this.pair = getAssetPair(this.asset, this.currency); this.name = 'kraken'; this.since = null; + + this.market = _.find(Trader.getCapabilities().markets, (market) => { + return market.pair[0] === this.currency && market.pair[1] === this.asset + }); + this.pair = this.market.book; this.kraken = new Kraken( this.key, @@ -110,7 +46,7 @@ var retryForever = { maxTimeout: 30 * 1000 }; -var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|API:Rate limit exceeded|API:Invalid nonce|Service:Unavailable|Request timed out|Response code 525|Response code 520|Response code 504|Response code 502)/) +var recoverableErrors = new RegExp(/(SOCKETTIMEDOUT|TIMEDOUT|CONNRESET|CONNREFUSED|NOTFOUND|API:Rate limit exceeded|API:Invalid nonce|Service:Unavailable|Request timed out|Response code 5)/) Trader.prototype.processError = function(funcName, error) { if (!error) return undefined; @@ -177,17 +113,12 @@ Trader.prototype.getTrades = function(since, callback, descending) { }; Trader.prototype.getPortfolio = function(callback) { - console.log('getPortfolio'); var setBalance = function(err, data) { - console.log('aa', arguments); if(err) return callback(err); log.debug('[kraken.js] entering "setBalance" callback after kraken-api call, data:' , data); - // When using the prefix-less assets, you remove the prefix from the assset but leave - // it on the curreny in this case. An undocumented Kraken quirk. - var assetId = _.contains(assets_without_prefix, this.asset) ? this.asset : addPrefix(this.asset); - var assetAmount = parseFloat( data.result[assetId] ); - var currencyAmount = parseFloat( data.result[addPrefix(this.currency)] ); + var assetAmount = parseFloat( data.result[this.market.prefixed[1]] ); + var currencyAmount = parseFloat( data.result[this.market.prefixed[0]] ); if(!_.isNumber(assetAmount) || _.isNaN(assetAmount)) { log.error(`Kraken did not return portfolio for ${this.asset}, assuming 0.`); @@ -256,8 +187,7 @@ Trader.prototype.roundAmount = function(amount) { }; Trader.prototype.addOrder = function(tradeType, amount, price, callback) { - amount = this.roundAmount(amount); - price = this.roundAmount(price); // but the link talks about rounding price... And I had the bug + price = this.roundAmount(price); // only round price, not amount log.debug('[kraken.js] (addOrder)', tradeType.toUpperCase(), amount, this.asset, '@', price, this.currency); @@ -275,7 +205,7 @@ Trader.prototype.addOrder = function(tradeType, amount, price, callback) { type: tradeType.toLowerCase(), ordertype: 'limit', price: price, - volume: amount.toString() + volume: amount }; let handler = (cb) => this.kraken.api('AddOrder', reqData, this.handleResponse('addOrder', cb)); @@ -331,99 +261,9 @@ Trader.getCapabilities = function () { return { name: 'Kraken', slug: 'kraken', - currencies: ['CAD', 'EUR', 'GBP', 'JPY', 'USD', 'XBT', 'ETH'], - assets: ['XBT', 'LTC', 'GNO', 'ICN', 'MLN', 'REP', 'XDG', 'XLM', 'XMR', 'XRP', 'ZEC', 'ETH', 'BCH', 'DASH', 'EOS', 'ETC', 'USDT'], - markets: [ - //Tradeable againt ETH - { pair: ['XBT', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - { pair: ['CAD', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['EUR', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['GBP', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['JPY', 'ETH'], minimalOrder: { amount: 1, unit: 'asset' }, precision: 0 }, - { pair: ['USD', 'ETH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - - //Tradeable against LTC - { pair: ['XBT', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 6 }, - { pair: ['EUR', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['USD', 'LTC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - - //Tradeable against BCH - { pair: ['USD', 'BCH'], minimalOrder: { amount: 0.1, unit: 'asset' }, precision: 1 }, - { pair: ['EUR', 'BCH'], minimalOrder: { amount: 0.1, unit: 'asset' }, precision: 1 }, - { pair: ['XBT', 'BCH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - - //Tradeable against DASH - { pair: ['USD', 'DASH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['EUR', 'DASH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['XBT', 'DASH'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - - //Tradeable against EOS - { pair: ['USD', 'EOS'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['EUR', 'EOS'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['XBT', 'EOS'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 7 }, - { pair: ['ETH', 'EOS'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 6 }, - - //Tradeable against ETC - { pair: ['USD', 'ETC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 3 }, - { pair: ['EUR', 'ETC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 3 }, - { pair: ['XBT', 'ETC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 6 }, - { pair: ['ETH', 'ETC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - - //Tradeable against GNO - { pair: ['USD', 'GNO'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['EUR', 'GNO'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['XBT', 'GNO'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - { pair: ['ETH', 'GNO'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 4 }, - - //Tradeable against ICN - { pair: ['XBT', 'ICN'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 7 }, - { pair: ['ETH', 'ICN'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 6 }, - - //Tradeable against MLN - { pair: ['XBT', 'MLN'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 6 }, - { pair: ['ETH', 'MLN'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - - //Tradeable against REP - { pair: ['USD', 'REP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['EUR', 'REP'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 3 }, - { pair: ['XBT', 'REP'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 6 }, - { pair: ['ETH', 'REP'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - - //Tradeable against XDG - { pair: ['XBT', 'XDG'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - - //Tradeable against XLM - { pair: ['USD', 'XLM'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['EUR', 'XLM'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['XBT', 'XLM'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 8 }, - - //Tradeable against XMR - { pair: ['USD', 'XMR'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['EUR', 'XMR'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['XBT', 'XMR'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 6 }, - - //Tradeable against XRP - { pair: ['USD', 'XRP'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - { pair: ['EUR', 'XRP'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - { pair: ['XBT', 'XRP'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 8 }, - { pair: ['CAD', 'XRP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['JPY', 'XRP'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - - //Tradeable against ZEC - { pair: ['USD', 'ZEC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['EUR', 'ZEC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 2 }, - { pair: ['XBT', 'ZEC'], minimalOrder: { amount: 0.01, unit: 'asset' }, precision: 5 }, - - //Tradeable against XBT - { pair: ['CAD', 'XBT'], minimalOrder: { amount: 0.1, unit: 'asset' }, precision: 1 }, - { pair: ['EUR', 'XBT'], minimalOrder: { amount: 0.1, unit: 'asset' }, precision: 1 }, - { pair: ['GBP', 'XBT'], minimalOrder: { amount: 0.01, unit: 'asset' } }, - { pair: ['JPY', 'XBT'], minimalOrder: { amount: 1, unit: 'asset' }, precision: 0 }, - { pair: ['USD', 'XBT'], minimalOrder: { amount: 0.1, unit: 'asset' }, precision: 1 }, - - //Tradeable against USDT - { pair: ['USD', 'USDT'], minimalOrder: { amount: 0.1, unit: 'asset' }, precision: 2 }, - ], + currencies: marketData.currencies, + assets: marketData.assets, + markets: marketData.markets, requires: ['key', 'secret'], providesHistory: 'date', providesFullHistory: true, diff --git a/exchanges/quadriga.js b/exchanges/quadriga.js index 22b05ac9a..607edb604 100644 --- a/exchanges/quadriga.js +++ b/exchanges/quadriga.js @@ -92,16 +92,16 @@ Trader.prototype.getPortfolio = function(callback) { if (data && data.error) return this.retry(this.getPortfolio, 'unable to get balance', args, data.error); if (err) return this.retry(this.getPortfolio, 'unable to get balance', args, err); - var assetAmount = parseFloat( data[this.asset + '_available'] ); - var currencyAmount = parseFloat( data[this.currency + '_available'] ); + var assetAmount = parseFloat( data[this.asset.toLowerCase() + '_available'] ); + var currencyAmount = parseFloat( data[this.currency.toLowerCase() + '_available'] ); if(!_.isNumber(assetAmount) || _.isNaN(assetAmount)) { - log.error(`Quadriga did not return balance for ${this.asset}, assuming 0.`); + log.error(`Quadriga did not return balance for ${this.asset.toLowerCase()}, assuming 0.`); assetAmount = 0; } if(!_.isNumber(currencyAmount) || _.isNaN(currencyAmount)) { - log.error(`Quadriga did not return balance for ${this.currency}, assuming 0.`); + log.error(`Quadriga did not return balance for ${this.currency.toLowerCase()}, assuming 0.`); currencyAmount = 0; } @@ -137,7 +137,7 @@ Trader.prototype.getTicker = function(callback) { Trader.prototype.roundAmount = function(amount) { var precision = 100000000; - var market = this.getCapabilities().markets.find(function(market){ return market.pair[0] === this.currency && market.pair[1] === this.asset }); + var market = Trader.getCapabilities().markets.find(function(market){ return market.pair[0] === this.currency && market.pair[1] === this.asset }); if(Number.isInteger(market.precision)) precision = 10 * market.precision; @@ -174,6 +174,7 @@ Trader.prototype.addOrder = function(tradeType, amount, price, callback) { Trader.prototype.getOrder = function(order, callback) { + var args = _.toArray(arguments); var get = function(err, data) { if (data && data.error) return this.retry(this.getOrder, 'unable to get order', args, data.error); @@ -198,6 +199,8 @@ Trader.prototype.sell = function(amount, price, callback) { }; Trader.prototype.checkOrder = function(order, callback) { + var args = _.toArray(arguments); + var check = function(err, data) { if (data && data.error) return this.retry(this.checkOrder, 'unable to get order', args, data.error); diff --git a/gekko.js b/gekko.js index 2dd656e7e..20e9af3cd 100644 --- a/gekko.js +++ b/gekko.js @@ -6,7 +6,7 @@ If you are interested in how Gekko works, read more about Gekko's architecture here: - https://github.com/askmike/gekko/blob/stable/docs/internals/architecture.md + https://gekko.wizb.it/docs/internals/architecture.html Disclaimer: diff --git a/package-lock.json b/package-lock.json index 9d06e8cb0..6f0ee2f47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,6 @@ - { "name": "gekko", - "version": "0.5.12", + "version": "0.5.13", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -17,7 +16,7 @@ "inherits": "2.0.3", "lodash": "4.17.4", "pkginfo": "0.4.1", - "request": "2.81.0", + "request": "2.83.0", "retry": "0.9.0", "url-join": "0.0.1", "winston": "2.3.1", @@ -121,12 +120,14 @@ } }, "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { "co": "4.6.0", - "json-stable-stringify": "1.0.1" + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ansi-regex": { @@ -208,6 +209,12 @@ "regenerator-runtime": "0.11.1" } }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", @@ -218,11 +225,11 @@ } }, "binance": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/binance/-/binance-1.1.0.tgz", - "integrity": "sha1-Fa9bppw++4SmpCF60jmZrg79DXQ=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/binance/-/binance-1.3.1.tgz", + "integrity": "sha1-ecicdUranlTtZiicVav6C/BkYUE=", "requires": { - "request": "2.81.0", + "request": "2.83.0", "underscore": "1.8.3", "ws": "3.3.3" }, @@ -254,10 +261,10 @@ "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.0.tgz", "integrity": "sha1-nqCaZnLBE0tejEMToT5HzKloxyA=" }, - "bitcoin-co-id": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/bitcoin-co-id/-/bitcoin-co-id-0.0.1.tgz", - "integrity": "sha1-w1kKGMt0+vQzk3fOnhtc+j2xRPk=", + "bitcoin-co-id-update": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/bitcoin-co-id-update/-/bitcoin-co-id-update-0.0.2.tgz", + "integrity": "sha512-1t96Fg/FcWDuf5HmfLNCq9dFXioDO35BQJNrqmiWNDxk49e9EAB2yKxmdlEIOIw8pGarvNQkqVGgE5PXxY/uig==", "requires": { "crypto": "1.0.1", "querystring": "0.2.0", @@ -266,163 +273,11 @@ "verror": "1.10.0" }, "dependencies": { - "ajv": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.4.0.tgz", - "integrity": "sha1-MtHPCNvIDEMvQm8S4QslEfa0ZHQ=", - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.2.0" - } - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.2.0" - } - } - } - }, "crypto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" }, - "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "requires": { - "ajv": "5.4.0", - "har-schema": "2.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.1.0" - } - }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" - }, - "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "requires": { - "hoek": "4.2.0" - } - }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", - "requires": { - "punycode": "1.4.1" - } - }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", @@ -452,7 +307,7 @@ "requires": { "debug": "2.6.8", "lodash": "4.17.4", - "request": "2.81.0", + "request": "2.83.0", "request-promise": "4.2.1", "ws": "3.2.0" }, @@ -549,6 +404,22 @@ "hoek": "2.16.3" } }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, "btc-china-fork": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/btc-china-fork/-/btc-china-fork-0.0.6.tgz", @@ -587,7 +458,7 @@ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", "requires": { "chalk": "1.1.3", - "commander": "2.11.0", + "commander": "2.13.0", "is-my-json-valid": "2.16.1", "pinkie-promise": "2.0.1" } @@ -865,19 +736,32 @@ } }, "chai": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-2.3.0.tgz", - "integrity": "sha1-ii9qNHSNqAEJD9cyh7Kqc5pOkJo=", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "1.0.0", - "deep-eql": "0.1.3" + "assertion-error": "1.0.2", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.7" }, "dependencies": { - "assertion-error": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.7" + } + }, + "type-detect": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.7.tgz", + "integrity": "sha512-4Rh17pAMVdMWzktddFhISRnUnFIStObtUMNGzDwlA6w/77bmGv3aBbRdCmQR6IjzfkTo9otnW+2K/cDRhKSxDA==", "dev": true } } @@ -899,6 +783,12 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, "cheerio": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", @@ -983,9 +873,9 @@ } }, "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==" }, "composition": { "version": "2.3.0", @@ -996,6 +886,12 @@ "co": "4.6.0" } }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -1152,9 +1048,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "dev": true }, "dom-serializer": { @@ -1303,9 +1199,9 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", "requires": { "asynckit": "0.4.0", "combined-stream": "1.0.5", @@ -1313,12 +1209,12 @@ } }, "formatio": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz", - "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", "dev": true, "requires": { - "samsam": "1.1.2" + "samsam": "1.3.0" } }, "fresh": { @@ -1331,6 +1227,12 @@ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, "gdax": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/gdax/-/gdax-0.4.2.tgz", @@ -1391,7 +1293,7 @@ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", "requires": { "chalk": "1.1.3", - "commander": "2.11.0", + "commander": "2.13.0", "is-my-json-valid": "2.16.1", "pinkie-promise": "2.0.1" } @@ -1661,6 +1563,12 @@ "is-property": "1.0.2" } }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -1682,13 +1590,17 @@ } }, "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", "inherits": "2.0.3", - "minimatch": "0.3.0" + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "got": { @@ -1713,23 +1625,23 @@ } }, "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, "has-ansi": { @@ -1740,6 +1652,12 @@ "ansi-regex": "2.1.1" } }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, "has-symbol-support-x": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz", @@ -1764,6 +1682,12 @@ "sntp": "1.0.9" } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, "hoek": { "version": "2.16.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", @@ -1857,6 +1781,16 @@ "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.0.0.tgz", "integrity": "sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=" }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -1946,30 +1880,6 @@ "is-object": "1.0.1" } }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "dev": true, - "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "dev": true - } - } - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -2046,6 +1956,12 @@ } } }, + "just-extend": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", + "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "dev": true + }, "keygrip": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.2.tgz", @@ -2180,6 +2096,18 @@ "@you21979/promise-sleep": "1.0.1", "request-limitter": "0.0.2", "request-promise": "4.1.1" + }, + "dependencies": { + "request-promise": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.1.1.tgz", + "integrity": "sha1-JgIeT29W/Uwwn2vx69jJepWsH7U=", + "requires": { + "bluebird": "3.5.0", + "request-promise-core": "1.1.1", + "stealthy-require": "1.1.1" + } + } } }, "lodash": { @@ -2282,6 +2210,12 @@ "lodash.isarray": "3.0.4" } }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -2318,9 +2252,9 @@ "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" }, "lolex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", - "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.1.tgz", + "integrity": "sha512-mQuW55GhduF3ppo+ZRUTz1PRjEh1hS5BbqU7d8D0ez2OKxHDod7StPPeAVKisZR5aLkHZjdGWSL42LSONUJsZw==", "dev": true }, "lowercase-keys": { @@ -2328,12 +2262,6 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, "map-stream": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", @@ -2389,13 +2317,12 @@ "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=" }, "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" + "brace-expansion": "1.1.8" } }, "minimist": { @@ -2412,55 +2339,46 @@ } }, "mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.0.tgz", + "integrity": "sha512-ukB2dF+u4aeJjc6IGtPNnJXfeby5d4ZqySlIBT0OEyva/DrMjVm5HkQxKnHDLKEfEQBsEnwTg9HHhtPHJdTd8w==", "dev": true, "requires": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" + "supports-color": "4.4.0" }, "dependencies": { "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "ms": "0.7.1" + "ms": "2.0.0" } }, - "escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, "supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", - "dev": true + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } } } }, @@ -2471,9 +2389,9 @@ "dev": true }, "moment": { - "version": "2.19.3", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz", - "integrity": "sha1-vbmdJw1tf9p4zA+6zoVeJ/59pp8=" + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", + "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==" }, "ms": { "version": "2.0.0", @@ -2505,6 +2423,27 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, + "nise": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.2.0.tgz", + "integrity": "sha512-q9jXh3UNsMV28KeqI43ILz5+c3l+RiNW8mhurEwCKckuHQbL+hTJIKKTiUlCPKlgQ/OukFvSnKB/Jk3+sFbkGA==", + "dev": true, + "requires": { + "formatio": "1.2.0", + "just-extend": "1.1.27", + "lolex": "1.6.0", + "path-to-regexp": "1.7.0", + "text-encoding": "0.6.4" + }, + "dependencies": { + "lolex": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", + "dev": true + } + } + }, "nock": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/nock/-/nock-3.6.0.tgz", @@ -2706,7 +2645,7 @@ "event-stream": "3.3.4", "jsonic": "0.3.0", "JSONStream": "1.3.1", - "request": "2.81.0", + "request": "2.83.0", "signalr-client": "0.0.17" } }, @@ -2787,7 +2726,7 @@ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", "requires": { "chalk": "1.1.3", - "commander": "2.11.0", + "commander": "2.13.0", "is-my-json-valid": "2.16.1", "pinkie-promise": "2.0.1" } @@ -2863,6 +2802,15 @@ "ee-first": "1.1.1" } }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, "only": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", @@ -2923,6 +2871,12 @@ "isarray": "0.0.1" } }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, "pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", @@ -2932,9 +2886,9 @@ } }, "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pinkie": { "version": "2.0.4", @@ -3381,7 +3335,7 @@ "resolved": "https://registry.npmjs.org/quadrigacx/-/quadrigacx-0.0.7.tgz", "integrity": "sha1-vptrBG28vDpNqRbBpQtJ2kiulsQ=", "requires": { - "request": "2.81.0" + "request": "2.83.0" } }, "querystring": { @@ -3444,32 +3398,117 @@ } }, "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", "requires": { - "aws-sign2": "0.6.0", + "aws-sign2": "0.7.0", "aws4": "1.6.0", "caseless": "0.12.0", "combined-stream": "1.0.5", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", "mime-types": "2.1.17", "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", + "performance-now": "2.1.0", + "qs": "6.5.1", "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.3.2", + "tough-cookie": "2.3.3", "tunnel-agent": "0.6.0", "uuid": "3.1.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.2.0" + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.2.0" + } + }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "requires": { + "punycode": "1.4.1" + } + } } }, "request-limitter": { @@ -3478,13 +3517,26 @@ "integrity": "sha1-MQeFbY0bTbVt56Gnd8IRr3M4GJY=" }, "request-promise": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.1.1.tgz", - "integrity": "sha1-JgIeT29W/Uwwn2vx69jJepWsH7U=", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz", + "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=", + "dev": true, "requires": { "bluebird": "3.5.0", "request-promise-core": "1.1.1", - "stealthy-require": "1.1.1" + "stealthy-require": "1.1.1", + "tough-cookie": "2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + } } }, "request-promise-core": { @@ -3550,9 +3602,9 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "samsam": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz", - "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "dev": true }, "semver": { @@ -3565,12 +3617,6 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, "signalr-client": { "version": "0.0.17", "resolved": "https://registry.npmjs.org/signalr-client/-/signalr-client-0.0.17.tgz", @@ -3580,15 +3626,35 @@ } }, "sinon": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", - "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.2.0.tgz", + "integrity": "sha512-FAdCcQ6lUAakWQMVRSIhiQU90d5EH1k3V6wRPrjxcYsv4vlBHjFzWLeoD63GoTKrFkfzVQs209aFW8V3cGLNtA==", "dev": true, "requires": { - "formatio": "1.1.1", - "lolex": "1.3.2", - "samsam": "1.1.2", - "util": "0.10.3" + "diff": "3.3.1", + "formatio": "1.2.0", + "lodash.get": "4.4.2", + "lolex": "2.3.1", + "nise": "1.2.0", + "supports-color": "5.1.0", + "type-detect": "4.0.7" + }, + "dependencies": { + "supports-color": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "type-detect": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.7.tgz", + "integrity": "sha512-4Rh17pAMVdMWzktddFhISRnUnFIStObtUMNGzDwlA6w/77bmGv3aBbRdCmQR6IjzfkTo9otnW+2K/cDRhKSxDA==", + "dev": true + } } }, "sntp": { @@ -4396,6 +4462,12 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, "thenify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", @@ -4432,12 +4504,6 @@ "resolved": "https://registry.npmjs.org/tiny-promisify/-/tiny-promisify-0.1.1.tgz", "integrity": "sha1-FoHhWVyKEUIq9b9ESAIVQCdiq4Q=" }, - "to-iso-string": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", - "dev": true - }, "toml": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.3.tgz", @@ -4471,7 +4537,7 @@ "integrity": "sha1-B2I3jx3BwFDkj2ZqypBOJLGpYvQ=", "requires": { "deep-extend": "0.5.0", - "request": "2.81.0" + "request": "2.83.0" } }, "type-detect": { @@ -4529,23 +4595,6 @@ "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -4609,6 +4658,12 @@ } } }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, "ws": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.4.tgz", @@ -4637,7 +4692,7 @@ "@you21979/object-util": "0.0.1", "@you21979/simple-verify": "0.0.2", "limit-request-promise": "0.1.2", - "request": "2.81.0", + "request": "2.83.0", "ws": "1.1.4" } } diff --git a/package.json b/package.json index bbea662e5..91ea09298 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gekko", - "version": "0.5.12", + "version": "0.5.14", "description": "A bitcoin trading bot for auto trading at various exchanges", "keywords": [ "trading", @@ -17,8 +17,8 @@ "dependencies": { "@slack/client": "^3.10.0", "async": "2.1.2", - "binance": "^1.1.0", - "bitcoin-co-id": "0.0.1", + "binance": "^1.3.1", + "bitcoin-co-id-update": "0.0.2", "bitexthai": "^0.1.0", "bitfinex-api-node": "^1.2.0", "bitstamp": "^1.0.3", @@ -28,7 +28,8 @@ "cexio": "0.0.x", "co-fs": "^1.2.0", "coinfalcon": "^1.0.3", - "commander": "^2.9.0", + "coingi": "^1.0.7", + "commander": "^2.13.0", "gdax": "^0.4.2", "gekko": "0.0.9", "gemini-exchange-coffee-api": "2.0.6", @@ -42,7 +43,7 @@ "kraken-api-es5": "^1.0.0", "lakebtc_nodejs": "0.1.x", "lodash": "2.x", - "moment": "2.19.3", + "moment": "^2.20.1", "node-wex": "^1.0.3", "node.bittrex.api": "^0.4.3", "okcoin-china": "0.0.7", @@ -63,10 +64,12 @@ "zaif.jp": "^0.1.4" }, "devDependencies": { - "chai": "^2.0.0", - "mocha": "^2.1.1", + "chai": "^4.1.2", + "mocha": "^5.0.0", "proxyquire": "^1.7.10", - "sinon": "^1.12.2" + "request": "^2.83.0", + "request-promise": "^4.2.2", + "sinon": "^4.2.0" }, "engines": { "node": ">=6.0" diff --git a/plugins/performanceAnalyzer/performanceAnalyzer.js b/plugins/performanceAnalyzer/performanceAnalyzer.js index 0e5ede9dc..5df48a2bf 100644 --- a/plugins/performanceAnalyzer/performanceAnalyzer.js +++ b/plugins/performanceAnalyzer/performanceAnalyzer.js @@ -38,6 +38,7 @@ const PerformanceAnalyzer = function() { this.roundTrips = []; this.roundTrip = { + id: 0, entry: false, exit: false } @@ -74,21 +75,26 @@ PerformanceAnalyzer.prototype.processTrade = function(trade) { PerformanceAnalyzer.prototype.logRoundtripPart = function(trade) { // this is not part of a valid roundtrip - if(this.trades === 1 && trade.action === 'sell') { + if(!this.roundTrip.entry && trade.action === 'sell') { return; } if(trade.action === 'buy') { + if (this.roundTrip.exit) { + this.roundTrip.id++; + this.roundTrip.exit = false + } + this.roundTrip.entry = { date: trade.date, price: trade.price, - total: trade.portfolio.asset * trade.price, + total: trade.portfolio.currency + (trade.portfolio.asset * trade.price), } } else if(trade.action === 'sell') { this.roundTrip.exit = { date: trade.date, price: trade.price, - total: trade.portfolio.currency + total: trade.portfolio.currency + (trade.portfolio.asset * trade.price), } this.handleRoundtrip(); @@ -101,6 +107,8 @@ PerformanceAnalyzer.prototype.round = function(amount) { PerformanceAnalyzer.prototype.handleRoundtrip = function() { var roundtrip = { + id: this.roundTrip.id, + entryAt: this.roundTrip.entry.date, entryPrice: this.roundTrip.entry.price, entryBalance: this.roundTrip.entry.total, @@ -115,7 +123,9 @@ PerformanceAnalyzer.prototype.handleRoundtrip = function() { roundtrip.pnl = roundtrip.exitBalance - roundtrip.entryBalance; roundtrip.profit = (100 * roundtrip.exitBalance / roundtrip.entryBalance) - 100; - this.roundTrips.push(roundtrip); + this.roundTrips[this.roundTrip.id] = roundtrip; + + // this will keep resending roundtrips, that is not ideal.. what do we do about it? this.handler.handleRoundtrip(roundtrip); // we need a cache for sharpe diff --git a/plugins/postgresql/handle.js b/plugins/postgresql/handle.js index 38481dcb4..2d1c396f2 100755 --- a/plugins/postgresql/handle.js +++ b/plugins/postgresql/handle.js @@ -48,7 +48,7 @@ checkClient.connect(function(err){ if(err) { util.die(err); } - if(res.rowCount == 0){ //database does not exist + if(res.rows[0].count == 0){ //database does not exist log.debug("Database "+dbName+" does not exist"); if(mode === 'realtime') { //create database if not found log.debug("Creating database "+dbName); diff --git a/plugins/postgresql/reader.js b/plugins/postgresql/reader.js index 415a4977c..3190f8cbd 100755 --- a/plugins/postgresql/reader.js +++ b/plugins/postgresql/reader.js @@ -13,7 +13,7 @@ var Reader = function() { this.db = handle; } -// returns the furtherst point (up to `from`) in time we have valid data from +// returns the furthest point (up to `from`) in time we have valid data from Reader.prototype.mostRecentWindow = function(from, to, next) { to = to.unix(); from = from.unix(); diff --git a/plugins/postgresql/util.js b/plugins/postgresql/util.js index 42bd95cb3..e72a7e0e5 100755 --- a/plugins/postgresql/util.js +++ b/plugins/postgresql/util.js @@ -38,14 +38,14 @@ module.exports = { database: function () { return useSingleDatabase() ? config.postgresql.database : - config.watch.exchange.toLowerCase(); + config.watch.exchange.toLowerCase().replace(/\-/g,''); }, // returns table name which can be different if we use // single or multiple db setup. table: function (name) { if (useSingleDatabase()) { - name = watch.exchange + '_' + name; + name = watch.exchange.replace(/\-/g,'') + '_' + name; } var fullName = [name, settings.pair.join('_')].join('_'); return useLowerCaseTableNames() ? fullName.toLowerCase() : fullName; diff --git a/plugins/postgresql/writer.js b/plugins/postgresql/writer.js index 388051724..3173909da 100755 --- a/plugins/postgresql/writer.js +++ b/plugins/postgresql/writer.js @@ -45,7 +45,7 @@ Store.prototype.writeCandles = function() { var stmt = ` INSERT INTO ${postgresUtil.table('candles')} (start, open, high,low, close, vwp, volume, trades) - select $1, $2, $3, $4, $5, $6, $7, $8 + select $1, $2, $3, $4, $5, $6, $7, $8 WHERE NOT EXISTS (select id from ${postgresUtil.table('candles')} where start=$1); `; @@ -67,7 +67,7 @@ Store.prototype.writeCandles = function() { var processCandle = function(candle, done) { this.cache.push(candle); - if (this.cache.length > 100) + if (this.cache.length > 1) this.writeCandles(); done(); diff --git a/plugins/telegrambot.js b/plugins/telegrambot.js index 058fbf673..1260ee52f 100644 --- a/plugins/telegrambot.js +++ b/plugins/telegrambot.js @@ -1,35 +1,37 @@ -var log = require('../core/log'); -var moment = require('moment'); -var _ = require('lodash'); -var config = require('../core/util').getConfig(); -var telegrambot = config.telegrambot; -var utc = moment.utc; - -var telegram = require("node-telegram-bot-api"); - -var Actor = function() { +const log = require('../core/log'); +const moment = require('moment'); +const _ = require('lodash'); +const config = require('../core/util').getConfig(); +const telegrambot = config.telegrambot; +const utc = moment.utc; +const telegram = require("node-telegram-bot-api"); + +const Actor = function() { _.bindAll(this); - this.advice = 'Dont got one yet :('; + this.advice = null; this.adviceTime = utc(); this.price = 'Dont know yet :('; this.priceTime = utc(); this.commands = { + '/start': 'emitStart', '/advice': 'emitAdvice', + '/subscribe': 'emitSubscribe', + '/unsubscribe': 'emitUnSubscribe', '/price': 'emitPrice', - '/donate': 'emitDonation', - '/realadvice': 'emitRealAdvice', //Without space '/help': 'emitHelp' }; - + if (telegrambot.donate) { + this.commands['/donate'] = 'emitDonate'; + } this.rawCommands = _.keys(this.commands); - this.chatId = null; + this.subscribers = []; this.bot = new telegram(telegrambot.token, { polling: true }); this.bot.onText(/(.+)/, this.verifyQuestion); -} +}; Actor.prototype.processCandle = function(candle, done) { this.price = candle.close; @@ -39,32 +41,46 @@ Actor.prototype.processCandle = function(candle, done) { }; Actor.prototype.processAdvice = function(advice) { - if (telegrambot.muteSoft && advice.recommendation === 'soft') return; + if (advice.recommendation === 'soft') return; this.advice = advice.recommendation; this.adviceTime = utc(); - - if (telegrambot.emitUpdates) - this.newAdvice(); + this.advicePrice = this.price; + this.subscribers.forEach(this.emitAdvice, this); }; Actor.prototype.verifyQuestion = function(msg, text) { this.chatId = msg.chat.id; - if (text[1].toLowerCase() in this.commands) + if (text[1].toLowerCase() in this.commands) { this[this.commands[text[1].toLowerCase()]](); - else - this.bot.sendMessage(this.chatId, "Hello!"); -} - -Actor.prototype.newAdvice = function() { - if (this.chatId) { - this.bot.sendMessage(this.chatId, 'Important news!'); - this.emitAdvice(); + } else { + this.emitHelp(); } -} +}; -// sent advice to the last chat -Actor.prototype.emitAdvice = function() { - var message = [ +Actor.prototype.emitStart = function() { + this.bot.sendMessage(this.chatId, 'Hello! How can I help you?'); +}; + +Actor.prototype.emitSubscribe = function() { + if (this.subscribers.indexOf(this.chatId) === -1) { + this.subscribers.push(this.chatId); + this.bot.sendMessage(this.chatId, `Success! Got ${this.subscribers.length} subscribers.`); + } else { + this.bot.sendMessage(this.chatId, "You are already subscribed."); + } +}; + +Actor.prototype.emitUnSubscribe = function() { + if (this.subscribers.indexOf(this.chatId) > -1) { + this.subscribers.splice(this.subscribers.indexOf(this.chatId), 1); + this.bot.sendMessage(this.chatId, "Success!"); + } else { + this.bot.sendMessage(this.chatId, "You are not subscribed."); + } +}; + +Actor.prototype.emitAdvice = function(chatId) { + let message = [ 'Advice for ', config.watch.exchange, ' ', @@ -76,21 +92,30 @@ Actor.prototype.emitAdvice = function() { ' at ', config.tradingAdvisor.candleSize, ' minute candles, is:\n', - this.advice, - ' ', - config.watch.asset, - ' (from ', - this.adviceTime.fromNow(), - ')' ].join(''); + if (this.advice) { + message += this.advice + + ' ' + + config.watch.asset + + ' ' + + this.advicePrice + + ' (' + + this.adviceTime.fromNow() + + ')'; + } else { + message += 'None' + } - if (this.chatId) + if (chatId) { + this.bot.sendMessage(chatId, message); + } else { this.bot.sendMessage(this.chatId, message); + } }; // sent price over to the last chat Actor.prototype.emitPrice = function() { - var message = [ + const message = [ 'Current price at ', config.watch.exchange, ' ', @@ -102,54 +127,28 @@ Actor.prototype.emitPrice = function() { ' ', config.watch.currency, ' (from ', - this.priceTime.fromNow(), + this.priceTime.fromNow(), ')' ].join(''); - if (this.chatId) - this.bot.sendMessage(this.chatId, message); + this.bot.sendMessage(this.chatId, message); }; -// sent donation info over to the IRC channel -Actor.prototype.emitDonation = function() { - var message = 'You want to donate? How nice of you! You can send your coins here:'; - message += '\nBTC:\t13r1jyivitShUiv9FJvjLH7Nh1ZZptumwW'; - - if (this.chatId) - this.bot.sendMessage(this.chatId, message); +Actor.prototype.emitDonate = function() { + this.bot.sendMessage(this.chatId, telegrambot.donate); }; Actor.prototype.emitHelp = function() { - var message = _.reduce( + let message = _.reduce( this.rawCommands, function(message, command) { return message + ' ' + command + ','; }, - 'possible commands are:' + 'Possible commands are:' ); - message = message.substr(0, _.size(message) - 1) + '.'; - - if (this.chatId) - this.bot.sendMessage(this.chatId, message); -} - -Actor.prototype.emitRealAdvice = function() { - // http://www.examiner.com/article/uncaged-a-look-at-the-top-10-quotes-of-gordon-gekko - // http://elitedaily.com/money/memorable-gordon-gekko-quotes/ - var realAdvice = [ - 'I don\'t throw darts at a board. I bet on sure things. Read Sun-tzu, The Art of War. Every battle is won before it is ever fought.', - 'Ever wonder why fund managers can\'t beat the S&P 500? \'Cause they\'re sheep, and sheep get slaughtered.', - 'If you\'re not inside, you\'re outside!', - 'The most valuable commodity I know of is information.', - 'It\'s not a question of enough, pal. It\'s a zero sum game, somebody wins, somebody loses. Money itself isn\'t lost or made, it\'s simply transferred from one perception to another.', - 'What\'s worth doing is worth doing for money. (Wait, wasn\'t I a free and open source bot?)', - 'When I get a hold of the son of a bitch who leaked this, I\'m gonna tear his eyeballs out and I\'m gonna suck his fucking skull.' - ]; - - if (this.chatId) - this.bot.sendMessage(this.chatId, _.first(_.shuffle(realAdvice))); -} + this.bot.sendMessage(this.chatId, message); +}; Actor.prototype.logError = function(message) { log.error('Telegram ERROR:', message); diff --git a/plugins/trader/portfolioManager.js b/plugins/trader/portfolioManager.js index b97a7fbb5..ef7ebf296 100644 --- a/plugins/trader/portfolioManager.js +++ b/plugins/trader/portfolioManager.js @@ -12,7 +12,7 @@ var _ = require('lodash'); var util = require('../../core/util'); var dirs = util.dirs(); -var events = require("events"); +var events = require('events'); var log = require(dirs.core + 'log'); var async = require('async'); var checker = require(dirs.core + 'exchangeChecker.js'); @@ -189,62 +189,80 @@ Manager.prototype.getMinimum = function(price) { // the asset, if so BUY and keep track of the order // (amount is in asset quantity) Manager.prototype.buy = function(amount, price) { + let minimum = 0; + let process = (err, order) => { + // if order to small + if(!order.amount || order.amount < minimum) { + return log.warn( + 'Wanted to buy', + this.asset, + 'but the amount is too small ', + '(' + parseFloat(amount).toFixed(8) + ' @', + parseFloat(price).toFixed(8), + ') at', + this.exchange.name + ); + } - var minimum = this.getMinimum(price); - - // if order to small - if(amount < minimum) { - return log.error( - 'Wanted to buy', + log.info( + 'Attempting to BUY', + order.amount, this.asset, - 'but the amount is too small', - '(' + parseFloat(amount).toFixed(12) + ')', 'at', - this.exchange.name + this.exchange.name, + 'price:', + order.price ); + + this.exchange.buy(order.amount, order.price, this.noteOrder); } - log.info( - 'Attempting to BUY', - amount, - this.asset, - 'at', - this.exchange.name, - 'price:', - price - ); - this.exchange.buy(amount, price, this.noteOrder); + if (_.has(this.exchange, 'getLotSize')) { + this.exchange.getLotSize('buy', amount, price, _.bind(process)); + } else { + minimum = this.getMinimum(price); + process(undefined, { amount: amount, price: price }); + } }; // first do a quick check to see whether we can sell // the asset, if so SELL and keep track of the order // (amount is in asset quantity) Manager.prototype.sell = function(amount, price) { + let minimum = 0; + let process = (err, order) => { + // if order to small + if (!order.amount || order.amount < minimum) { + return log.warn( + 'Wanted to buy', + this.currency, + 'but the amount is too small ', + '(' + parseFloat(amount).toFixed(8) + ' @', + parseFloat(price).toFixed(8), + ') at', + this.exchange.name + ); + } - var minimum = this.getMinimum(price); - - // if order to small - if(amount < minimum) { - return log.error( - 'Wanted to buy', - this.currency, - 'but the amount is too small', - '(' + parseFloat(amount).toFixed(12) + ')', + log.info( + 'Attempting to SELL', + order.amount, + this.asset, 'at', - this.exchange.name + this.exchange.name, + 'price:', + order.price ); + + this.exchange.sell(order.amount, order.price, this.noteOrder); } - log.info( - 'Attempting to SELL', - amount, - this.asset, - 'at', - this.exchange.name, - 'price:', - price - ); - this.exchange.sell(amount, price, this.noteOrder); + if (_.has(this.exchange, 'getLotSize')) { + this.exchange.getLotSize('sell', amount, price, _.bind(process)); + } else { + minimum = this.getMinimum(price); + process(undefined, { amount: amount, price: price }); + } }; Manager.prototype.noteOrder = function(err, order) { @@ -253,9 +271,10 @@ Manager.prototype.noteOrder = function(err, order) { } this.orders.push(order); - // if after 1 minute the order is still there - // we cancel and calculate & make a new one - setTimeout(this.checkOrder, util.minToMs(1)); + + // If unfilled, cancel and replace order with adjusted price + let cancelDelay = this.conf.orderUpdateDelay || 1; + setTimeout(this.checkOrder, util.minToMs(cancelDelay)); }; diff --git a/plugins/tradingAdvisor/baseTradingMethod.js b/plugins/tradingAdvisor/baseTradingMethod.js index 75f0db939..7dca2866c 100644 --- a/plugins/tradingAdvisor/baseTradingMethod.js +++ b/plugins/tradingAdvisor/baseTradingMethod.js @@ -80,6 +80,9 @@ var Base = function(settings) { if(!this.end) this.end = function() {}; + if(!this.onTrade) + this.onTrade = function() {}; + // let's run the implemented starting point this.init(); @@ -223,10 +226,17 @@ Base.prototype.propogateTick = function(candle) { // than minimally needed. In that case check // whether candle start time is > startTime var isPremature; - if(mode === 'realtime') - isPremature = candle.start < startTime; - else + + if(mode === 'realtime'){ + // Subtract number of minutes in current candle for instant start + let startTimeMinusCandleSize = startTime.clone(); + startTimeMinusCandleSize.subtract(this.tradingAdvisor.candleSize, "minutes"); + + isPremature = candle.start < startTimeMinusCandleSize; + } + else{ isPremature = false; + } if(isAllowedToCheck && !isPremature) { this.log(candle); @@ -248,6 +258,10 @@ Base.prototype.propogateTick = function(candle) { this.finishCb(); } +Base.prototype.processTrade = function(trade) { + this.onTrade(trade); +} + Base.prototype.addTalibIndicator = function(name, type, parameters) { if(!talib) util.die('Talib is not enabled'); @@ -291,7 +305,7 @@ Base.prototype.addIndicator = function(name, type, parameters) { if(this.setup) util.die('Can only add indicators in the init method!'); - this.indicators[name] = new Indicators[type](parameters); + return this.indicators[name] = new Indicators[type](parameters); // some indicators need a price stream, others need full candles } @@ -314,13 +328,11 @@ Base.prototype.advice = function(newPosition, _candle) { this._prevAdvice = newPosition; - _.defer(function() { - this.emit('advice', { - recommendation: newPosition, - portfolio: 1, - candle - }); - }.bind(this)); + this.emit('advice', { + recommendation: newPosition, + portfolio: 1, + candle + }); } // Because the trading method might be async we need diff --git a/plugins/tradingAdvisor/tradingAdvisor.js b/plugins/tradingAdvisor/tradingAdvisor.js index a57144b68..7d7597993 100644 --- a/plugins/tradingAdvisor/tradingAdvisor.js +++ b/plugins/tradingAdvisor/tradingAdvisor.js @@ -63,6 +63,9 @@ Actor.prototype.setupTradingMethod = function() { this.method .on('advice', this.relayAdvice); + this.method + .on('trade', this.processTrade); + this.batcher .on('candle', this.processCustomCandle); } @@ -79,6 +82,10 @@ Actor.prototype.processCustomCandle = function(candle) { this.method.tick(candle); } +Actor.prototype.processTrade = function(trade) { + this.method.processTrade(trade); +} + // pass through shutdown handler Actor.prototype.finish = function(done) { this.method.finish(done); diff --git a/sample-config.js b/sample-config.js index 561244d2e..16de0bb93 100644 --- a/sample-config.js +++ b/sample-config.js @@ -33,17 +33,15 @@ config.watch = { config.tradingAdvisor = { enabled: true, method: 'MACD', - candleSize: 1, - historySize: 3, - adapter: 'sqlite' + candleSize: 60, + historySize: 10, } // Exponential Moving Averages settings: config.DEMA = { // EMA weight (α) // the higher the weight, the more smooth (and delayed) the line - short: 10, - long: 21, + weight: 21, // amount of candles to remember and base initial EMAs on // the difference between the EMAs (to act as triggers) thresholds: { @@ -216,7 +214,8 @@ config.trader = { key: '', secret: '', username: '', // your username, only required for specific exchanges. - passphrase: '' // GDAX, requires a passphrase. + passphrase: '', // GDAX, requires a passphrase. + orderUpdateDelay: 1, // Number of minutes to adjust unfilled order prices } config.adviceLogger = { @@ -303,10 +302,8 @@ config.ircbot = { config.telegrambot = { enabled: false, - emitUpdates: false, token: 'YOUR_TELEGRAM_BOT_TOKEN', - botName: 'gekkobot' -} +}; config.twitter = { // sends pushbullets if true diff --git a/strategies/debug-advice.js b/strategies/DEBUG_single-advice.js similarity index 100% rename from strategies/debug-advice.js rename to strategies/DEBUG_single-advice.js diff --git a/strategies/DEBUG_toggle-advice.js b/strategies/DEBUG_toggle-advice.js new file mode 100644 index 000000000..d687ad754 --- /dev/null +++ b/strategies/DEBUG_toggle-advice.js @@ -0,0 +1,39 @@ +var settings = { + wait: 0, + each: 6 +}; + +// ------- + +var _ = require('lodash'); +var log = require('../core/log.js'); + +var i = 0; + +var method = { + init: _.noop, + update: _.noop, + log: _.noop, + check: function() { + + if(settings.wait > i) + return; + + log.info('iteration:', i); + + if(i % settings.each === 0) + this.advice('short'); + else if(i % settings.each === settings.each / 2) + this.advice('long'); + + // if(i % 2 === 0) + // this.advice('long'); + // else if(i % 2 === 1) + // this.advice('short'); + + i++; + + } +}; + +module.exports = method; \ No newline at end of file diff --git a/strategies/DEMA.js b/strategies/DEMA.js index 95362af66..83ab0f73b 100644 --- a/strategies/DEMA.js +++ b/strategies/DEMA.js @@ -14,6 +14,7 @@ method.init = function() { // define the indicators we need this.addIndicator('dema', 'DEMA', this.settings); + this.addIndicator('sma', 'SMA', this.settings.weight); } // what happens on every new candle? @@ -24,21 +25,26 @@ method.update = function(candle) { // for debugging purposes: log the last calculated // EMAs and diff. method.log = function() { - var dema = this.indicators.dema; - - log.debug('calculated DEMA properties for candle:'); - log.debug('\t', 'long ema:', dema.long.result.toFixed(8)); - log.debug('\t', 'short ema:', dema.short.result.toFixed(8)); - log.debug('\t diff:', dema.result.toFixed(5)); - log.debug('\t DEMA age:', dema.short.age, 'candles'); + let dema = this.indicators.dema; + let sma = this.indicators.sma; + + log.debug('Calculated DEMA and SMA properties for candle:'); + log.debug('\t Inner EMA:', dema.inner.result.toFixed(8)); + log.debug('\t Outer EMA:', dema.outer.result.toFixed(8)); + log.debug('\t DEMA:', dema.result.toFixed(5)); + log.debug('\t SMA:', sma.result.toFixed(5)); + log.debug('\t DEMA age:', dema.inner.age, 'candles'); } method.check = function(candle) { - var dema = this.indicators.dema; - var diff = dema.result; - var price = candle.close; + let dema = this.indicators.dema; + let sma = this.indicators.sma; + let resDEMA = dema.result; + let resSMA = sma.result; + let price = candle.close; + let diff = resSMA - resDEMA; - var message = '@ ' + price.toFixed(8) + ' (' + diff.toFixed(5) + ')'; + let message = '@ ' + price.toFixed(8) + ' (' + resDEMA.toFixed(5) + '/' + diff.toFixed(5) + ')'; if(diff > this.settings.thresholds.up) { log.debug('we are currently in uptrend', message); diff --git a/strategies/TMA.js b/strategies/TMA.js new file mode 100644 index 000000000..7292153e5 --- /dev/null +++ b/strategies/TMA.js @@ -0,0 +1,34 @@ +var method = {}; + +method.init = function() { + this.name = 'Triple Moving Average'; + this.requiredHistory = this.settings.long; + + this.addIndicator('short', 'SMA', this.settings.short) + this.addIndicator('medium', 'SMA', this.settings.medium) + this.addIndicator('long', 'SMA', this.settings.long) +} + +method.update = function(candle) { + this.indicators.short.update(candle.close) + this.indicators.medium.update(candle.close) + this.indicators.long.update(candle.close) +} + +method.check = function() { + const short = this.indicators.short.result; + const medium = this.indicators.medium.result; + const long = this.indicators.long.result; + + if((short > medium) && (medium > long)) { + this.advice('long') + } else if((short < medium) && (medium > long)) { + this.advice('short') + } else if(((short > medium) && (medium < long))) { + this.advice('short') + } else { + this.advice(); + } +} + +module.exports = method; diff --git a/strategies/TSI.js b/strategies/TSI.js index 6089bb0cc..7f4cd64af 100644 --- a/strategies/TSI.js +++ b/strategies/TSI.js @@ -30,7 +30,7 @@ method.log = function(candle) { var digits = 8; var tsi = this.indicators.tsi; - log.debug('calculated Ultimate Oscillator properties for candle:'); + log.debug('calculated TSI properties for candle:'); log.debug('\t', 'tsi:', tsi.tsi.toFixed(digits)); log.debug('\t', 'price:', candle.close.toFixed(digits)); } diff --git a/strategies/indicators/DEMA.js b/strategies/indicators/DEMA.js index 75029cae7..39f076fef 100644 --- a/strategies/indicators/DEMA.js +++ b/strategies/indicators/DEMA.js @@ -2,26 +2,18 @@ var EMA = require('./EMA.js'); var Indicator = function(config) { - this.input = 'price' + this.input = 'price' this.result = false; - this.short = new EMA(config.short); - this.long = new EMA(config.long); + this.inner = new EMA(config.weight); + this.outer = new EMA(config.weight); } // add a price and calculate the EMAs and -// the diff for that price +// the result Indicator.prototype.update = function(price) { - this.short.update(price); - this.long.update(price); - this.calculateEMAdiff(); -} - -// @link https://github.com/virtimus/GoxTradingBot/blob/85a67d27b856949cf27440ae77a56d4a83e0bfbe/background.js#L145 -Indicator.prototype.calculateEMAdiff = function() { - var shortEMA = this.short.result; - var longEMA = this.long.result; - - this.result = 100 * (shortEMA - longEMA) / ((shortEMA + longEMA) / 2); + this.inner.update(price); + this.outer.update(this.inner.result); + this.result = 2 * this.inner.result - this.outer.result; } module.exports = Indicator; diff --git a/strategies/indicators/LRC.js b/strategies/indicators/LRC.js index a5d389cf1..5f3a29922 100644 --- a/strategies/indicators/LRC.js +++ b/strategies/indicators/LRC.js @@ -1,5 +1,5 @@ /* - * Lineair regression curve + * Linear regression curve */ var log = require('../../core/log'); diff --git a/strategies/indicators/TSI.js b/strategies/indicators/TSI.js index 2e4973250..9cf8ee5d7 100644 --- a/strategies/indicators/TSI.js +++ b/strategies/indicators/TSI.js @@ -3,7 +3,7 @@ var EMA = require('./EMA.js'); var Indicator = function(settings) { this.input = 'candle'; - this.lastClose = 0; + this.lastClose = null; this.tsi = 0; this.inner = new EMA(settings.long); this.outer = new EMA(settings.short); @@ -14,6 +14,14 @@ var Indicator = function(settings) { Indicator.prototype.update = function(candle) { var close = candle.close; var prevClose = this.lastClose; + + if (prevClose === null) { + // Set initial price to prevent invalid change calculation + this.lastClose = close; + // Do not calculate TSI on first close + return; + } + var momentum = close - prevClose; this.inner.update(momentum); diff --git a/strategies/varPPO.js b/strategies/varPPO.js index 4bcb479e8..3cd2536cf 100644 --- a/strategies/varPPO.js +++ b/strategies/varPPO.js @@ -37,10 +37,10 @@ method.update = function(candle) { // calculated parameters. method.log = function(candle) { var digits = 8; - var ppo = this.indicators.ppo; + var ppo = this.indicators.ppo.result; var result = ppo.ppo; - var signal = ppo.PPOsignal.result; - var hist = result - signal; + var signal = ppo.PPOsignal; + var hist = ppo.PPOhist; var momentumResult = this.indicators[momentumName][momentumName]; log.debug('\t', 'PPO:', result.toFixed(digits)); @@ -51,10 +51,8 @@ method.log = function(candle) { } method.check = function() { - var ppo = this.indicators.ppo; - var result = ppo.ppo; - var signal = ppo.PPOsignal.result; - var hist = result - signal; + var ppo = this.indicators.ppo.result; + var hist = ppo.PPOhist; var value = this.indicators[momentumName][momentumName]; diff --git a/test/indicators/dema.js b/test/indicators/dema.js index 105b7290f..406a5be07 100644 --- a/test/indicators/dema.js +++ b/test/indicators/dema.js @@ -9,26 +9,30 @@ var util = require('../../core/util'); var dirs = util.dirs(); var INDICATOR_PATH = dirs.indicators; -// Fake input prices to verify all indicators +// Fake input prices to verify all indicators // are working correctly by comparing fresh // calculated results to pre calculated results. -// The precalculated results are already compared +// The precalculated results are already compared // to MS Excel results, more info here: -// +// // https://github.com/askmike/gekko/issues/161 var prices = [81, 24, 75, 21, 34, 25, 72, 92, 99, 2, 86, 80, 76, 8, 87, 75, 32, 65, 41, 9, 13, 26, 56, 28, 65, 58, 17, 90, 87, 86, 99, 3, 70, 1, 27, 9, 92, 68, 9]; -xdescribe('indicators/DEMA', function() { +describe('indicators/DEMA', function() { var DEMA = require(INDICATOR_PATH + 'DEMA'); - xit('should correctly calculate DEMAs', function() { - // TODO! + var verified_dema10results = [81,62.157024793388416,65.1412471825695,49.61361928829999,42.570707415663364,34.597495090487996,44.47997295246192,58.6168391922143,71.4979863711489,48.963944850563,60.095241192962106,66.41965473810654,69.77997604557987,49.75572911767095,61.08641574881719,65.56112611350791,54.65374623818491,57.51231851211959,51.73955057939423,36.941596820151815,27.434153499662216,24.890025210750593,33.14097982029734,30.163817870645254,40.330715478873344,45.63811915119551,36.045947422710505,53.12735486322183,64.78921092296176,72.9995704035162,83.22304838955624,58.85287916072168,62.841348382387075,42.93804766689409,36.82301007497254,26.454331684513562,46.374329400503385,53.28360623846342,38.891184741941984]; + + it('should correctly calculate DEMA with weight 10', function() { + let dema = new DEMA({weight: 10}); + _.each(prices, function(p, i) { + dema.update(p); + expect(dema.result).to.equal(verified_dema10results[i]); + }); }); - - -}); \ No newline at end of file +}); diff --git a/util/genMarketFiles/update-binance.js b/util/genMarketFiles/update-binance.js new file mode 100644 index 000000000..64ebf31f5 --- /dev/null +++ b/util/genMarketFiles/update-binance.js @@ -0,0 +1,50 @@ +const _ = require('lodash'); +const fs = require('fs'); +const request = require('request-promise'); +const Promise = require('bluebird'); + +let getOrderMinSize = currency => { + if (currency === 'BTC') return 0.001; + else if (currency === 'ETH') return 0.01; + else if (currency === 'USDT') return 10; + else return 1; +}; + +const options = { + url: 'https://www.binance.com/exchange/public/product', + headers: { + Connection: 'keep-alive', + 'User-Agent': 'Request-Promise', + }, + json: true, +}; + +request(options) + .then(body => { + if (!body && !body.data) { + throw new Error('Unable to fetch product list, response was empty'); + } + + let assets = _.unique(_.map(body.data, market => market.baseAsset)); + let currencies = _.unique(_.map(body.data, market => market.quoteAsset)); + let pairs = _.map(body.data, market => { + return { + pair: [market.quoteAsset, market.baseAsset], + minimalOrder: { + amount: parseFloat(market.minTrade), + price: parseFloat(market.tickSize), + order: getOrderMinSize(market.quoteAsset), + }, + }; + }); + + return { assets: assets, currencies: currencies, markets: pairs }; + }) + .then(markets => { + fs.writeFileSync('../../exchanges/binance-markets.json', JSON.stringify(markets, null, 2)); + console.log(`Done writing Binance market data`); + }) + .catch(err => { + console.log(`Couldn't import products from Binance`); + console.log(err); + }); diff --git a/util/genMarketFiles/update-bitfinex.js b/util/genMarketFiles/update-bitfinex.js new file mode 100644 index 000000000..5b129bd16 --- /dev/null +++ b/util/genMarketFiles/update-bitfinex.js @@ -0,0 +1,54 @@ +const _ = require('lodash'); +const fs = require('fs'); +const request = require('request-promise'); +const Promise = require('bluebird'); + +request({ + url: 'https://api.bitfinex.com/v1/symbols_details', + headers: { + Connection: 'keep-alive', + 'User-Agent': 'Request-Promise', + }, + json: true, +}) +.then(body => { + if (!body) { + throw new Error('Unable to fetch list of assets, response was empty'); + } + + return body; +}) +.then(results => { + let assets = _.unique(_.map(results, market => { + return market.pair.substring(0, 3).toUpperCase(); + })); + + let currencies = _.unique(_.map(results, market => { + return market.pair.substring(3, 6).toUpperCase(); + })); + + let markets = _.map(results, market => { + return { + pair: [ + market.pair.substring(3, 6).toUpperCase(), + market.pair.substring(0, 3).toUpperCase() + ], + minimalOrder: { + amount: market.minimum_order_size, + unit: 'asset', + }, + }; + }); + + return { assets: assets, currencies: currencies, markets: markets }; +}) +.then(markets => { + fs.writeFileSync('../../exchanges/bitfinex-markets.json', JSON.stringify(markets, null, 2)); + console.log(`Done writing Bitfinex market data`); +}) +.catch(err => { + console.log(`Couldn't import products from Bitfinex`); + console.log(err); +}); + + diff --git a/util/genMarketFiles/update-coinfalcon.js b/util/genMarketFiles/update-coinfalcon.js new file mode 100644 index 000000000..b63000f5c --- /dev/null +++ b/util/genMarketFiles/update-coinfalcon.js @@ -0,0 +1,45 @@ +const _ = require('lodash'); +const fs = require('fs'); +const request = require('request-promise'); +const Promise = require('bluebird'); + +const options = { + url: 'https://coinfalcon.com/api/v1/markets', + headers: { + Connection: 'keep-alive', + 'User-Agent': 'Request-Promise', + }, + json: true, +}; + +request(options) + .then(body => { + if (!body && !body.data) { + throw new Error('Unable to fetch product list, response was empty'); + } + + let assets = _.unique(_.map(body.data, market => market.name.split('-')[0])); + let currencies = _.unique(_.map(body.data, market => market.name.split('-')[1])); + let pairs = _.map(body.data, market => { + var currency = market.name.split('-')[1]; + var asset = market.name.split('-')[0]; + return { + pair: [currency, asset], + minimalOrder: { + amount: parseFloat(market.min_volume), + price: parseFloat(market.min_price), + order: 0.0 + }, + }; + }); + + return { assets: assets, currencies: currencies, markets: pairs }; + }) + .then(markets => { + fs.writeFileSync('../../exchanges/coinfalcon-markets.json', JSON.stringify(markets, null, 2)); + console.log(`Done writing CoinFalcon market data`); + }) + .catch(err => { + console.log(`Couldn't import products from CoinFalcon`); + console.log(err); + }); diff --git a/util/genMarketFiles/update-kraken.js b/util/genMarketFiles/update-kraken.js new file mode 100644 index 000000000..8a34ce34a --- /dev/null +++ b/util/genMarketFiles/update-kraken.js @@ -0,0 +1,142 @@ +const _ = require('lodash'); +const fs = require('fs'); +const request = require('request-promise'); +const Promise = require('bluebird'); + +// Minimum amounts are not queryable, get them here +// https://support.kraken.com/hc/en-us/articles/205893708-What-is-the-minimum-order-size- + +let getMinTradeSize = asset => { + let minTradeSize = 0.01; + switch (asset) { + case 'XREP': + minTradeSize = '0.3' + break; + case 'XBT': + minTradeSize = '0.002' + break; + case 'BCH': + minTradeSize = '0.002' + break; + case 'DASH': + minTradeSize = '0.03' + break; + case 'EOS': + minTradeSize = '3.0' + break; + case 'XETH': + minTradeSize = '0.02' + break; + case 'XETC': + minTradeSize = '0.3' + break; + case 'GNO': + minTradeSize = '0.03' + break; + case 'XICN': + minTradeSize = '2.0' + break; + case 'XLTC': + minTradeSize = '0.1' + break; + case 'XMLN': + minTradeSize = '0.1' + break; + case 'XLTC': + minTradeSize = '0.1' + break; + case 'XXMR': + minTradeSize = '0.1' + break; + case 'XXRP': + minTradeSize = '30' + break; + case 'XXLM': + minTradeSize = '300' + break; + case 'XZEC': + minTradeSize = '0.03' + break; + case 'USDT': + minTradeSize = '5' + break; + default: + break; + } + + return minTradeSize; +} + +let assetPromise = request({ + url: 'https://api.kraken.com/0/public/Assets', + headers: { + Connection: 'keep-alive', + 'User-Agent': 'Request-Promise', + }, + json: true, +}).then(body => { + if (!body || !body.result) { + throw new Error('Unable to fetch list of assets, response was empty') + } else if (!_.isEmpty(body.error)) { + throw new Error(`Unable to fetch list of assets: ${body.error}`); + } + + return body.result; +}); + +let assetPairsPromise = request({ + url: 'https://api.kraken.com/0/public/AssetPairs', + headers: { + Connection: 'keep-alive', + 'User-Agent': 'Request-Promise', + }, + json: true, +}).then(body => { + if (!body || !body.result) { + throw new Error('Unable to fetch list of assets, response was empty') + } else if (!_.isEmpty(body.error)) { + throw new Error(`Unable to fetch list of assets: ${body.error}`); + } + + return body.result; +}); + +Promise.all([assetPromise, assetPairsPromise]) + .then(results => { + let assets = _.unique(_.map(results[1], market => { + return results[0][market.base].altname; + })); + + let currencies = _.unique(_.map(results[1], market => { + return results[0][market.quote].altname; + })); + + let marketKeys = _.filter(_.keys(results[1]), k => { return !k.endsWith('.d'); }); + let markets = _.map(marketKeys, k => { + let market = results[1][k]; + let asset = results[0][market.base]; + let currency = results[0][market.quote]; + return { + pair: [currency.altname, asset.altname], + prefixed: [market.quote, market.base], + book: k, + minimalOrder: { + amount: getMinTradeSize(market.base), + unit: 'asset', + }, + precision: market.pair_decimals + }; + }); + + return { assets: assets, currencies: currencies, markets: markets }; + }) + .then(markets => { + fs.writeFileSync('../../exchanges/kraken-markets.json', JSON.stringify(markets, null, 2)); + console.log(`Done writing Kraken market data`); + }) + .catch(err => { + console.log(`Couldn't import products from Kraken`); + console.log(err); + }); + + diff --git a/web/routes/baseConfig.js b/web/routes/baseConfig.js index 214ab1f97..98dbb1506 100644 --- a/web/routes/baseConfig.js +++ b/web/routes/baseConfig.js @@ -24,6 +24,10 @@ config.adviceWriter = { muteSoft: true, } +config.trader = { + orderUpdateDelay: 1 // Number of minutes to adjust unfilled order prices +} + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CONFIGURING ADAPTER // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/web/routes/startGekko.js b/web/routes/startGekko.js index 507bab964..e628134bf 100644 --- a/web/routes/startGekko.js +++ b/web/routes/startGekko.js @@ -83,7 +83,10 @@ module.exports = function *() { }); } - if(!event) + if(event && event.log) + return logger.write(event.log); + + if(!event || !event.type) return; if(event.type === 'trade') { @@ -112,13 +115,10 @@ module.exports = function *() { } broadcast(wsEvent); return; - } else if(event.log) { - logger.write(event.log); } let updates = {}; - if(event.type === 'update') { updates.latest = event.latest; } else { @@ -176,4 +176,4 @@ module.exports = function *() { }); this.body = gekko; -} \ No newline at end of file +} diff --git a/web/vue/dist/build.js b/web/vue/dist/build.js index 79238b555..f5c352eeb 100644 --- a/web/vue/dist/build.js +++ b/web/vue/dist/build.js @@ -1,9 +1,9 @@ -!function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/dist/",e(e.s=70)}([function(t,e){t.exports=function(){var t=[];return t.toString=function(){for(var t=[],e=0;e=0&&m.splice(e,1)}function a(t){var e=document.createElement("style");return e.type="text/css",i(t,e),e}function s(t,e){var n,r,i;if(e.singleton){var s=v++;n=h||(h=a(e)),r=u.bind(null,n,s,!1),i=u.bind(null,n,s,!0)}else n=a(e),r=c.bind(null,n),i=function(){o(n)};return r(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;r(t=e)}else i()}}function u(t,e,n,r){var i=n?"":r.css;if(t.styleSheet)t.styleSheet.cssText=g(e,i);else{var o=document.createTextNode(i),a=t.childNodes;a[e]&&t.removeChild(a[e]),a.length?t.insertBefore(o,a[e]):t.appendChild(o)}}function c(t,e){var n=e.css,r=e.media,i=e.sourceMap;if(r&&t.setAttribute("media",r),i&&(n+="\n/*# sourceURL="+i.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(i))))+" */"),t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}var l={},f=function(t){var e;return function(){return void 0===e&&(e=t.apply(this,arguments)),e}},d=f(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),p=f(function(){return document.head||document.getElementsByTagName("head")[0]}),h=null,v=0,m=[];t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");e=e||{},void 0===e.singleton&&(e.singleton=d()),void 0===e.insertAt&&(e.insertAt="bottom");var i=r(t);return n(i,e),function(t){for(var o=[],a=0;a-1}function h(t,e,n){for(var r=-1,i=null==t?0:t.length;++r-1;);return n}function L(t,e){for(var n=t.length;n--&&C(e,t[n],0)>-1;);return n}function z(t,e){for(var n=t.length,r=0;n--;)t[n]===e&&++r;return r}function V(t){return"\\"+$n[t]}function U(t,e){return null==t?it:t[e]}function q(t){return yn.test(t)}function H(t){return bn.test(t)}function W(t){for(var e,n=[];!(e=t.next()).done;)n.push(e.value);return n}function B(t){var e=-1,n=Array(t.size);return t.forEach(function(t,r){n[++e]=[r,t]}),n}function Y(t,e){return function(n){return t(e(n))}}function G(t,e){for(var n=-1,r=t.length,i=0,o=[];++n>>1,Lt=[["ary",kt],["bind",mt],["bindKey",gt],["curry",yt],["curryRight",bt],["flip",Et],["partial",xt],["partialRight",wt],["rearg",Ct]],zt="[object Arguments]",Vt="[object Array]",Ut="[object AsyncFunction]",qt="[object Boolean]",Ht="[object Date]",Wt="[object DOMException]",Bt="[object Error]",Yt="[object Function]",Gt="[object GeneratorFunction]",Kt="[object Map]",Xt="[object Number]",Jt="[object Null]",Zt="[object Object]",Qt="[object Proxy]",te="[object RegExp]",ee="[object Set]",ne="[object String]",re="[object Symbol]",ie="[object Undefined]",oe="[object WeakMap]",ae="[object WeakSet]",se="[object ArrayBuffer]",ue="[object DataView]",ce="[object Float32Array]",le="[object Float64Array]",fe="[object Int8Array]",de="[object Int16Array]",pe="[object Int32Array]",he="[object Uint8Array]",ve="[object Uint8ClampedArray]",me="[object Uint16Array]",ge="[object Uint32Array]",_e=/\b__p \+= '';/g,ye=/\b(__p \+=) '' \+/g,be=/(__e\(.*?\)|\b__t\)) \+\n'';/g,xe=/&(?:amp|lt|gt|quot|#39);/g,we=/[&<>"']/g,ke=RegExp(xe.source),Ce=RegExp(we.source),Ee=/<%-([\s\S]+?)%>/g,Oe=/<%([\s\S]+?)%>/g,Ae=/<%=([\s\S]+?)%>/g,$e=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Se=/^\w*$/,je=/^\./,Te=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Ne=/[\\^$.*+?()[\]{}|]/g,Re=RegExp(Ne.source),De=/^\s+|\s+$/g,Pe=/^\s+/,Me=/\s+$/,Ie=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Fe=/\{\n\/\* \[wrapped with (.+)\] \*/,Le=/,? & /,ze=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Ve=/\\(\\)?/g,Ue=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,qe=/\w*$/,He=/^[-+]0x[0-9a-f]+$/i,We=/^0b[01]+$/i,Be=/^\[object .+?Constructor\]$/,Ye=/^0o[0-7]+$/i,Ge=/^(?:0|[1-9]\d*)$/,Ke=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Xe=/($^)/,Je=/['\n\r\u2028\u2029\\]/g,Ze="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",Qe="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",tn="["+Qe+"]",en="["+Ze+"]",nn="[a-z\\xdf-\\xf6\\xf8-\\xff]",rn="[^\\ud800-\\udfff"+Qe+"\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",on="\\ud83c[\\udffb-\\udfff]",an="(?:\\ud83c[\\udde6-\\uddff]){2}",sn="[\\ud800-\\udbff][\\udc00-\\udfff]",un="[A-Z\\xc0-\\xd6\\xd8-\\xde]",cn="(?:"+nn+"|"+rn+")",ln="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",fn="(?:\\u200d(?:"+["[^\\ud800-\\udfff]",an,sn].join("|")+")[\\ufe0e\\ufe0f]?"+ln+")*",dn="[\\ufe0e\\ufe0f]?"+ln+fn,pn="(?:"+["[\\u2700-\\u27bf]",an,sn].join("|")+")"+dn,hn="(?:"+["[^\\ud800-\\udfff]"+en+"?",en,an,sn,"[\\ud800-\\udfff]"].join("|")+")",vn=RegExp("['’]","g"),mn=RegExp(en,"g"),gn=RegExp(on+"(?="+on+")|"+hn+dn,"g"),_n=RegExp([un+"?"+nn+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[tn,un,"$"].join("|")+")","(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[tn,un+cn,"$"].join("|")+")",un+"?"+cn+"+(?:['’](?:d|ll|m|re|s|t|ve))?",un+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)","\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)","\\d+",pn].join("|"),"g"),yn=RegExp("[\\u200d\\ud800-\\udfff"+Ze+"\\ufe0e\\ufe0f]"),bn=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,xn=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],wn=-1,kn={};kn[ce]=kn[le]=kn[fe]=kn[de]=kn[pe]=kn[he]=kn[ve]=kn[me]=kn[ge]=!0,kn[zt]=kn[Vt]=kn[se]=kn[qt]=kn[ue]=kn[Ht]=kn[Bt]=kn[Yt]=kn[Kt]=kn[Xt]=kn[Zt]=kn[te]=kn[ee]=kn[ne]=kn[oe]=!1;var Cn={};Cn[zt]=Cn[Vt]=Cn[se]=Cn[ue]=Cn[qt]=Cn[Ht]=Cn[ce]=Cn[le]=Cn[fe]=Cn[de]=Cn[pe]=Cn[Kt]=Cn[Xt]=Cn[Zt]=Cn[te]=Cn[ee]=Cn[ne]=Cn[re]=Cn[he]=Cn[ve]=Cn[me]=Cn[ge]=!0,Cn[Bt]=Cn[Yt]=Cn[oe]=!1;var En={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"},On={"&":"&","<":"<",">":">",'"':""","'":"'"},An={"&":"&","<":"<",">":">",""":'"',"'":"'"},$n={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Sn=parseFloat,jn=parseInt,Tn="object"==typeof t&&t&&t.Object===Object&&t,Nn="object"==typeof self&&self&&self.Object===Object&&self,Rn=Tn||Nn||Function("return this")(),Dn="object"==typeof e&&e&&!e.nodeType&&e,Pn=Dn&&"object"==typeof r&&r&&!r.nodeType&&r,Mn=Pn&&Pn.exports===Dn,In=Mn&&Tn.process,Fn=function(){try{return In&&In.binding&&In.binding("util")}catch(t){}}(),Ln=Fn&&Fn.isArrayBuffer,zn=Fn&&Fn.isDate,Vn=Fn&&Fn.isMap,Un=Fn&&Fn.isRegExp,qn=Fn&&Fn.isSet,Hn=Fn&&Fn.isTypedArray,Wn=$("length"),Bn=S(En),Yn=S(On),Gn=S(An),Kn=function t(e){function n(t){if(ou(t)&&!gd(t)&&!(t instanceof b)){if(t instanceof i)return t;if(ml.call(t,"__wrapped__"))return na(t)}return new i(t)}function r(){}function i(t,e){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!e,this.__index__=0,this.__values__=it}function b(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=Mt,this.__views__=[]}function S(){var t=new b(this.__wrapped__);return t.__actions__=Ii(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=Ii(this.__iteratees__),t.__takeCount__=this.__takeCount__,t.__views__=Ii(this.__views__),t}function J(){if(this.__filtered__){var t=new b(this);t.__dir__=-1,t.__filtered__=!0}else t=this.clone(),t.__dir__*=-1;return t}function et(){var t=this.__wrapped__.value(),e=this.__dir__,n=gd(t),r=e<0,i=n?t.length:0,o=Ao(0,i,this.__views__),a=o.start,s=o.end,u=s-a,c=r?s:a-1,l=this.__iteratees__,f=l.length,d=0,p=Bl(u,this.__takeCount__);if(!n||!r&&i==u&&p==u)return _i(t,this.__actions__);var h=[];t:for(;u--&&d-1}function un(t,e){var n=this.__data__,r=Xn(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this}function cn(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e=e?t:e)),t}function rr(t,e,n,r,i,o){var a,s=e&ft,u=e&dt,l=e&pt;if(n&&(a=i?n(t,r,i,o):n(t)),a!==it)return a;if(!iu(t))return t;var f=gd(t);if(f){if(a=jo(t),!s)return Ii(t,a)}else{var d=Af(t),p=d==Yt||d==Gt;if(yd(t))return Ei(t,s);if(d==Zt||d==zt||p&&!i){if(a=u||p?{}:To(t),!s)return u?zi(t,Qn(a,t)):Li(t,Zn(a,t))}else{if(!Cn[d])return i?t:{};a=No(t,d,rr,s)}}o||(o=new bn);var h=o.get(t);if(h)return h;o.set(t,a);var v=l?u?yo:_o:u?Vu:zu,m=f?it:v(t);return c(m||t,function(r,i){m&&(i=r,r=t[i]),Wn(a,i,rr(r,e,n,i,t,o))}),a}function ir(t){var e=zu(t);return function(n){return or(n,t,e)}}function or(t,e,n){var r=n.length;if(null==t)return!r;for(t=sl(t);r--;){var i=n[r],o=e[i],a=t[i];if(a===it&&!(i in t)||!o(a))return!1}return!0}function ar(t,e,n){if("function"!=typeof t)throw new ll(st);return jf(function(){t.apply(it,n)},e)}function sr(t,e,n,r){var i=-1,o=p,a=!0,s=t.length,u=[],c=e.length;if(!s)return u;n&&(e=v(e,P(n))),r?(o=h,a=!1):e.length>=ot&&(o=I,a=!1,e=new gn(e));t:for(;++ii?0:i+n),r=r===it||r>i?i:wu(r),r<0&&(r+=i),r=n>r?0:ku(r);n0&&n(s)?e>1?dr(s,e-1,n,r,i):m(i,s):r||(i[i.length]=s)}return i}function pr(t,e){return t&&gf(t,e,zu)}function hr(t,e){return t&&_f(t,e,zu)}function vr(t,e){return d(e,function(e){return eu(t[e])})}function mr(t,e){e=ki(e,t);for(var n=0,r=e.length;null!=t&&ne}function br(t,e){return null!=t&&ml.call(t,e)}function xr(t,e){return null!=t&&e in sl(t)}function wr(t,e,n){return t>=Bl(e,n)&&t=120&&l.length>=120)?new gn(a&&l):it}l=t[0];var f=-1,d=s[0];t:for(;++f-1;)s!==t&&jl.call(s,u,1),jl.call(t,u,1);return t}function Zr(t,e){for(var n=t?e.length:0,r=n-1;n--;){var i=e[n];if(n==r||i!==o){var o=i;Po(i)?jl.call(t,i,1):vi(t,i)}}return t}function Qr(t,e){return t+Ll(Kl()*(e-t+1))}function ti(t,e,n,r){for(var i=-1,o=Wl(Fl((e-t)/(n||1)),0),a=nl(o);o--;)a[r?o:++i]=t,t+=n;return a}function ei(t,e){var n="";if(!t||e<1||e>Rt)return n;do{e%2&&(n+=t),(e=Ll(e/2))&&(t+=t)}while(e);return n}function ni(t,e){return Tf(Yo(t,e,jc),t+"")}function ri(t){return Dn(Qu(t))}function ii(t,e){var n=Qu(t);return Zo(n,nr(e,0,n.length))}function oi(t,e,n,r){if(!iu(t))return t;e=ki(e,t);for(var i=-1,o=e.length,a=o-1,s=t;null!=s&&++ii?0:i+e),n=n>i?i:n,n<0&&(n+=i),i=e>n?0:n-e>>>0,e>>>=0;for(var o=nl(i);++r>>1,a=t[o];null!==a&&!mu(a)&&(n?a<=e:a=ot){var c=e?null:kf(t);if(c)return K(c);a=!1,i=I,u=new gn}else u=e?[]:s;t:for(;++r=r?t:si(t,e,n)}function Ei(t,e){if(e)return t.slice();var n=t.length,r=Ol?Ol(n):new t.constructor(n);return t.copy(r),r}function Oi(t){var e=new t.constructor(t.byteLength);return new El(e).set(new El(t)),e}function Ai(t,e){var n=e?Oi(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)}function $i(t,e,n){return g(e?n(B(t),ft):B(t),o,new t.constructor)}function Si(t){var e=new t.constructor(t.source,qe.exec(t));return e.lastIndex=t.lastIndex,e}function ji(t,e,n){return g(e?n(K(t),ft):K(t),a,new t.constructor)}function Ti(t){return df?sl(df.call(t)):{}}function Ni(t,e){var n=e?Oi(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.length)}function Ri(t,e){if(t!==e){var n=t!==it,r=null===t,i=t===t,o=mu(t),a=e!==it,s=null===e,u=e===e,c=mu(e);if(!s&&!c&&!o&&t>e||o&&a&&u&&!s&&!c||r&&a&&u||!n&&u||!i)return 1;if(!r&&!o&&!c&&t=s)return u;return u*("desc"==n[r]?-1:1)}}return t.index-e.index}function Pi(t,e,n,r){for(var i=-1,o=t.length,a=n.length,s=-1,u=e.length,c=Wl(o-a,0),l=nl(u+c),f=!r;++s1?n[i-1]:it,a=i>2?n[2]:it;for(o=t.length>3&&"function"==typeof o?(i--,o):it,a&&Mo(n[0],n[1],a)&&(o=i<3?it:o,i=1),e=sl(e);++r-1?i[o?e[a]:a]:it}}function Ji(t){return go(function(e){var n=e.length,r=n,o=i.prototype.thru;for(t&&e.reverse();r--;){var a=e[r];if("function"!=typeof a)throw new ll(st);if(o&&!s&&"wrapper"==bo(a))var s=new i([],!0)}for(r=s?r:n;++r1&&_.reverse(),f&&us))return!1;var c=o.get(t);if(c&&o.get(e))return c==e;var l=-1,f=!0,d=n&vt?new gn:it;for(o.set(t,e),o.set(e,t);++l1?"& ":"")+e[r],e=e.join(n>2?", ":" "),t.replace(Ie,"{\n/* [wrapped with "+e+"] */\n")}function Do(t){return gd(t)||md(t)||!!(Tl&&t&&t[Tl])}function Po(t,e){return!!(e=null==e?Rt:e)&&("number"==typeof t||Ge.test(t))&&t>-1&&t%1==0&&t0){if(++e>=$t)return arguments[0]}else e=0;return t.apply(it,arguments)}}function Zo(t,e){var n=-1,r=t.length,i=r-1;for(e=e===it?r:e;++n=this.__values__.length;return{done:t,value:t?it:this.__values__[this.__index__++]}}function ns(){return this}function rs(t){for(var e,n=this;n instanceof r;){var i=na(n);i.__index__=0,i.__values__=it,e?o.__wrapped__=i:e=i;var o=i;n=n.__wrapped__}return o.__wrapped__=t,e}function is(){var t=this.__wrapped__;if(t instanceof b){var e=t;return this.__actions__.length&&(e=new b(this)),e=e.reverse(),e.__actions__.push({func:Za,args:[$a],thisArg:it}),new i(e,this.__chain__)}return this.thru($a)}function os(){return _i(this.__wrapped__,this.__actions__)}function as(t,e,n){var r=gd(t)?f:ur;return n&&Mo(t,e,n)&&(e=it),r(t,wo(e,3))}function ss(t,e){return(gd(t)?d:fr)(t,wo(e,3))}function us(t,e){return dr(hs(t,e),1)}function cs(t,e){return dr(hs(t,e),Nt)}function ls(t,e,n){return n=n===it?1:wu(n),dr(hs(t,e),n)}function fs(t,e){return(gd(t)?c:vf)(t,wo(e,3))}function ds(t,e){return(gd(t)?l:mf)(t,wo(e,3))}function ps(t,e,n,r){t=Bs(t)?t:Qu(t),n=n&&!r?wu(n):0;var i=t.length;return n<0&&(n=Wl(i+n,0)),vu(t)?n<=i&&t.indexOf(e,n)>-1:!!i&&C(t,e,n)>-1}function hs(t,e){return(gd(t)?v:Vr)(t,wo(e,3))}function vs(t,e,n,r){return null==t?[]:(gd(e)||(e=null==e?[]:[e]),n=r?it:n,gd(n)||(n=null==n?[]:[n]),Yr(t,e,n))}function ms(t,e,n){var r=gd(t)?g:j,i=arguments.length<3;return r(t,wo(e,4),n,i,vf)}function gs(t,e,n){var r=gd(t)?_:j,i=arguments.length<3;return r(t,wo(e,4),n,i,mf)}function _s(t,e){return(gd(t)?d:fr)(t,Ns(wo(e,3)))}function ys(t){return(gd(t)?Dn:ri)(t)}function bs(t,e,n){return e=(n?Mo(t,e,n):e===it)?1:wu(e),(gd(t)?Pn:ii)(t,e)}function xs(t){return(gd(t)?In:ai)(t)}function ws(t){if(null==t)return 0;if(Bs(t))return vu(t)?Q(t):t.length;var e=Af(t);return e==Kt||e==ee?t.size:Fr(t).length}function ks(t,e,n){var r=gd(t)?y:ui;return n&&Mo(t,e,n)&&(e=it),r(t,wo(e,3))}function Cs(t,e){if("function"!=typeof e)throw new ll(st);return t=wu(t),function(){if(--t<1)return e.apply(this,arguments)}}function Es(t,e,n){return e=n?it:e,e=t&&null==e?t.length:e,co(t,kt,it,it,it,it,e)}function Os(t,e){var n;if("function"!=typeof e)throw new ll(st);return t=wu(t),function(){return--t>0&&(n=e.apply(this,arguments)),t<=1&&(e=it),n}}function As(t,e,n){e=n?it:e;var r=co(t,yt,it,it,it,it,it,e);return r.placeholder=As.placeholder,r}function $s(t,e,n){e=n?it:e;var r=co(t,bt,it,it,it,it,it,e);return r.placeholder=$s.placeholder,r}function Ss(t,e,n){function r(e){var n=d,r=p;return d=p=it,_=e,v=t.apply(r,n)}function i(t){return _=t,m=jf(s,e),y?r(t):v}function o(t){var n=t-g,r=t-_,i=e-n;return b?Bl(i,h-r):i}function a(t){var n=t-g,r=t-_;return g===it||n>=e||n<0||b&&r>=h}function s(){var t=od();if(a(t))return u(t);m=jf(s,o(t))}function u(t){return m=it,x&&d?r(t):(d=p=it,v)}function c(){m!==it&&wf(m),_=0,d=g=p=m=it}function l(){return m===it?v:u(od())}function f(){var t=od(),n=a(t);if(d=arguments,p=this,g=t,n){if(m===it)return i(g);if(b)return m=jf(s,e),r(g)}return m===it&&(m=jf(s,e)),v}var d,p,h,v,m,g,_=0,y=!1,b=!1,x=!0;if("function"!=typeof t)throw new ll(st);return e=Cu(e)||0,iu(n)&&(y=!!n.leading,b="maxWait"in n,h=b?Wl(Cu(n.maxWait)||0,e):h,x="trailing"in n?!!n.trailing:x),f.cancel=c,f.flush=l,f}function js(t){return co(t,Et)}function Ts(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new ll(st);var n=function(){var r=arguments,i=e?e.apply(this,r):r[0],o=n.cache;if(o.has(i))return o.get(i);var a=t.apply(this,r);return n.cache=o.set(i,a)||o,a};return n.cache=new(Ts.Cache||cn),n}function Ns(t){if("function"!=typeof t)throw new ll(st);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}function Rs(t){return Os(2,t)}function Ds(t,e){if("function"!=typeof t)throw new ll(st);return e=e===it?e:wu(e),ni(t,e)}function Ps(t,e){if("function"!=typeof t)throw new ll(st);return e=null==e?0:Wl(wu(e),0),ni(function(n){var r=n[e],i=Ci(n,0,e);return r&&m(i,r),s(t,this,i)})}function Ms(t,e,n){var r=!0,i=!0;if("function"!=typeof t)throw new ll(st);return iu(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),Ss(t,e,{leading:r,maxWait:e,trailing:i})}function Is(t){return Es(t,1)}function Fs(t,e){return fd(wi(e),t)}function Ls(){if(!arguments.length)return[];var t=arguments[0];return gd(t)?t:[t]}function zs(t){return rr(t,pt)}function Vs(t,e){return e="function"==typeof e?e:it,rr(t,pt,e)}function Us(t){return rr(t,ft|pt)}function qs(t,e){return e="function"==typeof e?e:it,rr(t,ft|pt,e)}function Hs(t,e){return null==e||or(t,e,zu(e))}function Ws(t,e){return t===e||t!==t&&e!==e}function Bs(t){return null!=t&&ru(t.length)&&!eu(t)}function Ys(t){return ou(t)&&Bs(t)}function Gs(t){return!0===t||!1===t||ou(t)&&_r(t)==qt}function Ks(t){return ou(t)&&1===t.nodeType&&!pu(t)}function Xs(t){if(null==t)return!0;if(Bs(t)&&(gd(t)||"string"==typeof t||"function"==typeof t.splice||yd(t)||Cd(t)||md(t)))return!t.length;var e=Af(t);if(e==Kt||e==ee)return!t.size;if(Vo(t))return!Fr(t).length;for(var n in t)if(ml.call(t,n))return!1;return!0}function Js(t,e){return Sr(t,e)}function Zs(t,e,n){n="function"==typeof n?n:it;var r=n?n(t,e):it;return r===it?Sr(t,e,it,n):!!r}function Qs(t){if(!ou(t))return!1;var e=_r(t);return e==Bt||e==Wt||"string"==typeof t.message&&"string"==typeof t.name&&!pu(t)}function tu(t){return"number"==typeof t&&Ul(t)}function eu(t){if(!iu(t))return!1;var e=_r(t);return e==Yt||e==Gt||e==Ut||e==Qt}function nu(t){return"number"==typeof t&&t==wu(t)}function ru(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=Rt}function iu(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function ou(t){return null!=t&&"object"==typeof t}function au(t,e){return t===e||Nr(t,e,Co(e))}function su(t,e,n){return n="function"==typeof n?n:it,Nr(t,e,Co(e),n)}function uu(t){return du(t)&&t!=+t}function cu(t){if($f(t))throw new il(at);return Rr(t)}function lu(t){return null===t}function fu(t){return null==t}function du(t){return"number"==typeof t||ou(t)&&_r(t)==Xt}function pu(t){if(!ou(t)||_r(t)!=Zt)return!1;var e=Al(t);if(null===e)return!0;var n=ml.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&vl.call(n)==bl}function hu(t){return nu(t)&&t>=-Rt&&t<=Rt}function vu(t){return"string"==typeof t||!gd(t)&&ou(t)&&_r(t)==ne}function mu(t){return"symbol"==typeof t||ou(t)&&_r(t)==re}function gu(t){return t===it}function _u(t){return ou(t)&&Af(t)==oe}function yu(t){return ou(t)&&_r(t)==ae}function bu(t){if(!t)return[];if(Bs(t))return vu(t)?tt(t):Ii(t);if(Nl&&t[Nl])return W(t[Nl]());var e=Af(t);return(e==Kt?B:e==ee?K:Qu)(t)}function xu(t){if(!t)return 0===t?t:0;if((t=Cu(t))===Nt||t===-Nt){return(t<0?-1:1)*Dt}return t===t?t:0}function wu(t){var e=xu(t),n=e%1;return e===e?n?e-n:e:0}function ku(t){return t?nr(wu(t),0,Mt):0}function Cu(t){if("number"==typeof t)return t;if(mu(t))return Pt;if(iu(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=iu(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(De,"");var n=We.test(t);return n||Ye.test(t)?jn(t.slice(2),n?2:8):He.test(t)?Pt:+t}function Eu(t){return Fi(t,Vu(t))}function Ou(t){return t?nr(wu(t),-Rt,Rt):0===t?t:0}function Au(t){return null==t?"":pi(t)}function $u(t,e){var n=hf(t);return null==e?n:Zn(n,e)}function Su(t,e){return w(t,wo(e,3),pr)}function ju(t,e){return w(t,wo(e,3),hr)}function Tu(t,e){return null==t?t:gf(t,wo(e,3),Vu)}function Nu(t,e){return null==t?t:_f(t,wo(e,3),Vu)}function Ru(t,e){return t&&pr(t,wo(e,3))}function Du(t,e){return t&&hr(t,wo(e,3))}function Pu(t){return null==t?[]:vr(t,zu(t))}function Mu(t){return null==t?[]:vr(t,Vu(t))}function Iu(t,e,n){var r=null==t?it:mr(t,e);return r===it?n:r}function Fu(t,e){return null!=t&&So(t,e,br)}function Lu(t,e){return null!=t&&So(t,e,xr)}function zu(t){return Bs(t)?Nn(t):Fr(t)}function Vu(t){return Bs(t)?Nn(t,!0):Lr(t)}function Uu(t,e){var n={};return e=wo(e,3),pr(t,function(t,r,i){tr(n,e(t,r,i),t)}),n}function qu(t,e){var n={};return e=wo(e,3),pr(t,function(t,r,i){tr(n,r,e(t,r,i))}),n}function Hu(t,e){return Wu(t,Ns(wo(e)))}function Wu(t,e){if(null==t)return{};var n=v(yo(t),function(t){return[t]});return e=wo(e),Kr(t,n,function(t,n){return e(t,n[0])})}function Bu(t,e,n){e=ki(e,t);var r=-1,i=e.length;for(i||(i=1,t=it);++re){var r=t;t=e,e=r}if(n||t%1||e%1){var i=Kl();return Bl(t+i*(e-t+Sn("1e-"+((i+"").length-1))),e)}return Qr(t,e)}function ic(t){return Xd(Au(t).toLowerCase())}function oc(t){return(t=Au(t))&&t.replace(Ke,Bn).replace(mn,"")}function ac(t,e,n){t=Au(t),e=pi(e);var r=t.length;n=n===it?r:nr(wu(n),0,r);var i=n;return(n-=e.length)>=0&&t.slice(n,i)==e}function sc(t){return t=Au(t),t&&Ce.test(t)?t.replace(we,Yn):t}function uc(t){return t=Au(t),t&&Re.test(t)?t.replace(Ne,"\\$&"):t}function cc(t,e,n){t=Au(t),e=wu(e);var r=e?Q(t):0;if(!e||r>=e)return t;var i=(e-r)/2;return no(Ll(i),n)+t+no(Fl(i),n)}function lc(t,e,n){t=Au(t),e=wu(e);var r=e?Q(t):0;return e&&r>>0)?(t=Au(t),t&&("string"==typeof e||null!=e&&!wd(e))&&!(e=pi(e))&&q(t)?Ci(tt(t),0,n):t.split(e,n)):[]}function mc(t,e,n){return t=Au(t),n=null==n?0:nr(wu(n),0,t.length),e=pi(e),t.slice(n,n+e.length)==e}function gc(t,e,r){var i=n.templateSettings;r&&Mo(t,e,r)&&(e=it),t=Au(t),e=Sd({},e,i,lo);var o,a,s=Sd({},e.imports,i.imports,lo),u=zu(s),c=M(s,u),l=0,f=e.interpolate||Xe,d="__p += '",p=ul((e.escape||Xe).source+"|"+f.source+"|"+(f===Ae?Ue:Xe).source+"|"+(e.evaluate||Xe).source+"|$","g"),h="//# sourceURL="+("sourceURL"in e?e.sourceURL:"lodash.templateSources["+ ++wn+"]")+"\n";t.replace(p,function(e,n,r,i,s,u){return r||(r=i),d+=t.slice(l,u).replace(Je,V),n&&(o=!0,d+="' +\n__e("+n+") +\n'"),s&&(a=!0,d+="';\n"+s+";\n__p += '"),r&&(d+="' +\n((__t = ("+r+")) == null ? '' : __t) +\n'"),l=u+e.length,e}),d+="';\n";var v=e.variable;v||(d="with (obj) {\n"+d+"\n}\n"),d=(a?d.replace(_e,""):d).replace(ye,"$1").replace(be,"$1;"),d="function("+(v||"obj")+") {\n"+(v?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(o?", __e = _.escape":"")+(a?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+d+"return __p\n}";var m=Jd(function(){return ol(u,h+"return "+d).apply(it,c)});if(m.source=d,Qs(m))throw m;return m}function _c(t){return Au(t).toLowerCase()}function yc(t){return Au(t).toUpperCase()}function bc(t,e,n){if((t=Au(t))&&(n||e===it))return t.replace(De,"");if(!t||!(e=pi(e)))return t;var r=tt(t),i=tt(e);return Ci(r,F(r,i),L(r,i)+1).join("")}function xc(t,e,n){if((t=Au(t))&&(n||e===it))return t.replace(Me,"");if(!t||!(e=pi(e)))return t;var r=tt(t);return Ci(r,0,L(r,tt(e))+1).join("")}function wc(t,e,n){if((t=Au(t))&&(n||e===it))return t.replace(Pe,"");if(!t||!(e=pi(e)))return t;var r=tt(t);return Ci(r,F(r,tt(e))).join("")}function kc(t,e){var n=Ot,r=At;if(iu(e)){var i="separator"in e?e.separator:i;n="length"in e?wu(e.length):n,r="omission"in e?pi(e.omission):r}t=Au(t);var o=t.length;if(q(t)){var a=tt(t);o=a.length}if(n>=o)return t;var s=n-Q(r);if(s<1)return r;var u=a?Ci(a,0,s).join(""):t.slice(0,s);if(i===it)return u+r;if(a&&(s+=u.length-s),wd(i)){if(t.slice(s).search(i)){var c,l=u;for(i.global||(i=ul(i.source,Au(qe.exec(i))+"g")),i.lastIndex=0;c=i.exec(l);)var f=c.index;u=u.slice(0,f===it?s:f)}}else if(t.indexOf(pi(i),s)!=s){var d=u.lastIndexOf(i);d>-1&&(u=u.slice(0,d))}return u+r}function Cc(t){return t=Au(t),t&&ke.test(t)?t.replace(xe,Gn):t}function Ec(t,e,n){return t=Au(t),e=n?it:e,e===it?H(t)?rt(t):x(t):t.match(e)||[]}function Oc(t){var e=null==t?0:t.length,n=wo();return t=e?v(t,function(t){if("function"!=typeof t[1])throw new ll(st);return[n(t[0]),t[1]]}):[],ni(function(n){for(var r=-1;++rRt)return[];var n=Mt,r=Bl(t,Mt);e=wo(e),t-=Mt;for(var i=R(r,e);++n1?t[e-1]:it;return n="function"==typeof n?(t.pop(),n):it,Ya(t,n)}),Xf=go(function(t){var e=t.length,n=e?t[0]:0,r=this.__wrapped__,o=function(e){return er(e,t)};return!(e>1||this.__actions__.length)&&r instanceof b&&Po(n)?(r=r.slice(n,+n+(e?1:0)),r.__actions__.push({func:Za,args:[o],thisArg:it}),new i(r,this.__chain__).thru(function(t){return e&&!t.length&&t.push(it),t})):this.thru(o)}),Jf=Vi(function(t,e,n){ml.call(t,n)?++t[n]:tr(t,n,1)}),Zf=Xi(fa),Qf=Xi(da),td=Vi(function(t,e,n){ml.call(t,n)?t[n].push(e):tr(t,n,[e])}),ed=ni(function(t,e,n){var r=-1,i="function"==typeof e,o=Bs(t)?nl(t.length):[];return vf(t,function(t){o[++r]=i?s(e,t,n):Er(t,e,n)}),o}),nd=Vi(function(t,e,n){tr(t,n,e)}),rd=Vi(function(t,e,n){t[n?0:1].push(e)},function(){return[[],[]]}),id=ni(function(t,e){if(null==t)return[];var n=e.length;return n>1&&Mo(t,e[0],e[1])?e=[]:n>2&&Mo(e[0],e[1],e[2])&&(e=[e[0]]),Yr(t,dr(e,1),[])}),od=Ml||function(){return Rn.Date.now()},ad=ni(function(t,e,n){var r=mt;if(n.length){var i=G(n,xo(ad));r|=xt}return co(t,r,e,n,i)}),sd=ni(function(t,e,n){var r=mt|gt;if(n.length){var i=G(n,xo(sd));r|=xt}return co(e,r,t,n,i)}),ud=ni(function(t,e){return ar(t,1,e)}),cd=ni(function(t,e,n){return ar(t,Cu(e)||0,n)});Ts.Cache=cn;var ld=xf(function(t,e){e=1==e.length&&gd(e[0])?v(e[0],P(wo())):v(dr(e,1),P(wo()));var n=e.length;return ni(function(r){for(var i=-1,o=Bl(r.length,n);++i=e}),md=Or(function(){return arguments}())?Or:function(t){return ou(t)&&ml.call(t,"callee")&&!Sl.call(t,"callee")},gd=nl.isArray,_d=Ln?P(Ln):Ar,yd=Vl||Vc,bd=zn?P(zn):$r,xd=Vn?P(Vn):Tr,wd=Un?P(Un):Dr,kd=qn?P(qn):Pr,Cd=Hn?P(Hn):Mr,Ed=oo(zr),Od=oo(function(t,e){return t<=e}),Ad=Ui(function(t,e){if(Vo(e)||Bs(e))return void Fi(e,zu(e),t);for(var n in e)ml.call(e,n)&&Wn(t,n,e[n])}),$d=Ui(function(t,e){Fi(e,Vu(e),t)}),Sd=Ui(function(t,e,n,r){Fi(e,Vu(e),t,r)}),jd=Ui(function(t,e,n,r){Fi(e,zu(e),t,r)}),Td=go(er),Nd=ni(function(t){return t.push(it,lo),s(Sd,it,t)}),Rd=ni(function(t){return t.push(it,fo),s(Fd,it,t)}),Dd=Qi(function(t,e,n){t[e]=n},$c(jc)),Pd=Qi(function(t,e,n){ml.call(t,e)?t[e].push(n):t[e]=[n]},wo),Md=ni(Er),Id=Ui(function(t,e,n){Hr(t,e,n)}),Fd=Ui(function(t,e,n,r){Hr(t,e,n,r)}),Ld=go(function(t,e){var n={};if(null==t)return n;var r=!1;e=v(e,function(e){return e=ki(e,t),r||(r=e.length>1),e}),Fi(t,yo(t),n),r&&(n=rr(n,ft|dt|pt,po));for(var i=e.length;i--;)vi(n,e[i]);return n}),zd=go(function(t,e){return null==t?{}:Gr(t,e)}),Vd=uo(zu),Ud=uo(Vu),qd=Yi(function(t,e,n){return e=e.toLowerCase(),t+(n?ic(e):e)}),Hd=Yi(function(t,e,n){return t+(n?"-":"")+e.toLowerCase()}),Wd=Yi(function(t,e,n){return t+(n?" ":"")+e.toLowerCase()}),Bd=Bi("toLowerCase"),Yd=Yi(function(t,e,n){return t+(n?"_":"")+e.toLowerCase()}),Gd=Yi(function(t,e,n){return t+(n?" ":"")+Xd(e)}),Kd=Yi(function(t,e,n){return t+(n?" ":"")+e.toUpperCase()}),Xd=Bi("toUpperCase"),Jd=ni(function(t,e){try{return s(t,it,e)}catch(t){return Qs(t)?t:new il(t)}}),Zd=go(function(t,e){return c(e,function(e){e=Qo(e),tr(t,e,ad(t[e],t))}),t}),Qd=Ji(),tp=Ji(!0),ep=ni(function(t,e){return function(n){return Er(n,t,e)}}),np=ni(function(t,e){return function(n){return Er(t,n,e)}}),rp=eo(v),ip=eo(f),op=eo(y),ap=io(),sp=io(!0),up=to(function(t,e){return t+e},0),cp=so("ceil"),lp=to(function(t,e){return t/e},1),fp=so("floor"),dp=to(function(t,e){return t*e},1),pp=so("round"),hp=to(function(t,e){return t-e},0);return n.after=Cs,n.ary=Es,n.assign=Ad,n.assignIn=$d,n.assignInWith=Sd,n.assignWith=jd,n.at=Td,n.before=Os,n.bind=ad,n.bindAll=Zd,n.bindKey=sd,n.castArray=Ls,n.chain=Xa,n.chunk=ra,n.compact=ia,n.concat=oa,n.cond=Oc,n.conforms=Ac,n.constant=$c,n.countBy=Jf,n.create=$u,n.curry=As,n.curryRight=$s,n.debounce=Ss,n.defaults=Nd,n.defaultsDeep=Rd,n.defer=ud,n.delay=cd,n.difference=Rf,n.differenceBy=Df,n.differenceWith=Pf,n.drop=aa,n.dropRight=sa,n.dropRightWhile=ua,n.dropWhile=ca,n.fill=la,n.filter=ss,n.flatMap=us,n.flatMapDeep=cs,n.flatMapDepth=ls,n.flatten=pa,n.flattenDeep=ha,n.flattenDepth=va,n.flip=js,n.flow=Qd,n.flowRight=tp,n.fromPairs=ma,n.functions=Pu,n.functionsIn=Mu,n.groupBy=td,n.initial=ya,n.intersection=Mf,n.intersectionBy=If,n.intersectionWith=Ff,n.invert=Dd,n.invertBy=Pd,n.invokeMap=ed,n.iteratee=Tc,n.keyBy=nd,n.keys=zu,n.keysIn=Vu,n.map=hs,n.mapKeys=Uu,n.mapValues=qu,n.matches=Nc,n.matchesProperty=Rc,n.memoize=Ts,n.merge=Id,n.mergeWith=Fd,n.method=ep,n.methodOf=np,n.mixin=Dc,n.negate=Ns,n.nthArg=Ic,n.omit=Ld,n.omitBy=Hu,n.once=Rs,n.orderBy=vs,n.over=rp,n.overArgs=ld,n.overEvery=ip,n.overSome=op,n.partial=fd,n.partialRight=dd,n.partition=rd,n.pick=zd,n.pickBy=Wu,n.property=Fc,n.propertyOf=Lc,n.pull=Lf,n.pullAll=Ca,n.pullAllBy=Ea,n.pullAllWith=Oa,n.pullAt=zf,n.range=ap,n.rangeRight=sp,n.rearg=pd,n.reject=_s,n.remove=Aa,n.rest=Ds,n.reverse=$a,n.sampleSize=bs,n.set=Yu,n.setWith=Gu,n.shuffle=xs,n.slice=Sa,n.sortBy=id,n.sortedUniq=Ma,n.sortedUniqBy=Ia,n.split=vc,n.spread=Ps,n.tail=Fa,n.take=La,n.takeRight=za,n.takeRightWhile=Va,n.takeWhile=Ua,n.tap=Ja,n.throttle=Ms,n.thru=Za,n.toArray=bu,n.toPairs=Vd,n.toPairsIn=Ud,n.toPath=Bc,n.toPlainObject=Eu,n.transform=Ku,n.unary=Is,n.union=Vf,n.unionBy=Uf,n.unionWith=qf,n.uniq=qa,n.uniqBy=Ha,n.uniqWith=Wa,n.unset=Xu,n.unzip=Ba,n.unzipWith=Ya,n.update=Ju,n.updateWith=Zu,n.values=Qu,n.valuesIn=tc,n.without=Hf,n.words=Ec,n.wrap=Fs,n.xor=Wf,n.xorBy=Bf,n.xorWith=Yf,n.zip=Gf,n.zipObject=Ga,n.zipObjectDeep=Ka,n.zipWith=Kf,n.entries=Vd,n.entriesIn=Ud,n.extend=$d,n.extendWith=Sd,Dc(n,n),n.add=up,n.attempt=Jd,n.camelCase=qd,n.capitalize=ic,n.ceil=cp,n.clamp=ec,n.clone=zs,n.cloneDeep=Us,n.cloneDeepWith=qs,n.cloneWith=Vs,n.conformsTo=Hs,n.deburr=oc,n.defaultTo=Sc,n.divide=lp,n.endsWith=ac,n.eq=Ws,n.escape=sc,n.escapeRegExp=uc,n.every=as,n.find=Zf,n.findIndex=fa,n.findKey=Su,n.findLast=Qf,n.findLastIndex=da,n.findLastKey=ju,n.floor=fp,n.forEach=fs,n.forEachRight=ds,n.forIn=Tu,n.forInRight=Nu,n.forOwn=Ru,n.forOwnRight=Du,n.get=Iu,n.gt=hd,n.gte=vd,n.has=Fu,n.hasIn=Lu,n.head=ga,n.identity=jc,n.includes=ps,n.indexOf=_a,n.inRange=nc,n.invoke=Md,n.isArguments=md,n.isArray=gd,n.isArrayBuffer=_d,n.isArrayLike=Bs,n.isArrayLikeObject=Ys,n.isBoolean=Gs,n.isBuffer=yd,n.isDate=bd,n.isElement=Ks,n.isEmpty=Xs,n.isEqual=Js,n.isEqualWith=Zs,n.isError=Qs,n.isFinite=tu,n.isFunction=eu,n.isInteger=nu,n.isLength=ru,n.isMap=xd,n.isMatch=au,n.isMatchWith=su,n.isNaN=uu,n.isNative=cu,n.isNil=fu,n.isNull=lu,n.isNumber=du,n.isObject=iu,n.isObjectLike=ou,n.isPlainObject=pu,n.isRegExp=wd,n.isSafeInteger=hu,n.isSet=kd,n.isString=vu,n.isSymbol=mu,n.isTypedArray=Cd,n.isUndefined=gu,n.isWeakMap=_u,n.isWeakSet=yu,n.join=ba,n.kebabCase=Hd,n.last=xa,n.lastIndexOf=wa,n.lowerCase=Wd,n.lowerFirst=Bd,n.lt=Ed,n.lte=Od,n.max=Gc,n.maxBy=Kc,n.mean=Xc,n.meanBy=Jc,n.min=Zc,n.minBy=Qc,n.stubArray=zc,n.stubFalse=Vc,n.stubObject=Uc,n.stubString=qc,n.stubTrue=Hc,n.multiply=dp,n.nth=ka,n.noConflict=Pc,n.noop=Mc,n.now=od,n.pad=cc,n.padEnd=lc,n.padStart=fc,n.parseInt=dc,n.random=rc,n.reduce=ms,n.reduceRight=gs,n.repeat=pc,n.replace=hc,n.result=Bu,n.round=pp,n.runInContext=t,n.sample=ys,n.size=ws,n.snakeCase=Yd,n.some=ks,n.sortedIndex=ja,n.sortedIndexBy=Ta,n.sortedIndexOf=Na,n.sortedLastIndex=Ra,n.sortedLastIndexBy=Da,n.sortedLastIndexOf=Pa,n.startCase=Gd,n.startsWith=mc,n.subtract=hp,n.sum=tl,n.sumBy=el,n.template=gc,n.times=Wc,n.toFinite=xu,n.toInteger=wu,n.toLength=ku,n.toLower=_c,n.toNumber=Cu,n.toSafeInteger=Ou,n.toString=Au,n.toUpper=yc,n.trim=bc,n.trimEnd=xc,n.trimStart=wc,n.truncate=kc,n.unescape=Cc,n.uniqueId=Yc,n.upperCase=Kd,n.upperFirst=Xd,n.each=fs,n.eachRight=ds,n.first=ga,Dc(n,function(){var t={};return pr(n,function(e,r){ml.call(n.prototype,r)||(t[r]=e)}),t}(),{chain:!1}),n.VERSION="4.17.4",c(["bind","bindKey","curry","curryRight","partial","partialRight"],function(t){n[t].placeholder=n}),c(["drop","take"],function(t,e){b.prototype[t]=function(n){n=n===it?1:Wl(wu(n),0);var r=this.__filtered__&&!e?new b(this):this.clone();return r.__filtered__?r.__takeCount__=Bl(n,r.__takeCount__):r.__views__.push({size:Bl(n,Mt),type:t+(r.__dir__<0?"Right":"")}),r},b.prototype[t+"Right"]=function(e){return this.reverse()[t](e).reverse()}}),c(["filter","map","takeWhile"],function(t,e){var n=e+1,r=n==jt||3==n;b.prototype[t]=function(t){var e=this.clone();return e.__iteratees__.push({iteratee:wo(t,3),type:n}),e.__filtered__=e.__filtered__||r,e}}),c(["head","last"],function(t,e){var n="take"+(e?"Right":"");b.prototype[t]=function(){return this[n](1).value()[0]}}),c(["initial","tail"],function(t,e){var n="drop"+(e?"":"Right");b.prototype[t]=function(){return this.__filtered__?new b(this):this[n](1)}}),b.prototype.compact=function(){return this.filter(jc)},b.prototype.find=function(t){return this.filter(t).head()},b.prototype.findLast=function(t){return this.reverse().find(t)},b.prototype.invokeMap=ni(function(t,e){return"function"==typeof t?new b(this):this.map(function(n){return Er(n,t,e)})}),b.prototype.reject=function(t){return this.filter(Ns(wo(t)))},b.prototype.slice=function(t,e){t=wu(t);var n=this;return n.__filtered__&&(t>0||e<0)?new b(n):(t<0?n=n.takeRight(-t):t&&(n=n.drop(t)),e!==it&&(e=wu(e),n=e<0?n.dropRight(-e):n.take(e-t)),n)},b.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},b.prototype.toArray=function(){return this.take(Mt)},pr(b.prototype,function(t,e){var r=/^(?:filter|find|map|reject)|While$/.test(e),o=/^(?:head|last)$/.test(e),a=n[o?"take"+("last"==e?"Right":""):e],s=o||/^find/.test(e);a&&(n.prototype[e]=function(){var e=this.__wrapped__,u=o?[1]:arguments,c=e instanceof b,l=u[0],f=c||gd(e),d=function(t){var e=a.apply(n,m([t],u));return o&&p?e[0]:e};f&&r&&"function"==typeof l&&1!=l.length&&(c=f=!1);var p=this.__chain__,h=!!this.__actions__.length,v=s&&!p,g=c&&!h;if(!s&&f){e=g?e:new b(this);var _=t.apply(e,u);return _.__actions__.push({func:Za,args:[d],thisArg:it}),new i(_,p)}return v&&g?t.apply(this,u):(_=this.thru(d),v?o?_.value()[0]:_.value():_)})}),c(["pop","push","shift","sort","splice","unshift"],function(t){var e=fl[t],r=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",i=/^(?:pop|shift)$/.test(t);n.prototype[t]=function(){var t=arguments;if(i&&!this.__chain__){var n=this.value();return e.apply(gd(n)?n:[],t)}return this[r](function(n){return e.apply(gd(n)?n:[],t)})}}),pr(b.prototype,function(t,e){var r=n[e];if(r){var i=r.name+"";(of[i]||(of[i]=[])).push({name:e,func:r})}}),of[Zi(it,gt).name]=[{name:"wrapper",func:it}],b.prototype.clone=S,b.prototype.reverse=J,b.prototype.value=et,n.prototype.at=Xf,n.prototype.chain=Qa,n.prototype.commit=ts,n.prototype.next=es,n.prototype.plant=rs,n.prototype.reverse=is,n.prototype.toJSON=n.prototype.valueOf=n.prototype.value=os,n.prototype.first=n.prototype.head,Nl&&(n.prototype[Nl]=ns),n}();Rn._=Kn,(i=function(){return Kn}.call(e,n,e,r))!==it&&(r.exports=i)}).call(this)}).call(e,n(12),n(193)(t))},function(t,e,n){"use strict";(function(t,n){/*! +!function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/dist/",e(e.s=70)}([function(t,e){t.exports=function(){var t=[];return t.toString=function(){for(var t=[],e=0;e=0&&m.splice(e,1)}function a(t){var e=document.createElement("style");return e.type="text/css",i(t,e),e}function s(t,e){var n,r,i;if(e.singleton){var s=v++;n=h||(h=a(e)),r=u.bind(null,n,s,!1),i=u.bind(null,n,s,!0)}else n=a(e),r=c.bind(null,n),i=function(){o(n)};return r(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;r(t=e)}else i()}}function u(t,e,n,r){var i=n?"":r.css;if(t.styleSheet)t.styleSheet.cssText=g(e,i);else{var o=document.createTextNode(i),a=t.childNodes;a[e]&&t.removeChild(a[e]),a.length?t.insertBefore(o,a[e]):t.appendChild(o)}}function c(t,e){var n=e.css,r=e.media,i=e.sourceMap;if(r&&t.setAttribute("media",r),i&&(n+="\n/*# sourceURL="+i.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(i))))+" */"),t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}var l={},f=function(t){var e;return function(){return void 0===e&&(e=t.apply(this,arguments)),e}},d=f(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),p=f(function(){return document.head||document.getElementsByTagName("head")[0]}),h=null,v=0,m=[];t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");e=e||{},void 0===e.singleton&&(e.singleton=d()),void 0===e.insertAt&&(e.insertAt="bottom");var i=r(t);return n(i,e),function(t){for(var o=[],a=0;a-1}function h(t,e,n){for(var r=-1,i=null==t?0:t.length;++r-1;);return n}function L(t,e){for(var n=t.length;n--&&C(e,t[n],0)>-1;);return n}function z(t,e){for(var n=t.length,r=0;n--;)t[n]===e&&++r;return r}function V(t){return"\\"+$n[t]}function U(t,e){return null==t?it:t[e]}function q(t){return yn.test(t)}function H(t){return bn.test(t)}function W(t){for(var e,n=[];!(e=t.next()).done;)n.push(e.value);return n}function B(t){var e=-1,n=Array(t.size);return t.forEach(function(t,r){n[++e]=[r,t]}),n}function Y(t,e){return function(n){return t(e(n))}}function G(t,e){for(var n=-1,r=t.length,i=0,o=[];++n>>1,Lt=[["ary",kt],["bind",mt],["bindKey",gt],["curry",yt],["curryRight",bt],["flip",Et],["partial",xt],["partialRight",wt],["rearg",Ct]],zt="[object Arguments]",Vt="[object Array]",Ut="[object AsyncFunction]",qt="[object Boolean]",Ht="[object Date]",Wt="[object DOMException]",Bt="[object Error]",Yt="[object Function]",Gt="[object GeneratorFunction]",Kt="[object Map]",Xt="[object Number]",Jt="[object Null]",Zt="[object Object]",Qt="[object Proxy]",te="[object RegExp]",ee="[object Set]",ne="[object String]",re="[object Symbol]",ie="[object Undefined]",oe="[object WeakMap]",ae="[object WeakSet]",se="[object ArrayBuffer]",ue="[object DataView]",ce="[object Float32Array]",le="[object Float64Array]",fe="[object Int8Array]",de="[object Int16Array]",pe="[object Int32Array]",he="[object Uint8Array]",ve="[object Uint8ClampedArray]",me="[object Uint16Array]",ge="[object Uint32Array]",_e=/\b__p \+= '';/g,ye=/\b(__p \+=) '' \+/g,be=/(__e\(.*?\)|\b__t\)) \+\n'';/g,xe=/&(?:amp|lt|gt|quot|#39);/g,we=/[&<>"']/g,ke=RegExp(xe.source),Ce=RegExp(we.source),Ee=/<%-([\s\S]+?)%>/g,Oe=/<%([\s\S]+?)%>/g,Ae=/<%=([\s\S]+?)%>/g,$e=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Se=/^\w*$/,je=/^\./,Te=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Ne=/[\\^$.*+?()[\]{}|]/g,Re=RegExp(Ne.source),De=/^\s+|\s+$/g,Pe=/^\s+/,Me=/\s+$/,Ie=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Fe=/\{\n\/\* \[wrapped with (.+)\] \*/,Le=/,? & /,ze=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Ve=/\\(\\)?/g,Ue=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,qe=/\w*$/,He=/^[-+]0x[0-9a-f]+$/i,We=/^0b[01]+$/i,Be=/^\[object .+?Constructor\]$/,Ye=/^0o[0-7]+$/i,Ge=/^(?:0|[1-9]\d*)$/,Ke=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,Xe=/($^)/,Je=/['\n\r\u2028\u2029\\]/g,Ze="\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff",Qe="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",tn="["+Qe+"]",en="["+Ze+"]",nn="[a-z\\xdf-\\xf6\\xf8-\\xff]",rn="[^\\ud800-\\udfff"+Qe+"\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde]",on="\\ud83c[\\udffb-\\udfff]",an="(?:\\ud83c[\\udde6-\\uddff]){2}",sn="[\\ud800-\\udbff][\\udc00-\\udfff]",un="[A-Z\\xc0-\\xd6\\xd8-\\xde]",cn="(?:"+nn+"|"+rn+")",ln="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",fn="(?:\\u200d(?:"+["[^\\ud800-\\udfff]",an,sn].join("|")+")[\\ufe0e\\ufe0f]?"+ln+")*",dn="[\\ufe0e\\ufe0f]?"+ln+fn,pn="(?:"+["[\\u2700-\\u27bf]",an,sn].join("|")+")"+dn,hn="(?:"+["[^\\ud800-\\udfff]"+en+"?",en,an,sn,"[\\ud800-\\udfff]"].join("|")+")",vn=RegExp("['’]","g"),mn=RegExp(en,"g"),gn=RegExp(on+"(?="+on+")|"+hn+dn,"g"),_n=RegExp([un+"?"+nn+"+(?:['’](?:d|ll|m|re|s|t|ve))?(?="+[tn,un,"$"].join("|")+")","(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['’](?:D|LL|M|RE|S|T|VE))?(?="+[tn,un+cn,"$"].join("|")+")",un+"?"+cn+"+(?:['’](?:d|ll|m|re|s|t|ve))?",un+"+(?:['’](?:D|LL|M|RE|S|T|VE))?","\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)","\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)","\\d+",pn].join("|"),"g"),yn=RegExp("[\\u200d\\ud800-\\udfff"+Ze+"\\ufe0e\\ufe0f]"),bn=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,xn=["Array","Buffer","DataView","Date","Error","Float32Array","Float64Array","Function","Int8Array","Int16Array","Int32Array","Map","Math","Object","Promise","RegExp","Set","String","Symbol","TypeError","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","WeakMap","_","clearTimeout","isFinite","parseInt","setTimeout"],wn=-1,kn={};kn[ce]=kn[le]=kn[fe]=kn[de]=kn[pe]=kn[he]=kn[ve]=kn[me]=kn[ge]=!0,kn[zt]=kn[Vt]=kn[se]=kn[qt]=kn[ue]=kn[Ht]=kn[Bt]=kn[Yt]=kn[Kt]=kn[Xt]=kn[Zt]=kn[te]=kn[ee]=kn[ne]=kn[oe]=!1;var Cn={};Cn[zt]=Cn[Vt]=Cn[se]=Cn[ue]=Cn[qt]=Cn[Ht]=Cn[ce]=Cn[le]=Cn[fe]=Cn[de]=Cn[pe]=Cn[Kt]=Cn[Xt]=Cn[Zt]=Cn[te]=Cn[ee]=Cn[ne]=Cn[re]=Cn[he]=Cn[ve]=Cn[me]=Cn[ge]=!0,Cn[Bt]=Cn[Yt]=Cn[oe]=!1;var En={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"},On={"&":"&","<":"<",">":">",'"':""","'":"'"},An={"&":"&","<":"<",">":">",""":'"',"'":"'"},$n={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Sn=parseFloat,jn=parseInt,Tn="object"==typeof t&&t&&t.Object===Object&&t,Nn="object"==typeof self&&self&&self.Object===Object&&self,Rn=Tn||Nn||Function("return this")(),Dn="object"==typeof e&&e&&!e.nodeType&&e,Pn=Dn&&"object"==typeof r&&r&&!r.nodeType&&r,Mn=Pn&&Pn.exports===Dn,In=Mn&&Tn.process,Fn=function(){try{return In&&In.binding&&In.binding("util")}catch(t){}}(),Ln=Fn&&Fn.isArrayBuffer,zn=Fn&&Fn.isDate,Vn=Fn&&Fn.isMap,Un=Fn&&Fn.isRegExp,qn=Fn&&Fn.isSet,Hn=Fn&&Fn.isTypedArray,Wn=$("length"),Bn=S(En),Yn=S(On),Gn=S(An),Kn=function t(e){function n(t){if(ou(t)&&!gd(t)&&!(t instanceof b)){if(t instanceof i)return t;if(ml.call(t,"__wrapped__"))return na(t)}return new i(t)}function r(){}function i(t,e){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!e,this.__index__=0,this.__values__=it}function b(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=Mt,this.__views__=[]}function S(){var t=new b(this.__wrapped__);return t.__actions__=Ii(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=Ii(this.__iteratees__),t.__takeCount__=this.__takeCount__,t.__views__=Ii(this.__views__),t}function J(){if(this.__filtered__){var t=new b(this);t.__dir__=-1,t.__filtered__=!0}else t=this.clone(),t.__dir__*=-1;return t}function et(){var t=this.__wrapped__.value(),e=this.__dir__,n=gd(t),r=e<0,i=n?t.length:0,o=Ao(0,i,this.__views__),a=o.start,s=o.end,u=s-a,c=r?s:a-1,l=this.__iteratees__,f=l.length,d=0,p=Bl(u,this.__takeCount__);if(!n||!r&&i==u&&p==u)return _i(t,this.__actions__);var h=[];t:for(;u--&&d-1}function un(t,e){var n=this.__data__,r=Xn(n,t);return r<0?(++this.size,n.push([t,e])):n[r][1]=e,this}function cn(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e=e?t:e)),t}function rr(t,e,n,r,i,o){var a,s=e&ft,u=e&dt,l=e&pt;if(n&&(a=i?n(t,r,i,o):n(t)),a!==it)return a;if(!iu(t))return t;var f=gd(t);if(f){if(a=jo(t),!s)return Ii(t,a)}else{var d=Af(t),p=d==Yt||d==Gt;if(yd(t))return Ei(t,s);if(d==Zt||d==zt||p&&!i){if(a=u||p?{}:To(t),!s)return u?zi(t,Qn(a,t)):Li(t,Zn(a,t))}else{if(!Cn[d])return i?t:{};a=No(t,d,rr,s)}}o||(o=new bn);var h=o.get(t);if(h)return h;o.set(t,a);var v=l?u?yo:_o:u?Vu:zu,m=f?it:v(t);return c(m||t,function(r,i){m&&(i=r,r=t[i]),Wn(a,i,rr(r,e,n,i,t,o))}),a}function ir(t){var e=zu(t);return function(n){return or(n,t,e)}}function or(t,e,n){var r=n.length;if(null==t)return!r;for(t=sl(t);r--;){var i=n[r],o=e[i],a=t[i];if(a===it&&!(i in t)||!o(a))return!1}return!0}function ar(t,e,n){if("function"!=typeof t)throw new ll(st);return jf(function(){t.apply(it,n)},e)}function sr(t,e,n,r){var i=-1,o=p,a=!0,s=t.length,u=[],c=e.length;if(!s)return u;n&&(e=v(e,P(n))),r?(o=h,a=!1):e.length>=ot&&(o=I,a=!1,e=new gn(e));t:for(;++ii?0:i+n),r=r===it||r>i?i:wu(r),r<0&&(r+=i),r=n>r?0:ku(r);n0&&n(s)?e>1?dr(s,e-1,n,r,i):m(i,s):r||(i[i.length]=s)}return i}function pr(t,e){return t&&gf(t,e,zu)}function hr(t,e){return t&&_f(t,e,zu)}function vr(t,e){return d(e,function(e){return eu(t[e])})}function mr(t,e){e=ki(e,t);for(var n=0,r=e.length;null!=t&&ne}function br(t,e){return null!=t&&ml.call(t,e)}function xr(t,e){return null!=t&&e in sl(t)}function wr(t,e,n){return t>=Bl(e,n)&&t=120&&l.length>=120)?new gn(a&&l):it}l=t[0];var f=-1,d=s[0];t:for(;++f-1;)s!==t&&jl.call(s,u,1),jl.call(t,u,1);return t}function Zr(t,e){for(var n=t?e.length:0,r=n-1;n--;){var i=e[n];if(n==r||i!==o){var o=i;Po(i)?jl.call(t,i,1):vi(t,i)}}return t}function Qr(t,e){return t+Ll(Kl()*(e-t+1))}function ti(t,e,n,r){for(var i=-1,o=Wl(Fl((e-t)/(n||1)),0),a=nl(o);o--;)a[r?o:++i]=t,t+=n;return a}function ei(t,e){var n="";if(!t||e<1||e>Rt)return n;do{e%2&&(n+=t),(e=Ll(e/2))&&(t+=t)}while(e);return n}function ni(t,e){return Tf(Yo(t,e,jc),t+"")}function ri(t){return Dn(Qu(t))}function ii(t,e){var n=Qu(t);return Zo(n,nr(e,0,n.length))}function oi(t,e,n,r){if(!iu(t))return t;e=ki(e,t);for(var i=-1,o=e.length,a=o-1,s=t;null!=s&&++ii?0:i+e),n=n>i?i:n,n<0&&(n+=i),i=e>n?0:n-e>>>0,e>>>=0;for(var o=nl(i);++r>>1,a=t[o];null!==a&&!mu(a)&&(n?a<=e:a=ot){var c=e?null:kf(t);if(c)return K(c);a=!1,i=I,u=new gn}else u=e?[]:s;t:for(;++r=r?t:si(t,e,n)}function Ei(t,e){if(e)return t.slice();var n=t.length,r=Ol?Ol(n):new t.constructor(n);return t.copy(r),r}function Oi(t){var e=new t.constructor(t.byteLength);return new El(e).set(new El(t)),e}function Ai(t,e){var n=e?Oi(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)}function $i(t,e,n){return g(e?n(B(t),ft):B(t),o,new t.constructor)}function Si(t){var e=new t.constructor(t.source,qe.exec(t));return e.lastIndex=t.lastIndex,e}function ji(t,e,n){return g(e?n(K(t),ft):K(t),a,new t.constructor)}function Ti(t){return df?sl(df.call(t)):{}}function Ni(t,e){var n=e?Oi(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.length)}function Ri(t,e){if(t!==e){var n=t!==it,r=null===t,i=t===t,o=mu(t),a=e!==it,s=null===e,u=e===e,c=mu(e);if(!s&&!c&&!o&&t>e||o&&a&&u&&!s&&!c||r&&a&&u||!n&&u||!i)return 1;if(!r&&!o&&!c&&t=s)return u;return u*("desc"==n[r]?-1:1)}}return t.index-e.index}function Pi(t,e,n,r){for(var i=-1,o=t.length,a=n.length,s=-1,u=e.length,c=Wl(o-a,0),l=nl(u+c),f=!r;++s1?n[i-1]:it,a=i>2?n[2]:it;for(o=t.length>3&&"function"==typeof o?(i--,o):it,a&&Mo(n[0],n[1],a)&&(o=i<3?it:o,i=1),e=sl(e);++r-1?i[o?e[a]:a]:it}}function Ji(t){return go(function(e){var n=e.length,r=n,o=i.prototype.thru;for(t&&e.reverse();r--;){var a=e[r];if("function"!=typeof a)throw new ll(st);if(o&&!s&&"wrapper"==bo(a))var s=new i([],!0)}for(r=s?r:n;++r1&&_.reverse(),f&&us))return!1;var c=o.get(t);if(c&&o.get(e))return c==e;var l=-1,f=!0,d=n&vt?new gn:it;for(o.set(t,e),o.set(e,t);++l1?"& ":"")+e[r],e=e.join(n>2?", ":" "),t.replace(Ie,"{\n/* [wrapped with "+e+"] */\n")}function Do(t){return gd(t)||md(t)||!!(Tl&&t&&t[Tl])}function Po(t,e){return!!(e=null==e?Rt:e)&&("number"==typeof t||Ge.test(t))&&t>-1&&t%1==0&&t0){if(++e>=$t)return arguments[0]}else e=0;return t.apply(it,arguments)}}function Zo(t,e){var n=-1,r=t.length,i=r-1;for(e=e===it?r:e;++n=this.__values__.length;return{done:t,value:t?it:this.__values__[this.__index__++]}}function ns(){return this}function rs(t){for(var e,n=this;n instanceof r;){var i=na(n);i.__index__=0,i.__values__=it,e?o.__wrapped__=i:e=i;var o=i;n=n.__wrapped__}return o.__wrapped__=t,e}function is(){var t=this.__wrapped__;if(t instanceof b){var e=t;return this.__actions__.length&&(e=new b(this)),e=e.reverse(),e.__actions__.push({func:Za,args:[$a],thisArg:it}),new i(e,this.__chain__)}return this.thru($a)}function os(){return _i(this.__wrapped__,this.__actions__)}function as(t,e,n){var r=gd(t)?f:ur;return n&&Mo(t,e,n)&&(e=it),r(t,wo(e,3))}function ss(t,e){return(gd(t)?d:fr)(t,wo(e,3))}function us(t,e){return dr(hs(t,e),1)}function cs(t,e){return dr(hs(t,e),Nt)}function ls(t,e,n){return n=n===it?1:wu(n),dr(hs(t,e),n)}function fs(t,e){return(gd(t)?c:vf)(t,wo(e,3))}function ds(t,e){return(gd(t)?l:mf)(t,wo(e,3))}function ps(t,e,n,r){t=Bs(t)?t:Qu(t),n=n&&!r?wu(n):0;var i=t.length;return n<0&&(n=Wl(i+n,0)),vu(t)?n<=i&&t.indexOf(e,n)>-1:!!i&&C(t,e,n)>-1}function hs(t,e){return(gd(t)?v:Vr)(t,wo(e,3))}function vs(t,e,n,r){return null==t?[]:(gd(e)||(e=null==e?[]:[e]),n=r?it:n,gd(n)||(n=null==n?[]:[n]),Yr(t,e,n))}function ms(t,e,n){var r=gd(t)?g:j,i=arguments.length<3;return r(t,wo(e,4),n,i,vf)}function gs(t,e,n){var r=gd(t)?_:j,i=arguments.length<3;return r(t,wo(e,4),n,i,mf)}function _s(t,e){return(gd(t)?d:fr)(t,Ns(wo(e,3)))}function ys(t){return(gd(t)?Dn:ri)(t)}function bs(t,e,n){return e=(n?Mo(t,e,n):e===it)?1:wu(e),(gd(t)?Pn:ii)(t,e)}function xs(t){return(gd(t)?In:ai)(t)}function ws(t){if(null==t)return 0;if(Bs(t))return vu(t)?Q(t):t.length;var e=Af(t);return e==Kt||e==ee?t.size:Fr(t).length}function ks(t,e,n){var r=gd(t)?y:ui;return n&&Mo(t,e,n)&&(e=it),r(t,wo(e,3))}function Cs(t,e){if("function"!=typeof e)throw new ll(st);return t=wu(t),function(){if(--t<1)return e.apply(this,arguments)}}function Es(t,e,n){return e=n?it:e,e=t&&null==e?t.length:e,co(t,kt,it,it,it,it,e)}function Os(t,e){var n;if("function"!=typeof e)throw new ll(st);return t=wu(t),function(){return--t>0&&(n=e.apply(this,arguments)),t<=1&&(e=it),n}}function As(t,e,n){e=n?it:e;var r=co(t,yt,it,it,it,it,it,e);return r.placeholder=As.placeholder,r}function $s(t,e,n){e=n?it:e;var r=co(t,bt,it,it,it,it,it,e);return r.placeholder=$s.placeholder,r}function Ss(t,e,n){function r(e){var n=d,r=p;return d=p=it,_=e,v=t.apply(r,n)}function i(t){return _=t,m=jf(s,e),y?r(t):v}function o(t){var n=t-g,r=t-_,i=e-n;return b?Bl(i,h-r):i}function a(t){var n=t-g,r=t-_;return g===it||n>=e||n<0||b&&r>=h}function s(){var t=od();if(a(t))return u(t);m=jf(s,o(t))}function u(t){return m=it,x&&d?r(t):(d=p=it,v)}function c(){m!==it&&wf(m),_=0,d=g=p=m=it}function l(){return m===it?v:u(od())}function f(){var t=od(),n=a(t);if(d=arguments,p=this,g=t,n){if(m===it)return i(g);if(b)return m=jf(s,e),r(g)}return m===it&&(m=jf(s,e)),v}var d,p,h,v,m,g,_=0,y=!1,b=!1,x=!0;if("function"!=typeof t)throw new ll(st);return e=Cu(e)||0,iu(n)&&(y=!!n.leading,b="maxWait"in n,h=b?Wl(Cu(n.maxWait)||0,e):h,x="trailing"in n?!!n.trailing:x),f.cancel=c,f.flush=l,f}function js(t){return co(t,Et)}function Ts(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new ll(st);var n=function(){var r=arguments,i=e?e.apply(this,r):r[0],o=n.cache;if(o.has(i))return o.get(i);var a=t.apply(this,r);return n.cache=o.set(i,a)||o,a};return n.cache=new(Ts.Cache||cn),n}function Ns(t){if("function"!=typeof t)throw new ll(st);return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}function Rs(t){return Os(2,t)}function Ds(t,e){if("function"!=typeof t)throw new ll(st);return e=e===it?e:wu(e),ni(t,e)}function Ps(t,e){if("function"!=typeof t)throw new ll(st);return e=null==e?0:Wl(wu(e),0),ni(function(n){var r=n[e],i=Ci(n,0,e);return r&&m(i,r),s(t,this,i)})}function Ms(t,e,n){var r=!0,i=!0;if("function"!=typeof t)throw new ll(st);return iu(n)&&(r="leading"in n?!!n.leading:r,i="trailing"in n?!!n.trailing:i),Ss(t,e,{leading:r,maxWait:e,trailing:i})}function Is(t){return Es(t,1)}function Fs(t,e){return fd(wi(e),t)}function Ls(){if(!arguments.length)return[];var t=arguments[0];return gd(t)?t:[t]}function zs(t){return rr(t,pt)}function Vs(t,e){return e="function"==typeof e?e:it,rr(t,pt,e)}function Us(t){return rr(t,ft|pt)}function qs(t,e){return e="function"==typeof e?e:it,rr(t,ft|pt,e)}function Hs(t,e){return null==e||or(t,e,zu(e))}function Ws(t,e){return t===e||t!==t&&e!==e}function Bs(t){return null!=t&&ru(t.length)&&!eu(t)}function Ys(t){return ou(t)&&Bs(t)}function Gs(t){return!0===t||!1===t||ou(t)&&_r(t)==qt}function Ks(t){return ou(t)&&1===t.nodeType&&!pu(t)}function Xs(t){if(null==t)return!0;if(Bs(t)&&(gd(t)||"string"==typeof t||"function"==typeof t.splice||yd(t)||Cd(t)||md(t)))return!t.length;var e=Af(t);if(e==Kt||e==ee)return!t.size;if(Vo(t))return!Fr(t).length;for(var n in t)if(ml.call(t,n))return!1;return!0}function Js(t,e){return Sr(t,e)}function Zs(t,e,n){n="function"==typeof n?n:it;var r=n?n(t,e):it;return r===it?Sr(t,e,it,n):!!r}function Qs(t){if(!ou(t))return!1;var e=_r(t);return e==Bt||e==Wt||"string"==typeof t.message&&"string"==typeof t.name&&!pu(t)}function tu(t){return"number"==typeof t&&Ul(t)}function eu(t){if(!iu(t))return!1;var e=_r(t);return e==Yt||e==Gt||e==Ut||e==Qt}function nu(t){return"number"==typeof t&&t==wu(t)}function ru(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=Rt}function iu(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function ou(t){return null!=t&&"object"==typeof t}function au(t,e){return t===e||Nr(t,e,Co(e))}function su(t,e,n){return n="function"==typeof n?n:it,Nr(t,e,Co(e),n)}function uu(t){return du(t)&&t!=+t}function cu(t){if($f(t))throw new il(at);return Rr(t)}function lu(t){return null===t}function fu(t){return null==t}function du(t){return"number"==typeof t||ou(t)&&_r(t)==Xt}function pu(t){if(!ou(t)||_r(t)!=Zt)return!1;var e=Al(t);if(null===e)return!0;var n=ml.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&vl.call(n)==bl}function hu(t){return nu(t)&&t>=-Rt&&t<=Rt}function vu(t){return"string"==typeof t||!gd(t)&&ou(t)&&_r(t)==ne}function mu(t){return"symbol"==typeof t||ou(t)&&_r(t)==re}function gu(t){return t===it}function _u(t){return ou(t)&&Af(t)==oe}function yu(t){return ou(t)&&_r(t)==ae}function bu(t){if(!t)return[];if(Bs(t))return vu(t)?tt(t):Ii(t);if(Nl&&t[Nl])return W(t[Nl]());var e=Af(t);return(e==Kt?B:e==ee?K:Qu)(t)}function xu(t){if(!t)return 0===t?t:0;if((t=Cu(t))===Nt||t===-Nt){return(t<0?-1:1)*Dt}return t===t?t:0}function wu(t){var e=xu(t),n=e%1;return e===e?n?e-n:e:0}function ku(t){return t?nr(wu(t),0,Mt):0}function Cu(t){if("number"==typeof t)return t;if(mu(t))return Pt;if(iu(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=iu(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(De,"");var n=We.test(t);return n||Ye.test(t)?jn(t.slice(2),n?2:8):He.test(t)?Pt:+t}function Eu(t){return Fi(t,Vu(t))}function Ou(t){return t?nr(wu(t),-Rt,Rt):0===t?t:0}function Au(t){return null==t?"":pi(t)}function $u(t,e){var n=hf(t);return null==e?n:Zn(n,e)}function Su(t,e){return w(t,wo(e,3),pr)}function ju(t,e){return w(t,wo(e,3),hr)}function Tu(t,e){return null==t?t:gf(t,wo(e,3),Vu)}function Nu(t,e){return null==t?t:_f(t,wo(e,3),Vu)}function Ru(t,e){return t&&pr(t,wo(e,3))}function Du(t,e){return t&&hr(t,wo(e,3))}function Pu(t){return null==t?[]:vr(t,zu(t))}function Mu(t){return null==t?[]:vr(t,Vu(t))}function Iu(t,e,n){var r=null==t?it:mr(t,e);return r===it?n:r}function Fu(t,e){return null!=t&&So(t,e,br)}function Lu(t,e){return null!=t&&So(t,e,xr)}function zu(t){return Bs(t)?Nn(t):Fr(t)}function Vu(t){return Bs(t)?Nn(t,!0):Lr(t)}function Uu(t,e){var n={};return e=wo(e,3),pr(t,function(t,r,i){tr(n,e(t,r,i),t)}),n}function qu(t,e){var n={};return e=wo(e,3),pr(t,function(t,r,i){tr(n,r,e(t,r,i))}),n}function Hu(t,e){return Wu(t,Ns(wo(e)))}function Wu(t,e){if(null==t)return{};var n=v(yo(t),function(t){return[t]});return e=wo(e),Kr(t,n,function(t,n){return e(t,n[0])})}function Bu(t,e,n){e=ki(e,t);var r=-1,i=e.length;for(i||(i=1,t=it);++re){var r=t;t=e,e=r}if(n||t%1||e%1){var i=Kl();return Bl(t+i*(e-t+Sn("1e-"+((i+"").length-1))),e)}return Qr(t,e)}function ic(t){return Xd(Au(t).toLowerCase())}function oc(t){return(t=Au(t))&&t.replace(Ke,Bn).replace(mn,"")}function ac(t,e,n){t=Au(t),e=pi(e);var r=t.length;n=n===it?r:nr(wu(n),0,r);var i=n;return(n-=e.length)>=0&&t.slice(n,i)==e}function sc(t){return t=Au(t),t&&Ce.test(t)?t.replace(we,Yn):t}function uc(t){return t=Au(t),t&&Re.test(t)?t.replace(Ne,"\\$&"):t}function cc(t,e,n){t=Au(t),e=wu(e);var r=e?Q(t):0;if(!e||r>=e)return t;var i=(e-r)/2;return no(Ll(i),n)+t+no(Fl(i),n)}function lc(t,e,n){t=Au(t),e=wu(e);var r=e?Q(t):0;return e&&r>>0)?(t=Au(t),t&&("string"==typeof e||null!=e&&!wd(e))&&!(e=pi(e))&&q(t)?Ci(tt(t),0,n):t.split(e,n)):[]}function mc(t,e,n){return t=Au(t),n=null==n?0:nr(wu(n),0,t.length),e=pi(e),t.slice(n,n+e.length)==e}function gc(t,e,r){var i=n.templateSettings;r&&Mo(t,e,r)&&(e=it),t=Au(t),e=Sd({},e,i,lo);var o,a,s=Sd({},e.imports,i.imports,lo),u=zu(s),c=M(s,u),l=0,f=e.interpolate||Xe,d="__p += '",p=ul((e.escape||Xe).source+"|"+f.source+"|"+(f===Ae?Ue:Xe).source+"|"+(e.evaluate||Xe).source+"|$","g"),h="//# sourceURL="+("sourceURL"in e?e.sourceURL:"lodash.templateSources["+ ++wn+"]")+"\n";t.replace(p,function(e,n,r,i,s,u){return r||(r=i),d+=t.slice(l,u).replace(Je,V),n&&(o=!0,d+="' +\n__e("+n+") +\n'"),s&&(a=!0,d+="';\n"+s+";\n__p += '"),r&&(d+="' +\n((__t = ("+r+")) == null ? '' : __t) +\n'"),l=u+e.length,e}),d+="';\n";var v=e.variable;v||(d="with (obj) {\n"+d+"\n}\n"),d=(a?d.replace(_e,""):d).replace(ye,"$1").replace(be,"$1;"),d="function("+(v||"obj")+") {\n"+(v?"":"obj || (obj = {});\n")+"var __t, __p = ''"+(o?", __e = _.escape":"")+(a?", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n":";\n")+d+"return __p\n}";var m=Jd(function(){return ol(u,h+"return "+d).apply(it,c)});if(m.source=d,Qs(m))throw m;return m}function _c(t){return Au(t).toLowerCase()}function yc(t){return Au(t).toUpperCase()}function bc(t,e,n){if((t=Au(t))&&(n||e===it))return t.replace(De,"");if(!t||!(e=pi(e)))return t;var r=tt(t),i=tt(e);return Ci(r,F(r,i),L(r,i)+1).join("")}function xc(t,e,n){if((t=Au(t))&&(n||e===it))return t.replace(Me,"");if(!t||!(e=pi(e)))return t;var r=tt(t);return Ci(r,0,L(r,tt(e))+1).join("")}function wc(t,e,n){if((t=Au(t))&&(n||e===it))return t.replace(Pe,"");if(!t||!(e=pi(e)))return t;var r=tt(t);return Ci(r,F(r,tt(e))).join("")}function kc(t,e){var n=Ot,r=At;if(iu(e)){var i="separator"in e?e.separator:i;n="length"in e?wu(e.length):n,r="omission"in e?pi(e.omission):r}t=Au(t);var o=t.length;if(q(t)){var a=tt(t);o=a.length}if(n>=o)return t;var s=n-Q(r);if(s<1)return r;var u=a?Ci(a,0,s).join(""):t.slice(0,s);if(i===it)return u+r;if(a&&(s+=u.length-s),wd(i)){if(t.slice(s).search(i)){var c,l=u;for(i.global||(i=ul(i.source,Au(qe.exec(i))+"g")),i.lastIndex=0;c=i.exec(l);)var f=c.index;u=u.slice(0,f===it?s:f)}}else if(t.indexOf(pi(i),s)!=s){var d=u.lastIndexOf(i);d>-1&&(u=u.slice(0,d))}return u+r}function Cc(t){return t=Au(t),t&&ke.test(t)?t.replace(xe,Gn):t}function Ec(t,e,n){return t=Au(t),e=n?it:e,e===it?H(t)?rt(t):x(t):t.match(e)||[]}function Oc(t){var e=null==t?0:t.length,n=wo();return t=e?v(t,function(t){if("function"!=typeof t[1])throw new ll(st);return[n(t[0]),t[1]]}):[],ni(function(n){for(var r=-1;++rRt)return[];var n=Mt,r=Bl(t,Mt);e=wo(e),t-=Mt;for(var i=R(r,e);++n1?t[e-1]:it;return n="function"==typeof n?(t.pop(),n):it,Ya(t,n)}),Xf=go(function(t){var e=t.length,n=e?t[0]:0,r=this.__wrapped__,o=function(e){return er(e,t)};return!(e>1||this.__actions__.length)&&r instanceof b&&Po(n)?(r=r.slice(n,+n+(e?1:0)),r.__actions__.push({func:Za,args:[o],thisArg:it}),new i(r,this.__chain__).thru(function(t){return e&&!t.length&&t.push(it),t})):this.thru(o)}),Jf=Vi(function(t,e,n){ml.call(t,n)?++t[n]:tr(t,n,1)}),Zf=Xi(fa),Qf=Xi(da),td=Vi(function(t,e,n){ml.call(t,n)?t[n].push(e):tr(t,n,[e])}),ed=ni(function(t,e,n){var r=-1,i="function"==typeof e,o=Bs(t)?nl(t.length):[];return vf(t,function(t){o[++r]=i?s(e,t,n):Er(t,e,n)}),o}),nd=Vi(function(t,e,n){tr(t,n,e)}),rd=Vi(function(t,e,n){t[n?0:1].push(e)},function(){return[[],[]]}),id=ni(function(t,e){if(null==t)return[];var n=e.length;return n>1&&Mo(t,e[0],e[1])?e=[]:n>2&&Mo(e[0],e[1],e[2])&&(e=[e[0]]),Yr(t,dr(e,1),[])}),od=Ml||function(){return Rn.Date.now()},ad=ni(function(t,e,n){var r=mt;if(n.length){var i=G(n,xo(ad));r|=xt}return co(t,r,e,n,i)}),sd=ni(function(t,e,n){var r=mt|gt;if(n.length){var i=G(n,xo(sd));r|=xt}return co(e,r,t,n,i)}),ud=ni(function(t,e){return ar(t,1,e)}),cd=ni(function(t,e,n){return ar(t,Cu(e)||0,n)});Ts.Cache=cn;var ld=xf(function(t,e){e=1==e.length&&gd(e[0])?v(e[0],P(wo())):v(dr(e,1),P(wo()));var n=e.length;return ni(function(r){for(var i=-1,o=Bl(r.length,n);++i=e}),md=Or(function(){return arguments}())?Or:function(t){return ou(t)&&ml.call(t,"callee")&&!Sl.call(t,"callee")},gd=nl.isArray,_d=Ln?P(Ln):Ar,yd=Vl||Vc,bd=zn?P(zn):$r,xd=Vn?P(Vn):Tr,wd=Un?P(Un):Dr,kd=qn?P(qn):Pr,Cd=Hn?P(Hn):Mr,Ed=oo(zr),Od=oo(function(t,e){return t<=e}),Ad=Ui(function(t,e){if(Vo(e)||Bs(e))return void Fi(e,zu(e),t);for(var n in e)ml.call(e,n)&&Wn(t,n,e[n])}),$d=Ui(function(t,e){Fi(e,Vu(e),t)}),Sd=Ui(function(t,e,n,r){Fi(e,Vu(e),t,r)}),jd=Ui(function(t,e,n,r){Fi(e,zu(e),t,r)}),Td=go(er),Nd=ni(function(t){return t.push(it,lo),s(Sd,it,t)}),Rd=ni(function(t){return t.push(it,fo),s(Fd,it,t)}),Dd=Qi(function(t,e,n){t[e]=n},$c(jc)),Pd=Qi(function(t,e,n){ml.call(t,e)?t[e].push(n):t[e]=[n]},wo),Md=ni(Er),Id=Ui(function(t,e,n){Hr(t,e,n)}),Fd=Ui(function(t,e,n,r){Hr(t,e,n,r)}),Ld=go(function(t,e){var n={};if(null==t)return n;var r=!1;e=v(e,function(e){return e=ki(e,t),r||(r=e.length>1),e}),Fi(t,yo(t),n),r&&(n=rr(n,ft|dt|pt,po));for(var i=e.length;i--;)vi(n,e[i]);return n}),zd=go(function(t,e){return null==t?{}:Gr(t,e)}),Vd=uo(zu),Ud=uo(Vu),qd=Yi(function(t,e,n){return e=e.toLowerCase(),t+(n?ic(e):e)}),Hd=Yi(function(t,e,n){return t+(n?"-":"")+e.toLowerCase()}),Wd=Yi(function(t,e,n){return t+(n?" ":"")+e.toLowerCase()}),Bd=Bi("toLowerCase"),Yd=Yi(function(t,e,n){return t+(n?"_":"")+e.toLowerCase()}),Gd=Yi(function(t,e,n){return t+(n?" ":"")+Xd(e)}),Kd=Yi(function(t,e,n){return t+(n?" ":"")+e.toUpperCase()}),Xd=Bi("toUpperCase"),Jd=ni(function(t,e){try{return s(t,it,e)}catch(t){return Qs(t)?t:new il(t)}}),Zd=go(function(t,e){return c(e,function(e){e=Qo(e),tr(t,e,ad(t[e],t))}),t}),Qd=Ji(),tp=Ji(!0),ep=ni(function(t,e){return function(n){return Er(n,t,e)}}),np=ni(function(t,e){return function(n){return Er(t,n,e)}}),rp=eo(v),ip=eo(f),op=eo(y),ap=io(),sp=io(!0),up=to(function(t,e){return t+e},0),cp=so("ceil"),lp=to(function(t,e){return t/e},1),fp=so("floor"),dp=to(function(t,e){return t*e},1),pp=so("round"),hp=to(function(t,e){return t-e},0);return n.after=Cs,n.ary=Es,n.assign=Ad,n.assignIn=$d,n.assignInWith=Sd,n.assignWith=jd,n.at=Td,n.before=Os,n.bind=ad,n.bindAll=Zd,n.bindKey=sd,n.castArray=Ls,n.chain=Xa,n.chunk=ra,n.compact=ia,n.concat=oa,n.cond=Oc,n.conforms=Ac,n.constant=$c,n.countBy=Jf,n.create=$u,n.curry=As,n.curryRight=$s,n.debounce=Ss,n.defaults=Nd,n.defaultsDeep=Rd,n.defer=ud,n.delay=cd,n.difference=Rf,n.differenceBy=Df,n.differenceWith=Pf,n.drop=aa,n.dropRight=sa,n.dropRightWhile=ua,n.dropWhile=ca,n.fill=la,n.filter=ss,n.flatMap=us,n.flatMapDeep=cs,n.flatMapDepth=ls,n.flatten=pa,n.flattenDeep=ha,n.flattenDepth=va,n.flip=js,n.flow=Qd,n.flowRight=tp,n.fromPairs=ma,n.functions=Pu,n.functionsIn=Mu,n.groupBy=td,n.initial=ya,n.intersection=Mf,n.intersectionBy=If,n.intersectionWith=Ff,n.invert=Dd,n.invertBy=Pd,n.invokeMap=ed,n.iteratee=Tc,n.keyBy=nd,n.keys=zu,n.keysIn=Vu,n.map=hs,n.mapKeys=Uu,n.mapValues=qu,n.matches=Nc,n.matchesProperty=Rc,n.memoize=Ts,n.merge=Id,n.mergeWith=Fd,n.method=ep,n.methodOf=np,n.mixin=Dc,n.negate=Ns,n.nthArg=Ic,n.omit=Ld,n.omitBy=Hu,n.once=Rs,n.orderBy=vs,n.over=rp,n.overArgs=ld,n.overEvery=ip,n.overSome=op,n.partial=fd,n.partialRight=dd,n.partition=rd,n.pick=zd,n.pickBy=Wu,n.property=Fc,n.propertyOf=Lc,n.pull=Lf,n.pullAll=Ca,n.pullAllBy=Ea,n.pullAllWith=Oa,n.pullAt=zf,n.range=ap,n.rangeRight=sp,n.rearg=pd,n.reject=_s,n.remove=Aa,n.rest=Ds,n.reverse=$a,n.sampleSize=bs,n.set=Yu,n.setWith=Gu,n.shuffle=xs,n.slice=Sa,n.sortBy=id,n.sortedUniq=Ma,n.sortedUniqBy=Ia,n.split=vc,n.spread=Ps,n.tail=Fa,n.take=La,n.takeRight=za,n.takeRightWhile=Va,n.takeWhile=Ua,n.tap=Ja,n.throttle=Ms,n.thru=Za,n.toArray=bu,n.toPairs=Vd,n.toPairsIn=Ud,n.toPath=Bc,n.toPlainObject=Eu,n.transform=Ku,n.unary=Is,n.union=Vf,n.unionBy=Uf,n.unionWith=qf,n.uniq=qa,n.uniqBy=Ha,n.uniqWith=Wa,n.unset=Xu,n.unzip=Ba,n.unzipWith=Ya,n.update=Ju,n.updateWith=Zu,n.values=Qu,n.valuesIn=tc,n.without=Hf,n.words=Ec,n.wrap=Fs,n.xor=Wf,n.xorBy=Bf,n.xorWith=Yf,n.zip=Gf,n.zipObject=Ga,n.zipObjectDeep=Ka,n.zipWith=Kf,n.entries=Vd,n.entriesIn=Ud,n.extend=$d,n.extendWith=Sd,Dc(n,n),n.add=up,n.attempt=Jd,n.camelCase=qd,n.capitalize=ic,n.ceil=cp,n.clamp=ec,n.clone=zs,n.cloneDeep=Us,n.cloneDeepWith=qs,n.cloneWith=Vs,n.conformsTo=Hs,n.deburr=oc,n.defaultTo=Sc,n.divide=lp,n.endsWith=ac,n.eq=Ws,n.escape=sc,n.escapeRegExp=uc,n.every=as,n.find=Zf,n.findIndex=fa,n.findKey=Su,n.findLast=Qf,n.findLastIndex=da,n.findLastKey=ju,n.floor=fp,n.forEach=fs,n.forEachRight=ds,n.forIn=Tu,n.forInRight=Nu,n.forOwn=Ru,n.forOwnRight=Du,n.get=Iu,n.gt=hd,n.gte=vd,n.has=Fu,n.hasIn=Lu,n.head=ga,n.identity=jc,n.includes=ps,n.indexOf=_a,n.inRange=nc,n.invoke=Md,n.isArguments=md,n.isArray=gd,n.isArrayBuffer=_d,n.isArrayLike=Bs,n.isArrayLikeObject=Ys,n.isBoolean=Gs,n.isBuffer=yd,n.isDate=bd,n.isElement=Ks,n.isEmpty=Xs,n.isEqual=Js,n.isEqualWith=Zs,n.isError=Qs,n.isFinite=tu,n.isFunction=eu,n.isInteger=nu,n.isLength=ru,n.isMap=xd,n.isMatch=au,n.isMatchWith=su,n.isNaN=uu,n.isNative=cu,n.isNil=fu,n.isNull=lu,n.isNumber=du,n.isObject=iu,n.isObjectLike=ou,n.isPlainObject=pu,n.isRegExp=wd,n.isSafeInteger=hu,n.isSet=kd,n.isString=vu,n.isSymbol=mu,n.isTypedArray=Cd,n.isUndefined=gu,n.isWeakMap=_u,n.isWeakSet=yu,n.join=ba,n.kebabCase=Hd,n.last=xa,n.lastIndexOf=wa,n.lowerCase=Wd,n.lowerFirst=Bd,n.lt=Ed,n.lte=Od,n.max=Gc,n.maxBy=Kc,n.mean=Xc,n.meanBy=Jc,n.min=Zc,n.minBy=Qc,n.stubArray=zc,n.stubFalse=Vc,n.stubObject=Uc,n.stubString=qc,n.stubTrue=Hc,n.multiply=dp,n.nth=ka,n.noConflict=Pc,n.noop=Mc,n.now=od,n.pad=cc,n.padEnd=lc,n.padStart=fc,n.parseInt=dc,n.random=rc,n.reduce=ms,n.reduceRight=gs,n.repeat=pc,n.replace=hc,n.result=Bu,n.round=pp,n.runInContext=t,n.sample=ys,n.size=ws,n.snakeCase=Yd,n.some=ks,n.sortedIndex=ja,n.sortedIndexBy=Ta,n.sortedIndexOf=Na,n.sortedLastIndex=Ra,n.sortedLastIndexBy=Da,n.sortedLastIndexOf=Pa,n.startCase=Gd,n.startsWith=mc,n.subtract=hp,n.sum=tl,n.sumBy=el,n.template=gc,n.times=Wc,n.toFinite=xu,n.toInteger=wu,n.toLength=ku,n.toLower=_c,n.toNumber=Cu,n.toSafeInteger=Ou,n.toString=Au,n.toUpper=yc,n.trim=bc,n.trimEnd=xc,n.trimStart=wc,n.truncate=kc,n.unescape=Cc,n.uniqueId=Yc,n.upperCase=Kd,n.upperFirst=Xd,n.each=fs,n.eachRight=ds,n.first=ga,Dc(n,function(){var t={};return pr(n,function(e,r){ml.call(n.prototype,r)||(t[r]=e)}),t}(),{chain:!1}),n.VERSION="4.17.4",c(["bind","bindKey","curry","curryRight","partial","partialRight"],function(t){n[t].placeholder=n}),c(["drop","take"],function(t,e){b.prototype[t]=function(n){n=n===it?1:Wl(wu(n),0);var r=this.__filtered__&&!e?new b(this):this.clone();return r.__filtered__?r.__takeCount__=Bl(n,r.__takeCount__):r.__views__.push({size:Bl(n,Mt),type:t+(r.__dir__<0?"Right":"")}),r},b.prototype[t+"Right"]=function(e){return this.reverse()[t](e).reverse()}}),c(["filter","map","takeWhile"],function(t,e){var n=e+1,r=n==jt||3==n;b.prototype[t]=function(t){var e=this.clone();return e.__iteratees__.push({iteratee:wo(t,3),type:n}),e.__filtered__=e.__filtered__||r,e}}),c(["head","last"],function(t,e){var n="take"+(e?"Right":"");b.prototype[t]=function(){return this[n](1).value()[0]}}),c(["initial","tail"],function(t,e){var n="drop"+(e?"":"Right");b.prototype[t]=function(){return this.__filtered__?new b(this):this[n](1)}}),b.prototype.compact=function(){return this.filter(jc)},b.prototype.find=function(t){return this.filter(t).head()},b.prototype.findLast=function(t){return this.reverse().find(t)},b.prototype.invokeMap=ni(function(t,e){return"function"==typeof t?new b(this):this.map(function(n){return Er(n,t,e)})}),b.prototype.reject=function(t){return this.filter(Ns(wo(t)))},b.prototype.slice=function(t,e){t=wu(t);var n=this;return n.__filtered__&&(t>0||e<0)?new b(n):(t<0?n=n.takeRight(-t):t&&(n=n.drop(t)),e!==it&&(e=wu(e),n=e<0?n.dropRight(-e):n.take(e-t)),n)},b.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},b.prototype.toArray=function(){return this.take(Mt)},pr(b.prototype,function(t,e){var r=/^(?:filter|find|map|reject)|While$/.test(e),o=/^(?:head|last)$/.test(e),a=n[o?"take"+("last"==e?"Right":""):e],s=o||/^find/.test(e);a&&(n.prototype[e]=function(){var e=this.__wrapped__,u=o?[1]:arguments,c=e instanceof b,l=u[0],f=c||gd(e),d=function(t){var e=a.apply(n,m([t],u));return o&&p?e[0]:e};f&&r&&"function"==typeof l&&1!=l.length&&(c=f=!1);var p=this.__chain__,h=!!this.__actions__.length,v=s&&!p,g=c&&!h;if(!s&&f){e=g?e:new b(this);var _=t.apply(e,u);return _.__actions__.push({func:Za,args:[d],thisArg:it}),new i(_,p)}return v&&g?t.apply(this,u):(_=this.thru(d),v?o?_.value()[0]:_.value():_)})}),c(["pop","push","shift","sort","splice","unshift"],function(t){var e=fl[t],r=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",i=/^(?:pop|shift)$/.test(t);n.prototype[t]=function(){var t=arguments;if(i&&!this.__chain__){var n=this.value();return e.apply(gd(n)?n:[],t)}return this[r](function(n){return e.apply(gd(n)?n:[],t)})}}),pr(b.prototype,function(t,e){var r=n[e];if(r){var i=r.name+"";(of[i]||(of[i]=[])).push({name:e,func:r})}}),of[Zi(it,gt).name]=[{name:"wrapper",func:it}],b.prototype.clone=S,b.prototype.reverse=J,b.prototype.value=et,n.prototype.at=Xf,n.prototype.chain=Qa,n.prototype.commit=ts,n.prototype.next=es,n.prototype.plant=rs,n.prototype.reverse=is,n.prototype.toJSON=n.prototype.valueOf=n.prototype.value=os,n.prototype.first=n.prototype.head,Nl&&(n.prototype[Nl]=ns),n}();Rn._=Kn,(i=function(){return Kn}.call(e,n,e,r))!==it&&(r.exports=i)}).call(this)}).call(e,n(13),n(193)(t))},function(t,e,n){"use strict";(function(t,n){/*! * Vue.js v2.4.2 * (c) 2014-2017 Evan You * Released under the MIT License. */ -function r(t){return void 0===t||null===t}function i(t){return void 0!==t&&null!==t}function o(t){return!0===t}function a(t){return!1===t}function s(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t}function u(t){return null!==t&&"object"==typeof t}function c(t){return"[object Object]"===sr.call(t)}function l(t){return"[object RegExp]"===sr.call(t)}function f(t){var e=parseFloat(t);return e>=0&&Math.floor(e)===e&&isFinite(t)}function d(t){return null==t?"":"object"==typeof t?JSON.stringify(t,null,2):String(t)}function p(t){var e=parseFloat(t);return isNaN(e)?t:e}function h(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i-1)return t.splice(n,1)}}function m(t,e){return lr.call(t,e)}function g(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}function _(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function y(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function b(t,e){for(var n in e)t[n]=e[n];return t}function x(t){for(var e={},n=0;nCi)){Cr("You may have an infinite update loop "+(e.user?'in watcher with expression "'+e.expression+'"':"in a component render function."),e.vm);break}var r=Oi.slice(),i=Ei.slice();Nt(),Mt(r),Dt(i),Yr&&xr.devtools&&Yr.emit("flush")}function Dt(t){for(var e=t.length;e--;){var n=t[e],r=n.vm;r._watcher===n&&r._isMounted&&Tt(r,"updated")}}function Pt(t){t._inactive=!1,Oi.push(t)}function Mt(t){for(var e=0;eTi&&Ei[n].id>t.id;)n--;Ei.splice(n+1,0,t)}else Ei.push(t);Si||(Si=!0,Kr(Rt))}}function Ft(t){Di.clear(),Lt(t,Di)}function Lt(t,e){var n,r,i=Array.isArray(t);if((i||u(t))&&Object.isExtensible(t)){if(t.__ob__){var o=t.__ob__.dep.id;if(e.has(o))return;e.add(o)}if(i)for(n=t.length;n--;)Lt(t[n],e);else for(r=Object.keys(t),n=r.length;n--;)Lt(t[r[n]],e)}}function zt(t,e,n){Pi.get=function(){return this[e][n]},Pi.set=function(t){this[e][n]=t},Object.defineProperty(t,n,Pi)}function Vt(t){t._watchers=[];var e=t.$options;e.props&&qt(t,e.props),e.methods&&Kt(t,e.methods),e.data?Ht(t):P(t._data={},!0),e.computed&&Bt(t,e.computed),e.watch&&e.watch!==Vr&&Xt(t,e.watch)}function Ut(t,e){c(t.$options[e])||Cr('component option "'+e+'" should be an object.',t)}function qt(e,n){var r=e.$options.propsData||{},i=e._props={},o=e.$options._propKeys=[],a=!e.$parent;ni.shouldConvert=a;for(var s in n)!function(a){o.push(a);var s=X(a,n,r,e);"production"!==t.env.NODE_ENV?((cr(a)||xr.isReservedAttr(a))&&Cr('"'+a+'" is a reserved attribute and cannot be used as component prop.',e),M(i,a,s,function(){e.$parent&&!ki&&Cr("Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: \""+a+'"',e)})):M(i,a,s),a in e||zt(e,"_props",a)}(s);ni.shouldConvert=!0}function Ht(e){var n=e.$options.data;n=e._data="function"==typeof n?Wt(n,e):n||{},c(n)||(n={},"production"!==t.env.NODE_ENV&&Cr("data functions should return an object:\nhttps://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function",e));for(var r=Object.keys(n),i=e.$options.props,o=e.$options.methods,a=r.length;a--;){var s=r[a];"production"!==t.env.NODE_ENV&&o&&m(o,s)&&Cr('method "'+s+'" has already been defined as a data property.',e),i&&m(i,s)?"production"!==t.env.NODE_ENV&&Cr('The data property "'+s+'" is already declared as a prop. Use prop default value instead.',e):O(s)||zt(e,"_data",s)}P(n,!0)}function Wt(t,e){try{return t.call(e)}catch(t){return S(t,e,"data()"),{}}}function Bt(e,n){"production"!==t.env.NODE_ENV&&Ut(e,"computed");var r=e._computedWatchers=Object.create(null);for(var i in n){var o=n[i],a="function"==typeof o?o:o.get;"production"!==t.env.NODE_ENV&&null==a&&Cr('Getter is missing for computed property "'+i+'".',e),r[i]=new Ri(e,a||w,w,Mi),i in e?"production"!==t.env.NODE_ENV&&(i in e.$data?Cr('The computed property "'+i+'" is already defined in data.',e):e.$options.props&&i in e.$options.props&&Cr('The computed property "'+i+'" is already defined as a prop.',e)):Yt(e,i,o)}}function Yt(e,n,r){"function"==typeof r?(Pi.get=Gt(n),Pi.set=w):(Pi.get=r.get?!1!==r.cache?Gt(n):r.get:w,Pi.set=r.set?r.set:w),"production"!==t.env.NODE_ENV&&Pi.set===w&&(Pi.set=function(){Cr('Computed property "'+n+'" was assigned to but it has no setter.',this)}),Object.defineProperty(e,n,Pi)}function Gt(t){return function(){var e=this._computedWatchers&&this._computedWatchers[t];if(e)return e.dirty&&e.evaluate(),Jr.target&&e.depend(),e.value}}function Kt(e,n){"production"!==t.env.NODE_ENV&&Ut(e,"methods");var r=e.$options.props;for(var i in n)e[i]=null==n[i]?w:_(n[i],e),"production"!==t.env.NODE_ENV&&(null==n[i]&&Cr('method "'+i+'" has an undefined value in the component definition. Did you reference the function correctly?',e),r&&m(r,i)&&Cr('method "'+i+'" has already been defined as a prop.',e))}function Xt(e,n){"production"!==t.env.NODE_ENV&&Ut(e,"watch");for(var r in n){var i=n[r];if(Array.isArray(i))for(var o=0;o=0||n.indexOf(t[i])<0)&&r.push(t[i]);return r}return t}function Oe(e){"production"===t.env.NODE_ENV||this instanceof Oe||Cr("Vue is a constructor and should be called with the `new` keyword"),this._init(e)}function Ae(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=y(arguments,1);return n.unshift(this),"function"==typeof t.install?t.install.apply(t,n):"function"==typeof t&&t.apply(null,n),e.push(t),this}}function $e(t){t.mixin=function(t){return this.options=G(this.options,t),this}}function Se(e){e.cid=0;var n=1;e.extend=function(e){e=e||{};var r=this,i=r.cid,o=e._Ctor||(e._Ctor={});if(o[i])return o[i];var a=e.name||r.options.name;"production"!==t.env.NODE_ENV&&(/^[a-zA-Z][\w-]*$/.test(a)||Cr('Invalid component name: "'+a+'". Component names can only contain alphanumeric characters and the hyphen, and must start with a letter.'));var s=function(t){this._init(t)};return s.prototype=Object.create(r.prototype),s.prototype.constructor=s,s.cid=n++,s.options=G(r.options,e),s.super=r,s.options.props&&je(s),s.options.computed&&Te(s),s.extend=r.extend,s.mixin=r.mixin,s.use=r.use,yr.forEach(function(t){s[t]=r[t]}),a&&(s.options.components[a]=s),s.superOptions=r.options,s.extendOptions=e,s.sealedOptions=b({},s.options),o[i]=s,s}}function je(t){var e=t.options.props;for(var n in e)zt(t.prototype,"_props",n)}function Te(t){var e=t.options.computed;for(var n in e)Yt(t.prototype,n,e[n])}function Ne(e){yr.forEach(function(n){e[n]=function(e,r){return r?("production"!==t.env.NODE_ENV&&"component"===n&&xr.isReservedTag(e)&&Cr("Do not use built-in or reserved HTML elements as component id: "+e),"component"===n&&c(r)&&(r.name=r.name||e,r=this.options._base.extend(r)),"directive"===n&&"function"==typeof r&&(r={bind:r,update:r}),this.options[n+"s"][e]=r,r):this.options[n+"s"][e]}})}function Re(t){return t&&(t.Ctor.options.name||t.tag)}function De(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!l(t)&&t.test(e)}function Pe(t,e,n){for(var r in t){var i=t[r];if(i){var o=Re(i.componentOptions);o&&!n(o)&&(i!==e&&Me(i),t[r]=null)}}}function Me(t){t&&t.componentInstance.$destroy()}function Ie(t){for(var e=t.data,n=t,r=t;i(r.componentInstance);)r=r.componentInstance._vnode,r.data&&(e=Fe(r.data,e));for(;i(n=n.parent);)n.data&&(e=Fe(e,n.data));return Le(e.staticClass,e.class)}function Fe(t,e){return{staticClass:ze(t.staticClass,e.staticClass),class:i(t.class)?[t.class,e.class]:e.class}}function Le(t,e){return i(t)||i(e)?ze(t,Ve(e)):""}function ze(t,e){return t?e?t+" "+e:t:e||""}function Ve(t){return Array.isArray(t)?Ue(t):u(t)?qe(t):"string"==typeof t?t:""}function Ue(t){for(var e,n="",r=0,o=t.length;r-1?ao[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:ao[t]=/HTMLUnknownElement/.test(e.toString())}function Be(e){if("string"==typeof e){var n=document.querySelector(e);return n||("production"!==t.env.NODE_ENV&&Cr("Cannot find element: "+e),document.createElement("div"))}return e}function Ye(t,e){var n=document.createElement(t);return"select"!==t?n:(e.data&&e.data.attrs&&void 0!==e.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)}function Ge(t,e){return document.createElementNS(no[t],e)}function Ke(t){return document.createTextNode(t)}function Xe(t){return document.createComment(t)}function Je(t,e,n){t.insertBefore(e,n)}function Ze(t,e){t.removeChild(e)}function Qe(t,e){t.appendChild(e)}function tn(t){return t.parentNode}function en(t){return t.nextSibling}function nn(t){return t.tagName}function rn(t,e){t.textContent=e}function on(t,e,n){t.setAttribute(e,n)}function an(t,e){var n=t.data.ref;if(n){var r=t.context,i=t.componentInstance||t.elm,o=r.$refs;e?Array.isArray(o[n])?v(o[n],i):o[n]===i&&(o[n]=void 0):t.data.refInFor?Array.isArray(o[n])?o[n].indexOf(i)<0&&o[n].push(i):o[n]=[i]:o[n]=i}}function sn(t,e){return t.key===e.key&&(t.tag===e.tag&&t.isComment===e.isComment&&i(t.data)===i(e.data)&&un(t,e)||o(t.isAsyncPlaceholder)&&t.asyncFactory===e.asyncFactory&&r(e.asyncFactory.error))}function un(t,e){if("input"!==t.tag)return!0;var n;return(i(n=t.data)&&i(n=n.attrs)&&n.type)===(i(n=e.data)&&i(n=n.attrs)&&n.type)}function cn(t,e,n){var r,o,a={};for(r=e;r<=n;++r)o=t[r].key,i(o)&&(a[o]=r);return a}function ln(t,e){(t.data.directives||e.data.directives)&&fn(t,e)}function fn(t,e){var n,r,i,o=t===co,a=e===co,s=dn(t.data.directives,t.context),u=dn(e.data.directives,e.context),c=[],l=[];for(n in u)r=s[n],i=u[n],r?(i.oldValue=r.value,hn(i,"update",e,t),i.def&&i.def.componentUpdated&&l.push(i)):(hn(i,"bind",e,t),i.def&&i.def.inserted&&c.push(i));if(c.length){var f=function(){for(var n=0;n-1?e.split(/\s+/).forEach(function(e){return t.classList.add(e)}):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Tn(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.remove(e)}):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");n=n.trim(),n?t.setAttribute("class",n):t.removeAttribute("class")}}function Nn(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&b(e,$o(t.name||"v")),b(e,t),e}return"string"==typeof t?$o(t):void 0}}function Rn(t){Mo(function(){Mo(t)})}function Dn(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),jn(t,e))}function Pn(t,e){t._transitionClasses&&v(t._transitionClasses,e),Tn(t,e)}function Mn(t,e,n){var r=In(t,e),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===jo?Ro:Po,u=0,c=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++u>=a&&c()};setTimeout(function(){u0&&(n=jo,l=a,f=o.length):e===To?c>0&&(n=To,l=c,f=u.length):(l=Math.max(a,c),n=l>0?a>c?jo:To:null,f=n?n===jo?o.length:u.length:0),{type:n,timeout:l,propCount:f,hasTransform:n===jo&&Io.test(r[No+"Property"])}}function Fn(t,e){for(;t.length explicit "+e+" duration is not a valid number - got "+JSON.stringify(t)+".",n.context):isNaN(t)&&Cr(" explicit "+e+" duration is NaN - the duration expression might be incorrect.",n.context)}function qn(t){return"number"==typeof t&&!isNaN(t)}function Hn(t){if(r(t))return!1;var e=t.fns;return i(e)?Hn(Array.isArray(e)?e[0]:e):(t._length||t.length)>1}function Wn(t,e){!0!==e.data.show&&zn(e)}function Bn(e,n,r){var i=n.value,o=e.multiple;if(o&&!Array.isArray(i))return void("production"!==t.env.NODE_ENV&&Cr(' expects an Array value for its binding, but got '+Object.prototype.toString.call(i).slice(8,-1),r));for(var a,s,u=0,c=e.options.length;u-1,s.selected!==a&&(s.selected=a);else if(k(Yn(s),i))return void(e.selectedIndex!==u&&(e.selectedIndex=u));o||(e.selectedIndex=-1)}function Yn(t){return"_value"in t?t._value:t.value}function Gn(t){t.target.composing=!0}function Kn(t){t.target.composing&&(t.target.composing=!1,Xn(t.target,"input"))}function Xn(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Jn(t){return!t.componentInstance||t.data&&t.data.transition?t:Jn(t.componentInstance._vnode)}function Zn(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Zn(gt(e.children)):t}function Qn(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var i=n._parentListeners;for(var o in i)e[dr(o)]=i[o];return e}function tr(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}function er(t){for(;t=t.parent;)if(t.data.transition)return!0}function nr(t,e){return e.key===t.key&&e.tag===t.tag}function rr(t){return t.isComment&&t.asyncFactory}function ir(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function or(t){t.data.newPos=t.elm.getBoundingClientRect()}function ar(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,i=e.top-n.top;if(r||i){t.data.moved=!0;var o=t.elm.style;o.transform=o.WebkitTransform="translate("+r+"px,"+i+"px)",o.transitionDuration="0s"}}var sr=Object.prototype.toString,ur=h("slot,component",!0),cr=h("key,ref,slot,is"),lr=Object.prototype.hasOwnProperty,fr=/-(\w)/g,dr=g(function(t){return t.replace(fr,function(t,e){return e?e.toUpperCase():""})}),pr=g(function(t){return t.charAt(0).toUpperCase()+t.slice(1)}),hr=/([^-])([A-Z])/g,vr=g(function(t){return t.replace(hr,"$1-$2").replace(hr,"$1-$2").toLowerCase()}),mr=function(t,e,n){return!1},gr=function(t){return t},_r="data-server-rendered",yr=["component","directive","filter"],br=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated"],xr={optionMergeStrategies:Object.create(null),silent:!1,productionTip:"production"!==t.env.NODE_ENV,devtools:"production"!==t.env.NODE_ENV,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:mr,isReservedAttr:mr,isUnknownElement:mr,getTagNamespace:w,parsePlatformTagName:gr,mustUseProp:mr,_lifecycleHooks:br},wr=Object.freeze({}),kr=/[^\w.$]/,Cr=w,Er=w,Or=null;if("production"!==t.env.NODE_ENV){var Ar="undefined"!=typeof console,$r=/(?:^|[-_])(\w)/g,Sr=function(t){return t.replace($r,function(t){return t.toUpperCase()}).replace(/[-_]/g,"")};Cr=function(t,e){var n=e?Tr(e):"";xr.warnHandler?xr.warnHandler.call(null,t,e,n):Ar&&!xr.silent&&console.error("[Vue warn]: "+t+n)},Er=function(t,e){Ar&&!xr.silent&&console.warn("[Vue tip]: "+t+(e?Tr(e):""))},Or=function(t,e){if(t.$root===t)return"";var n="string"==typeof t?t:"function"==typeof t&&t.options?t.options.name:t._isVue?t.$options.name||t.$options._componentTag:t.name,r=t._isVue&&t.$options.__file;if(!n&&r){var i=r.match(/([^\/\\]+)\.vue$/);n=i&&i[1]}return(n?"<"+Sr(n)+">":"")+(r&&!1!==e?" at "+r:"")};var jr=function(t,e){for(var n="";e;)e%2==1&&(n+=t),e>1&&(t+=t),e>>=1;return n},Tr=function(t){if(t._isVue&&t.$parent){for(var e=[],n=0;t;){if(e.length>0){var r=e[e.length-1];if(r.constructor===t.constructor){n++,t=t.$parent;continue}n>0&&(e[e.length-1]=[r,n],n=0)}e.push(t),t=t.$parent}return"\n\nfound in\n\n"+e.map(function(t,e){return""+(0===e?"---\x3e ":jr(" ",5+2*e))+(Array.isArray(t)?Or(t[0])+"... ("+t[1]+" recursive calls)":Or(t))}).join("\n")}return"\n\n(found in "+Or(t)+")"}}var Nr="__proto__"in{},Rr="undefined"!=typeof window,Dr=Rr&&window.navigator.userAgent.toLowerCase(),Pr=Dr&&/msie|trident/.test(Dr),Mr=Dr&&Dr.indexOf("msie 9.0")>0,Ir=Dr&&Dr.indexOf("edge/")>0,Fr=Dr&&Dr.indexOf("android")>0,Lr=Dr&&/iphone|ipad|ipod|ios/.test(Dr),zr=Dr&&/chrome\/\d+/.test(Dr)&&!Ir,Vr={}.watch,Ur=!1;if(Rr)try{var qr={};Object.defineProperty(qr,"passive",{get:function(){Ur=!0}}),window.addEventListener("test-passive",null,qr)}catch(t){}var Hr,Wr,Br=function(){return void 0===Hr&&(Hr=!Rr&&void 0!==n&&"server"===n.process.env.VUE_ENV),Hr},Yr=Rr&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,Gr="undefined"!=typeof Symbol&&j(Symbol)&&"undefined"!=typeof Reflect&&j(Reflect.ownKeys),Kr=function(){function t(){r=!1;var t=n.slice(0);n.length=0;for(var e=0;e1?y(i):i;for(var o=y(arguments,1),a=0,s=i.length;a1&&(e[n[0].trim()]=n[1].trim())}}),e}),wo=/^--/,ko=/\s*!important$/,Co=function(t,e,n){if(wo.test(e))t.style.setProperty(e,n);else if(ko.test(n))t.style.setProperty(e,n.replace(ko,""),"important");else{var r=Oo(e);if(Array.isArray(n))for(var i=0,o=n.length;i-1||!xr.isUnknownElement(f)||Cr("Unknown custom element: <"+f+'> - did you register the component correctly? For recursive components, make sure to provide the "name" option.',e.context)),e.elm=e.ns?N.createElementNS(e.ns,f):N.createElement(f,e),_(e),v(e,c,n),i(u)&&g(e,n),p(r,e.elm,a),"production"!==t.env.NODE_ENV&&u&&u.pre&&R--):o(e.isComment)?(e.elm=N.createComment(e.text),p(r,e.elm,a)):(e.elm=N.createTextNode(e.text),p(r,e.elm,a))}}function l(t,e,n,r){var a=t.data;if(i(a)){var s=i(t.componentInstance)&&a.keepAlive;if(i(a=a.hook)&&i(a=a.init)&&a(t,!1,n,r),i(t.componentInstance))return f(t,e),o(s)&&d(t,e,n,r),!0}}function f(t,e){i(t.data.pendingInsert)&&(e.push.apply(e,t.data.pendingInsert),t.data.pendingInsert=null),t.elm=t.componentInstance.$el,m(t)?(g(t,e),_(t)):(an(t),e.push(t))}function d(t,e,n,r){for(var o,a=t;a.componentInstance;)if(a=a.componentInstance._vnode,i(o=a.data)&&i(o=o.transition)){for(o=0;ov?(d=r(o[_+1])?null:o[_+1].elm,y(e,d,o,h,_,a)):h>_&&x(e,n,p,v)}function C(t,e,n,a){if(t!==e){var s=e.elm=t.elm;if(o(t.isAsyncPlaceholder))return void(i(e.asyncFactory.resolved)?O(t.elm,e,n):e.isAsyncPlaceholder=!0);if(o(e.isStatic)&&o(t.isStatic)&&e.key===t.key&&(o(e.isCloned)||o(e.isOnce)))return void(e.componentInstance=t.componentInstance);var u,c=e.data;i(c)&&i(u=c.hook)&&i(u=u.prepatch)&&u(t,e);var l=t.children,f=e.children;if(i(c)&&m(e)){for(u=0;u, or missing . Bailing hydration and performing full client-side render.")}e=n(e)}var v=e.elm,g=N.parentNode(v);if(c(a,p,v._leaveCb?null:g,N.nextSibling(v)),i(a.parent)){for(var _=a.parent;_;)_.elm=a.elm,_=_.parent;if(m(a))for(var y=0;y1&&Cr(" can only be used on a single element. Use for lists.",this.$parent);var i=this.mode;"production"!==t.env.NODE_ENV&&i&&"in-out"!==i&&"out-in"!==i&&Cr("invalid mode: "+i,this.$parent);var o=r[0];if(er(this.$vnode))return o;var a=Zn(o);if(!a)return o;if(this._leaving)return tr(e,o);var u="__transition-"+this._uid+"-";a.key=null==a.key?a.isComment?u+"comment":u+a.tag:s(a.key)?0===String(a.key).indexOf(u)?a.key:u+a.key:a.key;var c=(a.data||(a.data={})).transition=Qn(this),l=this._vnode,f=Zn(l);if(a.data.directives&&a.data.directives.some(function(t){return"show"===t.name})&&(a.data.show=!0),f&&f.data&&!nr(a,f)&&!rr(f)){var d=f&&(f.data.transition=b({},c));if("out-in"===i)return this._leaving=!0,st(d,"afterLeave",function(){n._leaving=!1,n.$forceUpdate()}),tr(e,o);if("in-out"===i){if(rr(a))return l;var p,h=function(){p()};st(c,"afterEnter",h),st(c,"enterCancelled",h),st(d,"delayLeave",function(t){p=t})}}return o}}},Go=b({tag:String,moveClass:String},Bo);delete Go.mode;var Ko={props:Go,render:function(e){for(var n=this.tag||this.$vnode.data.tag||"span",r=Object.create(null),i=this.prevChildren=this.children,o=this.$slots.default||[],a=this.children=[],s=Qn(this),u=0;u children must be keyed: <"+f+">")}}if(i){for(var d=[],p=[],h=0;h"},r.setOptions({renderer:i}),e.a=r},function(t,e,n){"use strict";n.d(e,"a",function(){return s}),n.d(e,"b",function(){return a}),n.d(e,"c",function(){return o});var r=window.CONFIG.ui,i=r.host+(80===r.port?"":":"+r.port)+r.path,o=void 0,a=void 0,s=void 0;o=r.ssl?"https://"+i:"http://"+i,a=o+"api/",s=r.ssl?"wss://"+i+"/api":"ws://"+i+"/api"},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function i(t){if(l===setTimeout)return setTimeout(t,0);if((l===n||!l)&&setTimeout)return l=setTimeout,setTimeout(t,0);try{return l(t,0)}catch(e){try{return l.call(null,t,0)}catch(e){return l.call(this,t,0)}}}function o(t){if(f===clearTimeout)return clearTimeout(t);if((f===r||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(t);try{return f(t)}catch(e){try{return f.call(null,t)}catch(e){return f.call(this,t)}}}function a(){v&&p&&(v=!1,p.length?h=p.concat(h):m=-1,h.length&&s())}function s(){if(!v){var t=i(a);v=!0;for(var e=h.length;e;){for(p=h,h=[];++m1)for(var n=1;n2)return!0}),r=r.sort(function(t,e){var n=t.to.diff(t.from),r=e.to.diff(e.from);return nr?1:0}).reverse(),t.datasets=r})}}};e.a=i},function(t,e){function n(t){return null!==t&&"object"==typeof t}t.exports=n},function(t,e,n){var r,i;n(192),r=n(40);var o=n(164);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;r=n(56);var o=n(135);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(185),r=n(57);var o=n(157);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(173),r=n(59);var o=n(143);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(187),r=n(60);var o=n(159);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(168),r=n(62);var o=n(136);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){"use strict";function r(t){E&&(t._devtoolHook=E,E.emit("vuex:init",t),E.on("vuex:travel-to-state",function(e){t.replaceState(e)}),t.subscribe(function(t,e){E.emit("vuex:mutation",t,e)}))}function i(t,e){Object.keys(t).forEach(function(n){return e(t[n],n)})}function o(t){return null!==t&&"object"==typeof t}function a(t){return t&&"function"==typeof t.then}function s(t,e){if(!t)throw new Error("[vuex] "+e)}function u(t,e){if(t.update(e),e.modules)for(var n in e.modules){if(!t.getChild(n))return void console.warn("[vuex] trying to add a new module '"+n+"' on hot reloading, manual reload is needed");u(t.getChild(n),e.modules[n])}}function c(t,e){t._actions=Object.create(null),t._mutations=Object.create(null),t._wrappedGetters=Object.create(null),t._modulesNamespaceMap=Object.create(null);var n=t.state;f(t,n,[],t._modules.root,!0),l(t,n,e)}function l(t,e,n){var r=t._vm;t.getters={};var o=t._wrappedGetters,a={};i(o,function(e,n){a[n]=function(){return e(t)},Object.defineProperty(t.getters,n,{get:function(){return t._vm[n]},enumerable:!0})});var s=S.config.silent;S.config.silent=!0,t._vm=new S({data:{$$state:e},computed:a}),S.config.silent=s,t.strict&&g(t),r&&(n&&t._withCommit(function(){r._data.$$state=null}),S.nextTick(function(){return r.$destroy()}))}function f(t,e,n,r,i){var o=!n.length,a=t._modules.getNamespace(n);if(r.namespaced&&(t._modulesNamespaceMap[a]=r),!o&&!i){var s=_(e,n.slice(0,-1)),u=n[n.length-1];t._withCommit(function(){S.set(s,u,r.state)})}var c=r.context=d(t,a,n);r.forEachMutation(function(e,n){h(t,a+n,e,c)}),r.forEachAction(function(e,n){v(t,a+n,e,c)}),r.forEachGetter(function(e,n){m(t,a+n,e,c)}),r.forEachChild(function(r,o){f(t,e,n.concat(o),r,i)})}function d(t,e,n){var r=""===e,i={dispatch:r?t.dispatch:function(n,r,i){var o=y(n,r,i),a=o.payload,s=o.options,u=o.type;return s&&s.root||(u=e+u,t._actions[u])?t.dispatch(u,a):void console.error("[vuex] unknown local action type: "+o.type+", global type: "+u)},commit:r?t.commit:function(n,r,i){var o=y(n,r,i),a=o.payload,s=o.options,u=o.type;if(!(s&&s.root||(u=e+u,t._mutations[u])))return void console.error("[vuex] unknown local mutation type: "+o.type+", global type: "+u);t.commit(u,a,s)}};return Object.defineProperties(i,{getters:{get:r?function(){return t.getters}:function(){return p(t,e)}},state:{get:function(){return _(t.state,n)}}}),i}function p(t,e){var n={},r=e.length;return Object.keys(t.getters).forEach(function(i){if(i.slice(0,r)===e){var o=i.slice(r);Object.defineProperty(n,o,{get:function(){return t.getters[i]},enumerable:!0})}}),n}function h(t,e,n,r){(t._mutations[e]||(t._mutations[e]=[])).push(function(t){n(r.state,t)})}function v(t,e,n,r){(t._actions[e]||(t._actions[e]=[])).push(function(e,i){var o=n({dispatch:r.dispatch,commit:r.commit,getters:r.getters,state:r.state,rootGetters:t.getters,rootState:t.state},e,i);return a(o)||(o=Promise.resolve(o)),t._devtoolHook?o.catch(function(e){throw t._devtoolHook.emit("vuex:error",e),e}):o})}function m(t,e,n,r){if(t._wrappedGetters[e])return void console.error("[vuex] duplicate getter key: "+e);t._wrappedGetters[e]=function(t){return n(r.state,r.getters,t.state,t.getters)}}function g(t){t._vm.$watch(function(){return this._data.$$state},function(){s(t._committing,"Do not mutate vuex store state outside mutation handlers.")},{deep:!0,sync:!0})}function _(t,e){return e.length?e.reduce(function(t,e){return t[e]},t):t}function y(t,e,n){return o(t)&&t.type&&(n=e,e=t,t=t.type),s("string"==typeof t,"Expects string as the type, but found "+typeof t+"."),{type:t,payload:e,options:n}}function b(t){if(S)return void console.error("[vuex] already installed. Vue.use(Vuex) should be called only once.");S=t,C(S)}function x(t){return Array.isArray(t)?t.map(function(t){return{key:t,val:t}}):Object.keys(t).map(function(e){return{key:e,val:t[e]}})}function w(t){return function(e,n){return"string"!=typeof e?(n=e,e=""):"/"!==e.charAt(e.length-1)&&(e+="/"),t(e,n)}}function k(t,e,n){var r=t._modulesNamespaceMap[n];return r||console.error("[vuex] module namespace not found in "+e+"(): "+n),r}/** * vuex v2.3.0 * (c) 2017 Evan You * @license MIT @@ -13,4 +13,4 @@ var C=function(t){function e(){var t=this.$options;t.store?this.$store=t.store:t * (c) 2017 Evan You * @license MIT */ -function n(t,e){if(!t)throw new Error("[vue-router] "+e)}function r(e,n){"production"===t.env.NODE_ENV||e||"undefined"!=typeof console&&console.warn("[vue-router] "+n)}function i(t){return Object.prototype.toString.call(t).indexOf("Error")>-1}function o(e,n){switch(typeof n){case"undefined":return;case"object":return n;case"function":return n(e);case"boolean":return n?e.params:void 0;default:"production"!==t.env.NODE_ENV&&r(!1,'props in "'+e.path+'" is a '+typeof n+", expecting an object, function or boolean.")}}function a(e,n,i){void 0===n&&(n={});var o,a=i||s;try{o=a(e||"")}catch(e){"production"!==t.env.NODE_ENV&&r(!1,e.message),o={}}for(var u in n){var c=n[u];o[u]=Array.isArray(c)?c.slice():c}return o}function s(t){var e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach(function(t){var n=t.replace(/\+/g," ").split("="),r=Pt(n.shift()),i=n.length>0?Pt(n.join("=")):null;void 0===e[r]?e[r]=i:Array.isArray(e[r])?e[r].push(i):e[r]=[e[r],i]}),e):e}function u(t){var e=t?Object.keys(t).map(function(e){var n=t[e];if(void 0===n)return"";if(null===n)return Dt(e);if(Array.isArray(n)){var r=[];return n.forEach(function(t){void 0!==t&&(null===t?r.push(Dt(e)):r.push(Dt(e)+"="+Dt(t)))}),r.join("&")}return Dt(e)+"="+Dt(n)}).filter(function(t){return t.length>0}).join("&"):null;return e?"?"+e:""}function c(t,e,n,r){var i=r&&r.options.stringifyQuery,o={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:e.query||{},params:e.params||{},fullPath:f(e,i),matched:t?l(t):[]};return n&&(o.redirectedFrom=f(n,i)),Object.freeze(o)}function l(t){for(var e=[];t;)e.unshift(t),t=t.parent;return e}function f(t,e){var n=t.path,r=t.query;void 0===r&&(r={});var i=t.hash;void 0===i&&(i="");var o=e||u;return(n||"/")+o(r)+i}function d(t,e){return e===It?t===e:!!e&&(t.path&&e.path?t.path.replace(Mt,"")===e.path.replace(Mt,"")&&t.hash===e.hash&&p(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&p(t.query,e.query)&&p(t.params,e.params)))}function p(t,e){void 0===t&&(t={}),void 0===e&&(e={});var n=Object.keys(t),r=Object.keys(e);return n.length===r.length&&n.every(function(n){var r=t[n],i=e[n];return"object"==typeof r&&"object"==typeof i?p(r,i):String(r)===String(i)})}function h(t,e){return 0===t.path.replace(Mt,"/").indexOf(e.path.replace(Mt,"/"))&&(!e.hash||t.hash===e.hash)&&v(t.query,e.query)}function v(t,e){for(var n in e)if(!(n in t))return!1;return!0}function m(t){if(!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey||t.defaultPrevented||void 0!==t.button&&0!==t.button)){if(t.currentTarget&&t.currentTarget.getAttribute){if(/\b_blank\b/i.test(t.currentTarget.getAttribute("target")))return}return t.preventDefault&&t.preventDefault(),!0}}function g(t){if(t)for(var e,n=0;n=0&&(e=t.slice(r),t=t.slice(0,r));var i=t.indexOf("?");return i>=0&&(n=t.slice(i+1),t=t.slice(0,i)),{path:t,query:n,hash:e}}function x(t){return t.replace(/\/\//g,"/")}function w(t,e){for(var n,r=[],i=0,o=0,a="",s=e&&e.delimiter||"/";null!=(n=Gt.exec(t));){var u=n[0],c=n[1],l=n.index;if(a+=t.slice(o,l),o=l+u.length,c)a+=c[1];else{var f=t[o],d=n[2],p=n[3],h=n[4],v=n[5],m=n[6],g=n[7];a&&(r.push(a),a="");var _=null!=d&&null!=f&&f!==d,y="+"===m||"*"===m,b="?"===m||"*"===m,x=n[2]||s,w=h||v;r.push({name:p||i++,prefix:d||"",delimiter:x,optional:b,repeat:y,partial:_,asterisk:!!g,pattern:w?$(w):g?".*":"[^"+A(x)+"]+?"})}}return o-1&&(a.params[f]=n.params[f]);if(u)return a.path=M(u.path,a.params,'named route "'+s+'"'),l(u,a,o)}else if(a.path){a.params={};for(var v=0;v=t.length?n():t[i]?e(t[i],function(){r(i+1)}):r(i+1)};r(0)}function st(e){return function(n,o,a){var s=!1,u=0,c=null;ut(e,function(e,n,o,l){if("function"==typeof e&&void 0===e.cid){s=!0,u++;var f,d=lt(function(t){t.__esModule&&t.default&&(t=t.default),e.resolved="function"==typeof t?t:St.extend(t),o.components[l]=t,--u<=0&&a()}),p=lt(function(e){var n="Failed to resolve async component "+l+": "+e;"production"!==t.env.NODE_ENV&&r(!1,n),c||(c=i(e)?e:new Error(n),a(c))});try{f=e(d,p)}catch(t){p(t)}if(f)if("function"==typeof f.then)f.then(d,p);else{var h=f.component;h&&"function"==typeof h.then&&h.then(d,p)}}}),s||a()}}function ut(t,e){return ct(t.map(function(t){return Object.keys(t.components).map(function(n){return e(t.components[n],t.instances[n],t,n)})}))}function ct(t){return Array.prototype.concat.apply([],t)}function lt(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}function ft(t){if(!t)if(Vt){var e=document.querySelector("base");t=e&&e.getAttribute("href")||"/",t=t.replace(/^https?:\/\/[^\/]+/,"")}else t="/";return"/"!==t.charAt(0)&&(t="/"+t),t.replace(/\/$/,"")}function dt(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n=0?e.slice(0,n):e;window.location.replace(r+"#"+t)}function At(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}function $t(t,e,n){var r="hash"===n?"#"+e:e;return t?x(t+"/"+r):r}var St,jt={name:"router-view",functional:!0,props:{name:{type:String,default:"default"}},render:function(t,e){var n=e.props,r=e.children,i=e.parent,a=e.data;a.routerView=!0;for(var s=i.$createElement,u=n.name,c=i.$route,l=i._routerViewCache||(i._routerViewCache={}),f=0,d=!1;i&&i._routerRoot!==i;)i.$vnode&&i.$vnode.data.routerView&&f++,i._inactive&&(d=!0),i=i.$parent;if(a.routerViewDepth=f,d)return s(l[u],a,r);var p=c.matched[f];if(!p)return l[u]=null,s();var h=l[u]=p.components[u];return a.registerRouteInstance=function(t,e){var n=p.instances[u];(e&&n!==t||!e&&n===t)&&(p.instances[u]=e)},(a.hook||(a.hook={})).prepatch=function(t,e){p.instances[u]=e.componentInstance},a.props=o(c,p.props&&p.props[u]),s(h,a,r)}},Tt=/[!'()*]/g,Nt=function(t){return"%"+t.charCodeAt(0).toString(16)},Rt=/%2C/g,Dt=function(t){return encodeURIComponent(t).replace(Tt,Nt).replace(Rt,",")},Pt=decodeURIComponent,Mt=/\/?$/,It=c(null,{path:"/"}),Ft=[String,Object],Lt=[String,Array],zt={name:"router-link",props:{to:{type:Ft,required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:Lt,default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,i=n.resolve(this.to,r,this.append),o=i.location,a=i.route,s=i.href,u={},l=n.options.linkActiveClass,f=n.options.linkExactActiveClass,p=null==l?"router-link-active":l,v=null==f?"router-link-exact-active":f,_=null==this.activeClass?p:this.activeClass,y=null==this.exactActiveClass?v:this.exactActiveClass,b=o.path?c(null,o,null,n):a;u[y]=d(r,b),u[_]=this.exact?u[y]:h(r,b);var x=function(t){m(t)&&(e.replace?n.replace(o):n.push(o))},w={click:m};Array.isArray(this.event)?this.event.forEach(function(t){w[t]=x}):w[this.event]=x;var k={class:u};if("a"===this.tag)k.on=w,k.attrs={href:s};else{var C=g(this.$slots.default);if(C){C.isStatic=!1;var E=St.util.extend;(C.data=E({},C.data)).on=w;(C.data.attrs=E({},C.data.attrs)).href=s}else k.on=w}return t(this.tag,k,this.$slots.default)}},Vt="undefined"!=typeof window,Ut=Array.isArray||function(t){return"[object Array]"==Object.prototype.toString.call(t)},qt=P,Ht=w,Wt=k,Bt=O,Yt=D,Gt=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");qt.parse=Ht,qt.compile=Wt,qt.tokensToFunction=Bt,qt.tokensToRegExp=Yt;var Kt=Object.create(null),Xt=Object.create(null),Jt=Vt&&function(){var t=window.navigator.userAgent;return(-1===t.indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&(window.history&&"pushState"in window.history)}(),Zt=Vt&&window.performance&&window.performance.now?window.performance:Date,Qt=et(),te=function(t,e){this.router=t,this.base=ft(e),this.current=It,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};te.prototype.listen=function(t){this.cb=t},te.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},te.prototype.onError=function(t){this.errorCbs.push(t)},te.prototype.transitionTo=function(t,e,n){var r=this,i=this.router.match(t,this.current);this.confirmTransition(i,function(){r.updateRoute(i),e&&e(i),r.ensureURL(),r.ready||(r.ready=!0,r.readyCbs.forEach(function(t){t(i)}))},function(t){n&&n(t),t&&!r.ready&&(r.ready=!0,r.readyErrorCbs.forEach(function(e){e(t)}))})},te.prototype.confirmTransition=function(t,e,n){var o=this,a=this.current,s=function(t){i(t)&&(o.errorCbs.length?o.errorCbs.forEach(function(e){e(t)}):(r(!1,"uncaught error during route navigation:"),console.error(t))),n&&n(t)};if(d(t,a)&&t.matched.length===a.matched.length)return this.ensureURL(),s();var u=dt(this.current.matched,t.matched),c=u.updated,l=u.deactivated,f=u.activated,p=[].concat(vt(l),this.router.beforeHooks,mt(c),f.map(function(t){return t.beforeEnter}),st(f));this.pending=t;var h=function(e,n){if(o.pending!==t)return s();try{e(t,a,function(t){!1===t||i(t)?(o.ensureURL(!0),s(t)):"string"==typeof t||"object"==typeof t&&("string"==typeof t.path||"string"==typeof t.name)?(s(),"object"==typeof t&&t.replace?o.replace(t):o.push(t)):n(t)})}catch(t){s(t)}};at(p,h,function(){var n=[];at(_t(f,n,function(){return o.current===t}).concat(o.router.resolveHooks),h,function(){if(o.pending!==t)return s();o.pending=null,e(t),o.router.app&&o.router.app.$nextTick(function(){n.forEach(function(t){t()})})})})},te.prototype.updateRoute=function(t){var e=this.current;this.current=t,this.cb&&this.cb(t),this.router.afterHooks.forEach(function(n){n&&n(t,e)})};var ee=function(t){function e(e,n){var r=this;t.call(this,e,n);var i=e.options.scrollBehavior;i&&B(),window.addEventListener("popstate",function(t){var n=r.current;r.transitionTo(xt(r.base),function(t){i&&Y(e,t,n,!0)})})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,i=this,o=i.current;this.transitionTo(t,function(t){it(x(r.base+t.fullPath)),Y(r.router,t,o,!1),e&&e(t)},n)},e.prototype.replace=function(t,e,n){var r=this,i=this,o=i.current;this.transitionTo(t,function(t){ot(x(r.base+t.fullPath)),Y(r.router,t,o,!1),e&&e(t)},n)},e.prototype.ensureURL=function(t){if(xt(this.base)!==this.current.fullPath){var e=x(this.base+this.current.fullPath);t?it(e):ot(e)}},e.prototype.getCurrentLocation=function(){return xt(this.base)},e}(te),ne=function(t){function e(e,n,r){t.call(this,e,n),r&&wt(this.base)||kt()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;window.addEventListener("hashchange",function(){kt()&&t.transitionTo(Ct(),function(t){Ot(t.fullPath)})})},e.prototype.push=function(t,e,n){this.transitionTo(t,function(t){Et(t.fullPath),e&&e(t)},n)},e.prototype.replace=function(t,e,n){this.transitionTo(t,function(t){Ot(t.fullPath),e&&e(t)},n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ct()!==e&&(t?Et(e):Ot(e))},e.prototype.getCurrentLocation=function(){return Ct()},e}(te),re=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)},n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)},n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,function(){e.index=n,e.updateRoute(r)})}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(te),ie=function(e){void 0===e&&(e={}),this.app=null,this.apps=[],this.options=e,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=q(e.routes||[],this);var r=e.mode||"hash";switch(this.fallback="history"===r&&!Jt&&!1!==e.fallback,this.fallback&&(r="hash"),Vt||(r="abstract"),this.mode=r,r){case"history":this.history=new ee(this,e.base);break;case"hash":this.history=new ne(this,e.base,this.fallback);break;case"abstract":this.history=new re(this,e.base);break;default:"production"!==t.env.NODE_ENV&&n(!1,"invalid mode: "+r)}},oe={currentRoute:{}};ie.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},oe.currentRoute.get=function(){return this.history&&this.history.current},ie.prototype.init=function(e){var r=this;if("production"!==t.env.NODE_ENV&&n(_.installed,"not installed. Make sure to call `Vue.use(VueRouter)` before creating root instance."),this.apps.push(e),!this.app){this.app=e;var i=this.history;if(i instanceof ee)i.transitionTo(i.getCurrentLocation());else if(i instanceof ne){var o=function(){i.setupListeners()};i.transitionTo(i.getCurrentLocation(),o,o)}i.listen(function(t){r.apps.forEach(function(e){e._route=t})})}},ie.prototype.beforeEach=function(t){return At(this.beforeHooks,t)},ie.prototype.beforeResolve=function(t){return At(this.resolveHooks,t)},ie.prototype.afterEach=function(t){return At(this.afterHooks,t)},ie.prototype.onReady=function(t,e){this.history.onReady(t,e)},ie.prototype.onError=function(t){this.history.onError(t)},ie.prototype.push=function(t,e,n){this.history.push(t,e,n)},ie.prototype.replace=function(t,e,n){this.history.replace(t,e,n)},ie.prototype.go=function(t){this.history.go(t)},ie.prototype.back=function(){this.go(-1)},ie.prototype.forward=function(){this.go(1)},ie.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map(function(t){return Object.keys(t.components).map(function(e){return t.components[e]})})):[]},ie.prototype.resolve=function(t,e,n){var r=V(t,e||this.history.current,n,this),i=this.match(r,e),o=i.redirectedFrom||i.fullPath;return{location:r,route:i,href:$t(this.history.base,o,this.mode),normalizedTo:r,resolved:i}},ie.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==It&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(ie.prototype,oe),ie.install=_,ie.version="2.7.0",Vt&&window.Vue&&window.Vue.use(ie),e.a=ie}).call(e,n(9))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(130),i=n.n(r),o=n(129),a=n.n(o),s=n(131),u=n.n(s);e.default={name:"app",components:{top:i.a,bottom:a.a,modal:u.a}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(125),i=n.n(r),o=n(20),a=n.n(o),s=n(18),u=n.n(s),c=n(3),l=n.n(c),f=n(2);e.default={created:function(){var t=this;n.i(f.a)("configPart/performanceAnalyzer",function(e,n){t.performanceAnalyzer=toml.parse(n.part),t.performanceAnalyzer.enabled=!0})},data:function(){return{dataset:{},strat:{},paperTrader:{},performanceAnalyzer:{}}},components:{stratPicker:a.a,datasetPicker:i.a,paperTrader:u.a},computed:{market:function(){return this.dataset.exchange?{exchange:this.dataset.exchange,currency:this.dataset.currency,asset:this.dataset.asset}:{}},range:function(){return this.dataset.exchange?{from:this.dataset.from,to:this.dataset.to}:{}},config:function(){var t={};return Object.assign(t,{watch:this.market},{paperTrader:this.paperTrader},this.strat,{backtest:{daterange:this.range}},{performanceAnalyzer:this.performanceAnalyzer}),t.valid=this.validConfig(t),t}},methods:{validConfig:function(t){if(!t.backtest)return!1;if(!t.backtest.daterange)return!1;if(l.a.isEmpty(t.backtest.daterange))return!1;if(!t.watch)return!1;if(!t.tradingAdvisor)return!1;var e=t.tradingAdvisor.method;if(l.a.isEmpty(t[e]))return!1;if(t.tradingAdvisor){if(l.a.isNaN(t.tradingAdvisor.candleSize))return!1;if(0==t.tradingAdvisor.candleSize)return!1}return!0},updateDataset:function(t){this.dataset=t,this.$emit("config",this.config)},updateStrat:function(t){this.strat=t,this.$emit("config",this.config)},updatePaperTrader:function(t){this.paperTrader=t,this.paperTrader.enabled=!0,this.$emit("config",this.config)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(119),i=n.n(r),o=n(120),a=n.n(o),s=n(2),u=n(5),c=n.n(u);e.default={data:function(){return{backtestable:!1,backtestState:"idle",backtestResult:!1,config:!1}},methods:{check:function(t){if(this.config=t,!t.valid)return this.backtestable=!1;this.backtestable=!0},run:function(){var t=this;this.backtestState="fetching";var e={gekkoConfig:this.config,data:{candleProps:["close","start"],indicatorResults:!0,report:!0,roundtrips:!0,trades:!0}};n.i(s.b)("backtest",e,function(e,n){t.backtestState="fetched",t.backtestResult=n})}},components:{configBuilder:i.a,result:a.a,spinner:c.a}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(68),i=n(69);e.default={props:["data","height"],data:function(){return{isClicked:!1}},watch:{data:function(){this.render()}},created:function(){setTimeout(this.render,100)},beforeDestroy:function(){this.remove()},methods:{click:function(){this.isClicked=!0},render:function(){this.remove(),_.size(this.data.candles)<4?n.i(i.a)("Not enough data to spawn chart"):n.i(r.a)(this.data.candles,this.data.trades,this.height)},remove:function(){d3.select("#chart").html("")}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(121),i=n.n(r),o=n(10),a=n.n(o),s=n(16),u=n.n(s);e.default={props:["result"],data:function(){return{}},methods:{},components:{roundtripTable:u.a,resultSummary:i.a,chart:a.a}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:["roundtrips"],data:function(){return{}},methods:{diff:function(t){return moment.duration(t).humanize()},humanizeDuration:function(t){return window.humanizeDuration(t)},fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},round:function(t){return(+t).toFixed(3)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(21),i=n.n(r);e.default={props:["report"],components:{paperTradeSummary:i.a},methods:{round:function(t){return(+t).toFixed(5)}},computed:{profitClass:function(){return this.report.relativeProfit>0?"profit":"loss"}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(126),i=n.n(r),o=n(3),a=(n.n(o),n(2));e.default={data:function(){return{exchange:!1,credentials:{}}},components:{exchangePicker:i.a},computed:{apiKeySets:function(){return this.$store.state.apiKeys},exchanges:function(){return this.$store.state.exchanges},requires:function(){return this.exchanges&&this.exchange?this.exchanges[this.exchange].requires:[]},config:function(){return{exchange:this.exchange,values:this.credentials}}},watch:{credentials:function(){this.emitConfig()}},methods:{updateExchange:function(t){this.credentials={},this.exchange=t,this.emitConfig()},emitConfig:function(){this.$emit("config",this.config)},upload:function(){var t=this,e=this.config.exchange;this.exchanges&&this.apiKeySets.includes(e)&&!confirm("You already have API keys for "+e+" defined, do you want to overwrite them?")||n.i(a.b)("addApiKey",this.config,function(e,n){if(e)return alert(e);t.credentials={}})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(122),i=n.n(r),o=n(2);e.default={components:{apiConfigBuilder:i.a},data:function(){return{addApiToggle:!1}},methods:{openAddApi:function(){this.addApiToggle=!0},removeApiKey:function(t){confirm("Are you sure you want to delete these API keys?")&&n.i(o.b)("removeApiKey",{exchange:t},function(t,e){if(t)return alert(t)})}},computed:{apiKeySets:function(){return this.$store.state.apiKeys}},watch:{apiKeySets:function(){this.addApiToggle=!1}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(5),i=n.n(r),o=n(8),a=n(13),s=n.i(o.a)("\n\n## Local data\n\nGekko needs local market data in order to backtest strategies. The local\ndata can also be used in a warmup period when running a strategy against a\nlive market.\n\n");e.default={mixins:[a.a],components:{spinner:i.a},data:function(){return{intro:s,viewUnscannable:!1}},methods:{toggleUnscannable:function(){this.viewUnscannable=!0},humanizeDuration:function(t){return window.humanizeDuration(t)},fmt:function(t){return t.format("YYYY-MM-DD HH:mm")}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(17),i=n.n(r),o=n(11),a=n.n(o),s=n(3);n.n(s);e.default={data:function(){return{market:{},range:{}}},components:{marketPicker:i.a,rangeCreator:a.a},computed:{config:function(){var t={};return Object.assign(t,this.market,{importer:{daterange:this.range}},{candleWriter:{enabled:!0}}),t}},methods:{updateMarketConfig:function(t){this.market=t,this.emitConfig()},updateRange:function(t){this.range=t,this.emitConfig()},emitConfig:function(){this.$emit("config",this.config)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),i=n(5),o=n.n(i),a=n(123),s=n.n(a),u=n(8),c=n.i(u.a)("\n\n## Import data\n\nThe importer can download historical market data directly from the exchange.\n\n");e.default={components:{importConfigBuilder:s.a,spinner:o.a},data:function(){return{intro:c,config:{}}},computed:{imports:function(){return this.$store.state.imports}},methods:{daysApart:function(t){var e=moment(t.to),n=moment(t.from);return e.diff(n,"days")},updateConfig:function(t){this.config=t},run:function(){var t=this;if(this.daysApart(this.config.importer.daterange)<1)return alert("You can only import at least one day of data..");n.i(r.b)("import",this.config,function(e,n){if(e)return alert(e);t.$store.commit("addImport",n),t.$router.push({path:"/data/importer/import/"+n.id})})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(128),a=n.n(o),s=n(5),u=n.n(s);e.default={components:{progressBar:a.a,spinner:u.a},computed:{data:function(){return i.a.find(this.$store.state.imports,{id:this.$route.params.id})},initialized:function(){if(this.data&&this.latest.isValid())return!0},latest:function(){if(this.data)return this.mom(this.data.latest)},fromEndMs:function(){if(this.data)return this.to.diff(this.latest)},fromEnd:function(){return this.latest?humanizeDuration(this.fromEndMs):"LOADING"},from:function(){if(this.data)return this.mom(this.data.from)},to:function(){if(this.data)return this.mom(this.data.to)},timespan:function(){if(this.data)return this.to.diff(this.from)},progress:function(){if(this.data){return 100*(this.timespan-this.fromEndMs)/this.timespan}}},methods:{fmt:function(t){return t.format("YYYY-MM-DD HH:mm:ss")},mom:function(t){return moment.utc(t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(17),i=n.n(r),o=n(127),a=n.n(o),s=n(20),u=n.n(s),c=n(18),l=n.n(c),f=n(2),d=n(3),p=n.n(d);e.default={created:function(){var t=this;n.i(f.a)("configPart/candleWriter",function(e,n){t.candleWriter=toml.parse(n.part)}),n.i(f.a)("configPart/performanceAnalyzer",function(e,n){t.performanceAnalyzer=toml.parse(n.part),t.performanceAnalyzer.enabled=!0})},data:function(){return{market:{},range:{},type:"",strat:{},paperTrader:{},candleWriter:{},performanceAnalyzer:{}}},components:{marketPicker:i.a,typePicker:a.a,stratPicker:u.a,paperTrader:l.a},computed:{isTradebot:function(){return"tradebot"===this.type},config:function(){var t={};return Object.assign(t,this.market,this.strat,{paperTrader:this.paperTrader},{candleWriter:this.candleWriter},{type:this.type},{performanceAnalyzer:this.performanceAnalyzer}),this.isTradebot&&(delete t.paperTrader,t.trader={enabled:!0}),t.valid=this.validConfig(t),t}},methods:{validConfig:function(t){if("market watcher"===t.type)return!0;if(!t.tradingAdvisor)return!1;if(p.a.isNaN(t.tradingAdvisor.candleSize))return!1;if(0==t.tradingAdvisor.candleSize)return!1;var e=t.tradingAdvisor.method;return!p.a.isEmpty(t[e])},updateMarketConfig:function(t){this.market=t,this.emitConfig()},updateType:function(t){this.type=t,this.emitConfig()},updateStrat:function(t){this.strat=t,this.emitConfig()},updatePaperTrader:function(t){this.paperTrader=t,this.paperTrader.enabled=!0,this.emitConfig()},emitConfig:function(){this.$emit("config",this.config)}}}},function(t,e,n){"use strict";function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}Object.defineProperty(e,"__esModule",{value:!0});var i,o=n(8),a=n.i(o.a)("\n\n## Live Gekko\n\nRun your strategy against the live market!\n\n");e.default=(i={data:function(){return{text:a}},created:function(){var t=this;this.timer=setInterval(function(){t.now=moment()},1e3)},destroyed:function(){clearTimeout(this.timer)}},r(i,"data",function(){return{text:a,timer:!1,now:moment()}}),r(i,"computed",{stratrunners:function(){return this.$store.state.stratrunners},watchers:function(){return this.$store.state.watchers}}),r(i,"methods",{humanizeDuration:function(t){return window.humanizeDuration(t)},moment:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}(function(t){return moment.utc(t)}),fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},round:function(t){return(+t).toFixed(3)},timespan:function(t,e){return this.humanizeDuration(this.moment(t).diff(this.moment(e)))}}),i)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(4),a=n(2),s=n(124),u=n.n(s);e.default={components:{gekkoConfigBuilder:u.a},data:function(){return{pendingStratrunner:!1,config:{}}},computed:{watchers:function(){return this.$store.state.watchers},stratrunners:function(){return this.$store.state.stratrunners},watchConfig:function(){var t=i.a.pick(this.config,"watch","candleWriter"),e=o.a.util.extend({},t);return e.type="market watcher",e.mode="realtime",e},requiredHistoricalData:function(){if(this.config.tradingAdvisor&&this.config.valid){var t=this.config.tradingAdvisor;return t.candleSize*t.historySize}},gekkoConfig:function(){var t;if(this.existingMarketWatcher){if(this.requiredHistoricalData){var e=moment().utc().startOf("minute").subtract(this.requiredHistoricalData,"minutes").unix(),n=moment.utc(this.existingMarketWatcher.firstCandle.start).unix();t=moment.unix(Math.max(e,n)).utc().format()}else t=moment().utc().startOf("minute").format();return o.a.util.extend({market:{type:"leech",from:t},mode:"realtime"},this.config)}},existingMarketWatcher:function(){var t=o.a.util.extend({},this.watchConfig.watch);return i.a.find(this.watchers,{watch:t})},exchange:function(){return this.watchConfig.watch.exchange},existingTradebot:function(){return i.a.find(this.stratrunners.filter(function(t){return"tradebot"===t.trader}),{watch:{exchange:this.exchange}})},availableApiKeys:function(){return this.$store.state.apiKeys}},watch:{existingMarketWatcher:function(t,e){var n=this;this.pendingStratrunner&&t&&t.firstCandle&&t.lastCandle&&(this.pendingStratrunner=!1,this.startGekko(function(t,e){n.$router.push({path:"/live-gekkos/stratrunner/"+e.id})}))}},methods:{updateConfig:function(t){this.config=t},start:function(){var t=this;if("tradebot"===this.config.type){if(this.existingTradebot){var e="You already have a tradebot running on this exchange";return e+=", you can only run one tradebot per exchange.",alert(e)}if(!this.availableApiKeys.includes(this.exchange))return alert("Please first configure API keys for this exchange in the config page.")}"market watcher"===this.config.type?this.existingMarketWatcher?(alert("This market is already being watched, redirecting you now..."),this.$router.push({path:"/live-gekkos/watcher/"+this.existingMarketWatcher.id})):this.startWatcher(function(e,n){t.$router.push({path:"/live-gekkos/watcher/"+n.id})}):this.existingMarketWatcher?this.startGekko(this.routeToGekko):this.startWatcher(function(e,n){t.pendingStratrunner=!0})},routeToGekko:function(t,e){if(t||e.error)return console.error(t,e.error);this.$router.push({path:"/live-gekkos/stratrunner/"+e.id})},startWatcher:function(t){n.i(a.b)("startGekko",this.watchConfig,t)},startGekko:function(t){n.i(a.b)("startGekko",this.gekkoConfig,t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(4),i=n(3),o=n.n(i),a=n(2),s=n(5),u=n.n(s),c=n(10),l=n.n(c),f=n(16),d=n.n(f),p=n(21),h=n.n(p);e.default={created:function(){this.isLoading||this.getCandles()},components:{spinner:u.a,chart:l.a,paperTradeSummary:h.a,roundtrips:d.a},data:function(){return{candleFetch:"idle",candles:!1}},computed:{stratrunners:function(){return this.$store.state.stratrunners},data:function(){return o.a.find(this.stratrunners,{id:this.$route.params.id})},chartData:function(){return{candles:this.candles,trades:this.trades}},trades:function(){return this.data?this.data.trades:[]},report:function(){if(this.data)return this.data.report},stratName:function(){if(this.data)return this.data.strat.tradingAdvisor.method},stratParams:function(){if(!this.data)return"";var t=r.a.util.extend({},this.data.strat.params);return delete t.__empty,o.a.isEmpty(t)?"No parameters":JSON.stringify(t,null,4)},isLoading:function(){return!this.data||(!o.a.isObject(this.data.firstCandle)||!o.a.isObject(this.data.lastCandle))},watchers:function(){return this.$store.state.watchers},watcher:function(){var t=r.a.util.extend({},this.data.watch);return o.a.find(this.watchers,{watch:t})}},watch:{"data.lastCandle.start":function(){this.candleFetch="dirty"},data:function(t,e){this.isLoading||"fetched"!==this.candleFetch&&this.getCandles()}},methods:{round:function(t){return(+t).toFixed(5)},humanizeDuration:function(t){return window.humanizeDuration(t)},moment:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}(function(t){return moment.utc(t)}),fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},getCandles:function(){var t=this;this.candleFetch="fetching";var e=this.data.lastCandle.start,r=this.data.firstCandle.start,i=this.data.strat.tradingAdvisor.candleSize,s={watch:this.data.watch,daterange:{to:e,from:r},candleSize:i};n.i(a.b)("getCandles",s,function(e,n){t.candleFetch="fetched",n&&!n.error&&o.a.isArray(n)||console.log(n),t.candles=n.map(function(t){return t.start=moment.unix(t.start).utc().format(),t})})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),i=n(3),o=n.n(i),a=n(5),s=n.n(a),u=(n(4),n(10)),c=n.n(u);e.default={created:function(){this.isLoading||this.getCandles()},components:{spinner:s.a,chart:c.a},data:function(){return{candleFetch:"idle",candles:[]}},computed:{watchers:function(){return this.$store.state.watchers},data:function(){return o.a.find(this.watchers,{id:this.$route.params.id})},chartData:function(){return{candles:this.candles,trades:[]}},isLoading:function(){return!this.data||(!o.a.isObject(this.data.firstCandle)||!o.a.isObject(this.data.lastCandle))}},watch:{"data.lastCandle.start":function(){this.candleFetch="dirty"},data:function(t,e){t&&t.firstCandle&&t.lastCandle&&"fetched"!==this.candleFetch&&this.getCandles()}},methods:{humanizeDuration:function(t){return window.humanizeDuration(t)},moment:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}(function(t){return moment.utc(t)}),fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},getCandles:function(){var t=this;this.candleFetch="fetching";var e=moment.utc(this.data.lastCandle.start).unix(),i=Math.max(moment.utc(this.data.firstCandle.start).unix(),moment.utc(e).subtract(7,"days").unix()),o=e-i,a=60;o<86400&&(a=o<43200?1:5),i=moment.unix(i).utc().format(),e=moment.unix(e).utc().format();var s={watch:this.data.watch,daterange:{to:e,from:i},candleSize:a};n.i(r.b)("getCandles",s,function(e,n){t.candleFetch="fetched",t.candles=n.map(function(t){return t.start=moment.unix(t.start).utc().format(),t})})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=(n.n(r),n(4)),o=(n(2),n(5)),a=n.n(o),s=n(13);e.default={components:{spinner:a.a},data:function(){return{setIndex:-1,customTo:!1,customFrom:!1,rangeVisible:!1,set:!1}},mixins:[s.a],methods:{humanizeDuration:function(t){return window.humanizeDuration(t,{largest:4})},fmt:function(t){return t.utc().format("YYYY-MM-DD HH:mm")},openRange:function(){if(-1===this.setIndex)return alert("Select a dataset to adjust range");this.updateCustomRange(),this.rangeVisible=!0},updateCustomRange:function(){this.customTo=this.fmt(this.set.to),this.customFrom=this.fmt(this.set.from)},emitSet:function(t){if(t){var e=void 0;this.customTo?(e=i.a.util.extend({},t),e.to=moment.utc(this.customTo,"YYYY-MM-DD HH:mm").format(),e.from=moment.utc(this.customFrom,"YYYY-MM-DD HH:mm").format()):e=t,this.$emit("dataset",e)}}},watch:{setIndex:function(){this.set=this.datasets[this.setIndex],this.updateCustomRange(),this.emitSet(this.set)},customTo:function(){this.emitSet(this.set)},customFrom:function(){this.emitSet(this.set)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(19),a=(n.n(o),n(11));n.n(a),n(2);e.default={props:["onlyTradable","onlyImportable"],data:function(){return{exchange:"poloniex"}},created:function(){this.emitExchange()},computed:{exchanges:function(){var t=Object.assign({},this.$store.state.exchanges);return!i.a.isEmpty(t)&&(this.onlyTradable&&i.a.each(t,function(e,n){e.tradable||delete t[n]}),this.onlyImportable&&i.a.each(t,function(e,n){e.importable||delete t[n]}),t)}},watch:{exchanges:function(){this.emitExchange()},exchange:function(){this.emitExchange()}},methods:{emitExchange:function(){this.$emit("exchange",this.exchange)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(19),a=(n.n(o),n(11));n.n(a),n(2);e.default={props:["onlyTradable","onlyImportable"],data:function(){return{exchange:"poloniex",currency:"USDT",asset:"BTC"}},created:function(){this.emitConfig()},computed:{exchanges:function(){var t=Object.assign({},this.$store.state.exchanges);return!i.a.isEmpty(t)&&(this.onlyTradable&&i.a.each(t,function(e,n){e.tradable||delete t[n]}),this.onlyImportable&&i.a.each(t,function(e,n){e.importable||delete t[n]}),t)},markets:function(){return this.exchanges?this.exchanges[this.exchange]:null},assets:function(){return this.exchanges?this.exchanges[this.exchange].markets[this.currency]:null},currencies:function(){return this.exchanges?i.a.keys(this.exchanges[this.exchange].markets):null},watchConfig:function(){return{watch:{exchange:this.exchange,currency:this.currency,asset:this.asset}}}},watch:{currency:function(){this.emitConfig()},asset:function(){this.emitConfig()},market:function(){this.emitConfig()},exchanges:function(){this.emitConfig()},exchange:function(){this.emitConfig()}},methods:{emitConfig:function(){this.$emit("market",this.watchConfig)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=(n.n(r),n(2));e.default={created:function(){var t=this;n.i(i.a)("configPart/paperTrader",function(e,n){t.rawPaperTraderParams=n.part})},data:function(){return{rawPaperTraderParams:"",rawPaperTraderParamsError:!1,paperTraderParams:{},toggle:"closed"}},watch:{rawPaperTraderParams:function(){this.emitConfig()}},methods:{switchToggle:function(){"open"===this.toggle?this.toggle="closed":this.toggle="open"},emitConfig:function(){this.parseParams(),this.$emit("settings",this.paperTraderParams)},parseParams:function(){try{this.paperTraderParams=toml.parse(this.rawPaperTraderParams),this.paperTraderParams.reportRoundtrips=!0,this.rawPaperTraderParamsError=!1}catch(t){this.rawPaperTraderParamsError=t,this.paperTraderParams={}}}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3);n.n(r),n(2);e.default={data:function(){return{from:"",to:""}},created:function(){var t=moment().startOf("minute"),e=t.clone().subtract(3,"months");this.to=this.fmt(t),this.from=this.fmt(e),this.emitRange()},methods:{fmtTs:function(t){return moment.unix(t).utc()},fmt:function(t){return t.utc().format("YYYY-MM-DD HH:mm")},emitRange:function(){this.$emit("range",{from:this.fmtTs(this.from),to:this.fmtTs(this.to)})},emitManualEntry:function(){if(this.from.length<"4"||this.from.length<"4")return this.$emit("range",{});var t=moment.utc(this.from),e=moment.utc(this.to);t.isValid()&&e.isValid()?this.$emit("range",{from:this.fmt(t),to:this.fmt(e)}):this.$emit("range",{})}},watch:{from:function(){this.emitManualEntry()},to:function(){this.emitManualEntry()},config:function(){this.scanned=!1},tab:function(){this.scanned=!1,this.$emit("range",{})},selectedRangeIndex:function(){var t=this.ranges[this.selectedRangeIndex];t&&this.emitRange(t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=(n.n(r),n(2));e.default={props:["config"],data:function(){return{scanned:!1,ranges:[],selectedRangeIndex:-1,tab:"scan",from:"",to:""}},methods:{scan:function(){var t=this;this.scanned="fetching",this.selectedRangeIndex=-1,n.i(i.b)("scan",this.config,function(e,n){t.scanned=!0,t.ranges=n,t.selectedRangeIndex=0})},printRange:function(t){var e=function(t){return t.format("YYYY-MM-DD HH:mm")},n=moment.unix(t.from),r=moment.unix(t.to),i=moment.duration(r.diff(n)).humanize();return e(n)+" to "+e(r)+" ("+i+")"},fmtTs:function(t){return moment.unix(t).utc()},fmt:function(t){return t.utc().format()},emitRange:function(t){this.$emit("range",{from:this.fmtTs(t.from),to:this.fmtTs(t.to)})},emitManualEntry:function(){if(this.from.length<"4"||this.from.length<"4")return this.$emit("range",{});var t=moment.utc(this.from),e=moment.utc(this.to);t.isValid()&&e.isValid()?this.$emit("range",{from:this.fmt(t),to:this.fmt(e)}):this.$emit("range",{})},reset:function(){this.scanned=!1,this.$emit("range",{})}},watch:{from:function(){this.emitManualEntry()},to:function(){this.emitManualEntry()},config:function(){this.reset()},tab:function(){this.reset()},selectedRangeIndex:function(){var t=this.ranges[this.selectedRangeIndex];t&&this.emitRange(t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(2);e.default={data:function(){return{strategies:[],candleSizeUnit:"hours",rawCandleSize:1,strategy:"MACD",historySize:10,rawStratParams:"",rawStratParamsError:!1,emptyStrat:!1,stratParams:{}}},created:function(){var t=this;n.i(o.a)("strategies",function(e,n){t.strategies=n,i.a.each(t.strategies,function(t){t.empty=""===t.params}),t.rawStratParams=i.a.find(t.strategies,{name:t.strategy}).params,t.emptyStrat=i.a.find(t.strategies,{name:t.strategy}).empty,t.emitConfig()})},watch:{strategy:function(t){t=i.a.find(this.strategies,{name:t}),this.rawStratParams=t.params,this.emptyStrat=t.empty,this.emitConfig()},candleSize:function(){this.emitConfig()},historySize:function(){this.emitConfig()},rawStratParams:function(){this.emitConfig()}},computed:{candleSize:function(){return"minutes"===this.candleSizeUnit?this.rawCandleSize:"hours"===this.candleSizeUnit?60*this.rawCandleSize:"days"===this.candleSizeUnit?60*this.rawCandleSize*24:void 0},singularCandleSizeUnit:function(){return this.candleSizeUnit.slice(0,-1)},config:function(){var t={tradingAdvisor:{enabled:!0,method:this.strategy,candleSize:+this.candleSize,historySize:+this.historySize}};return this.emptyStrat?t[this.strategy]={__empty:!0}:t[this.strategy]=this.stratParams,t}},methods:{humanizeDuration:function(t){return window.humanizeDuration(t)},emitConfig:function(){this.parseParams(),this.$emit("stratConfig",this.config)},parseParams:function(){try{this.stratParams=toml.parse(this.rawStratParams),this.rawStratParamsError=!1}catch(t){this.rawStratParamsError=t,this.stratParams={}}}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={created:function(){this.emitType()},data:function(){return{types:["paper trader","market watcher","tradebot"],selectedTypeIndex:0}},methods:{emitType:function(){this.$emit("type",this.type)}},watch:{type:function(){this.emitType()}},computed:{type:function(){return this.types[this.selectedTypeIndex]}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:["report"],methods:{round2:function(t){return(+t).toFixed(2)},round:function(t){return(+t).toFixed(5)}},computed:{profitClass:function(){return this.report.relativeProfit>0?"profit":"loss"}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:["progress"],methods:{round:function(t){return(+t).toFixed(2)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(112),i=n(113);e.default={data:function(){return{version:{gekko:r.version,ui:i.version}}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(8),i=n.i(r.a)("\n\n## Gekko\n\nGekko is a Bitcoin trading bot and backtesting platform that\nconnects to popular Bitcoin exchanges. It is written in javascript\nand runs on nodejs.\n\n[Find out more](https://gekko.wizb.it/).\n\n*Gekko is 100% open source and free, if you paid for this you have been scammed.*\n\n");e.default={data:function(){return{left:i}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(8),i={disconnected:n.i(r.a)("\n\n## Disconnected\n\nSomething happened to either Gekko or the connection.\nPlease check the terminal where Gekko is running or\nyour network connection.\n\n ")};e.default={computed:{active:function(){return!this.$store.state.warnings.connected},content:function(){return this.$store.state.warnings.connected?"":i.disconnected}}}},function(t,e,n){"use strict";var r=n(3),i=n.n(r),o=function(){function t(t,e){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){i=!0,o=t}finally{try{!r&&s.return&&s.return()}finally{if(i)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();e.a=function(t,e,n){function r(){if(!d3.event.sourceEvent||"zoom"!==d3.event.sourceEvent.type){var t=d3.event.selection||y.range();_.domain(t.map(y.invert,y)),a(_.domain()),d.select(".axis--y").call(C),T.attr("cx",function(t){return _(t.date)}).attr("cy",function(t){return b(t.price)}),S.select(".line").attr("d",A),S.select(".axis--x").call(w),d.select(".zoom").call(O.transform,d3.zoomIdentity.scale(m/(t[1]-t[0])).translate(-t[0],0))}}function a(t){var e=o(t,2),n=e[0],r=e[1],a=i.a.sortedIndex(l,n),s=i.a.sortedIndex(l,r),u=f.slice(a,s);b.domain([.9995*d3.min(u),1.0005*d3.max(u)])}function s(){if(!d3.event.sourceEvent||"brush"!==d3.event.sourceEvent.type){var t=d3.event.transform;a(t.rescaleX(y).domain()),d.select(".axis--y").call(C),_.domain(t.rescaleX(y).domain()),S.select(".line").attr("d",A),T.attr("cx",function(t){return _(t.date)}).attr("cy",function(t){return b(t.price)}),S.select(".axis--x").call(w),j.select(".brush").call(E.move,_.range().map(t.invertX,t))}}var u=e.map(function(t){return{price:t.price,date:moment.utc(t.date).toDate(),action:t.action}}),c=t.map(function(t){return{price:t.close,date:moment.utc(t.start).toDate()}}),l=c.map(function(t){return+t.date}),f=c.map(function(t){return+t.price}),d=d3.select("#chart");d.attr("width",window.innerWidth-20);var p={top:20,right:20,bottom:110,left:40},h=n-p.top-p.bottom,v={top:n-70,right:20,bottom:30,left:40},m=+d.attr("width")-p.left-p.right,g=n-v.top-v.bottom,_=d3.scaleUtc().range([0,m]),y=d3.scaleUtc().range([0,m]),b=d3.scaleLinear().range([h,0]),x=d3.scaleLinear().range([g,0]),w=d3.axisBottom(_),k=d3.axisBottom(y),C=d3.axisLeft(b).ticks(n/50),E=d3.brushX().extent([[0,0],[m,g]]).on("brush end",r),O=d3.zoom().scaleExtent([1,100]).translateExtent([[0,0],[m,h]]).extent([[0,0],[m,h]]).on("zoom",s),A=d3.line().x(function(t){return _(t.date)}).y(function(t){return b(t.price)}),$=d3.line().x(function(t){return y(t.date)}).y(function(t){return x(t.price)});d.append("defs").append("clipPath").attr("id","clip").append("rect").attr("width",m).attr("height",h);var S=d.append("g").attr("class","focus").attr("transform","translate("+p.left+","+p.top+")"),j=d.append("g").attr("class","context").attr("transform","translate("+v.left+","+v.top+")");_.domain(d3.extent(c,function(t){return t.date})),b.domain([.99*d3.min(f),1.01*d3.max(f)]),y.domain(_.domain()),x.domain(b.domain()),S.append("path").datum(c).attr("class","line price").attr("d",A),S.append("g").attr("class","axis axis--x").attr("transform","translate(0,"+h+")").call(w),S.append("g").attr("class","axis axis--y").call(C),j.append("path").datum(c).attr("class","line").attr("d",$),j.append("g").attr("class","axis axis--x").attr("transform","translate(0,"+g+")").call(k);var T=d.append("g").attr("transform","translate("+p.left+","+p.top+")").selectAll("circle").data(u).enter().append("circle").attr("class",function(t){return t.action}).attr("cx",function(t){return _(t.date)}).attr("cy",function(t){return b(t.price)}).attr("r",5);j.append("g").selectAll("circle").data(u).enter().append("circle").attr("class",function(t){return t.action}).attr("cx",function(t){return y(t.date)}).attr("cy",function(t){return x(t.price)}).attr("r",3);j.append("g").attr("class","brush").call(E).call(E.move,_.range()),d.append("rect").attr("class","zoom").attr("width",m).attr("height",h).attr("transform","translate("+p.left+","+p.top+")").call(O)}},function(t,e,n){"use strict";n.d(e,"a",function(){return r});var r=function(t){d3.select("#chart").append("text").attr("class","message").attr("x",150).attr("y",150).text(t)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){var e=n(4),r=n(23),i=n.n(r),o=n(34),a=n(7),s=n(24),u=n.n(s),c=n(33),l=n.n(c),f=n(26),d=n.n(f),p=n(27),h=n.n(p),v=n(28),m=n.n(v),g=n(25),_=n.n(g),y=n(29),b=n.n(y),x=n(30),w=n.n(x),k=n(31),C=n.n(k),E=n(32),O=n.n(E),A=n(6);e.a.use(o.a);var $=new o.a({mode:"hash",base:t,routes:[{path:"/",redirect:"/home"},{path:"/home",component:l.a},{path:"/backtest",component:u.a},{path:"/config",component:_.a},{path:"/data",component:d.a},{path:"/data/importer",component:h.a},{path:"/data/importer/import/:id",component:m.a},{path:"/live-gekkos",component:b.a},{path:"/live-gekkos/new",component:w.a},{path:"/live-gekkos/stratrunner/:id",component:C.a},{path:"/live-gekkos/watcher/:id",component:O.a}]});n.i(A.a)(),new e.a({router:$,store:a.a,el:"#app",render:function(t){return t(i.a)}})}.call(e,"/")},function(t,e,n){"use strict";var r=(n(4),n(22),n(75)),i=n(81),o=n(79),a=n(77),s=n(73);e.a=function(){n.i(r.a)(),n.i(i.a)(),n.i(o.a)(),n.i(a.a)(),n.i(s.a)()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"syncApiKeys",function(){return i}),n.d(e,"syncExchanges",function(){return o});var r=n(4),i=function(t,e){return r.a.set(t,"apiKeys",e),t},o=function(t,e){return r.a.set(t,"exchanges",e),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=function(){function t(t,e){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){i=!0,o=t}finally{try{!r&&s.return&&s.return()}finally{if(i)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),s=function(t){var e=t,n={};return e.forEach(function(t){n[t.slug]=n[t.slug]||{markets:{}},t.markets.forEach(function(e){var r=a(e.pair,2),i=r[0],o=r[1];n[t.slug].markets[i]=n[t.slug].markets[i]||[],n[t.slug].markets[i].push(o)}),n[t.slug].importable=!!t.providesFullHistory,n[t.slug].tradable=!!t.tradable,n[t.slug].requires=t.requires}),n},u=function(){n.i(r.a)("apiKeys",function(t,e){i.a.commit("syncApiKeys",e)}),n.i(r.a)("exchanges",function(t,e){i.a.commit("syncExchanges",s(e))})},c=function(){o.b.$on("apiKeys",function(t){i.a.commit("syncApiKeys",t.exchanges)})};e.a=function(){u(),c()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"addImport",function(){return i}),n.d(e,"syncImports",function(){return o}),n.d(e,"updateImport",function(){return a});var r=n(4),i=function(t,e){return t.imports.push(e),t},o=function(t,e){return t.imports=e,t},a=function(t,e){var n=t.imports.findIndex(function(t){return t.id===e.import_id}),i=t.imports[n];if(!i)return t;var o=r.a.util.extend(i,e.updates);return r.a.set(t.imports,n,o),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=function(){n.i(r.a)("imports",function(t,e){i.a.commit("syncImports",e)})},s=function(){o.b.$on("import_update",function(t){i.a.commit("updateImport",t)})};e.a=function(){a(),s()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"setGlobalWarning",function(){return i});var r=(n(4),n(3)),i=(n.n(r),function(t,e){return t.warnings[e.key]=e.value,t})},function(t,e,n){"use strict";var r=n(7),i=n(6),o=function(){i.b.$on("WS_STATUS_CHANGE",function(t){return r.a.commit("setGlobalWarning",{key:"connected",value:t.connected})})};e.a=function(){o()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"addStratrunner",function(){return i}),n.d(e,"syncStratrunners",function(){return o}),n.d(e,"updateStratrunner",function(){return a}),n.d(e,"addTradeToStratrunner",function(){return s}),n.d(e,"addRoundtripToStratrunner",function(){return u});var r=n(4),i=function(t,e){return t.stratrunners.push(e),t},o=function(t,e){return t.stratrunners=e,t},a=function(t,e){var n=t.stratrunners.findIndex(function(t){return t.id===e.gekko_id}),i=t.stratrunners[n];if(!i)return t;var o=r.a.util.extend(i,e.updates);return r.a.set(t.stratrunners,n,o),t},s=function(t,e){var n=t.stratrunners.findIndex(function(t){return t.id===e.gekko_id}),i=t.stratrunners[n];if(!i)return t;var o=r.a.util.extend({},i);return o.trades.push(e.trade),r.a.set(t.stratrunners,n,o),t},u=function(t,e){var n=t.stratrunners.findIndex(function(t){return t.id===e.gekko_id}),i=t.stratrunners[n];if(!i)return t;var o=r.a.util.extend({},i);return o.roundtrips.push(e.roundtrip),r.a.set(t.stratrunners,n,o),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=n(3),s=n.n(a),u=function(){n.i(r.a)("gekkos",function(t,e){var n=s.a.filter(e,{type:"leech"});i.a.commit("syncStratrunners",n)})},c=function(){o.b.$on("new_gekko",function(t){"leech"===t.gekko.type&&i.a.commit("addStratrunner",t.gekko)});var t=function(t){i.a.commit("updateStratrunner",t)},e=function(t){i.a.commit("addTradeToStratrunner",t)},n=function(t){i.a.commit("addRoundtripToStratrunner",t)};o.b.$on("report",t),o.b.$on("trade",e),o.b.$on("update",t),o.b.$on("startAt",t),o.b.$on("lastCandle",t),o.b.$on("firstCandle",t),o.b.$on("roundtrip",n)};e.a=function(){u(),c()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"addWatcher",function(){return i}),n.d(e,"syncWatchers",function(){return o}),n.d(e,"updateWatcher",function(){return a});var r=n(4),i=function(t,e){return t.watchers.push(e),t},o=function(t,e){return t.watchers=e,t},a=function(t,e){var n=t.watchers.findIndex(function(t){return t.id===e.gekko_id}),i=t.watchers[n];if(!i)return t;var o=r.a.util.extend(i,e.updates);return r.a.set(t.watchers,n,o),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=n(3),s=n.n(a),u=function(){n.i(r.a)("gekkos",function(t,e){var n=s.a.filter(e,{type:"watcher"});i.a.commit("syncWatchers",n)})},c=function(){o.b.$on("new_gekko",function(t){"watcher"===t.gekko.type&&i.a.commit("addWatcher",t.gekko)});var t=function(t){i.a.commit("updateWatcher",t)};o.b.$on("update",t),o.b.$on("startAt",t),o.b.$on("lastCandle",t),o.b.$on("firstCandle",t)};e.a=function(){u(),c()}},function(t,e,n){function r(t){if(t)return i(t)}function i(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}t.exports=r,r.prototype.on=r.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},r.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var r,i=0;i4?t:document.documentMode}()},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"#chartWrapper.clickable{position:relative}#chartWrapper.clickable .shield{cursor:zoom-in;position:absolute;top:0;bottom:0;left:0;right:0;background:grey;opacity:.1}#chart{background-color:#eee;width:100%}#chart circle{clip-path:url(#clip)}#chart .zoom{cursor:move;fill:none;pointer-events:all}#chart .line{fill:none;stroke:#4682b4;stroke-width:1.5px;clip-path:url(#clip)}#chart circle.buy{fill:#7fff00}#chart circle.sell{fill:red}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".scan-btn{margin-top:80px;margin-bottom:30px}.radio label{margin-top:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".progressbarWrapper p{text-align:center;font-size:20px}.progressbar{background-color:hsla(0,0%,85%,.99);border-radius:13px;padding:0}@keyframes shimmer{0%{background-position:0 0}to{background-position:960px 0}}.progressbar>div{height:20px;border-radius:10px;background-color:orange;animation-duration:1.5s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:shimmer;animation-timing-function:linear;background:#f6f7f8;background:linear-gradient(90deg,orange 10%,#ffce77 25%,orange 40%);background-size:960px 50px;background-position:0;position:relative}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".summary td{text-align:right}.big{font-size:1.3em}.big,.summary table{width:80%}.price.profit{color:#7fff00}.price.loss{color:red}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".summary td{text-align:right}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".scan-btn{margin-top:80px;margin-bottom:30px}.radio label{margin-top:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".clickable{cursor:pointer}table.full{width:100%}table.full td{padding:.5rem 0}table.full.data th{text-align:left;padding:.5rem 0}.warning p{margin:0;padding:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".menu{display:flex;width:100%;flex-direction:row;margin-top:0;margin-bottom:2rem}.menu a{flex:1 1 100%;display:block;text-align:center;text-decoration:none;color:inherit}.menu .router-link-active{background-color:hsla(0,0%,98%,.99)}.menu a:hover{text-decoration:underline}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".contain{max-width:900px;margin-left:auto;margin-right:auto}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".spinner{margin:20px auto 100px;width:50px;height:40px;text-align:center;font-size:10px}.spinner>div{background-color:#333;height:100%;width:6px;display:inline-block;margin-right:4px;-webkit-animation:sk-stretchdelay 1.2s infinite ease-in-out;animation:sk-stretchdelay 1.2s infinite ease-in-out}.spinner .rect2{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.spinner .rect3{-webkit-animation-delay:-1s;animation-delay:-1s}.spinner .rect4{-webkit-animation-delay:-.9s;animation-delay:-.9s}.spinner .rect5{-webkit-animation-delay:-.8s;animation-delay:-.8s}@-webkit-keyframes sk-stretchdelay{0%,40%,to{-webkit-transform:scaleY(.4)}20%{-webkit-transform:scaleY(1)}}@keyframes sk-stretchdelay{0%,40%,to{transform:scaleY(.4);-webkit-transform:scaleY(.4)}20%{transform:scaleY(1);-webkit-transform:scaleY(1)}}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".radio label{margin-top:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"#app{display:flex;min-height:100vh;flex-direction:column}.fill{flex:1}.text{max-width:500px}input{background:none;margin-top:.5em}.params{min-height:235px;line-height:1.3em}.hr{margin-top:2rem;margin-bottom:2rem;height:10px;background-color:hsla(0,0%,98%,.99)}.btn--primary{display:inline-block;margin-right:12px;margin-bottom:12px;height:40px;padding:0 18px;border-radius:4px;text-shadow:0 1px 3px rgba(36,180,126,.4);box-shadow:0 4px 6px rgba(50,50,93,.11),0 1px 3px rgba(0,0,0,.08);line-height:40px;transition:transform .25s}.btn--primary,.btn--primary:hover{background-color:#3498db;color:#fff;text-decoration:none}.btn--primary:hover{transform:translateY(-1px);box-shadow:0 7px 14px rgba(50,50,93,.1),0 3px 6px rgba(0,0,0,.08)}.btn--primary:active,.btn--primary:focus{background-color:#3498db;color:#fff;text-decoration:none}.btn--primary:active{transform:translateY(1px)}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"table.clickable{border-collapse:separate}tr.clickable td:first-child{padding-left:5px}tr.clickable{cursor:pointer}tr.clickable:hover{background:hsla(0,0%,85%,.99)}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"td.radio{width:45px}td label{display:inline;font-size:1em}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"#modal-background{position:fixed;top:0;bottom:0;left:0;right:0;background-color:#000;opacity:.5}.modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:600px;min-height:300px;background-color:#fff}.modal-guts{position:absolute;top:0;left:0;width:100%;height:100%;padding:20px 50px 20px 20px;overflow:auto}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".align .custom-select select{padding:.4em 1.2em .3em .8em}.label-like{display:block;font-size:.9em;color:#777}.align{padding-left:1em}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".align .custom-select select{padding:.4em 1.2em .3em .8em}.label-like{display:block;font-size:.9em;color:#777}.align{padding-left:1em}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".roundtrips{margin-top:50px;margin-bottom:50px}.roundtrips table{width:100%}.roundtrips table td,.roundtrips table th{border:1px solid #c6cbd1;padding:8px 12px}.roundtrips table td.loss{color:red;text-align:right}.roundtrips table td.profit{color:green;text-align:right}.roundtrips table tr:nth-child(2n){background-color:#f6f8fa}",""])},function(t,e){t.exports={name:"gekko",version:"0.5.12",description:"A bitcoin trading bot for auto trading at various exchanges",keywords:["trading","bot","bitcoin","TA","finance"],scripts:{test:"./node_modules/.bin/mocha test/*.js --recursive test -u tdd --reporter spec",start:"node ./gekko --config config.js --ui"},author:"Mike van Rossum ",dependencies:{"@slack/client":"^3.10.0",async:"2.1.2",binance:"^1.1.0","bitcoin-co-id":"0.0.1",bitexthai:"^0.1.0","bitfinex-api-node":"^1.2.0",bitstamp:"^1.0.3",bitx:"^1.5.0","btc-china-fork":"0.0.6","btc-markets":"0.0.10",cexio:"0.0.x","co-fs":"^1.2.0",coinfalcon:"^1.0.3",commander:"^2.9.0",gdax:"^0.4.2",gekko:"0.0.9","gemini-exchange-coffee-api":"2.0.6","humanize-duration":"^3.10.0",koa:"^1.2.0","koa-bodyparser":"^2.2.0","koa-cors":"0.0.16","koa-logger":"^1.3.0","koa-router":"^5.4.0","koa-static":"^2.0.0","kraken-api-es5":"^1.0.0",lakebtc_nodejs:"0.1.x",lodash:"2.x",moment:"2.19.3","node-wex":"^1.0.3","node.bittrex.api":"^0.4.3","okcoin-china":"0.0.7",opn:"^4.0.2","poloniex.js":"0.0.7","promisify-node":"^0.4.0","prompt-lite":"0.1.1",pushbullet:"1.4.3",quadrigacx:"0.0.7",relieve:"^2.1.3",retry:"^0.10.1",semver:"5.4.1",sqlite3:"^3.1.13","stats-lite":"^2.0.4","tiny-promisify":"^0.1.1",toml:"^2.3.0",twitter:"^1.7.1","zaif.jp":"^0.1.4"},devDependencies:{chai:"^2.0.0",mocha:"^2.1.1",proxyquire:"^1.7.10",sinon:"^1.12.2"},engines:{node:">=6.0"},license:"MIT",repository:{type:"git",url:"https://github.com/askmike/gekko.git"}}},function(t,e){t.exports={name:"vue",version:"0.2.0",description:"The frontend for the Gekko UI",author:"Mike van Rossum ",scripts:{dev:"cross-env NODE_ENV=development webpack-dev-server --open --inline --hot",build:"cross-env NODE_ENV=production webpack --progress --hide-modules"},devDependencies:{"babel-core":"^6.0.0","babel-loader":"^6.0.0","babel-preset-es2015":"^6.0.0","cross-env":"^3.0.0","css-loader":"^0.25.0","file-loader":"^0.9.0","json-loader":"^0.5.4",marked:"^0.3.6",superagent:"^2.3.0","superagent-no-cache":"uditalias/superagent-no-cache",vue:"^2.0.1","vue-loader":"^9.7.0","vue-router":"^2.0.3",vuex:"^2.2.1",webpack:"^2.1.0-beta.25","webpack-dev-server":"^2.1.0-beta.0"},dependencies:{jade:"^1.11.0"}}},function(t,e,n){(function(e){(function(){function e(t){this.tokens=[],this.tokens.links={},this.options=t||l.defaults,this.rules=f.normal,this.options.gfm&&(this.options.tables?this.rules=f.tables:this.rules=f.gfm)}function n(t,e){if(this.options=e||l.defaults,this.links=t,this.rules=d.normal,this.renderer=this.options.renderer||new r,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.gfm?this.options.breaks?this.rules=d.breaks:this.rules=d.gfm:this.options.pedantic&&(this.rules=d.pedantic)}function r(t){this.options=t||{}}function i(t){this.tokens=[],this.token=null,this.options=t||l.defaults,this.options.renderer=this.options.renderer||new r,this.renderer=this.options.renderer,this.renderer.options=this.options}function o(t,e){return t.replace(e?/&/g:/&(?!#?\w+;)/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function a(t){return t.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g,function(t,e){return e=e.toLowerCase(),"colon"===e?":":"#"===e.charAt(0)?"x"===e.charAt(1)?String.fromCharCode(parseInt(e.substring(2),16)):String.fromCharCode(+e.substring(1)):""})}function s(t,e){return t=t.source,e=e||"",function n(r,i){return r?(i=i.source||i,i=i.replace(/(^|[^\[])\^/g,"$1"),t=t.replace(r,i),n):new RegExp(t,e)}}function u(){}function c(t){for(var e,n,r=1;rAn error occured:

"+o(t.message+"",!0)+"
";throw t}}var f={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:u,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:u,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:u,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};f.bullet=/(?:[*+-]|\d+\.)/,f.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,f.item=s(f.item,"gm")(/bull/g,f.bullet)(),f.list=s(f.list)(/bull/g,f.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+f.def.source+")")(),f.blockquote=s(f.blockquote)("def",f.def)(),f._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",f.html=s(f.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,f._tag)(),f.paragraph=s(f.paragraph)("hr",f.hr)("heading",f.heading)("lheading",f.lheading)("blockquote",f.blockquote)("tag","<"+f._tag)("def",f.def)(),f.normal=c({},f),f.gfm=c({},f.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/}),f.gfm.paragraph=s(f.paragraph)("(?!","(?!"+f.gfm.fences.source.replace("\\1","\\2")+"|"+f.list.source.replace("\\1","\\3")+"|")(),f.tables=c({},f.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/}),e.rules=f,e.lex=function(t,n){return new e(n).lex(t)},e.prototype.lex=function(t){return t=t.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(t,!0)},e.prototype.token=function(t,e,n){for(var r,i,o,a,s,u,c,l,d,t=t.replace(/^ +$/gm,"");t;)if((o=this.rules.newline.exec(t))&&(t=t.substring(o[0].length),o[0].length>1&&this.tokens.push({type:"space"})),o=this.rules.code.exec(t))t=t.substring(o[0].length),o=o[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?o:o.replace(/\n+$/,"")});else if(o=this.rules.fences.exec(t))t=t.substring(o[0].length),this.tokens.push({type:"code",lang:o[2],text:o[3]||""});else if(o=this.rules.heading.exec(t))t=t.substring(o[0].length),this.tokens.push({type:"heading",depth:o[1].length,text:o[2]});else if(e&&(o=this.rules.nptable.exec(t))){for(t=t.substring(o[0].length),u={type:"table",header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/\n$/,"").split("\n")},l=0;l ?/gm,""),this.token(o,e,!0),this.tokens.push({type:"blockquote_end"});else if(o=this.rules.list.exec(t)){for(t=t.substring(o[0].length),a=o[2],this.tokens.push({type:"list_start",ordered:a.length>1}),o=o[0].match(this.rules.item),r=!1,d=o.length,l=0;l1&&s.length>1||(t=o.slice(l+1).join("\n")+t,l=d-1)),i=r||/\n\n(?!\s*$)/.test(u),l!==d-1&&(r="\n"===u.charAt(u.length-1),i||(i=r)),this.tokens.push({type:i?"loose_item_start":"list_item_start"}),this.token(u,!1,n),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(o=this.rules.html.exec(t))t=t.substring(o[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===o[1]||"script"===o[1]||"style"===o[1]),text:o[0]});else if(!n&&e&&(o=this.rules.def.exec(t)))t=t.substring(o[0].length),this.tokens.links[o[1].toLowerCase()]={href:o[2],title:o[3]};else if(e&&(o=this.rules.table.exec(t))){for(t=t.substring(o[0].length),u={type:"table",header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/(?: *\| *)?\n$/,"").split("\n")},l=0;l])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:u,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:u,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/,d.link=s(d.link)("inside",d._inside)("href",d._href)(),d.reflink=s(d.reflink)("inside",d._inside)(),d.normal=c({},d),d.pedantic=c({},d.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/}),d.gfm=c({},d.normal,{escape:s(d.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:s(d.text)("]|","~]|")("|","|https?://|")()}),d.breaks=c({},d.gfm,{br:s(d.br)("{2,}","*")(),text:s(d.gfm.text)("{2,}","*")()}),n.rules=d,n.output=function(t,e,r){return new n(e,r).output(t)},n.prototype.output=function(t){for(var e,n,r,i,a="";t;)if(i=this.rules.escape.exec(t))t=t.substring(i[0].length),a+=i[1];else if(i=this.rules.autolink.exec(t))t=t.substring(i[0].length),"@"===i[2]?(n=":"===i[1].charAt(6)?this.mangle(i[1].substring(7)):this.mangle(i[1]),r=this.mangle("mailto:")+n):(n=o(i[1]),r=n),a+=this.renderer.link(r,null,n);else if(this.inLink||!(i=this.rules.url.exec(t))){if(i=this.rules.tag.exec(t))!this.inLink&&/^/i.test(i[0])&&(this.inLink=!1),t=t.substring(i[0].length),a+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(i[0]):o(i[0]):i[0];else if(i=this.rules.link.exec(t))t=t.substring(i[0].length),this.inLink=!0,a+=this.outputLink(i,{href:i[2],title:i[3]}),this.inLink=!1;else if((i=this.rules.reflink.exec(t))||(i=this.rules.nolink.exec(t))){if(t=t.substring(i[0].length),e=(i[2]||i[1]).replace(/\s+/g," "),!(e=this.links[e.toLowerCase()])||!e.href){a+=i[0].charAt(0),t=i[0].substring(1)+t;continue}this.inLink=!0,a+=this.outputLink(i,e),this.inLink=!1}else if(i=this.rules.strong.exec(t))t=t.substring(i[0].length),a+=this.renderer.strong(this.output(i[2]||i[1]));else if(i=this.rules.em.exec(t))t=t.substring(i[0].length),a+=this.renderer.em(this.output(i[2]||i[1]));else if(i=this.rules.code.exec(t))t=t.substring(i[0].length),a+=this.renderer.codespan(o(i[2],!0));else if(i=this.rules.br.exec(t))t=t.substring(i[0].length),a+=this.renderer.br();else if(i=this.rules.del.exec(t))t=t.substring(i[0].length),a+=this.renderer.del(this.output(i[1]));else if(i=this.rules.text.exec(t))t=t.substring(i[0].length),a+=this.renderer.text(o(this.smartypants(i[0])));else if(t)throw new Error("Infinite loop on byte: "+t.charCodeAt(0))}else t=t.substring(i[0].length),n=o(i[1]),r=n,a+=this.renderer.link(r,null,n);return a},n.prototype.outputLink=function(t,e){var n=o(e.href),r=e.title?o(e.title):null;return"!"!==t[0].charAt(0)?this.renderer.link(n,r,this.output(t[1])):this.renderer.image(n,r,o(t[1]))},n.prototype.smartypants=function(t){return this.options.smartypants?t.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014\/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014\/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):t},n.prototype.mangle=function(t){if(!this.options.mangle)return t;for(var e,n="",r=t.length,i=0;i.5&&(e="x"+e.toString(16)),n+="&#"+e+";";return n},r.prototype.code=function(t,e,n){if(this.options.highlight){var r=this.options.highlight(t,e);null!=r&&r!==t&&(n=!0,t=r)}return e?'
'+(n?t:o(t,!0))+"\n
\n":"
"+(n?t:o(t,!0))+"\n
"},r.prototype.blockquote=function(t){return"
\n"+t+"
\n"},r.prototype.html=function(t){return t},r.prototype.heading=function(t,e,n){return"'+t+"\n"},r.prototype.hr=function(){return this.options.xhtml?"
\n":"
\n"},r.prototype.list=function(t,e){var n=e?"ol":"ul";return"<"+n+">\n"+t+"\n"},r.prototype.listitem=function(t){return"
  • "+t+"
  • \n"},r.prototype.paragraph=function(t){return"

    "+t+"

    \n"},r.prototype.table=function(t,e){return"\n\n"+t+"\n\n"+e+"\n
    \n"},r.prototype.tablerow=function(t){return"\n"+t+"\n"},r.prototype.tablecell=function(t,e){var n=e.header?"th":"td";return(e.align?"<"+n+' style="text-align:'+e.align+'">':"<"+n+">")+t+"\n"},r.prototype.strong=function(t){return""+t+""},r.prototype.em=function(t){return""+t+""},r.prototype.codespan=function(t){return""+t+""},r.prototype.br=function(){return this.options.xhtml?"
    ":"
    "},r.prototype.del=function(t){return""+t+""},r.prototype.link=function(t,e,n){if(this.options.sanitize){try{var r=decodeURIComponent(a(t)).replace(/[^\w:]/g,"").toLowerCase()}catch(t){return""}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:"))return""}var i='
    "},r.prototype.image=function(t,e,n){var r=''+n+'":">"},r.prototype.text=function(t){return t},i.parse=function(t,e,n){return new i(e,n).parse(t)},i.prototype.parse=function(t){this.inline=new n(t.links,this.options,this.renderer),this.tokens=t.reverse();for(var e="";this.next();)e+=this.tok();return e},i.prototype.next=function(){return this.token=this.tokens.pop()},i.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},i.prototype.parseText=function(){for(var t=this.token.text;"text"===this.peek().type;)t+="\n"+this.next().text;return this.inline.output(t)},i.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var t,e,n,r,i="",o="";for(n="",t=0;t=300)&&(r=new Error(e.statusText||"Unsuccessful HTTP response"),r.original=t,r.response=e,r.status=e.status)}catch(t){r=t}r?n.callback(r,e):n.callback(null,e)})}function p(t,e){var n=_("DELETE",t);return e&&n.end(e),n}var h;"undefined"!=typeof window?h=window:"undefined"!=typeof self?h=self:(console.warn("Using browser-only version of superagent in non-browser environment"),h=this);var v=n(82),m=n(117),g=n(15),_=t.exports=n(118).bind(null,d);_.getXHR=function(){if(!(!h.XMLHttpRequest||h.location&&"file:"==h.location.protocol&&h.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(t){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(t){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(t){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(t){}throw Error("Browser-only verison of superagent could not find XHR")};var y="".trim?function(t){return t.trim()}:function(t){return t.replace(/(^\s*|\s*$)/g,"")};_.serializeObject=i,_.parseString=a,_.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},_.serialize={"application/x-www-form-urlencoded":i,"application/json":JSON.stringify},_.parse={"application/x-www-form-urlencoded":a,"application/json":JSON.parse},f.prototype.get=function(t){return this.header[t.toLowerCase()]},f.prototype._setHeaderProperties=function(t){var e=this.header["content-type"]||"";this.type=c(e);var n=l(e);for(var r in n)this[r]=n[r]},f.prototype._parseBody=function(t){var e=_.parse[this.type];return!e&&u(this.type)&&(e=_.parse["application/json"]),e&&t&&(t.length||t instanceof Object)?e(t):null},f.prototype._setStatusProperties=function(t){1223===t&&(t=204);var e=t/100|0;this.status=this.statusCode=t,this.statusType=e,this.info=1==e,this.ok=2==e,this.clientError=4==e,this.serverError=5==e,this.error=(4==e||5==e)&&this.toError(),this.accepted=202==t,this.noContent=204==t,this.badRequest=400==t,this.unauthorized=401==t,this.notAcceptable=406==t,this.notFound=404==t,this.forbidden=403==t},f.prototype.toError=function(){var t=this.req,e=t.method,n=t.url,r="cannot "+e+" "+n+" ("+this.status+")",i=new Error(r);return i.status=this.status,i.method=e,i.url=n,i},_.Response=f,v(d.prototype);for(var b in m)d.prototype[b]=m[b];d.prototype.type=function(t){return this.set("Content-Type",_.types[t]||t),this},d.prototype.responseType=function(t){return this._responseType=t,this},d.prototype.accept=function(t){return this.set("Accept",_.types[t]||t),this},d.prototype.auth=function(t,e,n){switch(n||(n={type:"basic"}),n.type){case"basic":var r=btoa(t+":"+e);this.set("Authorization","Basic "+r);break;case"auto":this.username=t,this.password=e}return this},d.prototype.query=function(t){return"string"!=typeof t&&(t=i(t)),t&&this._query.push(t),this},d.prototype.attach=function(t,e,n){return this._getFormData().append(t,e,n||e.name),this},d.prototype._getFormData=function(){return this._formData||(this._formData=new h.FormData),this._formData},d.prototype.callback=function(t,e){var n=this._callback;this.clearTimeout(),n(t,e)},d.prototype.crossDomainError=function(){var t=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");t.crossDomain=!0,t.status=this.status,t.method=this.method,t.url=this.url,this.callback(t)},d.prototype._timeoutError=function(){var t=this._timeout,e=new Error("timeout of "+t+"ms exceeded");e.timeout=t,this.callback(e)},d.prototype._appendQueryString=function(){var t=this._query.join("&");t&&(this.url+=~this.url.indexOf("?")?"&"+t:"?"+t)},d.prototype.end=function(t){var e=this,n=this.xhr=_.getXHR(),i=this._timeout,o=this._formData||this._data;this._callback=t||r,n.onreadystatechange=function(){if(4==n.readyState){var t;try{t=n.status}catch(e){t=0}if(0==t){if(e.timedout)return e._timeoutError();if(e._aborted)return;return e.crossDomainError()}e.emit("end")}};var a=function(t,n){n.total>0&&(n.percent=n.loaded/n.total*100),n.direction=t,e.emit("progress",n)};if(this.hasListeners("progress"))try{n.onprogress=a.bind(null,"download"),n.upload&&(n.upload.onprogress=a.bind(null,"upload"))}catch(t){}if(i&&!this._timer&&(this._timer=setTimeout(function(){e.timedout=!0,e.abort()},i)),this._appendQueryString(),this.username&&this.password?n.open(this.method,this.url,!0,this.username,this.password):n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof o&&!this._isHost(o)){var s=this._header["content-type"],c=this._serializer||_.serialize[s?s.split(";")[0]:""];!c&&u(s)&&(c=_.serialize["application/json"]),c&&(o=c(o))}for(var l in this.header)null!=this.header[l]&&n.setRequestHeader(l,this.header[l]);return this._responseType&&(n.responseType=this._responseType),this.emit("request",this),n.send(void 0!==o?o:null),this},_.Request=d,_.get=function(t,e,n){var r=_("GET",t);return"function"==typeof e&&(n=e,e=null),e&&r.query(e),n&&r.end(n),r},_.head=function(t,e,n){var r=_("HEAD",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.options=function(t,e,n){var r=_("OPTIONS",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.del=p,_.delete=p,_.patch=function(t,e,n){var r=_("PATCH",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.post=function(t,e,n){var r=_("POST",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.put=function(t,e,n){var r=_("PUT",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r}},function(t,e,n){var r=n(15);e.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},e.parse=function(t){return this._parser=t,this},e.serialize=function(t){return this._serializer=t,this},e.timeout=function(t){return this._timeout=t,this},e.then=function(t,e){if(!this._fullfilledPromise){var n=this;this._fullfilledPromise=new Promise(function(t,e){n.end(function(n,r){n?e(n):t(r)})})}return this._fullfilledPromise.then(t,e)},e.catch=function(t){return this.then(void 0,t)},e.use=function(t){return t(this),this},e.get=function(t){return this._header[t.toLowerCase()]},e.getHeader=e.get,e.set=function(t,e){if(r(t)){for(var n in t)this.set(n,t[n]);return this}return this._header[t.toLowerCase()]=e,this.header[t]=e,this},e.unset=function(t){return delete this._header[t.toLowerCase()],delete this.header[t],this},e.field=function(t,e){if(null===t||void 0===t)throw new Error(".field(name, val) name can not be empty");if(r(t)){for(var n in t)this.field(n,t[n]);return this}if(null===e||void 0===e)throw new Error(".field(name, val) val can not be empty");return this._getFormData().append(t,e),this},e.abort=function(){return this._aborted?this:(this._aborted=!0,this.xhr&&this.xhr.abort(),this.req&&this.req.abort(),this.clearTimeout(),this.emit("abort"),this)},e.withCredentials=function(){return this._withCredentials=!0,this},e.redirects=function(t){return this._maxRedirects=t,this},e.toJSON=function(){return{method:this.method,url:this.url,data:this._data,headers:this._header}},e._isHost=function(t){switch({}.toString.call(t)){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}},e.send=function(t){var e=r(t),n=this._header["content-type"];if(e&&r(this._data))for(var i in t)this._data[i]=t[i];else"string"==typeof t?(n||this.type("form"),n=this._header["content-type"],this._data="application/x-www-form-urlencoded"==n?this._data?this._data+"&"+t:t:(this._data||"")+t):this._data=t;return!e||this._isHost(t)?this:(n||this.type("json"),this)}},function(t,e){function n(t,e,n){return"function"==typeof n?new t("GET",e).end(n):2==arguments.length?new t("GET",e):new t(e,n)}t.exports=n},function(t,e,n){var r,i;n(191),r=n(36);var o=n(163);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(170),r=n(39);var o=n(140);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(169),r=n(41);var o=n(139);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(189),r=n(42);var o=n(161);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(175),r=n(45);var o=n(145);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(190),r=n(48);var o=n(162);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(182),r=n(54);var o=n(154);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;r=n(55);var o=n(151);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(179),r=n(61);var o=n(150);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(167),r=n(63);var o=n(134);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;r=n(64);var o=n(138);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(176),r=n(65);var o=n(146);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(184),r=n(67);var o=n(156);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{class:{clickable:!t.isClicked},attrs:{id:"chartWrapper"}},[n("div",{staticClass:"shield",on:{click:function(e){e.preventDefault(),t.click(e)}}}),n("svg",{attrs:{id:"chart",width:"960",height:t.height}})])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Daterange")]),n("div",[n("label",{attrs:{for:"from"}},[t._v("From")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.from,expression:"from"}],domProps:{value:t.from},on:{input:function(e){e.target.composing||(t.from=e.target.value)}}})]),n("div",[n("label",{attrs:{for:"to"}},[t._v("To")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.to,expression:"to"}],domProps:{value:t.to},on:{input:function(e){e.target.composing||(t.to=e.target.value)}}})])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.progress?n("div",{staticClass:"progressbarWrapper"},[n("p",[n("strong",[t._v(t._s(t.round(t.progress))+"%")])]),n("div",{staticClass:"progressbar"},[n("div",{style:{width:t.progress+"%"}})])]):t._e()},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{staticClass:"mx1"},[n("label",{staticClass:"wrapper",attrs:{for:"exchange"}},[t._v("Exchange:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.exchange,expression:"exchange"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.exchange=e.target.multiple?n:n[0]}}},t._l(t.exchanges,function(e,r){return n("option",[t._v(t._s(r))])}))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("label",{attrs:{for:"currency"}},[t._v("Currency:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.currency,expression:"currency"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.currency=e.target.multiple?n:n[0]}}},t._l(t.currencies,function(e){return n("option",[t._v(t._s(e))])}))])]),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("label",{attrs:{for:"asset"}},[t._v("Asset:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.asset,expression:"asset"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.asset=e.target.multiple?n:n[0]}}},t._l(t.assets,function(e){return n("option",[t._v(t._s(e))])}))])])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-3-6"},[n("table",{staticClass:"p1"},[n("tr",[n("th",[t._v("amount of trades")]),n("td",[t._v(t._s(t.report.trades))])]),n("tr",[n("th",[t._v("sharpe ratio")]),n("td",[t._v(t._s(t.round2(t.report.sharpe)))])]),n("tr",[n("th",[t._v("start balance")]),n("td",[t._v(t._s(t.round(t.report.startBalance))+" "+t._s(t.report.currency))])]),n("tr",[n("th",[t._v("final balance")]),n("td",[t._v(t._s(t.round(t.report.balance))+" "+t._s(t.report.currency))])]),t._m(0)]),n("div",{staticClass:"big txt--right price",class:t.profitClass},[t._v(t._s(t.round(t.report.relativeProfit))+"%")])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("tr",[n("th",[t._v("simulated profit")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("h2",[t._v("Config")]),n("div",{staticClass:"hr"}),n("h3",[t._v("Available API keys")]),t.apiKeySets.length?t._e():n("p",[n("em",[t._v("You don't have any API keys yet.")])]),n("ul",t._l(t.apiKeySets,function(e){return n("li",[t._v(t._s(e)+" ("),n("a",{attrs:{href:"#"},on:{click:function(n){n.preventDefault(),t.removeApiKey(e)}}},[t._v("remove")]),t._v(")")])})),t.addApiToggle?t._e():n("a",{staticClass:"btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.openAddApi(e)}}},[t._v("Add an API key")]),t.addApiToggle?[n("div",{staticClass:"hr"}),n("apiConfigBuilder")]:t._e(),n("div",{staticClass:"hr"})],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("footer",{staticClass:"p2 bg--off-white"},[n("div",{staticClass:"contain"},[t._m(0),n("p",[t._v("Using Gekko v"+t._s(t.version.gekko)+" and Gekko UI v"+t._s(t.version.ui)+".")])])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("p",[n("em",[t._v("Use Gekko at your own risk.")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("div",{staticClass:"grd-row summary"},[n("div",{staticClass:"grd-row-col-3-6"},[n("table",{staticClass:"p1"},[n("tr",[n("th",[t._v("start time")]),n("td",[t._v(t._s(t.report.startTime))])]),n("tr",[n("th",[t._v("end time")]),n("td",[t._v(t._s(t.report.endTime))])]),n("tr",[n("th",[t._v("timespan")]),n("td",[t._v(t._s(t.report.timespan))])]),n("tr",[n("th",[t._v("start price")]),n("td",[t._v(t._s(t.round(t.report.startPrice))+" "+t._s(t.report.currency))])]),n("tr",[n("th",[t._v("end price")]),n("td",[t._v(t._s(t.round(t.report.endPrice))+" "+t._s(t.report.currency))])]),n("tr",[n("th",[t._v("market")]),n("td",[t._v(t._s(t.round(t.report.market))+"%")])])])]),n("paperTradeSummary",{attrs:{report:t.report}})],1)])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{staticClass:"hr contain"}),t._m(0),n("result-summary",{attrs:{report:t.result.report}}),n("div",{staticClass:"hr contain"}),n("chart",{attrs:{data:t.result,height:"500"}}),n("div",{staticClass:"hr contain"}),n("roundtripTable",{attrs:{roundtrips:t.result.roundtrips}})],1)},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("h3",[t._v("Backtest result")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain my2"},[n("h3",[t._v("Start a new gekko")]),n("gekko-config-builder",{on:{config:t.updateConfig}}),n("div",{staticClass:"hr"}),t.config.valid?n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.start(e)}}},[t._v("Start")])]):t._e()],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain my2"},[n("div",{staticClass:"text",domProps:{innerHTML:t._s(t.intro)}}),n("div",{staticClass:"hr"}),n("h3",[t._v("Currently running imports")]),0===t.imports.length?n("p",[t._v("You currently don't have any imports running.")]):t._e(),t.imports.length?n("ul",t._l(t.imports,function(e){return n("li",[n("router-link",{attrs:{to:"/data/importer/import/"+e.id}},[t._v(t._s(e.watch.exchange)+":"+t._s(e.watch.currency)+"/"+t._s(e.watch.asset))])],1)})):t._e(),n("div",{staticClass:"hr"}),n("h3",[t._v("Start a new import")]),n("import-config-builder",{on:{config:t.updateConfig}}),n("div",{staticClass:"hr"}),n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.run(e)}}},[t._v("Import")])])],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Daterange")]),"scan"===t.tab?[t.scanned?t._e():n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s btn--primary scan-btn",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("Scan available data")])]),"fetching"==t.scanned?n("div",{staticClass:"txt--center"},[n("p",{staticClass:"scan-btn"},[t._v("Scanning..")])]):t._e(),1==t.scanned?[0===t.ranges.length?[n("p",[n("strong",[t._v('Unable to find any local data, do you have local data available for\n"'+t._s(t.config.watch.exchange)+":"+t._s(t.config.watch.currency)+"/"+t._s(t.config.watch.asset)+'"?')])])]:[n("label",{staticClass:"wrapper",attrs:{for:"exchange"}},[t._v("Run simulation over:")]),n("form",{staticClass:"radio grd"},t._l(t.ranges,function(e,r){return n("div",{staticClass:"grd-row m1"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.selectedRangeIndex,expression:"selectedRangeIndex"}],staticClass:"grd-row-col-1-6",attrs:{type:"radio"},domProps:{value:r,checked:t._q(t.selectedRangeIndex,r)},on:{__c:function(e){t.selectedRangeIndex=r}}}),n("label",{staticClass:"grd-row-col-5-6",attrs:{for:r}},[t._v(t._s(t.printRange(e)))])])}))],n("p",[n("em",[n("a",{attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("rescan")])])])]:t._e(),n("p",{staticClass:"txt--center"},[n("em",[n("a",{attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.tab="manual"}}},[t._v("Or manually set a daterange")])])])]:t._e(),"manual"===t.tab?[n("div",[n("label",{attrs:{for:"from"}},[t._v("From:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.from,expression:"from"}],domProps:{value:t.from},on:{input:function(e){e.target.composing||(t.from=e.target.value)}}})]),n("div",[n("label",{attrs:{for:"to"}},[t._v("To:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.to,expression:"to"}],domProps:{value:t.to},on:{input:function(e){e.target.composing||(t.to=e.target.value)}}})]),n("p",{staticClass:"txt--center"}),n("em",[n("a",{attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.tab="scan"}}},[t._v("Or scan for a daterange")])])]:t._e()],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("div",{staticClass:"text",domProps:{innerHTML:t._s(t.intro)}}),n("div",{staticClass:"hr"}),n("h2",[t._v("Available datasets")]),"idle"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("a",{staticClass:"w100--s btn--primary scan-btn",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("Scan available data")])]):t._e(),"scanning"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("spinner")],1):t._e(),"scanned"===t.datasetScanstate?n("div",{staticClass:"my2"},[t.unscannableMakets.length?n("div",{staticClass:"bg--orange p1 warning my1"},[t.viewUnscannable?t._e():n("p",{staticClass:"clickable",on:{click:function(e){e.preventDefault(),t.toggleUnscannable(e)}}},[t._v("Some markets were unscannable, click here for details.")]),t.viewUnscannable?[n("p",[t._v("Unable to find datasets in the following markets:")]),t._l(t.unscannableMakets,function(e){return n("div",{staticClass:"mx2"},[t._v("- "+t._s(e.exchange)+":"+t._s(e.currency)+":"+t._s(e.asset))])})]:t._e()],2):t._e(),t.datasets.length?[n("table",{staticClass:"full data"},[t._m(0),n("tbody",t._l(t.datasets,function(e){return n("tr",[n("td",[t._v(t._s(e.exchange))]),n("td",[t._v(t._s(e.currency))]),n("td",[t._v(t._s(e.asset))]),n("td",[t._v(t._s(t.fmt(e.from)))]),n("td",[t._v(t._s(t.fmt(e.to)))]),n("td",[t._v(t._s(t.humanizeDuration(e.to.diff(e.from))))])])}))])]:t._e(),t.datasets.length?t._e():[n("p",[t._v("It looks like you don't have any local data yet.")])]],2):t._e(),n("div",{staticClass:"my2"},[n("h2",[t._v("Import more data")]),n("p",{staticClass:"text"},[t._v("You can easily import more market data directly from exchanges using the importer.")]),n("router-link",{staticClass:"btn--primary",attrs:{to:"/data/importer"}},[t._v("Go to the importer!")])],1)])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("from")]),n("th",[t._v("to")]),n("th",[t._v("duration")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd contain"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Market")]),n("market-picker",{staticClass:"contain",attrs:{"only-importable":"true"},on:{market:t.updateMarketConfig}})],1),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("range-creator",{on:{range:t.updateRange}})],1)])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{attrs:{id:"top"}}),t._m(0),n("nav",{staticClass:"bg--light-gray"},[n("div",{staticClass:"menu contain"},[n("router-link",{staticClass:"py1",attrs:{to:"/home"}},[t._v("Home")]),n("router-link",{staticClass:"py1",attrs:{to:"/live-gekkos"}},[t._v("Live Gekkos")]),n("router-link",{staticClass:"py1",attrs:{to:"/backtest"}},[t._v("Backtest")]),n("router-link",{staticClass:"py1",attrs:{to:"/data"}},[t._v("Local data")]),n("router-link",{staticClass:"py1",attrs:{to:"/config"}},[t._v("Config")]),n("a",{staticClass:"py1",attrs:{href:"https://gekko.wizb.it/docs/introduction/about_gekko.html",target:"_blank"}},[t._v("Documentation")])],1)])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("header",{staticClass:"bg--off-white grd"},[n("div",{staticClass:"contain grd-row"},[n("h3",{staticClass:"py1 px2 col-2"},[t._v("Gekko UI")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{staticClass:"contain grd-row"},[n("div",{staticClass:"grd-row-col-3-6",domProps:{innerHTML:t._s(t.left)}}),t._m(0)])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-3-6 txt--center"},[n("img",{attrs:{src:"/assets/gekko.jpg"}}),n("p",[n("em",[t._v("The most valuable commodity I know of is information.")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h2",{staticClass:"contain"},[t._v("Backtest")]),n("div",{staticClass:"hr contain"}),n("config-builder",{on:{config:t.check}}),t.backtestable?n("div",[n("div",{staticClass:"txt--center"},["fetching"!==t.backtestState?n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.run(e)}}},[t._v("Backtest")]):t._e(),"fetching"===t.backtestState?n("div",{staticClass:"scan-btn"},[n("p",[t._v("Running backtest..")]),n("spinner")],1):t._e()])]):t._e(),t.backtestResult&&"fetched"===t.backtestState?n("result",{attrs:{result:t.backtestResult}}):t._e()],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement;t._self._c;return t._m(0)},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"spinner"},[n("div",{staticClass:"rect1"}),n("div",{staticClass:"rect2"}),n("div",{staticClass:"rect3"}),n("div",{staticClass:"rect4"})])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Type")]),[n("label",{staticClass:"wrapper",attrs:{for:"type"}},[t._v("What do you want to do with gekko?")]),n("form",{staticClass:"radio grd"},t._l(t.types,function(e,r){return n("div",{staticClass:"grd-row m1"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.selectedTypeIndex,expression:"selectedTypeIndex"}],staticClass:"grd-row-col-1-6",attrs:{type:"radio"},domProps:{value:r,checked:t._q(t.selectedTypeIndex,r)},on:{__c:function(e){t.selectedTypeIndex=r}}}),n("label",{staticClass:"grd-row-col-5-6",attrs:{for:r}},[t._v(t._s(e))])])}))]],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{staticClass:"mx1"},[n("label",{staticClass:"wrapper",attrs:{for:"exchange"}},[t._v("Exchange:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.exchange,expression:"exchange"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.exchange=e.target.multiple?n:n[0]}}},t._l(t.exchanges,function(e,r){return n("option",[t._v(t._s(r))])}))])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"app"}},[n("top"),n("div",{staticClass:"fill"},[n("router-view",{staticClass:"view"})],1),n("bottom"),n("modal")],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain py2"},[n("div",{staticClass:"text",domProps:{innerHTML:t._s(t.text)}}),n("div",{staticClass:"hr"}),n("h3",[t._v("Market watchers")]),t.watchers.length?t._e():n("div",{staticClass:"text"},[n("p",[t._v("You are currently not watching any markets.")])]),t.watchers.length?n("table",{staticClass:"full clickable"},[t._m(0),n("tbody",t._l(t.watchers,function(e){return n("tr",{staticClass:"clickable",on:{click:function(n){t.$router.push({path:"live-gekkos/watcher/"+e.id})}}},[n("td",[t._v(t._s(e.watch.exchange))]),n("td",[t._v(t._s(e.watch.currency))]),n("td",[t._v(t._s(e.watch.asset))]),n("td",[e.firstCandle?[t._v(t._s(t.fmt(e.firstCandle.start)))]:t._e()],2),n("td",[e.lastCandle?[t._v(t._s(t.fmt(e.lastCandle.start)))]:t._e()],2),n("td",[e.firstCandle&&e.lastCandle?[t._v(t._s(t.timespan(e.lastCandle.start,e.firstCandle.start)))]:t._e()],2)])}))]):t._e(),n("h3",[t._v("Strat runners")]),t.stratrunners.length?t._e():n("div",{staticClass:"text"},[n("p",[t._v("You are currently not running any strategies.")])]),t.stratrunners.length?n("table",{staticClass:"full"},[t._m(1),n("tbody",t._l(t.stratrunners,function(e){return n("tr",{staticClass:"clickable",on:{click:function(n){t.$router.push({path:"live-gekkos/stratrunner/"+e.id})}}},[n("td",[t._v(t._s(e.watch.exchange))]),n("td",[t._v(t._s(e.watch.currency))]),n("td",[t._v(t._s(e.watch.asset))]),n("td",[e.lastCandle?[t._v(t._s(t.fmt(e.lastCandle.start)))]:t._e()],2),n("td",[e.firstCandle&&e.lastCandle?[t._v(t._s(t.timespan(e.lastCandle.start,e.firstCandle.start)))]:t._e()],2),n("td",[t._v(t._s(e.strat.name))]),n("td",[e.report?t._e():[t._v("0")],e.report?[t._v(t._s(t.round(e.report.profit))+" "+t._s(e.watch.currency))]:t._e()],2)])}))]):t._e(),n("div",{staticClass:"hr"}),n("h2",[t._v("Start a new live Gekko")]),n("router-link",{staticClass:"btn--primary",attrs:{to:"/live-gekkos/new"}},[t._v("Start a new live Gekko!")])],1)},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("started at")]),n("th",[t._v("last update")]),n("th",[t._v("duration")])])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("last update")]),n("th",[t._v("duration")]),n("th",[t._v("strategy")]),n("th",[t._v("profit")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Select a dataset")]),"idle"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("a",{staticClass:"w100--s btn--primary scan-btn",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("Scan available data")])]):t._e(),"scanning"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("spinner")],1):t._e(),"scanned"===t.datasetScanstate?n("div",{staticClass:"my2"},[0!=t.datasets.length?n("div",[n("table",{staticClass:"full"},[t._m(0),n("tbody",t._l(t.datasets,function(e,r){return n("tr",[n("td",{staticClass:"radio"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.setIndex,expression:"setIndex"}],attrs:{type:"radio",name:"dataset",id:e.id},domProps:{value:r,checked:t._q(t.setIndex,r)},on:{__c:function(e){t.setIndex=r}}})]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(e.exchange))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(e.currency))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(e.asset))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(t.fmt(e.from)))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(t.fmt(e.to)))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(t.humanizeDuration(e.to.diff(e.from))))])])])}))]),t.rangeVisible?t._e():n("a",{staticClass:"btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.openRange(e)}}},[t._v("Adjust range")]),t.rangeVisible?[n("div",[n("label",{attrs:{for:"customFrom"}},[t._v("From:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.customFrom,expression:"customFrom"}],domProps:{value:t.customFrom},on:{input:function(e){e.target.composing||(t.customFrom=e.target.value)}}})]),n("div",[n("label",{attrs:{for:"customTo"}},[t._v("To:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.customTo,expression:"customTo"}],domProps:{value:t.customTo},on:{input:function(e){e.target.composing||(t.customTo=e.target.value)}}})])]:t._e()],2):n("em",[t._v("No Data found "),n("a",{attrs:{href:"#/data/importer"}},[t._v("Lets add some")])])]):t._e()])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th"),n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("from")]),n("th",[t._v("to")]),n("th",[t._v("duration")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"my2"},[t.data?t._e():n("div",{staticClass:"contain"},[n("h1",[t._v("Unknown Strat runner")]),n("p",[t._v("Gekko doesn't know what strat runner this is...")])]),t.data?n("div",[n("h2",{staticClass:"contain"},[t._v("Strat runner")]),n("div",{staticClass:"grd contain"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Market")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Exchange")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.data.watch.exchange))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Currency")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Asset")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.data.watch.asset))])])]),n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Runtime")]),t.isLoading?n("spinner"):t._e(),t.isLoading?t._e():[t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Watching since")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.firstCandle.start)))])]):t._e(),t.data.lastCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Received data until")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.lastCandle.start)))])]):t._e(),t.data.lastCandle&&t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Data spanning")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.humanizeDuration(t.moment(t.data.lastCandle.start).diff(t.moment(t.data.firstCandle.start)))))])]):t._e(),t.data.lastCandle&&t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Amount of trades")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.trades.length))])]):t._e()]],2)]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Strategy")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Name")]),n("div",{staticClass:"grd-row-col-3-6"},[n("strong",[t._v(t._s(t.stratName))])])]),t._v("Parameters"),n("pre",[t._v(t._s(t.stratParams))])]),n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Profit report")]),t.report?t._e():[t._m(0)],t.report?[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Start balance")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.startBalance)))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Current balance")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.balance)))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Market")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.market))+" "+t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Profit")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.profit))+" "+t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Alpha")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.alpha))+" "+t._s(t.data.watch.currency))])])]:t._e()],2)]),t.watcher?n("p",[n("em",[t._v("This strat runner gets data from "),n("router-link",{attrs:{to:"/live-gekkos/watcher/"+t.watcher.id}},[t._v("this market watcher")])],1),t._v(".")]):t._e()]),t.isLoading?t._e():[n("h3",{staticClass:"contain"},[t._v("Market graph")]),"fetching"===t.candleFetch?n("spinner"):t._e(),"fetched"===t.candleFetch?[n("chart",{attrs:{data:t.chartData,height:300}})]:t._e(),n("roundtrips",{attrs:{roundtrips:t.data.roundtrips}})]],2):t._e()])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("p",[n("em",[t._v("Waiting for at least one trade..")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.active?n("div",[n("div",{attrs:{id:"modal-background"}}),n("div",{staticClass:"modal",attrs:{id:"modal"}},[n("div",{staticClass:"modal-guts",domProps:{innerHTML:t._s(t.content)}})])]):t._e()},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd"},[n("div",{staticClass:"px1"},[n("h3",[t._v("Paper trader")]),"closed"===t.toggle?n("a",{staticClass:"btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.switchToggle(e)}}},[t._v("Change paper trader settings")]):t._e(),"open"===t.toggle?[n("p",[t._v("Settings:")]),n("textarea",{directives:[{name:"model",rawName:"v-model",value:t.rawPaperTraderParams,expression:"rawPaperTraderParams"}],staticClass:"params",domProps:{value:t.rawPaperTraderParams},on:{input:function(e){e.target.composing||(t.rawPaperTraderParams=e.target.value)}}}),t.rawPaperTraderParamsError?n("p",{staticClass:"bg--red p1"},[t._v(t._s(t.rawPaperTraderParamsError.message))]):t._e()]:t._e()],2)])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain my2"},[t.data&&!t.data.done?n("div",[n("h2",[t._v("Importing data..")]),n("div",{staticClass:"grd"},[n("div",{staticClass:"grd-row"},[t._m(0),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.exchange))])]),n("div",{staticClass:"grd-row"},[t._m(1),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.currency)+"/"+t._s(t.data.watch.asset))])])]),n("div",{staticClass:"grd"},[n("div",{staticClass:"grd-row"},[t._m(2),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.from)))])]),n("div",{staticClass:"grd-row"},[t._m(3),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.to)))])]),t.initialized?n("div",{staticClass:"grd-row"},[t._m(4),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.latest)))])]):t._e(),t.initialized?n("div",{staticClass:"grd-row"},[t._m(5),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fromEnd))])]):t._e()]),t.initialized?t._e():n("spinner"),t.initialized?n("div",{staticClass:"contain"},[n("progressBar",{attrs:{progress:t.progress}})],1):t._e(),n("p",[n("em",[t._v("(you don't have to wait until the import is done,\nyou can already start "),n("router-link",{attrs:{to:"/backtest"}},[t._v("backtesting")]),t._v(").")],1)])],1):t._e(),t.data&&t.data.done?n("div",{staticClass:"txt--center"},[n("h2",[t._v("Import done")]),n("p",[t._v(" \nGo and "),n("router-link",{attrs:{to:"/backtest"}},[t._v("backtest")]),t._v(" with your new data!")],1)]):t._e(),t.data?t._e():n("div",{staticClass:"txt--center"},[n("h2",[t._v("ERROR: Uknown import")]),n("p",[n("I",[t._v("don't know this import..")])],1)])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Market:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Currency/Asset:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("From:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("To:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Imported data until:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Remaining:")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 px1"},[n("h3",[t._v("Strategy")]),n("div",[n("label",{staticClass:"wrapper",attrs:{for:"strat"}},[t._v("Strategy:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.strategy,expression:"strategy"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.strategy=e.target.multiple?n:n[0]}}},t._l(t.strategies,function(e){return n("option",[t._v(t._s(e.name))])}))])]),n("div",[n("label",{attrs:{for:"candleSize"}},[t._v("Candle Size")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.rawCandleSize,expression:"rawCandleSize"}],domProps:{value:t.rawCandleSize},on:{input:function(e){e.target.composing||(t.rawCandleSize=e.target.value)}}})]),n("div",{staticClass:"grd-row-col-3-6 align"},[n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.candleSizeUnit,expression:"candleSizeUnit"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.candleSizeUnit=e.target.multiple?n:n[0]}}},[n("option",[t._v("minutes")]),n("option",[t._v("hours")]),n("option",[t._v("days")])])])])])]),n("div",[n("label",{attrs:{for:"historySize"}},[t._v("Warmup period (in "+t._s(t.rawCandleSize)+" "+t._s(t.singularCandleSizeUnit)+" candles):")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.historySize,expression:"historySize"}],domProps:{value:t.historySize},on:{input:function(e){e.target.composing||(t.historySize=e.target.value)}}}),n("em",{staticClass:"label-like"},[t._v("(will use "+t._s(t.humanizeDuration(t.candleSize*t.historySize*1e3*60))+" of data as history)")])])]),n("div",{staticClass:"grd-row-col-2-6 px1"},[n("div",[n("h3",[t._v("Parameters")]),n("p",[t._v(t._s(t.strategy)+" Parameters:")]),n("textarea",{directives:[{name:"model",rawName:"v-model",value:t.rawStratParams,expression:"rawStratParams"}],staticClass:"params",domProps:{value:t.rawStratParams},on:{input:function(e){e.target.composing||(t.rawStratParams=e.target.value)}}}),t.rawStratParamsError?n("p",{staticClass:"bg--red p1"},[t._v(t._s(t.rawStratParamsError.message))]):t._e()])])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"my2"},[t.data?t._e():n("div",{staticClass:"contain"},[n("h1",[t._v("Unknown Watcher")]),n("p",[t._v("Gekko doesn't know what whatcher this is...")])]),t.data?n("div",[n("h2",{staticClass:"contain"},[t._v("Market Watcher")]),n("div",{staticClass:"grd contain"},[n("h3",[t._v("Market")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Exchange")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.exchange))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Currency")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Asset")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.asset))])]),n("h3",[t._v("Statistics")]),t.isLoading?n("spinner"):t._e(),t.isLoading?t._e():[t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Watching since")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.firstCandle.start)))])]):t._e(),t.data.lastCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Received data until")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.lastCandle.start)))])]):t._e(),t.data.lastCandle&&t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Data spanning")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.humanizeDuration(t.moment(t.data.lastCandle.start).diff(t.moment(t.data.firstCandle.start)))))])]):t._e()]],2),t.isLoading?t._e():[n("h3",{staticClass:"contain"},[t._v("Market graph")]),"fetching"===t.candleFetch?n("spinner"):t._e(),t.candles.length?[n("chart",{attrs:{data:t.chartData,height:500}})]:t._e()]],2):t._e()])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd contain"},[n("h3",[t._v("Add an API key")]),n("p",[t._v("Make sure that the API key has the permissions to create and cancel orders and view balances.")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Exchange")]),n("exchange-picker",{staticClass:"contain",attrs:{"only-tradable":"true"},on:{exchange:t.updateExchange}})],1),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Credentials")]),t._l(t.requires,function(e){return[n("label",[t._v(t._s(e))]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.credentials[e],expression:"credentials[cred]"}],domProps:{value:t.credentials[e]},on:{input:function(n){n.target.composing||t.$set(t.credentials,e,n.target.value)}}})]})],2)]),n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.upload(e)}}},[t._v("Add")])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd contain"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Market")]),n("market-picker",{staticClass:"contain",attrs:{"only-tradable":t.isTradebot},on:{market:t.updateMarketConfig}})],1),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("type-picker",{on:{type:t.updateType}})],1)]),"market watcher"!==t.type?[n("div",{staticClass:"hr"}),n("strat-picker",{staticClass:"contain my2",on:{stratConfig:t.updateStrat}}),"paper trader"===t.type?n("div",{staticClass:"hr"}):t._e(),"paper trader"===t.type?n("paper-trader",{on:{settings:t.updatePaperTrader}}):t._e()]:t._e()],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("dataset-picker",{staticClass:"contain my2",on:{dataset:t.updateDataset}}),n("div",{staticClass:"hr"}),n("strat-picker",{staticClass:"contain my2",on:{stratConfig:t.updateStrat}}),n("div",{staticClass:"hr"}),n("paper-trader",{on:{settings:t.updatePaperTrader}}),n("div",{staticClass:"hr"})],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain roundtrips"},[n("h2",[t._v("Roundtrips")]),t.roundtrips.length?n("table",[n("thead",[t._m(0),t._l(t.roundtrips,function(e){return n("tr",[n("td",[t._v(t._s(t.fmt(e.entryAt)))]),n("td",[t._v(t._s(t.fmt(e.exitAt)))]),n("td",[t._v(t._s(t.diff(e.duration)))]),n("td",[t._v(t._s(t.round(e.entryBalance)))]),n("td",[t._v(t._s(t.round(e.exitBalance)))]),-1===Math.sign(e.pnl)?[n("td",{staticClass:"loss"},[t._v(t._s(Math.sign(e.pnl)*e.pnl.toFixed(2)))]),n("td",{staticClass:"loss"},[t._v(t._s(e.profit.toFixed(2))+"%")])]:[n("td",{staticClass:"profit"},[t._v(t._s(e.pnl.toFixed(2)))]),n("td",{staticClass:"profit"},[t._v(t._s(e.profit.toFixed(2))+"%")])]],2)})],2)]):t._e(),t.roundtrips.length?t._e():n("div",[n("p",[t._v("Not enough data to display")])])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("tr",[n("th",[t._v("Entry at (UTC)")]),n("th",[t._v("Exit at (UTC)")]),n("th",[t._v("Exposure")]),n("th",[t._v("Entry balance")]),n("th",[t._v("Exit balance")]),n("th",[t._v("P&L")]),n("th",[t._v("Profit")])])}]}},function(t,e,n){var r=n(84);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(85);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(86);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(87);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(88);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(89);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(90);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(91);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(92);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(93);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(94);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(95);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(96);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(97);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(98);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(99);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(100);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(101);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(102);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(103);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(104);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(105);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(106);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(107);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(108);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(109);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(110);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(111);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}}]); \ No newline at end of file +function n(t,e){if(!t)throw new Error("[vue-router] "+e)}function r(e,n){"production"===t.env.NODE_ENV||e||"undefined"!=typeof console&&console.warn("[vue-router] "+n)}function i(t){return Object.prototype.toString.call(t).indexOf("Error")>-1}function o(e,n){switch(typeof n){case"undefined":return;case"object":return n;case"function":return n(e);case"boolean":return n?e.params:void 0;default:"production"!==t.env.NODE_ENV&&r(!1,'props in "'+e.path+'" is a '+typeof n+", expecting an object, function or boolean.")}}function a(e,n,i){void 0===n&&(n={});var o,a=i||s;try{o=a(e||"")}catch(e){"production"!==t.env.NODE_ENV&&r(!1,e.message),o={}}for(var u in n){var c=n[u];o[u]=Array.isArray(c)?c.slice():c}return o}function s(t){var e={};return(t=t.trim().replace(/^(\?|#|&)/,""))?(t.split("&").forEach(function(t){var n=t.replace(/\+/g," ").split("="),r=Pt(n.shift()),i=n.length>0?Pt(n.join("=")):null;void 0===e[r]?e[r]=i:Array.isArray(e[r])?e[r].push(i):e[r]=[e[r],i]}),e):e}function u(t){var e=t?Object.keys(t).map(function(e){var n=t[e];if(void 0===n)return"";if(null===n)return Dt(e);if(Array.isArray(n)){var r=[];return n.forEach(function(t){void 0!==t&&(null===t?r.push(Dt(e)):r.push(Dt(e)+"="+Dt(t)))}),r.join("&")}return Dt(e)+"="+Dt(n)}).filter(function(t){return t.length>0}).join("&"):null;return e?"?"+e:""}function c(t,e,n,r){var i=r&&r.options.stringifyQuery,o={name:e.name||t&&t.name,meta:t&&t.meta||{},path:e.path||"/",hash:e.hash||"",query:e.query||{},params:e.params||{},fullPath:f(e,i),matched:t?l(t):[]};return n&&(o.redirectedFrom=f(n,i)),Object.freeze(o)}function l(t){for(var e=[];t;)e.unshift(t),t=t.parent;return e}function f(t,e){var n=t.path,r=t.query;void 0===r&&(r={});var i=t.hash;void 0===i&&(i="");var o=e||u;return(n||"/")+o(r)+i}function d(t,e){return e===It?t===e:!!e&&(t.path&&e.path?t.path.replace(Mt,"")===e.path.replace(Mt,"")&&t.hash===e.hash&&p(t.query,e.query):!(!t.name||!e.name)&&(t.name===e.name&&t.hash===e.hash&&p(t.query,e.query)&&p(t.params,e.params)))}function p(t,e){void 0===t&&(t={}),void 0===e&&(e={});var n=Object.keys(t),r=Object.keys(e);return n.length===r.length&&n.every(function(n){var r=t[n],i=e[n];return"object"==typeof r&&"object"==typeof i?p(r,i):String(r)===String(i)})}function h(t,e){return 0===t.path.replace(Mt,"/").indexOf(e.path.replace(Mt,"/"))&&(!e.hash||t.hash===e.hash)&&v(t.query,e.query)}function v(t,e){for(var n in e)if(!(n in t))return!1;return!0}function m(t){if(!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey||t.defaultPrevented||void 0!==t.button&&0!==t.button)){if(t.currentTarget&&t.currentTarget.getAttribute){if(/\b_blank\b/i.test(t.currentTarget.getAttribute("target")))return}return t.preventDefault&&t.preventDefault(),!0}}function g(t){if(t)for(var e,n=0;n=0&&(e=t.slice(r),t=t.slice(0,r));var i=t.indexOf("?");return i>=0&&(n=t.slice(i+1),t=t.slice(0,i)),{path:t,query:n,hash:e}}function x(t){return t.replace(/\/\//g,"/")}function w(t,e){for(var n,r=[],i=0,o=0,a="",s=e&&e.delimiter||"/";null!=(n=Gt.exec(t));){var u=n[0],c=n[1],l=n.index;if(a+=t.slice(o,l),o=l+u.length,c)a+=c[1];else{var f=t[o],d=n[2],p=n[3],h=n[4],v=n[5],m=n[6],g=n[7];a&&(r.push(a),a="");var _=null!=d&&null!=f&&f!==d,y="+"===m||"*"===m,b="?"===m||"*"===m,x=n[2]||s,w=h||v;r.push({name:p||i++,prefix:d||"",delimiter:x,optional:b,repeat:y,partial:_,asterisk:!!g,pattern:w?$(w):g?".*":"[^"+A(x)+"]+?"})}}return o-1&&(a.params[f]=n.params[f]);if(u)return a.path=M(u.path,a.params,'named route "'+s+'"'),l(u,a,o)}else if(a.path){a.params={};for(var v=0;v=t.length?n():t[i]?e(t[i],function(){r(i+1)}):r(i+1)};r(0)}function st(e){return function(n,o,a){var s=!1,u=0,c=null;ut(e,function(e,n,o,l){if("function"==typeof e&&void 0===e.cid){s=!0,u++;var f,d=lt(function(t){t.__esModule&&t.default&&(t=t.default),e.resolved="function"==typeof t?t:St.extend(t),o.components[l]=t,--u<=0&&a()}),p=lt(function(e){var n="Failed to resolve async component "+l+": "+e;"production"!==t.env.NODE_ENV&&r(!1,n),c||(c=i(e)?e:new Error(n),a(c))});try{f=e(d,p)}catch(t){p(t)}if(f)if("function"==typeof f.then)f.then(d,p);else{var h=f.component;h&&"function"==typeof h.then&&h.then(d,p)}}}),s||a()}}function ut(t,e){return ct(t.map(function(t){return Object.keys(t.components).map(function(n){return e(t.components[n],t.instances[n],t,n)})}))}function ct(t){return Array.prototype.concat.apply([],t)}function lt(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}function ft(t){if(!t)if(Vt){var e=document.querySelector("base");t=e&&e.getAttribute("href")||"/",t=t.replace(/^https?:\/\/[^\/]+/,"")}else t="/";return"/"!==t.charAt(0)&&(t="/"+t),t.replace(/\/$/,"")}function dt(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n=0?e.slice(0,n):e;window.location.replace(r+"#"+t)}function At(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}function $t(t,e,n){var r="hash"===n?"#"+e:e;return t?x(t+"/"+r):r}var St,jt={name:"router-view",functional:!0,props:{name:{type:String,default:"default"}},render:function(t,e){var n=e.props,r=e.children,i=e.parent,a=e.data;a.routerView=!0;for(var s=i.$createElement,u=n.name,c=i.$route,l=i._routerViewCache||(i._routerViewCache={}),f=0,d=!1;i&&i._routerRoot!==i;)i.$vnode&&i.$vnode.data.routerView&&f++,i._inactive&&(d=!0),i=i.$parent;if(a.routerViewDepth=f,d)return s(l[u],a,r);var p=c.matched[f];if(!p)return l[u]=null,s();var h=l[u]=p.components[u];return a.registerRouteInstance=function(t,e){var n=p.instances[u];(e&&n!==t||!e&&n===t)&&(p.instances[u]=e)},(a.hook||(a.hook={})).prepatch=function(t,e){p.instances[u]=e.componentInstance},a.props=o(c,p.props&&p.props[u]),s(h,a,r)}},Tt=/[!'()*]/g,Nt=function(t){return"%"+t.charCodeAt(0).toString(16)},Rt=/%2C/g,Dt=function(t){return encodeURIComponent(t).replace(Tt,Nt).replace(Rt,",")},Pt=decodeURIComponent,Mt=/\/?$/,It=c(null,{path:"/"}),Ft=[String,Object],Lt=[String,Array],zt={name:"router-link",props:{to:{type:Ft,required:!0},tag:{type:String,default:"a"},exact:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,event:{type:Lt,default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,i=n.resolve(this.to,r,this.append),o=i.location,a=i.route,s=i.href,u={},l=n.options.linkActiveClass,f=n.options.linkExactActiveClass,p=null==l?"router-link-active":l,v=null==f?"router-link-exact-active":f,_=null==this.activeClass?p:this.activeClass,y=null==this.exactActiveClass?v:this.exactActiveClass,b=o.path?c(null,o,null,n):a;u[y]=d(r,b),u[_]=this.exact?u[y]:h(r,b);var x=function(t){m(t)&&(e.replace?n.replace(o):n.push(o))},w={click:m};Array.isArray(this.event)?this.event.forEach(function(t){w[t]=x}):w[this.event]=x;var k={class:u};if("a"===this.tag)k.on=w,k.attrs={href:s};else{var C=g(this.$slots.default);if(C){C.isStatic=!1;var E=St.util.extend;(C.data=E({},C.data)).on=w;(C.data.attrs=E({},C.data.attrs)).href=s}else k.on=w}return t(this.tag,k,this.$slots.default)}},Vt="undefined"!=typeof window,Ut=Array.isArray||function(t){return"[object Array]"==Object.prototype.toString.call(t)},qt=P,Ht=w,Wt=k,Bt=O,Yt=D,Gt=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");qt.parse=Ht,qt.compile=Wt,qt.tokensToFunction=Bt,qt.tokensToRegExp=Yt;var Kt=Object.create(null),Xt=Object.create(null),Jt=Vt&&function(){var t=window.navigator.userAgent;return(-1===t.indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&(window.history&&"pushState"in window.history)}(),Zt=Vt&&window.performance&&window.performance.now?window.performance:Date,Qt=et(),te=function(t,e){this.router=t,this.base=ft(e),this.current=It,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[]};te.prototype.listen=function(t){this.cb=t},te.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},te.prototype.onError=function(t){this.errorCbs.push(t)},te.prototype.transitionTo=function(t,e,n){var r=this,i=this.router.match(t,this.current);this.confirmTransition(i,function(){r.updateRoute(i),e&&e(i),r.ensureURL(),r.ready||(r.ready=!0,r.readyCbs.forEach(function(t){t(i)}))},function(t){n&&n(t),t&&!r.ready&&(r.ready=!0,r.readyErrorCbs.forEach(function(e){e(t)}))})},te.prototype.confirmTransition=function(t,e,n){var o=this,a=this.current,s=function(t){i(t)&&(o.errorCbs.length?o.errorCbs.forEach(function(e){e(t)}):(r(!1,"uncaught error during route navigation:"),console.error(t))),n&&n(t)};if(d(t,a)&&t.matched.length===a.matched.length)return this.ensureURL(),s();var u=dt(this.current.matched,t.matched),c=u.updated,l=u.deactivated,f=u.activated,p=[].concat(vt(l),this.router.beforeHooks,mt(c),f.map(function(t){return t.beforeEnter}),st(f));this.pending=t;var h=function(e,n){if(o.pending!==t)return s();try{e(t,a,function(t){!1===t||i(t)?(o.ensureURL(!0),s(t)):"string"==typeof t||"object"==typeof t&&("string"==typeof t.path||"string"==typeof t.name)?(s(),"object"==typeof t&&t.replace?o.replace(t):o.push(t)):n(t)})}catch(t){s(t)}};at(p,h,function(){var n=[];at(_t(f,n,function(){return o.current===t}).concat(o.router.resolveHooks),h,function(){if(o.pending!==t)return s();o.pending=null,e(t),o.router.app&&o.router.app.$nextTick(function(){n.forEach(function(t){t()})})})})},te.prototype.updateRoute=function(t){var e=this.current;this.current=t,this.cb&&this.cb(t),this.router.afterHooks.forEach(function(n){n&&n(t,e)})};var ee=function(t){function e(e,n){var r=this;t.call(this,e,n);var i=e.options.scrollBehavior;i&&B(),window.addEventListener("popstate",function(t){var n=r.current;r.transitionTo(xt(r.base),function(t){i&&Y(e,t,n,!0)})})}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,i=this,o=i.current;this.transitionTo(t,function(t){it(x(r.base+t.fullPath)),Y(r.router,t,o,!1),e&&e(t)},n)},e.prototype.replace=function(t,e,n){var r=this,i=this,o=i.current;this.transitionTo(t,function(t){ot(x(r.base+t.fullPath)),Y(r.router,t,o,!1),e&&e(t)},n)},e.prototype.ensureURL=function(t){if(xt(this.base)!==this.current.fullPath){var e=x(this.base+this.current.fullPath);t?it(e):ot(e)}},e.prototype.getCurrentLocation=function(){return xt(this.base)},e}(te),ne=function(t){function e(e,n,r){t.call(this,e,n),r&&wt(this.base)||kt()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;window.addEventListener("hashchange",function(){kt()&&t.transitionTo(Ct(),function(t){Ot(t.fullPath)})})},e.prototype.push=function(t,e,n){this.transitionTo(t,function(t){Et(t.fullPath),e&&e(t)},n)},e.prototype.replace=function(t,e,n){this.transitionTo(t,function(t){Ot(t.fullPath),e&&e(t)},n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Ct()!==e&&(t?Et(e):Ot(e))},e.prototype.getCurrentLocation=function(){return Ct()},e}(te),re=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)},n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)},n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,function(){e.index=n,e.updateRoute(r)})}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(te),ie=function(e){void 0===e&&(e={}),this.app=null,this.apps=[],this.options=e,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=q(e.routes||[],this);var r=e.mode||"hash";switch(this.fallback="history"===r&&!Jt&&!1!==e.fallback,this.fallback&&(r="hash"),Vt||(r="abstract"),this.mode=r,r){case"history":this.history=new ee(this,e.base);break;case"hash":this.history=new ne(this,e.base,this.fallback);break;case"abstract":this.history=new re(this,e.base);break;default:"production"!==t.env.NODE_ENV&&n(!1,"invalid mode: "+r)}},oe={currentRoute:{}};ie.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},oe.currentRoute.get=function(){return this.history&&this.history.current},ie.prototype.init=function(e){var r=this;if("production"!==t.env.NODE_ENV&&n(_.installed,"not installed. Make sure to call `Vue.use(VueRouter)` before creating root instance."),this.apps.push(e),!this.app){this.app=e;var i=this.history;if(i instanceof ee)i.transitionTo(i.getCurrentLocation());else if(i instanceof ne){var o=function(){i.setupListeners()};i.transitionTo(i.getCurrentLocation(),o,o)}i.listen(function(t){r.apps.forEach(function(e){e._route=t})})}},ie.prototype.beforeEach=function(t){return At(this.beforeHooks,t)},ie.prototype.beforeResolve=function(t){return At(this.resolveHooks,t)},ie.prototype.afterEach=function(t){return At(this.afterHooks,t)},ie.prototype.onReady=function(t,e){this.history.onReady(t,e)},ie.prototype.onError=function(t){this.history.onError(t)},ie.prototype.push=function(t,e,n){this.history.push(t,e,n)},ie.prototype.replace=function(t,e,n){this.history.replace(t,e,n)},ie.prototype.go=function(t){this.history.go(t)},ie.prototype.back=function(){this.go(-1)},ie.prototype.forward=function(){this.go(1)},ie.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map(function(t){return Object.keys(t.components).map(function(e){return t.components[e]})})):[]},ie.prototype.resolve=function(t,e,n){var r=V(t,e||this.history.current,n,this),i=this.match(r,e),o=i.redirectedFrom||i.fullPath;return{location:r,route:i,href:$t(this.history.base,o,this.mode),normalizedTo:r,resolved:i}},ie.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==It&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(ie.prototype,oe),ie.install=_,ie.version="2.7.0",Vt&&window.Vue&&window.Vue.use(ie),e.a=ie}).call(e,n(10))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(130),i=n.n(r),o=n(129),a=n.n(o),s=n(131),u=n.n(s);e.default={name:"app",components:{top:i.a,bottom:a.a,modal:u.a}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(125),i=n.n(r),o=n(20),a=n.n(o),s=n(18),u=n.n(s),c=n(3),l=n.n(c),f=n(2);e.default={created:function(){var t=this;n.i(f.a)("configPart/performanceAnalyzer",function(e,n){t.performanceAnalyzer=toml.parse(n.part),t.performanceAnalyzer.enabled=!0})},data:function(){return{dataset:{},strat:{},paperTrader:{},performanceAnalyzer:{}}},components:{stratPicker:a.a,datasetPicker:i.a,paperTrader:u.a},computed:{market:function(){return this.dataset.exchange?{exchange:this.dataset.exchange,currency:this.dataset.currency,asset:this.dataset.asset}:{}},range:function(){return this.dataset.exchange?{from:this.dataset.from,to:this.dataset.to}:{}},config:function(){var t={};return Object.assign(t,{watch:this.market},{paperTrader:this.paperTrader},this.strat,{backtest:{daterange:this.range}},{performanceAnalyzer:this.performanceAnalyzer}),t.valid=this.validConfig(t),t}},methods:{validConfig:function(t){if(!t.backtest)return!1;if(!t.backtest.daterange)return!1;if(l.a.isEmpty(t.backtest.daterange))return!1;if(!t.watch)return!1;if(!t.tradingAdvisor)return!1;var e=t.tradingAdvisor.method;if(l.a.isEmpty(t[e]))return!1;if(t.tradingAdvisor){if(l.a.isNaN(t.tradingAdvisor.candleSize))return!1;if(0==t.tradingAdvisor.candleSize)return!1}return!0},updateDataset:function(t){this.dataset=t,this.$emit("config",this.config)},updateStrat:function(t){this.strat=t,this.$emit("config",this.config)},updatePaperTrader:function(t){this.paperTrader=t,this.paperTrader.enabled=!0,this.$emit("config",this.config)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(119),i=n.n(r),o=n(120),a=n.n(o),s=n(2),u=n(5),c=n.n(u);e.default={data:function(){return{backtestable:!1,backtestState:"idle",backtestResult:!1,config:!1}},methods:{check:function(t){if(this.config=t,!t.valid)return this.backtestable=!1;this.backtestable=!0},run:function(){var t=this;this.backtestState="fetching";var e={gekkoConfig:this.config,data:{candleProps:["close","start"],indicatorResults:!0,report:!0,roundtrips:!0,trades:!0}};n.i(s.b)("backtest",e,function(e,n){t.backtestState="fetched",t.backtestResult=n})}},components:{configBuilder:i.a,result:a.a,spinner:c.a}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(68),i=n(69);e.default={props:["data","height"],data:function(){return{isClicked:!1}},watch:{data:function(){this.render()}},created:function(){setTimeout(this.render,100)},beforeDestroy:function(){this.remove()},methods:{click:function(){this.isClicked=!0},render:function(){this.remove(),_.size(this.data.candles)<4?n.i(i.a)("Not enough data to spawn chart"):n.i(r.a)(this.data.candles,this.data.trades,this.height)},remove:function(){d3.select("#chart").html("")}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(121),i=n.n(r),o=n(11),a=n.n(o),s=n(16),u=n.n(s);e.default={props:["result"],data:function(){return{}},methods:{},components:{roundtripTable:u.a,resultSummary:i.a,chart:a.a}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:["roundtrips"],data:function(){return{}},methods:{diff:function(t){return moment.duration(t).humanize()},humanizeDuration:function(t){return window.humanizeDuration(t)},fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},round:function(t){return(+t).toFixed(3)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(21),i=n.n(r);e.default={props:["report"],components:{paperTradeSummary:i.a},methods:{round:function(t){return(+t).toFixed(5)}},computed:{profitClass:function(){return this.report.relativeProfit>0?"profit":"loss"}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(126),i=n.n(r),o=n(3),a=(n.n(o),n(2));e.default={data:function(){return{exchange:!1,credentials:{}}},components:{exchangePicker:i.a},computed:{apiKeySets:function(){return this.$store.state.apiKeys},exchanges:function(){return this.$store.state.exchanges},requires:function(){return this.exchanges&&this.exchange?this.exchanges[this.exchange].requires:[]},config:function(){return{exchange:this.exchange,values:this.credentials}}},watch:{credentials:function(){this.emitConfig()}},methods:{updateExchange:function(t){this.credentials={},this.exchange=t,this.emitConfig()},emitConfig:function(){this.$emit("config",this.config)},upload:function(){var t=this,e=this.config.exchange;this.exchanges&&this.apiKeySets.includes(e)&&!confirm("You already have API keys for "+e+" defined, do you want to overwrite them?")||n.i(a.b)("addApiKey",this.config,function(e,n){if(e)return alert(e);t.credentials={}})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(122),i=n.n(r),o=n(2);e.default={components:{apiConfigBuilder:i.a},data:function(){return{addApiToggle:!1}},methods:{openAddApi:function(){this.addApiToggle=!0},removeApiKey:function(t){confirm("Are you sure you want to delete these API keys?")&&n.i(o.b)("removeApiKey",{exchange:t},function(t,e){if(t)return alert(t)})}},computed:{apiKeySets:function(){return this.$store.state.apiKeys}},watch:{apiKeySets:function(){this.addApiToggle=!1}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(5),i=n.n(r),o=n(8),a=n(14),s=n.i(o.a)("\n\n## Local data\n\nGekko needs local market data in order to backtest strategies. The local\ndata can also be used in a warmup period when running a strategy against a\nlive market.\n\n");e.default={mixins:[a.a],components:{spinner:i.a},data:function(){return{intro:s,viewUnscannable:!1}},methods:{toggleUnscannable:function(){this.viewUnscannable=!0},humanizeDuration:function(t){return window.humanizeDuration(t)},fmt:function(t){return t.format("YYYY-MM-DD HH:mm")}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(17),i=n.n(r),o=n(12),a=n.n(o),s=n(3);n.n(s);e.default={data:function(){return{market:{},range:{}}},components:{marketPicker:i.a,rangeCreator:a.a},computed:{config:function(){var t={};return Object.assign(t,this.market,{importer:{daterange:this.range}},{candleWriter:{enabled:!0}}),t}},methods:{updateMarketConfig:function(t){this.market=t,this.emitConfig()},updateRange:function(t){this.range=t,this.emitConfig()},emitConfig:function(){this.$emit("config",this.config)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),i=n(5),o=n.n(i),a=n(123),s=n.n(a),u=n(8),c=n.i(u.a)("\n\n## Import data\n\nThe importer can download historical market data directly from the exchange.\n\n");e.default={components:{importConfigBuilder:s.a,spinner:o.a},data:function(){return{intro:c,config:{}}},computed:{imports:function(){return this.$store.state.imports}},methods:{daysApart:function(t){var e=moment(t.to),n=moment(t.from);return e.diff(n,"days")},updateConfig:function(t){this.config=t},run:function(){var t=this;if(this.daysApart(this.config.importer.daterange)<1)return alert("You can only import at least one day of data..");n.i(r.b)("import",this.config,function(e,n){if(e)return alert(e);t.$store.commit("addImport",n),t.$router.push({path:"/data/importer/import/"+n.id})})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(128),a=n.n(o),s=n(5),u=n.n(s);e.default={components:{progressBar:a.a,spinner:u.a},computed:{data:function(){return i.a.find(this.$store.state.imports,{id:this.$route.params.id})},initialized:function(){if(this.data&&this.latest.isValid())return!0},latest:function(){if(this.data)return this.mom(this.data.latest)},fromEndMs:function(){if(this.data)return this.to.diff(this.latest)},fromEnd:function(){return this.latest?humanizeDuration(this.fromEndMs):"LOADING"},from:function(){if(this.data)return this.mom(this.data.from)},to:function(){if(this.data)return this.mom(this.data.to)},timespan:function(){if(this.data)return this.to.diff(this.from)},progress:function(){if(this.data){return 100*(this.timespan-this.fromEndMs)/this.timespan}}},methods:{fmt:function(t){return t.format("YYYY-MM-DD HH:mm:ss")},mom:function(t){return moment.utc(t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(17),i=n.n(r),o=n(127),a=n.n(o),s=n(20),u=n.n(s),c=n(18),l=n.n(c),f=n(2),d=n(3),p=n.n(d);e.default={created:function(){var t=this;n.i(f.a)("configPart/candleWriter",function(e,n){t.candleWriter=toml.parse(n.part)}),n.i(f.a)("configPart/performanceAnalyzer",function(e,n){t.performanceAnalyzer=toml.parse(n.part),t.performanceAnalyzer.enabled=!0})},data:function(){return{market:{},range:{},type:"",strat:{},paperTrader:{},candleWriter:{},performanceAnalyzer:{}}},components:{marketPicker:i.a,typePicker:a.a,stratPicker:u.a,paperTrader:l.a},computed:{isTradebot:function(){return"tradebot"===this.type},config:function(){var t={};return Object.assign(t,this.market,this.strat,{paperTrader:this.paperTrader},{candleWriter:this.candleWriter},{type:this.type},{performanceAnalyzer:this.performanceAnalyzer}),this.isTradebot&&(delete t.paperTrader,t.trader={enabled:!0}),t.valid=this.validConfig(t),t}},methods:{validConfig:function(t){if("market watcher"===t.type)return!0;if(!t.tradingAdvisor)return!1;if(p.a.isNaN(t.tradingAdvisor.candleSize))return!1;if(0==t.tradingAdvisor.candleSize)return!1;var e=t.tradingAdvisor.method;return!p.a.isEmpty(t[e])},updateMarketConfig:function(t){this.market=t,this.emitConfig()},updateType:function(t){this.type=t,this.emitConfig()},updateStrat:function(t){this.strat=t,this.emitConfig()},updatePaperTrader:function(t){this.paperTrader=t,this.paperTrader.enabled=!0,this.emitConfig()},emitConfig:function(){this.$emit("config",this.config)}}}},function(t,e,n){"use strict";function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}Object.defineProperty(e,"__esModule",{value:!0});var i,o=n(8),a=n.i(o.a)("\n\n## Live Gekko\n\nRun your strategy against the live market!\n\n");e.default=(i={data:function(){return{text:a}},created:function(){var t=this;this.timer=setInterval(function(){t.now=moment()},1e3)},destroyed:function(){clearTimeout(this.timer)}},r(i,"data",function(){return{text:a,timer:!1,now:moment()}}),r(i,"computed",{stratrunners:function(){return this.$store.state.stratrunners},watchers:function(){return this.$store.state.watchers}}),r(i,"methods",{humanizeDuration:function(t){return window.humanizeDuration(t)},moment:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}(function(t){return moment.utc(t)}),fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},round:function(t){return(+t).toFixed(3)},timespan:function(t,e){return this.humanizeDuration(this.moment(t).diff(this.moment(e)))}}),i)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(4),a=n(2),s=n(124),u=n.n(s);e.default={components:{gekkoConfigBuilder:u.a},data:function(){return{pendingStratrunner:!1,config:{}}},computed:{watchers:function(){return this.$store.state.watchers},stratrunners:function(){return this.$store.state.stratrunners},watchConfig:function(){var t=i.a.pick(this.config,"watch","candleWriter"),e=o.a.util.extend({},t);return e.type="market watcher",e.mode="realtime",e},requiredHistoricalData:function(){if(this.config.tradingAdvisor&&this.config.valid){var t=this.config.tradingAdvisor;return t.candleSize*t.historySize}},gekkoConfig:function(){var t;if(this.existingMarketWatcher){if(this.requiredHistoricalData){var e=moment().utc().startOf("minute").subtract(this.requiredHistoricalData,"minutes").unix(),n=moment.utc(this.existingMarketWatcher.firstCandle.start).unix();t=moment.unix(Math.max(e,n)).utc().format()}else t=moment().utc().startOf("minute").format();return o.a.util.extend({market:{type:"leech",from:t},mode:"realtime"},this.config)}},existingMarketWatcher:function(){var t=o.a.util.extend({},this.watchConfig.watch);return i.a.find(this.watchers,{watch:t})},exchange:function(){return this.watchConfig.watch.exchange},existingTradebot:function(){return i.a.find(this.stratrunners.filter(function(t){return"tradebot"===t.trader}),{watch:{exchange:this.exchange}})},availableApiKeys:function(){return this.$store.state.apiKeys}},watch:{existingMarketWatcher:function(t,e){var n=this;this.pendingStratrunner&&t&&t.firstCandle&&t.lastCandle&&(this.pendingStratrunner=!1,this.startGekko(function(t,e){n.$router.push({path:"/live-gekkos/stratrunner/"+e.id})}))}},methods:{updateConfig:function(t){this.config=t},start:function(){var t=this;if("tradebot"===this.config.type){if(this.existingTradebot){var e="You already have a tradebot running on this exchange";return e+=", you can only run one tradebot per exchange.",alert(e)}if(!this.availableApiKeys.includes(this.exchange))return alert("Please first configure API keys for this exchange in the config page.")}"market watcher"===this.config.type?this.existingMarketWatcher?(alert("This market is already being watched, redirecting you now..."),this.$router.push({path:"/live-gekkos/watcher/"+this.existingMarketWatcher.id})):this.startWatcher(function(e,n){t.$router.push({path:"/live-gekkos/watcher/"+n.id})}):this.existingMarketWatcher?this.startGekko(this.routeToGekko):this.startWatcher(function(e,n){t.pendingStratrunner=!0})},routeToGekko:function(t,e){if(t||e.error)return console.error(t,e.error);this.$router.push({path:"/live-gekkos/stratrunner/"+e.id})},startWatcher:function(t){n.i(a.b)("startGekko",this.watchConfig,t)},startGekko:function(t){n.i(a.b)("startGekko",this.gekkoConfig,t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(4),i=n(3),o=n.n(i),a=n(2),s=n(5),u=n.n(s),c=n(11),l=n.n(c),f=n(16),d=n.n(f),p=n(21),h=n.n(p);e.default={created:function(){this.isLoading||this.getCandles()},components:{spinner:u.a,chart:l.a,paperTradeSummary:h.a,roundtrips:d.a},data:function(){return{candleFetch:"idle",candles:!1}},computed:{stratrunners:function(){return this.$store.state.stratrunners},data:function(){return o.a.find(this.stratrunners,{id:this.$route.params.id})},chartData:function(){return{candles:this.candles,trades:this.trades}},trades:function(){return this.data?this.data.trades:[]},report:function(){if(this.data)return this.data.report},stratName:function(){if(this.data)return this.data.strat.tradingAdvisor.method},stratParams:function(){if(!this.data)return"";var t=r.a.util.extend({},this.data.strat.params);return delete t.__empty,o.a.isEmpty(t)?"No parameters":JSON.stringify(t,null,4)},isLoading:function(){return!this.data||(!o.a.isObject(this.data.firstCandle)||!o.a.isObject(this.data.lastCandle))},watchers:function(){return this.$store.state.watchers},watcher:function(){var t=r.a.util.extend({},this.data.watch);return o.a.find(this.watchers,{watch:t})}},watch:{"data.lastCandle.start":function(){this.candleFetch="dirty"},data:function(t,e){this.isLoading||"fetched"!==this.candleFetch&&this.getCandles()}},methods:{round:function(t){return(+t).toFixed(5)},humanizeDuration:function(t){return window.humanizeDuration(t)},moment:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}(function(t){return moment.utc(t)}),fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},getCandles:function(){var t=this;this.candleFetch="fetching";var e=this.data.lastCandle.start,r=this.data.firstCandle.start,i=this.data.strat.tradingAdvisor.candleSize,s={watch:this.data.watch,daterange:{to:e,from:r},candleSize:i};n.i(a.b)("getCandles",s,function(e,n){if(t.candleFetch="fetched",!n||n.error||!o.a.isArray(n))return console.log(n);t.candles=n.map(function(t){return t.start=moment.unix(t.start).utc().format(),t})})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),i=n(3),o=n.n(i),a=n(5),s=n.n(a),u=(n(4),n(11)),c=n.n(u);e.default={created:function(){this.isLoading||this.getCandles()},components:{spinner:s.a,chart:c.a},data:function(){return{candleFetch:"idle",candles:[]}},computed:{watchers:function(){return this.$store.state.watchers},data:function(){return o.a.find(this.watchers,{id:this.$route.params.id})},chartData:function(){return{candles:this.candles,trades:[]}},isLoading:function(){return!this.data||(!o.a.isObject(this.data.firstCandle)||!o.a.isObject(this.data.lastCandle))}},watch:{"data.lastCandle.start":function(){this.candleFetch="dirty"},data:function(t,e){t&&t.firstCandle&&t.lastCandle&&"fetched"!==this.candleFetch&&this.getCandles()}},methods:{humanizeDuration:function(t){return window.humanizeDuration(t)},moment:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}(function(t){return moment.utc(t)}),fmt:function(t){return moment.utc(t).format("YYYY-MM-DD HH:mm")},getCandles:function(){var t=this;this.candleFetch="fetching";var e=moment.utc(this.data.lastCandle.start).unix(),i=Math.max(moment.utc(this.data.firstCandle.start).unix(),moment.utc(e).subtract(7,"days").unix()),o=e-i,a=60;o<86400&&(a=o<43200?1:5),i=moment.unix(i).utc().format(),e=moment.unix(e).utc().format();var s={watch:this.data.watch,daterange:{to:e,from:i},candleSize:a};n.i(r.b)("getCandles",s,function(e,n){t.candleFetch="fetched",t.candles=n.map(function(t){return t.start=moment.unix(t.start).utc().format(),t})})}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=(n.n(r),n(4)),o=(n(2),n(5)),a=n.n(o),s=n(14);e.default={components:{spinner:a.a},data:function(){return{setIndex:-1,customTo:!1,customFrom:!1,rangeVisible:!1,set:!1}},mixins:[s.a],methods:{humanizeDuration:function(t){return window.humanizeDuration(t,{largest:4})},fmt:function(t){return t.utc().format("YYYY-MM-DD HH:mm")},openRange:function(){if(-1===this.setIndex)return alert("Select a dataset to adjust range");this.updateCustomRange(),this.rangeVisible=!0},updateCustomRange:function(){this.customTo=this.fmt(this.set.to),this.customFrom=this.fmt(this.set.from)},emitSet:function(t){if(t){var e=void 0;this.customTo?(e=i.a.util.extend({},t),e.to=moment.utc(this.customTo,"YYYY-MM-DD HH:mm").format(),e.from=moment.utc(this.customFrom,"YYYY-MM-DD HH:mm").format()):e=t,this.$emit("dataset",e)}}},watch:{setIndex:function(){this.set=this.datasets[this.setIndex],this.updateCustomRange(),this.emitSet(this.set)},customTo:function(){this.emitSet(this.set)},customFrom:function(){this.emitSet(this.set)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(19),a=(n.n(o),n(12));n.n(a),n(2);e.default={props:["onlyTradable","onlyImportable"],data:function(){return{exchange:"poloniex"}},created:function(){this.emitExchange()},computed:{exchanges:function(){var t=Object.assign({},this.$store.state.exchanges);return!i.a.isEmpty(t)&&(this.onlyTradable&&i.a.each(t,function(e,n){e.tradable||delete t[n]}),this.onlyImportable&&i.a.each(t,function(e,n){e.importable||delete t[n]}),t)}},watch:{exchanges:function(){this.emitExchange()},exchange:function(){this.emitExchange()}},methods:{emitExchange:function(){this.$emit("exchange",this.exchange)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(19),a=(n.n(o),n(12));n.n(a),n(2);e.default={props:["onlyTradable","onlyImportable"],data:function(){return{exchange:"poloniex",currency:"USDT",asset:"BTC"}},created:function(){this.emitConfig()},computed:{exchanges:function(){var t=Object.assign({},this.$store.state.exchanges);return!i.a.isEmpty(t)&&(this.onlyTradable&&i.a.each(t,function(e,n){e.tradable||delete t[n]}),this.onlyImportable&&i.a.each(t,function(e,n){e.importable||delete t[n]}),t)},markets:function(){return this.exchanges?this.exchanges[this.exchange]:null},assets:function(){return this.exchanges?this.exchanges[this.exchange].markets[this.currency]:null},currencies:function(){return this.exchanges?i.a.keys(this.exchanges[this.exchange].markets):null},watchConfig:function(){return{watch:{exchange:this.exchange,currency:this.currency,asset:this.asset}}}},watch:{currency:function(){this.emitConfig()},asset:function(){this.emitConfig()},market:function(){this.emitConfig()},exchanges:function(){this.emitConfig()},exchange:function(){this.emitConfig()}},methods:{emitConfig:function(){this.$emit("market",this.watchConfig)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=(n.n(r),n(2));e.default={created:function(){var t=this;n.i(i.a)("configPart/paperTrader",function(e,n){t.rawPaperTraderParams=n.part})},data:function(){return{rawPaperTraderParams:"",rawPaperTraderParamsError:!1,paperTraderParams:{},toggle:"closed"}},watch:{rawPaperTraderParams:function(){this.emitConfig()}},methods:{switchToggle:function(){"open"===this.toggle?this.toggle="closed":this.toggle="open"},emitConfig:function(){this.parseParams(),this.$emit("settings",this.paperTraderParams)},parseParams:function(){try{this.paperTraderParams=toml.parse(this.rawPaperTraderParams),this.paperTraderParams.reportRoundtrips=!0,this.rawPaperTraderParamsError=!1}catch(t){this.rawPaperTraderParamsError=t,this.paperTraderParams={}}}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3);n.n(r),n(2);e.default={data:function(){return{from:"",to:""}},created:function(){var t=moment().startOf("minute"),e=t.clone().subtract(3,"months");this.to=this.fmt(t),this.from=this.fmt(e),this.emitRange()},methods:{fmtTs:function(t){return moment.unix(t).utc()},fmt:function(t){return t.utc().format("YYYY-MM-DD HH:mm")},emitRange:function(){this.$emit("range",{from:this.fmtTs(this.from),to:this.fmtTs(this.to)})},emitManualEntry:function(){if(this.from.length<"4"||this.from.length<"4")return this.$emit("range",{});var t=moment.utc(this.from),e=moment.utc(this.to);t.isValid()&&e.isValid()?this.$emit("range",{from:this.fmt(t),to:this.fmt(e)}):this.$emit("range",{})}},watch:{from:function(){this.emitManualEntry()},to:function(){this.emitManualEntry()},config:function(){this.scanned=!1},tab:function(){this.scanned=!1,this.$emit("range",{})},selectedRangeIndex:function(){var t=this.ranges[this.selectedRangeIndex];t&&this.emitRange(t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=(n.n(r),n(2));e.default={props:["config"],data:function(){return{scanned:!1,ranges:[],selectedRangeIndex:-1,tab:"scan",from:"",to:""}},methods:{scan:function(){var t=this;this.scanned="fetching",this.selectedRangeIndex=-1,n.i(i.b)("scan",this.config,function(e,n){t.scanned=!0,t.ranges=n,t.selectedRangeIndex=0})},printRange:function(t){var e=function(t){return t.format("YYYY-MM-DD HH:mm")},n=moment.unix(t.from),r=moment.unix(t.to),i=moment.duration(r.diff(n)).humanize();return e(n)+" to "+e(r)+" ("+i+")"},fmtTs:function(t){return moment.unix(t).utc()},fmt:function(t){return t.utc().format()},emitRange:function(t){this.$emit("range",{from:this.fmtTs(t.from),to:this.fmtTs(t.to)})},emitManualEntry:function(){if(this.from.length<"4"||this.from.length<"4")return this.$emit("range",{});var t=moment.utc(this.from),e=moment.utc(this.to);t.isValid()&&e.isValid()?this.$emit("range",{from:this.fmt(t),to:this.fmt(e)}):this.$emit("range",{})},reset:function(){this.scanned=!1,this.$emit("range",{})}},watch:{from:function(){this.emitManualEntry()},to:function(){this.emitManualEntry()},config:function(){this.reset()},tab:function(){this.reset()},selectedRangeIndex:function(){var t=this.ranges[this.selectedRangeIndex];t&&this.emitRange(t)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n.n(r),o=n(2);e.default={data:function(){return{strategies:[],candleSizeUnit:"hours",rawCandleSize:1,strategy:"MACD",historySize:10,rawStratParams:"",rawStratParamsError:!1,emptyStrat:!1,stratParams:{}}},created:function(){var t=this;n.i(o.a)("strategies",function(e,n){t.strategies=n,i.a.each(t.strategies,function(t){t.empty=""===t.params}),t.rawStratParams=i.a.find(t.strategies,{name:t.strategy}).params,t.emptyStrat=i.a.find(t.strategies,{name:t.strategy}).empty,t.emitConfig()})},watch:{strategy:function(t){t=i.a.find(this.strategies,{name:t}),this.rawStratParams=t.params,this.emptyStrat=t.empty,this.emitConfig()},candleSize:function(){this.emitConfig()},historySize:function(){this.emitConfig()},rawStratParams:function(){this.emitConfig()}},computed:{candleSize:function(){return"minutes"===this.candleSizeUnit?this.rawCandleSize:"hours"===this.candleSizeUnit?60*this.rawCandleSize:"days"===this.candleSizeUnit?60*this.rawCandleSize*24:void 0},singularCandleSizeUnit:function(){return this.candleSizeUnit.slice(0,-1)},config:function(){var t={tradingAdvisor:{enabled:!0,method:this.strategy,candleSize:+this.candleSize,historySize:+this.historySize}};return this.emptyStrat?t[this.strategy]={__empty:!0}:t[this.strategy]=this.stratParams,t}},methods:{humanizeDuration:function(t){return window.humanizeDuration(t)},emitConfig:function(){this.parseParams(),this.$emit("stratConfig",this.config)},parseParams:function(){try{this.stratParams=toml.parse(this.rawStratParams),this.rawStratParamsError=!1}catch(t){this.rawStratParamsError=t,this.stratParams={}}}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={created:function(){this.emitType()},data:function(){return{types:["paper trader","market watcher","tradebot"],selectedTypeIndex:0}},methods:{emitType:function(){this.$emit("type",this.type)}},watch:{type:function(){this.emitType()}},computed:{type:function(){return this.types[this.selectedTypeIndex]}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:["report"],methods:{round2:function(t){return(+t).toFixed(2)},round:function(t){return(+t).toFixed(5)}},computed:{profitClass:function(){return this.report.relativeProfit>0?"profit":"loss"}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={props:["progress"],methods:{round:function(t){return(+t).toFixed(2)}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(112),i=n(113);e.default={data:function(){return{version:{gekko:r.version,ui:i.version}}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(8),i=n(9),o=n.i(r.a)("\n\n## Gekko\n\nGekko is a Bitcoin trading bot and backtesting platform that\nconnects to popular Bitcoin exchanges. It is written in javascript\nand runs on nodejs.\n\n[Find out more](https://gekko.wizb.it/).\n\n*Gekko is 100% open source and free, if you paid for this you have been scammed.*\n\n");e.default={data:function(){return{left:o}},computed:{imageUrl:function(){return i.c+"assets/gekko.jpg"}}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(8),i={disconnected:n.i(r.a)("\n\n## Disconnected\n\nSomething happened to either Gekko or the connection.\nPlease check the terminal where Gekko is running or\nyour network connection.\n\n ")};e.default={computed:{active:function(){return!this.$store.state.warnings.connected},content:function(){return this.$store.state.warnings.connected?"":i.disconnected}}}},function(t,e,n){"use strict";var r=n(3),i=n.n(r),o=function(){function t(t,e){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){i=!0,o=t}finally{try{!r&&s.return&&s.return()}finally{if(i)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();e.a=function(t,e,n){function r(){if(!d3.event.sourceEvent||"zoom"!==d3.event.sourceEvent.type){var t=d3.event.selection||y.range();_.domain(t.map(y.invert,y)),a(_.domain()),d.select(".axis--y").call(C),T.attr("cx",function(t){return _(t.date)}).attr("cy",function(t){return b(t.price)}),S.select(".line").attr("d",A),S.select(".axis--x").call(w),d.select(".zoom").call(O.transform,d3.zoomIdentity.scale(m/(t[1]-t[0])).translate(-t[0],0))}}function a(t){var e=o(t,2),n=e[0],r=e[1],a=i.a.sortedIndex(l,n),s=i.a.sortedIndex(l,r),u=f.slice(a,s);b.domain([.9995*d3.min(u),1.0005*d3.max(u)])}function s(){if(!d3.event.sourceEvent||"brush"!==d3.event.sourceEvent.type){var t=d3.event.transform;a(t.rescaleX(y).domain()),d.select(".axis--y").call(C),_.domain(t.rescaleX(y).domain()),S.select(".line").attr("d",A),T.attr("cx",function(t){return _(t.date)}).attr("cy",function(t){return b(t.price)}),S.select(".axis--x").call(w),j.select(".brush").call(E.move,_.range().map(t.invertX,t))}}var u=e.map(function(t){return{price:t.price,date:moment.utc(t.date).toDate(),action:t.action}}),c=t.map(function(t){return{price:t.close,date:moment.utc(t.start).toDate()}}),l=c.map(function(t){return+t.date}),f=c.map(function(t){return+t.price}),d=d3.select("#chart");d.attr("width",window.innerWidth-20);var p={top:20,right:20,bottom:110,left:40},h=n-p.top-p.bottom,v={top:n-70,right:20,bottom:30,left:40},m=+d.attr("width")-p.left-p.right,g=n-v.top-v.bottom,_=d3.scaleUtc().range([0,m]),y=d3.scaleUtc().range([0,m]),b=d3.scaleLinear().range([h,0]),x=d3.scaleLinear().range([g,0]),w=d3.axisBottom(_),k=d3.axisBottom(y),C=d3.axisLeft(b).ticks(n/50),E=d3.brushX().extent([[0,0],[m,g]]).on("brush end",r),O=d3.zoom().scaleExtent([1,100]).translateExtent([[0,0],[m,h]]).extent([[0,0],[m,h]]).on("zoom",s),A=d3.line().x(function(t){return _(t.date)}).y(function(t){return b(t.price)}),$=d3.line().x(function(t){return y(t.date)}).y(function(t){return x(t.price)});d.append("defs").append("clipPath").attr("id","clip").append("rect").attr("width",m).attr("height",h);var S=d.append("g").attr("class","focus").attr("transform","translate("+p.left+","+p.top+")"),j=d.append("g").attr("class","context").attr("transform","translate("+v.left+","+v.top+")");_.domain(d3.extent(c,function(t){return t.date})),b.domain([.99*d3.min(f),1.01*d3.max(f)]),y.domain(_.domain()),x.domain(b.domain()),S.append("path").datum(c).attr("class","line price").attr("d",A),S.append("g").attr("class","axis axis--x").attr("transform","translate(0,"+h+")").call(w),S.append("g").attr("class","axis axis--y").call(C),j.append("path").datum(c).attr("class","line").attr("d",$),j.append("g").attr("class","axis axis--x").attr("transform","translate(0,"+g+")").call(k);var T=d.append("g").attr("transform","translate("+p.left+","+p.top+")").selectAll("circle").data(u).enter().append("circle").attr("class",function(t){return t.action}).attr("cx",function(t){return _(t.date)}).attr("cy",function(t){return b(t.price)}).attr("r",5);j.append("g").selectAll("circle").data(u).enter().append("circle").attr("class",function(t){return t.action}).attr("cx",function(t){return y(t.date)}).attr("cy",function(t){return x(t.price)}).attr("r",3);j.append("g").attr("class","brush").call(E).call(E.move,_.range()),d.append("rect").attr("class","zoom").attr("width",m).attr("height",h).attr("transform","translate("+p.left+","+p.top+")").call(O)}},function(t,e,n){"use strict";n.d(e,"a",function(){return r});var r=function(t){d3.select("#chart").append("text").attr("class","message").attr("x",150).attr("y",150).text(t)}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),function(t){var e=n(4),r=n(23),i=n.n(r),o=n(34),a=n(7),s=n(24),u=n.n(s),c=n(33),l=n.n(c),f=n(26),d=n.n(f),p=n(27),h=n.n(p),v=n(28),m=n.n(v),g=n(25),_=n.n(g),y=n(29),b=n.n(y),x=n(30),w=n.n(x),k=n(31),C=n.n(k),E=n(32),O=n.n(E),A=n(6);e.a.use(o.a);var $=new o.a({mode:"hash",base:t,routes:[{path:"/",redirect:"/home"},{path:"/home",component:l.a},{path:"/backtest",component:u.a},{path:"/config",component:_.a},{path:"/data",component:d.a},{path:"/data/importer",component:h.a},{path:"/data/importer/import/:id",component:m.a},{path:"/live-gekkos",component:b.a},{path:"/live-gekkos/new",component:w.a},{path:"/live-gekkos/stratrunner/:id",component:C.a},{path:"/live-gekkos/watcher/:id",component:O.a}]});n.i(A.a)(),new e.a({router:$,store:a.a,el:"#app",render:function(t){return t(i.a)}})}.call(e,"/")},function(t,e,n){"use strict";var r=(n(4),n(22),n(75)),i=n(81),o=n(79),a=n(77),s=n(73);e.a=function(){n.i(r.a)(),n.i(i.a)(),n.i(o.a)(),n.i(a.a)(),n.i(s.a)()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"syncApiKeys",function(){return i}),n.d(e,"syncExchanges",function(){return o});var r=n(4),i=function(t,e){return r.a.set(t,"apiKeys",e),t},o=function(t,e){return r.a.set(t,"exchanges",e),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=function(){function t(t,e){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(t){i=!0,o=t}finally{try{!r&&s.return&&s.return()}finally{if(i)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),s=function(t){var e=t,n={};return e.forEach(function(t){n[t.slug]=n[t.slug]||{markets:{}},t.markets.forEach(function(e){var r=a(e.pair,2),i=r[0],o=r[1];n[t.slug].markets[i]=n[t.slug].markets[i]||[],n[t.slug].markets[i].push(o)}),n[t.slug].importable=!!t.providesFullHistory,n[t.slug].tradable=!!t.tradable,n[t.slug].requires=t.requires}),n},u=function(){n.i(r.a)("apiKeys",function(t,e){i.a.commit("syncApiKeys",e)}),n.i(r.a)("exchanges",function(t,e){i.a.commit("syncExchanges",s(e))})},c=function(){o.b.$on("apiKeys",function(t){i.a.commit("syncApiKeys",t.exchanges)})};e.a=function(){u(),c()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"addImport",function(){return i}),n.d(e,"syncImports",function(){return o}),n.d(e,"updateImport",function(){return a});var r=n(4),i=function(t,e){return t.imports.push(e),t},o=function(t,e){return t.imports=e,t},a=function(t,e){var n=t.imports.findIndex(function(t){return t.id===e.import_id}),i=t.imports[n];if(!i)return t;var o=r.a.util.extend(i,e.updates);return r.a.set(t.imports,n,o),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=function(){n.i(r.a)("imports",function(t,e){i.a.commit("syncImports",e)})},s=function(){o.b.$on("import_update",function(t){i.a.commit("updateImport",t)})};e.a=function(){a(),s()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"setGlobalWarning",function(){return i});var r=(n(4),n(3)),i=(n.n(r),function(t,e){return t.warnings[e.key]=e.value,t})},function(t,e,n){"use strict";var r=n(7),i=n(6),o=function(){i.b.$on("WS_STATUS_CHANGE",function(t){return r.a.commit("setGlobalWarning",{key:"connected",value:t.connected})})};e.a=function(){o()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"addStratrunner",function(){return i}),n.d(e,"syncStratrunners",function(){return o}),n.d(e,"updateStratrunner",function(){return a}),n.d(e,"addTradeToStratrunner",function(){return s}),n.d(e,"addRoundtripToStratrunner",function(){return u});var r=n(4),i=function(t,e){return t.stratrunners.push(e),t},o=function(t,e){return t.stratrunners=e,t},a=function(t,e){var n=t.stratrunners.findIndex(function(t){return t.id===e.gekko_id}),i=t.stratrunners[n];if(!i)return t;var o=r.a.util.extend(i,e.updates);return r.a.set(t.stratrunners,n,o),t},s=function(t,e){var n=t.stratrunners.findIndex(function(t){return t.id===e.gekko_id}),i=t.stratrunners[n];if(!i)return t;var o=r.a.util.extend({},i);return o.trades.push(e.trade),r.a.set(t.stratrunners,n,o),t},u=function(t,e){var n=t.stratrunners.findIndex(function(t){return t.id===e.gekko_id}),i=t.stratrunners[n];if(!i)return t;var o=r.a.util.extend({},i);return o.roundtrips.push(e.roundtrip),r.a.set(t.stratrunners,n,o),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=n(3),s=n.n(a),u=function(){n.i(r.a)("gekkos",function(t,e){var n=s.a.filter(e,{type:"leech"});i.a.commit("syncStratrunners",n)})},c=function(){o.b.$on("new_gekko",function(t){"leech"===t.gekko.type&&i.a.commit("addStratrunner",t.gekko)});var t=function(t){i.a.commit("updateStratrunner",t)},e=function(t){i.a.commit("addTradeToStratrunner",t)},n=function(t){i.a.commit("addRoundtripToStratrunner",t)};o.b.$on("report",t),o.b.$on("trade",e),o.b.$on("update",t),o.b.$on("startAt",t),o.b.$on("lastCandle",t),o.b.$on("firstCandle",t),o.b.$on("roundtrip",n)};e.a=function(){u(),c()}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),n.d(e,"addWatcher",function(){return i}),n.d(e,"syncWatchers",function(){return o}),n.d(e,"updateWatcher",function(){return a});var r=n(4),i=function(t,e){return t.watchers.push(e),t},o=function(t,e){return t.watchers=e,t},a=function(t,e){var n=t.watchers.findIndex(function(t){return t.id===e.gekko_id}),i=t.watchers[n];if(!i)return t;var o=r.a.util.extend(i,e.updates);return r.a.set(t.watchers,n,o),t}},function(t,e,n){"use strict";var r=n(2),i=n(7),o=n(6),a=n(3),s=n.n(a),u=function(){n.i(r.a)("gekkos",function(t,e){var n=s.a.filter(e,{type:"watcher"});i.a.commit("syncWatchers",n)})},c=function(){o.b.$on("new_gekko",function(t){"watcher"===t.gekko.type&&i.a.commit("addWatcher",t.gekko)});var t=function(t){i.a.commit("updateWatcher",t)};o.b.$on("update",t),o.b.$on("startAt",t),o.b.$on("lastCandle",t),o.b.$on("firstCandle",t)};e.a=function(){u(),c()}},function(t,e,n){function r(t){if(t)return i(t)}function i(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}t.exports=r,r.prototype.on=r.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},r.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var r,i=0;i4?t:document.documentMode}()},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"#chartWrapper.clickable{position:relative}#chartWrapper.clickable .shield{cursor:zoom-in;position:absolute;top:0;bottom:0;left:0;right:0;background:grey;opacity:.1}#chart{background-color:#eee;width:100%}#chart circle{clip-path:url(#clip)}#chart .zoom{cursor:move;fill:none;pointer-events:all}#chart .line{fill:none;stroke:#4682b4;stroke-width:1.5px;clip-path:url(#clip)}#chart circle.buy{fill:#7fff00}#chart circle.sell{fill:red}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".scan-btn{margin-top:80px;margin-bottom:30px}.radio label{margin-top:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".progressbarWrapper p{text-align:center;font-size:20px}.progressbar{background-color:hsla(0,0%,85%,.99);border-radius:13px;padding:0}@keyframes shimmer{0%{background-position:0 0}to{background-position:960px 0}}.progressbar>div{height:20px;border-radius:10px;background-color:orange;animation-duration:1.5s;animation-fill-mode:forwards;animation-iteration-count:infinite;animation-name:shimmer;animation-timing-function:linear;background:#f6f7f8;background:linear-gradient(90deg,orange 10%,#ffce77 25%,orange 40%);background-size:960px 50px;background-position:0;position:relative}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".summary td{text-align:right}.big{font-size:1.3em}.big,.summary table{width:80%}.price.profit{color:#7fff00}.price.loss{color:red}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".summary td{text-align:right}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".scan-btn{margin-top:80px;margin-bottom:30px}.radio label{margin-top:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".clickable{cursor:pointer}table.full{width:100%}table.full td{padding:.5rem 0}table.full.data th{text-align:left;padding:.5rem 0}.warning p{margin:0;padding:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".menu{display:flex;width:100%;flex-direction:row;margin-top:0;margin-bottom:2rem}.menu a{flex:1 1 100%;display:block;text-align:center;text-decoration:none;color:inherit}.menu .router-link-active{background-color:hsla(0,0%,98%,.99)}.menu a:hover{text-decoration:underline}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".contain{max-width:900px;margin-left:auto;margin-right:auto}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".spinner{margin:20px auto 100px;width:50px;height:40px;text-align:center;font-size:10px}.spinner>div{background-color:#333;height:100%;width:6px;display:inline-block;margin-right:4px;-webkit-animation:sk-stretchdelay 1.2s infinite ease-in-out;animation:sk-stretchdelay 1.2s infinite ease-in-out}.spinner .rect2{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.spinner .rect3{-webkit-animation-delay:-1s;animation-delay:-1s}.spinner .rect4{-webkit-animation-delay:-.9s;animation-delay:-.9s}.spinner .rect5{-webkit-animation-delay:-.8s;animation-delay:-.8s}@-webkit-keyframes sk-stretchdelay{0%,40%,to{-webkit-transform:scaleY(.4)}20%{-webkit-transform:scaleY(1)}}@keyframes sk-stretchdelay{0%,40%,to{transform:scaleY(.4);-webkit-transform:scaleY(.4)}20%{transform:scaleY(1);-webkit-transform:scaleY(1)}}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".radio label{margin-top:0}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"#app{display:flex;min-height:100vh;flex-direction:column}.fill{flex:1}.text{max-width:500px}input{background:none;margin-top:.5em}.params{min-height:235px;line-height:1.3em}.hr{margin-top:2rem;margin-bottom:2rem;height:10px;background-color:hsla(0,0%,98%,.99)}.btn--primary{display:inline-block;margin-right:12px;margin-bottom:12px;height:40px;padding:0 18px;border-radius:4px;text-shadow:0 1px 3px rgba(36,180,126,.4);box-shadow:0 4px 6px rgba(50,50,93,.11),0 1px 3px rgba(0,0,0,.08);line-height:40px;transition:transform .25s}.btn--primary,.btn--primary:hover{background-color:#3498db;color:#fff;text-decoration:none}.btn--primary:hover{transform:translateY(-1px);box-shadow:0 7px 14px rgba(50,50,93,.1),0 3px 6px rgba(0,0,0,.08)}.btn--primary:active,.btn--primary:focus{background-color:#3498db;color:#fff;text-decoration:none}.btn--primary:active{transform:translateY(1px)}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"table.clickable{border-collapse:separate}tr.clickable td:first-child{padding-left:5px}tr.clickable{cursor:pointer}tr.clickable:hover{background:hsla(0,0%,85%,.99)}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"td.radio{width:45px}td label{display:inline;font-size:1em}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"#modal-background{position:fixed;top:0;bottom:0;left:0;right:0;background-color:#000;opacity:.5}.modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:600px;min-height:300px;background-color:#fff}.modal-guts{position:absolute;top:0;left:0;width:100%;height:100%;padding:20px 50px 20px 20px;overflow:auto}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".align .custom-select select{padding:.4em 1.2em .3em .8em}.label-like{display:block;font-size:.9em;color:#777}.align{padding-left:1em}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".align .custom-select select{padding:.4em 1.2em .3em .8em}.label-like{display:block;font-size:.9em;color:#777}.align{padding-left:1em}",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,"",""])},function(t,e,n){e=t.exports=n(0)(),e.push([t.i,".roundtrips{margin-top:50px;margin-bottom:50px}.roundtrips table{width:100%}.roundtrips table td,.roundtrips table th{border:1px solid #c6cbd1;padding:8px 12px}.roundtrips table td.loss{color:red;text-align:right}.roundtrips table td.profit{color:green;text-align:right}.roundtrips table tr:nth-child(2n){background-color:#f6f8fa}",""])},function(t,e){t.exports={name:"gekko",version:"0.5.13",description:"A bitcoin trading bot for auto trading at various exchanges",keywords:["trading","bot","bitcoin","TA","finance"],scripts:{test:"./node_modules/.bin/mocha test/*.js --recursive test -u tdd --reporter spec",start:"node ./gekko --config config.js --ui"},author:"Mike van Rossum ",dependencies:{"@slack/client":"^3.10.0",async:"2.1.2",binance:"^1.3.1","bitcoin-co-id":"0.0.1",bitexthai:"^0.1.0","bitfinex-api-node":"^1.2.0",bitstamp:"^1.0.3",bitx:"^1.5.0","btc-china-fork":"0.0.6","btc-markets":"0.0.10",cexio:"0.0.x","co-fs":"^1.2.0",coinfalcon:"^1.0.3",commander:"^2.9.0",gdax:"^0.4.2",gekko:"0.0.9","gemini-exchange-coffee-api":"2.0.6","humanize-duration":"^3.10.0",koa:"^1.2.0","koa-bodyparser":"^2.2.0","koa-cors":"0.0.16","koa-logger":"^1.3.0","koa-router":"^5.4.0","koa-static":"^2.0.0","kraken-api-es5":"^1.0.0",lakebtc_nodejs:"0.1.x",lodash:"2.x",moment:"2.19.3","node-wex":"^1.0.3","node.bittrex.api":"^0.4.3","okcoin-china":"0.0.7",opn:"^4.0.2","poloniex.js":"0.0.7","promisify-node":"^0.4.0","prompt-lite":"0.1.1",pushbullet:"1.4.3",quadrigacx:"0.0.7",relieve:"^2.1.3",retry:"^0.10.1",semver:"5.4.1",sqlite3:"^3.1.13","stats-lite":"^2.0.4","tiny-promisify":"^0.1.1",toml:"^2.3.0",twitter:"^1.7.1","zaif.jp":"^0.1.4"},devDependencies:{chai:"^2.0.0",mocha:"^2.1.1",proxyquire:"^1.7.10",request:"^2.83.0","request-promise":"^4.2.2",sinon:"^1.12.2"},engines:{node:">=6.0"},license:"MIT",repository:{type:"git",url:"https://github.com/askmike/gekko.git"}}},function(t,e){t.exports={name:"vue",version:"0.2.0",description:"The frontend for the Gekko UI",author:"Mike van Rossum ",scripts:{dev:"cross-env NODE_ENV=development webpack-dev-server --open --inline --hot",build:"cross-env NODE_ENV=production webpack --progress --hide-modules"},devDependencies:{"babel-core":"^6.0.0","babel-loader":"^6.0.0","babel-preset-es2015":"^6.0.0","cross-env":"^3.0.0","css-loader":"^0.25.0","file-loader":"^0.9.0","json-loader":"^0.5.4",marked:"^0.3.6",superagent:"^2.3.0","superagent-no-cache":"uditalias/superagent-no-cache",vue:"^2.0.1","vue-loader":"^9.7.0","vue-router":"^2.0.3",vuex:"^2.2.1",webpack:"^2.1.0-beta.25","webpack-dev-server":"^2.1.0-beta.0"},dependencies:{jade:"^1.11.0"}}},function(t,e,n){(function(e){(function(){function e(t){this.tokens=[],this.tokens.links={},this.options=t||l.defaults,this.rules=f.normal,this.options.gfm&&(this.options.tables?this.rules=f.tables:this.rules=f.gfm)}function n(t,e){if(this.options=e||l.defaults,this.links=t,this.rules=d.normal,this.renderer=this.options.renderer||new r,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.gfm?this.options.breaks?this.rules=d.breaks:this.rules=d.gfm:this.options.pedantic&&(this.rules=d.pedantic)}function r(t){this.options=t||{}}function i(t){this.tokens=[],this.token=null,this.options=t||l.defaults,this.options.renderer=this.options.renderer||new r,this.renderer=this.options.renderer,this.renderer.options=this.options}function o(t,e){return t.replace(e?/&/g:/&(?!#?\w+;)/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function a(t){return t.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g,function(t,e){return e=e.toLowerCase(),"colon"===e?":":"#"===e.charAt(0)?"x"===e.charAt(1)?String.fromCharCode(parseInt(e.substring(2),16)):String.fromCharCode(+e.substring(1)):""})}function s(t,e){return t=t.source,e=e||"",function n(r,i){return r?(i=i.source||i,i=i.replace(/(^|[^\[])\^/g,"$1"),t=t.replace(r,i),n):new RegExp(t,e)}}function u(){}function c(t){for(var e,n,r=1;rAn error occured:

    "+o(t.message+"",!0)+"
    ";throw t}}var f={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:u,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:u,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:u,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};f.bullet=/(?:[*+-]|\d+\.)/,f.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,f.item=s(f.item,"gm")(/bull/g,f.bullet)(),f.list=s(f.list)(/bull/g,f.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+f.def.source+")")(),f.blockquote=s(f.blockquote)("def",f.def)(),f._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",f.html=s(f.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,f._tag)(),f.paragraph=s(f.paragraph)("hr",f.hr)("heading",f.heading)("lheading",f.lheading)("blockquote",f.blockquote)("tag","<"+f._tag)("def",f.def)(),f.normal=c({},f),f.gfm=c({},f.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/}),f.gfm.paragraph=s(f.paragraph)("(?!","(?!"+f.gfm.fences.source.replace("\\1","\\2")+"|"+f.list.source.replace("\\1","\\3")+"|")(),f.tables=c({},f.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/}),e.rules=f,e.lex=function(t,n){return new e(n).lex(t)},e.prototype.lex=function(t){return t=t.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(t,!0)},e.prototype.token=function(t,e,n){for(var r,i,o,a,s,u,c,l,d,t=t.replace(/^ +$/gm,"");t;)if((o=this.rules.newline.exec(t))&&(t=t.substring(o[0].length),o[0].length>1&&this.tokens.push({type:"space"})),o=this.rules.code.exec(t))t=t.substring(o[0].length),o=o[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?o:o.replace(/\n+$/,"")});else if(o=this.rules.fences.exec(t))t=t.substring(o[0].length),this.tokens.push({type:"code",lang:o[2],text:o[3]||""});else if(o=this.rules.heading.exec(t))t=t.substring(o[0].length),this.tokens.push({type:"heading",depth:o[1].length,text:o[2]});else if(e&&(o=this.rules.nptable.exec(t))){for(t=t.substring(o[0].length),u={type:"table",header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/\n$/,"").split("\n")},l=0;l ?/gm,""),this.token(o,e,!0),this.tokens.push({type:"blockquote_end"});else if(o=this.rules.list.exec(t)){for(t=t.substring(o[0].length),a=o[2],this.tokens.push({type:"list_start",ordered:a.length>1}),o=o[0].match(this.rules.item),r=!1,d=o.length,l=0;l1&&s.length>1||(t=o.slice(l+1).join("\n")+t,l=d-1)),i=r||/\n\n(?!\s*$)/.test(u),l!==d-1&&(r="\n"===u.charAt(u.length-1),i||(i=r)),this.tokens.push({type:i?"loose_item_start":"list_item_start"}),this.token(u,!1,n),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(o=this.rules.html.exec(t))t=t.substring(o[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===o[1]||"script"===o[1]||"style"===o[1]),text:o[0]});else if(!n&&e&&(o=this.rules.def.exec(t)))t=t.substring(o[0].length),this.tokens.links[o[1].toLowerCase()]={href:o[2],title:o[3]};else if(e&&(o=this.rules.table.exec(t))){for(t=t.substring(o[0].length),u={type:"table",header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/(?: *\| *)?\n$/,"").split("\n")},l=0;l])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:u,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:u,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/,d.link=s(d.link)("inside",d._inside)("href",d._href)(),d.reflink=s(d.reflink)("inside",d._inside)(),d.normal=c({},d),d.pedantic=c({},d.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/}),d.gfm=c({},d.normal,{escape:s(d.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:s(d.text)("]|","~]|")("|","|https?://|")()}),d.breaks=c({},d.gfm,{br:s(d.br)("{2,}","*")(),text:s(d.gfm.text)("{2,}","*")()}),n.rules=d,n.output=function(t,e,r){return new n(e,r).output(t)},n.prototype.output=function(t){for(var e,n,r,i,a="";t;)if(i=this.rules.escape.exec(t))t=t.substring(i[0].length),a+=i[1];else if(i=this.rules.autolink.exec(t))t=t.substring(i[0].length),"@"===i[2]?(n=":"===i[1].charAt(6)?this.mangle(i[1].substring(7)):this.mangle(i[1]),r=this.mangle("mailto:")+n):(n=o(i[1]),r=n),a+=this.renderer.link(r,null,n);else if(this.inLink||!(i=this.rules.url.exec(t))){if(i=this.rules.tag.exec(t))!this.inLink&&/^
    /i.test(i[0])&&(this.inLink=!1),t=t.substring(i[0].length),a+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(i[0]):o(i[0]):i[0];else if(i=this.rules.link.exec(t))t=t.substring(i[0].length),this.inLink=!0,a+=this.outputLink(i,{href:i[2],title:i[3]}),this.inLink=!1;else if((i=this.rules.reflink.exec(t))||(i=this.rules.nolink.exec(t))){if(t=t.substring(i[0].length),e=(i[2]||i[1]).replace(/\s+/g," "),!(e=this.links[e.toLowerCase()])||!e.href){a+=i[0].charAt(0),t=i[0].substring(1)+t;continue}this.inLink=!0,a+=this.outputLink(i,e),this.inLink=!1}else if(i=this.rules.strong.exec(t))t=t.substring(i[0].length),a+=this.renderer.strong(this.output(i[2]||i[1]));else if(i=this.rules.em.exec(t))t=t.substring(i[0].length),a+=this.renderer.em(this.output(i[2]||i[1]));else if(i=this.rules.code.exec(t))t=t.substring(i[0].length),a+=this.renderer.codespan(o(i[2],!0));else if(i=this.rules.br.exec(t))t=t.substring(i[0].length),a+=this.renderer.br();else if(i=this.rules.del.exec(t))t=t.substring(i[0].length),a+=this.renderer.del(this.output(i[1]));else if(i=this.rules.text.exec(t))t=t.substring(i[0].length),a+=this.renderer.text(o(this.smartypants(i[0])));else if(t)throw new Error("Infinite loop on byte: "+t.charCodeAt(0))}else t=t.substring(i[0].length),n=o(i[1]),r=n,a+=this.renderer.link(r,null,n);return a},n.prototype.outputLink=function(t,e){var n=o(e.href),r=e.title?o(e.title):null;return"!"!==t[0].charAt(0)?this.renderer.link(n,r,this.output(t[1])):this.renderer.image(n,r,o(t[1]))},n.prototype.smartypants=function(t){return this.options.smartypants?t.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014\/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014\/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):t},n.prototype.mangle=function(t){if(!this.options.mangle)return t;for(var e,n="",r=t.length,i=0;i.5&&(e="x"+e.toString(16)),n+="&#"+e+";";return n},r.prototype.code=function(t,e,n){if(this.options.highlight){var r=this.options.highlight(t,e);null!=r&&r!==t&&(n=!0,t=r)}return e?'
    '+(n?t:o(t,!0))+"\n
    \n":"
    "+(n?t:o(t,!0))+"\n
    "},r.prototype.blockquote=function(t){return"
    \n"+t+"
    \n"},r.prototype.html=function(t){return t},r.prototype.heading=function(t,e,n){return"'+t+"\n"},r.prototype.hr=function(){return this.options.xhtml?"
    \n":"
    \n"},r.prototype.list=function(t,e){var n=e?"ol":"ul";return"<"+n+">\n"+t+"\n"},r.prototype.listitem=function(t){return"
  • "+t+"
  • \n"},r.prototype.paragraph=function(t){return"

    "+t+"

    \n"},r.prototype.table=function(t,e){return"\n\n"+t+"\n\n"+e+"\n
    \n"},r.prototype.tablerow=function(t){return"\n"+t+"\n"},r.prototype.tablecell=function(t,e){var n=e.header?"th":"td";return(e.align?"<"+n+' style="text-align:'+e.align+'">':"<"+n+">")+t+"\n"},r.prototype.strong=function(t){return""+t+""},r.prototype.em=function(t){return""+t+""},r.prototype.codespan=function(t){return""+t+""},r.prototype.br=function(){return this.options.xhtml?"
    ":"
    "},r.prototype.del=function(t){return""+t+""},r.prototype.link=function(t,e,n){if(this.options.sanitize){try{var r=decodeURIComponent(a(t)).replace(/[^\w:]/g,"").toLowerCase()}catch(t){return""}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:"))return""}var i='
    "},r.prototype.image=function(t,e,n){var r=''+n+'":">"},r.prototype.text=function(t){return t},i.parse=function(t,e,n){return new i(e,n).parse(t)},i.prototype.parse=function(t){this.inline=new n(t.links,this.options,this.renderer),this.tokens=t.reverse();for(var e="";this.next();)e+=this.tok();return e},i.prototype.next=function(){return this.token=this.tokens.pop()},i.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},i.prototype.parseText=function(){for(var t=this.token.text;"text"===this.peek().type;)t+="\n"+this.next().text;return this.inline.output(t)},i.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var t,e,n,r,i="",o="";for(n="",t=0;t=300)&&(r=new Error(e.statusText||"Unsuccessful HTTP response"),r.original=t,r.response=e,r.status=e.status)}catch(t){r=t}r?n.callback(r,e):n.callback(null,e)})}function p(t,e){var n=_("DELETE",t);return e&&n.end(e),n}var h;"undefined"!=typeof window?h=window:"undefined"!=typeof self?h=self:(console.warn("Using browser-only version of superagent in non-browser environment"),h=this);var v=n(82),m=n(117),g=n(15),_=t.exports=n(118).bind(null,d);_.getXHR=function(){if(!(!h.XMLHttpRequest||h.location&&"file:"==h.location.protocol&&h.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(t){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(t){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(t){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(t){}throw Error("Browser-only verison of superagent could not find XHR")};var y="".trim?function(t){return t.trim()}:function(t){return t.replace(/(^\s*|\s*$)/g,"")};_.serializeObject=i,_.parseString=a,_.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},_.serialize={"application/x-www-form-urlencoded":i,"application/json":JSON.stringify},_.parse={"application/x-www-form-urlencoded":a,"application/json":JSON.parse},f.prototype.get=function(t){return this.header[t.toLowerCase()]},f.prototype._setHeaderProperties=function(t){var e=this.header["content-type"]||"";this.type=c(e);var n=l(e);for(var r in n)this[r]=n[r]},f.prototype._parseBody=function(t){var e=_.parse[this.type];return!e&&u(this.type)&&(e=_.parse["application/json"]),e&&t&&(t.length||t instanceof Object)?e(t):null},f.prototype._setStatusProperties=function(t){1223===t&&(t=204);var e=t/100|0;this.status=this.statusCode=t,this.statusType=e,this.info=1==e,this.ok=2==e,this.clientError=4==e,this.serverError=5==e,this.error=(4==e||5==e)&&this.toError(),this.accepted=202==t,this.noContent=204==t,this.badRequest=400==t,this.unauthorized=401==t,this.notAcceptable=406==t,this.notFound=404==t,this.forbidden=403==t},f.prototype.toError=function(){var t=this.req,e=t.method,n=t.url,r="cannot "+e+" "+n+" ("+this.status+")",i=new Error(r);return i.status=this.status,i.method=e,i.url=n,i},_.Response=f,v(d.prototype);for(var b in m)d.prototype[b]=m[b];d.prototype.type=function(t){return this.set("Content-Type",_.types[t]||t),this},d.prototype.responseType=function(t){return this._responseType=t,this},d.prototype.accept=function(t){return this.set("Accept",_.types[t]||t),this},d.prototype.auth=function(t,e,n){switch(n||(n={type:"basic"}),n.type){case"basic":var r=btoa(t+":"+e);this.set("Authorization","Basic "+r);break;case"auto":this.username=t,this.password=e}return this},d.prototype.query=function(t){return"string"!=typeof t&&(t=i(t)),t&&this._query.push(t),this},d.prototype.attach=function(t,e,n){return this._getFormData().append(t,e,n||e.name),this},d.prototype._getFormData=function(){return this._formData||(this._formData=new h.FormData),this._formData},d.prototype.callback=function(t,e){var n=this._callback;this.clearTimeout(),n(t,e)},d.prototype.crossDomainError=function(){var t=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");t.crossDomain=!0,t.status=this.status,t.method=this.method,t.url=this.url,this.callback(t)},d.prototype._timeoutError=function(){var t=this._timeout,e=new Error("timeout of "+t+"ms exceeded");e.timeout=t,this.callback(e)},d.prototype._appendQueryString=function(){var t=this._query.join("&");t&&(this.url+=~this.url.indexOf("?")?"&"+t:"?"+t)},d.prototype.end=function(t){var e=this,n=this.xhr=_.getXHR(),i=this._timeout,o=this._formData||this._data;this._callback=t||r,n.onreadystatechange=function(){if(4==n.readyState){var t;try{t=n.status}catch(e){t=0}if(0==t){if(e.timedout)return e._timeoutError();if(e._aborted)return;return e.crossDomainError()}e.emit("end")}};var a=function(t,n){n.total>0&&(n.percent=n.loaded/n.total*100),n.direction=t,e.emit("progress",n)};if(this.hasListeners("progress"))try{n.onprogress=a.bind(null,"download"),n.upload&&(n.upload.onprogress=a.bind(null,"upload"))}catch(t){}if(i&&!this._timer&&(this._timer=setTimeout(function(){e.timedout=!0,e.abort()},i)),this._appendQueryString(),this.username&&this.password?n.open(this.method,this.url,!0,this.username,this.password):n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof o&&!this._isHost(o)){var s=this._header["content-type"],c=this._serializer||_.serialize[s?s.split(";")[0]:""];!c&&u(s)&&(c=_.serialize["application/json"]),c&&(o=c(o))}for(var l in this.header)null!=this.header[l]&&n.setRequestHeader(l,this.header[l]);return this._responseType&&(n.responseType=this._responseType),this.emit("request",this),n.send(void 0!==o?o:null),this},_.Request=d,_.get=function(t,e,n){var r=_("GET",t);return"function"==typeof e&&(n=e,e=null),e&&r.query(e),n&&r.end(n),r},_.head=function(t,e,n){var r=_("HEAD",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.options=function(t,e,n){var r=_("OPTIONS",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.del=p,_.delete=p,_.patch=function(t,e,n){var r=_("PATCH",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.post=function(t,e,n){var r=_("POST",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r},_.put=function(t,e,n){var r=_("PUT",t);return"function"==typeof e&&(n=e,e=null),e&&r.send(e),n&&r.end(n),r}},function(t,e,n){var r=n(15);e.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},e.parse=function(t){return this._parser=t,this},e.serialize=function(t){return this._serializer=t,this},e.timeout=function(t){return this._timeout=t,this},e.then=function(t,e){if(!this._fullfilledPromise){var n=this;this._fullfilledPromise=new Promise(function(t,e){n.end(function(n,r){n?e(n):t(r)})})}return this._fullfilledPromise.then(t,e)},e.catch=function(t){return this.then(void 0,t)},e.use=function(t){return t(this),this},e.get=function(t){return this._header[t.toLowerCase()]},e.getHeader=e.get,e.set=function(t,e){if(r(t)){for(var n in t)this.set(n,t[n]);return this}return this._header[t.toLowerCase()]=e,this.header[t]=e,this},e.unset=function(t){return delete this._header[t.toLowerCase()],delete this.header[t],this},e.field=function(t,e){if(null===t||void 0===t)throw new Error(".field(name, val) name can not be empty");if(r(t)){for(var n in t)this.field(n,t[n]);return this}if(null===e||void 0===e)throw new Error(".field(name, val) val can not be empty");return this._getFormData().append(t,e),this},e.abort=function(){return this._aborted?this:(this._aborted=!0,this.xhr&&this.xhr.abort(),this.req&&this.req.abort(),this.clearTimeout(),this.emit("abort"),this)},e.withCredentials=function(){return this._withCredentials=!0,this},e.redirects=function(t){return this._maxRedirects=t,this},e.toJSON=function(){return{method:this.method,url:this.url,data:this._data,headers:this._header}},e._isHost=function(t){switch({}.toString.call(t)){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}},e.send=function(t){var e=r(t),n=this._header["content-type"];if(e&&r(this._data))for(var i in t)this._data[i]=t[i];else"string"==typeof t?(n||this.type("form"),n=this._header["content-type"],this._data="application/x-www-form-urlencoded"==n?this._data?this._data+"&"+t:t:(this._data||"")+t):this._data=t;return!e||this._isHost(t)?this:(n||this.type("json"),this)}},function(t,e){function n(t,e,n){return"function"==typeof n?new t("GET",e).end(n):2==arguments.length?new t("GET",e):new t(e,n)}t.exports=n},function(t,e,n){var r,i;n(191),r=n(36);var o=n(163);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(170),r=n(39);var o=n(140);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(169),r=n(41);var o=n(139);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(189),r=n(42);var o=n(161);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(175),r=n(45);var o=n(145);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(190),r=n(48);var o=n(162);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(182),r=n(54);var o=n(154);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;r=n(55);var o=n(151);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(179),r=n(61);var o=n(150);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(167),r=n(63);var o=n(134);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;r=n(64);var o=n(138);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(176),r=n(65);var o=n(146);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e,n){var r,i;n(184),r=n(67);var o=n(156);i=r=r||{},"object"!=typeof r.default&&"function"!=typeof r.default||(i=r=r.default),"function"==typeof i&&(i=i.options),i.render=o.render,i.staticRenderFns=o.staticRenderFns,t.exports=r},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{class:{clickable:!t.isClicked},attrs:{id:"chartWrapper"}},[n("div",{staticClass:"shield",on:{click:function(e){e.preventDefault(),t.click(e)}}}),n("svg",{attrs:{id:"chart",width:"960",height:t.height}})])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Daterange")]),n("div",[n("label",{attrs:{for:"from"}},[t._v("From")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.from,expression:"from"}],domProps:{value:t.from},on:{input:function(e){e.target.composing||(t.from=e.target.value)}}})]),n("div",[n("label",{attrs:{for:"to"}},[t._v("To")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.to,expression:"to"}],domProps:{value:t.to},on:{input:function(e){e.target.composing||(t.to=e.target.value)}}})])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.progress?n("div",{staticClass:"progressbarWrapper"},[n("p",[n("strong",[t._v(t._s(t.round(t.progress))+"%")])]),n("div",{staticClass:"progressbar"},[n("div",{style:{width:t.progress+"%"}})])]):t._e()},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{staticClass:"mx1"},[n("label",{staticClass:"wrapper",attrs:{for:"exchange"}},[t._v("Exchange:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.exchange,expression:"exchange"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.exchange=e.target.multiple?n:n[0]}}},t._l(t.exchanges,function(e,r){return n("option",[t._v(t._s(r))])}))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("label",{attrs:{for:"currency"}},[t._v("Currency:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.currency,expression:"currency"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.currency=e.target.multiple?n:n[0]}}},t._l(t.currencies,function(e){return n("option",[t._v(t._s(e))])}))])]),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("label",{attrs:{for:"asset"}},[t._v("Asset:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.asset,expression:"asset"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.asset=e.target.multiple?n:n[0]}}},t._l(t.assets,function(e){return n("option",[t._v(t._s(e))])}))])])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-3-6"},[n("table",{staticClass:"p1"},[n("tr",[n("th",[t._v("amount of trades")]),n("td",[t._v(t._s(t.report.trades))])]),n("tr",[n("th",[t._v("sharpe ratio")]),n("td",[t._v(t._s(t.round2(t.report.sharpe)))])]),n("tr",[n("th",[t._v("start balance")]),n("td",[t._v(t._s(t.round(t.report.startBalance))+" "+t._s(t.report.currency))])]),n("tr",[n("th",[t._v("final balance")]),n("td",[t._v(t._s(t.round(t.report.balance))+" "+t._s(t.report.currency))])]),t._m(0)]),n("div",{staticClass:"big txt--right price",class:t.profitClass},[t._v(t._s(t.round(t.report.relativeProfit))+"%")])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("tr",[n("th",[t._v("simulated profit")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("h2",[t._v("Config")]),n("div",{staticClass:"hr"}),n("h3",[t._v("Available API keys")]),t.apiKeySets.length?t._e():n("p",[n("em",[t._v("You don't have any API keys yet.")])]),n("ul",t._l(t.apiKeySets,function(e){return n("li",[t._v(t._s(e)+" ("),n("a",{attrs:{href:"#"},on:{click:function(n){n.preventDefault(),t.removeApiKey(e)}}},[t._v("remove")]),t._v(")")])})),t.addApiToggle?t._e():n("a",{staticClass:"btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.openAddApi(e)}}},[t._v("Add an API key")]),t.addApiToggle?[n("div",{staticClass:"hr"}),n("apiConfigBuilder")]:t._e(),n("div",{staticClass:"hr"})],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("footer",{staticClass:"p2 bg--off-white"},[n("div",{staticClass:"contain"},[t._m(0),n("p",[t._v("Using Gekko v"+t._s(t.version.gekko)+" and Gekko UI v"+t._s(t.version.ui)+".")])])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("p",[n("em",[t._v("Use Gekko at your own risk.")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("div",{staticClass:"grd-row summary"},[n("div",{staticClass:"grd-row-col-3-6"},[n("table",{staticClass:"p1"},[n("tr",[n("th",[t._v("start time")]),n("td",[t._v(t._s(t.report.startTime))])]),n("tr",[n("th",[t._v("end time")]),n("td",[t._v(t._s(t.report.endTime))])]),n("tr",[n("th",[t._v("timespan")]),n("td",[t._v(t._s(t.report.timespan))])]),n("tr",[n("th",[t._v("start price")]),n("td",[t._v(t._s(t.round(t.report.startPrice))+" "+t._s(t.report.currency))])]),n("tr",[n("th",[t._v("end price")]),n("td",[t._v(t._s(t.round(t.report.endPrice))+" "+t._s(t.report.currency))])]),n("tr",[n("th",[t._v("market")]),n("td",[t._v(t._s(t.round(t.report.market))+"%")])])])]),n("paperTradeSummary",{attrs:{report:t.report}})],1)])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{staticClass:"hr contain"}),t._m(0),n("result-summary",{attrs:{report:t.result.report}}),n("div",{staticClass:"hr contain"}),n("chart",{attrs:{data:t.result,height:"500"}}),n("div",{staticClass:"hr contain"}),n("roundtripTable",{attrs:{roundtrips:t.result.roundtrips}})],1)},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("h3",[t._v("Backtest result")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain my2"},[n("h3",[t._v("Start a new gekko")]),n("gekko-config-builder",{on:{config:t.updateConfig}}),n("div",{staticClass:"hr"}),t.config.valid?n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.start(e)}}},[t._v("Start")])]):t._e()],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain my2"},[n("div",{staticClass:"text",domProps:{innerHTML:t._s(t.intro)}}),n("div",{staticClass:"hr"}),n("h3",[t._v("Currently running imports")]),0===t.imports.length?n("p",[t._v("You currently don't have any imports running.")]):t._e(),t.imports.length?n("ul",t._l(t.imports,function(e){return n("li",[n("router-link",{attrs:{to:"/data/importer/import/"+e.id}},[t._v(t._s(e.watch.exchange)+":"+t._s(e.watch.currency)+"/"+t._s(e.watch.asset))])],1)})):t._e(),n("div",{staticClass:"hr"}),n("h3",[t._v("Start a new import")]),n("import-config-builder",{on:{config:t.updateConfig}}),n("div",{staticClass:"hr"}),n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.run(e)}}},[t._v("Import")])])],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Daterange")]),"scan"===t.tab?[t.scanned?t._e():n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s btn--primary scan-btn",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("Scan available data")])]),"fetching"==t.scanned?n("div",{staticClass:"txt--center"},[n("p",{staticClass:"scan-btn"},[t._v("Scanning..")])]):t._e(),1==t.scanned?[0===t.ranges.length?[n("p",[n("strong",[t._v('Unable to find any local data, do you have local data available for\n"'+t._s(t.config.watch.exchange)+":"+t._s(t.config.watch.currency)+"/"+t._s(t.config.watch.asset)+'"?')])])]:[n("label",{staticClass:"wrapper",attrs:{for:"exchange"}},[t._v("Run simulation over:")]),n("form",{staticClass:"radio grd"},t._l(t.ranges,function(e,r){return n("div",{staticClass:"grd-row m1"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.selectedRangeIndex,expression:"selectedRangeIndex"}],staticClass:"grd-row-col-1-6",attrs:{type:"radio"},domProps:{value:r,checked:t._q(t.selectedRangeIndex,r)},on:{__c:function(e){t.selectedRangeIndex=r}}}),n("label",{staticClass:"grd-row-col-5-6",attrs:{for:r}},[t._v(t._s(t.printRange(e)))])])}))],n("p",[n("em",[n("a",{attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("rescan")])])])]:t._e(),n("p",{staticClass:"txt--center"},[n("em",[n("a",{attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.tab="manual"}}},[t._v("Or manually set a daterange")])])])]:t._e(),"manual"===t.tab?[n("div",[n("label",{attrs:{for:"from"}},[t._v("From:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.from,expression:"from"}],domProps:{value:t.from},on:{input:function(e){e.target.composing||(t.from=e.target.value)}}})]),n("div",[n("label",{attrs:{for:"to"}},[t._v("To:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.to,expression:"to"}],domProps:{value:t.to},on:{input:function(e){e.target.composing||(t.to=e.target.value)}}})]),n("p",{staticClass:"txt--center"}),n("em",[n("a",{attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.tab="scan"}}},[t._v("Or scan for a daterange")])])]:t._e()],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("div",{staticClass:"text",domProps:{innerHTML:t._s(t.intro)}}),n("div",{staticClass:"hr"}),n("h2",[t._v("Available datasets")]),"idle"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("a",{staticClass:"w100--s btn--primary scan-btn",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("Scan available data")])]):t._e(),"scanning"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("spinner")],1):t._e(),"scanned"===t.datasetScanstate?n("div",{staticClass:"my2"},[t.unscannableMakets.length?n("div",{staticClass:"bg--orange p1 warning my1"},[t.viewUnscannable?t._e():n("p",{staticClass:"clickable",on:{click:function(e){e.preventDefault(),t.toggleUnscannable(e)}}},[t._v("Some markets were unscannable, click here for details.")]),t.viewUnscannable?[n("p",[t._v("Unable to find datasets in the following markets:")]),t._l(t.unscannableMakets,function(e){return n("div",{staticClass:"mx2"},[t._v("- "+t._s(e.exchange)+":"+t._s(e.currency)+":"+t._s(e.asset))])})]:t._e()],2):t._e(),t.datasets.length?[n("table",{staticClass:"full data"},[t._m(0),n("tbody",t._l(t.datasets,function(e){return n("tr",[n("td",[t._v(t._s(e.exchange))]),n("td",[t._v(t._s(e.currency))]),n("td",[t._v(t._s(e.asset))]),n("td",[t._v(t._s(t.fmt(e.from)))]),n("td",[t._v(t._s(t.fmt(e.to)))]),n("td",[t._v(t._s(t.humanizeDuration(e.to.diff(e.from))))])])}))])]:t._e(),t.datasets.length?t._e():[n("p",[t._v("It looks like you don't have any local data yet.")])]],2):t._e(),n("div",{staticClass:"my2"},[n("h2",[t._v("Import more data")]),n("p",{staticClass:"text"},[t._v("You can easily import more market data directly from exchanges using the importer.")]),n("router-link",{staticClass:"btn--primary",attrs:{to:"/data/importer"}},[t._v("Go to the importer!")])],1)])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("from")]),n("th",[t._v("to")]),n("th",[t._v("duration")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd contain"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Market")]),n("market-picker",{staticClass:"contain",attrs:{"only-importable":"true"},on:{market:t.updateMarketConfig}})],1),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("range-creator",{on:{range:t.updateRange}})],1)])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{attrs:{id:"top"}}),t._m(0),n("nav",{staticClass:"bg--light-gray"},[n("div",{staticClass:"menu contain"},[n("router-link",{staticClass:"py1",attrs:{to:"/home"}},[t._v("Home")]),n("router-link",{staticClass:"py1",attrs:{to:"/live-gekkos"}},[t._v("Live Gekkos")]),n("router-link",{staticClass:"py1",attrs:{to:"/backtest"}},[t._v("Backtest")]),n("router-link",{staticClass:"py1",attrs:{to:"/data"}},[t._v("Local data")]),n("router-link",{staticClass:"py1",attrs:{to:"/config"}},[t._v("Config")]),n("a",{staticClass:"py1",attrs:{href:"https://gekko.wizb.it/docs/introduction/about_gekko.html",target:"_blank"}},[t._v("Documentation")])],1)])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("header",{staticClass:"bg--off-white grd"},[n("div",{staticClass:"contain grd-row"},[n("h3",{staticClass:"py1 px2 col-2"},[t._v("Gekko UI")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{staticClass:"contain grd-row"},[n("div",{staticClass:"grd-row-col-3-6",domProps:{innerHTML:t._s(t.left)}}),n("div",{staticClass:"grd-row-col-3-6 txt--center"},[n("img",{attrs:{src:t.imageUrl}}),t._m(0)])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("p",[n("em",[t._v("The most valuable commodity I know of is information.")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h2",{staticClass:"contain"},[t._v("Backtest")]),n("div",{staticClass:"hr contain"}),n("config-builder",{on:{config:t.check}}),t.backtestable?n("div",[n("div",{staticClass:"txt--center"},["fetching"!==t.backtestState?n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.run(e)}}},[t._v("Backtest")]):t._e(),"fetching"===t.backtestState?n("div",{staticClass:"scan-btn"},[n("p",[t._v("Running backtest..")]),n("spinner")],1):t._e()])]):t._e(),t.backtestResult&&"fetched"===t.backtestState?n("result",{attrs:{result:t.backtestResult}}):t._e()],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement;t._self._c;return t._m(0)},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"spinner"},[n("div",{staticClass:"rect1"}),n("div",{staticClass:"rect2"}),n("div",{staticClass:"rect3"}),n("div",{staticClass:"rect4"})])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Type")]),[n("label",{staticClass:"wrapper",attrs:{for:"type"}},[t._v("What do you want to do with gekko?")]),n("form",{staticClass:"radio grd"},t._l(t.types,function(e,r){return n("div",{staticClass:"grd-row m1"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.selectedTypeIndex,expression:"selectedTypeIndex"}],staticClass:"grd-row-col-1-6",attrs:{type:"radio"},domProps:{value:r,checked:t._q(t.selectedTypeIndex,r)},on:{__c:function(e){t.selectedTypeIndex=r}}}),n("label",{staticClass:"grd-row-col-5-6",attrs:{for:r}},[t._v(t._s(e))])])}))]],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("div",{staticClass:"mx1"},[n("label",{staticClass:"wrapper",attrs:{for:"exchange"}},[t._v("Exchange:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.exchange,expression:"exchange"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.exchange=e.target.multiple?n:n[0]}}},t._l(t.exchanges,function(e,r){return n("option",[t._v(t._s(r))])}))])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"app"}},[n("top"),n("div",{staticClass:"fill"},[n("router-view",{staticClass:"view"})],1),n("bottom"),n("modal")],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain py2"},[n("div",{staticClass:"text",domProps:{innerHTML:t._s(t.text)}}),n("div",{staticClass:"hr"}),n("h3",[t._v("Market watchers")]),t.watchers.length?t._e():n("div",{staticClass:"text"},[n("p",[t._v("You are currently not watching any markets.")])]),t.watchers.length?n("table",{staticClass:"full clickable"},[t._m(0),n("tbody",t._l(t.watchers,function(e){return n("tr",{staticClass:"clickable",on:{click:function(n){t.$router.push({path:"live-gekkos/watcher/"+e.id})}}},[n("td",[t._v(t._s(e.watch.exchange))]),n("td",[t._v(t._s(e.watch.currency))]),n("td",[t._v(t._s(e.watch.asset))]),n("td",[e.firstCandle?[t._v(t._s(t.fmt(e.firstCandle.start)))]:t._e()],2),n("td",[e.lastCandle?[t._v(t._s(t.fmt(e.lastCandle.start)))]:t._e()],2),n("td",[e.firstCandle&&e.lastCandle?[t._v(t._s(t.timespan(e.lastCandle.start,e.firstCandle.start)))]:t._e()],2)])}))]):t._e(),n("h3",[t._v("Strat runners")]),t.stratrunners.length?t._e():n("div",{staticClass:"text"},[n("p",[t._v("You are currently not running any strategies.")])]),t.stratrunners.length?n("table",{staticClass:"full"},[t._m(1),n("tbody",t._l(t.stratrunners,function(e){return n("tr",{staticClass:"clickable",on:{click:function(n){t.$router.push({path:"live-gekkos/stratrunner/"+e.id})}}},[n("td",[t._v(t._s(e.watch.exchange))]),n("td",[t._v(t._s(e.watch.currency))]),n("td",[t._v(t._s(e.watch.asset))]),n("td",[e.lastCandle?[t._v(t._s(t.fmt(e.lastCandle.start)))]:t._e()],2),n("td",[e.firstCandle&&e.lastCandle?[t._v(t._s(t.timespan(e.lastCandle.start,e.firstCandle.start)))]:t._e()],2),n("td",[t._v(t._s(e.strat.name))]),n("td",[e.report?t._e():[t._v("0")],e.report?[t._v(t._s(t.round(e.report.profit))+" "+t._s(e.watch.currency))]:t._e()],2)])}))]):t._e(),n("div",{staticClass:"hr"}),n("h2",[t._v("Start a new live Gekko")]),n("router-link",{staticClass:"btn--primary",attrs:{to:"/live-gekkos/new"}},[t._v("Start a new live Gekko!")])],1)},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("started at")]),n("th",[t._v("last update")]),n("th",[t._v("duration")])])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("last update")]),n("th",[t._v("duration")]),n("th",[t._v("strategy")]),n("th",[t._v("profit")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("h3",[t._v("Select a dataset")]),"idle"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("a",{staticClass:"w100--s btn--primary scan-btn",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.scan(e)}}},[t._v("Scan available data")])]):t._e(),"scanning"===t.datasetScanstate?n("div",{staticClass:"txt--center my2"},[n("spinner")],1):t._e(),"scanned"===t.datasetScanstate?n("div",{staticClass:"my2"},[0!=t.datasets.length?n("div",[n("table",{staticClass:"full"},[t._m(0),n("tbody",t._l(t.datasets,function(e,r){return n("tr",[n("td",{staticClass:"radio"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.setIndex,expression:"setIndex"}],attrs:{type:"radio",name:"dataset",id:e.id},domProps:{value:r,checked:t._q(t.setIndex,r)},on:{__c:function(e){t.setIndex=r}}})]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(e.exchange))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(e.currency))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(e.asset))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(t.fmt(e.from)))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(t.fmt(e.to)))])]),n("td",[n("label",{attrs:{for:e.id}},[t._v(t._s(t.humanizeDuration(e.to.diff(e.from))))])])])}))]),t.rangeVisible?t._e():n("a",{staticClass:"btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.openRange(e)}}},[t._v("Adjust range")]),t.rangeVisible?[n("div",[n("label",{attrs:{for:"customFrom"}},[t._v("From:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.customFrom,expression:"customFrom"}],domProps:{value:t.customFrom},on:{input:function(e){e.target.composing||(t.customFrom=e.target.value)}}})]),n("div",[n("label",{attrs:{for:"customTo"}},[t._v("To:")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.customTo,expression:"customTo"}],domProps:{value:t.customTo},on:{input:function(e){e.target.composing||(t.customTo=e.target.value)}}})])]:t._e()],2):n("em",[t._v("No Data found "),n("a",{attrs:{href:"#/data/importer"}},[t._v("Lets add some")])])]):t._e()])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("thead",[n("tr",[n("th"),n("th",[t._v("exchange")]),n("th",[t._v("currency")]),n("th",[t._v("asset")]),n("th",[t._v("from")]),n("th",[t._v("to")]),n("th",[t._v("duration")])])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"my2"},[t.data?t._e():n("div",{staticClass:"contain"},[n("h1",[t._v("Unknown Strat runner")]),n("p",[t._v("Gekko doesn't know what strat runner this is...")])]),t.data?n("div",[n("h2",{staticClass:"contain"},[t._v("Strat runner")]),n("div",{staticClass:"grd contain"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Market")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Exchange")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.data.watch.exchange))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Currency")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Asset")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.data.watch.asset))])])]),n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Runtime")]),t.isLoading?n("spinner"):t._e(),t.isLoading?t._e():[t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Watching since")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.firstCandle.start)))])]):t._e(),t.data.lastCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Received data until")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.lastCandle.start)))])]):t._e(),t.data.lastCandle&&t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Data spanning")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.humanizeDuration(t.moment(t.data.lastCandle.start).diff(t.moment(t.data.firstCandle.start)))))])]):t._e(),t.data.lastCandle&&t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Amount of trades")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.trades.length))])]):t._e()]],2)]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Strategy")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Name")]),n("div",{staticClass:"grd-row-col-3-6"},[n("strong",[t._v(t._s(t.stratName))])])]),t._v("Parameters"),n("pre",[t._v(t._s(t.stratParams))])]),n("div",{staticClass:"grd-row-col-3-6"},[n("h3",[t._v("Profit report")]),t.report?t._e():[t._m(0)],t.report?[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Start balance")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.startBalance)))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Current balance")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.balance)))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Market")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.market))+" "+t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Profit")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.profit))+" "+t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[t._v("Alpha")]),n("div",{staticClass:"grd-row-col-3-6"},[t._v(t._s(t.round(t.report.alpha))+" "+t._s(t.data.watch.currency))])])]:t._e()],2)]),t.watcher?n("p",[n("em",[t._v("This strat runner gets data from "),n("router-link",{attrs:{to:"/live-gekkos/watcher/"+t.watcher.id}},[t._v("this market watcher")])],1),t._v(".")]):t._e()]),t.isLoading?t._e():[n("h3",{staticClass:"contain"},[t._v("Market graph")]),"fetching"===t.candleFetch?n("spinner"):t._e(),"fetched"===t.candleFetch?[n("chart",{attrs:{data:t.chartData,height:300}})]:t._e(),n("roundtrips",{attrs:{roundtrips:t.data.roundtrips}})]],2):t._e()])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("p",[n("em",[t._v("Waiting for at least one trade..")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.active?n("div",[n("div",{attrs:{id:"modal-background"}}),n("div",{staticClass:"modal",attrs:{id:"modal"}},[n("div",{staticClass:"modal-guts",domProps:{innerHTML:t._s(t.content)}})])]):t._e()},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd"},[n("div",{staticClass:"px1"},[n("h3",[t._v("Paper trader")]),"closed"===t.toggle?n("a",{staticClass:"btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.switchToggle(e)}}},[t._v("Change paper trader settings")]):t._e(),"open"===t.toggle?[n("p",[t._v("Settings:")]),n("textarea",{directives:[{name:"model",rawName:"v-model",value:t.rawPaperTraderParams,expression:"rawPaperTraderParams"}],staticClass:"params",domProps:{value:t.rawPaperTraderParams},on:{input:function(e){e.target.composing||(t.rawPaperTraderParams=e.target.value)}}}),t.rawPaperTraderParamsError?n("p",{staticClass:"bg--red p1"},[t._v(t._s(t.rawPaperTraderParamsError.message))]):t._e()]:t._e()],2)])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain my2"},[t.data&&!t.data.done?n("div",[n("h2",[t._v("Importing data..")]),n("div",{staticClass:"grd"},[n("div",{staticClass:"grd-row"},[t._m(0),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.exchange))])]),n("div",{staticClass:"grd-row"},[t._m(1),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.currency)+"/"+t._s(t.data.watch.asset))])])]),n("div",{staticClass:"grd"},[n("div",{staticClass:"grd-row"},[t._m(2),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.from)))])]),n("div",{staticClass:"grd-row"},[t._m(3),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.to)))])]),t.initialized?n("div",{staticClass:"grd-row"},[t._m(4),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.latest)))])]):t._e(),t.initialized?n("div",{staticClass:"grd-row"},[t._m(5),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fromEnd))])]):t._e()]),t.initialized?t._e():n("spinner"),t.initialized?n("div",{staticClass:"contain"},[n("progressBar",{attrs:{progress:t.progress}})],1):t._e(),n("p",[n("em",[t._v("(you don't have to wait until the import is done,\nyou can already start "),n("router-link",{attrs:{to:"/backtest"}},[t._v("backtesting")]),t._v(").")],1)])],1):t._e(),t.data&&t.data.done?n("div",{staticClass:"txt--center"},[n("h2",[t._v("Import done")]),n("p",[t._v(" \nGo and "),n("router-link",{attrs:{to:"/backtest"}},[t._v("backtest")]),t._v(" with your new data!")],1)]):t._e(),t.data?t._e():n("div",{staticClass:"txt--center"},[n("h2",[t._v("ERROR: Uknown import")]),n("p",[n("I",[t._v("don't know this import..")])],1)])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Market:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Currency/Asset:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("From:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("To:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Imported data until:")])])},function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd-row-col-2-6"},[n("strong",[t._v("Remaining:")])])}]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 px1"},[n("h3",[t._v("Strategy")]),n("div",[n("label",{staticClass:"wrapper",attrs:{for:"strat"}},[t._v("Strategy:")]),n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.strategy,expression:"strategy"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.strategy=e.target.multiple?n:n[0]}}},t._l(t.strategies,function(e){return n("option",[t._v(t._s(e.name))])}))])]),n("div",[n("label",{attrs:{for:"candleSize"}},[t._v("Candle Size")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6"},[n("input",{directives:[{name:"model",rawName:"v-model",value:t.rawCandleSize,expression:"rawCandleSize"}],domProps:{value:t.rawCandleSize},on:{input:function(e){e.target.composing||(t.rawCandleSize=e.target.value)}}})]),n("div",{staticClass:"grd-row-col-3-6 align"},[n("div",{staticClass:"custom-select button"},[n("select",{directives:[{name:"model",rawName:"v-model",value:t.candleSizeUnit,expression:"candleSizeUnit"}],on:{change:function(e){var n=Array.prototype.filter.call(e.target.options,function(t){return t.selected}).map(function(t){return"_value"in t?t._value:t.value});t.candleSizeUnit=e.target.multiple?n:n[0]}}},[n("option",[t._v("minutes")]),n("option",[t._v("hours")]),n("option",[t._v("days")])])])])])]),n("div",[n("label",{attrs:{for:"historySize"}},[t._v("Warmup period (in "+t._s(t.rawCandleSize)+" "+t._s(t.singularCandleSizeUnit)+" candles):")]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.historySize,expression:"historySize"}],domProps:{value:t.historySize},on:{input:function(e){e.target.composing||(t.historySize=e.target.value)}}}),n("em",{staticClass:"label-like"},[t._v("(will use "+t._s(t.humanizeDuration(t.candleSize*t.historySize*1e3*60))+" of data as history)")])])]),n("div",{staticClass:"grd-row-col-2-6 px1"},[n("div",[n("h3",[t._v("Parameters")]),n("p",[t._v(t._s(t.strategy)+" Parameters:")]),n("textarea",{directives:[{name:"model",rawName:"v-model",value:t.rawStratParams,expression:"rawStratParams"}],staticClass:"params",domProps:{value:t.rawStratParams},on:{input:function(e){e.target.composing||(t.rawStratParams=e.target.value)}}}),t.rawStratParamsError?n("p",{staticClass:"bg--red p1"},[t._v(t._s(t.rawStratParamsError.message))]):t._e()])])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"my2"},[t.data?t._e():n("div",{staticClass:"contain"},[n("h1",[t._v("Unknown Watcher")]),n("p",[t._v("Gekko doesn't know what whatcher this is...")])]),t.data?n("div",[n("h2",{staticClass:"contain"},[t._v("Market Watcher")]),n("div",{staticClass:"grd contain"},[n("h3",[t._v("Market")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Exchange")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.exchange))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Currency")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.currency))])]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Asset")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.data.watch.asset))])]),n("h3",[t._v("Statistics")]),t.isLoading?n("spinner"):t._e(),t.isLoading?t._e():[t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Watching since")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.firstCandle.start)))])]):t._e(),t.data.lastCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Received data until")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.fmt(t.data.lastCandle.start)))])]):t._e(),t.data.lastCandle&&t.data.firstCandle?n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-2-6"},[t._v("Data spanning")]),n("div",{staticClass:"grd-row-col-4-6"},[t._v(t._s(t.humanizeDuration(t.moment(t.data.lastCandle.start).diff(t.moment(t.data.firstCandle.start)))))])]):t._e()]],2),t.isLoading?t._e():[n("h3",{staticClass:"contain"},[t._v("Market graph")]),"fetching"===t.candleFetch?n("spinner"):t._e(),t.candles.length?[n("chart",{attrs:{data:t.chartData,height:500}})]:t._e()]],2):t._e()])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd contain"},[n("h3",[t._v("Add an API key")]),n("p",[t._v("Make sure that the API key has the permissions to create and cancel orders and view balances.")]),n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Exchange")]),n("exchange-picker",{staticClass:"contain",attrs:{"only-tradable":"true"},on:{exchange:t.updateExchange}})],1),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Credentials")]),t._l(t.requires,function(e){return[n("label",[t._v(t._s(e))]),n("input",{directives:[{name:"model",rawName:"v-model",value:t.credentials[e],expression:"credentials[cred]"}],domProps:{value:t.credentials[e]},on:{input:function(n){n.target.composing||t.$set(t.credentials,e,n.target.value)}}})]})],2)]),n("div",{staticClass:"txt--center"},[n("a",{staticClass:"w100--s my1 btn--primary",attrs:{href:"#"},on:{click:function(e){e.preventDefault(),t.upload(e)}}},[t._v("Add")])])])},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"grd contain"},[n("div",{staticClass:"grd-row"},[n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("h3",[t._v("Market")]),n("market-picker",{staticClass:"contain",attrs:{"only-tradable":t.isTradebot},on:{market:t.updateMarketConfig}})],1),n("div",{staticClass:"grd-row-col-3-6 mx1"},[n("type-picker",{on:{type:t.updateType}})],1)]),"market watcher"!==t.type?[n("div",{staticClass:"hr"}),n("strat-picker",{staticClass:"contain my2",on:{stratConfig:t.updateStrat}}),"paper trader"===t.type?n("div",{staticClass:"hr"}):t._e(),"paper trader"===t.type?n("paper-trader",{on:{settings:t.updatePaperTrader}}):t._e()]:t._e()],2)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain"},[n("dataset-picker",{staticClass:"contain my2",on:{dataset:t.updateDataset}}),n("div",{staticClass:"hr"}),n("strat-picker",{staticClass:"contain my2",on:{stratConfig:t.updateStrat}}),n("div",{staticClass:"hr"}),n("paper-trader",{on:{settings:t.updatePaperTrader}}),n("div",{staticClass:"hr"})],1)},staticRenderFns:[]}},function(t,e){t.exports={render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"contain roundtrips"},[n("h2",[t._v("Roundtrips")]),t.roundtrips.length?n("table",[n("thead",[t._m(0),t._l(t.roundtrips,function(e){return n("tr",[n("td",[t._v(t._s(t.fmt(e.entryAt)))]),n("td",[t._v(t._s(t.fmt(e.exitAt)))]),n("td",[t._v(t._s(t.diff(e.duration)))]),n("td",[t._v(t._s(t.round(e.entryBalance)))]),n("td",[t._v(t._s(t.round(e.exitBalance)))]),-1===Math.sign(e.pnl)?[n("td",{staticClass:"loss"},[t._v(t._s(Math.sign(e.pnl)*e.pnl.toFixed(2)))]),n("td",{staticClass:"loss"},[t._v(t._s(e.profit.toFixed(2))+"%")])]:[n("td",{staticClass:"profit"},[t._v(t._s(e.pnl.toFixed(2)))]),n("td",{staticClass:"profit"},[t._v(t._s(e.profit.toFixed(2))+"%")])]],2)})],2)]):t._e(),t.roundtrips.length?t._e():n("div",[n("p",[t._v("Not enough data to display")])])])},staticRenderFns:[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("tr",[n("th",[t._v("Entry at (UTC)")]),n("th",[t._v("Exit at (UTC)")]),n("th",[t._v("Exposure")]),n("th",[t._v("Entry balance")]),n("th",[t._v("Exit balance")]),n("th",[t._v("P&L")]),n("th",[t._v("Profit")])])}]}},function(t,e,n){var r=n(84);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(85);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(86);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(87);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(88);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(89);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(90);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(91);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(92);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(93);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(94);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(95);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(96);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(97);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(98);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(99);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(100);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(101);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(102);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(103);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(104);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(105);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(106);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(107);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(108);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(109);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(110);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e,n){var r=n(111);"string"==typeof r&&(r=[[t.i,r,""]]);n(1)(r,{});r.locals&&(t.exports=r.locals)},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),t.webpackPolyfill=1),t}}]); \ No newline at end of file diff --git a/web/vue/src/components/data/import/importer.vue b/web/vue/src/components/data/import/importer.vue index fe575fad0..3d070c1c1 100644 --- a/web/vue/src/components/data/import/importer.vue +++ b/web/vue/src/components/data/import/importer.vue @@ -7,7 +7,7 @@ ul(v-if='imports.length') li(v-for='_import in imports') router-link(:to='"/data/importer/import/" + _import.id') {{ _import.watch.exchange }}:{{ _import.watch.currency }}/{{ _import.watch.asset }} - + .hr h3 Start a new import import-config-builder(v-on:config='updateConfig') @@ -64,6 +64,13 @@ export default { if(daysApart < 1) return alert('You can only import at least one day of data..') + let exchange = this.$store.state.exchanges[this.config.watch.exchange]; + if ("exchangeMaxHistoryAge" in exchange) { + if (moment(this.config.importer.daterange.from) < moment().subtract(exchange.exchangeMaxHistoryAge, "days")) { + return alert('Your date from is too old for ' + this.config.watch.exchange + '. It supports only the last ' + exchange.exchangeMaxHistoryAge + ' days..'); + } + } + post('import', this.config, (error, response) => { if(error) return alert(error); diff --git a/web/vue/src/components/gekko/singleStratrunner.vue b/web/vue/src/components/gekko/singleStratrunner.vue index 153c24241..6910337bf 100644 --- a/web/vue/src/components/gekko/singleStratrunner.vue +++ b/web/vue/src/components/gekko/singleStratrunner.vue @@ -202,7 +202,7 @@ export default { this.candleFetch = 'fetched'; // todo if(!res || res.error || !_.isArray(res)) - console.log(res); + return console.log(res); this.candles = res.map(c => { c.start = moment.unix(c.start).utc().format(); diff --git a/web/vue/src/components/layout/home.vue b/web/vue/src/components/layout/home.vue index 933d339b9..3dba02dfa 100644 --- a/web/vue/src/components/layout/home.vue +++ b/web/vue/src/components/layout/home.vue @@ -2,13 +2,14 @@ section.contain.grd-row .grd-row-col-3-6(v-html='left') .grd-row-col-3-6.txt--center - img(src='./assets/gekko.jpg') + img(:src='imageUrl') p em The most valuable commodity I know of is information. diff --git a/web/vue/src/store/modules/config/sync.js b/web/vue/src/store/modules/config/sync.js index 5bb447ac3..9a3b0d689 100644 --- a/web/vue/src/store/modules/config/sync.js +++ b/web/vue/src/store/modules/config/sync.js @@ -15,6 +15,10 @@ const transformMarkets = backendData => { exchangesTemp[e.slug].markets[currency].push( asset ); }); + if ("exchangeMaxHistoryAge" in e) { + exchangesTemp[e.slug].exchangeMaxHistoryAge = e.exchangeMaxHistoryAge; + } + exchangesTemp[e.slug].importable = e.providesFullHistory ? true : false; exchangesTemp[e.slug].tradable = e.tradable ? true : false; exchangesTemp[e.slug].requires = e.requires; @@ -43,4 +47,4 @@ const sync = () => { export default function() { init(); sync(); -} \ No newline at end of file +} diff --git a/web/vue/src/tools/api.js b/web/vue/src/tools/api.js index 7027e0a01..6bc1a1473 100644 --- a/web/vue/src/tools/api.js +++ b/web/vue/src/tools/api.js @@ -1,20 +1,28 @@ // global window.CONFIG const config = window.CONFIG.ui; -const host = `${config.host}${config.port === 80 ? '' : `:${config.port}`}${config.path}api/`; +const endpoint = `${config.host}${config.port === 80 ? '' : `:${config.port}`}${config.path}`; + +let basePath, restPath, wsPath; // rest API path if(config.ssl) { - var restPath = `https://${host}`; + basePath = `https://${endpoint}`; } else { - var restPath = `http://${host}`; + basePath = `http://${endpoint}`; } +restPath = basePath + 'api/'; + // ws API path if(config.ssl) { - var wsPath = `wss://${host}`; + wsPath = `wss://${endpoint}/api`; } else { - var wsPath = `ws://${host}`; + wsPath = `ws://${endpoint}/api`; } -export {wsPath,restPath}; +export { + wsPath, + restPath, + basePath +};