DeviaVir / zenbot

Zenbot is a command-line cryptocurrency trading bot using Node.js and MongoDB.
MIT License
8.23k stars 2.03k forks source link

ta_ema broken. Promise.all() not being used correctly. #1501

Open travisstaloch opened 6 years ago

travisstaloch commented 6 years ago

System information

Describe the problem

Command above produces 3 consecutive errors (below) and then the second error before darwin exits.

Source code / Error logs

TypeError: Cannot read property 'selector' of undefined at processOutput (E:\Users\Travis\Documents\Code\zenbot-unstable\scripts\genetic_backtester\darwin.js:501:24) ... TypeError: Cannot read property 'replace' of undefined at generateCommandParams (E:\Users\Travis\Documents\Code\zenbot-unstable\scripts\genetic_backtester\darwin.js:1130:24)

Solution

  1. The result of Promise.all() is an array. It is being treated as if it is an object. Actually the first element [0] of the result is the object expected, the result of ta_ema.
  2. After fixing 1, there are still intermittent "Cannot read property 'selector' of undefined" errors which cause darwin to get stuck on a sim and it never completes. The solution to this is to put the rest of the body of onPeriod into the Promise.all().then() block to make sure its being executed after ta_ema completes. This is illustrated by: Promise.all([console.log('1')]).then(() => console.log('2')); console.log('3'); which produces output: 1 3 2 and shows that Promise.all() isn't blocking.

Here is a working portion of strategies/ta_ema/strategy.js lines replacing lines 51-81.

    // wait for promise to be resolved
    // we add all maybe we need more indicators
    Promise.all([ta_ema(s, s.options.trend_ema)])
      .then(([result1]) => {
        if (result1 && result1.outReal) {
          s.period.trend_ema = result1.outReal
        }
      })
      .then(result => {
        // calculate ema rate
        if (s.period.trend_ema && s.lookback[0] && s.lookback[0].trend_ema) {
          s.period.trend_ema_rate = (s.period.trend_ema - s.lookback[0].trend_ema) / s.lookback[0].trend_ema * 100
        }

        if (typeof s.period.trend_ema_stddev === 'number') {
          if (s.period.trend_ema_rate > s.period.trend_ema_stddev) {
            if (s.trend !== 'up') {
              s.acted_on_trend = false
            }
            s.trend = 'up'
            s.signal = !s.acted_on_trend ? 'buy' : null
            s.cancel_down = false
          } else if (!s.cancel_down && s.period.trend_ema_rate < s.period.trend_ema_stddev * -1) {
            if (s.trend !== 'down') {
              s.acted_on_trend = false
            }
            s.trend = 'down'
            s.signal = !s.acted_on_trend ? 'sell' : null
          }
        }
        cb()
      })
      .catch(err => {
        console.error(err)
        cb()
      })

Sorry I'm still working on being able to use git and make a pull request.

travisstaloch commented 6 years ago

@DeviaVir @Haehnchen I wanted to make sure you see this since you guys worked on #1383 .

Also, I was wrong. Darwin is still getting stuck once in a while (around 1 in every 100 sims hang). There is no error, just 1 progress indicator stops and I have to manually kill that process so that darwin can continue.

travisstaloch commented 6 years ago

Also, i forgot that I had made a change to /lib/ta_ema.js line 60:

} else resolve()

Otherwise, the sim hangs at startup and never progresses.

After this change I am able to run the command

node zenbot.js sim gdax.LTC-USD --period_length=29m --min_periods=26 --markdown_buy_pct=1.271754225045159 --markup_sell_pct=1.8058192494168712 --order_type=taker --sell_stop_pct=9 --buy_stop_pct=21 --profit_stop_enable_pct=0 --profit_stop_pct=9 --trend_ema=33 --oversold_rsi_periods=42 --oversold_rsi=27 --backtester_generation=2 --strategy=ta_ema --days=2

Now I get output showing it completed and made 3 trades.