diff --git a/.gitmodules b/.gitmodules index aed7382..f51ffeb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "gekko-strat-hl"] path = gekko-strat-hl url = https://github.com/mounirlabaied/gekko-strat-hl +[submodule "gekko"] + path = gekko + url = https://github.com/zzmike76/gekko diff --git a/CUSTOM_RSI/CUSTOM_RSI.js b/CUSTOM_RSI/CUSTOM_RSI.js index 5e260c3..5497c28 100644 --- a/CUSTOM_RSI/CUSTOM_RSI.js +++ b/CUSTOM_RSI/CUSTOM_RSI.js @@ -1,4 +1,5 @@ // Source: https://raw.githubusercontent.com/trainerbill/gekko/develop/strategies/CUSTOM-RSI.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies var log = require('../core/log.js'); const Joi = require('joi'); // If you want to use your own trading methods you can diff --git a/DEMACrossover/DEMACrossover.js b/DEMACrossover/DEMACrossover.js index b79e2fa..b431418 100644 --- a/DEMACrossover/DEMACrossover.js +++ b/DEMACrossover/DEMACrossover.js @@ -1,4 +1,5 @@ // Source: https://raw.githubusercontent.com/vrfurl/gekko/stable/strategies/DEMACrossover.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies // helpers var _ = require('lodash'); var log = require('../core/log.js'); diff --git a/DI/DI.js b/DI/DI.js index 90624b1..7f6008b 100644 --- a/DI/DI.js +++ b/DI/DI.js @@ -1,5 +1,5 @@ // Source: https://raw.githubusercontent.com/gcobs0834/gekko/develop/strategies/DI.js - +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies // let's create our own method var method = {}; diff --git a/EMACrossover/EMACrossover.js b/EMACrossover/EMACrossover.js index 1dc617a..2e12cfe 100644 --- a/EMACrossover/EMACrossover.js +++ b/EMACrossover/EMACrossover.js @@ -1,4 +1,5 @@ // Source: https://raw.githubusercontent.com/vrfurl/gekko/stable/strategies/EMACrossover.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies // helpers var _ = require('lodash'); var log = require('../core/log.js'); diff --git a/EMADIV/EMADIV.js b/EMADIV/EMADIV.js index 5f0dbef..dd3745f 100644 --- a/EMADIV/EMADIV.js +++ b/EMADIV/EMADIV.js @@ -1,4 +1,5 @@ // Source: https://raw.githubusercontent.com/imperator6/gekko/stable/strategies/EMADIV.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies // helpers var _ = require('lodash'); var log = require('../core/log.js'); diff --git a/EMADIV2/EMADIV2.js b/EMADIV2/EMADIV2.js index 881bc98..3232017 100644 --- a/EMADIV2/EMADIV2.js +++ b/EMADIV2/EMADIV2.js @@ -1,4 +1,5 @@ // Source: https://raw.githubusercontent.com/imperator6/gekko/stable/strategies/EMADIV2.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies // helpers var _ = require('lodash'); var log = require('../core/log.js'); diff --git a/EMA_OR_PRICE_DIV/EMA_OR_PRICE_DIV.js b/EMA_OR_PRICE_DIV/EMA_OR_PRICE_DIV.js index df49be7..e9c7b79 100644 --- a/EMA_OR_PRICE_DIV/EMA_OR_PRICE_DIV.js +++ b/EMA_OR_PRICE_DIV/EMA_OR_PRICE_DIV.js @@ -1,4 +1,5 @@ // Source: https://raw.githubusercontent.com/imperator6/gekko/stable/strategies/EMA_OR_PRICE_DIV.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies // helpers var _ = require('lodash'); var log = require('../core/log.js'); diff --git a/FIXPRICE/FIXPRICE.js b/FIXPRICE/FIXPRICE.js index 7dc9d99..84f40fa 100644 --- a/FIXPRICE/FIXPRICE.js +++ b/FIXPRICE/FIXPRICE.js @@ -1,4 +1,5 @@ // Source: https://raw.githubusercontent.com/imperator6/gekko/stable/strategies/FIXPRICE.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies // helpers var _ = require('lodash'); var log = require('../core/log.js'); diff --git a/MACD_1520024643/MACD_1520024643.js b/MACD_1520024643/MACD_1520024643.js index 0350d02..291a43a 100644 --- a/MACD_1520024643/MACD_1520024643.js +++ b/MACD_1520024643/MACD_1520024643.js @@ -1,4 +1,6 @@ // Source: https://raw.githubusercontent.com/jazzbre/gekko/stable/strategies/MACD.js +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies + /* MACD - DJM 31/12/2013 diff --git a/NEO/NEO.js b/NEO/NEO.js new file mode 100644 index 0000000..c1fc121 --- /dev/null +++ b/NEO/NEO.js @@ -0,0 +1,196 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies + +// Source: https://raw.githubusercontent.com/gcobs0834/gekko/develop/strategies/NEO.js +/* + RSI Bull and Bear + Use different RSI-strategies depending on a longer trend + 3 feb 2017 + + (CC-BY-SA 4.0) Tommie Hansen + https://creativecommons.org/licenses/by-sa/4.0/ +*/ + +// req's +var log = require ('../core/log.js'); +var config = require ('../core/util.js').getConfig(); + +// strategy +var strat = { + + /* INIT */ + init: function() + { + this.name = 'RSI Bull and Bear'; + this.requiredHistory = config.tradingAdvisor.historySize; + this.resetTrend(); + + // debug? set to flase to disable all logging (improves performance) + this.debug = false; + + // add indicators + this.addTulipIndicator('maSlow', 'sma', { optInTimePeriod: this.settings.SMA_long }); + this.addTulipIndicator('maFast', 'sma', { optInTimePeriod: this.settings.SMA_short }); + this.addTulipIndicator('BULL_RSI', 'rsi', { optInTimePeriod: this.settings.BULL_RSI }); + this.addTulipIndicator('IDLE_RSI', 'rsi', { optInTimePeriod: this.settings.IDLE_RSI }); + this.addTulipIndicator('BEAR_RSI', 'rsi', { optInTimePeriod: this.settings.BEAR_RSI }); + this.addTulipIndicator('ROC_val', 'roc', { optInTimePeriod: this.settings.ROC }); + + // debug stuff + this.startTime = new Date(); + this.stat = { + bear: { min: 100, max: 0 }, + bull: { min: 100, max: 0 }, + idle: { min: 100, max: 0 } + }; + + + }, // init() + + + /* RESET TREND */ + resetTrend: function() + { + var trend = { + duration: 0, + direction: 'none', + longPos: false, + }; + + this.trend = trend; + }, + + /* get lowest/highest for backtest-period */ + lowHigh: function( rsi, type ) + { + let cur; + if( type == 'bear' ) { + cur = this.stat.bear; + if( rsi < cur.min ) this.stat.bear.min = rsi; // set new + if( rsi > cur.max ) this.stat.bear.max = rsi; + } + else if( type == 'idle') { + cur = this.stat.idle; + if( rsi < cur.min ) this.stat.idle.min = rsi; // set new + if( rsi > cur.max ) this.stat.idle.max = rsi; + } + + else { + cur = this.stat.bull; + if( rsi < cur.min ) this.stat.bull.min = rsi; // set new + if( rsi > cur.max ) this.stat.bull.max = rsi; + } + }, + + + /* CHECK */ + check: function() + { + if( this.candle.close.length < this.requiredHistory ) { return; } // check if candle length is correct + + // get all indicators + let ind = this.tulipIndicators, + maSlow = ind.maSlow.result.result, + maFast = ind.maFast.result.result, + rsi, + ROC_val = ind.ROC_val.result.result; + + // BEAR TREND + if( maFast < maSlow ) + { + rsi = ind.BEAR_RSI.result.result; + if( rsi > this.settings.BEAR_RSI_high ) this.short(); + else if( rsi < this.settings.BEAR_RSI_low ) this.long(); + if(this.debug) this.lowHigh( rsi, 'bear' ); + //log.debug('BEAR-trend'); + } + + // BULL TREND + else + { + // IDLE-BULL OR REAL-BULL TREND ?? + if( ROC_val <= this.settings.ROC_lvl ) + { + // BULL-IDLE TREND + rsi = ind.IDLE_RSI.result.result; + if( rsi > this.settings.IDLE_RSI_high ) this.short(); + else if( rsi < this.settings.IDLE_RSI_low ) this.long(); + if(this.debug) this.lowHigh( rsi, 'idle' ); + //log.debug('IDLE-trend'); + } + // REAL BULL TREND + else + { + rsi = ind.BULL_RSI.result.result; + if( rsi > this.settings.BULL_RSI_high ) this.short(); + else if( rsi < this.settings.BULL_RSI_low ) this.long(); + if(this.debug) this.lowHigh( rsi, 'bull' ); + //log.debug('BULL-trend'); + } + + } + + }, // check() + + + /* LONG */ + long: function() + { + if( this.trend.direction !== 'up' ) // new trend? (only act on new trends) + { + this.resetTrend(); + this.trend.direction = 'up'; + this.advice('long'); + //log.debug('go long'); + } + + if(this.debug) + { + this.trend.duration++; + log.debug ('Long since', this.trend.duration, 'candle(s)'); + } + }, + + + /* SHORT */ + short: function() + { + // new trend? (else do things) + if( this.trend.direction !== 'down' ) + { + this.resetTrend(); + this.trend.direction = 'down'; + this.advice('short'); + } + + if(this.debug) + { + this.trend.duration++; + log.debug ('Short since', this.trend.duration, 'candle(s)'); + } + }, + + + /* END backtest */ + end: function(){ + + let seconds = ((new Date()- this.startTime)/1000), + minutes = seconds/60, + str; + + minutes < 1 ? str = seconds + ' seconds' : str = minutes + ' minutes'; + + log.debug('Finished in ' + str); + + if(this.debug) + { + let stat = this.stat; + log.debug('RSI low/high for period:'); + log.debug('BEAR low/high: ' + stat.bear.min + ' / ' + stat.bear.max); + log.debug('BULL low/high: ' + stat.bull.min + ' / ' + stat.bull.max); + log.debug('IDLE low/high: ' + stat.idle.min + ' / ' + stat.idle.max); + } + } + +}; + +module.exports = strat; diff --git a/NEO/NEO.toml b/NEO/NEO.toml new file mode 100644 index 0000000..d765aad --- /dev/null +++ b/NEO/NEO.toml @@ -0,0 +1,30 @@ +# Source: https://raw.githubusercontent.com/gcobs0834/gekko/develop/config/strategies/NEO.toml +# SMA Trends +SMA_long = 150 +SMA_short = 40 + +# BULL +BULL_RSI = 10 +BULL_RSI_high = 80 +BULL_RSI_low = 50 + +# IDLE +IDLE_RSI = 12 +IDLE_RSI_high = 65 +IDLE_RSI_low = 39 + +# BEAR +BEAR_RSI = 15 +BEAR_RSI_high = 50 +BEAR_RSI_low = 25 + +# ROC +ROC = 6 +ROC_lvl = 0 + +# BULL/BEAR is defined by the longer SMA trends +# if SHORT over LONG = BULL +# if SHORT under LONG = BEAR + +# ROC is the LENGHT (averaging) +# Leave ROC_lvl at 0 otherwise Results are negative diff --git a/NN_ADX_RSI/NN_ADX_RSI.js b/NN_ADX_RSI/NN_ADX_RSI.js index 39d2ed1..f91a40b 100644 --- a/NN_ADX_RSI/NN_ADX_RSI.js +++ b/NN_ADX_RSI/NN_ADX_RSI.js @@ -1,3 +1,5 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies + var convnetjs = require('convnetjs') var z = require('zero-fill') var stats = require('stats-lite') diff --git a/RSI_BB_ADX_Peak/RSI_BB_ADX_Peak.js b/RSI_BB_ADX_Peak/RSI_BB_ADX_Peak.js new file mode 100644 index 0000000..9afcbf6 --- /dev/null +++ b/RSI_BB_ADX_Peak/RSI_BB_ADX_Peak.js @@ -0,0 +1,245 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies +/* + RSI Bull and Bear + ADX modifier + 1. Use different RSI-strategies depending on a longer trend + 2. But modify this slighly if shorter BULL/BEAR is detected + - + 12 feb 2017 + - + (CC-BY-SA 4.0) Tommie Hansen + https://creativecommons.org/licenses/by-sa/4.0/ +*/ + +// req's +var log = require('../core/log.js'); +var config = require('../core/util.js').getConfig(); + +// strategy +var strat = { + + /* INIT */ + init: function() { + this.name = 'RSI Bull and Bear + ADX'; + this.requiredHistory = config.tradingAdvisor.historySize; + this.resetTrend(); + + // debug? set to flase to disable all logging/messages/stats (improves performance) + this.debug = false; + config.backtest.batchSize = 20000 //reduce db reads + + //GA Settings CHECK + log.debug('SMA Long: ' + this.settings.SMA_long); + log.debug('SMA Short: ' + this.settings.SMA_short); + log.debug('Bull RSI: ' + this.settings.BULL_RSI); + log.debug('Bear RSI: ' + this.settings.BEAR_RSI); + + // performance + config.backtest.batchSize = 1000; // increase performance + config.silent = true; + config.debug = false; + + // SMA + this.addTulipIndicator('maSlow', 'sma', { + optInTimePeriod: this.settings.SMA_long + }); + this.addTulipIndicator('maFast', 'sma', { + optInTimePeriod: this.settings.SMA_short + }); + + // RSI + this.addTulipIndicator('BULL_RSI', 'rsi', { + optInTimePeriod: this.settings.BULL_RSI + }); + this.addTulipIndicator('BEAR_RSI', 'rsi', { + optInTimePeriod: this.settings.BEAR_RSI + }); + + // ADX + this.addTulipIndicator('ADX', 'adx', { + optInTimePeriod: this.settings.ADX + }) + + // Previous RSI value + this.lastBearRsi = 50; + this.lastBullRsi = 50; + + // MOD (RSI modifiers) + this.BULL_MOD_high = this.settings.BULL_MOD_high; + this.BULL_MOD_low = this.settings.BULL_MOD_low; + this.BEAR_MOD_high = this.settings.BEAR_MOD_high; + this.BEAR_MOD_low = this.settings.BEAR_MOD_low; + + // Stop Loss + this.lastLongPrice = 0; // start at 0 + + + // debug stuff + this.startTime = new Date(); + + // add min/max if debug + if (this.debug) { + this.stat = { + adx: { + min: 1000, + max: 0 + }, + bear: { + min: 1000, + max: 0 + }, + bull: { + min: 1000, + max: 0 + } + }; + } + + }, // init() + + + /* RESET TREND */ + resetTrend: function() { + var trend = { + duration: 0, + direction: 'none', + longPos: false, + }; + + this.trend = trend; + }, + + + /* get low/high for backtest-period */ + lowHigh: function(val, type) { + let cur; + if (type == 'bear') { + cur = this.stat.bear; + if (val < cur.min) this.stat.bear.min = val; // set new + else if (val > cur.max) this.stat.bear.max = val; + } else if (type == 'bull') { + cur = this.stat.bull; + if (val < cur.min) this.stat.bull.min = val; // set new + else if (val > cur.max) this.stat.bull.max = val; + } else { + cur = this.stat.adx; + if (val < cur.min) this.stat.adx.min = val; // set new + else if (val > cur.max) this.stat.adx.max = val; + } + }, + + + /* CHECK */ + check: function(candle) { + // get all indicators + let ind = this.tulipIndicators, + maSlow = ind.maSlow.result.result, + maFast = ind.maFast.result.result, + rsi, + adx = ind.ADX.result.result; + + + if (candle.close < this.lastLongPrice * (this.settings.Stop_Loss_Percent / 100)) { + this.short(); + } + // BEAR TREND + else if (maFast < maSlow) { + rsi = ind.BEAR_RSI.result.result; + let rsi_hi = this.settings.BEAR_RSI_high, + rsi_low = this.settings.BEAR_RSI_low; + + // ADX trend strength? + if (adx > this.settings.ADX_high) rsi_hi = rsi_hi + this.BEAR_MOD_high; + else if (adx < this.settings.ADX_low) rsi_low = rsi_low + this.BEAR_MOD_low; + + if (rsi > rsi_hi && rsi <= this.lastBearRsi) this.short(); + else if (rsi < rsi_low && rsi >= this.lastBearRsi) this.long(candle); + + if (this.debug) this.lowHigh(rsi, 'bear'); + this.lastBearRsi = rsi; + } + + // BULL TREND + else { + rsi = ind.BULL_RSI.result.result; + let rsi_hi = this.settings.BULL_RSI_high, + rsi_low = this.settings.BULL_RSI_low; + + // ADX trend strength? + if (adx > this.settings.ADX_high) rsi_hi = rsi_hi + this.BULL_MOD_high; + else if (adx < this.settings.ADX_low) rsi_low = rsi_low + this.BULL_MOD_low; + + + if (rsi > rsi_hi && rsi <= this.lastBullRsi) this.short(); // && RSI no longer increasing. + else if (rsi < rsi_low && rsi >= this.lastBullRsi) this.long(candle); //&& RSI no longer decreasing + if (this.debug) this.lowHigh(rsi, 'bull'); + this.lastBullRsi = rsi; + } + + // add adx low/high if debug + if (this.debug) this.lowHigh(adx, 'adx'); + + + + }, // check() + + + /* LONG */ + long: function(candle) { + if (this.trend.direction !== 'up') // new trend? (only act on new trends) + { + this.resetTrend(); + this.trend.direction = 'up'; + this.advice('long'); + this.lastLongPrice = candle.close; + if (this.debug) log.info('Going long'); + } + + if (this.debug) { + this.trend.duration++; + log.info('Long since', this.trend.duration, 'candle(s)'); + } + }, + + + /* SHORT */ + short: function() { + // new trend? (else do things) + if (this.trend.direction !== 'down') { + this.resetTrend(); + this.trend.direction = 'down'; + this.advice('short'); + if (this.debug) log.info('Going short'); + } + + if (this.debug) { + this.trend.duration++; + log.info('Short since', this.trend.duration, 'candle(s)'); + } + }, + + + /* END backtest */ + end: function() { + let seconds = ((new Date() - this.startTime) / 1000), + minutes = seconds / 60, + str; + + minutes < 1 ? str = seconds.toFixed(2) + ' seconds' : str = minutes.toFixed(2) + ' minutes'; + + log.info('===================================='); + log.info('Finished in ' + str); + log.info('===================================='); + + // print stats and messages if debug + if (this.debug) { + let stat = this.stat; + log.info('BEAR RSI low/high: ' + stat.bear.min + ' / ' + stat.bear.max); + log.info('BULL RSI low/high: ' + stat.bull.min + ' / ' + stat.bull.max); + log.info('ADX min/max: ' + stat.adx.min + ' / ' + stat.adx.max); + } + + } + +}; + +module.exports = strat; \ No newline at end of file diff --git a/RSI_BB_ADX_Peak/RSI_BB_ADX_Peak.toml b/RSI_BB_ADX_Peak/RSI_BB_ADX_Peak.toml new file mode 100644 index 0000000..daf538e --- /dev/null +++ b/RSI_BB_ADX_Peak/RSI_BB_ADX_Peak.toml @@ -0,0 +1,27 @@ +# SMA Trends +SMA_long = 1000 +SMA_short = 50 + +# BULL +BULL_RSI = 10 +BULL_RSI_high = 80 +BULL_RSI_low = 60 + +# BEAR +BEAR_RSI = 15 +BEAR_RSI_high = 50 +BEAR_RSI_low = 20 + +# MODIFY RSI (depending on ADX) +BULL_MOD_high = 5 +BULL_MOD_low = -5 +BEAR_MOD_high = 15 +BEAR_MOD_low = -5 + +# ADX +ADX = 3 +ADX_high = 70 +ADX_low = 50 + +# Stop Loss +Stop_Loss_Percent = 50 diff --git a/RSI_BULL_BEAR_ADX_PINGPONG/RSI_BULL_BEAR_ADX_PINGPONG.js b/RSI_BULL_BEAR_ADX_PINGPONG/RSI_BULL_BEAR_ADX_PINGPONG.js new file mode 100644 index 0000000..24a32a7 --- /dev/null +++ b/RSI_BULL_BEAR_ADX_PINGPONG/RSI_BULL_BEAR_ADX_PINGPONG.js @@ -0,0 +1,304 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies +/* + RSI Bull and Bear + ADX modifier + 1. Use different RSI-strategies depending on a longer trend + 2. But modify this slighly if shorter BULL/BEAR is detected + - + (CC-BY-SA 4.0) Tommie Hansen + https://creativecommons.org/licenses/by-sa/4.0/ + + UPDATE: + 3. Add pingPong for sideways market + + Rafael Martín. +*/ + +// req's +var log = require('../core/log.js'); +var config = require('../core/util.js').getConfig(); + +// strategy +var strat = { + + /* INIT */ + init: function() + { + // core + this.name = 'RSI Bull and Bear + ADX + PingPong'; + this.requiredHistory = config.tradingAdvisor.historySize; + this.resetTrend(); + + // debug? set to false to disable all logging/messages/stats (improves performance in backtests) + this.debug = false; + + // performance + config.backtest.batchSize = 1000; // increase performance + config.silent = true; + config.debug = false; + + // SMA + this.addTulipIndicator('maSlow', 'sma', { optInTimePeriod: this.settings.SMA_long }); + this.addTulipIndicator('maFast', 'sma', { optInTimePeriod: this.settings.SMA_short }); + + // RSI + this.addTulipIndicator('BULL_RSI', 'rsi', { optInTimePeriod: this.settings.BULL_RSI }); + this.addTulipIndicator('BEAR_RSI', 'rsi', { optInTimePeriod: this.settings.BEAR_RSI }); + + // ADX + this.addTulipIndicator('ADX', 'adx', { optInTimePeriod: this.settings.ADX }) + + // MOD (RSI modifiers) + this.BULL_MOD_high = this.settings.BULL_MOD_high; + this.BULL_MOD_low = this.settings.BULL_MOD_low; + this.BEAR_MOD_high = this.settings.BEAR_MOD_high; + this.BEAR_MOD_low = this.settings.BEAR_MOD_low; + + + // debug stuff + this.startTime = new Date(); + + // add min/max if debug + if( this.debug ){ + this.stat = { + adx: { min: 1000, max: 0 }, + bear: { min: 1000, max: 0 }, + bull: { min: 1000, max: 0 } + }; + } + + /* MESSAGES */ + + // message the user about required history + log.info("===================================="); + log.info('Running', this.name); + log.info('===================================='); + log.info("Make sure your warmup period matches SMA_long and that Gekko downloads data if needed"); + + // warn users + if( this.requiredHistory < this.settings.SMA_long ) + { + log.warn("*** WARNING *** Your Warmup period is lower then SMA_long. If Gekko does not download data automatically when running LIVE the strategy will default to BEAR-mode until it has enough data."); + } + + }, // init() + + + /* RESET TREND */ + resetTrend: function() + { + var trend = { + duration: 0, + direction: 'none', + longPos: false, // this will be false or a price if we already have a long position + pingPong : { + gainsPercentage: this.settings.PINGPONG_GAINS_PERCENTAGE // when we want to close the long position? + } + }; + + this.trend = trend; + }, + + + /* get low/high for backtest-period */ + lowHigh: function( val, type ) + { + let cur; + if( type == 'bear' ) { + cur = this.stat.bear; + if( val < cur.min ) this.stat.bear.min = val; // set new + else if( val > cur.max ) this.stat.bear.max = val; + } + else if( type == 'bull' ) { + cur = this.stat.bull; + if( val < cur.min ) this.stat.bull.min = val; // set new + else if( val > cur.max ) this.stat.bull.max = val; + } + else { + cur = this.stat.adx; + if( val < cur.min ) this.stat.adx.min = val; // set new + else if( val > cur.max ) this.stat.adx.max = val; + } + }, + + + /* CHECK */ + check: function() + { + // get all indicators + let ind = this.tulipIndicators, + maSlow = ind.maSlow.result.result, + maFast = ind.maFast.result.result, + rsi, + adx = ind.ADX.result.result; + + + // BEAR TREND + if( maFast < maSlow ) + { + rsi = ind.BEAR_RSI.result.result; + let rsi_hi = this.settings.BEAR_RSI_high, + rsi_low = this.settings.BEAR_RSI_low; + + // ADX trend strength? + if( adx > this.settings.ADX_high ) rsi_hi = rsi_hi + this.BEAR_MOD_high; + else if( adx < this.settings.ADX_low ) rsi_low = rsi_low + this.BEAR_MOD_low; + + if( rsi > rsi_hi ) this.short(); + else if( rsi < rsi_low ) this.long(); + //else this.pingPong(); + + if(this.debug) this.lowHigh( rsi, 'bear' ); + } + + // BULL TREND + else + { + rsi = ind.BULL_RSI.result.result; + let rsi_hi = this.settings.BULL_RSI_high, + rsi_low = this.settings.BULL_RSI_low; + + // ADX trend strength? + if( adx > this.settings.ADX_high ) rsi_hi = rsi_hi + this.BULL_MOD_high; + else if( adx < this.settings.ADX_low ) rsi_low = rsi_low + this.BULL_MOD_low; + + if( rsi > rsi_hi ) this.short(); + else if( rsi < rsi_low ) this.long(); + else this.pingPong(); + + if(this.debug) this.lowHigh( rsi, 'bull' ); + } + + // add adx low/high if debug + if( this.debug ) this.lowHigh( adx, 'adx'); + + }, // check() + + + /* LONG */ + long: function() + { + if( this.trend.direction !== 'up' ) // new trend? (only act on new trends) + { + this.resetTrend(); + this.trend.direction = 'up'; + this.trend.longPos = this.candle.close; + this.advice('long'); + if( this.debug ) log.info('Going long'); + } + + if( this.debug ) + { + this.trend.duration++; + log.info('Long since', this.trend.duration, 'candle(s)'); + } + }, + + + /* SHORT */ + short: function() + { + // new trend? (else do things) + if( this.trend.direction !== 'down' ) + { + this.resetTrend(); + this.trend.direction = 'down'; + this.trend.longPos = false; + this.advice('short'); + if( this.debug ) log.info('Going short'); + } + + if( this.debug ) + { + this.trend.duration++; + log.info('Short since', this.trend.duration, 'candle(s)'); + } + }, + + pingPong: function() { + + /** + * Si actualmente tenemos una posicion long abierta vamos a comprobar si el precio + * actual del asset es un más alto (trend.long + %gainsPercentage >= currentPrice) + * y si es así cerramos la posición. + */ + if (this.trend.longPos) { + + /** + * Si tenemos una posicion long abierta pero la tendencia actual es bullish entonces + * no hacemos nada y dejamos que siga subiendo + */ + //if (this.trend.direction == 'up') return; + + if (this.candle.close < (this.trend.longPos - (this.trend.longPos * (this.trend.pingPong.gainsPercentage / 3) / 100))) this.trend.longPos = this.candle.close; + + /** + * Si no tenemos un porcentage de ganancias salimos de aqui + */ + if (this.candle.close < (this.trend.longPos + (this.trend.longPos * this.trend.pingPong.gainsPercentage / 100) )) return; + + /** + * Si hemos llegado hasta aqui significa que tenemos un long abierto, la tendencia actual es + * bajista y tenemos un de ganancias, por lo tanto cerramos la posicion + * para recoger ganancias y ponemos el longPos en false. + */ + this.trend.longPos = false; + this.advice('short'); + + + /** + * Si hemos llegado hasta aqui significa que no tenemos ninguna posicion long abierta, por lo tanto + * podemos aprovechar para abrir una nueva posicion cuando sea el momento propicio. + */ + } else { + + /** + * Si estamos en tendencia bajista salimos de aqui sin hacer nada, asi dejamos que siga + * bajando y solo actuamos cuando la tendencia cambie a alcista (bullish). + */ + if (this.trend.direction == 'down') return; + + /** + * Si ha bajado al menos un abrimos un nuevo long + */ + //if (this.candle.close < (this.trend.longPos - (this.trend.longPos * this.trend.pingPong.gainsPercentage / 100) )) return; + + + /** + * Si hemos llegado hasta aqui significa que se cumple los requisitos necesarios para volver a + * abrir una posicion long, por lo tanto ejecutamos un long y ademas guardamos el precio de la + * candle actual para saber a que precio hemos iniciado el long. + */ + this.trend.longPos = this.candle.close; + this.advice('long'); + + } + }, + + + /* END backtest */ + end: function() + { + let seconds = ((new Date()- this.startTime)/1000), + minutes = seconds/60, + str; + + minutes < 1 ? str = seconds.toFixed(2) + ' seconds' : str = minutes.toFixed(2) + ' minutes'; + + log.info('===================================='); + log.info('Finished in ' + str); + log.info('===================================='); + + // print stats and messages if debug + if(this.debug) + { + let stat = this.stat; + log.info('BEAR RSI low/high: ' + stat.bear.min + ' / ' + stat.bear.max); + log.info('BULL RSI low/high: ' + stat.bull.min + ' / ' + stat.bull.max); + log.info('ADX min/max: ' + stat.adx.min + ' / ' + stat.adx.max); + } + + } + +}; + +module.exports = strat; diff --git a/RSI_BULL_BEAR_ADX_PINGPONG/RSI_BULL_BEAR_ADX_PINGPONG.toml b/RSI_BULL_BEAR_ADX_PINGPONG/RSI_BULL_BEAR_ADX_PINGPONG.toml new file mode 100644 index 0000000..5bec9bd --- /dev/null +++ b/RSI_BULL_BEAR_ADX_PINGPONG/RSI_BULL_BEAR_ADX_PINGPONG.toml @@ -0,0 +1,27 @@ +# SMA INDICATOR +SMA_long = 1000 +SMA_short = 50 + +# RSI BULL +BULL_RSI = 10 +BULL_RSI_high = 80 +BULL_RSI_low = 60 + +# RSI BEAR +BEAR_RSI = 15 +BEAR_RSI_high = 50 +BEAR_RSI_low = 20 + +# MODIFY RSI (depending on ADX) +BULL_MOD_high = 5 +BULL_MOD_low = -5 +BEAR_MOD_high = 15 +BEAR_MOD_low = -5 + +# ADX +ADX = 3 +ADX_high = 70 +ADX_low = 50 + +# PING PONG +PINGPONG_GAINS_PERCENTAGE = 2 diff --git a/RSI_Bull_Bear_Adx_Stop/RSI_Bull_Bear_Adx_Stop.js b/RSI_Bull_Bear_Adx_Stop/RSI_Bull_Bear_Adx_Stop.js new file mode 100644 index 0000000..88b19ce --- /dev/null +++ b/RSI_Bull_Bear_Adx_Stop/RSI_Bull_Bear_Adx_Stop.js @@ -0,0 +1,237 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies +/* + RSI Bull and Bear + ADX modifier + 1. Use different RSI-strategies depending on a longer trend + 2. But modify this slighly if shorter BULL/BEAR is detected + - + 12 feb 2017 + - + (CC-BY-SA 4.0) Tommie Hansen + https://creativecommons.org/licenses/by-sa/4.0/ +*/ + +// req's +var log = require('../core/log.js'); +var config = require('../core/util.js').getConfig(); + +// strategy +var strat = { + + /* INIT */ + init: function() { + this.name = 'RSI Bull and Bear + ADX'; + this.requiredHistory = config.tradingAdvisor.historySize; + this.resetTrend(); + + // debug? set to flase to disable all logging/messages/stats (improves performance) + this.debug = false; + config.backtest.batchSize = 20000 //reduce db reads + + //GA Settings CHECK + log.debug('SMA Long: ' + this.settings.SMA_long); + log.debug('SMA Short: ' + this.settings.SMA_short); + log.debug('Bull RSI: ' + this.settings.BULL_RSI); + log.debug('Bear RSI: ' + this.settings.BEAR_RSI); + + // performance + config.backtest.batchSize = 1000; // increase performance + config.silent = true; + config.debug = false; + + // SMA + this.addTulipIndicator('maSlow', 'sma', { + optInTimePeriod: this.settings.SMA_long + }); + this.addTulipIndicator('maFast', 'sma', { + optInTimePeriod: this.settings.SMA_short + }); + + // RSI + this.addTulipIndicator('BULL_RSI', 'rsi', { + optInTimePeriod: this.settings.BULL_RSI + }); + this.addTulipIndicator('BEAR_RSI', 'rsi', { + optInTimePeriod: this.settings.BEAR_RSI + }); + + // ADX + this.addTulipIndicator('ADX', 'adx', { + optInTimePeriod: this.settings.ADX + }) + + // MOD (RSI modifiers) + this.BULL_MOD_high = this.settings.BULL_MOD_high; + this.BULL_MOD_low = this.settings.BULL_MOD_low; + this.BEAR_MOD_high = this.settings.BEAR_MOD_high; + this.BEAR_MOD_low = this.settings.BEAR_MOD_low; + + // Stop Loss + this.lastLongPrice = 0; // start at 0 + + + // debug stuff + this.startTime = new Date(); + + // add min/max if debug + if (this.debug) { + this.stat = { + adx: { + min: 1000, + max: 0 + }, + bear: { + min: 1000, + max: 0 + }, + bull: { + min: 1000, + max: 0 + } + }; + } + + }, // init() + + + /* RESET TREND */ + resetTrend: function() { + var trend = { + duration: 0, + direction: 'none', + longPos: false, + }; + + this.trend = trend; + }, + + + /* get low/high for backtest-period */ + lowHigh: function(val, type) { + let cur; + if (type == 'bear') { + cur = this.stat.bear; + if (val < cur.min) this.stat.bear.min = val; // set new + else if (val > cur.max) this.stat.bear.max = val; + } else if (type == 'bull') { + cur = this.stat.bull; + if (val < cur.min) this.stat.bull.min = val; // set new + else if (val > cur.max) this.stat.bull.max = val; + } else { + cur = this.stat.adx; + if (val < cur.min) this.stat.adx.min = val; // set new + else if (val > cur.max) this.stat.adx.max = val; + } + }, + + + /* CHECK */ + check: function(candle) { + // get all indicators + let ind = this.tulipIndicators, + maSlow = ind.maSlow.result.result, + maFast = ind.maFast.result.result, + rsi, + adx = ind.ADX.result.result; + + + if (candle.close < this.lastLongPrice * (this.settings.Stop_Loss_Percent / 100)) { + this.short(); + } + // BEAR TREND + else if (maFast < maSlow) { + rsi = ind.BEAR_RSI.result.result; + let rsi_hi = this.settings.BEAR_RSI_high, + rsi_low = this.settings.BEAR_RSI_low; + + // ADX trend strength? + if (adx > this.settings.ADX_high) rsi_hi = rsi_hi + this.BEAR_MOD_high; + else if (adx < this.settings.ADX_low) rsi_low = rsi_low + this.BEAR_MOD_low; + + if (rsi > rsi_hi) this.short(); + else if (rsi < rsi_low) this.long(candle); + + if (this.debug) this.lowHigh(rsi, 'bear'); + } + + // BULL TREND + else { + rsi = ind.BULL_RSI.result.result; + let rsi_hi = this.settings.BULL_RSI_high, + rsi_low = this.settings.BULL_RSI_low; + + // ADX trend strength? + if (adx > this.settings.ADX_high) rsi_hi = rsi_hi + this.BULL_MOD_high; + else if (adx < this.settings.ADX_low) rsi_low = rsi_low + this.BULL_MOD_low; + + + if (rsi > rsi_hi) this.short(); + else if (rsi < rsi_low) this.long(candle); + if (this.debug) this.lowHigh(rsi, 'bull'); + } + + // add adx low/high if debug + if (this.debug) this.lowHigh(adx, 'adx'); + + }, // check() + + + /* LONG */ + long: function(candle) { + if (this.trend.direction !== 'up') // new trend? (only act on new trends) + { + this.resetTrend(); + this.trend.direction = 'up'; + this.advice('long'); + this.lastLongPrice = candle.close; + if (this.debug) log.info('Going long'); + } + + if (this.debug) { + this.trend.duration++; + log.info('Long since', this.trend.duration, 'candle(s)'); + } + }, + + + /* SHORT */ + short: function() { + // new trend? (else do things) + if (this.trend.direction !== 'down') { + this.resetTrend(); + this.trend.direction = 'down'; + this.advice('short'); + if (this.debug) log.info('Going short'); + } + + if (this.debug) { + this.trend.duration++; + log.info('Short since', this.trend.duration, 'candle(s)'); + } + }, + + + /* END backtest */ + end: function() { + let seconds = ((new Date() - this.startTime) / 1000), + minutes = seconds / 60, + str; + + minutes < 1 ? str = seconds.toFixed(2) + ' seconds' : str = minutes.toFixed(2) + ' minutes'; + + log.info('===================================='); + log.info('Finished in ' + str); + log.info('===================================='); + + // print stats and messages if debug + if (this.debug) { + let stat = this.stat; + log.info('BEAR RSI low/high: ' + stat.bear.min + ' / ' + stat.bear.max); + log.info('BULL RSI low/high: ' + stat.bull.min + ' / ' + stat.bull.max); + log.info('ADX min/max: ' + stat.adx.min + ' / ' + stat.adx.max); + } + + } + +}; + +module.exports = strat; \ No newline at end of file diff --git a/RSI_Bull_Bear_Adx_Stop/RSI_Bull_Bear_Adx_Stop.toml b/RSI_Bull_Bear_Adx_Stop/RSI_Bull_Bear_Adx_Stop.toml new file mode 100644 index 0000000..daf538e --- /dev/null +++ b/RSI_Bull_Bear_Adx_Stop/RSI_Bull_Bear_Adx_Stop.toml @@ -0,0 +1,27 @@ +# SMA Trends +SMA_long = 1000 +SMA_short = 50 + +# BULL +BULL_RSI = 10 +BULL_RSI_high = 80 +BULL_RSI_low = 60 + +# BEAR +BEAR_RSI = 15 +BEAR_RSI_high = 50 +BEAR_RSI_low = 20 + +# MODIFY RSI (depending on ADX) +BULL_MOD_high = 5 +BULL_MOD_low = -5 +BEAR_MOD_high = 15 +BEAR_MOD_low = -5 + +# ADX +ADX = 3 +ADX_high = 70 +ADX_low = 50 + +# Stop Loss +Stop_Loss_Percent = 50 diff --git a/RsiStopLoss/RsiStopLoss.js b/RsiStopLoss/RsiStopLoss.js new file mode 100644 index 0000000..6fd4d8b --- /dev/null +++ b/RsiStopLoss/RsiStopLoss.js @@ -0,0 +1,220 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies +// Source: https://raw.githubusercontent.com/RevREB/gekko-estrategias/stable/strategies/RsiStopLoss.js +/* + + RSI - cykedev 14/02/2014 + + (updated a couple of times since, check git history) + + */ +// helpers +var _ = require('lodash'); +var log = require('../core/log.js'); + +var RSI = require('./indicators/RSI.js'); + +// let's create our own method +var method = {}; + +// prepare everything our method needs +method.init = function () { + this.name = 'RsiStopLoss'; + + this.trend = { + direction: 'none', + duration: 0, + persisted: false, + adviced: false, + }; + this.stop = {}; + this.stop = { + stop: 5, + gain: 5, + progressive: true, + progressiveGain: 2, + persisted: false, + duration: 0, + buy: false, + buyValue: 0, + stopValue: 0, + gainValue: 0, + + } + + if(this.settings && this.settings.stoploss) + this.stop = Object.assign(this.stop,this.settings.stoploss) + + this.requiredHistory = this.tradingAdvisor.historySize; + + // define the indicators we need + this.addIndicator('rsi', 'RSI', this.settings); +} + +// for debugging purposes log the last +// calculated parameters. +method.log = function (candle) { + // var digits = 8; + // var rsi = this.indicators.rsi; + + // log.debug('calculated RSI properties for candle:'); + // log.debug('\t', 'rsi:', rsi.result.toFixed(digits)); + // log.debug('\t', 'price:', candle.close.toFixed(digits)); +} + +method.check = function (candle) { + var rsi = this.indicators.rsi; + var rsiVal = rsi.result; + var digits = 8; + candleExample = { + id: 99039, + start: "2018-01-03T14:43:00.000", + open: 15000.00000009, + high: 15070, + low: 14770, + close: 14887.99999971, + vwp: 14886.873751966494, + volume: 338.5315601699998, + trades: 2580 + } + + //log.debug('Novo candle', rsi.lastClose.toFixed(digits), rsiVal) + + if (rsiVal > this.settings.thresholds.high) { // Venda + + if (!this.stop.buy) { + // new trend detected + if (this.trend.direction !== 'high') + this.trend = { + duration: 0, + persisted: false, + direction: 'high', + adviced: false + }; + + this.trend.duration++; + + log.debug('In high since', this.trend.duration, 'candle(s)'); + + if (this.trend.duration >= this.settings.thresholds.persistence) + this.trend.persisted = true; + + // if (this.trend.persisted && !this.trend.adviced) { + // this.trend.adviced = true; + // this.stop.buy = false; + // this.advice('short'); + // log.debug('short a => ', candle.vwp.toFixed(digits)) + // } else + this.advice(); + } else { + this.advice(); + } + + } else if (rsiVal < this.settings.thresholds.low) { // Compra + if (!this.stop.buy) { + // new trend detected + if (this.trend.direction !== 'low') + this.trend = { + duration: 0, + persisted: false, + direction: 'low', + adviced: false + }; + + this.trend.duration++; + + log.debug('In low since', this.trend.duration, 'candle(s)'); + + if (this.trend.duration >= this.settings.thresholds.persistence) + this.trend.persisted = true; + + if (this.trend.persisted && !this.trend.adviced) { + this.trend.adviced = true; + this.advice('long'); + log.debug('Compra - long a => ', candle.close.toFixed(digits)) + this.stop.buy = true; + this.stop.buyValue = candle.close; + this.stop.stopValue = this.stop.buyValue - (this.stop.buyValue * (this.stop.stop / 100)); + this.stop.gainValue = this.stop.buyValue + (this.stop.buyValue * (this.stop.gain / 100)); + log.debug('Limit STOP: ', this.stop.stopValue.toFixed(digits), 'GAIN: ', this.stop.gainValue.toFixed(digits)) + } else + this.advice(); + } + else{ + this.advice(); + } + + } else { // proteção com stop loss e gain (progressivo) + + // this.stop.stopValue = this.stop.buyValue - (this.stop.buyValue * (this.stop.stop / 100)); + // this.stop.gainValue = this.stop.buyValue + (this.stop.buyValue * (this.stop.gain / 100)); + + if (this.stop.buy) { //Se estou comprado + + if (this.candle.close <= this.stop.stopValue) { //Venda atingiu o stop + this.trend.adviced = true; + this.stop.buy = false; + this.advice('short'); + log.debug('Venda através do stop(LOW) => ', candle.vwp.toFixed(digits)) + } else if (this.candle.close > this.stop.gainValue) { //Se o candle atingiu o topo + + if (this.stop.progressiveGain) { //Se o stop é progressivo + //Atualiza o valor de compra de acordo com o ganho progressivo + this.stop.buyValue = this.stop.buyValue + (this.stop.buyValue * (this.stop.progressiveGain / 100)); + // e recalcula os novos limits de stop e gain + this.stop.stopValue = this.stop.buyValue - (this.stop.buyValue * (this.stop.stop / 100)); + this.stop.gainValue = this.stop.buyValue + (this.stop.buyValue * (this.stop.gain / 100)); + this.advice(); + log.debug('Recalculado o novo limit STOP: ', this.stop.stopValue.toFixed(digits), 'GAIN: ', this.stop.gainValue.toFixed(digits)) + } else { // Se não for progressivo - Venda com o ganho atingido + this.trend.adviced = true; + this.stop.buy = false; + this.advice('short'); + log.debug('Venda através do stop(GAIN) => ', candle.vwp.toFixed(digits)) + } + + } + + + + + //log.debug(this.stop); + + } else { + this.advice(); + } + } +} + +module.teste = function () { + //Na estratégia init, crie a variável stoploss: + this.stop = ""; + + // if (logic that determines a sell || this.stop != "" && price < this.stop) { + + // // se você quiser mostrar uma parada que está sendo acionada no console: + // if (this.stop != "" && price < this.stop) { + // console.log("stoplosss triggered - " + this.stop); + // } + + // this.direction = "short"; + // if (this.trend == "long") { + // this.stop = ""; + // this.trend = this.direction; + // this.advice(this.direction); + // } + + // } else if (logic that determines a buy) { + // if (this.stop == "") { + // // configura o stoploss, você deve fazer o .2 uma variável na configuração de estratégia realmente + // this.stop = price - (price * .2); + // this.direction = "long"; + // this.trend = this.direction; + // this.advice(this.direction); + // } + // } + +} + + + +module.exports = method; diff --git a/RsiStopLoss/RsiStopLoss.toml b/RsiStopLoss/RsiStopLoss.toml new file mode 100644 index 0000000..fc85f52 --- /dev/null +++ b/RsiStopLoss/RsiStopLoss.toml @@ -0,0 +1,13 @@ +# Source: https://raw.githubusercontent.com/RevREB/gekko-estrategias/stable/config/strategies/RsiStopLoss.toml +interval = 14 + +[thresholds] +low = 30 +high = 70 +persistence = 1 + +[stoploss] +loss = 5 +gain = 8 +progressive = true +progressivegain = 2 diff --git a/Supertrend_Gab0/Supertrend_Gab0.js b/Supertrend_Gab0/Supertrend_Gab0.js new file mode 100644 index 0000000..4492eda --- /dev/null +++ b/Supertrend_Gab0/Supertrend_Gab0.js @@ -0,0 +1,100 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies +// Source: https://github.com/Gab0/gekko-adapted-strategies + +// Let's create our own strategy + +var log = require('../core/log.js'); + + +var strat = {}; + +// Prepare everything our strat needs +strat.init = function() { + // your code! + this.requiredHistory = this.tradingAdvisor.historySize; + + this.addIndicator("myAtr", "ATR", this.settings.atrEma); + this.bought = 0; + + this.supertrend = { + upperBandBasic : 0, + lowerBandBasic : 0, + upperBand : 0, + lowerBand : 0, + supertrend : 0, + }; + this.lastSupertrend = { + upperBandBasic : 0, + lowerBandBasic : 0, + upperBand : 0, + lowerBand : 0, + supertrend : 0, + }; + this.lastCandleClose = 0; +} + +// What happens on every new candle? +strat.update = function(candle) { + // your code! +} + +// For debugging purposes. +strat.log = function() { + // your code! +} + +// Based on the newly calculated +// information, check if we should +// update or not. +strat.check = function(candle) { + + var atrResult = this.indicators.myAtr.result; + + this.supertrend.upperBandBasic = ((candle.high + candle.low) / 2) + (this.settings.bandFactor * atrResult); + this.supertrend.lowerBandBasic = ((candle.high + candle.low) / 2) - (this.settings.bandFactor * atrResult); + + if(this.supertrend.upperBandBasic < this.lastSupertrend.upperBand || this.lastCandleClose > this.lastSupertrend.upperBand) + this.supertrend.upperBand = this.supertrend.upperBandBasic; + else + this.supertrend.upperBand = this.lastSupertrend.upperBand; + + if(this.supertrend.lowerBandBasic > this.lastSupertrend.lowerBand || this.lastCandleClose < this.lastSupertrend.lowerBand) + this.supertrend.lowerBand = this.supertrend.lowerBandBasic; + else + this.supertrend.lowerBand = this.lastSupertrend.lowerBand; + + if(this.lastSupertrend.supertrend == this.lastSupertrend.upperBand && candle.close <= this.supertrend.upperBand) + this.supertrend.supertrend = this.supertrend.upperBand; + else if(this.lastSupertrend.supertrend == this.lastSupertrend.upperBand && candle.close >= this.supertrend.upperBand) + this.supertrend.supertrend = this.supertrend.lowerBand; + else if(this.lastSupertrend.supertrend == this.lastSupertrend.lowerBand && candle.close >= this.supertrend.lowerBand) + this.supertrend.supertrend = this.supertrend.lowerBand; + else if(this.lastSupertrend.supertrend == this.lastSupertrend.lowerBand && candle.close <= this.supertrend.lowerBand) + this.supertrend.supertrend = this.supertrend.upperBand; + else + this.supertrend.supertrend = 0 + + if(candle.close > this.supertrend.supertrend && this.bought == 0){ + this.advice("long"); + this.bought = 1; + log.debug("Buy at: ", candle.close); + } + + if(candle.close < this.supertrend.supertrend && this.bought == 1){ + this.advice("short") + this.bought = 0; + log.debug("Sell at: ", candle.close); + } + + this.lastCandleClose = candle.close; + this.lastSupertrend = { + upperBandBasic : this.supertrend.upperBandBasic, + lowerBandBasic : this.supertrend.lowerBandBasic, + upperBand : this.supertrend.upperBand, + lowerBand : this.supertrend.lowerBand, + supertrend : this.supertrend.supertrend, + }; +} + +module.exports = strat; + diff --git a/Supertrend_Gab0/Supertrend_Gab0.toml b/Supertrend_Gab0/Supertrend_Gab0.toml new file mode 100644 index 0000000..068e910 --- /dev/null +++ b/Supertrend_Gab0/Supertrend_Gab0.toml @@ -0,0 +1,3 @@ +atrEma = 13 +bandFactor = 3 + diff --git a/gekko b/gekko new file mode 160000 index 0000000..aa4cafc --- /dev/null +++ b/gekko @@ -0,0 +1 @@ +Subproject commit aa4cafc20f771e2dc2ca1d0d467391c07940a8f3 diff --git a/n8/n8.js b/n8/n8.js index 16cb7e9..9fa4640 100644 --- a/n8/n8.js +++ b/n8/n8.js @@ -1,3 +1,6 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies +// Source: https://justhodl.blogspot.com/ + var convnetjs = require('convnetjs') var z = require('zero-fill') var stats = require('stats-lite') diff --git a/n8_v2/n8_v2.js b/n8_v2/n8_v2.js index cc36b17..d1b1379 100644 --- a/n8_v2/n8_v2.js +++ b/n8_v2/n8_v2.js @@ -1,3 +1,6 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies +// Source: https://justhodl.blogspot.com/ + var convnetjs = require('convnetjs') var z = require('zero-fill') var stats = require('stats-lite') diff --git a/scarface_v2/scarface_v2.js b/scarface_v2/scarface_v2.js new file mode 100644 index 0000000..adac378 --- /dev/null +++ b/scarface_v2/scarface_v2.js @@ -0,0 +1,441 @@ +// Downloaded from: https://github.com/xFFFFF/Gekko-Strategies + +var convnetjs = require('convnetjs') +var z = require('zero-fill') +var stats = require('stats-lite') +var n = require('numbro') +var math = require('mathjs') +const cluster = require('cluster'); +const numCPUs = require('os').cpus().length; +var _ = require('lodash'); +var gauss = require('gauss'); +const deepqlearn = require('convnetjs/build/deepqlearn'); + +var BB = require('./indicators/BB2.js'); //Bollinger Bands +var RSI = require('./indicators/RSI.js'); //RSI +var log = require('../core/log.js'); +var helper = require('../helper.js') + + +// the below line starts you at 0 threads +global.forks = 0; + +// the below line is for calculating the last mean vs the now mean. +var oldmean = 0; +var oldmeanRSI = 0; + +var stop_loss = 0.07; //stop loss +var rsi_high = 70; +var rsi_low = 30; +var oversold = false; + + +var hasbought = false; //confirma compra! + +getOption = function () { + + } + + + + +// let's create our own method +var method = {}; +options = "Options Set"; +options.period = "1m"; +options.period_length = "1m"; +options.activation_1_type = "regression"; +options.neurons_1 = 25; +options.depth = 1; +options.selector = "Binance.BNB-BTC"; +options.min_periods = 1000; +options.min_predict = 1; +options.momentum =0.2; +options.decay = 0.1; +options.threads = 4; +options.learns = 2; + + +//settings - BB +var customBBSettings = { + TimePeriod: 20, + NbDevUp: 2, + NbDevDn: 2, + persistence_upper: 10, + persistence_lower: 10, + Matype:0 + }; + + + //EMA config + var customEMAShortSettings = { + optInTimePeriod: 10 + }; + + var customEMAMediumSettings = { + optInTimePeriod: 21 + }; + + var customEMALongSettings = { + optInTimePeriod: 100 + //persistence: 0 + }; + + +var stochParams = { + optInFastKPeriod: 8, + optInSlowKPeriod: 3, + optInSlowDPeriod: 3 + }; + + +neural = undefined; +neuralRSI = undefined; +// prepare everything our method needs +method.init = function() { + this.requiredHistory = this.tradingAdvisor.historySize; + + //indicators + this.addIndicator('bb', 'BB', customBBSettings); //bollinger bands + this.addIndicator('rsi', 'RSI', {interval:6}); + this.addTulipIndicator('myEMAShort', 'ema', customEMAShortSettings); + this.addTulipIndicator('myEMAMedium', 'ema', customEMAMediumSettings); + this.addTulipIndicator('myEMALong', 'ema', customEMALongSettings); + + + if (neural === undefined) { + // Create the net the first time it is needed and NOT on every run + neural = { + net : new convnetjs.Net(), + layer_defs : [ + {type:'input', out_sx:4, out_sy:4, out_depth:options.depth}, + {type:'fc', num_neurons:options.neurons_1, activation:options.activation_1_type}, + {type:'regression', num_neurons:5} + ], + neuralDepth: options.depth + } + neural.net.makeLayers(neural.layer_defs); + neural.trainer = new convnetjs.SGDTrainer(neural.net, {learning_rate:0.05, momentum:options.momentum, batch_size:10, l2_decay:options.decay}); + } + if (neuralRSI === undefined) { + // Create the net the first time it is needed and NOT on every run + neuralRSI = { + net : new convnetjs.Net(), + layer_defs : [ + {type:'input', out_sx:4, out_sy:4, out_depth:options.depth}, + {type:'fc', num_neurons:options.neurons_1, activation:options.activation_1_type}, + {type:'regression', num_neurons:5} + ], + neuralDepth: options.depth + } + neuralRSI.net.makeLayers(neuralRSI.layer_defs); + neuralRSI.trainer = new convnetjs.SGDTrainer(neuralRSI.net, {learning_rate:0.05, momentum:options.momentum, batch_size:10, l2_decay:options.decay}); + } +} + + + +var haspredicted = false; +var predictioncount = 0; +var maxaccuracy = 0; +var maxaccuracyRSI = 0; +var lowaccuracy = 0; +var lowaccuracyRSI = 0; +var highpeak =6; +var highpeakRSI =6; +var lowpeak =-100; +var lowpeakRSI =-100; + +var buyprice = 0; +var profitbuy = 0; + + +//Candle Heinsi Ashi +var calcHACandle = {}; +var xcloseprev = 0; +var xopenprev = 0; +var result = { + xclose: 0, + xopen: 0, + xhigh: 0, + xlow: 0 +}; + + +calcHACandle = function(candle) { + + xcloseprev = result.xclose; + xopenprev = result.xopen; + + // Calculate new Heikin-Ashi candles + result.xclose = (candle.open + candle.close + candle.high + candle.low)/4; + // xOpen = [xOpen(Previous Bar) + xClose(Previous Bar)]/2 + result.xopen = (xopenprev + xcloseprev)/2; + // xHigh = Max(High, xOpen, xClose) + result.xhigh = math.max(candle.high, result.xopen, result.xclose); + // xLow = Min(Low, xOpen, xClose) + result.xlow = math.min(candle.low, result.xopen, result.xclose); + + return result; +} ; //calculo de velas + + + +// what happens on every new candle? +method.update = function(candle) { + + var digits = 8; + + //Heinki-Ashi + this.HACandle = calcHACandle(candle); + this.HCL = (this.HACandle.xhigh + this.HACandle.xclose + this.HACandle.xopen) /3; + + //EMA's + this.myEMAShort = this.tulipIndicators.myEMAShort.result.result; + this.myEMAMedium = this.tulipIndicators.myEMAMedium.result.result; + this.myEMALong = this.tulipIndicators.myEMALong.result.result; + + //RSI + StochRSI + + + + Price.push(this.HACandle.xclose); //price + RSIs.push(this.indicators.rsi.result); //rsi + + if(Price.length > 2) + { + var tlp = [] + var tll = [] + + var my_data = Price; + var learn = function () { + for (var i = 0; i < Price.length - 1; i++) { + var data = my_data.slice(i, i + 1); + var real_value = [my_data[i + 1]]; + var x = new convnetjs.Vol(data); + neural.trainer.train(x, real_value); + var predicted_values =neural.net.forward(x); + var accuracy = predicted_values.w[0] -real_value + var accuracymatch = predicted_values.w[0] == real_value; + var rewardtheybitches = neural.net.backward(accuracymatch); + if(accuracy > 0) + { + if(accuracy > maxaccuracy) {maxaccuracy = accuracy} + } + if(accuracy <0) + { + if(accuracy < lowaccuracy) {lowaccuracy = accuracy} + + } + } + } + learn(); + var my_data_RSI = RSIs; + var learnRSI = function () { + for (var i = 0; i < RSIs.length - 1; i++) { + var data = my_data_RSI.slice(i, i + 1); + var real_value = [my_data_RSI[i + 1]]; + var x = new convnetjs.Vol(data); + neuralRSI.trainer.train(x, real_value); + var predicted_values = neuralRSI.net.forward(x); + var accuracyRSI = predicted_values.w[0] - real_value; + var accuracymatch = predicted_values.w[0] == real_value; + var rewardtheybitches = neuralRSI.net.backward(accuracymatch); + if(accuracyRSI > 0) + { + if(accuracyRSI > maxaccuracyRSI) {maxaccuracyRSI = accuracyRSI} + } + if(accuracyRSI <0) + { + if(accuracyRSI < lowaccuracyRSI) {lowaccuracyRSI = accuracyRSI} + + } + } + } + learnRSI(); + predictioncount++; + haspredicted = true; + // var json = neural.net.toJSON(); + // // the entire object is now simply string. You can save this somewhere + // var str = JSON.stringify(json); + // log.debug(str); + + } +} + + +method.log = function() { + + //console.log('prediction', prediction, mean, percentvar); + var digits = 8; +/* + log.debug('______________________________________'); + log.debug('calculated EMA:'); + log.debug('EMA Short:', this.myEMAShort); + log.debug('EMA Medium:', this.myEMAMedium); + log.debug('EMA Long:', this.myEMALong); +*/ + + //log.debug('______________________________________'); + //log.debug('calculated StochRSI properties for candle:'); + //log.debug('\t', 'rsi:', this.rsi.toFixed(digits)); + //log.debug("StochRSI min:\t\t" + this.lowestRSI.toFixed(digits)); + //log.debug("StochRSI max:\t\t" + this.highestRSI.toFixed(digits)); + //log.debug("StochRSI Value:\t\t" + this.stochRSI.toFixed(2)); + +/* + log.debug('______________________________________'); + log.debug('calculated BB properties for candle:'); + if (BB.upper>this.HACandle.xclose) log.debug('\t', 'Upper BB:', BB.upper.toFixed(digits)); + if (BB.middle>this.HACandle.xclose) log.debug('\t', 'Mid BB:', BB.middle.toFixed(digits)); + if (BB.lower>=this.HACandle.xclose) log.debug('\t', 'Lower BB:', BB.lower.toFixed(digits)); + log.debug('\t', 'Price:',this.HACandle.xclose.toFixed(digits)); + if (BB.upper<=this.HACandle.xclose) log.debug('\t', 'Upper BB:', BB.upper.toFixed(digits)); + if (BB.middle<=this.HACandle.xclose) log.debug('\t', 'Mid BB:', BB.middle.toFixed(digits)); + if (BB.lower 1000) + { + var item = Price; + prediction = predict(item); + predictionRSI = predictRSI(RSIs); + mean = Price[Price.length -1]; + lastRSI = RSIs[RSIs.length-1]; + oldmeanRSI = predictionRSI; + oldmean = prediction; + + meanp = math.mean(prediction, mean); + meanpRSI = math.mean(predictionRSI, lastRSI); + global.meanpRSI = meanpRSI; + global.meanp = meanp + global.mean = mean + global.lastRSI = lastRSI; + + var percentvar = (meanp-mean)/mean * 100; + var percentvarRSI = (meanpRSI-lastRSI)/lastRSI * 100; + if(percentvarRSI < 0) { + //predictionRSI += lowaccuracyRSI; + percentvarRSI += lowaccuracyRSI; + if(lowpeakRSI > percentvarRSI) { lowpeakRSI = percentvarRSI;} + } + if(percentvarRSI > 0) { + + //predictionRSI -= maxaccuracyRSI; + percentvarRSI -= maxaccuracyRSI; + if(highpeakRSI < percentvarRSI) { highpeakRSI = percentvarRSI;} + } + if(percentvar < 0) { + prediction += lowaccuracy; + percentvar += lowaccuracy; + if(lowpeak > percentvar) { lowpeak = percentvar;} + } + if(percentvar > 0) { + + prediction -= maxaccuracy; + percentvar -= maxaccuracy; + if(highpeak < percentvar) { highpeak = percentvar;} + } + + //console.log('prediction', prediction, mean, percentvar); + //console.log('predictionRSI', predictionRSI, lastRSI, percentvarRSI); + +/* + log.debug('______________________________________'); + log.debug('NN RSI:'); + log.debug('predictionRSI', predictionRSI); + log.debug('lastRSI', lastRSI); + log.debug('percentvarRSI', percentvarRSI); +*/ + + global.sig0 = global.meanp < global.mean && meanp != 0 + global.sig0RSI = global.meanpRSI < global.lastRSI && meanpRSI != 0 + + //check RSI + if (this.indicators.rsi.result > rsi_high) + { + oversold = true; + } + else oversold = false; + + + //console.log('precentvar', percentvar, global.sig0); + //console.log('percentvarRSI', percentvarRSI, global.sig0RSI); + + if ((global.sig0 === false && percentvar > 1.70 || (global.sig0RSI === true && this.indicators.rsi.result < rsi_low) || (Price <= BB.lower)) && (hasbought===false) ) + { + + //log.write("IA - Buy - Predicted variation: ",percentvar); + log.debug("IA - Buy - AT: \t\t",this.HACandle.xclose); + hasbought = true; //has buy! + meanp = 0 + mean = 0; + haspredicted = false; + buyprice = this.HACandle.xclose; + + // ManageSize(); + return this.advice('long'); + } + else if + ( (oversold && (buyprice - this.HACandle.xclose) / buyprice > stop_loss) || ((global.sig0 === true && percentvar+0.5 < -0.90 || (global.sig0RSI === false && this.indicators.rsi.result > rsi_high) || (Price >= BB.upper)) && (hasbought)) ) + { + profit = (this.HACandle.xclose - buyprice)/buyprice*100; + log.debug("IA - Sell - At: \t",this.HACandle.xclose, 'profit:', profit.toFixed(2)); + + meanp = 0 + mean = 0; + hasbought = false; //has buy! + haspredicted = false; + + buyprice = 0; + profitbuy = 0; + return this.advice('short'); + } + + }else{ + log.write('not enough predictions:', predictioncount); + } + + + +} + +module.exports = method; diff --git a/x2_rsi/x2_rsi.js b/x2_rsi/x2_rsi.js new file mode 100644 index 0000000..3e5bb95 --- /dev/null +++ b/x2_rsi/x2_rsi.js @@ -0,0 +1,187 @@ +/* + + RSI - cykedev 14/02/2014 + + (updated a couple of times since, check git history) + + */ +// helpers +var _ = require('lodash'); +var log = require('../core/log.js'); + +var RSI = require('./indicators/RSI.js'); + +// let's create our own method +var method = {}; +var fatherOnLowPoint = false; +// prepare everything our method needs +method.init = function () +{ + this.name = 'RSI'; + + this.trend = { + direction: 'none', + duration: 0, + persisted: false, + adviced: false + }; + + this.trendFather = { + direction: 'none', + duration: 0, + persisted: false, + adviced: false + }; + + this.requiredHistory = this.tradingAdvisor.historySize; + + // define the indicators we need + this.addIndicator('rsi', 'RSI', this.settings); + this.addIndicator('rsiFather', 'RSI', { interval: this.settings.interval + 5 , low: this.settings.low + 3, high: this.settings.high-5 }); +} + +// for debugging purposes log the last +// calculated parameters. +method.log = function (candle) +{ + var digits = 8; + var rsi = this.indicators.rsi; + + log.debug('calculated RSI properties for candle:'); + log.debug('\t', 'rsi:', rsi.result.toFixed(digits)); + log.debug('\t', 'price:', candle.close.toFixed(digits)); +} + +method.check = function () +{ + var rsi = this.indicators.rsi; + var rsiFather = this.indicators.rsiFather; + var rsiVal = rsi.result; + var rsiValFather = rsiFather.result; + + //RSI FATHER MAIN ---------------- + if (rsiValFather > this.settings.thresholds.high) + { + + // new trend detected + if (this.trendFather.direction !== 'high') + this.trendFather = { + duration: 0, + persisted: false, + direction: 'high', + adviced: false + }; + + this.trendFather.duration++; + + log.debug('FATHER ...> high since', this.trendFather.duration, 'candle(s)'); + + if (this.trendFather.duration >= this.settings.thresholds.persistence) + this.trendFather.persisted = true; + + if (this.trendFather.persisted && !this.trendFather.adviced) + { + this.trendFather.adviced = true; + this.fatherOnLowPoint = true; + } + + } else if (rsiValFather < this.settings.thresholds.low) + { + + // new trend detected + if (this.trendFather.direction !== 'low') + this.trendFather = { + duration: 0, + persisted: false, + direction: 'low', + adviced: false + }; + + this.trendFather.duration++; + + log.debug('FATHER ---> IN low since', this.trendFather.duration, 'candle(s)'); + + if (this.trendFather.duration >= this.settings.thresholds.persistence) + this.trendFather.persisted = true; + + if (this.trendFather.persisted && !this.trendFather.adviced) + { + this.trendFather.adviced = true; + this.fatherOnLowPoint = false; + + } + } else + { + + log.debug('In no trend'); + + } + + + //RSI MAIN ---------------- + if (rsiVal > this.settings.thresholds.high) + { + + // new trend detected + if (this.trend.direction !== 'high') + this.trend = { + duration: 0, + persisted: false, + direction: 'high', + adviced: false + }; + + this.trend.duration++; + + log.debug('In high since', this.trend.duration, 'candle(s)'); + + if (this.trend.duration >= this.settings.thresholds.persistence) + this.trend.persisted = true; + + if (this.trend.persisted && !this.trend.adviced && this.trendFather.direction === 'high' ) + { + this.trend.adviced = true; + this.advice('short'); + log.debug('SELL AT ---------->'); + + } else + this.advice(); + + } else if (rsiVal < this.settings.thresholds.low) + { + + // new trend detected + if (this.trend.direction !== 'low') + this.trend = { + duration: 0, + persisted: false, + direction: 'low', + adviced: false + }; + + this.trend.duration++; + + log.debug('In low since', this.trend.duration, 'candle(s)'); + + if (this.trend.duration >= this.settings.thresholds.persistence) + this.trend.persisted = true; + + if (this.trend.persisted && !this.trend.adviced && this.trendFather.direction === 'low' ) + { + this.trend.adviced = true; + this.advice('long'); + log.debug('BUY AT ---------->'); + + } else + this.advice(); + + } else + { + + log.debug('In no trend'); + + this.advice(); + } +} + +module.exports = method; diff --git a/x2_rsi/x2_rsi.toml b/x2_rsi/x2_rsi.toml new file mode 100644 index 0000000..ebc39c4 --- /dev/null +++ b/x2_rsi/x2_rsi.toml @@ -0,0 +1,6 @@ +interval = 14 + +[thresholds] +low = 30 +high = 70 +persistence = 1 \ No newline at end of file