Gab0 / gekko-adapted-strategies

39 stars 16 forks source link

ADX usage #5

Open mo2bel opened 6 years ago

mo2bel commented 6 years ago

Hey, I have an inquiry regarding the usage of the ADX in these strats. As far as I know, the ADX line indicates the strength or weakness of a trend regardless of whether the trend is going up or down. In your code (or the code written originally by Tommie Hansen), the RSI bull and bear values are modified naively once the ADX value reaches the up or down threshold, meaning if the ADX reaches the high threshold, increase the upper RSI threshold and decrease the lower RSI threshold by 5 or whatever the value is. However, ADX can reach this high threshold in a down trend indicating that the down trend is gaining even more momentum so modifying the RSI range to be more bullish would be actually disastrous in such a situation. An alternative would be using the DMI indicator instead as it has 3 lines; ADX line, DI+ line and DI- line where the ADX line signals strength regardless of trend direction (so it should be given just one threshold instead of a high and a low), and the directional signal can be obtained using the other 2 lines; DI+ > DI- = bullish and DI+ < DI- = bearish. Would be awesome if you would share your opinion on the matter and thank you sooooooooo much for all the awesome stuff you code!

Gab0 commented 6 years ago

This kind of discussion around strategy workings is very constructive, and is welcome! I didn't wrote this strat, but if I could I would debate your points. Anyway, lets clarify your points (point if I'm wrong) before calling @TommieHansen, who surely knows better.

1- ADX purpose is to identify trend strength, not trend direction. (true: https://www.investopedia.com/articles/trading/07/adx-trend-indicator.asp)
2- On RBBADX, ADX modifies RSI_BULL and RSI_BEAR values as if it was indicating downtrend when on negative values. That can lead to disastrous results under certain conditions.
3- So, we should change ADX to DMI that has also lines for trend direction.
mo2bel commented 6 years ago

Yes your 3 points are spot on!

tommiehansen commented 6 years ago

The whole RBB ADX strategy was basically made as an example modification of the original RBB strategy. The core idea was again to use a simple A/B switch but on a smaller scale so that one both has macro (SMA) and micro (ADX). Not much thought went in to using ADX specifically though since it was/is merely a result of an exclusion method; testing indicators for the same core idea and check what seems to work best. If you go to tulipindicators.org and check all momentum/strength indicators all of them has basically been tested and all of them ruled out in favor of ADX. It's a "this is the core idea and here's the code for it, so let's throw all these indicators at it and see what seem to work best".

"increase the upper RSI threshold and decrease the lower RSI threshold" No? Just one or the other.

You are correct however that ADX measures thrend strength no matter the direction (bull/bear) though. So if one were to improve it one should reverse the values for BEAR since a strong BEAR-trend would indicate that we should go lower and not the opposite. One idea is to also add a secondary trend (SMA) just for the the ADX in order to clearly see, on a smaller scale, what should be done for the ADX and if/or the values should be reversed.

However RBB ADX should be seen as a sample modification and a sample of one way to code it so that it makes sense and isn't a huge disaster of bad code. Reversing some parts, basically replacing > with < shouldn't be too hard. Shouldn't be too hard either to add a condition for ADX that is based off a smaller scale SMA value.

If i had the time i would try this:

  1. Add another SMA value for the micro scale of things that could be used for ADX (are we going up or down?) This would likely make the ADX indicator more efficient.
  2. Modify the ADX or replace it/try replacing it with something else like DMI as is mentioned here

The problem is that it is very easy to "over-engineer" these sort of things. I really do not want stuff that lack in clarity and becomes somewhat of a mess where it isn't clear what one is actually trying to do or what the reasoning behind it is.

-

A current ongoing modification is also to use percentage values instead of strict values, this in order to simplify it and create relations between high and low. As it is now one can set short to 1000 and long to 100. Not a problem when testing manually but when testing over 100 000 combinations of combinations .. of combinations it becomes less then stellar. It also makes sense that if X = 1000 Y should be some percentage of that if there's a logical relation between those two (e.g. the SMA long and short relation).

Problem now is that it isn't really that simplified since there's still a lot of values:

[SMA]
long = 1000

[RSI]
high = 80
bull = 10
bear = 15

[ADX]
high = 70
low = 30
length = 3

[CALC]
short = 10
low = 80
bear = 75
mod = 10

# short: % of long (10 = 10%)
# low: % of high
# bear: % of high
# mod: % up/down of high/low

Source: https://codepen.io/tommiehansen/pen/NYyOXV

So still too many values which makes it even more complex then the original RBB ADX which is somewhat of a problem. Thus ongoing and not complete, it's just not clear enough for my taste even though i made the percentages whole numbers instead of fractions.

It's basically also a solution to much more easily backtest the strategy in a more automated way since:

long = 100:1000,100
short = 100:1000,100

(min:max,stepping)

...would obviously be less then stellar since short would be higher then long in many cases. Having the "short" be a percentage value of long would rule such a thing out:

long = 100:1000,100
short = long * 0.1

So short is 10% of long, it does not matter if long is 100 or 1000 since 10% of X is always 10% of X.

This makes it much more easy to test more crazy ranges such as 100:3000,200.

This whole modification is of less interest if one doen't do auomated testing though.

But for me it is also a start for future modifications since i want this done before starting to modify other things since if one cannot backtest things properly one cannot statistically prove that A works better then B so proper backtesting is sort of key to ruling things out in a much more proper statistical correct way.

image BNB-USDT, 2017-11-01 > 2018-02-01.

Ignore the profit and look at the total amount of runs. When one reach such numbers one can really start to rule some things out with a much better level of statistical certainty. Basically with confidence say that X generally works and that Y does not.

mo2bel commented 6 years ago

I am going to try some modifications to the the strat if you do not mind @tommiehansen. The percentage idea is pure gold. The micro very short SMA is a plausible solution but still I think DMI would be really powerful as it always compares 2 candles to draw its histogram, so I personally think that it mixes 2 very important aspects of T.A.; the trend direction and strength AND candle stick patterns as well, I will try it out with the micro SMA first and let you know.

Gab0 commented 6 years ago

Nice... RSI_BULL_BEAR_ADX is among the best strategies out there and if it can still be improved, that would only have positive outcomes ;)

tommiehansen commented 6 years ago

@mo2bel Sounds awesome! RBB ADX was, as said, made to be modified. :)

@Gab0 Yes, there is some sort of mod/same core idea called BBRSI that sort of has the same idea but when i looked at it.. it used tulip indicators etc and ... well.. with your ADX-indicator + native indicators one can run 2 years of data in just around 15-20 seconds with 5 min candles. With the Tulip indicators the same run takes over 5 minutes....... Sort of important if one wants to do over 50 000 backtests. :)

It might have changed since i looked at it though.

Gab0 commented 6 years ago

@tommiehansen Yeah, tulip/talib indicators somehow are on slo-mo mode. I should code DMI later for statistical tests, and may code any other someone requests. @mo2bel Nice, keep investigating the strategies. You could join gekko discord server, there is some strategy discussion there. cheers!

tommiehansen commented 6 years ago

Here's a mod for RBB ADX. But in my current testing this doesn't yet yield that much more then the current RBB ADX. The difference is:

Obvious problems are:

Same TOML as for the old one will work with this one though (copy+rename).

CODE

/*
    RSI Bull and Bear + ADX + MOD
    -
    (CC-BY-SA 4.0) Tommie Hansen
    https://creativecommons.org/licenses/by-sa/4.0/
    -
    NOTE: Requires custom indicators found here:
    https://github.com/Gab0/Gekko-extra-indicators
    (c) Gabriel Araujo
    Howto: Download + add to gekko/strategies/indicators
*/

// 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';
        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; // NOTE: You may want to set this to 'false' @ live
        config.debug = false;

        // SMA
        this.addIndicator('maSlow', 'SMA', this.settings.SMA.long );
        this.addIndicator('maFast', 'SMA', this.settings.SMA.short );

        // RSI
        this.addIndicator('BULL_RSI', 'RSI', { interval: this.settings.BULL.rsi });
        this.addIndicator('BEAR_RSI', 'RSI', { interval: this.settings.BEAR.rsi });

        // ADX
        this.addIndicator('ADX', 'ADX', this.settings.ADX.adx );
        this.addIndicator('microSlow', 'SMA', 10 ); // ADX-sma
        this.addIndicator('microFast', 'SMA', 2 ); // ADX-sma

        // 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.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.indicators,
            maSlow = ind.maSlow.result,
            maFast = ind.maFast.result,
            microSlow = ind.microSlow.result,
            microFast = ind.microFast.result,
            rsi,
            adx = ind.ADX.result,
            adx_high, adx_low, bear_local;

        // check adx low/high and micro trends
        adx > this.settings.ADX.high ? adx_high = true : adx_high = false,
        adx < this.settings.ADX.low ? adx_low = true : adx_low = false;
        microFast < microSlow ? bear_local = true : bear_local = false;

        // BEAR TREND
        // NOTE: maFast will always be under maSlow if maSlow can't be calculated
        if( maFast < maSlow )
        {
            rsi = ind.BEAR_RSI.result;
            let rsi_hi = this.settings.BEAR.high,
                rsi_low = this.settings.BEAR.low;

            // ADX -- current local trend
            if( bear_local ) // BEAR local
            {
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.BEAR_MOD_low; // subtract from 'high'
                    rsi_low = rsi_low + this.BEAR_MOD_low; // subtract
                }
            }
            else { // BULL local
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.BEAR_MOD_high; // add to 'high'
                    rsi_low = rsi_low + this.BEAR_MOD_high; // add
                }
            }

            // go long or short
            if( rsi > rsi_hi ) this.short();
            else if( rsi < rsi_low ) this.long();

            if(this.debug) this.lowHigh( rsi, 'bear' );
        }

        // BULL TREND
        else
        {
            rsi = ind.BULL_RSI.result;
            let rsi_hi = this.settings.BULL.high,
                rsi_low = this.settings.BULL.low;

            // ADX -- current local trend
            if( bear_local ) // BEAR local
            {
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.BULL_MOD_low; // subtract from 'high'
                    rsi_low = rsi_low + this.BULL_MOD_low; // subtract
                }
            }
            else { // BULL local
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.BULL_MOD_high; // add to 'high'
                    rsi_low = rsi_low + this.BULL_MOD_high; // add
                }
            }

            if( rsi > rsi_hi ) this.short();
            else if( rsi < rsi_low )  this.long();

            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.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.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;
mo2bel commented 6 years ago

If someone wants to try out this new mod, here are the toml settings for it: (Do not forget to play around with the values to see what works best fore your style of trading)

[SMA] long = 1000 short = 50

[BULL] rsi = 13 high = 75 low = 40 mod_low = -5 mod_high = 5

[BEAR] rsi = 13 high = 40 low = 25 mod_low = -5 mod_high = 15

[ADX] adx = 3

tommiehansen commented 6 years ago

No? It's the same params as with the regular RBB ADX. :)

mo2bel commented 6 years ago

Yeah the toml file on your repository works but the one here is outdated!

tommiehansen commented 6 years ago

Oh. ok.

After over 12 000 total backtests for ZEC/USDT this mod does not seem to yield better results then the ordinary ADX version (which i've tested over 50 000 times with different params via my GAB-tool). I also tested 3x other pairs and in some it yielded a bit better but in most cases it did not. The bad/good trades sort of averages out.

This could be because of the static values for the ADX-SMA trend that's just or whatever but it's quite safe to say that just modifying that bit might not make such a huge difference. I'll probably try it though (meaning adding it as user setting + adding to toml): image

tommiehansen commented 6 years ago

So i did a new mod with all that percentage calculations + better usage of ADX. Unfortunately it is yet again safe to say that the original RBB ADX beats it hands down.

Did a run overnight using my GAB tool and after 8750 runs for XRP/USDT (period: 2016-01-02 > 2018-02-18, over 2 years!) it only managed to get a max of around 350 million % while RBB ADX had a top ten in the ranges 1 trillion > 5,5 trillion % profit.

So the mod and a better usage, logically, for ADX is again confirmed to suck. It's back to the drawing board. But here's the strategy for anyone interested:

/*
    RSI Bull and Bear + ADX
    -
    (CC-BY-SA 4.0) Tommie Hansen
    https://creativecommons.org/licenses/by-sa/4.0/
    -
    NOTE: Requires custom indicators found here:
    https://github.com/Gab0/Gekko-extra-indicators
    (c) Gabriel Araujo
    Howto: Download + add to gekko/strategies/indicators
*/

// 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';
        this.requiredHistory = config.tradingAdvisor.historySize;
        this.resetTrend();
        let settings = this.settings;

        // 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; // NOTE: You may want to set this to 'false' @ live
        config.debug = false;

        /* calculate settings */

        let calc = settings.CALC,
            short = calc.short/100, // convert to %
            low = calc.low/100,
            mod = calc.mod/100;

        // sma calc
        let sma_long = settings.SMA.long,
            sma_short = Math.round( sma_long * short );

        // bull calc
        let bull_high = settings.RSI.high;
        let bull_low = Math.round( bull_high * low );

        this.bull_mod_high = Math.round( bull_high * (mod/2) ), // go lower 'high' with bull
        this.bull_mod_low = Math.round( bull_low * mod );
        this.bull_high = bull_high;
        this.bull_low = bull_low;

        // bear calc
        let bear_high = bull_low;
        let bear_low = Math.round( bear_high * (low/2) );

        this.bear_mod_high = Math.round( bear_high * (mod*2) ), // go higher with bear
        this.bear_mod_low = Math.round( bear_low * mod ); // x % of bear_lwo
        this.bear_high = bear_high;
        this.bear_low = bear_low;

        // adx calc
        let adx_long = settings.ADX.long,
            adx_short = Math.round( adx_long * short ),
            adx_high = settings.ADX.high,
            adx_low = Math.round( adx_high * (low/2) ); // NOTE: this because bull/bear is split in two, adx is not so need lower value

        this.adx_high = adx_high;
        this.adx_low = adx_low;

        /* add indicators and values to scope */

        // SMA
        this.addIndicator('sma_long', 'SMA', sma_long );
        this.addIndicator('sma_short', 'SMA', sma_short );

        // RSI
        this.addIndicator('bull_rsi', 'RSI', { interval: settings.RSI.bull });
        this.addIndicator('bear_rsi', 'RSI', { interval: settings.RSI.bear });

        // ADX
        this.addIndicator('adx', 'ADX', this.settings.ADX.adx );
        this.addIndicator('adx_long', 'SMA', adx_long ); // ADX-sma
        this.addIndicator('adx_short', 'SMA', adx_short ); // ADX-sma       

        // debug stuff
        this.startTime = new Date();

        /* 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.trend = trend;
    },

    /* CHECK */
    check: function()
    {
        // get all indicators
        let ind = this.indicators,
            sma_long = ind.sma_long.result,
            sma_short = ind.sma_short.result,
            adx_long = ind.adx_long.result,
            adx_short = ind.adx_short.result,
            adx = ind.adx.result,
            adx_high, adx_low, bear_local;

        // check adx low/high and micro trends
        adx > this.adx_high ? adx_high = true : adx_high = false,
        adx < this.adx_low ? adx_low = true : adx_low = false;
        adx_short < adx_long ? bear_local = true : bear_local = false;

        /* BEAR TREND */
        // NOTE: sma_long will always be under sma_short if sma_long can't be calculated
        if( sma_short < sma_long )
        {
            let rsi = ind.bear_rsi.result,
                rsi_hi = this.bear_high,
                rsi_low = this.bear_low;

            /* ADX -- current local trend */
            if( bear_local ) // BEAR local
            {
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.bear_mod_low; // subtract from 'high'
                    rsi_low = rsi_low + this.bear_mod_low; // subtract
                }
            }
            else // BULL local
            { 
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.bear_mod_high; // add to 'high'
                    rsi_low = rsi_low + this.bear_mod_high; // add
                }
            }

            // go long or short
            if( rsi > rsi_hi ) this.short();
            else if( rsi < rsi_low ) this.long();

        }

        /* BULL TREND */
        else
        {
            let rsi = ind.bull_rsi.result,
                rsi_hi = this.bull_high,
                rsi_low = this.bull_low;

            /* ADX -- current local trend */
            if( bear_local ) // BEAR local
            {
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.bull_mod_low; // subtract from 'high'
                    rsi_low = rsi_low + this.bull_mod_low; // subtract
                }
            }
            else { // BULL local
                if( adx_high ) // strong
                {
                    rsi_hi = rsi_hi + this.bull_mod_high; // add to 'high'
                    rsi_low = rsi_low + this.bull_mod_high; // add
                }
            }

            if( rsi > rsi_hi ) this.short();
            else if( rsi < rsi_low )  this.long();
        }

    }, // 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');
            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('====================================');

    }

};

module.exports = strat;

TOML:

[SMA]
long = 500

[RSI]
bull = 10
bear = 15
high = 80

[ADX]
adx = 5
long = 20
high = 70

[CALC]
short = 10
low = 80
mod = 20

# short = % of long
# low = % of high
# mod = mod +/- RSI for ADX

Basically ADX uses it's own SMA to determine local (small) trends and then determines if it's a strong BEAR or strong BULL trend and acts accordingly. Since the strat is worse then RBB ADX the only good thing in this strategy is the use of percentage values to simplify the parameters. This is especially important when running tools such as a GA or my own GAB-tool since it cuts down number of possibilities quite a lot:

image

RBB ADX:

image

So this new iteration is much better as a starting point for new modifications since if adding even more indicators it would take forever to determine what a good average is due to the sheer amount of possibilities one would have/create.

The tool used to calc possibilities can be found here: https://codepen.io/tommiehansen/pen/OvKEJV?editors=1000 Just edit it, it changes live.

Gab0 commented 6 years ago

@tommiehansen Cool, so for now the main _ADX version is still the best, but don't you think DMI would do better than a single SMA? I heard stochastic calculations (present on ADX and all lines of DMI) are really good and capture trends more accurately than simple MAs. I'm now into actual trading bot usage (never messed with it). Looks like RBB_ADX is the only strategy that gives profit on paper trader. It seems that there is a heavy distortion between the backtesting world and real trading world, and some kind of strategy operators, like stochastic calculations that are not confined to STOCH indicator, and PSAR, that seems promising, may transition better to real trading than those simple indicators we commonly use. Do you actually run gekko trading bots? Or develop those things by intellectual purporses? I'm running some RBB_DMI evaluations thru GAs and should report here later. DMI indicator is online on my indicator repo. cheers!

tommiehansen commented 6 years ago

From studying different indicators a long SMA is a 100% sure way of knowing what the general trend is. This is pretty simple to check by just firing up tradingview.com and choosing the SMA-values and applying it to different cryptos.

The definition of "long" varies though. For the RBB ADX strategy usually that means somewhere around 300 at 5 min candles (so 1500 minutes / ~25 hours).

I did have an idea of long/short that did not rely on SMA but instead relied on some other indicator. Because the deal with the SMA's is still to get an idea of how things look on the macro scale and then adjust stuff on the micro scale (hence RSI BULL/BEAR -- basically 2x RSI setups for different macro trends). One quite easily use any other indicator and use a long value for it such as another RSI or whatever.

It is certainly possible that DMI could be better however one would have to test and verify that. I haven't checked DMI personally so i wouldn't know. I have checked a plethora of other indicators though.

Basically most that one finds at https://tulipindicators.org/list and that works with Gekko (not all do). This also includes the stochastic oscillator, https://tulipindicators.org/stoch, if i remember correctly. ADX was the best in this case but that was also before i had my tool GAB to actually test things on a more massive scale and really rule out working better -vs- not working better. So basically one could say that the earlier tests were flawed since not enough tests could be done. There's somewhat of a massive statistical difference between manually testing 50 times vs testing over 10 000 times.

An indicator that came close 2nd in those tests were the CMO (Chandes Momentum) indicator: https://tulipindicators.org/cmo

I'm currently evaluating ... and evaluating ... and evaluating. Been too occupied with developing GAB to improve on strategies and actually run things live. GAB was basically built for the task of testing and developing new strategies and doing A/B testing. :)

nmikaty commented 6 years ago

@mo2bel So I've looked into this ADX stuff. What @tommiehansen RSI_BULL_BEAR_ADX actually does is (whatever the macro trend defined by SMAs):

ADX length being very short (3), we should be looking at very short term price action. For me, whatever the macro trend is, what we should be doing instead is pushing the RSI limits away from the price when ADX is high:

It would be different with a longer ADX (14-20), but I think it would be too slow to be efficient with this strategy anyway.

So I gave it a shot and modified my last RBB_ADX_BB strategy (a RSI_BULL_BEAR_ADX_BB rewrite). It is now called RBB_ADX2_BB. It only uses ADX high, no ADX low. It improves my results by 35% on BTCUSD 5 minutes over one year+ (2017-2018). But I'm still struggling to get the results I had with the original one on 3 years.

I will continue playing with it and update here if I find anything mind blowing. @tommiehansen if you want to test your original strategy against the same with just the ADX modification I can rewrite it quickly for you.

I still don't think DMI would help. Whatever the direction of the micro trend is, if ADX is high I just want to push both RSI limits away from the price.

Cheers.