diff --git a/config/default.yaml b/config/default.yaml index 81b4287..f9dff29 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -110,7 +110,7 @@ LTC-USD: only_when_trend_is_full: true post_only: true cancel_after: min - below_midmarket: 0.005 + below_midmarket: 0.001 spread_n: 3 spread_v: 0.01 sell: diff --git a/lib/bot.js b/lib/bot.js index c468758..779c52d 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -187,7 +187,6 @@ class GDAXBot extends TradingBot { self.my_buy_data_by_id[data.id] = data; eventEmitter.emit('buy_confirmed', data); log.info(process.pid, 'BUY CONFIRMED', data); - } }); } diff --git a/lib/terminal.js b/lib/terminal.js index 87b28c1..a32b305 100644 --- a/lib/terminal.js +++ b/lib/terminal.js @@ -21,6 +21,8 @@ if (settings.get('general.log')) { var theme = require(`../themes/${settings.get('general.terminal.theme')}.json`); var product_ids = settings.get('general.product_ids'); var trades = {}; +var initial_profit_sn = undefined; +var initial_profit_wf = undefined; product_ids.forEach((product_id) => { trades[product_id] = []; @@ -211,6 +213,28 @@ function account (data) { { misc_x = calc_x + Math.max(calc_sell_now_length, calc_wait_fill_length, calc_fees_length); } + + + // Account Profits + options.x = misc_x; + options.y = 1; + let profits = `Profits (${settings.get('account.initial_investment')}): `; + options.attr = theme.account.title; + b_account.put(options, profits); + + options.x = misc_x + profits.length; + let profit_wait_fill_label = 'Wait Fill: '; + options.attr = theme.account.label; + b_account.put(options, profit_wait_fill_label); + + let profit_wait_fill = parseFloat(parseFloat(parseFloat(data.account.balance) + parseFloat(data.calculations.wait_fill) - parseFloat(settings.get('account.initial_investment'))).toFixed(2)); + if (initial_profit_wf === undefined) + initial_profit_wf = profit_wait_fill; + profit_wait_fill_percentage = (((profit_wait_fill / initial_profit_wf) - 1) * 100).toFixed(4); + + options.x = options.x + profit_wait_fill_label.length; + options.attr = theme.account.standard; + b_account.put(options, `${profit_wait_fill} (${profit_wait_fill_percentage} %; this run)`); } // Account Misc diff --git a/main.js b/main.js index aa5bae1..f2ad96a 100644 --- a/main.js +++ b/main.js @@ -346,7 +346,7 @@ function open_websocket() { fees: sell_now_sum * .003, } - orders_cache = []; + // orders_cache = []; getting_orders = false; } } else { diff --git a/strategies/trendlines.js b/strategies/trendlines.js new file mode 100644 index 0000000..a232892 --- /dev/null +++ b/strategies/trendlines.js @@ -0,0 +1,115 @@ +'use strict'; + +const settings = require('config'); +const stats = require('stats-lite'); + + + +class TrendLines { + constructor() { + this.trade_prices = []; + } + + add(add) { + if (typeof add !== 'object') + throw new Error(`The parameter 'add' should be an object; not a ${typeof add}.`); + + if (add.trades) + this.addTrades(add.trades); + } + + addTrades(trades) { + for (let trade in trades) { + // console.log('add trade price:', parseFloat(trades[trade].price.toString())) + this.trade_prices.push(parseFloat(trades[trade].toString())); + + while (this.trade_prices.length > settings.get(`${this.product_id}.strategies.StdDev.trades_n`)) { + this.trade_prices.shift(); + } + } + } + + generateDummyData(product_id, count) { + const uuidv4 = require('uuid/v4'); + + this.set({ + product_id: product_id + }); + + count = count || settings.get(`${this.product_id}.strategies.StdDev.trades_n`); + + let dummy_data = []; + let starting_id = Math.ceil(Math.random() * 100); + let starting_price = 0; + + switch (this.product_id) { + case 'BTC-USD': + starting_price = Math.random() * 10000; + case 'ETH-USD': + starting_price = Math.random() * 1000; + case 'LTC-USD': + starting_price = Math.random() * 100; + } + + for (let i = 0; i < count; i++) { + dummy_data.push(parseFloat((Math.floor(Math.random() * 2) ? starting_price + Math.random() * 2 : starting_price + Math.random() * 2)).toFixed(2)); + } + + this.add({ + trades: dummy_data + }); + } + + get() { + let strategy = { + stddev: stats.stdev(this.trade_prices), + mean: stats.mean(this.trade_prices), + last_trade_price: this.trade_prices[this.trade_prices.length - 1], + trades_n: this.trade_prices.length, + } + + strategy.diff_price_and_mean = strategy.last_trade_price - strategy.mean; + strategy.direction = (Math.abs(strategy.diff_price_and_mean) === strategy.diff_price_and_mean) ? 'Up' : 'Down'; + + // Only change directions if we exceed the stddev; positive or negative. + if ( + (Math.abs(strategy.diff_price_and_mean) > strategy.stddev) + && (Math.abs(strategy.diff_price_and_mean) === strategy.diff_price_and_mean) + ) { + this.trending_up = true; + } else if ( + (Math.abs(strategy.diff_price_and_mean) > strategy.stddev) + && (Math.abs(strategy.diff_price_and_mean) !== strategy.diff_price_and_mean) + ) { + this.trending_up = false; //literally: direction down + } + + strategy.is_trending_up = this.trending_up; + + // Buy as long as the overall direction is up. + strategy.should_buy = this.trending_up; + + return strategy; + } + + set(set) { + if (typeof set !== 'object') + throw new Error(`The parameter 'set' should be an object; not a ${typeof set}.`); + + if ('product_id' in set) + { + if (typeof set.product_id !== 'string') + throw new Error(`The parameter 'set.product_id' should be a string; not a ${typeof set.product_id}.`); + + if (settings.get('general.product_ids').indexOf(set.product_id) === -1) + throw new Error(`The parameter 'set.product_id' is not valid (${set.product_id}); should be one of: ${settings.get('general.product_ids')}.`); + + + this.product_id = set.product_id + } + } +} + +module.exports = StdDev; + +// const stddev = require('./strategies/stddev.js') \ No newline at end of file