|
var util = require('../../core/util'); |
|
var _ = require('lodash'); |
|
var fs = require('fs'); |
|
var toml = require('toml'); |
|
|
|
var config = util.getConfig(); |
|
var dirs = util.dirs(); |
|
var log = require(dirs.core + 'log'); |
|
|
|
|
|
var moment = require('moment'); |
|
var isLeecher = config.market && config.market.type === 'leech'; |
|
|
|
var Actor = function(done) { |
|
_.bindAll(this); |
|
|
|
this.done = done; |
|
|
|
methodName = config.tradingAdvisor.method; |
|
this.method= Actor.prototype.setupTradingMethod(methodName, true); |
|
this.method.batcher.on('candle'+config.tradingAdvisor.candleSize, this.method.tick); |
|
|
|
//setup main strategy and main candle batcher; |
|
//this.method = this.setupTradingMethod(methodName, true); |
|
//this.method.batcher = this.setupCandleBatcher(this.method, config.tradingAdvisor.candleSize); |
|
this.method.on('advice', this.relayAdvice); |
|
//this.batcher = this.setupCandleBatcher(this.method, config.tradingAdvisor.candleSize); |
|
|
|
|
|
|
|
var mode = util.gekkoMode(); |
|
|
|
// the stitcher will try to pump in historical data |
|
// so that the strat can use this data as a "warmup period" |
|
// |
|
// the realtime "leech" market won't use the stitcher |
|
if(mode === 'realtime' && !isLeecher) { |
|
var Stitcher = require(dirs.tools + 'dataStitcher'); |
|
var stitcher = new Stitcher(this.batcher); |
|
stitcher.prepareHistoricalData(done); |
|
} else |
|
done(); |
|
} |
|
|
|
util.makeEventEmitter(Actor); |
|
|
|
Actor.prototype.initConsultant = function(methodName) |
|
{ |
|
var method = require(dirs.methods + methodName); |
|
// bind all trading method specific functions |
|
// to the Consultant. |
|
var Consultant = require('./baseTradingMethod'); |
|
|
|
_.each(method, function(fn, name) { |
|
Consultant.prototype[name] = fn; |
|
}); |
|
|
|
return Consultant; |
|
} |
|
|
|
Actor.prototype.registerCandleMessage = function(method, candleSize) |
|
{ |
|
Actor.prototype.method.batcher.candleSize.push(candleSize); |
|
Actor.prototype.method.batcher.on('candle'+candleSize, method.tick); |
|
} |
|
|
|
|
|
|
|
|
|
Actor.prototype.setupTradingMethod = function(methodName, isMasterMethod) { |
|
|
|
if(!fs.existsSync(dirs.methods + methodName + '.js')) |
|
util.die('Gekko can\'t find the strategy "' + methodName + '"'); |
|
|
|
log.info('\t', 'Using the strategy: ' + methodName); |
|
|
|
var protoMethod = this.initConsultant(methodName); |
|
|
|
if (isMasterMethod)//the method that contains its own candle batcher; |
|
{ |
|
protoMethod.prototype.batcher = this.setupCandleBatcher(protoMethod, config.tradingAdvisor.candleSize); |
|
protoMethod.prototype.secondaryMethods = []; |
|
|
|
protoMethod.prototype.newTimeFrame = function(candleSize) |
|
{ |
|
|
|
|
|
var childMethod = Actor.prototype.setupTradingMethod('noop', false); |
|
|
|
//Consultant.prototype.batcher.on('candle'+candleSize, childMethod.tick); |
|
if (candleSize in this.batcher.candleSize === false) |
|
this.batcher.candleSize.push(candleSize); |
|
|
|
this.batcher.on('candle'+candleSize, childMethod.tick); |
|
|
|
if (this.asyncTick) |
|
{ |
|
util.die("Timeframes are not compatiple with TA-lib or Tulind indicators on main method.") |
|
} |
|
//Consultant.prototype.secondaryBatchers.push( |
|
// Actor.prototype.setupCandleBatcher(childMethod, candleSize)); |
|
|
|
childMethod.setup = false; |
|
childMethod.hasSyncIndicators = true; |
|
childMethod.requiredHistory = 1; |
|
|
|
this.secondaryMethods.push(childMethod); |
|
return childMethod; |
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
if(config[methodName]) { |
|
var tradingSettings = config[methodName]; |
|
} |
|
|
|
var Method = new protoMethod(tradingSettings); |
|
|
|
console.log(">>>>>>>>>>", Method); |
|
|
|
return Method; |
|
|
|
} |
|
|
|
Actor.prototype.setupCandleBatcher = function(method, candleSize) { |
|
var CandleBatcher = require(dirs.core + 'candleBatcher'); |
|
var batcher = new CandleBatcher(candleSize); |
|
//batcher.on('candle', method.tick); |
|
return batcher; |
|
} |
|
// HANDLERS |
|
// process the 1m candles |
|
Actor.prototype.processCandle = function(candle, done) { |
|
//write candles to main batcher; |
|
this.method.batcher.write([candle], 'interval'); |
|
|
|
done(); |
|
} |
|
|
|
|
|
// propogate a custom sized candle to the trading method - DEPRECATED; |
|
Actor.prototype.processCustomCandle = function(candle) { |
|
this.method.tick(candle); |
|
} |
|
|
|
// pass through shutdown handler |
|
Actor.prototype.finish = function(done) { |
|
this.method.finish(done); |
|
} |
|
|
|
// EMITTERS |
|
Actor.prototype.relayAdvice = function(advice) { |
|
this.emit('advice', advice); |
|
} |
|
|
|
|
|
module.exports = Actor; |