This strategy uses the Supertrend indicator to determine price trends and enters long or short positions when the trends change. The strategy allows adjusting the ATR period and multiplier to optimize parameters. It also provides the option to change the ATR calculation method for slightly different results.
The strategy has built-in backtesting date ranges and the ability to trade only within certain times of the day and close all trades at the end of that timeframe. This is especially useful for day trading stocks. When the timeframe option is enabled, you can choose to enter the current position immediately when the timeframe starts, or wait for a trend change to enter the first position.
The strategy also allows you to specify percentage based stop loss and take profit levels. In most cases, the ATR based stop provided by Supertrend itself makes an additional stop loss unnecessary. So you could enable only take profit to optimize the exit mechanism.
Finally, there are custom alert fields for entry and exit messages to be used with automated trading services.
The Supertrend strategy is based on the following key principles:
Calculate the ATR value: Can choose between SMA calculation or built-in ATR indicator. SMA formula:
atr2 = sma(tr, Periods)
Calculate upper and lower bands. Upper band is close minus ATR multiplier times ATR. Lower band is close plus multiplier times ATR.
up = close - (Multiplier * atr)
dn = close + (Multiplier * atr)
Determine trend direction by comparing price to bands. Uptrend when price crosses above lower band. Downtrend when price crosses below upper band.
trend := trend == -1 and close > dn ? 1 : trend == 1 and close < up ? -1 : trend
Generate trading signals on trend change, e.g. sell signal when changing from uptrend to downtrend:
sellSignal = trend == -1 and trend[1] == 1
Filter entry based on signals and additional conditions.
Use stop loss and take profit to lock in profits or limit risks.
These are the key working principles behind the Supertrend strategy. Combined with parameter optimization, it can produce good trading results.
The Supertrend strategy has several advantages:
Supertrend itself effectively identifies trends and is commonly used for trailing stops.
Customizable ATR parameters can be optimized across products for best fit. SMA calculation provides another option.
Configurable backtest and live trading time ranges suit different trading sessions.
Option to enter first trade immediately or wait for signal caters to different products.
Built-in stop loss and take profit helps improve risk management or lock in more profits.
Customizable trade alerts for integration with automated trading systems and bots.
There are also some risks to consider:
Supertrend can produce false signals which need to be filtered with additional conditions.
Improper ATR parameters may lead to over-trading or missing trends. Requires optimization for best balance.
Stop loss too close may prematurely exit profitable trades. Take profit too loose may leave money on the table.
Poor timeframe configuration can miss trading sessions or tie up margin unnecessarily.
These risks can be addressed through appropriate adjustments to parameters or additional filters to improve robustness.
Some ways the strategy can be further optimized:
Test different ATR periods to find the right balance, typically 10-20 works well.
Try different ATR multiplier values, generally 2-5 is appropriate, adjust to find optimum.
Add filters like MACD, RSI etc. to reduce false signals.
Optimize stop loss and take profit levels for best results. Consider dynamic trailing mechanisms.
Test different trading time ranges. Shorter durations suit intraday and high frequency strategies.
Implement auto symbol selection to track high momentum or volatility.
Overall this is a fairly common and practical trend following strategy. It efficiently tracks trends with customizable parameters, but also has inherent risks to manage. With optimization and additional conditions, it can be refined into a robust quant trading system with consistent alpha.
/*backtest start: 2024-01-01 00:00:00 end: 2024-01-31 23:59:59 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © REV0LUTI0N //@version=4 // Strategy strategy("Supertrend Strategy", overlay=true, initial_capital = 10000, default_qty_value = 10000, default_qty_type = strategy.cash) 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) enableentry = input(true, title="Enter First Trade ASAP") waitentry = input(false, title="Wait To Enter First Trade") 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 upPlot = plot(trend == 1 ? up : na, title="Up Trend", style=plot.style_linebr, linewidth=2, color=color.green) Long = (trend == 1 ? up : na) buySignal = trend == 1 and trend[1] == -1 dnPlot = plot(trend == 1 ? na : dn, title="Down Trend", style=plot.style_linebr, linewidth=2, color=color.red) Short = (trend == 1 ? na : dn) sellSignal = trend == -1 and trend[1] == 1 // Strategy Backtesting startDate = input(timestamp("2021-01-01T00:00:00"), type = input.time, title='Backtesting Start Date') finishDate = input(timestamp("2021-12-31T00:00:00"), type = input.time, title='Backtesting End Date') time_cond = true //Time Restriction Settings startendtime = input("", title='Time Frame To Enter Trades') enableclose = input(false, title='Enable Close Trade At End Of Time Frame') timetobuy = (time(timeframe.period, startendtime)) timetoclose = na(time(timeframe.period, startendtime)) // Stop Loss & Take Profit % Based enablesl = input(false, title='Enable Stop Loss') enabletp = input(false, title='Enable Take Profit') stopTick = input(5.0, title='Stop Loss %', type=input.float, step=0.1) / 100 takeTick = input(10.0, title='Take Profit %', type=input.float, step=0.1) / 100 longStop = strategy.position_avg_price * (1 - stopTick) shortStop = strategy.position_avg_price * (1 + stopTick) shortTake = strategy.position_avg_price * (1 - takeTick) longTake = strategy.position_avg_price * (1 + takeTick) plot(strategy.position_size > 0 and enablesl ? longStop : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Long Fixed SL") plot(strategy.position_size < 0 and enablesl ? shortStop : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Short Fixed SL") plot(strategy.position_size > 0 and enabletp ? longTake : na, style=plot.style_linebr, color=color.green, linewidth=1, title="Long Take Profit") plot(strategy.position_size < 0 and enabletp ? shortTake : na, style=plot.style_linebr, color=color.green, linewidth=1, title="Short Take Profit") // Alert messages message_enterlong = input("", title="Long Entry message") message_entershort = input("", title="Short Entry message") message_closelong = input("", title="Close Long message") message_closeshort = input("", title="Close Short message") // Strategy Execution if Long and time_cond and timetobuy and enableentry strategy.entry("Long", strategy.long, alert_message = message_enterlong) if Short and time_cond and timetobuy and enableentry strategy.entry("Short", strategy.short, alert_message = message_entershort) if buySignal and time_cond and timetobuy and waitentry strategy.entry("Long", strategy.long, alert_message = message_enterlong) if sellSignal and time_cond and timetobuy and waitentry strategy.entry("Short", strategy.short, alert_message = message_entershort) if strategy.position_size > 0 and timetoclose and enableclose strategy.close_all(alert_message = message_closelong) if strategy.position_size < 0 and timetoclose and enableclose strategy.close_all(alert_message = message_closeshort) if strategy.position_size > 0 and enablesl and time_cond strategy.exit(id="Close Long", stop=longStop, limit=longTake, alert_message = message_closelong) if strategy.position_size < 0 and enablesl and time_cond strategy.exit(id="Close Short", stop=shortStop, limit=shortTake, alert_message = message_closeshort) if strategy.position_size > 0 and enabletp and time_cond strategy.exit(id="Close Long", stop=longStop, limit=longTake, alert_message = message_closelong) if strategy.position_size < 0 and enabletp and time_cond strategy.exit(id="Close Short", stop=shortStop, limit=shortTake, alert_message = message_closeshort)