This Pine Script combines the Chandelier Exit indicator with a Zero Lag Least Squares Moving Average (ZLSMA) and adds trading session filters and alerts. Here’s a breakdown of the script and how to use it:

Description:
This script generates buy and sell signals based on the Chandelier Exit indicator, but only when the price is above (for buys) or below (for sells) the ZLSMA. This acts as a filter to potentially improve the quality of signals. It also incorporates customizable trading session filters, allowing you to specify the days and times you want the strategy to be active.
Key Components:
- Trading Session Filters: Allows you to define specific date ranges, time sessions (e.g., 0400-1900), UTC offset, and days of the week for trading. This ensures the strategy only operates during your desired trading hours.
- ZLSMA (Zero Lag Least Squares Moving Average): A moving average designed to reduce lag, providing potentially faster signals than traditional moving averages. It’s used here as a filter: buy signals are only considered if the close price is above the ZLSMA, and sell signals are only considered if the close price is below the ZLSMA.
- Chandelier Exit: A trailing stop-loss indicator that helps determine potential exit points for long and short positions. It’s calculated based on the highest high (for shorts) or lowest low (for longs) over a specified period, minus (for longs) or plus (for shorts) a multiple of the Average True Range (ATR).
- Alerts: Generates alerts for buy and sell signals, including the percentage difference between the last buy price and the current sell price (for sell alerts after a buy).
- Visualizations: Plots the ZLSMA, Chandelier Exit stop lines, buy/sell signals, and fills the area between the price and the stop lines to visualize the current trend.
How to Use:
- Open TradingView: Open a chart on TradingView for the asset you want to trade.
- Open Pine Editor: Click on “Pine Editor” at the bottom of the TradingView interface.
- Copy and Paste: Copy the provided Pine Script code and paste it into the Pine Editor.
- Add to Chart: Click “Add to Chart.” The script will now be applied to your chart.
Input Settings (Adjust these in the script’s settings after adding it to the chart):
- Trade Session:
From,To: Set the start and end dates for the strategy to be active.Trade time: Set the time session (e.g., “0930-1600” for US market hours).UTC Offset: Set your UTC offset.Trade Monday?toTrade Sunday?: Enable or disable trading on specific days of the week.
- ZLSMA Settings:
ZLSMA Length: The period for the ZLSMA calculation. Lower values make it more sensitive.ZLSMA Offset: Offset for the linear regression calculation. Usually left at 0.ZLSMA Source: The price source for the ZLSMA (usuallyclose).
- CE Calculation (Chandelier Exit Calculation):
ATR Period: The period for the ATR calculation.ATR Multiplier: The multiplier for the ATR, which determines the distance of the stop-loss from the extremum. A higher multiplier creates a wider stop.Use Close Price for Extremums: Whether to use the close price or the high/low for determining the extremums.
- CE Visuals (Chandelier Exit Visuals):
Show Buy/Sell Labels: Show text labels (“Buy” or “Sell”) on the chart.Highlight State: Fill the area between the price and the stop lines.
- CE Alerts (Chandelier Exit Alerts):
Await Bar Confirmation: Only trigger alerts when the bar closes and the conditions are met.
Interpreting Signals:
- Buy Signal: A buy signal is generated when the Chandelier Exit switches to a long position (
dirCE == 1) and the close price is above the ZLSMA. - Sell Signal: A sell signal is generated when the Chandelier Exit switches to a short position (
dirCE == -1) and the close price is below the ZLSMA.
Alerts:
The script sends alerts with messages like “Chandelier Exit Buy!” or “Chandelier Exit Sell!”. After a buy signal, the subsequent sell alert will also include the percentage difference between the buy price and the sell price (e.g., “Chandelier Exit Sell! Diff: -2.50%”).
Important Considerations:
- Backtesting: Thoroughly backtest this strategy on historical data to evaluate its performance on different assets and timeframes.
- Risk Management: Use appropriate risk management techniques, such as setting stop-loss orders and managing position size.
- Optimization: Experiment with different input settings to optimize the strategy for your specific trading style and the asset you are trading. The default settings might not be optimal for all markets.
- Timeframes: The effectiveness of this strategy may vary depending on the timeframe you are using.
This detailed explanation should help you understand and use the provided Pine Script. Remember to always test and adjust strategies before using them with real capital.
//@version=5
strategy(title="Chandelier Exit + ZLSMA by badr elmers", overlay = true)
// ------------------------------
// Trading Day and Time Session
// ------------------------------
//Session=====================================================================
fromDay = input.int(defval = 1, title = "From", minval = 1, maxval = 31, inline="1", group='Trade Session')
fromMonth = input.int(defval = 1, title = "", minval = 1, maxval = 12,inline="1", group='Trade Session')
fromYear = input.int(defval = 2010, title = "", minval = 1970, inline="1", group='Trade Session')
toDay = input.int(defval = 31, title = "To", minval = 1, maxval = 31, inline="2", group='Trade Session')
toMonth = input.int(defval = 12, title = "", minval = 1, maxval = 12, inline="2",group='Trade Session')
toYear = input.int(defval = 2099, title = "", minval = 1970, inline="2",group='Trade Session')
startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
date_cond = time >= startDate and time <= finishDate
i_sess = input.session("0400-1900", "Trade time", group='Trade Session')
UTC_offset = input.int(3, title='UTC Offset', minval=-10, maxval=13, group='Trade Session')
UTC_string = 'UTC' + (UTC_offset > 0 ? '+' : '') + (UTC_offset != 0 ? str.tostring(UTC_offset) : '')
time_cond = time(timeframe.period, i_sess, UTC_string)
is_trade_mon = input(true, title="Trade Monday?", group='Trade Session')
is_trade_tue = input(true, title="Trade Tuesday?", group='Trade Session')
is_trade_wed = input(true, title="Trade Wednesday?", group='Trade Session')
is_trade_thu = input(true, title="Trade Thursday?", group='Trade Session')
is_trade_fri = input(true, title="Trade Friday?", group='Trade Session')
is_trade_sat = input(false, title="Trade Saturday?", group='Trade Session')
is_trade_sun = input(false, title="Trade Sunday?", group='Trade Session')
day_cond = false
if(dayofweek(time_cond, UTC_string) == dayofweek.monday and is_trade_mon)
day_cond := true
else if(dayofweek(time_cond, UTC_string) == dayofweek.tuesday and is_trade_tue)
day_cond := true
else if(dayofweek(time_cond, UTC_string) == dayofweek.wednesday and is_trade_wed)
day_cond := true
else if(dayofweek(time_cond, UTC_string) == dayofweek.thursday and is_trade_thu)
day_cond := true
else if(dayofweek(time_cond, UTC_string) == dayofweek.friday and is_trade_fri)
day_cond := true
else if(dayofweek(time_cond, UTC_string) == dayofweek.saturday and is_trade_sat)
day_cond := true
else if(dayofweek(time_cond, UTC_string) == dayofweek.sunday and is_trade_sun)
day_cond := true
bgcolor(time == time_cond and day_cond ? color.new(color.gray,90) : na)
final_time_cond = time == time_cond and day_cond and date_cond
//=====================================================================
// ------------------------------
// ZLSMA - Zero Lag LSMA Section
// ------------------------------
lengthZLSMA = input.int(title="ZLSMA Length", defval=50, group="ZLSMA Settings")
offsetZLSMA = input.int(title="ZLSMA Offset", defval=0, group="ZLSMA Settings")
srcZLSMA = input.source(close, title="ZLSMA Source", group="ZLSMA Settings")
lsma = ta.linreg(srcZLSMA, lengthZLSMA, offsetZLSMA)
lsma2 = ta.linreg(lsma, lengthZLSMA, offsetZLSMA)
eq = lsma - lsma2
zlsma = lsma + eq
plot(zlsma, color=color.blue, linewidth=3, title="ZLSMA")
// ------------------------------------
// Chandelier Exit Section
// ------------------------------------
// Group: Calculation Inputs
var string calcGroup = 'CE Calculation'
lengthCE = input.int(title='ATR Period', defval=1, group=calcGroup)
multCE = input.float(title='ATR Multiplier', step=0.1, defval=2.0, group=calcGroup)
useCloseCE = input.bool(title='Use Close Price for Extremums', defval=true, group=calcGroup)
// Group: Visual Inputs
var string visualGroup = 'CE Visuals'
showLabelsCE = input.bool(title='Show Buy/Sell Labels', defval=true, group=visualGroup)
highlightStateCE = input.bool(title='Highlight State', defval=true, group=visualGroup)
// Group: Alerts Inputs
var string alertGroup = 'CE Alerts'
awaitBarConfirmationCE = input.bool(title="Await Bar Confirmation", defval=true, group=alertGroup)
// Calculation of ATR-based stops
atrCE = multCE * ta.atr(lengthCE)
// Long Stop Calculation
longStopCE = (useCloseCE ? ta.highest(close, lengthCE) : ta.highest(lengthCE)) - atrCE
longStopPrevCE = nz(longStopCE[1], longStopCE)
longStopCE := close[1] > longStopPrevCE ? math.max(longStopCE, longStopPrevCE) : longStopCE
// Short Stop Calculation
shortStopCE = (useCloseCE ? ta.lowest(close, lengthCE) : ta.lowest(lengthCE)) + atrCE
shortStopPrevCE = nz(shortStopCE[1], shortStopCE)
shortStopCE := close[1] < shortStopPrevCE ? math.min(shortStopCE, shortStopPrevCE) : shortStopCE
// Direction Calculation
var int dirCE = 1
dirCE := close > shortStopPrevCE ? 1 : close < longStopPrevCE ? -1 : dirCE
// Colors
var color longColorCE = color.green
var color shortColorCE = color.red
var color longFillColorCE = color.new(color.green, 90)
var color shortFillColorCE = color.new(color.red, 90)
var color textColorCE = color.new(color.white, 0)
// Plot Long Stop Line
longStopPlotCE = plot(dirCE == 1 ? longStopCE : na, title='Long Stop', style=plot.style_linebr, linewidth=2, color=color.new(longColorCE, 0), display=display.none)
// Buy Signal
buySignalCE = dirCE == 1 and dirCE[1] == -1
plotshape(buySignalCE ? longStopCE : na, title='Long Stop Start', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(longColorCE, 0), display=display.none)
plotshape(buySignalCE and showLabelsCE ? longStopCE : na, title='Buy Label', text='Buy', location=location.belowbar, style=shape.labelup, size=size.tiny, color=color.new(longColorCE, 0), textcolor=textColorCE)
// Plot Short Stop Line
shortStopPlotCE = plot(dirCE == 1 ? na : shortStopCE, title='Short Stop', style=plot.style_linebr, linewidth=2, color=color.new(shortColorCE, 0), display=display.none)
// Sell Signal
sellSignalCE = dirCE == -1 and dirCE[1] == 1
plotshape(sellSignalCE ? shortStopCE : na, title='Short Stop Start', location=location.absolute, style=shape.circle, size=size.tiny, color=color.new(shortColorCE, 0), display=display.none)
plotshape(sellSignalCE and showLabelsCE ? shortStopCE : na, title='Sell Label', text='Sell', location=location.abovebar, style=shape.labeldown, size=size.tiny, color=color.new(shortColorCE, 0), textcolor=textColorCE)
// Hidden Plot for State Filling
midPricePlotCE = plot(ohlc4, title='', style=plot.style_circles, linewidth=0, display=display.none, editable=false)
// State Fill Colors
longStateFillColorCE = highlightStateCE ? dirCE == 1 ? longFillColorCE : na : na
shortStateFillColorCE = highlightStateCE ? dirCE == -1 ? shortFillColorCE : na : na
fill(midPricePlotCE, longStopPlotCE, title='Long State Filling', color=longStateFillColorCE, display=display.none)
fill(midPricePlotCE, shortStopPlotCE, title='Short State Filling', color=shortStateFillColorCE, display=display.none)
// met1_2_1: alert only when bar closes and this conditions are met:
// i want the alert "Chandelier Exit Buy!" to be sent only when the bar is over the zlsma value
// i want the alert "Chandelier Exit Sell!" to be sent only when the bar is below the zlsma value
// so we check if the bar's close price is above or below the ZLSMA.
// i want to show also the difference in percent between the last buy and the actual sell, and send the difference in percent in the alert message too
var float lastBuyPrice = na // Variable to store the last buy price
awaitCE = awaitBarConfirmationCE ? barstate.isconfirmed : true
// do not use var here to set string alertMessage !!!!!!!!!!!!!!!!!!!!
// var string alertMessage = na // Initialize the alert message
string alertMessage = na // Initialize the alert message
// Check conditions for alerts and calculate percentage difference
if buySignalCE and awaitCE and close > zlsma and final_time_cond
strategy.entry("Buy", strategy.long)
lastBuyPrice := close // Store the price of the last buy signal
alertMessage := "Chandelier Exit Buy!" // Set alert message for Buy signal
label.new(x=bar_index, y=high , text="OK", style=label.style_label_down, color=color.new(color.blue, 50), textcolor=color.white) // Display "OK" label below the bar // * 1.002 means Adding 0.2% to the 'high' value so the other labels do not colapse or hide this one
else if sellSignalCE and awaitCE and close < zlsma and final_time_cond
strategy.entry("Sell", strategy.short)
percentDiff = na(lastBuyPrice) ? na : ((close - lastBuyPrice) / lastBuyPrice) * 100 // Calculate percentage difference if there was a previous Buy
alertMessage := na(lastBuyPrice) ? "Chandelier Exit Sell!" : "Chandelier Exit Sell! Diff: " + str.tostring(percentDiff, "#.##") + "%" // If no previous buy we send the standard Sell alert otherwise we send the diff too
labelText = na(percentDiff) ? "OK" : "OK\n" + str.tostring(percentDiff, "#.##") // If no previous buy, show just "OK", otherwise Show percentage difference too
label.new(x=bar_index, y=low , text=labelText, style=label.style_label_up, color=color.new(color.yellow, 50), textcolor=color.black) // Display "OK" label above the bar with percentage difference.
if not na(alertMessage) // Send the alert if the message is not null
alert(alertMessage, alert.freq_once_per_bar_close)