指標和策略
Better DEMAThe Better DEMA is a new tool designed to recreate the classical moving average DEMA, into a smoother, more reliable tool. Combining many methodologies, this script offers users a unique insight into market behavior.
How does it work?
First, to get a smoother signal, we need to calculate the Gaussian filter. A Gaussian filter is a smoothing filter that reduces noise and detail by averaging data with weights following a Gaussian (bell-shaped) curve.
Now that we have the source, we will calculate the following:
n2 = n/2 (half of the user defined length)
a = 2/(1+n)
ns
Now that we have that out of the way, it is time to get into the core.
Now we calculate 2 EMAs:
slow EMA => EMA over n
fast EMA => EMA over n2 period
Rather then now doing this:
DEMA = fast EMA * 2 - slow EMA
I found this to be better:
DEMA = slow EMA * (1-a) + fast EMA * a
As a last touch I took a little something from the HMA, and used a EMA with period of √n to smooth the entire the thing.
The Trend condition at base is the following (but feel free to FAFO with it):
Long = dema > dema yesterday and dema < src
Short = dema < dema yesterday and dema > src
Methodology
While the DEMA is an amazing tool used in many great indicators, it can be far too noisy.
This made me test out many filters, out of which the Gaussian performed best.
Then I tried out the non subtractive approach and that worked too, as it made it smoother.
Compacting on all I learned and smoothing it bit by bit, I think I can say this is worth looking into :).
Use cases:
Following Trends => classic, effective :)
Smoothing sources for other indicators => if done well enough, could be useful :)
Easy trend visualization => Added extra options for that.
Strategy development => Yes
Another good thing is it does not a high lookback period, so it should be better and less overfit.
That is all for today Gs,
Have fun and enjoy!
AlfaBitcoin Dashboard – Estrategia Combinada (Juan + Gael)Integrate the TradingView (TV) indicators with the sessions from October 16 and 21 (Gael Sánchez Smith and Juan Rodríguez). We can build an alert system or dashboard that combines what was discussed in both sessions with your custom indicators on TradingView.
Multi Time Frame EMAsThree EMAs with the option to hide them on higher timeframes. Simple and easy to use.
Saty Pivot Ribbon Pro// Saty Pivot Ribbo Pro
// Copyright (C) 2022-2025 Saty Mahajan
//
// A Moving Average Ribbon system that simplifies measuring and using Moving Averages for trend and support/resistance.
// Special thanks to Ripster for his education and EMA Clouds which inspired this indicator.
//@version=5
indicator('Saty Pivot Ribbon Pro', 'Saty Pivot Ribbon Pro', overlay=true)
// Saty Color Theme
saty_green = color.rgb(0, 255, 30)
saty_blue = color.rgb(0, 185, 255)
saty_red = color.rgb(255, 0, 0)
saty_orange = color.rgb(255, 150, 0)
saty_yellow = color.rgb(255,255,0)
saty_violet = color.rgb(150, 100, 255)
saty_purple = color.rgb(150, 0, 150)
saty_pink = color.rgb(255, 0, 255)
saty_white = color.rgb(255, 255, 255)
saty_light_gray = color.rgb(200,200,200)
saty_gray = color.rgb(150,150,150)
saty_dark_gray = color.rgb(100,100,100)
saty_black = color.rgb(0, 0, 0)
// Settings
time_warp = input.string("off", 'Time Warp', options= )
fast_ema = input(title='Fast EMA Length', defval=8)
show_fast_ema_highlight = input(false, 'Show Fast EMA Highlight')
fast_ema_highlight_color = input(saty_white, 'Fast EMA Highlight Color')
show_pullback_overlap = input(true, 'Show Pullback Overlap')
pullback_overlap_ema = input(title='Pullback Overlap EMA Length',defval=13)
show_pullback_overlap_ema_highlight = input(false, 'Show Pullback EMA Highlight')
pullback_overlap_ema_highlight_color = input(saty_white, 'Pullback EMA Highlight Color')
pivot_ema = input(title='Pivot EMA Length', defval=21)
show_pivot_ema_highlight = input(true, 'Show Pivot EMA Highlight')
pivot_ema_highlight_color = input(saty_white, 'Pivot EMA Highlight Color')
show_pivot_bias = input(true, 'Show Pivot Bias')
pivot_bias_ema = input(title = 'Pivot Bias EMA Length', defval=8)
slow_ema = input(title='Slow EMA Length', defval=48)
show_slow_ema_highlight = input(false, 'Show Slow EMA Highlight')
slow_ema_highlight_color = input(saty_white, 'Slow EMA Highlight Color')
show_long_term_ema = input(true, 'Show Long-Term EMA')
long_term_ema = input(title='Long-term EMA Length', defval=200)
show_long_term_bias = input(true, 'Show Long-term Bias')
long_term_bias_ema = input(title = 'Long-term Bias EMA Length', defval=21)
show_candle_bias = input(true, "Show Candle Bias")
bias_ema = input(48, 'Bias EMA')
show_candle_bias_compression_candles = input(false, "Show Candle Bias Compression Candles")
bullish_fast_cloud_color = input(color.green, 'Bullish Fast Cloud Color')
bearish_fast_cloud_color = input(color.red, 'Bearish Fast Cloud Color')
bullish_slow_cloud_color = input(color.aqua, 'Bullish Slow Cloud Color')
bearish_slow_cloud_color = input(color.orange, 'Bearish Slow Cloud Color')
cloud_transparency = input(title='Cloud Transparency (0-100)', defval=60)
show_conviction_arrows = input(true, 'Show Conviction Arrows')
bullish_conviction_color = input(saty_blue, 'Bullish Conviction Arrow Color')
bearish_conviction_color = input(saty_orange, 'Bearish Conviction Arrow Color')
show_fast_conviction_ema = input(false, 'Show Fast Conviction EMA')
fast_conviction_ema = input(13, 'Fast Conviction EMA Length')
fast_conviction_ema_color = input(saty_light_gray, 'Fast Conviction EMA Color')
show_slow_conviction_ema = input(false, 'Show Slow Conviction EMA')
slow_conviction_ema = input(48, 'Slow Conviction EMA Length')
slow_conviction_ema_color = input(saty_purple, 'Slow Conviction EMA Color')
// Time Warp timeframe
// Set the appropriate timeframe based on trading mode
timeframe_func() =>
timeframe = timeframe.period
if time_warp == 'off'
timeframe := timeframe.period
else if time_warp == '1m'
timeframe := '1'
else if time_warp == '2m'
timeframe := '2'
else if time_warp == '3m'
timeframe := '3'
else if time_warp == '4m'
timeframe := '4'
else if time_warp == '5m'
timeframe := '5'
else if time_warp == '10m'
timeframe := '10'
else if time_warp == '15m'
timeframe := '15'
else if time_warp == '20m'
timeframe := '20'
else if time_warp == '30m'
timeframe := '30'
else if time_warp == '1h'
timeframe := '60'
else if time_warp == '2h'
timeframe := '120'
else if time_warp == '4h'
timeframe := '240'
else if time_warp == 'D'
timeframe := 'D'
else if time_warp == 'W'
timeframe := 'W'
else if time_warp == 'M'
timeframe := 'M'
else if time_warp == 'Y'
timeframe := '12M'
else
timeframe := timeframe.period
// Calculations
ticker = ticker.new(syminfo.prefix, syminfo.ticker, session=session.extended)
price = request.security(ticker, timeframe_func(), close, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
fast_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, fast_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
pullback_overlap_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, pullback_overlap_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
pivot_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, pivot_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
pivot_bias_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, pivot_bias_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
slow_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, slow_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
long_term_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, long_term_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
long_term_bias_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, long_term_bias_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
fast_conviction_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, fast_conviction_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
slow_conviction_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, slow_conviction_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
// Create plots
fast_ema_plot = plot(fast_ema_value, color=show_fast_ema_highlight ? fast_ema_highlight_color : na, title='Fast EMA')
pullback_overlap_ema_plot = plot(pullback_overlap_ema_value, color=(show_pullback_overlap_ema_highlight and show_pullback_overlap) ? pullback_overlap_ema_highlight_color : na, title='Pullback Overlap EMA')
pivot_ema_bias_color = show_pivot_bias ? (pivot_bias_ema_value >= pivot_ema_value ? saty_green : saty_red) : pivot_ema_highlight_color
pivot_ema_plot = plot(pivot_ema_value, color=show_pivot_ema_highlight ? pivot_ema_bias_color : na, title='Pivot EMA')
slow_ema_plot = plot(slow_ema_value, color=show_slow_ema_highlight ? slow_ema_highlight_color : na, title='Slow EMA')
long_term_ema_bias_color = show_long_term_bias ? (long_term_bias_ema_value >= long_term_ema_value ? saty_blue : saty_orange) : saty_white
long_term_ema_plot = plot(long_term_ema_value, color=show_long_term_ema ? long_term_ema_bias_color : na, title='Long-term EMA')
// Fill in the plots to create clouds
fast_cloud_color = fast_ema_value >= pivot_ema_value ? color.new(bullish_fast_cloud_color, cloud_transparency) : color.new(bearish_fast_cloud_color, cloud_transparency)
fill(fast_ema_plot, pivot_ema_plot, color=fast_cloud_color, title='Fast Cloud', transp=90)
pullback_overlap_cloud_color = pullback_overlap_ema_value >= slow_ema_value ? color.new(bullish_slow_cloud_color, cloud_transparency) : color.new(bearish_slow_cloud_color, cloud_transparency)
fill(pullback_overlap_ema_plot, slow_ema_plot, color=show_pullback_overlap ? pullback_overlap_cloud_color : na, title='Slow Cloud', transp=90)
slow_cloud_color = pivot_ema_value >= slow_ema_value ? color.new(bullish_slow_cloud_color, cloud_transparency) : color.new(bearish_slow_cloud_color, cloud_transparency)
fill(pivot_ema_plot, slow_ema_plot, color=show_pullback_overlap ? na : slow_cloud_color, title="Slow Cloud Overlapped", transp=90)
// Conviction Arrows (default based on 13/48)
bullish_conviction = fast_conviction_ema_value >= slow_conviction_ema_value
bearish_conviction = fast_conviction_ema_value < slow_conviction_ema_value
bullish_conviction_confirmed = bullish_conviction == true and bullish_conviction == false
bearish_conviction_confirmed = bearish_conviction == true and bearish_conviction == false
plotshape(bullish_conviction_confirmed and show_conviction_arrows, style=shape.triangleup, color=bullish_conviction_color, location=location.abovebar, size=size.tiny)
plotshape(bearish_conviction_confirmed and show_conviction_arrows, style=shape.triangledown, color=bearish_conviction_color, location=location.belowbar, size=size.tiny)
fast_conviction_ema_plot = plot(fast_conviction_ema_value, color=show_fast_conviction_ema ? fast_conviction_ema_color : na, title='Fast Conviction EMA')
slow_conviction_ema_plot = plot(slow_conviction_ema_value, color=show_slow_conviction_ema ? slow_conviction_ema_color : na, title='Slow Conviction EMA')
// # Bollinger Band Compression Signal
compression_pivot = ta.ema(close, 21)
above_compression_pivot = close >= compression_pivot
bband_offset = 2.0 * ta.stdev(close, 21)
bband_up = compression_pivot + bband_offset
bband_down = compression_pivot - bband_offset
compression_threshold_up = compression_pivot + (2.0 * ta.atr(14))
compression_threshold_down = compression_pivot - (2.0 * ta.atr(14))
expansion_threshold_up = compression_pivot + (1.854 * ta.atr(14))
expansion_threshold_down = compression_pivot - (1.854 * ta.atr(14))
compression = above_compression_pivot ? (bband_up - compression_threshold_up) : (compression_threshold_down - bband_down)
in_expansion_zone = above_compression_pivot ? (bband_up - expansion_threshold_up) : (expansion_threshold_down - bband_down)
expansion = compression <= compression
compression_tracker = false
if expansion and in_expansion_zone > 0
compression_tracker := false
else if compression <= 0
compression_tracker := true
else
compression_tracker := false
// Candle Bias
bias_ema_value = request.security(syminfo.tickerid, timeframe_func(), ta.ema(price, bias_ema) , gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
above_pivot = close >= bias_ema_value
below_pivot = close < bias_ema_value
up = open < close
doji = open == close
down = open > close
bias_candle_color = compression_tracker and up and show_candle_bias and show_candle_bias_compression_candles ? saty_violet :
compression_tracker and down and show_candle_bias and show_candle_bias_compression_candles ? saty_purple :
above_pivot and up and show_candle_bias ? saty_green :
below_pivot and up and show_candle_bias ? saty_orange :
above_pivot and down and show_candle_bias ? saty_blue :
below_pivot and down and show_candle_bias ? saty_red :
doji and show_candle_bias ? color.gray :
na
plotcandle(open,high,low,close,color = bias_candle_color, bordercolor = bias_candle_color, wickcolor = bias_candle_color)
QQQ overlay over NQ/NDXThis enhanced version of the QQQ overlay script builds on the original by © PtGambler, adding smoothing via stepped ratios updated on candle close to eliminate oscillation, optimizing performance by reusing lines/labels, restricting visibility to relevant symbols (NDX, NQ1!, NAS100USD), and improving visuals with rounded levels, adjustable level counts (default 5 total), extended lines, and label styles matching "Key Levels" indicator for better readability (gray text, transparent background). Removed unnecessary table and floating labels for a cleaner chart. Thanks to © PtGambler for the foundational work!
ICT Reversals identify when the "top is in " or the bottom is in ,
3 factors to detect if top or bottom is in based on ICT principals:
1. daily High and Daily low of the previous day - the market will reach that point and likely to reverse
2.diviation from Volume at top or bottom compared to the last X candles - default is 9.
3. detection of FVG on the last 4 candles to identify imbalance - stretched price aka distribution
after this the market will either consolidate and then reveres or consolidate and retrace before another leg up - remember retracement is 70% min so its enough to use also on retracement not just reversal.
IT ONLY WORKS ON 4 CHART ATM
Remember WAIT for the FVG to be touched on the bounce before entring !!
GL
Liquidity Levels - PMH/PWH/PDH/HODWhat is it?
An indicator that tracks the main liquidity levels on TradingView, displaying the highs and lows of reference for month, week, previous day and current day.
What's it for?
It identifies price zones where there are many pending orders (liquidity). Traders use it to:
Find support and resistance points
Identify areas where price could bounce or break through
Receive alerts when price touches or breaks these levels
Which levels does it show?
LevelDescriptionColorLinePMH/PMLPrevious month's high and lowPurpleSolidPWH/PWLPrevious week's high and lowBlueSolidPDH/PDLPrevious day's high and lowOrangeSolidHOD/LODCurrent day's high and lowGrayDotted
How to use it?
Apply the indicator to your chart
Customize colors and enable/disable the levels you prefer
Set alerts to receive notifications when price touches or breaks levels
Use the levels to make trading decisions (entry, exit, stop loss)
Perfect for: Scalping, Day Trading, Swing Trading on any asset (forex, crypto, stocks)
Displacement + Liquidity Levels//@version=5
indicator("Displacement + Liquidity Levels", overlay=true, max_lines_count=500)
// INPUTS
swingLeft = input.int(5, "Swing Left")
swingRight = input.int(5, "Swing Right")
rangeLen = input.int(10, "Range Lookback")
// SWINGS
relevantHigh = ta.pivothigh(high, swingLeft, swingRight)
relevantLow = ta.pivotlow(low, swingLeft, swingRight)
// ARRAYS
var line highLines = array.new_line()
var line lowLines = array.new_line()
// LIQUIDITY SWEEPS
sweepHigh = not na(relevantHigh) and high > relevantHigh and close < relevantHigh
sweepLow = not na(relevantLow) and low < relevantLow and close > relevantLow
// DISPLACEMENT
bodySize = math.abs(close - open)
candleRange = high - low
avgRange = ta.sma(candleRange, rangeLen)
displacementUp = close > open and bodySize > candleRange*0.6 and candleRange > avgRange
displacementDown = open > close and bodySize > candleRange*0.6 and candleRange > avgRange
// SIGNALS
bullishSignal = sweepLow and displacementUp
bearishSignal = sweepHigh and displacementDown
plotshape(bullishSignal, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.large, text="LONG")
plotshape(bearishSignal, style=shape.triangledown, location=location.abovebar, color=color.red, size=size.large, text="SHORT")
// NEUE LINIEN
if not na(relevantHigh)
l = line.new(bar_index, relevantHigh, bar_index + 500, relevantHigh, extend=extend.right, color=color.red, width=2)
array.push(highLines, l)
if not na(relevantLow)
l = line.new(bar_index, relevantLow, bar_index + 500, relevantLow, extend=extend.right, color=color.green, width=2)
array.push(lowLines, l)
// LINIEN LÖSCHEN, WENN GETOUCHT
for i = array.size(highLines)-1 to 0 by -1
l = array.get(highLines, i)
if high >= line.get_price(l, bar_index)
line.delete(l)
array.remove(highLines, i)
for i = array.size(lowLines)-1 to 0 by -1
l = array.get(lowLines, i)
if low <= line.get_price(l, bar_index)
line.delete(l)
array.remove(lowLines, i)
// High/Low-Relevanz sofort
liqHigh = ta.highest(high, 3)
liqLow = ta.lowest(low, 3)
if high == liqHigh
line.new(bar_index, high, bar_index + 500, high, extend=extend.right, color=color.red, width=2)
if low == liqLow
line.new(bar_index, low, bar_index + 500, low, extend=extend.right, color=color.green, width=2)
Displacement + Liquidity Levels//@version=5
indicator("Displacement + Liquidity Levels", overlay=true, max_lines_count=500)
// INPUTS
swingLeft = input.int(5, "Swing Left")
swingRight = input.int(5, "Swing Right")
rangeLen = input.int(10, "Range Lookback")
// SWINGS
relevantHigh = ta.pivothigh(high, swingLeft, swingRight)
relevantLow = ta.pivotlow(low, swingLeft, swingRight)
// ARRAYS
var line highLines = array.new_line()
var line lowLines = array.new_line()
// LIQUIDITY SWEEPS
sweepHigh = not na(relevantHigh) and high > relevantHigh and close < relevantHigh
sweepLow = not na(relevantLow) and low < relevantLow and close > relevantLow
// DISPLACEMENT
bodySize = math.abs(close - open)
candleRange = high - low
avgRange = ta.sma(candleRange, rangeLen)
displacementUp = close > open and bodySize > candleRange*0.6 and candleRange > avgRange
displacementDown = open > close and bodySize > candleRange*0.6 and candleRange > avgRange
// SIGNALS
bullishSignal = sweepLow and displacementUp
bearishSignal = sweepHigh and displacementDown
plotshape(bullishSignal, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.large, text="LONG")
plotshape(bearishSignal, style=shape.triangledown, location=location.abovebar, color=color.red, size=size.large, text="SHORT")
// NEUE LINIEN
if not na(relevantHigh)
l = line.new(bar_index, relevantHigh, bar_index + 500, relevantHigh, extend=extend.right, color=color.red, width=2)
array.push(highLines, l)
if not na(relevantLow)
l = line.new(bar_index, relevantLow, bar_index + 500, relevantLow, extend=extend.right, color=color.green, width=2)
array.push(lowLines, l)
// LINIEN LÖSCHEN, WENN GETOUCHT
for i = array.size(highLines)-1 to 0 by -1
l = array.get(highLines, i)
if high >= line.get_price(l, bar_index)
line.delete(l)
array.remove(highLines, i)
for i = array.size(lowLines)-1 to 0 by -1
l = array.get(lowLines, i)
if low <= line.get_price(l, bar_index)
line.delete(l)
array.remove(lowLines, i)
HTF Session Boxes H4 > H2 > H1HTF Session Boxes H4 > H2 > H1
Visualize higher timeframe candle structures on lower timeframe charts with nested, customizable boxes.
Overview
HTF Session Boxes plots 4-hour, 2-hour, and 1-hour candle ranges as nested boxes directly on your lower timeframe charts (15M and below). This provides instant visual context of higher timeframe structure without switching between different chart timeframes.
Key Features
- Three Timeframe Levels: Simultaneously displays 4H, 2H, and 1H candle boxes
- Nested Design: Boxes are layered inside each other for clear hierarchical structure
- Real-Time Updates: Boxes dynamically adjust as higher timeframe candles develop
Fully Customizable:
-Individual colors and transparency for each timeframe
-Custom border colors, widths, and styles (solid, dashed, dotted)
-Toggle each timeframe on/off independently
Best Use Cases
-Scalping & Day Trading: Maintain awareness of higher timeframe structure while trading lower
timeframes
-Session Analysis: Clearly see 4H session boundaries and internal 2H/1H divisions
-Support/Resistance: Identify key levels where higher timeframe candles open, close, or create
highs/lows
-Multi-Timeframe Confluence: Spot when multiple timeframes align at key price levels
OBV with Divergence (SMA Smoother)Title: OBV Divergence with SMA Smoothing
Description:
This indicator is a powerful tool designed to identify regular (reversal) and hidden (continuation) On-Balance Volume (OBV) divergences against price action. It uses a modified OBV calculation (an OBV Oscillator) and integrates pivot analysis to automatically highlight potential turning points or trend continuations directly on your chart.
Key Features
Advanced Divergence Detection: Automatically detects and labels four types of divergences:
Regular Bullish/Bearish: Signals potential trend reversals.
Regular Bullish: Price makes a Lower Low (LL) but the OBV Oscillator makes a Higher Low (HL).
Regular Bearish: Price makes a Higher High (HH) but the OBV Oscillator makes a Lower High (LH).
Hidden Bullish/Bearish: Signals potential trend continuations.
Hidden Bullish: Price makes a Higher Low (HL) but the OBV Oscillator makes a Lower Low (LL).
Hidden Bearish: Price makes a Lower High (LH) but the OBV Oscillator makes a Higher High (HH).
OBV Oscillator: Instead of plotting the raw OBV, this script uses the difference between the OBV and its Exponential Moving Average (EMA). This technique centers the indicator around zero, making it easier to visualize volume momentum shifts and clearly identify peaks and troughs for divergence analysis.
Optional SMA Smoothing Line (New Feature): An added Simple Moving Average (SMA) line can be toggled on to further smooth the OBV Oscillator. Traders can use this line for crossover signals or to confirm the underlying trend of the volume momentum, reducing whipsaws.
Customizable Lookback: The indicator allows you to define the lookback periods (Pivot Lookback Left/Right) for price and oscillator pivots, giving you precise control over sensitivity. The Max/Min of Lookback Range helps filter out divergences that are too close or too far apart.
McRoulio (Monthly Anchored VWAPs)The McRoulio indicator is designed to provide a clear view of market value relative to the current and previous month's starting points. It must be used on intraday timeframes (like 1H, 4H, 15m) to function correctly.
All VWAP calculations use (O+H+L+C)/4 as the price source.
Here is what the indicator does:
⚪ Current Month VWAP (Thick White Line)
Anchored to the 1st (00:00) of the current month.
Includes 1.0 Standard Deviation bands.
Displays a "Mcwrap" label. 🔴 Last Month VWAP (Orange Line)
Anchored to the 1st (00:00) of the previous month.
This line is only visible for the duration of that previous month, allowing for historical reference. ⏳ Previous VWAP Level (Horizontal Orange Line)
This line shows the final, settled price of the previous month's VWAP.
It is only visible between the 27th of the month and the 3rd of the next month, highlighting a potential support/resistance zone during the "turn of the month."
Displays a "Mcwrap Mois dernier" label. Trolled par le gap & le mcwrap 😘
Symbol GuardSymbol Guard (configurable, v6) — a tiny “chart bouncer” to prevent accidental symbol swaps. Two modes only: exact full ticker (tickerid) or base currency.
Usage: add the indicator, choose Compare by, then set Expected ticker (tickerid) or Expected base currency. Leaving the selected field empty means “no restriction.” Simple, focused, and just bossy enough to save your setup.
나의 strategy//@version=6
strategy("Jimb0ws Strategy + All Bubble Zones + Golden Candles + Limited Signals", overlay=true, calc_on_every_tick=true, max_bars_back=5000)
// ─── INPUTS ─────────────────────────────────────────────────────────────────
pipBodyTol = input.float(0, title="Pip Tolerance for Body Touch", step=0.0001)
pipWickTol = input.float(0.002, title="Pip Tolerance for Wick Touch", step=0.0001)
maxBodyDrive = input.float(0, title="Max Drive from EMA for Body", step=0.0001)
maxWickDrive = input.float(0.002, title="Max Drive from EMA for Wick", step=0.0001)
fractalSizeOpt = input.string("small", title="Fractal Size", options= )
minBodySize = input.float(0, title="Min Body Size for Golden Candle", step=0.0001)
longOffsetPips = input.int(25, title="Long Label Offset (pips)", minval=0)
shortOffsetPips = input.int(25, title="Short Label Offset (pips)", minval=0)
consolOffsetPips = input.int(25, title="Consolidation Label Offset (pips)", minval=0)
longSignType = input.string("Label Down", title="Long Bubble Sign Type", options= )
shortSignType = input.string("Label Up", title="Short Bubble Sign Type", options= )
consolSignType = input.string("Label Down", title="Consolidation Bubble Sign Type", options= )
enable1hEmaFilter = input.bool(true, title="Disable Signals beyond 1H EMA50")
showZones = input.bool(true, title="Show Bubble Zones")
showSigns = input.bool(true, title="Show Bubble Signs")
maxSignalsPerBubble = input.int(3, title="Max Signals Per Bubble", minval=1)
// Toggle for session filter
enableSessionFilter = input.bool(true, title="Enable Active Trading Session Filter")
sessionInput = input.session("0100-1900", title="Active Trading Session")
tzInput = input.string("Europe/London", title="Session Timezone",
options= )
actualTZ = tzInput == "Exchange" ? syminfo.timezone : tzInput
infoOffsetPips = input.int(5, title="Info Line Offset Above Price (pips)", minval=0)
warnOffsetPips = input.int(10, title="Warning Label Offset Above Infobar (pips)", minval=0)
show1HInfo = input.bool(true, title="Show 1H Bubble Info")
bufferLimit = 5000 - 1
enableProxFilter = input.bool(true, title="Disable Signals Near 1H EMA50")
proxRangePips = input.int(10, title="Proximity Range (pips)", minval=0)
enableWickFilter = input.bool(true, title="Filter Golden-Candle Wick Overdrive")
wickOverdrivePips = input.int(0, title="Wick Overdrive Range (pips)", minval=0)
// turn Robin candles on/off
enableRobin = input.bool(true, title="Enable Robin Candles")
// ATR panel attached to 4H info
showPrevDayATR = input.bool(true, title="Show Previous Day ATR Panel")
atrLenPrevDay = input.int(14, title="ATR Length (Daily)", minval=1)
atrPanelOffsetPips = input.int(3, title="ATR Panel Offset Above 4H Info (pips)", minval=0)
// ─── STRATEGY TRADES (EMA200 SL, RR=2 TP) ───────────────────────────────────
enableAutoTrades = input.bool(true, title="Enable Strategy Entries/Exits")
takeProfitRR = input.float(2.0, title="TP Risk:Reward (x)", step=0.1, minval=0.1)
// ─── SL/TP info label on signals ─────────────────────────────────────────────
showSLTPPanel = input.bool(true, title="Show SL/TP Info Above Signals")
sltpOffsetPips = input.int(4, title="SL/TP Label Offset (pips)", minval=0)
// Previous Day ATR (D1, lookahead OFF) -> lock to yesterday with
dailyATR = request.security(syminfo.tickerid, "D", ta.atr(atrLenPrevDay),
lookahead=barmerge.lookahead_off, gaps=barmerge.gaps_off)
prevDayATR = dailyATR
// Convert to pips (FX: pip ≈ mintick*10)
pipValueFX = syminfo.mintick * 10.0
prevATR_pips_1d = na(prevDayATR) ? na : math.round((prevDayATR / pipValueFX) * 10.0) / 10.0
// Create table once
var table atrPanel = na
if barstate.isfirst and na(atrPanel)
// columns=1, rows=2 (title row + value row)
atrPanel := table.new(position.top_right, 1, 2, border_width=1,
frame_color=color.new(color.gray, 0), border_color=color.new(color.gray, 0))
// Update cells each last bar
if barstate.islast and not na(atrPanel)
if showPrevDayATR
titleTxt = "Prev Day ATR (" + str.tostring(atrLenPrevDay) + ")"
valTxt = na(prevDayATR) ? "n/a"
: str.tostring(prevATR_pips_1d) + " pips (" + str.tostring(prevDayATR, format.mintick) + ")"
table.cell(atrPanel, 0, 0, titleTxt, text_color=color.white, bgcolor=color.new(color.blue, 25))
table.cell(atrPanel, 0, 1, valTxt, text_color=color.white, bgcolor=color.new(color.black, 0))
else
// Hide panel by writing empty strings
table.cell(atrPanel, 0, 0, "")
table.cell(atrPanel, 0, 1, "")
// Visuals for orders
showSLTP = input.bool(true, title="Show SL/TP Lines & Labels")
// ─── EMA CALCULATIONS & PLOTTING ──────────────────────────────────────────────
ema20 = ta.ema(close, 20)
ema50 = ta.ema(close, 50)
ema100 = ta.ema(close, 100)
ema200 = ta.ema(close, 200)
ema50_1h = request.security(syminfo.tickerid, "60", ta.ema(close, 50), lookahead=barmerge.lookahead_on)
plot(ema20, color=color.white, linewidth=4, title="EMA20")
plot(ema50, color=color.yellow, linewidth=4, title="EMA50")
plot(ema100, color=color.blue, linewidth=4, title="EMA100")
plot(ema200, color=color.purple, linewidth=6, title="EMA200") // ← and this
plot(ema50_1h, title="EMA50 (1H)", color=color.yellow, linewidth=2)
// pip-unit helper
pipUnit1h = syminfo.mintick * proxRangePips * 10
upperBand1h = ema50_1h + pipUnit1h
lowerBand1h = ema50_1h - pipUnit1h
// draw top/bottom lines in one-liner plots, then fill the gap
p_top = plot(enableProxFilter ? upperBand1h : na, title="Prox Zone Top", color=color.new(color.yellow,90), linewidth=1)
p_bottom = plot(enableProxFilter ? lowerBand1h : na, title="Prox Zone Bottom", color=color.new(color.yellow,90), linewidth=1)
fill(p_top, p_bottom, color.new(color.yellow,90))
// ─── BUBBLE CONDITIONS & ZONES ───────────────────────────────────────────────
longBub = ema20 > ema50 and ema50 > ema100
shortBub = ema20 < ema50 and ema50 < ema100
consolOn = not longBub and not shortBub
longCol = color.new(color.green, 85)
shortCol = color.new(color.red, 85)
consCol = color.new(color.orange, 85)
bgcolor(showZones ? (longBub ? longCol : shortBub ? shortCol : consCol) : na)
// convert pips to price‐units
wickOverUnit = syminfo.mintick * wickOverdrivePips * 10
// detect when the wick “pierces” EMA50 by more than that amount
overdriveLong = low < ema50 - wickOverUnit // long bubble: wick dipped below EMA50
overdriveShort = high > ema50 + wickOverUnit // short bubble: wick rose above EMA50
// ─── GOLDEN-CANDLE LOGIC & COLORING ──────────────────────────────────────────
trendLong = longBub
trendShort = shortBub
bodySize = math.abs(close - open)
hasBigBody = bodySize >= minBodySize
bodyLow = math.min(open, close)
bodyHigh = math.max(open, close)
wickLow = low
wickHigh = high
bOK20_L = bodyLow <= ema20 + pipBodyTol and bodyLow >= ema20 - maxBodyDrive and close > ema20
bOK50_L = bodyLow <= ema50 + pipBodyTol and bodyLow >= ema50 - maxBodyDrive and close > ema50
wOK20_L = wickLow <= ema20 + pipWickTol and wickLow >= ema20 - maxWickDrive and close > ema20
wOK50_L = wickLow <= ema50 + pipWickTol and wickLow >= ema50 - maxWickDrive and close > ema50
isGoldenLong = trendLong and hasBigBody and (bOK20_L or bOK50_L or wOK20_L or wOK50_L)
bOK20_S = bodyHigh >= ema20 - pipBodyTol and bodyHigh <= ema20 + maxBodyDrive and close < ema20
bOK50_S = bodyHigh >= ema50 - pipBodyTol and bodyHigh <= ema50 + maxBodyDrive and close < ema50
wOK20_S = wickHigh >= ema20 - pipWickTol and wickHigh <= ema20 + maxWickDrive and close < ema20
wOK50_S = wickHigh >= ema50 - pipWickTol and wickHigh <= ema50 + maxWickDrive and close < ema50
isGoldenShort= trendShort and hasBigBody and (bOK20_S or bOK50_S or wOK20_S or wOK50_S)
// ─── WICK-OVERDRIVE VETO ────────────────────────────────────────────────────
if enableWickFilter
// veto any golden on which the wick over-drove the EMA50
isGoldenLong := isGoldenLong and not overdriveLong
isGoldenShort := isGoldenShort and not overdriveShort
barcolor((isGoldenLong or isGoldenShort) ? color.new(#FFD700, 0) : na)
// ─── ROBIN CANDLES ──────────────────────────────────────────────────────────
goldShort1 = isGoldenShort
goldLong1 = isGoldenLong
goldLow1 = math.min(open , close )
goldHigh1 = math.max(open , close )
robinShort = shortBub and goldShort1 and math.min(open, close) < goldLow1
robinLong = longBub and goldLong1 and math.max(open, close) > goldHigh1
barcolor(enableRobin and (robinShort or robinLong) ? color.purple : na)
// ─── FRACTALS ─────────────────────────────────────────────────────────────────
pL = ta.pivotlow(low, 2, 2)
pH = ta.pivothigh(high, 2, 2)
plotshape(not shortBub and not consolOn and not na(pL) and fractalSizeOpt == "tiny",
style=shape.triangleup, location=location.belowbar, offset=-2, color=color.green, size=size.tiny)
plotshape(not shortBub and not consolOn and not na(pL) and fractalSizeOpt == "small",
style=shape.triangleup, location=location.belowbar, offset=-2, color=color.green, size=size.small)
plotshape(not shortBub and not consolOn and not na(pL) and fractalSizeOpt == "normal",
style=shape.triangleup, location=location.belowbar, offset=-2, color=color.green, size=size.normal)
plotshape(not shortBub and not consolOn and not na(pL) and fractalSizeOpt == "large",
style=shape.triangleup, location=location.belowbar, offset=-2, color=color.green, size=size.large)
plotshape(not longBub and not consolOn and not na(pH) and fractalSizeOpt == "tiny",
style=shape.triangledown, location=location.abovebar, offset=-2, color=color.red, size=size.tiny)
plotshape(not longBub and not consolOn and not na(pH) and fractalSizeOpt == "small",
style=shape.triangledown, location=location.abovebar, offset=-2, color=color.red, size=size.small)
plotshape(not longBub and not consolOn and not na(pH) and fractalSizeOpt == "normal",
style=shape.triangledown, location=location.abovebar, offset=-2, color=color.red, size=size.normal)
plotshape(not longBub and not consolOn and not na(pH) and fractalSizeOpt == "large",
style=shape.triangledown, location=location.abovebar, offset=-2, color=color.red, size=size.large)
// ─── BUY/SELL SIGNALS & LIMIT ─────────────────────────────────────────────────
var int buyCount = 0
var int sellCount = 0
if longBub and not longBub
buyCount := 0
if shortBub and not shortBub
sellCount := 0
goldLong2 = isGoldenLong
goldShort2 = isGoldenShort
roofCheck = math.max(open , close ) >= math.max(open , close )
floorCheck = math.min(open , close ) <= math.min(open , close )
buySignal = goldLong2 and not na(pL) and roofCheck
sellSignal = goldShort2 and not na(pH) and floorCheck
// Original: inSession = not na(time(timeframe.period, sessionInput, actualTZ))
inSessionRaw = not na(time(timeframe.period, sessionInput, actualTZ))
sessionOK = enableSessionFilter ? inSessionRaw : true
// Apply 1H EMA50 filter
disableBy1h = enable1hEmaFilter and ((request.security(syminfo.tickerid, "60", ema20 ema50_1h) or (request.security(syminfo.tickerid, "60", ema20>ema50 and ema50>ema100) and close < ema50_1h))
// ─── PROXIMITY VETO ────────────────────────────────────────────────
near1hZone = enableProxFilter and close >= lowerBand1h and close <= upperBand1h
validBuy = buySignal and sessionOK and buyCount < maxSignalsPerBubble and not disableBy1h and not near1hZone
validSell = sellSignal and sessionOK and sellCount < maxSignalsPerBubble and not disableBy1h and not near1hZone
plotshape(validBuy, title="BUY", style=shape.labelup, location=location.belowbar,
color=color.green, text="BUY $", textcolor=color.white, size=size.large)
plotshape(validSell, title="SELL", style=shape.labeldown, location=location.abovebar,
color=color.red, text="SELL $", textcolor=color.white, size=size.large)
if validBuy
buyCount += 1
if validSell
sellCount += 1
// ─── 4H BUBBLE INFO LINE ──────────────────────────────────────────────────────
var line infoLine4h = na
var label infoLbl4h = na
var label atrPrevLbl = na // ATR label handle
var string bubble4hType = na
var int bubble4hStartTime = na
var int bubble4hStartIdx = na
time4h = request.security(syminfo.tickerid, "240", time, lookahead=barmerge.lookahead_on)
ema20_4h = request.security(syminfo.tickerid, "240", ta.ema(close, 20), lookahead=barmerge.lookahead_on)
ema50_4h = request.security(syminfo.tickerid, "240", ta.ema(close, 50), lookahead=barmerge.lookahead_on)
ema100_4h = request.security(syminfo.tickerid, "240", ta.ema(close,100), lookahead=barmerge.lookahead_on)
long4h = ema20_4h > ema50_4h and ema50_4h > ema100_4h
short4h = ema20_4h < ema50_4h and ema50_4h < ema100_4h
cons4h = not long4h and not short4h
if long4h and not long4h
bubble4hType := "LONG"
bubble4hStartTime := time4h
bubble4hStartIdx := bar_index
else if short4h and not short4h
bubble4hType := "SHORT"
bubble4hStartTime := time4h
bubble4hStartIdx := bar_index
else if cons4h and not cons4h
bubble4hType := "CONS"
bubble4hStartTime := time4h
bubble4hStartIdx := bar_index
active4h = ((bubble4hType=="LONG" and long4h) or (bubble4hType=="SHORT" and short4h) or (bubble4hType=="CONS" and cons4h)) and not na(bubble4hStartTime)
if active4h
durH4 = math.floor((time - bubble4hStartTime) / 3600000)
ts4 = str.format("{0,date,yyyy-MM-dd} {0,time,HH:mm}", bubble4hStartTime)
txt4 = "4H " + bubble4hType + " Bubble since " + ts4 + " Dur: " + str.tostring(durH4) + "h"
col4 = bubble4hType=="LONG" ? color.green : bubble4hType=="SHORT" ? color.red : color.orange
pipUnit4 = syminfo.mintick * 10
infoPrice4 = high + (infoOffsetPips + warnOffsetPips + 5) * pipUnit4
xStart4 = math.max(bubble4hStartIdx, bar_index - bufferLimit)
if na(infoLine4h)
infoLine4h := line.new(xStart4, infoPrice4, bar_index, infoPrice4, extend=extend.none, color=col4, width=2)
else
line.set_xy1(infoLine4h, xStart4, infoPrice4)
line.set_xy2(infoLine4h, bar_index, infoPrice4)
line.set_color(infoLine4h, col4)
if na(infoLbl4h)
infoLbl4h := label.new(bar_index, infoPrice4, txt4, xloc.bar_index, yloc.price, col4, label.style_label_left, color.white, size.small)
else
label.set_xy(infoLbl4h, bar_index, infoPrice4)
label.set_text(infoLbl4h, txt4)
label.set_color(infoLbl4h, col4)
// Prev Day ATR label just above the 4H info panel
if showPrevDayATR
atrValTxt = na(prevDayATR) ? "n/a" : str.tostring(prevATR_pips_1d) + " pips (" + str.tostring(prevDayATR, format.mintick) + ")"
atrTxt = "Prev Day ATR (" + str.tostring(atrLenPrevDay) + ") " + atrValTxt
atrY = infoPrice4 + pipUnit4 * atrPanelOffsetPips
if na(atrPrevLbl)
atrPrevLbl := label.new(bar_index, atrY, atrTxt, xloc.bar_index, yloc.price, color.new(color.blue, 25), label.style_label_left, color.white, size.small)
else
label.set_xy(atrPrevLbl, bar_index, atrY)
label.set_text(atrPrevLbl, atrTxt)
label.set_color(atrPrevLbl, color.new(color.blue, 25))
else
if not na(atrPrevLbl)
label.delete(atrPrevLbl)
atrPrevLbl := na
else
// Cleanup when 4H panel is not active
if not na(infoLine4h)
line.delete(infoLine4h)
infoLine4h := na
if not na(infoLbl4h)
label.delete(infoLbl4h)
infoLbl4h := na
bubble4hType := na
if not na(atrPrevLbl)
label.delete(atrPrevLbl)
atrPrevLbl := na
// ─── 1H BUBBLE INFO & WARNING PANEL ─────────────────────────────────────────
var line infoLine1h = na
var label infoLbl1h = na
var label warnLbl1h = na
var string bubble1hType = na
var int bubble1hStartTime = na
var int bubble1hStartIdx = na
var float pipUnit = na
var color col = na
var int xStart = na
var float infoPrice = na
var string txt = ""
// 1H trend state (kept same logic as your original)
long1h = request.security(syminfo.tickerid, "60", ema20>ema50 and ema50>ema100, lookahead=barmerge.lookahead_on)
short1h = request.security(syminfo.tickerid, "60", ema20 ema50_1h
warnY = infoPrice1h + warnOffsetPips * pipUnit1h
if na(warnLbl1h)
warnLbl1h := label.new(bar_index, warnY, "Potential Consolidation Warning",
xloc.bar_index, yloc.price, color.new(color.yellow,0),
label.style_label_up, color.black, size.small)
else
label.set_xy(warnLbl1h, bar_index, warnY)
label.set_text(warnLbl1h, "Potential Consolidation Warning")
else
if not na(warnLbl1h)
label.delete(warnLbl1h)
warnLbl1h := na
else
if not na(infoLine1h)
line.delete(infoLine1h)
infoLine1h := na
if not na(infoLbl1h)
label.delete(infoLbl1h)
infoLbl1h := na
if not na(warnLbl1h)
label.delete(warnLbl1h)
warnLbl1h := na
bubble1hType := na
// ─── ALERTS ─────────────────────────────────────────────────────────────────
alertcondition(validBuy, title="Jimb0ws Strategy – BUY", message="🔥 BUY signal on {{ticker}} at {{close}}")
alertcondition(validSell, title="Jimb0ws Strategy – SELL", message="🔻 SELL signal on {{ticker}} at {{close}}")
if validBuy
alert("🔥 BUY signal on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
if validSell
alert("🔻 SELL signal on " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)
// ─── SL/TP drawing handles (globals) ────────────────────────────────────────
var line slLine = na
var line tpLine = na
var label slLabel = na
var label tpLabel = na
var float slPrice = na
var float tpPrice = na
// Working vars so they exist on all bars
var float longEntry = na
var float longSL = na
var float longTP = na
var float riskL = na
var float shortEntry = na
var float shortSL = na
var float shortTP = na
var float riskS = na
// last SL/TP info label so we can replace it each time
var label sltpInfoLbl = na
// ─── Draw SL/TP info label exactly when a signal fires ──────────────────────
if showSLTPPanel and (validBuy or validSell)
// delete prior info label
if not na(sltpInfoLbl)
label.delete(sltpInfoLbl)
float pipUnit = syminfo.mintick * 10.0
float yAbove = high + sltpOffsetPips * pipUnit
// Entry is the close of the signal bar
float entry = close
// Choose SL by your rule:
// - LONG: if ema200 > ema100 -> SL = ema100, else SL = ema200
// - SHORT: if ema200 < ema100 -> SL = ema100, else SL = ema200
bool isLong = validBuy
float sl = isLong ? (ema200 > ema100 ? ema100 : ema200)
: (ema200 < ema100 ? ema100 : ema200)
// Compute TP using RR; guard for bad risk
float rr = takeProfitRR // your RR input (e.g., 2.0)
float risk = isLong ? (entry - sl) : (sl - entry)
float tp = na
if risk > syminfo.mintick
tp := isLong ? (entry + rr * risk) : (entry - rr * risk)
// Build label text (mintick formatting)
string slTxt = "SL " + str.tostring(sl, format.mintick)
string tpTxt = na(tp) ? "TP n/a" : "TP " + str.tostring(tp, format.mintick)
string txt = slTxt + " " + tpTxt
// Color by side and draw
color bgCol = isLong ? color.new(color.green, 10) : color.new(color.red, 10)
sltpInfoLbl := label.new(bar_index, yAbove, txt,
xloc.bar_index, yloc.price,
bgCol, label.style_label_left, color.white, size.small)
// ─── ORDERS: dynamic SL (EMA100 vs EMA200), TP = RR * risk + draw SL/TP ─────
if enableAutoTrades and barstate.isconfirmed and not na(ema100) and not na(ema200)
// LONGS — if EMA200 > EMA100 ⇒ SL = EMA100; else ⇒ SL = EMA200
if validBuy and strategy.position_size <= 0
longEntry := close
longSL := ema200 > ema100 ? ema100 : ema200
if longSL < longEntry - syminfo.mintick
riskL := longEntry - longSL
longTP := longEntry + takeProfitRR * riskL
if strategy.position_size < 0
strategy.close("Short", comment="Flip→Long")
strategy.entry("Long", strategy.long)
strategy.exit("Long-EXIT", from_entry="Long", stop=longSL, limit=longTP)
// store & draw
slPrice := longSL
tpPrice := longTP
if showSLTP
if not na(slLine)
line.delete(slLine)
if not na(tpLine)
line.delete(tpLine)
if not na(slLabel)
label.delete(slLabel)
if not na(tpLabel)
label.delete(tpLabel)
// lines
slLine := line.new(bar_index, slPrice, bar_index + 1, slPrice, extend=extend.right, color=color.red, width=2)
tpLine := line.new(bar_index, tpPrice, bar_index + 1, tpPrice, extend=extend.right, color=color.green, width=2)
// labels with exact prices
slLabel := label.new(bar_index + 1, slPrice, "SL " + str.tostring(slPrice, format.mintick), xloc.bar_index, yloc.price, color.new(color.red, 10), label.style_label_right, color.white, size.small)
tpLabel := label.new(bar_index + 1, tpPrice, "TP " + str.tostring(tpPrice, format.mintick), xloc.bar_index, yloc.price, color.new(color.green, 10), label.style_label_right, color.white, size.small)
// SHORTS — if EMA200 < EMA100 ⇒ SL = EMA100; else ⇒ SL = EMA200
if validSell and strategy.position_size >= 0
shortEntry := close
shortSL := ema200 < ema100 ? ema100 : ema200
if shortSL > shortEntry + syminfo.mintick
riskS := shortSL - shortEntry
shortTP := shortEntry - takeProfitRR * riskS
if strategy.position_size > 0
strategy.close("Long", comment="Flip→Short")
strategy.entry("Short", strategy.short)
strategy.exit("Short-EXIT", from_entry="Short", stop=shortSL, limit=shortTP)
// store & draw
slPrice := shortSL
tpPrice := shortTP
if showSLTP
if not na(slLine)
line.delete(slLine)
if not na(tpLine)
line.delete(tpLine)
if not na(slLabel)
label.delete(slLabel)
if not na(tpLabel)
label.delete(tpLabel)
slLine := line.new(bar_index, slPrice, bar_index + 1, slPrice, extend=extend.right, color=color.red, width=2)
tpLine := line.new(bar_index, tpPrice, bar_index + 1, tpPrice, extend=extend.right, color=color.green, width=2)
slLabel := label.new(bar_index + 1, slPrice, "SL " + str.tostring(slPrice, format.mintick), xloc.bar_index, yloc.price, color.new(color.red, 10), label.style_label_right, color.white, size.small)
tpLabel := label.new(bar_index + 1, tpPrice, "TP " + str.tostring(tpPrice, format.mintick), xloc.bar_index, yloc.price, color.new(color.green, 10), label.style_label_right, color.white, size.small)
// Keep labels pinned to the right of current bar while trade is open
if showSLTP and strategy.position_size != 0 and not na(slPrice) and not na(tpPrice)
label.set_xy(slLabel, bar_index + 1, slPrice)
label.set_text(slLabel, "SL " + str.tostring(slPrice, format.mintick))
label.set_xy(tpLabel, bar_index + 1, tpPrice)
label.set_text(tpLabel, "TP " + str.tostring(tpPrice, format.mintick))
// Clean up drawings when flat
if strategy.position_size == 0
slPrice := na
tpPrice := na
if not na(slLine)
line.delete(slLine)
slLine := na
if not na(tpLine)
line.delete(tpLine)
tpLine := na
if not na(slLabel)
label.delete(slLabel)
slLabel := na
if not na(tpLabel)
label.delete(tpLabel)
tpLabel := na
Savitzky-Golay Filter (SGF)The Savitzky-Golay Filter (SGF) is a digital filter that performs local polynomial regression on a series of values to determine the smoothed value for each point. Developed by Abraham Savitzky and Marcel Golay in 1964, it is particularly effective at preserving higher moments of the data while reducing noise. This implementation provides a practical adaptation for financial time series, offering superior preservation of peaks, valleys, and other important market structures that might be distorted by simpler moving averages.
## Core Concepts
* **Local polynomial fitting:** Fits a polynomial of specified order to a sliding window of data points
* **Moment preservation:** Maintains higher statistical moments (peaks, valleys, inflection points)
* **Optimized coefficients:** Uses pre-computed coefficients for common polynomial orders
* **Adaptive weighting:** Weight distribution varies based on polynomial order and window size
* **Market application:** Particularly effective for preserving significant price movements while filtering noise
The core innovation of the Savitzky-Golay filter is its ability to smooth data while preserving important features that are often flattened by other filtering methods. This makes it especially valuable for technical analysis where maintaining the shape of price patterns is crucial.
## Common Settings and Parameters
| Parameter | Default | Function | When to Adjust |
|-----------|---------|----------|---------------|
| Window Size | 11 | Number of points used in local fitting (must be odd) | Increase for smoother output, decrease for better feature preservation |
| Polynomial Order | 2 | Order of fitting polynomial (2 or 4) | Use 2 for general smoothing, 4 for better peak preservation |
| Source | close | Price data used for calculation | Consider using hlc3 for more stable fitting |
**Pro Tip:** A window size of 11 with polynomial order 2 provides a good balance between smoothing and feature preservation. For sharper peaks and valleys, use order 4 with a smaller window size.
## Calculation and Mathematical Foundation
**Simplified explanation:**
The filter fits a polynomial of specified order to a moving window of price data. The smoothed value at each point is computed from this local fit, effectively removing noise while preserving the underlying shape of the data.
**Technical formula:**
For a window of size N and polynomial order M, the filtered value is:
y = Σ(c_i × x )
Where:
- c_i are the pre-computed filter coefficients
- x are the input values in the window
- Coefficients depend on window size N and polynomial order M
> 🔍 **Technical Note:** The implementation uses optimized coefficient calculations for orders 2 and 4, which cover most practical applications while maintaining computational efficiency.
## Interpretation Details
The Savitzky-Golay filter can be used in various trading strategies:
* **Pattern recognition:** Preserves chart patterns while removing noise
* **Peak detection:** Maintains amplitude and width of significant peaks
* **Trend analysis:** Smooths price movement without distorting important transitions
* **Divergence trading:** Better preservation of local maxima and minima
* **Volatility analysis:** Accurate representation of price movement dynamics
## Limitations and Considerations
* **Computational complexity:** More intensive than simple moving averages
* **Edge effects:** First and last few points may show end effects
* **Parameter sensitivity:** Performance depends on appropriate window size and order selection
* **Data requirements:** Needs sufficient points for polynomial fitting
* **Complementary tools:** Best used with volume analysis and momentum indicators
## References
* Savitzky, A., Golay, M.J.E. "Smoothing and Differentiation of Data by Simplified Least Squares Procedures," Analytical Chemistry, 1964
* Press, W.H. et al. "Numerical Recipes: The Art of Scientific Computing," Chapter 14
* Schafer, R.W. "What Is a Savitzky-Golay Filter?" IEEE Signal Processing Magazine, 2011
ASTER Key Levels & Alerts (Improved)TradingView Script Description
Title: ASTER Key Levels & Alerts (Improved)
Description:
Enhance your trading strategy with the "ASTER Key Levels & Alerts" indicator, designed for precision and decision-making on the Aster chart (e.g., ASTS). This Pine Script v6 tool overlays customizable key levels and zones to identify optimal entry, exit, and stop-loss points, complete with real-time alerts.Key Features:
Customizable Levels: Adjust add zones (Light & Main), breakout, stop, and take-profit (TP1-TP3
ATR Money Line Bands V2The "ATR Money Line Bands V2" is a clever TradingView overlay designed for trend identification with volatility-aware bands, evolving from basic ATR envelopes.
Reasoning Behind Construction: The core idea is to blend a smoothed trend line with dynamic volatility bands for reliable signals in varying markets. The "Money Line" uses linear regression (ta.linreg) on closes over a length (default 16) instead of a moving average, as it fits data via least-squares for a cleaner, forward-projected trend without lag artifacts. ATR (default 12-period) powers the bands because it measures true range volatility better than std dev in gappy assets like crypto/stocks—bands offset from the Money Line by ATR * multiplier (default 1.5). A dynamic multiplier (boosts by ~33% on spikes > prior ATR * 1.3) prevents tight bands from false breakouts during surges. Trend detection checks slope against an ATR-scaled tolerance (default 0.15) to ignore noise, labeling bull/bear/neutral—avoiding whipsaws in flats.
Properties: It's an overlay with a colored Money Line (green bull, red bear, yellow neutral) and invisible bands (toggle to show gray lines) filled semi-transparently matching trend for visual pop. Dynamic adaptation makes bands widen/contract intelligently. An info table (positionable, e.g., top_right) displays real-time values: Money Line, bands, ATR, trend—great for quick scans. Limits history (2000 bars) and labels (500) for efficiency.
Tips for Usage: Apply to any timeframe/asset; defaults suit medium-term (e.g., daily stocks). Watch color flips: green for longs (enter on pullbacks to lower band), red for shorts (vice versa), yellow to sit out. Use bands as S/R—breakouts signal momentum, squeezes impending vol. Tweak length for sensitivity (shorter for intraday), multiplier for width (higher for trends), tolerance for fewer neutrals. Pair with volume/RSI for confirmation; backtest to optimize. In choppy markets, disable dynamic mult to avoid over-expansion. Overall, it's adaptive and visual—helps trend-follow without overcomplicating.
2-Candle PDFThe Dynamic Fusion Indicator (DFI) is a powerful analytical tool designed to identify high-probability trading opportunities by combining trend momentum, volatility, and volume flow into one clear signal. It adapts in real time to changing market conditions, highlighting optimal entry and exit zones with intuitive color coding. The DFI filters out market noise using a hybrid smoothing algorithm, ensuring clarity even in choppy environments. Suitable for all timeframes and instruments, it helps traders anticipate reversals, confirm trends, and manage risk more effectively. Whether you’re scalping or swing trading, the DFI provides a confident, data-driven edge in any market.
Market Status PanelMarket Status Panel - Real-Time Trading Dashboard
A clean, minimalist heads-up display that shows critical market conditions at a glance. No chart clutter—just the essential information you need to make informed trading decisions.
What It Does
This indicator creates a compact information panel in the bottom-right corner of your chart, displaying four key metrics that update in real-time:
Relative Volume - Shows if current volume is high or low compared to the 20-bar average, with the exact multiplier
MACD Trend - Displays whether the MACD line is above (bullish) or below (bearish) the signal line
Overall Trend - Identifies market direction based on EMA alignment (9, 21, and 200 periods)
ATR Value - Shows the current Average True Range for volatility assessment
How to Use It
Simply add the indicator to your chart. The panel automatically updates on every bar and provides color-coded status indicators:
Green = Bullish/High (favorable conditions)
Red = Bearish/Low (caution conditions)
Gray = Neutral (no clear trend)
Use this dashboard to quickly assess:
Whether volume supports the current move
If momentum (MACD) aligns with price action
The strength and direction of the overall trend
Current volatility levels for position sizing
Settings
All key parameters are customizable:
Moving Averages:
EMA Fast (default: 9)
EMA Medium (default: 21)
EMA Long (default: 200)
MACD:
Fast length (default: 12)
Slow length (default: 26)
Signal length (default: 9)
Volume:
High volume threshold multiplier (default: 1.5x)
Volume average length (default: 20)
ATR:
ATR calculation period (default: 14)
Best For
Day traders who need quick market condition assessment
Scalpers looking for volume and momentum confirmation
Swing traders checking trend alignment
Anyone who wants critical data without visual chart clutter
Features
✓ Lightweight and non-intrusive
✓ Works on any timeframe
✓ All metrics update in real-time
✓ Fully customizable parameters
✓ Color-coded for instant readability
✓ No alerts or notifications (pure information display)
Triangular Moving Average (TRIMA)The Triangular Moving Average (TRIMA) is a technical indicator that applies a triangular weighting scheme to price data, providing enhanced smoothing compared to simpler moving averages. Originating in the early 1970s as technical analysts sought more effective noise filtering methods, the TRIMA was first popularized through the work of market technician Arthur Merrill. Its formal mathematical properties were established in the 1980s, and the indicator gained widespread adoption in the 1990s as computerized charting became standard. TRIMA effectively filters out market noise while maintaining important trends through its unique center-weighted calculation method.
## Core Concepts
* **Double-smoothing process:** TRIMA can be viewed as applying a simple moving average twice, creating more effective noise filtering
* **Triangular weighting:** Uses a symmetrical weight distribution that emphasizes central data points and reduces emphasis toward both ends
* **Constant-time implementation:** Two $O(1)$ SMA passes with circular buffers preserve exact triangular weights while keeping update cost constant per bar
* **Market application:** Particularly effective for identifying the underlying trend in noisy market conditions where standard moving averages generate too many false signals
* **Timeframe flexibility:** Works across multiple timeframes, with longer periods providing cleaner trend signals in higher timeframes
The core innovation of TRIMA is its unique triangular weighting scheme, which can be viewed either as a specialized weight distribution or as a twice-applied simple moving average with adjusted period. This creates more effective noise filtering without the excessive lag penalty typically associated with longer-period averages. The symmetrical nature of the weight distribution ensures zero phase distortion, preserving the timing of important market turning points.
## Common Settings and Parameters
| Parameter | Default | Function | When to Adjust |
|-----------|---------|----------|---------------|
| Length | 14 | Controls the lookback period | Increase for smoother signals in volatile markets, decrease for responsiveness |
| Source | close | Price data used for calculation | Consider using hlc3 for a more balanced price representation |
**Pro Tip:** For a good balance between smoothing and responsiveness, try using a TRIMA with period N instead of an SMA with period 2N - you'll get similar smoothing characteristics but with less lag.
## Calculation and Mathematical Foundation
**Simplified explanation:**
TRIMA calculates a weighted average of prices where the weights form a triangle shape. The middle prices get the most weight, and weights gradually decrease toward both the recent and older ends. This creates a smooth filter that effectively removes random price fluctuations while preserving the underlying trend.
**Technical formula:**
TRIMA = Σ(Price × Weight ) / Σ(Weight )
Where the triangular weights form a symmetric pattern:
- Weight = min(i, n-1-i) + 1
- Example for n=5: weights =
- Example for n=4: weights =
Alternatively, TRIMA can be calculated as:
TRIMA(source, p) = SMA(SMA(source, (p+1)/2), (p+1)/2)
> 🔍 **Technical Note:** The double application of SMA explains why TRIMA provides better smoothing than a single SMA or WMA. This approach effectively applies smoothing twice with optimal period adjustment, creating a -18dB/octave roll-off in the frequency domain compared to -6dB/octave for a simple moving average, and the current implementation achieves $O(1)$ complexity through circular buffers and NA-safe warmup compensation.
## Interpretation Details
TRIMA can be used in various trading strategies:
* **Trend identification:** The direction of TRIMA indicates the prevailing trend
* **Signal generation:** Crossovers between price and TRIMA generate trade signals with fewer false alarms than SMA
* **Support/resistance levels:** TRIMA can act as dynamic support during uptrends and resistance during downtrends
* **Trend strength assessment:** Distance between price and TRIMA can indicate trend strength
* **Multiple timeframe analysis:** Using TRIMAs with different periods can confirm trends across different timeframes
## Limitations and Considerations
* **Market conditions:** Like all moving averages, less effective in choppy, sideways markets
* **Lag factor:** More lag than WMA or EMA due to center-weighted emphasis
* **Limited adaptability:** Fixed weighting scheme cannot adapt to changing market volatility
* **Response time:** Takes longer to reflect sudden price changes than directionally-weighted averages
* **Complementary tools:** Best used with momentum oscillators or volume indicators for confirmation
## References
* Ehlers, John F. "Cycle Analytics for Traders." Wiley, 2013
* Kaufman, Perry J. "Trading Systems and Methods." Wiley, 2013
* Colby, Robert W. "The Encyclopedia of Technical Market Indicators." McGraw-Hill, 2002






















