The main idea of this strategy is to calculate the long and short stop-loss lines based on the ATR indicator. It generates trading signals when the price breaks through these stop-loss lines. It has both trend tracking and oscillation capturing capabilities.
The strategy uses the N-period ATR multiplied by a coefficient to calculate the long and short stop-loss lines. The specific calculation formulas are as follows:
Long Stop = Highest Price - ATR * Coefficient
Short Stop = Lowest Price + ATR * Coefficient
It goes long when the price rises and breaks through the long stop-loss line, and goes short when the price falls and breaks through the short stop-loss line. After going long or short, it will track price fluctuations in real time to move the stop-loss lines.
By using the ATR band as the stop-loss level, this method can fully capture the price trend while ensuring the stop-loss risk. It generates signals when there is a significant breakthrough in price, which can effectively filter out false breakouts.
The biggest advantage of this strategy is that it can automatically adjust the stop-loss level to capture price trends while controlling risks. The specific advantages are as follows:
The floating stop-loss based on the ATR indicator can adjust the stop-loss range according to market volatility to effectively control single loss.
Adopting a breakthrough method to generate signals can filter out some noise and avoid chasing peaks and bottoms.
Real-time adjustment of stop-loss lines to track price fluctuations prevents the stop-loss from being too loose and locks in more profits.
The strategy also has some risks, mainly concentrated in the setting of stop-loss level and signal generation. The specific risk points are:
Improper ATR cycle and coefficients may lead to excessively wide or narrow stop-loss.
The breakthrough signal method may miss early trend opportunities.
There may be some lag in stop-loss tracking during trend ending, unable to perfectly exit.
The countermeasures are mainly to adjust the parameters to make the stop-loss more reasonable, or assist with other indicators to determine the trend and signals.
The strategy can be further optimized in the following aspects:
Set up a second-layer stop-loss to further control risks.
Combine other indicators to determine the trend and improve signal quality.
Add moving stop-profit strategies to increase profit when the trend further continues.
Optimize ATR cycle and coefficient parameters to make stop-loss closer to actual price fluctuations.
Overall, this strategy is very practical. It can effectively control risks by automatically adjusting the stop-loss level, while obtaining good profits through trend tracking. We can further optimize and improve the strategy by combining other analytical methods on the existing basis to make it more stable and intelligent.
/*backtest start: 2024-01-04 00:00:00 end: 2024-02-03 00:00:00 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/ // © melihtuna //@version=4 strategy("Chandelier Exit - Strategy",shorttitle="CE-STG" , overlay=true, default_qty_type=strategy.cash, default_qty_value=10000, initial_capital=10000, currency=currency.USD, commission_value=0.03, commission_type=strategy.commission.percent) length = input(title="ATR Period", type=input.integer, defval=22) mult = input(title="ATR Multiplier", type=input.float, step=0.1, defval=3.0) showLabels = input(title="Show Buy/Sell Labels ?", type=input.bool, defval=false) useClose = input(title="Use Close Price for Extremums ?", type=input.bool, defval=true) highlightState = input(title="Highlight State ?", type=input.bool, defval=true) atr = mult * atr(length) longStop = (useClose ? highest(close, length) : highest(length)) - atr longStopPrev = nz(longStop[1], longStop) longStop := close[1] > longStopPrev ? max(longStop, longStopPrev) : longStop shortStop = (useClose ? lowest(close, length) : lowest(length)) + atr shortStopPrev = nz(shortStop[1], shortStop) shortStop := close[1] < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop var int dir = 1 dir := close > shortStopPrev ? 1 : close < longStopPrev ? -1 : dir var color longColor = color.green var color shortColor = color.red longStopPlot = plot(dir == 1 ? longStop : na, title="Long Stop", style=plot.style_linebr, linewidth=2, color=longColor) buySignal = dir == 1 and dir[1] == -1 plotshape(buySignal ? longStop : na, title="Long Stop Start", location=location.absolute, style=shape.circle, size=size.tiny, color=longColor, transp=0) plotshape(buySignal and showLabels ? longStop : na, title="Buy Label", text="Buy", location=location.absolute, style=shape.labelup, size=size.tiny, color=longColor, textcolor=color.white, transp=0) shortStopPlot = plot(dir == 1 ? na : shortStop, title="Short Stop", style=plot.style_linebr, linewidth=2, color=shortColor) sellSignal = dir == -1 and dir[1] == 1 plotshape(sellSignal ? shortStop : na, title="Short Stop Start", location=location.absolute, style=shape.circle, size=size.tiny, color=shortColor, transp=0) plotshape(sellSignal and showLabels ? shortStop : na, title="Sell Label", text="Sell", location=location.absolute, style=shape.labeldown, size=size.tiny, color=shortColor, textcolor=color.white, transp=0) midPricePlot = plot(ohlc4, title="", style=plot.style_circles, linewidth=0, display=display.none, editable=false) longFillColor = highlightState ? (dir == 1 ? longColor : na) : na shortFillColor = highlightState ? (dir == -1 ? shortColor : na) : na fill(midPricePlot, longStopPlot, title="Long State Filling", color=longFillColor) fill(midPricePlot, shortStopPlot, title="Short State Filling", color=shortFillColor) long_short = input(true, "Long-Short",type=input.bool, group="Strategy Settings") start = input(timestamp("2019-01-01"), "Date", type=input.time, group="Strategy Settings") finish = input(timestamp("2025-01-01"), "Date", type=input.time, group="Strategy Settings") window() => true slRatio=input(5, "Manuel Stop Loss Ratio", type=input.float, minval=0, group="Strategy Settings") tpRatio=input(20, "Take Profit Ratio", type=input.float, minval=0, group="Strategy Settings") tsStartRatio=input(10, "Trailing Stop Start Ratio", type=input.float, minval=0, group="Strategy Settings") tsRatio=input(5, "Trailing Stop Ratio", type=input.float, minval=1, group="Strategy Settings") lastBuyPrice = strategy.position_avg_price diffHiPriceRatio = (high-lastBuyPrice)/lastBuyPrice*100 diffLoPriceRatio = (close-lastBuyPrice)/lastBuyPrice*100 posHiRatio=0.0 posHiRatio:= strategy.position_size > 0 ? diffHiPriceRatio > posHiRatio[1] ? diffHiPriceRatio : posHiRatio[1] : 0 s_diffHiPriceRatio = (low-lastBuyPrice)/lastBuyPrice*100 s_diffLoPriceRatio = (close-lastBuyPrice)/lastBuyPrice*100 s_posHiRatio=0.0 s_posHiRatio:= strategy.position_size < 0 ? s_diffLoPriceRatio < s_posHiRatio[1] ? s_diffLoPriceRatio : s_posHiRatio[1] : 0 strategy.entry("LONG", strategy.long, when = window() and buySignal) strategy.close("LONG", when = window() and sellSignal) strategy.close("LONG", when = diffLoPriceRatio<(slRatio*(-1)), comment="STOP-LONG") strategy.close("LONG", when = diffHiPriceRatio>tpRatio, comment="TAKE-PROFIT-LONG") strategy.close("LONG", when = ((posHiRatio[1]>tsStartRatio) and (posHiRatio[1]-diffHiPriceRatio)>tsRatio), comment="TRAILING-STOP-LONG") if long_short strategy.entry("SHORT", strategy.short, when = window() and sellSignal) strategy.close("SHORT", when = window() and buySignal) strategy.close("SHORT", when = s_diffLoPriceRatio>(slRatio), comment="STOP-SHORT") strategy.close("SHORT", when = s_diffHiPriceRatio<(tpRatio*(-1)), comment="TAKE-PROFIT-SHORT") strategy.close("SHORT", when = ((s_posHiRatio[1]*(-1)>tsStartRatio) and ((s_posHiRatio[1]-s_diffLoPriceRatio))*(-1)>tsRatio), comment="TRAILING-STOP-SHORT")template: strategy.tpl:40:21: executing "strategy.tpl" at <.api.GetStrategyListByName>: wrong number of args for GetStrategyListByName: want 7 got 6