Combining Six Supertrend Signals for Long Entries and Exits
Summary
This strategy combines six Supertrend direction readings: three configured for long entries and three for exits. It enters a long position when all three selected entry indicators point upward and volume is positive. It exits when all three selected exit indicators point downward, again requiring positive volume. Entry and exit settings can use different multiplier and lookback-period values, which are exposed as tunable parameters.
The code also specifies a one-hour timeframe, a warm-up period, return targets, a stop loss, and a trailing stop. The listed parameter values were generated through hyperparameter optimization, but the document supplies no backtest performance results or evidence that they generalize. It explicitly cautions that this is only one possible use of Supertrend and that its indicator implementation has not been validated against the original paper or another trusted reference. The strategy therefore illustrates a confirmation approach, while leaving implementation correctness and out-of-sample effectiveness unresolved.
Key ideas
- A long entry requires three selected Supertrend directions to be upward at the same time.
- A long exit requires three separately configured Supertrend directions to be downward.
- Positive trading volume is required for both entry and exit signals.
- The entry and exit indicators have independently tunable multipliers and periods.
- The document cautions that the Supertrend implementation is unvalidated and gives no performance evidence.
Tags
Full text
# Supertrend
# Supertrend
Supertrend strategy:
* Description: Generate a 3 supertrend indicators for 'buy' strategies & 3 supertrend indicators for 'sell' strategies
Buys if the 3 'buy' indicators are 'up'
Sells if the 3 'sell' indicators are 'down'
* Author: @juankysoriano (Juan Carlos Soriano)
* github: https://github.com/juankysoriano/
*** NOTE: This Supertrend strategy is just one of many possible strategies using `Supertrend` as indicator. It should in any case be used at your own risk.
It comes with at least a couple of caveats:
1. The implementation for the `supertrend` indicator is based on the following discussion: https://github.com/freqtrade/freqtrade-strategies/issues/30 . Concretely https://github.com/freqtrade/freqtrade-strategies/issues/30#issuecomment-853042401
2. The implementation for `supertrend` on this strategy is not validated; meaning this that is not proven to match the results by the paper where it was originally introduced or any other trusted academic resources
## Source (GPL-3.0)
```python
"""
Supertrend strategy:
* Description: Generate a 3 supertrend indicators for 'buy' strategies & 3 supertrend indicators for 'sell' strategies
Buys if the 3 'buy' indicators are 'up'
Sells if the 3 'sell' indicators are 'down'
* Author: @juankysoriano (Juan Carlos Soriano)
* github: https://github.com/juankysoriano/
*** NOTE: This Supertrend strategy is just one of many possible strategies using `Supertrend` as indicator. It should in any case be used at your own risk.
It comes with at least a couple of caveats:
1. The implementation for the `supertrend` indicator is based on the following discussion: https://github.com/freqtrade/freqtrade-strategies/issues/30 . Concretely https://github.com/freqtrade/freqtrade-strategies/issues/30#issuecomment-853042401
2. The implementation for `supertrend` on this strategy is not validated; meaning this that is not proven to match the results by the paper where it was originally introduced or any other trusted academic resources
"""
import logging
from freqtrade.strategy import IStrategy, IntParameter
from pandas import DataFrame
import pandas as pd
import talib.abstract as ta
import numpy as np
import technical.indicators as ftt
class Supertrend(IStrategy):
# Buy params, Sell params, ROI, Stoploss and Trailing Stop are values generated by 'freqtrade hyperopt --strategy Supertrend --hyperopt-loss ShortTradeDurHyperOptLoss --timerange=20210101- --timeframe=1h --spaces all'
# It's encouraged that you find the values that better suit your needs and risk management strategies
INTERFACE_VERSION: int = 3
# Buy hyperspace params:
buy_params = {
"buy_m1": 4,
"buy_m2": 7,
"buy_m3": 1,
"buy_p1": 8,
"buy_p2": 9,
"buy_p3": 8,
}
# Sell hyperspace params:
sell_params = {
"sell_m1": 1,
"sell_m2": 3,
"sell_m3": 6,
"sell_p1": 16,
"sell_p2": 18,
"sell_p3": 18,
}
# ROI table:
minimal_roi = {
"0": 0.087,
"372": 0.058,
"861": 0.029,
"2221": 0
}
# Stoploss:
stoploss = -0.265
# Trailing stop:
trailing_stop = True
trailing_stop_positive = 0.05
trailing_stop_positive_offset = 0.144
trailing_only_offset_is_reached = False
timeframe = '1h'
startup_candle_count = 199
buy_m1 = IntParameter(1, 7, default=4)
buy_m2 = IntParameter(1, 7, default=4)
buy_m3 = IntParameter(1, 7, default=4)
buy_p1 = IntParameter(7, 21, default=14)
buy_p2 = IntParameter(7, 21, default=14)
buy_p3 = IntParameter(7, 21, default=14)
sell_m1 = IntParameter(1, 7, default=4)
sell_m2 = IntParameter(1, 7, default=4)
sell_m3 = IntParameter(1, 7, default=4)
sell_p1 = IntParameter(7, 21, default=14)
sell_p2 = IntParameter(7, 21, default=14)
sell_p3 = IntParameter(7, 21, default=14)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
new_cols = []
for multiplier in self.buy_m1.range:
for period in self.buy_p1.range:
new_cols.append(self.supertrend_direction(
dataframe, multiplier, period, f'supertrend_1_buy_{multiplier}_{period}'))
for multiplier in self.buy_m2.range:
for period in self.buy_p2.range:
new_cols.append(self.supertrend_direction(
dataframe, multiplier, period, f'supertrend_2_buy_{multiplier}_{period}'))
for multiplier in self.buy_m3.range:
for period in self.buy_p3.range:
new_cols.append(self.supertrend_direction(
dataframe, multiplier, period, f'supertrend_3_buy_{multiplier}_{period}'))
for multiplier in self.sell_m1.range:
for period in self.sell_p1.range:
new_cols.append(self.supertrend_direction(
dataframe, multiplier, period, f'supertrend_1_sell_{multiplier}_{period}'))
for multiplier in self.sell_m2.range:
for period in self.sell_p2.range:
new_cols.append(self.supertrend_direction(
dataframe, multiplier, period, f'supertrend_2_sell_{multiplier}_{period}'))
for multiplier in self.sell_m3.range:
for period in self.sell_p3.range:
new_cols.append(self.supertrend_direction(
dataframe, multiplier, period, f'supertrend_3_sell_{multiplier}_{period}'))
if new_cols:
dataframe = pd.concat([dataframe] + new_cols, axis=1)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe[f'supertrend_1_buy_{self.buy_m1.value}_{self.buy_p1.value}'] == 'up') &
(dataframe[f'supertrend_2_buy_{self.buy_m2.value}_{self.buy_p2.value}'] == 'up') &
(dataframe[f'supertrend_3_buy_{self.buy_m3.value}_{self.buy_p3.value}'] == 'up') & # The three indicators are 'up' for the current candle
(dataframe['volume'] > 0) # There is at least some trading volume
),
'enter_long'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe[f'supertrend_1_sell_{self.sell_m1.value}_{self.sell_p1.value}'] == 'down') &
(dataframe[f'supertrend_2_sell_{self.sell_m2.value}_{self.sell_p2.value}'] == 'down') &
(dataframe[f'supertrend_3_sell_{self.sell_m3.value}_{self.sell_p3.value}'] == 'down') & # The three indicators are 'down' for the current candle
(dataframe['volume'] > 0) # There is at least some trading volume
),
'exit_long'] = 1
return dataframe
def supertrend_direction(self, dataframe: DataFrame, multiplier: int, period: int, name: str) -> pd.Series:
"""
Supertrend direction ('up' / 'down') as a named series.
`ftt.supertrend` returns a (value, direction) tuple - only the direction is used here.
"""
_, stx = ftt.supertrend(dataframe, period=period, multiplier=multiplier)
# 'stx' is None before the indicator has warmed up - keep the empty string
return pd.Series(stx, index=dataframe.index, name=name).fillna('')
```Shown in full with attribution under the source's licence. Licence: GPL-3.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.