[TUT] STRATEGIE #3 CPU TIME MESSUREMENT [SHARE]
#1
Bug 
When developing a strategie it may be useful to look at the cpu-time needed for calculating one candle.
This would indicate a abnormal increase in processing time, if the newer code would be faulty. (looopsy-dooo)

thanks to THOMMIE HANSEN

We can use the built in date function to messure the total backtest time.
cpu time = backtest time total / ammount of candles

in the init we capture the start time
Code:
trenda.cpuTime = function()
{
   //CPU TIME SET
   this.startTime = new Date();
}

then we can use the [end] function to calculate and display the value after the backtest period is finished.
Code:
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;

   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'+'\t'+'\t'+
   '.....backtest started with longpos = '+ this.longpos                                   +'\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'
   );
}

whats all this...
Code:
+'\n'+'\t'+
...stuff is all about..?

for debug lines we can use the newline or insert-tab comand.
The cli window has a restricted width to display.
In this way i get rid of the date header for having enough space for debug statistics.
Here i choose the seperat days/minutes/hours debug line for having a colon inbetween instead of coma.

Since this looks somewhat familiar why not drop the intro header and put it all together:


Code:
/*
Tutorial:     trendatron #2
           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'; //enter the strat name here

   this.allInit();

   this.userMap();

   this.cpuTime();

   this.indInit();

   this.setupLog();
}

trenda.update = function (candle) {

   this.timeCursor();
   this.price.close = this.candle.close;
   this.resultRSI = this.tulipIndicators.myrsi.result.result;
}

trenda.log = function () {

}

trenda.check = function (candle) {

   //lets trade...
   if (this.resultRSI > this.settings.trsRSI.high && this.logic.longpos !== false) {
       this.goShort();
   }
   else if (this.resultRSI < this.settings.trsRSI.low && this.logic.longpos !== true) {
       this.goLong();
   }
}
//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><
//>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>
//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><
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');
   log.debug(' <<<' + this.timearr + ' Long price.close = ' + this.price.close);
}


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.close
   price =
       {
           close: 0,
       };
   this.price = price;

   logic =
       {
           longpos: false,
           globalcount: 0
       };
   this.logic = logic;
}
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'+
   '                                                       '                               +'\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;
This is the final strat. copy/paste and run with gekko backtest.

now i have my own preset waiting for...
i know this was boring sorry.
therefore:
in the next tutorial we will design some more intresting stuff:
>>>basic tulip indicators as modular blocks
-MA
-MACD
-Stoch osc
...(RSI)
  Reply


Forum Jump:


Users browsing this thread: