[SHARE] dynamic Stoploss/Stopwait
#1
The dynamic approch of a stoploss seems to bring better results.
I designed my own stop indicator by using the candle.trades amount as signal.
Since this is a simple calculation it basicly can be eny
x **= candle.data;

4 month
1 month

Binance
BTC/Usdt
candlesize 1min
warmup 10min

For the 4 month period with such a difficult trend, its not bad.
>>>>>>>>its only a rsi and a stoploss...<<<<<<<<<
the one month as expected, is a bit less then the bulltrend

here is the finished code:

Code:
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;

And here the settings .toml

Code:
Code:
[___trendatron___]
#<<<>>><<<>>>#
__longPos = false

#>>><<<>>><<#
[_backtest_start_]
__________day = 1
______month = 4
_____hour = 18
_minute = 38
candle_size = 1
#<<<>>><<<>>>#

[RSI]
optInTimePeriod = 30

[trsRSI]
high = 68
low = 30

[___stop_abs____]
stop_abs = -1.7
abs_exp = -250


The actual code for the strat would be fearly small, the rest are just debug tools.
  Reply


Forum Jump:


Users browsing this thread: