Zero Lag Overlapping Moving Average with Chandelier Exit Trading Strategy
The main idea of this strategy is to combine the Zero Lag Overlapping Moving Average (ZLSMA) indicator to judge the trend direction, and the Chandelier Exit (CE) indicator to find more precise entry and exit points…

Overview
The main idea of this strategy is to combine the Zero Lag Overlapping Moving Average (ZLSMA) indicator to judge the trend direction, and the Chandelier Exit (CE) indicator to find more precise entry and exit points. ZLSMA is a trend indicator that can identify trend changes earlier. CE dynamically adjusts exit points by calculating ATR to effectively control stop loss. This strategy is mainly suitable for medium-short term operations.
Strategy Principle
ZLSMA part:
- Use linear regression method to calculate 130-period LMA lines respectively.
- Then overlay the two LMA lines to get the difference value assigned to eq.
- Finally, construct the Zero Lag Overlapping Moving Average ZLSMA through the original LMA line plus the eq difference.
CE part:
- Calculate the ATR indicator and multiply it by a factor (default 2) to determine the dynamic distance from the most recent high or low point.
- When the closing price exceeds the most recent long or short stop loss line, adjust the stop loss line accordingly.
- Determine long or short direction based on the change in closing price relative to the stop loss line.
Entry signal:
- ZLSMA judges trend direction, enter when CE issues signal.
Exit stop loss:
- Fixed stop loss and take profit for long position.
- For short position, use CE's dynamic exit to replace fixed stop loss.
Advantage Analysis
- ZLSMA can identify trend earlier to avoid false breakout.
- CE can flexibly adjust exit points according to market volatility.
- Customizable risk-reward ratio of the strategy.
- Different methods of stop loss and take profit used for long and short positions to control risk.
Risk Analysis
- Improper parameter settings may increase loss rate or expand stop loss range.
- There is still risk of stop loss being broken in case of swift market reversal.
Optimization Directions
- Parameters can be optimized for different markets and timeframes.
- Consider adjusting profit/stop parameters based on volatility or specific cycles.
- Try combining with other indicators or models to improve profit rate.
Summary
The strategy mainly uses Zero Lag Overlapping Moving Average to determine the trend direction, combined with Chandelier Exit indicator to find more precise entry and exit points. The advantages lie in the customizable stop/profit ratio and the dynamic adjustment of Chandelier Exit can control risks according to market conditions. Next steps could be parameter optimization and strategy combination to further improve stability and profitability.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_1 | 2 | (?take profit / stop loss)long TP% |
| v_input_2 | 2 | long SL% |
| v_input_3 | 2 | short TP |
| v_input_4 | 2 | short SL |
| v_input_5 | 130 | (?ZLSMA settings)Length |
| v_input_6 | false | Offset |
| v_input_7_close | 0 | Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4 |
| v_input_int_1 | true | (?Chandelier exit settings)ATR Period |
| v_input_float_1 | 2 | ATR Multiplier |
| v_input_bool_1 | true | Use Close Price for Extremums |
| v_input_bool_2 | true | (?Visuals)Show Buy/Sell Labels |
| v_input_bool_3 | true | Highlight State |
| v_input_bool_4 | true | (?Alerts)Await Bar Confirmation |
Source Pine Script
/*backtest
start: 2024-01-14 00:00:00
end: 2024-01-21 00:00:00
period: 3m
basePeriod: 1m
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/
// © GGkurg
//@version=5
strategy(title = "ZLSMA + Chandelier Exit", shorttitle="ZLSMA + CE", overlay=true)
var GRP1 = "take profit / stop loss"
TP = input(title='long TP%', defval=2.0, inline = "1", group = GRP1)
SL = input(title='long SL%', defval=2.0, inline = "1", group = GRP1)
TP2 = input(title='short TP', defval=2.0, inline = "2", group = GRP1)
SL2 = input(title='short SL', defval=2.0, inline = "2", group = GRP1)
//-------------------------------------------------calculations
takeProfitPrice = strategy.position_avg_price * (1+(TP/100))
stopLossPrice = strategy.position_avg_price * (1-(SL/100))
takeProfitPrice2 = strategy.position_avg_price * (1-(TP2/100))
stopLossPrice2 = strategy.position_avg_price * (1+(SL2/100))
//---------------------------------------ZLSMA - Zero Lag LSMA
var GRP2 = "ZLSMA settings"
length1 = input(title='Length', defval=130, inline = "1", group = GRP2)
offset1 = input(title='Offset', defval=0, inline = "2", group = GRP2)
src = input(close, title='Source', inline = "3", group = GRP2)
lsma = ta.linreg(src, length1, offset1)
lsma2 = ta.linreg(lsma, length1, offset1)
eq = lsma - lsma2
zlsma = lsma + eq
plot(zlsma, color=color.new(color.yellow, 0), linewidth=3)
//---------------------------------------ZLSMA conditisions
//---------long
longc1 = close > zlsma
longclose1 = close < zlsma
//---------short
shortc1 = close < zlsma
shortclose1 = close > zlsma
//---------------------------------------Chandelier Exit
var string calcGroup = 'Chandelier exit settings'
length = input.int(title='ATR Period', defval=1, group=calcGroup)
mult = input.float(title='ATR Multiplier', step=0.1, defval=2.0, group=calcGroup)
useClose = input.bool(title='Use Close Price for Extremums', defval=true, group=calcGroup)
var string visualGroup = 'Visuals'
showLabels = input.bool(title='Show Buy/Sell Labels', defval=true, group=visualGroup)
highlightState = input.bool(title='Highlight State', defval=true, group=visualGroup)
var string alertGroup = 'Alerts'
awaitBarConfirmation = input.bool(title="Await Bar Confirmation", defval=true, group=alertGroup)
atr = mult * ta.atr(length)
longStop = (useClose ? ta.highest(close, length) : ta.highest(length)) - atr
longStopPrev = nz(longStop[1], longStop)
longStop := close[1] > longStopPrev ? math.max(longStop, longStopPrev) : longStop
shortStop = (useClose ? ta.lowest(close, length) : ta.lowest(length)) + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := close[1] < shortStopPrev ? math.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
var color longFillColor = color.new(color.green, 90)
var color shortFillColor = color.new(color.red, 90)
var color textColor = color.new(color.white, 0)
longStopPlot = plot(dir == 1 ? longStop : na, title='Long Stop', style=plot.style_linebr, linewidth=2, color=color.new(longColor, 0))
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=color.new(longColor, 0))
plotshape(buySignal and showLabels ? longStop : na, title='Buy Label', text='Buy', location=location.absolute, style=shape.labelup, size=size.tiny, color=color.new(longColor, 0), textcolor=textColor)
shortStopPlot = plot(dir == 1 ? na : shortStop, title='Short Stop', style=plot.style_linebr, linewidth=2, color=color.new(shortColor, 0))
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=color.new(shortColor, 0))
plotshape(sellSignal and showLabels ? shortStop : na, title='Sell Label', text='Sell', location=location.absolute, style=shape.labeldown, size=size.tiny, color=color.new(shortColor, 0), textcolor=textColor)
midPricePlot = plot(ohlc4, title='', style=plot.style_circles, linewidth=0, display=display.none, editable=false)
longStateFillColor = highlightState ? dir == 1 ? longFillColor : na : na
shortStateFillColor = highlightState ? dir == -1 ? shortFillColor : na : na
fill(midPricePlot, longStopPlot, title='Long State Filling', color=longStateFillColor)
fill(midPricePlot, shortStopPlot, title='Short State Filling', color=shortStateFillColor)
await = awaitBarConfirmation ? barstate.isconfirmed : true
alertcondition(dir != dir[1] and await, title='Alert: CE Direction Change', message='Chandelier Exit has changed direction!')
alertcondition(buySignal and await, title='Alert: CE Buy', message='Chandelier Exit Buy!')
alertcondition(sellSignal and await, title='Alert: CE Sell', message='Chandelier Exit Sell!')
//---------------------------------------Chandelier Exit conditisions
//---------long
longc2 = buySignal
longclose2 = sellSignal
//---------short
shortc2 = sellSignal
shortclose2 = buySignal
//---------------------------------------Long entry and exit
if longc1 and longc2
strategy.entry("long", strategy.long)
if strategy.position_avg_price > 0
strategy.exit("close long", "long", limit = takeProfitPrice, stop = stopLossPrice, alert_message = "close all orders")
if longclose1 and longclose2 and strategy.opentrades == 1
strategy.close("long","ema long cross", alert_message = "close all orders")
//---------------------------------------Short entry and exit
if shortc1 and shortc2
strategy.entry("short", strategy.short)
if strategy.position_avg_price > 0
strategy.exit("close short", "short", limit = takeProfitPrice2, stop = stopLossPrice2, alert_message = "close all orders")
if shortclose1 and shortclose2 and strategy.opentrades == 1
strategy.close("close short","short", alert_message = "close all orders")
Published by ChaoZhang on the FMZ strategy square · last modified 2024-01-22. 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.
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Zero-Lag-Overlapping-Moving-Average-with-Chandelier-Exit-Trading-Strategy.md- npx agenkit install engineering-kit in your project
- Paste the command into your agent and approve each phase
- 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
- BB Breakout StrategyPine Script · Breakout · 1d
- Donchian Channel and Larry Williams Large Trade Index StrategyPine Script · Breakout · 1m
- Dual Breakout Volatility Channel StrategyPine Script · Breakout · 1h
- Dual MA Momentum Breakout StrategyPine Script · Breakout · 1h
- Dynamic ATR Trend Following Strategy Based on Support BreakoutPine Script · Breakout · 1d
- Dynamic ATR based Trailing Stop Trading StrategyPine Script · Breakout · 1d