问题在技术上是关于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值为&gt;而不是其紧接的先例值
一个新的卖出条件:当实际的macddiff值为&lt;而不是其紧接的先例值
例如,假设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,但是......不幸的是我无法理解它。
提前致谢!
答案 0 :(得分:0)
/*
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;