Code:
/*
Tutorial: trendatron #5
rsi trader
philipp wyler
2018-04-25
*/
var _ = require('lodash');
var log = require('../core/log.js');
var config = require('../core/util.js').getConfig();
var trenda = {};
//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><
//>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>
//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><
trenda.init = function () {
this.name = 'trendatron_2';
this.allInit();
this.userMap();
this.cpuTime();
this.indInit();
this.setupLog();
}
trenda.update = function (candle) {
this.timeCursor();
this.priceUpdate();
this.calculus();
this.resultRSI = this.tulipIndicators.myrsi.result.result;
}
trenda.log = function () {
}
trenda.check = function (candle) {
this.stop();
//lets trade...
if (this.logic.stopabs !== true && this.resultRSI > this.settings.trsRSI.high && this.logic.longpos !== false) {
this.goShort();
}
else if (this.logic.stopabs !== true && this.resultRSI < this.settings.trsRSI.low && this.logic.longpos !== true) {
this.goLong();
}
}
//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><
//>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>
//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><
trenda.stop = function () {
if (this.logic.stopabs !== false) {
if (this.logic.lock !== false && this.resultRSI > this.settings.trsRSI.high) {
this.logic.lock = false;
}
if (this.logic.lock !== true && this.resultRSI < this.settings.trsRSI.low) {
this.logic.stopabs = false;
log.debug('- ' + this.timearr + ' zz---unlock ' + ' stop ' + this.logic.stopabs + ' pc ' + this.price.close.toFixed(2) + ' exp ' + this.price.exp.toFixed(2));
}
}
//SIDECHAIN STOP
if (this.logic.stopabs !== true && this.logic.longpos !== false && this.stopabsset > this.price.abs) {
if (this.stopabsexpset > this.price.exp) {
this.logic.stopabs = true;
this.logic.lock = true;
this.goShort();
this.logic.stopcount++;
log.debug('- ' + this.timearr + ' xxxxxxxxxxx ' + ' stop ' + this.logic.stopabs + ' pc ' + this.price.close.toFixed(2) + ' exp ' + this.price.exp.toFixed(2));
}
}
if (this.logic.stopabs !== true && this.logic.longpos !== true && this.stopabsset > this.price.abs) {
if (this.stopabsexpset > this.price.exp) {
this.logic.stopabs = true;
this.logic.lock = true;
this.logic.waitcount++;
log.debug('- ' + this.timearr + ' yyyyyyyyyy ' + ' wait ' + this.logic.stopabs + ' pc ' + this.price.close.toFixed(2) + ' exp ' + this.price.exp.toFixed(2));
}
}
}
trenda.goShort = function () {
this.logic.longpos = false;
this.advice('short');
log.debug('>>> ' + this.timearr + ' Short price.close = ' + this.price.close);
}
trenda.goLong = function () {
this.logic.longpos = true;
this.advice('long');
this.price.long = this.price.close;
log.debug(' <<<' + this.timearr + ' Long price.close = ' + this.price.close);
}
trenda.priceUpdate = function () {
this.price.close = this.candle.close;
this.price.low = this.candle.low;
this.price.high = this.candle.high;
this.price.volume = this.candle.volume;
this.price.vwp = this.candle.vwp;
this.price.trades = this.candle.trades;
}
trenda.calculus = function () {
this.price.abs = ((this.price.long - this.price.close) / this.price.long) * -100; //LAST LONG
this.price.dif = ((this.price.last - this.price.close) / this.price.last) * -100; //LAST LONG
this.price.last = 0;
this.price.last = this.price.close;
this.price.exp = this.price.trades * this.price.dif;
}
trenda.indInit = function () {
// define the indicators we need //move the settings into >>>rsi input length
this.addTulipIndicator('myrsi', 'rsi', this.customRSIsettings);
}
trenda.allInit = function () {
//first fetch settings from .toml
this.customRSIsettings = this.settings.RSI;
//add candle
price =
{
close: 0,//this.candle
low: 0,//this.candle
high: 0,//this.candle
volume: 0,//this.candle
vwp: 0,//this.candle
trades: 0,//this.candle
long: 0,
last: 0,
dif: 0,
exp: 0
};
this.price = price;
logic =
{
longpos: false,
stopabs: false,
lock: false,
globalcount: 0,
stopcount: 0,
waitcount: 0
};
this.logic = logic;
this.stopabsset = this.settings.___stop_abs____.stop_abs;
this.stopabsexpset = this.settings.___stop_abs____.abs_exp;
}
trenda.cpuTime = function () {
//CPU TIME SET
this.startTime = new Date();
}
trenda.userMap = function () {
this.longpos = this.settings.___trendatron___.__longPos;
month = this.settings._backtest_start_.______month;
day = this.settings._backtest_start_.__________day;
hour = this.settings._backtest_start_._____hour;
minute = this.settings._backtest_start_._minute;
this.montharr = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
this.month = month;
this.day = day;
this.hour = hour;
this.minute = minute;
this.timearr = [];
this.candlesize = this.settings._backtest_start_.candle_size;
}
trenda.timeCursor = function () {
if (this.logic.globalcount == 0) {
this.mcount = this.minute;
this.hcount = this.hour;
this.dcount = this.day;
this.moncount = this.month;
}
y = this.candlesize;
for (i = 0; i < y; i++) {
this.logic.globalcount++;//COUNT BACKTEST CANDLES
z = this.moncount - 1;
this.monthframe = this.montharr[z];
candleminute = this.logic.globalcount % 60;//MINUTE MODULUS////
this.candleminute = candleminute;
//HOUR COUNT
if (this.mcount == 59) {
this.hcount++;//HOUR COUNT
this.mcount = 0;
}
else if (this.mcount < 59) {
this.mcount++;
}
//DAY COUNT
if (this.hcount == 24) {
this.dcount++;//DAY COUNT
this.hcount = 0;
}
//MONTHDAY
if (this.dcount > (this.monthframe)) {
this.moncount++;
this.dcount = 1
}
//MONTH
else if (this.moncount > 12) {
this.moncount = 1;
}
this.candlehour = this.hcount;//HOUR
this.candleday = this.dcount;//DAY
this.candlemonth = this.moncount;//MONTH
this.timearr = [this.candlemonth, this.candleday, this.candlehour, this.candleminute];
}
}
trenda.setupLog = function () {
log.info
(
'\n' + '\t' + '\t' + '\t' + '\t' +
' ...last longpos = ' + this.logic.longpos + '\n' + '\t' + '\t' + '\t' +
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' + '\n' + '\t' + '\t' + '\t' +
' .....start backtest ' + this.name + ' varactor' + '\n' + '\t' + '\t' + '\t' +
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' + '\n' + '\t' + '\t' + '\t' +
'\n' + '\t' + '\t' + '\t' +
' <<>>' + '\n' + '\t' + '\t' + '\t' +
' ><<><>><<>>' + '\n' + '\t' + '\t' + '\t' +
' >><<>> <<>><<' + '\n' + '\t' + '\t' + '\t' +
' <>><<> system v3 >><<>>' + '\n' + '\t' + '\t' + '\t' +
' <<>><<> start date ' + this.month + ':' + this.day + ':' + this.hour + ':' + this.minute + ' >><<>>' + '\n' + '\t' + '\t' + '\t' +
' ><<>>< ......beginn trading <>><<>' + '\n' + '\t' + '\t' + '\t' +
'><<>>< ' + this.name + ' ><>><<' + '\n' + '\t' + '\t' + '\t' +
' >><<>> susitronix d-sign <<>><<' + '\n' + '\t' + '\t' + '\t' +
' >><<<<<>>><< <<>>><<>><<' + '\n' + '\t' + '\t' + '\t' +
' ><<<<>>><<<>>><<>>' + '\n' + '\t' + '\t' + '\t' +
' >>><<<' + '\n' + '\t' + '\t' + '\t' +
' <>' + '\n'
);
}
trenda.end = function () {
this.logic.globalcount;
this.monthdif = (((this.logic.globalcount / 60) / 24) / 30) % 12;
this.daysdif = ((this.logic.globalcount / 60) / 24) % 30;
this.hoursdif = (this.logic.globalcount / 60) % 24;
this.minutesdif = this.logic.globalcount % 60;
this.globalcountdif = this.logic.globalcount - this.globalcountbegin;
let seconds = ((new Date() - this.startTime) / 1000),
minutes = seconds / 60,
str;
//CPU TIME CALCULUS IN MILLISECONDS
this.totaltime = ((minutes / 60) + seconds);
this.cputime = ((this.totaltime / this.logic.globalcount) * 1000);
minutes < 1 ? str = seconds.toFixed(2) + ' seconds' : str = minutes.toFixed(2) + ' minutes';
log.info
(
'\n' + '\t' + '\t' +
'.....backtest started with longpos = ' + this.longpos + '\n' + '\t' +
'.....stop count = ' + this.logic.stopcount + '\n' + '\t' +
'.....wait count = ' + this.logic.waitcount + '\n' + '\t' +
' ' + '\n' + '\t' +
' <<>> ' + '\n' + '\t' +
' <<>><<>><<>><<>> ' + '\n' + '\t' +
' >><<>><<>><<>><<>><<>><<>><< ' + '\n' + '\t' +
' <<>><<>> ' + this.name + ' <<>><<>>' + '\n' + '\t' +
' <<>><<>> start date ' + this.month + ':' + this.day + ':' + this.hour + ':' + this.minute + ' <<>><<>>' + '\n' + '\t' +
' <<>><<>> end time ' + this.candlemonth + ':' + this.candleday + ':' + this.candlehour + ':' + this.candleminute + ' finish <<>><<>>' + '\n' + '\t' +
' <<>><<>> ' + str + ' / candles = ' + this.logic.globalcount + ' <<>><<>>' + '\n' + '\t' +
' <<>><<>> candle cpu time = ' + this.cputime.toFixed(4) + ' mSec <<>><<>>' + '\n' + '\t' +
' >><< <<>><<>><<>> <<>><<>><<>> <<>> ' + '\n' + '\t' +
' <<>><> <<>><<>><<>><<>><<>><<>> <<>><< ' + '\n' + '\t' +
'<<>><<>>><< <<>><<>> ><<>><<>>>< ' + '\n' + '\t'
);
}
module.exports = trenda;