IU Three Line Strike Candlestick PatternIU Three Line Strike Candlestick Pattern
This indicator identifies the Three Line Strike candlestick pattern — a rare yet powerful 4-bar reversal setup that captures exhaustion and momentum shifts at the end of strong trends.
Pattern Logic:
The Three Line Strike is a 4-candle pattern that typically signals a sharp reversal after a sustained directional move. This script detects both bullish and bearish variations using strict criteria to ensure accuracy.
Bullish Three Line Strike:
* Previous three candles must be bearish (red)
* Each of these candles must close progressively lower (indicating a strong downtrend)
* The current candle must:
* Be bullish (green)
* Open below the prior close
* Completely engulf the previous three candles by closing above the first candle's open
* And make a higher high than the last 3 bars — confirming a strong reversal
* Once confirmed, a green shaded box is drawn around the 4-bar zone to highlight the pattern
Bearish Three Line Strike:
* Previous three candles must be bullish (green)
* Each must close progressively higher (indicating a strong uptrend)
* The current candle must:
* Be bearish (red)
* Open above the prior close
* Completely engulf the prior three candles by closing below the first candle's open
* And make a lower low than the last 3 bars — confirming downside strength
* A red shaded box is plotted around the 4-bar formation to emphasize the reversal zone
Why this is unique:
Most candlestick tools focus on 1–2 bar patterns. The Three Line Strike goes a step further by combining trend exhaustion (3 same-colored candles) with a full reversal engulfing candle. This pattern is both rare and highly expressive of sentiment shift, making it a standout signal for discretionary and algorithmic traders alike.
How users can benefit:
* High-probability setups: Filters out weak signals using multi-bar confirmation logic
* Clear visual cues: Dynamic shaded boxes and labels make spotting reversals effortless
* Cross-timeframe compatible: Works on intraday and higher timeframes across all markets
* Real-time alerts: Get notified instantly when a bullish or bearish setup forms
This indicator is a valuable addition for traders who want to capture key reversals backed by strong multi-bar price action logic. Whether you are a price action purist or a pattern-based strategist, the IU Three Line Strike gives you a reliable edge.
Disclaimer:
This script is for educational purposes only and does not constitute financial advice. Trading involves risk, and past performance is not indicative of future results. Always do your own research and consult with a licensed financial advisor before making trading decisions.
Pattern grafici
Enigma Sniper 369The "Enigma Sniper 369" is a custom-built Pine Script indicator designed for TradingView, tailored specifically for forex traders seeking high-probability entries during high-volatility market sessions.
Unlike generic trend-following or scalping tools, this indicator uniquely combines session-based "kill zones" (London and US sessions), momentum-based candle analysis, and an optional EMA trend filter to pinpoint liquidity grabs and reversal opportunities.
Its originality lies in its focus on liquidity hunting—identifying levels where stop losses are likely clustered (around swing highs/lows and wick midpoints)—and providing visual entry zones that are dynamically removed once price breaches them, reducing clutter and focusing on actionable signals.
The name "369" reflects the structured approach of three key components (session timing, candle logic, and trend filter) working in harmony to snipe precise entries.
What It Does
"Enigma Sniper 369" identifies potential buy and sell opportunities by drawing two types of horizontal lines on the chart during user-defined London and US
session kill zones:
Solid Lines: Mark the swing low (for buys) or swing high (for sells) of a trigger candle, indicating a potential entry point where stop losses might be clustered.
Dotted Lines: Mark the 50% level of the candle’s wick (lower wick for buys, upper wick for sells), serving as a secondary confirmation zone for entries or tighter stop-loss placement.
These lines are plotted only when specific candle conditions are met within the kill zones, and they are automatically deleted once the price crosses them, signaling that the liquidity at that level has likely been grabbed. The indicator also includes an optional EMA filter to ensure trades align with the broader trend, reducing false signals in choppy markets.
How It Works
The indicator’s logic is built on a multi-layered approach:
Kill Zone Timing: Trades are only considered during user-defined London and US session hours (e.g., London from 02:00 to 12:00 UTC, as seen in the screenshots). These sessions are known for high volatility and liquidity, making them ideal for capturing institutional moves.
Candle-Based Momentum Logic:
Buy Signal: A candle must close above its midpoint (indicating bullish momentum) and have a lower low than the previous candle (suggesting a potential liquidity grab below the previous swing low). This is expressed as close > (high + low) / 2 and low < low .
Sell Signal: A candle must close below its midpoint (bearish momentum) and have a higher high than the previous candle (indicating a potential liquidity grab above the previous swing high), expressed as close < (high + low) / 2 and high > high .
These conditions ensure the indicator targets candles that break recent structure to hunt stop losses while showing directional momentum.
Optional EMA Filter: A 50-period EMA (customizable) can be enabled to filter signals based on trend direction.
Buy signals are only generated if the EMA is trending upward (ema_value > ema_value ), and sell signals require a downward EMA trend (ema_value < ema_value ). This reduces noise by aligning entries with the broader market trend.
Liquidity Levels and Deletion Logic:
For a buy signal, a solid green line is drawn at the candle’s low, and a dotted green line at the 50% level of the lower wick (from the candle body’s bottom to the low).
For a sell signal, a solid red line is drawn at the candle’s high, and a dotted red line at the 50% level of the upper wick (from the body’s top to the high).
These lines extend to the right until the price crosses them, at which point they are deleted, indicating the liquidity at that level has been taken (e.g., stop losses triggered).
Alerts: The indicator includes alert conditions for buy and sell signals, notifying traders when a new setup is identified.
Underlying Concepts
The indicator is grounded in the concept of liquidity hunting, a strategy often employed by institutional traders. Markets frequently move to levels where stop losses are clustered—typically just beyond swing highs or lows—before reversing in the opposite direction. The "Enigma Sniper 369" targets these moves by identifying candles that break structure (e.g., a lower low or higher high) during high-volatility sessions, suggesting a potential sweep of stop losses. The 50% wick level acts as a secondary confirmation, as this midpoint often represents a zone where tighter stop losses are placed by retail traders. The optional EMA filter adds a trend-following element, ensuring entries are taken in the direction of the broader market momentum, which is particularly useful on lower timeframes like the 15-minute chart shown in the screenshots.
How to Use It
Here’s a step-by-step guide based on the provided usage example on the GBP/USD 15-minute chart:
Setup the Indicator: Add "Enigma Sniper 369" to your TradingView chart. Adjust the London and US session hours to match your timezone (e.g., London from 02:00 to 12:00 UTC, US from 13:00 to 22:00 UTC). Customize the EMA period (default 50) and line styles/colors if desired.
Identify Kill Zones: The indicator highlights the London session in light green and the US session in light purple, as seen in the screenshots. Focus on these periods for signals, as they are the most volatile and likely to produce liquidity grabs.
Wait for a Signal: Look for solid and dotted lines to appear during the kill zones:
Buy Setup: A solid green line at the swing low and a dotted green line at the 50% lower wick level indicate a potential buy. This suggests the market may have grabbed liquidity below the swing low and is now poised to move higher.
Sell Setup: A solid red line at the swing high and a dotted red line at the 50% upper wick level indicate a potential sell, suggesting liquidity was taken above the swing high.
Place Your Trade:
For a buy, set a buy limit order at the dotted green line (50% wick level), as this is a more conservative entry point. Place your stop loss just below the solid green line (swing low) to cover the full swing. For example, in the screenshots, the market retraces to the dotted line at 1.32980 after a liquidity grab below the swing low, triggering a buy limit order.
For a sell, set a sell limit order at the dotted red line, with a stop loss just above the solid red line.
Monitor Price Action: Once the price crosses a line, it is deleted, indicating the liquidity at that level has been taken. In the screenshots, after the buy limit is triggered, the market moves higher, confirming the setup. The caption notes, “The market returns and tags us in long with a buy limit,” highlighting this retracement strategy.
Additional Context: Use the indicator to identify liquidity levels that may be targeted later. For example, the screenshot notes, “If a new session is about to open I will wait for the grab liquidity to go long,” showing how the indicator can be used to anticipate future moves at session opens (e.g., London open at 1.32980).
Risk Management: Always set a stop loss below the swing low (for buys) or above the swing high (for sells) to protect against adverse moves. The 50% wick level helps tighten entries, improving the risk-reward ratio.
Practical Example
On the GBP/USD 15-minute chart, during the London session (02:00 UTC), the indicator identifies a buy setup with a solid green line at 1.32901 (swing low) and a dotted green line at 1.32980 (50% wick level). The market initially dips below the swing low, grabbing liquidity, then retraces to the dotted line, triggering a buy limit order. The price subsequently rises to 1.33404, yielding a profitable trade. The user notes, “The logic is in the last candle it provides new level to go long,” emphasizing the indicator’s ability to identify fresh levels after a liquidity sweep.
Customization Tips
Adjust the EMA period to suit your timeframe (e.g., a shorter period like 20 for faster signals on lower timeframes).
Modify the session hours to align with your broker’s timezone or specific market conditions.
Use the alert feature to get notified of new setups without constantly monitoring the chart.
Why It’s Useful for Traders
The "Enigma Sniper 369" stands out by combining session timing, momentum-based candle analysis, and liquidity hunting into a single tool. It provides clear, actionable levels for entries and stop losses, removes invalid signals dynamically, and aligns trades with high-probability market conditions. Whether you’re a scalper looking for quick moves during London open or a swing trader targeting session-based reversals, this indicator offers a structured, data-driven approach to trading.
AlgoRanger Dynamic Trend Flow + Smart Buy and Sell📊 AlgoRanger Dynamic Trend Flow + Smart Buy/Sell
An Intelligent Trend Indicator with Automated Buy & Sell Signals
🔍 What This Indicator Does:
This indicator dynamically visualizes market trend direction using color-coded zones (green for bullish, red for bearish), along with automated Buy/Sell labels to guide your entry and exit points.
🟢 Green Zones = Bullish Trend
🔴 Red Zones = Bearish Trend
✅ Buy/Sell Labels = Smart signals based on momentum and trend strength
Perfect for trend-following traders looking for a clean, simple visual to assess trend direction and make confident trading decisions.
⭐ Best Used with Line Chart (Not Candlesticks)
This indicator is designed to work best with Line Charts, which emphasize price flow and trend direction without the noise of candlestick wicks.
Using it with Line Charts provides a clearer visualization of Trend Flow and smoother signal recognition.
It reduces market noise, especially on lower timeframes, improving accuracy in identifying trend changes.
🧠 How to Use:
1. Watch for Zone Colors
Green Zone = Look for Buy opportunities
Red Zone = Look for Sell opportunities
Frequent color shifts = Ranging market — use caution
2. Follow Buy/Sell Signals
Buy Signal: When the zone turns green and a Buy label appears
Sell Signal: When the zone turns red and a Sell label appears
Tip: Signals work best in trending conditions where zones hold direction consistently
⚙️ Customization & Flexibility
Adjustable smoothing and sensitivity settings (for short- or long-term trends)
Turn Buy/Sell labels on/off
Liquidity + OB + FVG + Market StructureSmart Money Techniques using Liquidity sweep, FVG, OB, CHOCH/ BOS while aligning with BB, RSI. Support and Resistance key levels marked
Opening Range Retest█ OVERVIEW
This indicator shows the opening range as a box. It also draws markers and triggers alerts when the opening range is retested. The opening range time is configurable, as is the period of time that must elapse before each return to the opening range is considered a retest.
█ FEATURES
Opening range time configurable in bars or minutes
Configurable "resting" period between the end of the opening range or since the last retest before a new retest is considered valid
Configurable tolerance so that a retest can trigger sooner
Active time range can be used to filter alerts and markers to a specific time window
Visual box showing the opening range, which can be optionally limited to the above-mentioned active time window
Well-documented, high-quality, open-source code for those interested
█ CONCEPTS
This indicator can be used for an opening range retest trading strategy, where long or short positions are taken on the retest of the opening range.
The opening range can be user-configured, so it is suitable for use with any opening range time period (e.g., 1-min, 5-min, 15-min, etc.).
The markers and alerts are equivalent, in the sense that whenever a marker appears, an alert will also trigger (assuming the user has set an alert up).
The alert active time range is simply used as a filter for markers and alerts, meaning that these will not draw or trigger outside of the specified time range.
█ LIMITATIONS
The indicator is intended for equities that have a highly active regular market open. For other security types, it will draw the opening range box from whenever TradingView specifies the market open time.
GOVIND// This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
// © iamsachinughade
//@version=5
indicator(title='GOVIND', overlay=true)
src = close
prd = input.int(defval=10, title='Pivot Period', minval=4, maxval=30, group='Setup')
ppsrc = input.string(defval='High/Low', title='Source', options= , group='Setup')
maxnumpp = input.int(defval=20, title=' Max Pivot', minval=5, maxval=100, group='Setup')
ChannelW = input.int(defval=10, title='Max Channel Width %', minval=1, group='Setup')
maxnumsr = input.int(defval=5, title=' Number of S&R', minval=1, maxval=10, group='Setup')
min_strength = input.int(defval=2, title=' Minimum Strength', minval=1, maxval=10, group='Setup')
labelloc = input.int(defval=20, title='Label Location', group='Colors', tooltip='Positive numbers reference future bars, negative numbers reference histical bars')
linestyle = input.string(defval='Dotted', title='Line Style', options= , group='Colors')
linewidth = input.int(defval=2, title='Line Width', minval=1, maxval=4, group='Colors')
resistancecolor = input.color(defval=color.red, title='Resistance Color', group='Colors')
supportcolor = input.color(defval=color.lime, title='Support Color', group='Colors')
showpp = input(false, title='Show High Low Points')
float src1 = ppsrc == 'High/Low' ? high : math.max(close, open)
float src2 = ppsrc == 'High/Low' ? low : math.min(close, open)
float ph = ta.pivothigh(src1, prd, prd)
float pl = ta.pivotlow(src2, prd, prd)
plotshape(ph and showpp, text='H', style=shape.labeldown, color=na, textcolor=color.new(color.red, 0), location=location.abovebar, offset=-prd)
plotshape(pl and showpp, text='L', style=shape.labelup, color=na, textcolor=color.new(color.lime, 0), location=location.belowbar, offset=-prd)
Lstyle = linestyle == 'Dashed' ? line.style_dashed : linestyle == 'Solid' ? line.style_solid : line.style_dotted
//calculate maximum S/R channel zone width
prdhighest = ta.highest(300)
prdlowest = ta.lowest(300)
cwidth = (prdhighest - prdlowest) * ChannelW / 100
var pivotvals = array.new_float(0)
if ph or pl
array.unshift(pivotvals, ph ? ph : pl)
if array.size(pivotvals) > maxnumpp // limit the array size
array.pop(pivotvals)
get_sr_vals(ind) =>
float lo = array.get(pivotvals, ind)
float hi = lo
int numpp = 0
for y = 0 to array.size(pivotvals) - 1 by 1
float cpp = array.get(pivotvals, y)
float wdth = cpp <= lo ? hi - cpp : cpp - lo
if wdth <= cwidth // fits the max channel width?
lo := cpp <= lo ? cpp : lo
hi := cpp > lo ? cpp : hi
numpp += 1
numpp
var sr_up_level = array.new_float(0)
var sr_dn_level = array.new_float(0)
sr_strength = array.new_float(0)
find_loc(strength) =>
ret = array.size(sr_strength)
for i = ret > 0 ? array.size(sr_strength) - 1 : na to 0 by 1
if strength <= array.get(sr_strength, i)
break
ret := i
ret
ret
check_sr(hi, lo, strength) =>
ret = true
for i = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
//included?
if array.get(sr_up_level, i) >= lo and array.get(sr_up_level, i) <= hi or array.get(sr_dn_level, i) >= lo and array.get(sr_dn_level, i) <= hi
if strength >= array.get(sr_strength, i)
array.remove(sr_strength, i)
array.remove(sr_up_level, i)
array.remove(sr_dn_level, i)
ret
else
ret := false
ret
break
ret
var sr_lines = array.new_line(11, na)
var sr_labels = array.new_label(11, na)
for x = 1 to 10 by 1
rate = 100 * (label.get_y(array.get(sr_labels, x)) - close) / close
label.set_text(array.get(sr_labels, x), text=str.tostring(label.get_y(array.get(sr_labels, x))) + '(' + str.tostring(rate, '#.##') + '%)')
label.set_x(array.get(sr_labels, x), x=bar_index + labelloc)
label.set_color(array.get(sr_labels, x), color=label.get_y(array.get(sr_labels, x)) >= close ? color.red : color.lime)
label.set_textcolor(array.get(sr_labels, x), textcolor=label.get_y(array.get(sr_labels, x)) >= close ? color.white : color.black)
label.set_style(array.get(sr_labels, x), style=label.get_y(array.get(sr_labels, x)) >= close ? label.style_label_down : label.style_label_up)
line.set_color(array.get(sr_lines, x), color=line.get_y1(array.get(sr_lines, x)) >= close ? resistancecolor : supportcolor)
if ph or pl
//because of new calculation, remove old S/R levels
array.clear(sr_up_level)
array.clear(sr_dn_level)
array.clear(sr_strength)
//find S/R zones
for x = 0 to array.size(pivotvals) - 1 by 1
= get_sr_vals(x)
if check_sr(hi, lo, strength)
loc = find_loc(strength)
// if strength is in first maxnumsr sr then insert it to the arrays
if loc < maxnumsr and strength >= min_strength
array.insert(sr_strength, loc, strength)
array.insert(sr_up_level, loc, hi)
array.insert(sr_dn_level, loc, lo)
// keep size of the arrays = 5
if array.size(sr_strength) > maxnumsr
array.pop(sr_strength)
array.pop(sr_up_level)
array.pop(sr_dn_level)
for x = 1 to 10 by 1
line.delete(array.get(sr_lines, x))
label.delete(array.get(sr_labels, x))
for x = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
float mid = math.round_to_mintick((array.get(sr_up_level, x) + array.get(sr_dn_level, x)) / 2)
rate = 100 * (mid - close) / close
array.set(sr_labels, x + 1, label.new(x=bar_index + labelloc, y=mid, text=str.tostring(mid) + '(' + str.tostring(rate, '#.##') + '%)', color=mid >= close ? color.red : color.lime, textcolor=mid >= close ? color.white : color.black, style=mid >= close ? label.style_label_down : label.style_label_up))
array.set(sr_lines, x + 1, line.new(x1=bar_index, y1=mid, x2=bar_index - 1, y2=mid, extend=extend.both, color=mid >= close ? resistancecolor : supportcolor, style=Lstyle, width=linewidth))
f_crossed_over() =>
ret = false
for x = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
float mid = math.round_to_mintick((array.get(sr_up_level, x) + array.get(sr_dn_level, x)) / 2)
if close <= mid and close > mid
ret := true
ret
ret
f_crossed_under() =>
ret = false
for x = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
float mid = math.round_to_mintick((array.get(sr_up_level, x) + array.get(sr_dn_level, x)) / 2)
if close >= mid and close < mid
ret := true
ret
ret
alertcondition(f_crossed_over(), title='Resistance Broken', message='Resistance Broken')
alertcondition(f_crossed_under(), title='Support Broken', message='Support Broken')
length = input.int(10, step=5, minval=5)
showZigzag = input(false)
showPivots = input(true)
showStats = input(true)
bullishColor = input(color.green)
bullTrapColor = input(color.orange)
bearishColor = input(color.red)
bearTrapColor = input(color.lime)
textColor = input(color.black)
MaxRiskPerReward = input.int(30, step=5, minval=5, maxval=100)
DisplayRiskPerReward = input(true)
var zigzagvalues = array.new_float(0)
var zigzagindexes = array.new_int(0)
var zigzagdir = array.new_int(0)
var doubleTopBottomValues = array.new_float(3)
var doubleTopBottomIndexes = array.new_int(3)
var doubleTopBottomDir = array.new_int(3)
int max_array_size = 10
max_bars_back(high, 1000)
max_bars_back(low, 1000)
var lineArray = array.new_line(0)
var labelArray = array.new_label(0)
pivots(length) =>
float ph = ta.highestbars(high, length) == 0 ? high : na
float pl = ta.lowestbars(low, length) == 0 ? low : na
dir = 0
iff_1 = pl and na(ph) ? -1 : dir
dir := ph and na(pl) ? 1 : iff_1
add_to_array(value, index, dir) =>
mult = array.size(zigzagvalues) < 2 ? 1 : dir * value > dir * array.get(zigzagvalues, 1) ? 2 : 1
array.unshift(zigzagindexes, index)
array.unshift(zigzagvalues, value)
array.unshift(zigzagdir, dir * mult)
if array.size(zigzagindexes) > max_array_size
array.pop(zigzagindexes)
array.pop(zigzagvalues)
array.pop(zigzagdir)
add_to_zigzag(dir, dirchanged, ph, pl, index) =>
value = dir == 1 ? ph : pl
if array.size(zigzagvalues) == 0 or dirchanged
add_to_array(value, index, dir)
else if dir == 1 and value > array.get(zigzagvalues, 0) or dir == -1 and value < array.get(zigzagvalues, 0)
array.shift(zigzagvalues)
array.shift(zigzagindexes)
array.shift(zigzagdir)
add_to_array(value, index, dir)
zigzag(length) =>
= pivots(length)
dirchanged = ta.change(dir)
if ph or pl
add_to_zigzag(dir, dirchanged, ph, pl, bar_index)
calculate_double_pattern() =>
doubleTop = false
doubleTopConfirmation = 0
doubleBottom = false
doubleBottomConfirmation = 0
if array.size(zigzagvalues) >= 4
index = array.get(zigzagindexes, 1)
value = array.get(zigzagvalues, 1)
highLow = array.get(zigzagdir, 1)
lindex = array.get(zigzagindexes, 2)
lvalue = array.get(zigzagvalues, 2)
lhighLow = array.get(zigzagdir, 2)
llindex = array.get(zigzagindexes, 3)
llvalue = array.get(zigzagvalues, 3)
llhighLow = array.get(zigzagdir, 3)
risk = math.abs(value - llvalue)
reward = math.abs(value - lvalue)
riskPerReward = risk * 100 / (risk + reward)
if highLow == 1 and llhighLow == 2 and lhighLow < 0 and riskPerReward < MaxRiskPerReward
doubleTop := true
doubleTop
if highLow == -1 and llhighLow == -2 and lhighLow > 0 and riskPerReward < MaxRiskPerReward
doubleBottom := true
doubleBottom
if doubleTop or doubleBottom
array.set(doubleTopBottomValues, 0, value)
array.set(doubleTopBottomValues, 1, lvalue)
array.set(doubleTopBottomValues, 2, llvalue)
array.set(doubleTopBottomIndexes, 0, index)
array.set(doubleTopBottomIndexes, 1, lindex)
array.set(doubleTopBottomIndexes, 2, llindex)
array.set(doubleTopBottomDir, 0, highLow)
array.set(doubleTopBottomDir, 1, lhighLow)
array.set(doubleTopBottomDir, 2, llhighLow)
get_crossover_info(doubleTop, doubleBottom) =>
index = array.get(doubleTopBottomIndexes, 0)
value = array.get(doubleTopBottomValues, 0)
highLow = array.get(doubleTopBottomDir, 0)
lindex = array.get(doubleTopBottomIndexes, 1)
lvalue = array.get(doubleTopBottomValues, 1)
lhighLow = array.get(doubleTopBottomDir, 1)
llindex = array.get(doubleTopBottomIndexes, 2)
llvalue = array.get(doubleTopBottomValues, 2)
llhighLow = array.get(doubleTopBottomDir, 2)
latestDoubleTop = false
latestDoubleBottom = false
latestDoubleTop := doubleTop ? true : doubleBottom ? false : latestDoubleTop
latestDoubleBottom := doubleBottom ? true : doubleTop ? false : latestDoubleBottom
doubleTopConfirmation = 0
doubleBottomConfirmation = 0
doubleTopConfirmation := latestDoubleTop ? ta.crossunder(low, lvalue) ? 1 : ta.crossover(high, llvalue) ? -1 : 0 : 0
doubleBottomConfirmation := latestDoubleBottom ? ta.crossover(high, lvalue) ? 1 : ta.crossunder(low, llvalue) ? -1 : 0 : 0
draw_double_pattern(doubleTop, doubleBottom, doubleTopConfirmation, doubleBottomConfirmation) =>
index = array.get(doubleTopBottomIndexes, 0)
value = array.get(doubleTopBottomValues, 0)
highLow = array.get(doubleTopBottomDir, 0)
lindex = array.get(doubleTopBottomIndexes, 1)
lvalue = array.get(doubleTopBottomValues, 1)
lhighLow = array.get(doubleTopBottomDir, 1)
llindex = array.get(doubleTopBottomIndexes, 2)
llvalue = array.get(doubleTopBottomValues, 2)
llhighLow = array.get(doubleTopBottomDir, 2)
isBullish = true
isBullish := doubleTop or doubleBottom ? doubleTop : isBullish
risk = math.abs(value - llvalue)
reward = math.abs(value - lvalue)
riskPerReward = risk * 100 / (risk + reward)
base = line.new(x1=index, y1=value, x2=llindex, y2=llvalue, color=doubleTop ? bearishColor : bullishColor, width=2, style=line.style_solid)
l1 = line.new(x1=index, y1=value, x2=lindex, y2=lvalue, color=doubleTop ? bearishColor : bullishColor, width=2, style=line.style_dotted)
l2 = line.new(x1=lindex, y1=lvalue, x2=llindex, y2=llvalue, color=doubleTop ? bearishColor : bullishColor, width=2, style=line.style_dotted)
labelText = (doubleTop ? 'Double Top' : 'Double Bottom') + (DisplayRiskPerReward ? ' RR - ' + str.tostring(riskPerReward) : '')
baseLabel = label.new(x=index, y=value, text=labelText, yloc=doubleTop ? yloc.abovebar : yloc.belowbar, color=doubleTop ? bearishColor : bullishColor, style=doubleTop ? label.style_label_down : label.style_label_up, textcolor=textColor, size=size.normal)
if not(doubleTop or doubleBottom)
line.delete(base)
line.delete(l1)
line.delete(l2)
label.delete(baseLabel)
var doubleTopCount = 0
var doubleBottomCount = 0
doubleTopCount := doubleTop ? nz(doubleTopCount , 0) + 1 : nz(doubleTopCount , 0)
doubleBottomCount := doubleBottom ? nz(doubleBottomCount , 0) + 1 : nz(doubleBottomCount , 0)
if line.get_x2(base) == line.get_x2(base )
line.delete(base )
line.delete(l1 )
line.delete(l2 )
label.delete(baseLabel )
doubleTopCount := doubleTop ? doubleTopCount - 1 : doubleTopCount
doubleBottomCount := doubleBottom ? doubleBottomCount - 1 : doubleBottomCount
doubleBottomCount
if barstate.islast
lres = line.new(x1=bar_index, y1=lvalue, x2=lindex, y2=lvalue, color=isBullish ? bearishColor : bullishColor, width=2, style=line.style_dashed, extend=extend.left)
lsup = line.new(x1=bar_index, y1=llvalue, x2=llindex, y2=llvalue, color=isBullish ? bullishColor : bearishColor, width=2, style=line.style_dashed, extend=extend.left)
lsup
doubleTopConfirmationCount = doubleTopConfirmation > 0 ? 1 : 0
doubleBottomConfirmationCount = doubleBottomConfirmation > 0 ? 1 : 0
doubleTopInvalidationCount = doubleTopConfirmation < 0 ? 1 : 0
doubleBottomInvalidationCount = doubleBottomConfirmation < 0 ? 1 : 0
if doubleTopConfirmation != 0 or doubleBottomConfirmation != 0
if doubleTopConfirmation > 0 or doubleBottomConfirmation > 0
lresbreak = line.new(x1=lindex, y1=lvalue, x2=bar_index, y2=lvalue, color=isBullish ? bearishColor : bullishColor, width=2, style=line.style_dashed)
if line.get_x1(lresbreak ) == line.get_x1(lresbreak)
doubleTopConfirmationCount := 0
doubleBottomConfirmationCount := 0
doubleTopInvalidationCount := 0
doubleBottomInvalidationCount := 0
line.delete(lresbreak)
lresbreak := lresbreak
lresbreak
else if doubleTopConfirmation < 0 or doubleBottomConfirmation < 0
lsupbreak = line.new(x1=llindex, y1=llvalue, x2=bar_index, y2=llvalue, color=isBullish ? bullishColor : bearishColor, width=2, style=line.style_dashed)
if line.get_x1(lsupbreak ) == line.get_x1(lsupbreak)
doubleTopInvalidationCount := 0
doubleBottomInvalidationCount := 0
doubleTopConfirmationCount := 0
doubleBottomConfirmationCount := 0
line.delete(lsupbreak)
lsupbreak := lsupbreak
lsupbreak
doubleTopConfirmationCount := nz(doubleTopConfirmationCount , 0) + doubleTopConfirmationCount
doubleBottomConfirmationCount := nz(doubleBottomConfirmationCount , 0) + doubleBottomConfirmationCount
doubleTopInvalidationCount := nz(doubleTopInvalidationCount , 0) + doubleTopInvalidationCount
doubleBottomInvalidationCount := nz(doubleBottomInvalidationCount , 0) + doubleBottomInvalidationCount
zigzag(length)
= calculate_double_pattern()
= get_crossover_info(doubleTop, doubleBottom)
= draw_double_pattern(doubleTop, doubleBottom, doubleTopConfirmation, doubleBottomConfirmation)
var stats = table.new(position=position.top_center, columns=5, rows=5, border_width=2)
if barstate.islast and showStats
colorWorst = color.rgb(255, 153, 51)
colorBest = color.rgb(51, 204, 51)
colorBad = color.rgb(255, 204, 153)
colorGood = color.rgb(204, 255, 204)
colorNeutral = color.rgb(255, 255, 204)
dtConfirmationPercent = doubleTopConfirmationCount + doubleTopInvalidationCount == 0 ? 0.5 : doubleTopConfirmationCount / (doubleTopConfirmationCount + doubleTopInvalidationCount)
dbConfirmationPercent = doubleBottomConfirmationCount + doubleBottomInvalidationCount == 0 ? 0.5 : doubleBottomConfirmationCount / (doubleBottomConfirmationCount + doubleBottomInvalidationCount)
dtColor = dtConfirmationPercent >= 0.8 ? colorBest : dtConfirmationPercent >= 0.6 ? colorGood : dtConfirmationPercent >= 0.4 ? colorNeutral : dtConfirmationPercent >= 0.2 ? colorBad : colorWorst
dbColor = dbConfirmationPercent >= 0.8 ? colorBest : dbConfirmationPercent >= 0.6 ? colorGood : dbConfirmationPercent >= 0.4 ? colorNeutral : dbConfirmationPercent >= 0.2 ? colorBad : colorWorst
table.cell(table_id=stats, column=0, row=0, text='', bgcolor=color.black, text_color=color.white)
table.cell(table_id=stats, column=0, row=1, text='Double Top', bgcolor=color.black, text_color=color.white)
table.cell(table_id=stats, column=0, row=2, text='Double Bottom', bgcolor=color.black, text_color=color.white)
table.cell(table_id=stats, column=1, row=0, text='Count', bgcolor=color.black, text_color=color.white)
table.cell(table_id=stats, column=2, row=0, text='Confirmation', bgcolor=color.black, text_color=color.white)
table.cell(table_id=stats, column=3, row=0, text='Invalidation', bgcolor=color.black, text_color=color.white)
table.cell(table_id=stats, column=1, row=1, text=str.tostring(doubleTopCount), bgcolor=dtColor)
table.cell(table_id=stats, column=1, row=2, text=str.tostring(doubleBottomCount), bgcolor=dbColor)
table.cell(table_id=stats, column=2, row=1, text=str.tostring(doubleTopConfirmationCount), bgcolor=dtColor)
table.cell(table_id=stats, column=3, row=1, text=str.tostring(doubleTopInvalidationCount), bgcolor=dtColor)
table.cell(table_id=stats, column=2, row=2, text=str.tostring(doubleBottomConfirmationCount), bgcolor=dbColor)
table.cell(table_id=stats, column=3, row=2, text=str.tostring(doubleBottomInvalidationCount), bgcolor=dbColor)
if barstate.islast and array.size(zigzagindexes) > 1
lastHigh = 0.0
lastLow = 0.0
for x = 0 to array.size(zigzagindexes) - 1 by 1
i = array.size(zigzagindexes) - 1 - x
index = array.get(zigzagindexes, i)
value = array.get(zigzagvalues, i)
highLow = array.get(zigzagdir, i)
index_offset = bar_index - index
labelText = highLow == 2 ? 'HH' : highLow == 1 ? 'LH' : highLow == -1 ? 'HL' : 'LL'
labelColor = highLow == 2 ? bullishColor : highLow == 1 ? bullTrapColor : highLow == -1 ? bearTrapColor : bearishColor
labelStyle = highLow > 0 ? label.style_label_down : label.style_label_up
// labelLocation = highLow > 0? yloc.abovebar : yloc.belowbar
labelLocation = yloc.price
if showPivots
l = label.new(x=index, y=value, text=labelText, xloc=xloc.bar_index, yloc=labelLocation, style=labelStyle, size=size.tiny, color=labelColor, textcolor=textColor)
array.unshift(labelArray, l)
if array.size(labelArray) > 100
label.delete(array.pop(labelArray))
if i < array.size(zigzagindexes) - 1 and showZigzag
indexLast = array.get(zigzagindexes, i + 1)
valueLast = array.get(zigzagvalues, i + 1)
l = line.new(x1=index, y1=value, x2=indexLast, y2=valueLast, color=labelColor, width=2, style=line.style_solid)
array.unshift(lineArray, l)
if array.size(lineArray) > 100
line.delete(array.pop(lineArray))
alertcondition(doubleBottom, 'Double Bottom', 'Probable double bottom observed for {{ticker}} on {{interval}} timeframe')
alertcondition(doubleBottomConfirmation > 0, 'Double Bottom Confirmation', 'Double bottom confirmation observed for {{ticker}} on {{interval}} timeframe')
alertcondition(doubleBottomConfirmation < 0, 'Double Bottom Invalidation', 'Double bottom invalidation observed for {{ticker}} on {{interval}} timeframe')
alertcondition(doubleTop, 'Double Top', 'Probable double top observed for {{ticker}} on {{interval}} timeframe')
alertcondition(doubleTopConfirmation > 0, 'Double Top Confirmation', 'Double top confirmation observed for {{ticker}} on {{interval}} timeframe')
alertcondition(doubleTopConfirmation < 0, 'Double Top Invalidation', 'Double top invalidation observed for {{ticker}} on {{interval}} timeframe')
per = input.int(defval=100, minval=1, title='Sampling Period')
// Range Multiplier
mult = input.float(defval=2.0, minval=0.1, title='Range Multiplier')
// Smooth Average Range
smoothrng(x, t, m) =>
wper = t * 2 - 1
avrng = ta.ema(math.abs(x - x ), t)
smoothrng = ta.ema(avrng, wper) * m
smoothrng
smrng = smoothrng(src, per, mult)
// Range Filter
rngfilt(x, r) =>
rngfilt = x
rngfilt := x > nz(rngfilt ) ? x - r < nz(rngfilt ) ? nz(rngfilt ) : x - r : x + r > nz(rngfilt ) ? nz(rngfilt ) : x + r
rngfilt
filt = rngfilt(src, smrng)
// Filter Direction
upward = 0.0
upward := filt > filt ? nz(upward ) + 1 : filt < filt ? 0 : nz(upward )
downward = 0.0
downward := filt < filt ? nz(downward ) + 1 : filt > filt ? 0 : nz(downward )
// Target Bands
hband = filt + smrng
lband = filt - smrng
// Colors
filtcolor = upward > 0 ? color.lime : downward > 0 ? color.red : color.orange
barcolor = src > filt and src > src and upward > 0 ? color.lime : src > filt and src < src and upward > 0 ? color.green : src < filt and src < src and downward > 0 ? color.red : src < filt and src > src and downward > 0 ? color.maroon : color.orange
filtplot = plot(filt, color=filtcolor, linewidth=3, title='Range Filter')
// Target
hbandplot = plot(hband, color=color.new(color.aqua, 100), title='High Target')
lbandplot = plot(lband, color=color.new(color.fuchsia, 100), title='Low Target')
// Fills
fill(hbandplot, filtplot, color=color.new(color.aqua, 90), title='High Target Range')
fill(lbandplot, filtplot, color=color.new(color.fuchsia, 90), title='Low Target Range')
// Bar Color
barcolor(barcolor)
// Break Outs
longCond = bool(na)
shortCond = bool(na)
longCond := src > filt and src > src and upward > 0 or src > filt and src < src and upward > 0
shortCond := src < filt and src < src and downward > 0 or src < filt and src > src and downward > 0
CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni
longCondition = longCond and CondIni == -1
shortCondition = shortCond and CondIni == 1
//Alerts
plotshape(longCondition, title='Buy Signal', text='BUY', textcolor=color.new(color.white, 0), style=shape.labelup, size=size.normal, location=location.belowbar, color=color.new(color.green, 0))
plotshape(shortCondition, title='Sell Signal', text='SELL', textcolor=color.new(color.white, 0), style=shape.labeldown, size=size.normal, location=location.abovebar, color=color.new(color.red, 0))
alertcondition(longCondition, title='Buy Alert', message='BUY')
alertcondition(shortCondition, title='Sell Alert', message='BUY')
Inside Bar (Body-based) Ind/AlertDescription:
This indicator detects Inside Bar patterns based strictly on the candle body (open/close range) of the mother candle, rather than the traditional high/low wick method. An inside bar is highlighted when the current candle’s entire body is contained within the body of the previous candle.
It can be useful for traders who want a more conservative and reliable definition of inside bars, focusing on true consolidation periods and filtering out signals caused by extended wicks.
Features:
Body-based Inside Bar detection:
The indicator colors and marks candles where the current bar’s body is fully within the previous bar’s body.
Bullish/Bearish identification:
Bullish inside bars are marked in green, bearish in red.
Double Inside Bar Detection:
An optional feature marks when two consecutive candles’ bodies are inside the same mother bar body—potentially indicating stronger consolidation.
Alerts:
Set alerts for single or double inside bars for automated monitoring.
How to Use:
Add the indicator to your chart.
Look for colored bars or plotted shapes for inside bar signals based on candle bodies.
Use alerts to get notified in real time when inside bar patterns appear.
Note:
This script uses only the candle body (open and close) for inside bar calculations, which may help filter out less reliable signals found with wick-based approaches.
Price Action Pattern DetectorThis indicator detects price action on the chart. It will automatically add tags when an automatic pattern is formed.
Mogambo ScalpingJUST SCALP with the SIGNALS. Make little entries take your profit and enjoy the trades.
📊 Portfolio TrackerPortfolio Tracker
🧠 How This Script Works
This Pine Script generates a dynamic portfolio table in the upper-right corner of your chart. It:
Monitors your positions in: BTC, SOL, ADA, XRP, and XAU (Gold).
Calculates for each asset:
Current value,
Profit/Loss in your currency ,
Percentage change.
Color-coded output:
🟢 Green = Profit
🔴 Red = Loss
Automatically updates every few candles.
Tracks total portfolio value, PnL, and % return.
Triggers custom alerts when:
Total portfolio profit exceeds +5% or +10%.
🛠️ How to Customize It for Your Own Portfolio
🔹 1. Update your personal asset data
Inside the // === INPUTS === section of the code, modify these lines:
btc1_qty = 0.0013
btc1_entry = 72831.80
Repeat for each asset you own:
Replace xxx_qty with your amount.
Replace xxx_entry with your buy price (in your currency).
Make sure the request.security(...) line fetches the correct symbol.
🔹 2. Add more assets (optional)
Duplicate any block like ADA and change the variable names and symbols:
new_qty = ...
new_entry = ...
new_price = request.security("BINANCE:NEWTOKENUSD", timeframe.period, close)
Also include the new asset in:
total_pnl += ...
total_value_now += ...
total_cost += ...
The table.cell(...) block to show it in the table.
Why This Tool Rocks
Tracks all your holdings in one chart panel.
Requires no API or external data feed.
Real-time updates based on TradingView chart prices.
Fully editable and extendable to any other token or asset.
Complete Horizontal Pivot Lines with Color Controlpivot max min (numberbar=?) select the number of candles you want to follow and focus on the max and min, the control points of the impulses, and see better what is happening by giving you the key levels
Períodos Macros com Ajuste de Horárioindicator in TradingView that marks the macro periods on the chart with colored background bands, at the following times:
09:45 – 10:15
10:45 – 11:15
11:45 – 12:15
12:45 – 13:15
13:45 – 14:15
14:45 – 15:15
Sticky Candlestick Quarter Divider (Dynamic Update)This indicator divides the most recent candlestick into four equal parts and dynamically plots horizontal lines that move along with the latest candle.
Features:
Dynamic Sticky Lines:
The lines remain visually attached to the current candle, moving seamlessly as the chart updates, zooms, or pans.
Price Level Calculation:
Divides the candlestick into four distinct levels:
High Line (Red): Marks the highest point of the candle.
Low Line (Red): Marks the lowest point of the candle.
Midpoint Line (Blue): Marks the midpoint between high and low.
Upper Quarter Line (Green): Marks the 25% level between low and high.
Lower Quarter Line (Green): Marks the 75% level between low and high.
Real-Time Update:
The lines automatically adjust to the latest candle, maintaining accurate positioning.
Ideal for Candle Analysis:
Quickly identify key price levels and candle structure.
Suitable for analyzing trend strength and potential price reversals.
VWMA and SMA Crossover AlertUsing SMA and VWMA to find crossovers for buy and sell signals. The indicator has a bult in buy sell signal.
RSI Crossover with RSI EMAdfsffefdfnsdbhavddd
dnadghvadudvhbdasbdjadd
sdcasdvscdhgasvxdhzvjx
sasvhx zhxvjhx
Custom Green Candle Signalbuying candle indicates...................................................................................................
Customizable Disparity Index (Short EMA + Mid SMA, Base 100%)This indicator plots the Disparity Index (%) from both a short-term EMA and a mid-term SMA, using 100% as the baseline.
1. How to use:
- Disparity above 100% means price is above the selected moving average.
- Disparity below 100% indicates the price is below the moving average.
- This can help identify overbought/oversold conditions or mean-reversion opportunities.
Fully customizable periods for both EMA and SMA. Suitable for fast-moving markets like crypto.
2. Practical Interpretation of the 100% Baseline Disparity Index
100%: Price is equal to the moving average (neutral baseline)
100–103%: Normal bullish movement, price riding above MA support
105%+: Potential short-term overbought, especially after a sharp rise
110–115%+: Strong overbought signal, often followed by pullback or consolidation
95% or lower: Possible oversold condition, potential bounce or reversal zone
Use in combination with volume, RSI, or candlestick patterns for confirmation.
Candle Rating (1–5)This custom TradingView indicator assigns a rating from 1 to 5 to each candlestick on the chart based on the relative position of the close within its high-low range. It provides an at-a-glance visual assessment of candle strength or weakness, which can be useful for gauging intrabar sentiment.
Plotting the Rating
The rating value is displayed above each candle using a label.
Label colors provide intuitive visual cues:
🟩 1 (Green) – Strong bullish
🟢 2 (Lime) – Mild bullish
⚪ 3 (Gray) – Neutral
🟠 4 (Orange) – Mild bearish
🔴 5 (Red) – Strong bearish
%MAThis indicator is designed to plot a Simple Moving Average (SMA) along with customizable upper and lower bands (% up/down) on a TradingView chart. Here's a brief but thorough explanation of its functionality:
TL;DR: This script shows percentages above and below customizable moving average timeframes & legnths. It's unique in the sense that it isn't on a separate pane & gives visual clarity against the price in real time HLOC.
1. Main SMA Plot
The script calculates a Simple Moving Average (SMA) based on user-defined inputs:
Timeframe: E.g., daily ("Daily") by default.
Length: E.g., 50 periods by default.
Color: Customizable by the user.
This SMA acts as the central reference line and can be toggled on or off using a "Show" option.
2. Upper and Lower Bands
The script generates two upper bands and two lower bands around the main SMA.
Each band is derived from an SMA (calculated similarly to the main SMA) and offset by a percentage:
Upper Bands: SMA × (1 + distance percentage / 100), e.g., SMA × 1.05 for a 5% offset.
Lower Bands: SMA × (1 - distance percentage / 100), e.g., SMA × 0.95 for a 5% offset.
These bands can indicate potential support, resistance, or volatility ranges.
3. Customization
Users can independently configure:
Visibility: Toggle each band and the main SMA on or off.
Timeframe: Set the timeframe for each SMA calculation.
Length: Define the SMA period.
Distance Percentage: Adjust the offset for each band.
Color: Choose colors for all plotted lines.
This flexibility allows tailored analysis for different trading strategies or timeframes.
4. Plotting
The main SMA and each band are plotted using TradingView’s plot function, but only if their respective "Show" options are enabled.
Lines are displayed with user-specified colors and styles (e.g., the main SMA has a linewidth of 2).
Purpose
This script provides a versatile tool for technical analysis, enabling traders to visualize an SMA with percentage-based bands to identify key price levels or ranges, such as support/resistance, volatility zones, and trends, with extensive customization options.
Position Size Calculator//@version=5
indicator("Position Size Calculator", overlay=false)
sl_points = input.int(20, title="SL worth (Points)", minval=1)
max_risk = input.float(5000.0, title="Max risk aimed ($)")
contract_value_per_point = input.float(1.0, title="Value per Point (e.g., $1/pt for micro US30)")
lot_size = max_risk / (sl_points * contract_value_per_point)
label.new(x=bar_index, y=close,
text="Lot Size: " + str.tostring(lot_size, "#.##"),
style=label.style_label_down,
textcolor=color.white,
size=size.normal,
color=color.blue,
tooltip="This is your calculated lot size based on SL and Risk")
20-Day & 60-Day Disparity Index (Base 100%)**Disparity Index with 100% Baseline for 20-day & 60-day Moving Averages**
This indicator shows how far the current price is from its 20-day and 60-day simple moving averages, expressed as a percentage with 100% as the baseline. It helps traders visually identify overbought or oversold conditions relative to key moving averages.
How to Use:
- A value above 100% means the price is above the moving average.
- A value below 100% means the price is below the moving average.
- For example, 105% means the price is 5% above the moving average.
- Common buy zone: when the disparity drops below 95% (price is 5% or more below the MA).
- Use in combination with RSI, volume, or candlestick patterns for confirmation.
Settings:
- Uses 20-day and 60-day **Simple Moving Averages (SMA)**.
- You can edit the script to change these periods or switch to EMA if desired.
Useful for swing traders, mean-reversion strategies, or identifying stretched price conditions.
Created by ChartJay
Dual Candle Engulfing (Classic + Heikin Ashi) Indicators based on ris deviations and characteristic K-line patterns