The so-called “Supertrend” indicator is generating a lot of interest lately, but is it profitable to trade with? Let’s get to the bottom of this.
Supertrend strategy and indicators have grown in attention on charting sites such as Tradingview.com, here the leading public library indicator of this genre has 23,332 ‘followers’.
And video blogs have taken to this indicator, for example “Part Time Larry” who recently built a trading bot using this trigger.
The indicator itself is rather sexy when graphed…
Math matters.
But is the profitable? For one thing the math involved is non-trivial.
The point of this piece is not the revisit the math involved but rather to test its profitability in crypto quant trading. Shall we proceed?
The devil is in the details.
One small but crucial point before we continue, notice that this indicator is a “trend following indicator”, this is very important for 2 reasons:
- roughly 80% of the time markets are NOT trending
- the profits of a trending strategy must be compared with the profits of simply holding (or shorting) the same asset. This is very different from judging profits themselves (i.e. remaining in cash).
Outline
In this piece we will do the following:
- Borrow some Python code for the Supertrend indicator math (why re-invent the wheel)
- Collect Binance historical data
- Backtest the strategy against an exchange (eg. ‘BTCUSDT’) over a period of time and review results
- Brute-force difference indicator parameters to see what ‘fits’ profitably
Binance setup
As usual to work with the Binance API you will need to setup a Binance account (free) and get API keys. There are instructions on their site on how to do this.
Next you’ll create a config.py in the directory with the crypto quant code. This will be used to import your key and secret.
API_KEY = ‘your API key’
API_SECRET = ‘your API secret’
Supertrend math
The Supertrend indicator user the True Range (TR) and Average True Range (ATR) calculations:
- True Range (TR): A True Range of an asset is calculated by taking the greatest values of three price differences which are: market high minus marker low, market high minus previous market close, previous market close minus market low.
- Average True Rance (ATR): Average True Range is a smoothed average of the previously calculated True Range values for a specified number of periods.
For a deep-dive on the Supertrend calculations see here.
We’ll use a simplified set of calculations courtesy of ‘Part Time Larry’ and his video blog on this topic. He goes into great detail on the math here so no need to rehash all of that. Watch his video.
These videos are a lot of work and hat’s off to these authors for publishing content on these topics.
Please buy him a ☕, or a whiskey!
Here are our imports and client setup. Nothing special here.
import ccxt
import config
import schedule
import pandas as pd
pd.set_option(‘display.max_rows’, None)import warnings
warnings.filterwarnings(‘ignore’)import numpy as np
from datetime import datetime
import time
from binance.client import Client
import randomclient = Client(config.API_KEY, config.API_SECRET)
We’ll need data, let’s use 15minute tick data for Etherium (ETH) in a trending period on early 2021
candlesticks = client.get_historical_klines(“ETHUSDT”, Client.KLINE_INTERVAL_15MINUTE, “22 Jan, 2021”, “21 Feb, 2021”)
# trim each candle
for candle in candlesticks:
del candle[-6:] # only need the first few columns
Let’s see our data in a dataframe:
Backtesting!
Now we’ll create the backtest code. The double-indentation is a place-holder we’ll revisit later on.
The strategy is simple: when the Supertrend indicator reverses from “Sell” to “Buy”, we take a long position IF the most recent close value is above the 200 period EMA (Exponential Moving Average) value. Here is the essence of the buy trigger:
if not df['in_uptrend'][previous_row_index] and df['in_uptrend'][last_row_index]:
print("*changed to uptrend")
if not in_position:
if df['close'][last_row_index] < df['ema200'][last_row_index]:
print("below EMA")
return # do not buy hereprint(' ema200', df['ema200'][last_row_index])
print(" BUY!", df['timestamp'][last_row_index], df['close'][last_row_index])
The strategy sells when close price falls below EMA.
if df[‘close’][previous_row_index] < df[‘ema200’][previous_row_index]: # closed below ema
if in_position:
print(‘ ema200’, df[‘ema200’][previous_row_index])
print(“ SELL!”, df[‘timestamp’][last_row_index], df[‘close’][last_row_index])
The rest of the code is mostly to keep track of our trading ledger.
Trending markets
So in early 2021 the market was trending strongly for ETH…
Here are our Supertrend backtest results for this period with default parameters for the Supertrend indicator:
*changed to uptrend
ema200 1336.3416667585598
BUY! 2021-01-26 23:00:00 1365.57
ema200 1337.542530741581
SELL! 2021-01-27 01:15:00 1327.7
*changed to uptrend
ema200 1293.9199247860201
BUY! 2021-01-28 13:45:00 1343.0
ema200 1314.384770497579
SELL! 2021-01-29 03:45:00 1320.82
*changed to uptrend
ema200 1329.4749563894045
BUY! 2021-02-01 21:45:00 1350.12
ema200 1576.8033662124164
SELL! 2021-02-04 15:15:00 1566.06
*changed to uptrend
ema200 1615.0917589663093
BUY! 2021-02-05 13:30:00 1685.92
ema200 1657.0474199540897
SELL! 2021-02-06 05:15:00 1662.5
*changed to uptrend
ema200 1622.6337214761083
BUY! 2021-02-08 06:15:00 1634.53
ema200 1748.050539834764
SELL! 2021-02-10 12:45:00 1745.0
*changed to uptrend
ema200 1740.2712583651808
BUY! 2021-02-11 10:30:00 1783.51
ema200 1762.7249257898284
SELL! 2021-02-12 04:15:00 1750.14
*changed to uptrend
ema200 1790.4360684700155
BUY! 2021-02-15 12:45:00 1805.14
ema200 1790.2882902636748
SELL! 2021-02-15 12:45:00 1805.14
*changed to uptrend
ema200 1781.059323775294
BUY! 2021-02-17 09:30:00 1817.25
ema200 1961.7364660509322
SELL! 2021-02-20 22:15:00 1931.86
Period: 20 arm: 6
profit % 2.733345624999929
2.7% profit in a month, great! No, terrible. We cannot compare this with a non-position during this period, instead it should be compared with being in the market and holding long.
Be careful how you evaluate backtesting profit results.
In fact to have held ETH during this period would have resulted in >80% [paper] profit
Non trending markets
So what about a non-trending period? This is the case approximately 80% of the time.
Markets are trending only ~20% of the time. The other 80% of the time they are ‘moving sideways’.
In that case the hold profits would be negligible (or negative), how did Supertrend strategy do there? Very easy for us to see that by simply changing the date period of our backtest.
We had negative profits in this non-trending period with the default parameters:
Period: 20 arm: 6
profit % -0.49146142499997947
Indeed June was a classic non-trending period for ETH, in fact the Supertrend strategy outperformed (including commissions) a holding loss but not by much and this is still a net loss!
A net loss is still a net loss! Would have been better off being OUT of the market.
A trading strategy is only worthwhile if significantly better than staying in or out of the market during the period in question.
Brute forcing parameters
But the default parameters are unlikely to be ideal here, as we did in our prior crypto quant exploration let’s brute-force our way to more profitable parameters for our Supertrend indicator.
You need only to modify the header of our backtesting code:
verbose = Falsefor p in range(20,40):
for arm in range(4, 9):
#if True:
# if True:
# p = 20
# arm = 6
Now we will see the most profitable parameters for this non-trending period, and we can compare these with being in (or out) of the market. The Supertrend parameters are period (ticks to look back) and atr_multiplier (an amplifier, see the math details above).
Being OUT of the ETH market in June yielded $0, and being IN it also yielded approximately $0.
The best Supertend parameters for this period:
Period: 21 arm: 5
in position True 2117.18 balance $ 10140.623120000004
profit % 1.4062312000000383
Of the 100 brute-force combinations (20..40)x(4..9) only 20% of them were profitable, so 80% of all possible combinations (within these practical ranges) would not have been better than our alternative positions (in or out).
Strategy during DOWN trend market
What about in a down trending period of the market? 2 weeks in May 2021 were brutal for ETH, as shown below:
Our Supertrend strategy outperformed the market in this period but still posting marginal gains with 13% of the parameter values producing profit.
Period: 36 arm: 4
profit % 0.6344214999999894
This is clearly superior to being IN the market during this period (a loss of ~60%!) but over the longer term it performed relatively poorly.
Conclusion
Run the backtests for yourself and try different crypto coins. See if you can find a reliable trading strategy using the Supertrend indicator. On it’s own it is somewhat less than ‘Super’, right?
- '
- "
- 100
- 7
- 9
- Account
- All
- api
- ARM
- asset
- authors
- Backtesting
- BEST
- binance
- blogs
- buy
- Cash
- closed
- code
- Coins
- content
- continue
- crypto
- CZ
- data
- detail
- DID
- Early
- EMA
- ETH
- EU
- EV
- exchange
- First
- Free
- GM
- great
- here
- High
- hold
- How
- How To
- hr
- HTTPS
- ia
- Including
- interest
- involved
- IP
- IT
- Key
- keys
- leading
- Ledger
- LG
- Library
- Long
- LP
- Market
- Markets
- math
- Matters
- medium
- ML
- MS
- MT
- net
- Other
- Paper
- price
- Profit
- profitability
- public
- Publishing
- range
- reasons
- REST
- Results
- review
- set
- Shorting
- Simple
- Sites
- small
- So
- Strategy
- test
- time
- Topics
- track
- trade
- Trading
- trending
- us
- value
- Video
- Videos
- W
- Watch
- Wheel
- WHO
- within
- Work
- youtube