Welcome, Guest |
You have to register before you can post on our site.
|
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
|
|
|
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
|
|
|
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?
|
|
|
[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.
|
|
|
[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...
...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)
|
|
|
[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:
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.
|
|
|
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?
|
|
|
|