We have decided to give EVERYTHING for free! What are you waiting for?


Volatility indicators helps us identify if the market is trending or not. The indicator we want to expose today is the Choppiness Index (CHOP).

Choppiness Index is an indicator designed to determine if the market is trading sideways. It is a metric to define the market trendiness only. A higher value means more choppiness, while lower values indicate directional trending.

The choppiness index was created by Australian E.W. Dreiss.


100 * LOG10( SUM(ATR(1), n) / ( MaxHi(n) - MinLo(n) ) ) / LOG10(n)

n = User defined period length.
LOG10(n) = base-10 LOG of n
ATR(1) = Average True Range (Period of 1)
SUM(ATR(1), n) = Sum of the Average True Range over past n bars 
MaxHi(n) = The highest high over past n bars


Let’s combine the choppiness index with the ema crossover strategy we created before. We’ll use the moving averages to determine the trend (7 cross over 25) and then verify if we are trending (choppiness index below 45).


if ema 7 is above ema25 AND candle before was below AND CHOP < 45 AND volume > 10 units AND candle open > 130 units (units will be in your base pair) then BUY

if ema 7 is below ema25 AND candle before was above OR Profit = 15% OR Profit = -10 then SELL

How does it look like

[tv-ideaview idea=”vl7vV6iO” width=”980″ height=”610″ language=”en”]

Implementing in freqtrade

We’ll need to use qtpylib which contains the choppiness indicator.

Let’s start by copying the sample_strategy.py into another file. Change directories into your freqtrade user_data/strategy/ folder.

$ cp sample_strategy.py chop.py

Open the file and let’s modify it

  1. The libraries should already be imported, but just in case, make sure that this line is at the top of the strategy file:
    import freqtrade.vendor.qtpylib.indicators as qtpylib
  2. Change the strategy class name:
    class SampleStrategy(IStrategy) to class chop(IStrategy)
  3. Modify roi and stoploss.
  4. Choose your ticker interval.
  5. Change use_sell_signal to True:
    use_sell_signal = True
  6. Create the indicator in def populate_indicators function:
    dataframe['chop']= qtpylib.chopiness(dataframe, 14)
    dataframe['ema7'] = ta.EMA(dataframe, timeperiod=7)
    dataframe['ema25'] = ta.EMA(dataframe, timeperiod=25)
  7. Delete unused indicators in the def populate_indicators function.
  8. Create the conditions on def populate_buy_trend and def populate_sell_trend.
    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
                (dataframe['chop'] < 45) &
                (dataframe['ema7'] > dataframe['ema25']) &
                (dataframe['ema7'].shift(1) <= dataframe['ema25'].shift(1)) &
                ((dataframe['volume'] * dataframe['high']) > 10) &

            'buy'] = 1

        return dataframe

    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
                    (dataframe['ema7'] < dataframe['ema25']) &
                    (dataframe['ema7'].shift(1) >= dataframe['ema25'].shift(1))
            'sell'] = 1
        return dataframe
dataframe[‘volume’] * dataframe[‘high’] will convert the volume into base units, so if your base pair its BTC then we’ll have BTC volume in given candle so we can compare it.
We use dataframe’open’]>0.00000130 to avoid trading BTC pairs below 130 satoshis, which would yield wrong results as stoploss would be hit more often.


backtesting using USDT

As always, feel free to backtest and modify the strategy to obtain better results.

Leave a Reply

Your email address will not be published. Required fields are marked *