Long-Term Trading Strategy Based on SuperTrend

Author: ChaoZhang, Date: 2023-09-20 17:14:33
Tags:

Overview

This strategy identifies long opportunities using the SuperTrend indicator. It uses ATR and a multiplier to determine dynamic support levels for long entry. The focus is on long trades.

Strategy Logic

  1. The upper and lower bands are calculated based on ATR period, multiplier. Breaking upper band indicates uptrend, breaking lower band indicates downtrend.

  2. The current trend is tracked, with 1 for uptrend and -1 for downtrend. Price breaking above upper band switches trend from down to up, generating buy signal. Breaking below lower band switches from up to down, generating sell signal.

  3. A moving average is added as a trend filter. Buy only if price is above MA when breaking above upper band. Sell only if price is below MA when breaking below lower band. This avoids fake breakouts.

  4. Visual helpers highlight trends, signals etc to assist with decision making.

Advantage Analysis

The advantages of this strategy:

  1. SuperTrend dynamically tracks price changes and reflects trend shifts timely.

  2. The ATR stop loss adjusts stops based on market volatility, helping lock in profits.

  3. The MA filter eliminates false signals from noise in ranging markets.

  4. Visual design intuitively presents strategy mechanics and market situation.

  5. Only trading trend reversals makes it suitable for long-term holding.

Risk Analysis

The main risks are:

  1. SuperTrend is sensitive to parameters. Frequent band adjustments may lead to over trading.

  2. In choppy markets, stops can get triggered frequently.

  3. No consideration of trading costs. Small accounts suffer greater impact.

  4. No stop loss means high drawdown risk.

  5. Trend filter may miss some opportunities.

Risks can be reduced by:

  1. Optimizing ATR parameters to lower band adjustment frequency.

  2. Adding equivalent bar filtering to avoid stops by high frequency minor swings.

  3. Implementing stop loss and take profit to protect profits.

  4. Tuning moving average period to balance filtering effect.

  5. Optimizing money management to lower trading cost impacts.

Optimization Directions

The strategy can be enhanced in the following aspects:

  1. Test different price sources like close, high etc.

  2. Try other dynamic stop loss indicators like Chandelier Exit.

  3. Add position sizing to optimize capital utilization.

  4. Incorporate volatility indicators to refine entries.

  5. Implement stop loss and take profit to control risks.

  6. Adjust parameters for different markets.

  7. Explore machine learning for parameter optimization.

  8. Combine other indicators to improve filter accuracy.

Conclusion

This strategy uses SuperTrend with dynamic stops to determine trends, and adds an MA filter to identify long entries. Visual design simplifies operations. With optimized parameters and added features, it can become a robust long-term trading strategy.


/*backtest
start: 2020-09-13 00:00:00
end: 2023-09-19 00:00:00
period: 3d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("SuperTrend Long Strategy", overlay=true, initial_capital=50000, currency=currency.USD, default_qty_type=strategy.cash, default_qty_value=50000)

Periods = input(title="ATR Period", type=input.integer, defval=10)
src = input(hl2, title="Source")
Multiplier = input(title="ATR Multiplier", type=input.float, step=0.1, defval=3.0)
changeATR = input(title="Change ATR Calculation Method ?", type=input.bool, defval=true)
showsignals = input(title="Show Buy/Sell Signals ?", type=input.bool, defval=false)
highlighting = input(title="Highlighter On/Off ?", type=input.bool, defval=true)
barcoloring = input(title="Bar Coloring On/Off ?", type=input.bool, defval=true)

atr2 = sma(tr, Periods)
atr = changeATR ? atr(Periods) : atr2

up = src - (Multiplier * atr)
up1 = nz(up[1], up)
up := close[1] > up1 ? max(up, up1) : up

dn = src + (Multiplier * atr)
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? min(dn, dn1) : dn

trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend

// Moving Average as Trend Filter
periodes_ma = input(title="Moving Average Period", type=input.integer, defval=20)
src_ma = input(title="Moving Average Source", type=input.source, defval=close)
ma = sma(src_ma, periodes_ma)

upPlot = plot(trend == 1 ? up : na, title="Up Trend", style=plot.style_linebr, linewidth=2, color=color.green)
buySignal = trend == 1 and trend[1] == -1 and close > ma
plotshape(buySignal ? up : na, title="UpTrend Begins", location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(color.green, 0))
plotshape(buySignal and showsignals ? up : na, title="Buy", text="Buy", location=location.absolute, style=shape.labelup, size=size.tiny, color=color.new(color.green, 0))

dnPlot = plot(trend == 1 ? na : dn, title="Down Trend", style=plot.style_linebr, linewidth=2, color=color.red)
sellSignal = trend == -1 and trend[1] == 1 and close < ma
plotshape(sellSignal ? dn : na, title="DownTrend Begins", location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(color.red, 0))
plotshape(sellSignal and showsignals ? dn : na, title="Sell", text="Sell", location=location.absolute, style=shape.labeldown, size=size.tiny, color=color.new(color.red, 0))

mPlot = plot(ohlc4, title="", style=plot.style_circles, linewidth=0)
longFillColor = highlighting ? (trend == 1 ? color.new(color.green, 70) : color.white) : color.white
shortFillColor = highlighting ? (trend == -1 ? color.new(color.red, 70) : color.white) : color.white
fill(mPlot, upPlot, title="UpTrend Highlighter", color=longFillColor)
fill(mPlot, dnPlot, title="DownTrend Highlighter", color=shortFillColor)

FromMonth = input(defval = 9, title = "From Month", minval = 1, maxval = 12)
FromDay   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear  = input(defval = 2018, title = "From Year", minval = 999)
ToMonth   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear    = input(defval = 9999, title = "To Year", minval = 999)

start     = timestamp(FromYear, FromMonth, FromDay, 00, 00)  
finish    = timestamp(ToYear, ToMonth, ToDay, 23, 59)       

window()  => time >= start and time <= finish ? true : false

longCondition = buySignal
if (longCondition)
    strategy.entry("BUY", strategy.long, when = window())

shortCondition = sellSignal
if (shortCondition)
    strategy.close("BUY")
    strategy.entry("SELL", strategy.short, when = window())

buy1 = barssince(buySignal)
sell1 = barssince(sellSignal)
color1 = buy1[1] < sell1[1] ? color.green : buy1[1] > sell1[1] ? color.red : na
barcolor(barcoloring ? color1 : na)


More