ICT OB/FVG + Envelope (SMA Alertable) - 엔벨로프 신호 추가Here’s a full explanation of the strategy:
Primary Entry
Buy when price breaks above the 40-day moving average (MA40).
Envelope Scale-Out and Re-Entry
After price breaks above the +15% envelope, add to your position.
Sell 30% of your position when price breaks above the +30% envelope.
If price fails to break +30% but instead finds support at +15%, add again.
Likewise, after adding at +30%, if price pulls back to +30% and holds, add once more.
Adjust entries and exits around each envelope band.
Trend Baseline Logic
The 40-day MA is your primary trend line.
Once price is above MA40, the +15% envelope becomes your new “mini-baseline”—you only trade as long as price respects it.
Exit 100% of your position when price reaches the +100% envelope, or if it falls back below that level.
Trend Confirmation
All of this only applies in a “properly aligned” uptrend (MA40 > MA200).
A golden cross of the 40-day MA above the 200-day MA is a very strong entry filter.
Order-Block Entries
Bullish OB Low: if price touches a Bullish Order-Block Low above MA40, treat it as a pullback and buy.
Bearish OB High: if price touches a Bearish Order-Block High above MA40, treat it as a pullback-and-rebound and buy.
Stop-Loss
Stop out if price closes 3–5% below the 40-day MA.
Lower-Band “Bounce” Buys
If price touches the –15% envelope and finds support, buy 10% of your target size—exit all if it breaks below.
If price touches the –30% envelope and holds, buy again—exit all on a breach.
In short, this is a “band-play” strategy within a bullish trend, using MA40 → +15% envelope → +30% envelope → +45% envelope as your stepping-stone baselines, with order-block and lower-band bounces as additional entries. Good luck!
Corak carta
%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")
Dual Candle Engulfing (Classic + Heikin Ashi) Indicators based on ris deviations and characteristic K-line patterns
Bar ColorHis BTCUSDT Script to easy way in trade from next moving Guys due to the past levels spot and resistance and also where did price will break and push to upside,
key levels to watch
Take long hold in blue zone see our goal in long time with prefect entries
Like Pivot point
Resistance zone
Support levels
Breakout Points
Keep eye on these levels you may find details more in script
Inside Bar IndicatorFind Inside Bar helps price action traders spot inside bars without having to watch the chart constantly.
StarterPack MAsThis indicator includes 5 moving averages widely used in modern price action analysis:
EMA 9 (green): captures recent candle momentum
SMA 20 (gold): classic reference for pullbacks
SMA 50 (red): dynamic short- to mid-term support and resistance
SMA 200 (blue): long-term trend foundation
EMA 400 (pink): used by traders tracking institutional moves
Perfect for identifying trend direction, balance zones, and key confluence areas.
Use it with strategy and discipline. Moving averages show the path — execution is up to you.
Cumulative Volume Delta with Divergence🧠 Core Functionality:
1. Cumulative Volume Delta (CVD):
Purpose: Visualizes the difference between buying and selling pressure over time.
Mechanism:
It uses lower-timeframe volume delta data, retrieved from ta.requestVolumeDelta(), to build a candle-style visualization of the net volume movement.
Plotted candles show whether buying (up volume) or selling (down volume) was dominant within each period.
Teal candles: More buying than selling (CVD up).
Red candles: More selling than buying (CVD down).
Volume Source: Based on intrabar up/down volume approximation from lower timeframes.
🧭 Divergence Detection (New Feature):
2. Regular Bullish Divergence:
Condition:
Price makes a lower low.
CVD (lastVolume) makes a higher low.
Interpretation: Selling pressure is weakening despite price making new lows — a potential reversal signal to the upside.
Displayed As:
Green line and label "Bull" under the CVD at the divergence point.
3. Regular Bearish Divergence:
Condition:
Price makes a higher high.
CVD makes a lower high.
Interpretation: Buying pressure is fading despite price rising — a potential reversal signal to the downside.
Displayed As:
Red line and label "Bear" above the CVD at the divergence point.
🧰 User Controls:
Use custom timeframe: Overrides default volume delta resolution for finer or broader analysis.
Calculate Divergence: Turns the divergence detection on or off.
Adjustable via script inputs.
🔔 Alerts:
Two alert conditions are included:
One for bullish divergence.
One for bearish divergence.
Alerts trigger at the bar where the divergence is confirmed, not where it starts.
📈 Use Case:
This tool is ideal for traders looking to:
Spot early reversals or momentum shifts.
Combine volume analysis with price action.
Time entries or exits more accurately using volume-confirmed divergence.
Anchored VWAP with Bands DebugAnchored VWAP with ±1% Bands Starting at 9:00 AM
This indicator calculates an Anchored Volume Weighted Average Price (VWAP) starting precisely at 9:00 AM each trading day (customizable). It plots the VWAP line alongside two dynamic bands set at ±1% above and below the VWAP. The bands help visualize potential support and resistance zones relative to the intraday VWAP anchored at market open.
Key Features:
Anchors VWAP calculation to user-defined start time (default 9:00 AM)
Displays VWAP line in orange for easy tracking
Shows upper and lower dashed bands at ±1% of VWAP in green and red, respectively
Bands update dynamically with each new bar throughout the trading day
Designed for intraday charts (1-minute, 5-minute, etc.)
Use this tool to better assess intraday price action around VWAP and identify potential trading opportunities based on price deviations from the anchored VWAP.
High Volume Candle HighlightThis indicator visually highlights individual candles that experience unusually high trading volume. A candle is marked if its volume exceeds a user-defined multiple of the average volume over a set period (default: 20 bars). Instead of coloring the background, this script specifically colors only the candle body, making it easy to spot volume spikes without cluttering the chart.
Key Candle Re-Entry ZonesTime zone markups for the 1:25 & 9:25 times. This helps build identity for the pre-market and market analysis
FVG Candle HighlighterThis indicator highlights only the true Fair Value Gap (FVG) creator candle — the middle candle in a 3-bar FVG formation — with zero clutter.
🔹 Bullish FVG: Candle is colored if price gaps above the high two bars back
🔹 Bearish FVG: Candle is colored if price gaps below the low two bars back
✨ No boxes. No zones. Just pure, visual price-action accuracy.
🔧 Powered by Pine Script v6
🧠 Based on institutional-style FVG logic
🎯 Ideal for Smart Money / ICT / Order Block strategies
Advanced Candlestick Pattern Detector (12 Types)This Pine Script identifies 12 major candlestick patterns and distinguishes them based on market context (trend), especially for those with similar shapes (e.g., Hammer vs Hanging Man).
EMA 9/21 Cross Alerts with RSI Filter and Push AlertsSirve para compra y venta de futuros en 5m. Se entra cuand la EMA9 cruza hacia arriba la EMA 21.
Whole Dollar RaysThis script plots horizontal rays at every whole dollar level above and below the current price. It visually emphasizes key psychological price levels to help traders identify potential areas of support, resistance, and breakout zones.
EMA Validation4 EMA with Support/Resistance Validation (EMA-V)
This indicator displays four Exponential Moving Averages (EMAs) with customizable periods (default: 21, 50, 100, 200) and visually validates their roles as support or resistance.
Each EMA changes color based on its behavior: green for respected support , red for respected resistance, or default colors when unvalidated.
Ideal for traders seeking to identify reliable support and resistance levels across multiple timeframes.
Separador SemanalSeparate weekly, that's right, separate weekly but not only that but separate and I have to write this so that tw lets me publish it.
Dynamic Candle rating by Nikhil DoshiThis 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.
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
BARPUMP [BOLL TREND]Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
Barpump Bollinger Bands Strategy
TBR(3AM, 9AM, 3PM)How It Works
• Monitors 3 key institutional hours: 3AM (London Open), 9AM (New York Open), and 3PM (US Close)
• Captures the full range (high and low) of each 1H candle at those times
• Confirms breakout only if the next 1H candle closes above or below the range
• Draws the zone (box) aligned with the original hourly candle (not delayed)
• Displays retracement lines at:
- 25% (initial reaction)
- 50% (mitigation level)
- 75% (deep retracement entry)
Key Features
• Precise zone alignment — Boxes are anchored to the actual breakout candle
• Mitigation logic — Zones are considered mitigated once price revisits the 0.5 level
• Expiry filter — Zones automatically remove after 7 days
• Time zone support — Choose from major time zones or fixed UTC offsets (e.g., Etc/GMT+4)
• Multi-timeframe compatible — Works on all timeframes (1m, 5m, 15m, etc.)
• Clean structure — No duplicated boxes on lower timeframes
• Fully customizable colors and visibility toggles
Settings
• Toggle visibility for 3AM / 9AM / 3PM zones independently
• Choose time zone (supports America/New_York, UTC, Asia/Tokyo, etc.)
• Adjust how long zones stay visible (in hours)
• Enable/disable auto-removal after mitigation
Ideal For
• ICT traders
• Smart money concepts (SMC)
• Zone-based entries and liquidity grabs
• Traders using mitigation and premium/discount retracement logic
Tip
• Use this script with liquidity/volume indicators or SMT divergence for even stronger confluence.
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')
Trading Time Highlighter v2Check boxes for days of week.
Set the time you want to trade or backtest.
Adjust for UTC time.
GM
Dynamic Candle rating by Nikhil DoshiThis 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.
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