Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums



(Advanced Search)

Forum Statistics
» Members: 28,509
» Latest member: iwinvntv
» Forum threads: 1,541
» Forum posts: 8,068

Full Statistics

Online Users
There are currently 296 online users.
» 0 Member(s) | 296 Guest(s)

Latest Threads
Gekko with malware spotte...
Forum: Announcements
Last Post: Isobel
36 minutes ago
» Replies: 191
» Views: 170,141
Gekko development status ...
Forum: Announcements
Last Post: kontho
42 minutes ago
» Replies: 1,008
» Views: 931,248
Gekko 0.6 released
Forum: Announcements
Last Post: Pharagon
11-23-2024, 10:13 AM
» Replies: 122
» Views: 269,049
An official Gekko service...
Forum: Announcements
Last Post: drivemad2
11-22-2024, 07:24 AM
» Replies: 103
» Views: 189,852
New Gekko UI in the works
Forum: Announcements
Last Post: clduplicateremover
11-18-2024, 08:21 PM
» Replies: 174
» Views: 227,732
How to Soft Reset or Hard...
Forum: General Discussion
Last Post: lucifar
10-07-2021, 07:18 PM
» Replies: 22
» Views: 53,024
How to add Binance Future...
Forum: Technical Support
Last Post: Xavier32
10-07-2021, 02:20 PM
» Replies: 47
» Views: 108,388
Bittrex Configuration hel...
Forum: Bittrex
Last Post: yirzolusto
10-07-2021, 07:39 AM
» Replies: 6
» Views: 19,116
[Question] Why does gekko...
Forum: General Discussion
Last Post: cryptocurrency0
10-06-2021, 01:16 PM
» Replies: 16
» Views: 45,830
a couple of technical Que...
Forum: Technical Support
Last Post: mtom78632
10-06-2021, 11:08 AM
» Replies: 25
» Views: 58,579

 
Information sell if price>x or sell if price<y
Posted by: MoneyNeverSleeps - 05-01-2018, 05:43 PM - Forum: Strategy Development - Replies (1)

I know a minimal amount of coding and I'm basically trying to set up simultaneous stop loss and take profit orders. So for example, if the price of BTC becomes higher than 9500 USDT, I want to market sell my BTC position. Likewise, if it drops to below 8500, I also wanna sell it at market price as well. I want to keep my position as long as the price stays in this range. The below code I attempted to use gives the 'child process has dies' error. What's wrong with it? Can somebody help?

var strat = {};

// Prepare everything our strat needs
strat.init = function() {
  // setting take profit price
  this.proPrice = 9500;

  // setting stop loss price
  this.losPrice = 8500;
}

strat.check = function(candle) {
    if(candle.close <= this.losPrice) {
        this.advice(“short”);
        return;
    }
    if(candle.close >= this.proPrice) {
        this.advice(“short”);
        return;
    }
}

module.exports = strat;


  Crossover EMA strat
Posted by: MrBird - 05-01-2018, 12:17 AM - Forum: Automated Trading - Replies (3)

Hi everyone. 

I am trying to sort out a simple Crossover EMA strat. But I can't workout how to import two EMA indicators or how to code that in general. 

has anybody done this who can point me in the right direction?

-Bird


  where put the amount for trading ?
Posted by: cena3 - 04-30-2018, 02:58 PM - Forum: Automated Trading - Replies (2)

where put the amount for trading ?


  Gekko tranding live
Posted by: cena3 - 04-30-2018, 07:54 AM - Forum: General Discussion - No Replies

Hi, can anyone give me a gekko that works on trade live with advice? because I do not know much about it and wanted it to buy and sell itself, but the only thing I can do is simulation. can any one help me?


Bug [TUT] STRATEGIE #4 TULIP: MA, MACD, STOCH, RSI [SHARE]
Posted by: susitronix - 04-30-2018, 03:33 AM - Forum: Guides - Replies (1)

In this tutorial you can learn how to setup indicators.

>>>i have randoomly choosen Tulip indicators but it could be eny avilable indicators for gekko.
>>>>>the test results are all in the same uptrend/period and should only show the trigger points.
>>>>>>>WARNING THESE STRATEGIES ARE NOT PROFITABLE ENOUGH OVER TIME.
(((((it needs more than one indicator-if-statement to become a profitable trader)))))

Some indicators have two or three options (user input averaging length) and more than one output.
In this case, Arrays are used to set the inputs or read the output values.

First a simple RSI (realtime strength index) with one input/output
////////Test results: BASSic RSI

Code:
/*
BASSic tulip_RSI
*/

var _ = require('lodash');
var log = require('../core/log.js');
var config = require('../core/util.js').getConfig();

var strat = {};

strat.init = function () {
    //add candle.close
    price =
        {
            close: 0//this.candle
        };
    this.price = price;

    logic =
        {
            longpos: false
        };
    this.logic = logic;

    //first fetch settings from .toml
    var customRSIsettings = this.settings.RSI;

    // define the indicators we need     //move the settings into >>>rsi input length
    this.addTulipIndicator('myrsi', 'rsi', customRSIsettings);
}

strat.update = function (candle) {

}

strat.log = function () {

}

strat.check = function (candle) {
    //update price.close
    this.price.close = this.candle.close;

    //update the indicator before using it
    var resultRSI = this.tulipIndicators.myrsi.result.result;

    //lets trade...
    if (resultRSI > this.settings.trsRSI.high && this.logic.longpos !== false) {
        this.logic.longpos = false;
        this.advice('short');
        log.debug('goShort price ' + this.price.close + '  rsi ' + resultRSI.toFixed(2));
    }
    else if (resultRSI < this.settings.trsRSI.low && this.logic.longpos !== true) {
        this.logic.longpos = true;
        this.advice('long');
        log.debug('goLong price ' + this.price.close + '  rsi ' + resultRSI.toFixed(2));
    }
}

module.exports = strat;
use your editor and load a existing gekko strategie.js file from the gekko folder (gekko/strategies/.....)
>select all and delete the content
>>copy/paste my example code strat above
>>>Save as: rename to:
>>>>tulip_RSI.js //and save

WARNIG: MY CODE INDENTS HAVE BEEN BIT  MESSED UP HERE
JUST: in your editor right-click choose [format document] before save...

Code:
[RSI]
optInTimePeriod = 15

[trsRSI]
high = 71
low = 28

#_try_1min_candles_#
#_binance_BTC_USDT_#
use your editor and load a existing gekko strategie.toml file from the gekko folder (gekko/config/strategies/.....)
>select all and delete the content
>>copy/paste my example code user settings above
>>>Save as: rename to:
>>>>tulip_RSI.toml
>>>>>Save as type //<<<SELECT TYPE: ALL FILES (SCROLL UP TO FIND IT..!)


The MA (Moving avereage) with two MAs looking for the crossing point.
//////////test results: BASSic MA

Code:
/*
BASSic tulip_MA
*/

var _ = require('lodash');
var log = require('../core/log.js');
var config = require('../core/util.js').getConfig();

var strat = {};

strat.init = function () {
    //add candle.close
    price =
        {
            close: 0//this.candle
        };
    this.price = price;

    logic =
        {
            longpos: false
        };
    this.logic = logic;

    //first fetch settings from .toml
    var customMAfastsettings = this.settings.MA_Fast;
    var customMAslowsettings = this.settings.MA_Slow;

    // define the indicators we need     //move the settings into >>>rsi input length
    this.addTulipIndicator('mafast', 'sma', customMAfastsettings);
    this.addTulipIndicator('maslow', 'sma', customMAslowsettings);
}

strat.update = function (candle) {

}

strat.log = function () {

}

strat.check = function (candle) {
    //update price.close
    this.price.close = this.candle.close;

    //update the indicator before using it
    var resultMAfast = this.tulipIndicators.mafast.result.result;
    var resultMAslow = this.tulipIndicators.maslow.result.result;

    //lets trade...
    if (resultMAslow > resultMAfast && this.logic.longpos !== false) {
        this.logic.longpos = false;
        this.advice('short');
        log.debug('goShort price ' + this.price.close + '  maS ' + resultMAslow.toFixed(2) + '  maF ' + resultMAfast.toFixed(2));
    }
    else if (resultMAslow < resultMAfast && this.logic.longpos !== true) {
        this.logic.longpos = true;
        this.advice('long');
        log.debug('goLong price ' + this.price.close + '  maS ' + resultMAslow.toFixed(2) + '  maF ' + resultMAfast.toFixed(2));
    }
}

module.exports = strat;
>>>>save as tulip_MA.js

Code:
[MA_Fast]
optInTimePeriod = 50

[MA_Slow]
optInTimePeriod = 100

#_try_15min_candles_#
#_binance_BTC_USDT_#
>>>>save as tulip_MA.toml

It is the same setup as for the RSI, only dual.

the MACD has more options and outputs, but which ones??
In the gekko folder:
Code:
C:\Users.....\gekko\core
looking for tulind.js
>>>thats all we need for the configuration.

more information:

tulip bindings for node.js
tulip indicators

//////////test results: BASSic MACD
Code:
/*
BASSic tulip_MACD
*/

var _ = require('lodash');
var log = require('../core/log.js');
var config = require('../core/util.js').getConfig();

var strat = {};

strat.init = function () {
    //add candle.close
    price =
        {
            close: 0//this.candle
        };
    this.price = price;

    logic =
        {
            longpos: false
        };
    this.logic = logic;

    //first fetch settings from .toml
    var customMACDsettings = this.settings.MACD;

    // define the indicators we need     //move the settings into >>>macd input length
    this.addTulipIndicator('mymacd', 'macd', customMACDsettings);
}

strat.update = function (candle) {

}

strat.log = function () {

}

strat.check = function (candle) {
    //update price.close
    this.price.close = this.candle.close;

    //update the indicator before using it
    var resultMACD = this.tulipIndicators.mymacd.result;

    //lets trade...
    if (resultMACD.macd > resultMACD.macdSignal && this.logic.longpos !== false) {
        this.logic.longpos = false;
        this.advice('short');
        log.debug('goShort price ' + this.price.close + '  mc ' + resultMACD.macd.toFixed(2) + '  m.sig ' + resultMACD.macdSignal.toFixed(2));
    }
    else if (resultMACD.macd < resultMACD.macdSignal && this.logic.longpos !== true) {
        this.logic.longpos = true;
        this.advice('long');
        log.debug('goLong price ' + this.price.close + '  mc ' + resultMACD.macd.toFixed(2) + '  m.sig ' + resultMACD.macdSignal.toFixed(2));
    }
}

module.exports = strat;
>>>>save as tulip_MACD.js

Code:
[MACD]
optInFastPeriod = 25
optInSlowPeriod = 50
optInSignalPeriod = 30

#_try_15min_candles_#
#_Binance_BTC_USDT_#
>>>>save as tulip_MACD.toml

lets have a look at the tulind.js file (library).
Its long. Use the Find function in your editor:
>>>Ctrl+F
>>>>>type macd and hit enter
Code:
methods.macd = {
   requires: ['optInFastPeriod', 'optInSlowPeriod', 'optInSignalPeriod'],
   create: (params) => {
       verifyParams('macd', params);

       return (data, callback) => execute(callback, {
           indicator: tulind.indicators.macd,
           inputs: [data.close],
           options: [params.optInFastPeriod, params.optInSlowPeriod, params.optInSignalPeriod],
           results: ['macd', 'macdSignal', 'macdHistogram'],
       });
   }
}
Its a bit hard to understand  but we only need the options.
Above it says "requires".

As you learnd in my TUT #2
>>>>>the squared bracket designate  ARRAYs (number-chains).

Code:
['optInFastPeriod', 'optInSlowPeriod', 'optInSignalPeriod']

and the outputs:
Code:
['macd', 'macdSignal', 'macdHistogram']

In the options array, are objects that have a name and a value associated to it.
If we map the user.settings we can use the array name. thats the quick n dirty way:
Code:
var customMACDsettings = this.settings.MACD;
 
now we move the whole array into the indicator:
Code:
this.addTulipIndicator('mymacd', 'macd', customMACDsettings);
the order would be the same as we set it up in the setttings.

For the results we would use the right object:

Code:
resultMACD.macd
resultMACD.macdSignal
resultMACD.macdHistogram

>>>Remember if you want to use it globally, you must first make a global object out of it. TUT #1


The Stoch oscillator has also multiple options/outputs.
//////////test results: BASSic STOCH

Code:
/*
BASSic tulip_STOCH
*/

var _ = require('lodash');
var log = require('../core/log.js');
var config = require('../core/util.js').getConfig();

var strat = {};

strat.init = function () {
    //add candle.close
    price =
        {
            close: 0//this.candle
        };
    this.price = price;

    logic =
        {
            longpos: false
        };
    this.logic = logic;

    //first fetch settings from .toml
    var customSTOCHsettings = this.settings.STOCH;

    // define the indicators we need     //move the settings into >>>rsi input length
    this.addTulipIndicator('mystoch', 'stoch', customSTOCHsettings);
}

strat.update = function (candle) {

}

strat.log = function () {

}

strat.check = function (candle) {
    //update price.close
    this.price.close = this.candle.close;

    //update the indicator before using it
    var resultSTOCH = this.tulipIndicators.mystoch.result;

    //lets trade...
    if (resultSTOCH.stochD > this.settings.trsSTOCH.high && this.logic.longpos !== false) {
        this.logic.longpos = false;
        this.advice('short');
        log.debug('goShort price ' + this.price.close + '  stochD ' + resultSTOCH.stochD.toFixed(2));
    }
    else if (resultSTOCH.stochD < this.settings.trsSTOCH.low && this.logic.longpos !== true) {
        this.logic.longpos = true;
        this.advice('long');
        log.debug('goLong price ' + this.price.close + '  stochD ' + resultSTOCH.stochD.toFixed(2));
    }
}

module.exports = strat;
>>>>save as tulip_STOCH.js

[url=https://forum.gekko.wizb.it/thread-57009.html][/url]
Code:
[STOCH]
optInFastKPeriod = 30
optInSlowKPeriod = 4
optInSlowDPeriod = 4

[trsSTOCH]
high = 80
low = 20

#_try_8min_candles_#
#_binance_BTC_USDT_#
>>>>save as tulip_STOCH.toml


Code:
methods.stoch = {
   requires: ['optInFastKPeriod', 'optInSlowKPeriod', 'optInSlowDPeriod'],
   create: (params) => {
       verifyParams('stoch', params);

       return (data, callback) => execute(callback, {
           indicator: tulind.indicators.stoch,
           inputs: [data.high, data.low, data.close],
           options: [params.optInFastKPeriod, params.optInSlowKPeriod, params.optInSlowDPeriod],
           results: ['stochK', 'stochD'],
       });
   }
}
The options and outputs are a bit different.
I have tryed other indicators but the test results were aweful
>>> THUS THIS BASSic TULIP STRATs, AS THEY ARE, WOULD BE USED FOR SHORTTERM TRADING
>>>>>OTHER INDICATORS COULD BE USEFULL FOR LONGTERM TREND INDICATION. let me know...
___________________________________________________________________________

In the previous TUTs, we have created utilities for a preset strat.
here we learnd how to setup indicators.

In the next TUTs we will beginn to build our strat.


Bug [TUT] STRATEGIE #3 CPU TIME MESSUREMENT [SHARE]
Posted by: susitronix - 04-30-2018, 12:50 AM - Forum: Guides - No Replies

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)


Bug [TUT] STRATEGIE #2 TIME CURSOR [SHARE]
Posted by: susitronix - 04-29-2018, 11:05 PM - Forum: Guides - Replies (2)

In the following tutorial you can learn how to:

-build a useful timecursor for our debug purposes
>>> use a Array
>>>>> use a for loop

>>>ONLY START THE SIMULATION WHEN I ASK YOU TO (incomplete snippets wont work)

IF YOU ARE NEW TO GEKKO AND JAVA SCRIPT, PLEASE LOOKING FOR [TUT] #1
BASSic TULIP RSI

The timecursor, can be added to eny debug line.
First in the settings we set the Start date, of the Backtest period.
Then the time cursor will calculate the same date/time as we looking at in the gekko --ui Test result waveform window.
...the time reference to eny event...

For solving the month/day problem we use our first Array where we simply preset the monthdays, for each month, into it.

The simple way for the time reference would be, the build-in date function, but i found that it will have lots of decimal places.
To go around we could use the function:

Code:
myValue.toFixed(0)


this will loose all the decimal places BUT!!! it crates a rounding with error included and becomes useless.

i designed my own whole number counter that works pretty spot-on.

Version3 uses the settings:
candle_size //(minutes!) this sets a [for loop], to update the right minutes-ammount if the candle_size is bigger than 1 minute.
>>> therefore we design our first [for loop].

Here is the code from the last TUT with a little tuning of the RSI:
Code:
/*
Tutorial:     trendatron #0
           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 () {
   //add candle.close
   price =
       {
           close: 0,//this.candle
       };
   this.price = price;

   logic =
       {
           longpos: false
       };
   this.logic = logic;

   //first fetch settings from .toml
   var customRSIsettings = this.settings.RSI;

   // define the indicators we need     //move the settings into >>>rsi input length
   this.addTulipIndicator('myrsi', 'rsi', customRSIsettings);
}

trenda.update = function (candle) {

}

trenda.log = function () {

}

trenda.check = function (candle) {
   //update price.close
   this.price.close = this.candle.close;

   //update the indicator before using it
   var resultRSI = this.tulipIndicators.myrsi.result.result;

   //add debug line and display the rsi value
   //log.debug('RSI result = ' + resultRSI);

   //lets trade...
   if (resultRSI > this.settings.trsRSI.high && this.logic.longpos !== false) {
       this.logic.longpos = false;
       this.advice('short');
       log.debug('goShort price.close = ' + this.price.close);
   }
   else if (resultRSI < this.settings.trsRSI.low && this.logic.longpos !== true) {
       this.logic.longpos = true;
       this.advice('long');
       log.debug('goLong price.close = ' + this.price.close);
   }
}

module.exports = trenda;
use your editor and load a existing gekko strategie.js file from the gekko folder (gekko/strategies/.....)
>select all and delete the content
>>copy/paste my example code strat above
>>>Save as: rename to:
>>>>trendatron_1.js //and save
WARNIG: MY CODE INDENTS HAVE BEEN BIT  MESSED UP HERE
JUST: in your editor right-click choose [format document] before save...

The settings.toml code:
Code:
[RSI]
optInTimePeriod = 15

[trsRSI]
high = 71
low = 28
use your editor and load a existing gekko strategie.toml file from the gekko folder (gekko/config/strategies/.....)
>select all and delete the content
>>copy/paste my example code user settings above
>>>Save as: rename to:
>>>>trendatron_1.toml
>>>>>Save as type //<<<SELECT TYPE: ALL FILES (SCROLL UP TO FIND IT..!)


Now we implement the timecurser step by step as i would write the code.
First write settings.toml

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

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

[RSI]
optInTimePeriod = 15

[trsRSI]
high = 71
low = 28
we also use the logic.longpos to tell gekko if we start trading with currency or asset.
that way we dont need to edit the code for using basic functions like this.

Now i have nice names in the settings but for writing code i use different names.
instead of just initializing the settings in the [INIT] we create a mapping:
Code:
trenda.init = 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;

   //add candle.close
   price =
       {
           close: 0,//this.candle
       };
   this.price = price;

   logic =
       {
           longpos: this.longpos
       };
   this.logic = logic;

   //first fetch settings from .toml
   var customRSIsettings = this.settings.RSI;

   // define the indicators we need     //move the settings into >>>rsi input length
   this.addTulipIndicator('myrsi', 'rsi', customRSIsettings);
}
we have also initialized two arrays:
this.montharr //here we set the values for each month directly. This will also set the length to 12
this.timearr //here we only init a empty array since we dont know/have the content yet.

>>>WE CAN CHECK A ARRAY LENGTH IN THE DEBUG LINE:
Code:
log.debug('Array length ' + this.myArray.length);

add the main code to the update function, that will execute before we can use it:
Code:
trenda.update = function (candle) {
   
   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];
   }
}

Now we setup the main counter in the [INIT] that will count the candles for the backtest period.
Code:
logic =
       {
           longpos: false,
           globalcount: 0 //candle counter
       };
   this.logic = logic;



The final code with the debug lines using the time array:
Code:
/*
Tutorial:     trendatron #0
           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.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;

   //add candle.close
   price =
       {
           close: 0,//this.candle
       };
   this.price = price;

   logic =
       {
           longpos: false,
           globalcount: 0
       };
   this.logic = logic;

   //first fetch settings from .toml
   var customRSIsettings = this.settings.RSI;

   // define the indicators we need     //move the settings into >>>rsi input length
   this.addTulipIndicator('myrsi', 'rsi', customRSIsettings);
}

trenda.update = function (candle) {

   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.log = function () {

}

trenda.check = function (candle) {
   //update price.close
   this.price.close = this.candle.close;

   //update the indicator before using it
   var resultRSI = this.tulipIndicators.myrsi.result.result;

   //lets trade...
   if (resultRSI > this.settings.trsRSI.high && this.logic.longpos !== false) {
       this.logic.longpos = false;
       this.advice('short');
       log.debug('>>> ' + this.timearr + ' Short price.close = ' + this.price.close);
   }
   else if (resultRSI < this.settings.trsRSI.low && this.logic.longpos !== true) {
       this.logic.longpos = true;
       this.advice('long');
       log.debug(' <<<' + this.timearr + ' Long price.close = ' + this.price.close);
   }
}

module.exports = trenda;
>>>save this code as: trendatron_1.js
>>>>>save also the latest settings.toml from above, as trendatron_1.toml (File type "all files")
>>>>>>>run the code


The code works but looks alllready stuffed with nothing in there yet.
>>>>>We create subroutines/functions that can be called from every where:
(this makes sense for functions that are called more than once, or that are only to be initialized, like the timecursor (set and forget)).
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.allInit();

   this.userMap();

   this.indInit();
}

trenda.update = function (candle) {

   this.timeCursor();
}

trenda.log = function () {

}

trenda.check = function (candle) {
   //update price.close
   this.price.close = this.candle.close;

   //update the indicator before using it
   var resultRSI = this.tulipIndicators.myrsi.result.result;

   //add debug line and display the rsi value
   //log.debug('RSI result = ' + resultRSI);

   //lets trade...
   if (resultRSI > this.settings.trsRSI.high && this.logic.longpos !== false) {
       this.goShort();
   }
   else if (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.candle
       };
   this.price = price;

   logic =
       {
           longpos: false,
           globalcount: 0
       };
   this.logic = logic;
}
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];
   }
}

module.exports = trenda;

looks better but lets use the [update] as its ment to, and the [check] for the final strategic statements:

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.allInit();

   this.userMap();

   this.indInit();
}

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.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];
   }
}

module.exports = trenda;

much better ;-)
its now modular to comment/uncomment functions, besides it has become somewhat structurized.
Code:
//this.timeCursor();
now the whole function is switched off


thats it for the timecursor and subcircuits.
in the next short tutorial a simple cpu-prozessing-time messurement tool and debug functions are the topic.


  candle size in strats overview
Posted by: DanPan - 04-28-2018, 08:44 PM - Forum: Technical Support - Replies (1)

i have a few strategies running wih different candle size against the live market.

How can i see in the list of running strats the candle size i had selected?

Thanks for your reply.


  I will pay for make a system using aacandlesstem using a candle anon2 moving average
Posted by: Presunto - 04-27-2018, 08:45 PM - Forum: Strategy Development - No Replies

I will pay for make a system using 2 moving average and a candlestick pattern (one bar only).

I will pay after job is done or using any site wich you have good reviews 

Bot Needs to works on bitfinex and be easy to adapt to any other broker gekko supports


  Convert from Sierra Charts
Posted by: Presunto - 04-27-2018, 08:21 PM - Forum: Third Party Software - Replies (1)

I paid a lot of money to make a Bot for Sierra Chart but now I am not able to use it because bitmex is a scam and reject 70% of orders 

It is too much difficult to convert a system from Sierra Charts to gekko?