0bps

Strategy vault / Trend following

Adaptive Trailing Stop Strategy

This strategy mainly implements an adaptive stop loss mechanism that automatically adjusts the stop loss position based on price fluctuations to achieve better stop loss effect. The strategy uses the ATR indicator to…

Author
ChaoZhang
Complexity
Intermediate · 72 lines
Parameters
9
Backtest bar
1h · intraday
Tested on
BTC/USDT · futures

Overview

This strategy mainly implements an adaptive stop loss mechanism that automatically adjusts the stop loss position based on price fluctuations to achieve better stop loss effect. The strategy uses the ATR indicator to calculate a reasonable stop loss range, and generates trading signals in combination with EMA lines. It opens long or short positions when price breaks through EMA lines, and uses an adaptive stop loss algorithm to trail the stop loss.

Strategy Logic

  1. Calculate ATR indicator and set ATR value multiplied by parameter a as stop loss range nLoss.
  2. Calculate EMA line.
  3. Go long when price breaks above EMA line, and go short when price breaks below EMA line.
  4. Use adaptive stop loss algorithm to automatically adjust stop loss position xATRTrailingStop, with rules as follows:
    • When price breaks above stop loss position, adjust stop loss to price minus stop loss range nLoss.
    • When price breaks below stop loss position, adjust stop loss to price plus stop loss range nLoss.
    • Otherwise, keep stop loss unchanged.
  5. Close position for stop loss when price hits stop loss level.

Advantage Analysis

  1. Implements adaptive stop loss mechanism that automatically adjusts stop loss range based on market volatility, effectively controlling risks.
  2. Calculates reasonable stop loss range with ATR indicator, avoiding overlarge or too small stop loss.
  3. Uses EMA to generate trading signals, reducing unnecessary trades and filtering market noise.
  4. Simple and clear strategy logic, easy to understand and optimize.
  5. Allows input parameters adjustment to adapt to different market environments.

Risks and Improvements

  1. EMA signals may lag, leading to late entry. Consider using other indicators to assist judgement for early entry.
  2. Uncertain holding period, unable to control single stop loss size. Can set profit target or max holding period to limit losses.
  3. Stop loss may be triggered too frequently in strong trending markets. Consider adjusting parameters or adding filters based on trend conditions.
  4. Parameters like ATR period, stop loss multiplier should be tuned based on symbol characteristics, default values should not be used blindly.

Optimization Directions

  1. Consider adding trend indicator, taking trades in trend direction to avoid counter-trend trades.
  2. Adjust stop loss multiplier based on volatility, allowing wider stop in high volatility conditions.
  3. Set maximum holding period, active stop loss after exceeding certain time.
  4. Add moving stop loss strategy, gradually raising stop as price moves.
  5. Customize ATR period parameter based on symbol characteristics.

Conclusion

The strategy has clear and simple logic, managing risks with adaptive ATR-based stop loss and EMA for trade signals. But it is relatively passive with much room for optimization. Consider adding trend judgement, dynamic parameter adjustment based on market conditions to make it more proactive. Overall it serves as a good idea and template for reversal stop loss strategies, but parameters should be tuned for different symbols instead of blindly applying default values.

Parameters

NameDefaultWhat it controls
v_input_1trueKey Vaule. 'This changes the sensitivity'
v_input_210ATR Period
v_input_3falseSignals from Heikin Ashi Candles
v_input_4trueFrom Day
v_input_5trueFrom Month
v_input_62019From Year
v_input_7trueTo Day
v_input_8trueTo Month
v_input_92100To Year

Source Pine Script

/*backtest
start: 2023-09-07 00:00:00
end: 2023-10-07 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="UT Bot Strategy", overlay = true)
//CREDITS to HPotter for the orginal code. The guy trying to sell this as his own is a scammer lol. 

// Inputs
a = input(1,     title = "Key Vaule. 'This changes the sensitivity'")
c = input(10,    title = "ATR Period")
h = input(false, title = "Signals from Heikin Ashi Candles")

////////////////////////////////////////////////////////////////////////////////
// BACKTESTING RANGE
 
// From Date Inputs
fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromYear = input(defval = 2019, title = "From Year", minval = 1970)
 
// To Date Inputs
toDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
toMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
toYear = input(defval = 2100, title = "To Year", minval = 1970)
 
// Calculate start/end date and time condition
startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
time_cond = true
 
////////////////////////////////////////////////////////////////////////////////


xATR  = atr(c)
nLoss = a * xATR

src = h ? security(heikinashi(syminfo.tickerid), timeframe.period, close, lookahead = false) : close

xATRTrailingStop = 0.0
xATRTrailingStop := iff(src > nz(xATRTrailingStop[1], 0) and src[1] > nz(xATRTrailingStop[1], 0), max(nz(xATRTrailingStop[1]), src - nLoss),
   iff(src < nz(xATRTrailingStop[1], 0) and src[1] < nz(xATRTrailingStop[1], 0), min(nz(xATRTrailingStop[1]), src + nLoss), 
   iff(src > nz(xATRTrailingStop[1], 0), src - nLoss, src + nLoss)))
 
pos = 0   
pos :=	iff(src[1] < nz(xATRTrailingStop[1], 0) and src > nz(xATRTrailingStop[1], 0), 1,
   iff(src[1] > nz(xATRTrailingStop[1], 0) and src < nz(xATRTrailingStop[1], 0), -1, nz(pos[1], 0))) 
   
xcolor = pos == -1 ? color.red: pos == 1 ? color.green : color.blue 

ema   = ema(src,1)
above = crossover(ema, xATRTrailingStop)
below = crossover(xATRTrailingStop, ema)

buy  = src > xATRTrailingStop and above 
sell = src < xATRTrailingStop and below

barbuy  = src > xATRTrailingStop 
barsell = src < xATRTrailingStop 

plotshape(buy,  title = "Buy",  text = 'Buy',  style = shape.labelup,   location = location.belowbar, color= color.green, textcolor = color.white, transp = 0, size = size.tiny)
plotshape(sell, title = "Sell", text = 'Sell', style = shape.labeldown, location = location.abovebar, color= color.red,   textcolor = color.white, transp = 0, size = size.tiny)

barcolor(barbuy  ? color.green : na)
barcolor(barsell ? color.red   : na)

strategy.entry("long",   true, when = buy  and time_cond)
strategy.entry("short", false, when = sell and time_cond)

Published by ChaoZhang on the FMZ strategy square · last modified 2023-10-08. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Adaptive-Trailing-Stop-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open