The 'AdxSmas' strategy - Is this strategy profitable or not?

The 'AdxSmas' strategy - Is this strategy profitable or not?

By DutchCryptoDad | DutchCryptoDad | 26 May 2022


In this blog series I will be searching for the best trading strategy for cryptocurrency trading with a trading bot. These posts are complementary to the video's I make on Youtube, which you can watch below.




The trading bot I use is the Freqtrade ( trading bot which not only has good options for bot trading, but also is excellent in backtesting and optimization of trading parameters. Therefore I will use this program to not only trade automatically, but also look for the best strategies and setups.

All code that is specifically written for this strategy or for hyperparameter optimisation is available at the bottom of this post.

If you appreciate the effort I take to create this strategy or optimisation code, then please consider a tip for this post!

The backtesting setup

If you want to know more on how I do these backtests like: which pairs I use, which timeframes and which periods I test, then see this blog post to know more about the approach I use:


In this post I am going to test the ADX SMA’s strategy. This is a strategy that was originally created by Gert Wohlgemuth, otherwise known as ‘berlinguyinca’.

The original time frame for this strategy is the 1 hour timeframe. And we will find out soon enough if this is really the case.

Then there are three indicators used:

  • The ADX with a default time period of 14
  • And two simple moving averages.
  • One with a time period of 3 and one with 6 which are pretty quick i might add

Now the buy and sell settings of this strategy are pretty simple as well:

  • The bot buys when the adx is above 25 and only when there is a crossover of the short sma above the longer sma
  • And the bot has a sell signal when the adx is below 25 again and only when the longer sma crosses above the shorter sma.  Or in other words, if the short sma gets below the long sma.


Stoploss and takeprofit

The ROI setting for this strategy is 0.1 which means that the bot will take profit when at some point there is a 10% profit.

The bot will sell the position if there is a loss of 25%, which is indicated with the stop loss setting.

Initial backtest results

After backtesting, the initial backtest results are as follows:

  • Best timeframe: 1d 
  • Total profit of strategy: 104%
  • Drawdown of strategy: 39%
  • Winrate: around 67%
  • Risk of ruin of strategy: 0.8%


Hyperparameter optimisation

Now The original strategy does not have the option to optimise the parameters except for the default ROI and stop loss settings.

I created a hyperopt file that tries to find the optimal setting for the line that the ADX indicator has to cross to get a bullish signal.

So this time I am going to find out if the momentum level, roi and stop loss can be tweaked to make this strategy perform better than the original settings. I think that changing the ADX line and especially the ROI settings could make a lot of difference for this strategy.

In the Hyperopt session I wil ltry to find the optimal settings for the following parameters:

  • ROI
  • Stoploss
  • The horisontal line the ADX should cross to get a bullis signal


Parameter optimisation indeed proves to be very advantageous. It improved the overal profitability of the 1 day strategy with 233%


As I already predicted, a change in the settings of the ROI and ADX level made a huge difference between the original strategy and the hyperopted one.

The original strategy was indeed too tight and therefore took profits too fast.

It also had much more trades, almost double, and there also were more winning trades so therefore the winrate was also higher.

Beware that the original strategy has a lower risk of ruin but that is also because the average risk per trade is quite low.


If we compare the chart of bitcoin and the points where both versions of the strategy entered and exited the market, you can also see that the original strategy had more entries that also were profitable because of quick profit taking.


The hyperopted strategy did not have that many trades but the average profit per trade is much higher because of the higher roi settings.

And actually there is not much more to say than that. A pretty simple strategy that makes use of the ADX trend strength indicator with the two SMA’s to determine which direction this trend has.

Strategy League

This ADX Sma crossover strategy enters the total strategy league in 16th position.

It is a very moderate and simple to follow strategy and has a nice profit compared with some of the other strategies on the bottom of this list. 

The strategy code

The hyperopt code

# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib

# These libs are for hyperopt
from functools import reduce
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter,IStrategy, IntParameter)

# --------------------------------

class AdxSmasHopt(IStrategy):

    [email protected]: Gert Wohlgemuth
    Hyperopt file by: DutchCryptoDad

    converted from:


    # Minimal ROI designed for the strategy.
    # adjust based on market conditions. We would recommend to keep it low for quick turn arounds
    # This attribute will be overridden if the config file contains "minimal_roi"
    minimal_roi = {
        "0": 0.1

    # Optimal stoploss designed for the strategy
    stoploss = -0.25

    # Optimal timeframe for the strategy
    timeframe = '1d'

    # Hyperopt spaces
    adx_line = IntParameter(15, 35, default=25, space="buy")

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
        dataframe['short'] = ta.SMA(dataframe, timeperiod=3)
        dataframe['long'] = ta.SMA(dataframe, timeperiod=6)

        return dataframe

    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        conditions = []
                (dataframe['adx'] > self.adx_line.value) &
                (qtpylib.crossed_above(dataframe['short'], dataframe['long']))

        if conditions:
            dataframe.loc[reduce(lambda x, y: x & y, conditions),'buy'] = 1
        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        conditions = []
                (dataframe['adx'] < self.adx_line.value) &
                (qtpylib.crossed_above(dataframe['long'], dataframe['short']))
        if conditions:
            dataframe.loc[reduce(lambda x, y: x & y, conditions),'sell'] = 1
        return dataframe

The hyperopt json results

  "strategy_name": "AdxSmasHopt",
  "params": {
    "trailing": {
      "trailing_stop": false,
      "trailing_stop_positive": null,
      "trailing_stop_positive_offset": 0.0,
      "trailing_only_offset_is_reached": false
    "buy": {
      "adx_line": 29
    "sell": {},
    "protection": {},
    "roi": {
      "0": 0.644,
      "6789": 0.314,
      "13011": 0.162,
      "46704": 0
    "stoploss": {
      "stoploss": -0.341
  "ft_stratparam_v": 1,
  "export_time": "2022-05-26 11:39:10.117047+00:00"

How do you rate this article?




I'm just a regular Dutch dad with a passion for crypto, trading, technology and learning. This channel is my personal journey into the world of Crypto, blockchain, programming, trading bots, trading strategies, NFT's, Defi and many things more.


I'm just a regular Dutch dad with a passion for crypto, trading, technology and learning. This blog is my personal journey into the world of Crypto, blockchain, programming, trading bots, trading strategies, NFT's, Defi and many things more related to digital assets. I want to share my knowledge with others to help them as well in this vast world of digital assets.

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.