【问题标题】:Simple node.js modification, how to determine if a variable is increasing or decreasing?简单的node.js修改,如何判断一个变量是递增还是递减?
【发布时间】:2018-06-02 07:58:53
【问题描述】:

问题在技术上是关于 Javascript (node.js),特别是使用它编码的 Gekko 软件。我正在尝试对其其中一个交易策略进行非常简单的修改:the MACD。涉及的文件有:

MACD配置文件:gekko/config/strategies/MACD.toml

short = 10
long = 21
signal = 9

[thresholds]
down = -0.025
up = 0.025
persistence = 1

MACD 指标文件:gekko/strategies/indicators/MACD.js

// required indicators
var EMA = require('./EMA.js');

var Indicator = function(config) {
  this.input = 'price';
  this.diff = false;
  this.short = new EMA(config.short);
  this.long = new EMA(config.long);
  this.signal = new EMA(config.signal);
}

Indicator.prototype.update = function(price) {
  this.short.update(price);
  this.long.update(price);
  this.calculateEMAdiff();
  this.signal.update(this.diff);
  this.result = this.diff - this.signal.result;
}

Indicator.prototype.calculateEMAdiff = function() {
  var shortEMA = this.short.result;
  var longEMA = this.long.result;

  this.diff = shortEMA - longEMA;
}

module.exports = Indicator;

最后,要修改的文件,MACD 策略:gekko/strategies/MACD.js

/*

  MACD - DJM 31/12/2013

  (updated a couple of times since, check git history)

 */

// helpers
var _ = require('lodash');
var log = require('../core/log.js');

// let's create our own method
var method = {};

// prepare everything our method needs
method.init = function() {
  // keep state about the current trend
  // here, on every new candle we use this
  // state object to check if we need to
  // report it.
  this.trend = {
    direction: 'none',
    duration: 0,
    persisted: false,
    adviced: false
  };

  // how many candles do we need as a base
  // before we can start giving advice?
  this.requiredHistory = this.tradingAdvisor.historySize;

  // define the indicators we need
  this.addIndicator('macd', 'MACD', this.settings);
}

// what happens on every new candle?
method.update = function(candle) {
  // nothing!
}

// for debugging purposes: log the last calculated
// EMAs and diff.
method.log = function() {
  var digits = 8;
  var macd = this.indicators.macd;

  var diff = macd.diff;
  var signal = macd.signal.result;

  log.debug('calculated MACD properties for candle:');
  log.debug('\t', 'short:', macd.short.result.toFixed(digits));
  log.debug('\t', 'long:', macd.long.result.toFixed(digits));
  log.debug('\t', 'macd:', diff.toFixed(digits));
  log.debug('\t', 'signal:', signal.toFixed(digits));
  log.debug('\t', 'macdiff:', macd.result.toFixed(digits));
}

method.check = function() {
  var macddiff = this.indicators.macd.result;

  if(macddiff > this.settings.thresholds.up) {

    // new trend detected
    if(this.trend.direction !== 'up')
      // reset the state for the new trend
      this.trend = {
        duration: 0,
        persisted: false,
        direction: 'up',
        adviced: false
      };

    this.trend.duration++;

    log.debug('In uptrend since', this.trend.duration, 'candle(s)');

    if(this.trend.duration >= this.settings.thresholds.persistence)
      this.trend.persisted = true;

    if(this.trend.persisted && !this.trend.adviced) {
      this.trend.adviced = true;
      this.advice('long');
    } else
      this.advice();

  } else if(macddiff < this.settings.thresholds.down) {

    // new trend detected
    if(this.trend.direction !== 'down')
      // reset the state for the new trend
      this.trend = {
        duration: 0,
        persisted: false,
        direction: 'down',
        adviced: false
      };

    this.trend.duration++;

    log.debug('In downtrend since', this.trend.duration, 'candle(s)');

    if(this.trend.duration >= this.settings.thresholds.persistence)
      this.trend.persisted = true;

    if(this.trend.persisted && !this.trend.adviced) {
      this.trend.adviced = true;
      this.advice('short');
    } else
      this.advice();

  } else {

    log.debug('In no trend');

    // we're not in an up nor in a downtrend
    // but for now we ignore sideways trends
    //
    // read more @link:
    //
    // https://github.com/askmike/gekko/issues/171

    // this.trend = {
    //   direction: 'none',
    //   duration: 0,
    //   persisted: false,
    //   adviced: false
    // };

    this.advice();
  }
}

module.exports = method;

当所有这些条件都成立时,此 MACD 策略建议买入:

  • macddiff > this.settings.thresholds.up
  • this.trend.duration >= this.settings.thresholds.persistence

当相反的情况发生时建议卖出:

  • macddiff this.settings.thresholds.up
  • this.trend.duration >= this.settings.thresholds.persistence


好的,我需要的修改是:

  • 一个新的买入条件:当实际的 macddiff 值 > 大于它的前一个值时

  • 一个新的卖出条件:当实际的 macddiff 值


例如,假设 15 分钟的蜡烛棒:

2018/06/12 00:00        macddiff = 5.3452
2018/06/12 00:15        macddiff = 7.5891 ----> **BUY**, because 7.5891 > 5.3452
2018/06/12 00:30        macddiff = 8.4982
2018/06/12 00:45        macddiff = 10.4389
2018/06/12 01:00        macddiff = 4.2340 ----> **SELL**, because 4.2340 < 10.4389
2018/06/12 01:15        macddiff = -2.4902
2018/06/12 01:30        macddiff = -1.9049 ---> **BUY**, because -1.9049 > -2.490

如何做到这一点?必须对gekko/strategies/MACD.js 文件进行哪些修改?请提供完整的文件和完整的修改。


This another answer in the Gekko forum 可能是 util,但是......不幸的是我无法正确理解它。

提前致谢!

【问题讨论】:

    标签: javascript node.js gekko


    【解决方案1】:
    /*
      MACD - DJM 31/12/2013 LUCCHI 07/06/2018
      (updated a couple of times since, check git history)
     */
    
    // helpers
    var _ = require('lodash');
    var log = require('../core/log.js');
    
    // let's create our own method
    var method = {};
    
    // prepare everything our method needs
    method.init = function() {
      // keep state about the current trend
      // here, on every new candle we use this
      // state object to check if we need to
      // report it.
      this.trend = {
        direction: 'none',
        duration: 0,
        persisted: false,
        adviced: false
      };
    
      // how many candles do we need as a base
      // before we can start giving advice?
      this.requiredHistory = this.tradingAdvisor.historySize;
    
      // define the indicators we need
      this.addIndicator('macd', 'MACD', this.settings);
    }
    
    // what happens on every new candle?
    method.update = function(candle) {
      // nothing!
    }
    
    // for debugging purposes: log the last calculated
    // EMAs and diff.
    method.log = function() {
      var digits = 8;
      var macd = this.indicators.macd;
    
      var diff = macd.diff;
      var signal = macd.signal.result;
    
      log.debug('calculated MACD properties for candle:');
      log.debug('\t', 'short:', macd.short.result.toFixed(digits));
      log.debug('\t', 'long:', macd.long.result.toFixed(digits));
      log.debug('\t', 'macd:', diff.toFixed(digits));
      log.debug('\t', 'signal:', signal.toFixed(digits));
      log.debug('\t', 'macdiff:', macd.result.toFixed(digits));
    }
    
    var macddiffLastValue // ADDED THIS LINE recipient for last value
    
    method.check = function() {
      var macddiff = this.indicators.macd.result;
    
      if(macddiff > macddiffLastValue) { // Modified Check
    
        // new trend detected
        if(this.trend.direction !== 'up')
          // reset the state for the new trend
          this.trend = {
            duration: 0,
            persisted: false,
            direction: 'up',
            adviced: false
          };
    
        this.trend.duration++;
    
        log.debug('In uptrend since', this.trend.duration, 'candle(s)');
    
        if(this.trend.duration >= this.settings.thresholds.persistence)
          this.trend.persisted = true;
    
        if(this.trend.persisted && !this.trend.adviced) {
          this.trend.adviced = true;
          this.advice('long');
        } else
          this.advice();
    
      } else if(macddiff < this.settings.thresholds.down) {
    
        // new trend detected
        if(this.trend.direction !== 'down')
          // reset the state for the new trend
          this.trend = {
            duration: 0,
            persisted: false,
            direction: 'down',
            adviced: false
          };
    
        this.trend.duration++;
    
        log.debug('In downtrend since', this.trend.duration, 'candle(s)');
    
        if(this.trend.duration >= this.settings.thresholds.persistence)
          this.trend.persisted = true;
    
        if(this.trend.persisted && !this.trend.adviced) {
          this.trend.adviced = true;
          this.advice('short');
        } else
          this.advice();
    
      } else {
    
        log.debug('In no trend');
    
        // we're not in an up nor in a downtrend
        // but for now we ignore sideways trends
        //
        // read more @link:
        //
        // https://github.com/askmike/gekko/issues/171
    
        // this.trend = {
        //   direction: 'none',
        //   duration: 0,
        //   persisted: false,
        //   adviced: false
        // };
    
        this.advice();
      }
      macddiffLastValue = macddiff // ADDED THIS LINE keep last value
    }
    
    module.exports = method;
    

    【讨论】:

    • 非常感谢 lucchi 的关注、时间和帮助。不幸的是,似乎不起作用,使用您的修改,我得到了与正常 MACD 策略相同的回测结果。此外,卖空/卖出策略似乎不完整。
    • @vicmarto,正如你在代码中看到的,我修改了卖出策略检查,如下:“我想修改这个策略”,在“相反的卖空/卖出”之后。看完之后,我必须承认,这张支票可能毫无意义。使用修改后的购买策略尝试我的编辑。
    • 非常感谢。我已经尝试了您的最后一次代码修改,购买似乎没有得到预期的结果。为了更好地理解,我稍微修改了我的问题。请看一下,我想现在清楚多了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多