指标
指标和策略
Forward P/E (MUST COMPLETE STEP 1 FOR INDICATOR TO WORK)Forward P/E Valuation Indicator (MUST COMPLETE STEP 1 FOR THE INDICATOR TO WORK)
1. Set up the indicator
Use the indicator on a 1-day chart. Its one- and three-year calculations assume daily bars.
First, add these TradingView indicators to your chart:
a. P/E forward
b. Price/earnings to growth ratio, usually shown as PEG ratio
c. Then add the custom Forward P/E Valuation indicator.
Open the "Forward P/E Valuation indicator" settings → Inputs and select:
P/E forward → Choose the P/E forward from the dropdown
Price/earnings to growth ratio → Choose the PEG ratio from the dropdown
After selecting the correct sources, click to add a checkmark to the following boxes:
a. P/E forward source linked correctly
b. PEG source linked correctly
Now, the "Forward P/E Valuation" indicator will work.
2. Recommended settings
The default settings are appropriate for most stocks:
Chart band lookback: 3 Years
Forward EPS trend threshold: 2%
Primary-driver lookback: 21 bars
Primary-driver threshold: 3%
Growth-supported premium threshold: 15%
Growth-supportive PEG: 1.5×
Use the three-year lookback for the main interpretation. Switch to one year only when you want to emphasize the stock’s recent valuation regime.
How to read the dashboard:
Read the first four rows first. They summarize the model’s conclusion.
Overall Valuation Status
This compares the current forward P/E with its selected historical range.
Rank
Status
0%–5% = Deep Discount
Above 5%–10% = Cheap
Above 10%–25% = Below Normal
Above 25%–Below 75% = Normal
75%–Below 90% = Above Normal
90%–Below 95% = Expensive
95%–100% = Extreme Expensive
A low percentile means the forward P/E is low relative to its own history. It does not automatically mean the stock is undervalued.
Valuation + Growth Signal
This combines valuation, growth, estimate direction, and PEG.
Signal
Meaning
Attractive Discount
Historically inexpensive with supportive growth or rising estimates
Potential Value
Cheap, but growth confirmation is limited
Value-Trap Risk
Cheap while growth or estimates are deteriorating
Growth-Supported Premium
Expensive, but strong growth may justify the premium
Multiple Risk
Expensive without enough growth support
High-Risk Premium
Expensive while estimates or growth are deteriorating
Improving Fundamentals
Normal valuation with rising estimates
Balanced
Normal valuation with stable estimates
The strongest favorable reading is Attractive Discount. The most concerning is High-Risk Premium.
Valuation + Estimate Direction
This gives a simpler valuation-versus-estimates interpretation.
Reading
Interpretation
Discount + Upgrades
Favorable valuation with improving estimates
Discount + Stable Estimates
Potential value, but no estimate catalyst
Discount + Cuts
Possible value trap
Normal + Upgrades
Improving fundamentals at a normal valuation
Premium + Upgrades
Expensive but supported by estimate improvement
Premium + Cuts
Highest-risk combination
Primary Driver
This explains what caused the recent movement over approximately 21 trading days.
Driver
Meaning
Earnings-Led Advance
Price rose mainly because forward EPS improved
Price + Estimate Expansion
Both estimates and the valuation multiple improved
Price-Led Multiple Expansion
Price rose without much earnings improvement
Estimate Upgrades / Price Lag
Estimates improved, but price has not responded
Price-Led Multiple Compression
Price fell more than estimates, making valuation cheaper
Estimate Cuts
Forward earnings expectations weakened
Price Up Despite Estimate Cuts
Price rose while estimates declined; caution
Stable / Consolidation
No major price, EPS, or P/E movement
The Context column shows the actual price, EPS, and P/E percentage changes used in the classification.
Supporting dashboard rows
TradingView Forward P/E
This is the directly linked TradingView forward-P/E value. It drives the historical ranks, medians, bands, and valuation status.
Implied Forward EPS
Calculated as:
Implied Forward EPS=Stock PriceForward P/E\text{Implied Forward EPS} = \frac{\text{Stock Price}}{\text{Forward P/E}}Implied Forward EPS=Forward P/EStock Price
Example:
210÷21=$10.00210\div21=\$10.00210÷21=$10.00
This is the earnings denominator implied by TradingView’s forward-P/E reading.
Current P/E Ratio
Calculated from:
Price÷Trailing-12-Month EPS\text{Price}\div\text{Trailing-12-Month EPS}Price÷Trailing-12-Month EPS
A forward P/E materially below the current P/E generally indicates expected earnings growth.
Forward EPS Growth Proxy
Compares implied forward EPS with the latest reported fiscal-year diluted EPS.
General interpretation:
Negative: expected earnings deterioration
0%–10%: limited growth
10%–15%: moderate growth
Above 15%: strong growth
This is a proxy, not a perfect analyst-consensus growth measure.
PEG Ratio
The PEG value comes from the linked TradingView PEG indicator.
Below 1.0×: low valuation relative to growth
1.0×–1.5×: generally growth supportive
1.5×–2.0×: moderate premium
Above 2.0×: valuation increasingly dependent on sustained growth
Do not use PEG alone. Cyclical or temporarily depressed earnings can distort it.
1Y / 3Y P/E Rank
Shows where the current forward P/E falls relative to its one- and three-year history.
Example:
12% / 38%
The stock is inexpensive compared with the past year, but closer to normal compared with the past three years.
1Y / 3Y Median P/E
Shows the stock’s typical forward P/E over each period.
If the current P/E is below both medians, the stock is trading below its recent historical norms.
Forward EPS Trend
Rising: latest detected revision above +2%
Stable: between −2% and +2%
Falling: below −2%
Rising estimates generally strengthen a favorable valuation signal. Falling estimates weaken it.
Estimate Freshness
Fresh: 0–100 days
Aging: 101–180 days
Stale: more than 180 days
This measures how long it has been since the model detected a meaningful change in implied forward EPS. It is not necessarily the exact analyst-revision date.
Model Confidence
High: 80%–100%
Medium: 60%–79%
Low: below 60%
Confidence reflects source links, historical coverage, available EPS data, freshness, and use of a daily chart.
Low confidence means insufficient data—not necessarily a negative stock outlook.
Two practical examples
Favorable setup
Overall Valuation: Cheap
Valuation + Growth: Attractive Discount
Valuation + Estimate Direction: Discount + Upgrades
Primary Driver: Earnings-Led Advance
Forward EPS Trend: Rising
Confidence: High
Interpretation: the stock is historically inexpensive, estimates are improving, and earnings rather than pure multiple expansion are supporting the move.
Warning setup
Overall Valuation: Expensive
Valuation + Growth: High-Risk Premium
Valuation + Estimate Direction: Premium + Cuts
Primary Driver: Price Up Despite Estimate Cuts
Forward EPS Trend: Falling
Confidence: High
Interpretation: the stock is historically expensive while earnings expectations are weakening. Price strength is being supported primarily by multiple expansion, which increases downside risk.
Best quick-reading rule
The most favorable combination is:
Discount + Upgrades + Attractive Discount + Earnings-Led Advance
The most concerning combination is:
Premium + Cuts + High-Risk Premium + Price Up Despite Estimate Cuts
Here is the code:
//@version=6
indicator("Forward P/E Linked Metrics ", shorttitle="Forward PE", overlay=false, max_bars_back=2000, precision=2)
// ============================================================================
// PURPOSE
// ============================================================================
// This version links only the TradingView plots that are available through
// input.source():
//
// Required linked sources:
// 1. TradingView "P/E forward"
// 2. TradingView "Price/earnings to growth ratio" / "PEG ratio"
//
// The regular current P/E is calculated internally:
// Current P/E = Current price / TTM EPS
//
// The model recovers the forward EPS denominator from the linked forward P/E:
// Implied forward EPS = Current price / Linked forward P/E
//
// If the linked P/E-forward plot is TradingView's live price-to-forward-EPS
// series, this inversion recovers the underlying forward EPS estimate while
// preserving an exact match with TradingView's displayed forward P/E.
//
// Use primarily on a 1D chart so 252 and 756 bars approximate 1 and 3 years.
//
// Added decision framework:
// 1. Overall Valuation Status
// 2. Valuation + Growth Signal
// 3. Valuation + Estimate Direction
// 4. Primary Driver
// ============================================================================
// 1. LINK TRADINGVIEW METRICS
// ============================================================================
grpLinks = "1. Link TradingView Metrics"
forwardPESource = input.source(
close,
"P/E forward",
tooltip="Select the plot from TradingView's built-in P/E forward indicator.",
group=grpLinks,
display=display.none)
pegRatioSource = input.source(
close,
"Price/earnings to growth ratio",
tooltip="Select the plot from TradingView's PEG ratio indicator.",
group=grpLinks,
display=display.none)
confirmForwardPELinked = input.bool(
false,
"P/E forward source linked correctly",
group=grpLinks,
display=display.none)
confirmPEGLinked = input.bool(
false,
"PEG source linked correctly",
group=grpLinks,
display=display.none)
// ============================================================================
// 2. MODEL SETTINGS
// ============================================================================
grpModel = "2. Model Settings"
minValidEPS = input.float(
0.01,
"Minimum valid implied forward EPS",
minval=0.0001,
step=0.01,
group=grpModel,
display=display.none)
maxValidEPS = input.float(
1000.0,
"Maximum valid implied forward EPS",
minval=1.0,
step=10.0,
group=grpModel,
display=display.none)
minValidPE = input.float(
0.1,
"Minimum valid P/E",
minval=0.0,
step=0.1,
group=grpModel,
display=display.none)
maxValidPE = input.float(
500.0,
"Maximum valid P/E",
minval=1.0,
step=5.0,
group=grpModel,
display=display.none)
maxValidPEG = input.float(
100.0,
"Maximum valid PEG",
minval=1.0,
step=1.0,
group=grpModel,
display=display.none)
chartLookback = input.string(
"3 Years",
"Chart band lookback",
options= ,
group=grpModel,
display=display.none)
trendThreshold = input.float(
2.0,
"Forward EPS revision trend threshold %",
minval=0.0,
step=0.25,
group=grpModel,
display=display.none)
revisionDetectionPct = input.float(
0.05,
"Minimum implied EPS change counted as a revision %",
minval=0.001,
step=0.01,
group=grpModel,
display=display.none)
freshDays = input.int(
100,
"Fresh estimate: maximum calendar days",
minval=1,
group=grpModel,
display=display.none)
staleDays = input.int(
180,
"Aging estimate: maximum calendar days",
minval=2,
group=grpModel,
display=display.none)
primaryDriverLookback = input.int(
21,
"Primary driver lookback bars",
minval=5,
maxval=252,
group=grpModel,
display=display.none)
primaryDriverThreshold = input.float(
3.0,
"Primary driver movement threshold %",
minval=0.5,
step=0.5,
group=grpModel,
display=display.none)
growthSupportThreshold = input.float(
15.0,
"Growth-supported premium threshold %",
minval=0.0,
step=1.0,
group=grpModel,
display=display.none)
attractivePEGThreshold = input.float(
1.5,
"PEG threshold considered growth supportive",
minval=0.1,
step=0.1,
group=grpModel,
display=display.none)
// ============================================================================
// 3. VISUALS & DASHBOARD
// ============================================================================
grpVisual = "3. Visuals & Dashboard"
showMedianLine = input.bool(
true,
"Show historical median",
group=grpVisual,
display=display.none)
showPercentileBands = input.bool(
true,
"Show percentile bands",
group=grpVisual,
display=display.none)
showNormalZoneFill = input.bool(
true,
"Fill normal valuation zone",
group=grpVisual,
display=display.none)
showExtremeBackground = input.bool(
false,
"Highlight 5th / 95th percentile extremes",
group=grpVisual,
display=display.none)
showDashboard = input.bool(
true,
"Show dashboard",
group=grpVisual,
display=display.none)
dashboardPosition = input.string(
"Top Right",
"Dashboard position",
options= ,
group=grpVisual,
display=display.none)
// ============================================================================
// CONSTANTS
// ============================================================================
bars1Y = 252
bars3Y = 756
dayMs = 86400000.0
selectedLength = chartLookback == "1 Year" ? bars1Y : bars3Y
// ============================================================================
// COLOR PALETTE — LIGHT CHART / DARK DASHBOARD
// ============================================================================
clrSlate0 = color.rgb(45, 52, 64)
clrSlate1 = color.rgb(55, 62, 74)
clrSlate2 = color.rgb(69, 76, 88)
clrText = color.rgb(248, 249, 251)
clrMuted = color.rgb(205, 211, 220)
clrDarkText = color.rgb(42, 49, 60)
clrGreenText = color.rgb(18, 145, 88)
clrRedText = color.rgb(211, 52, 69)
clrAmberText = color.rgb(181, 112, 8)
clrTeal = color.rgb(35, 190, 208)
clrAqua = color.rgb(70, 198, 235)
clrBlue = color.rgb(72, 116, 235)
clrGreen = color.rgb(40, 178, 109)
clrAmber = color.rgb(245, 179, 48)
clrOrange = color.rgb(245, 153, 36)
clrRed = color.rgb(235, 74, 91)
clrGrayLine = color.rgb(116, 125, 140)
clrLightCyan = color.rgb(126, 216, 233)
clrLightBlue = color.rgb(202, 232, 242)
clrLightGray = color.rgb(205, 209, 215)
clrLightMint = color.rgb(214, 241, 226)
clrLightAmber = color.rgb(250, 232, 192)
clrLightRed = color.rgb(249, 220, 225)
// ============================================================================
// HELPERS
// ============================================================================
f_valid_eps(_value) =>
not na(_value) and _value >= minValidEPS and _value <= maxValidEPS ? _value : na
f_valid_pe(_value) =>
not na(_value) and _value >= minValidPE and _value <= maxValidPE ? _value : na
f_valid_peg(_value) =>
not na(_value) and _value > 0.0 and _value <= maxValidPEG ? _value : na
f_x(_value) =>
na(_value) ? "n/a" : str.tostring(_value, "#.##") + "x"
f_pct(_value) =>
na(_value) ? "n/a" : str.tostring(_value, "#.##") + "%"
f_eps(_value) =>
na(_value) ? "n/a" : str.tostring(_value, "#.##")
f_rank_text(_value) =>
na(_value) ? "n/a" : str.tostring(_value, "#") + "%"
f_position(_selection) =>
_selection == "Top Left" ? position.top_left :
_selection == "Bottom Right" ? position.bottom_right :
_selection == "Bottom Left" ? position.bottom_left :
position.top_right
f_rank_color(_rank, _ready) =>
color _result = clrGrayLine
if _ready and not na(_rank)
if _rank >= 95
_result := clrRed
else if _rank >= 90
_result := clrOrange
else if _rank >= 75
_result := clrAmber
else if _rank <= 5
_result := clrBlue
else if _rank <= 10
_result := clrAqua
else if _rank <= 25
_result := clrTeal
else
_result := clrGrayLine
_result
f_rank_fill_color(_rank, _ready) =>
color _result = clrLightGray
if _ready and not na(_rank)
if _rank >= 95
_result := clrLightRed
else if _rank >= 75
_result := clrLightAmber
else if _rank <= 25
_result := clrLightCyan
else
_result := clrLightGray
_result
// ============================================================================
// LINKED METRICS
// ============================================================================
linkedForwardPE = confirmForwardPELinked ? f_valid_pe(forwardPESource) : na
linkedPEG = confirmPEGLinked ? f_valid_peg(pegRatioSource) : na
// Regular trailing P/E calculated internally using TradingView's documented
// price-to-TTM-EPS method.
epsTTMRaw = request.financial(
syminfo.tickerid,
"EARNINGS_PER_SHARE",
"TTM",
gaps=barmerge.gaps_off,
ignore_invalid_symbol=true,
currency=syminfo.currency)
epsTTM = f_valid_eps(epsTTMRaw)
currentPERatio = f_valid_pe(
not na(epsTTM) and epsTTM > 0.0 ? close / epsTTM : na)
// Invert TradingView's linked forward P/E to recover its implied forward EPS.
impliedForwardEPS = f_valid_eps(
not na(linkedForwardPE) and linkedForwardPE > 0.0 ? close / linkedForwardPE : na)
// Latest annual diluted EPS is used only as a baseline for a growth proxy.
priorFYDilutedEPSRaw = request.financial(
syminfo.tickerid,
"EARNINGS_PER_SHARE_DILUTED",
"FY",
gaps=barmerge.gaps_off,
ignore_invalid_symbol=true,
currency=syminfo.currency)
priorFYDilutedEPS = f_valid_eps(priorFYDilutedEPSRaw)
forwardEPSGrowthProxy =
not na(impliedForwardEPS) and not na(priorFYDilutedEPS) and priorFYDilutedEPS > 0.0 ?
((impliedForwardEPS / priorFYDilutedEPS) - 1.0) * 100.0 :
na
// The PEG identity is PEG = P/E ÷ growth rate. When both linked metrics are
// available, this recovers the growth rate implicit in TradingView's PEG.
pegImpliedGrowthPct =
not na(currentPERatio) and not na(linkedPEG) and linkedPEG > 0.0 ?
currentPERatio / linkedPEG :
na
// ============================================================================
// IMPLIED FORWARD EPS TREND AND FRESHNESS
// ============================================================================
impliedEPSChangePct =
not na(impliedForwardEPS) and
not na(impliedForwardEPS ) and
impliedForwardEPS != 0.0 ?
((impliedForwardEPS / impliedForwardEPS ) - 1.0) * 100.0 :
na
impliedEPSChanged =
not na(impliedEPSChangePct) and
math.abs(impliedEPSChangePct) >= revisionDetectionPct
var float latestPublishedEstimate = na
var float priorPublishedEstimate = na
var int lastEstimateUpdateTime = na
if impliedEPSChanged
priorPublishedEstimate := latestPublishedEstimate
latestPublishedEstimate := impliedForwardEPS
lastEstimateUpdateTime := time
// Seed the latest available estimate without falsely labeling it a revision.
if na(latestPublishedEstimate) and not na(impliedForwardEPS)
latestPublishedEstimate := impliedForwardEPS
estimateRevisionPct =
not na(latestPublishedEstimate) and
not na(priorPublishedEstimate) and
priorPublishedEstimate != 0.0 ?
((latestPublishedEstimate / priorPublishedEstimate) - 1.0) * 100.0 :
na
string estimateTrendText = "No prior revision"
color estimateTrendColor = clrMuted
if not na(estimateRevisionPct)
if estimateRevisionPct > trendThreshold
estimateTrendText := "Rising"
estimateTrendColor := clrGreen
else if estimateRevisionPct < -trendThreshold
estimateTrendText := "Falling"
estimateTrendColor := clrRed
else
estimateTrendText := "Stable"
estimateTrendColor := clrAmber
estimateAgeDays =
not na(lastEstimateUpdateTime) ?
(time - lastEstimateUpdateTime) / dayMs :
na
string freshnessText = "No revision date"
color freshnessColor = clrMuted
if not na(estimateAgeDays)
if estimateAgeDays <= freshDays
freshnessText := "Fresh"
freshnessColor := clrGreen
else if estimateAgeDays <= staleDays
freshnessText := "Aging"
freshnessColor := clrAmber
else
freshnessText := "Stale"
freshnessColor := clrRed
// ============================================================================
// HISTORICAL RANKS AND MEDIANS — 1Y / 3Y ONLY
// ============================================================================
var int validHistoryBars = 0
validHistoryBars := not na(linkedForwardPE) ? nz(validHistoryBars ) + 1 : 0
has1Y = validHistoryBars >= bars1Y
has3Y = validHistoryBars >= bars3Y
hasSelectedHistory = validHistoryBars >= selectedLength
rank1YRaw = ta.percentrank(linkedForwardPE, bars1Y)
rank3YRaw = ta.percentrank(linkedForwardPE, bars3Y)
median1YRaw = ta.percentile_linear_interpolation(linkedForwardPE, bars1Y, 50)
median3YRaw = ta.percentile_linear_interpolation(linkedForwardPE, bars3Y, 50)
rank1Y = has1Y ? rank1YRaw : na
rank3Y = has3Y ? rank3YRaw : na
median1Y = has1Y ? median1YRaw : na
median3Y = has3Y ? median3YRaw : na
selectedRankRaw = ta.percentrank(linkedForwardPE, selectedLength)
selectedP95Raw = ta.percentile_linear_interpolation(linkedForwardPE, selectedLength, 95)
selectedP90Raw = ta.percentile_linear_interpolation(linkedForwardPE, selectedLength, 90)
selectedP50Raw = ta.percentile_linear_interpolation(linkedForwardPE, selectedLength, 50)
selectedP10Raw = ta.percentile_linear_interpolation(linkedForwardPE, selectedLength, 10)
selectedP05Raw = ta.percentile_linear_interpolation(linkedForwardPE, selectedLength, 5)
selectedRank = hasSelectedHistory ? selectedRankRaw : na
selectedP95 = hasSelectedHistory ? selectedP95Raw : na
selectedP90 = hasSelectedHistory ? selectedP90Raw : na
selectedP50 = hasSelectedHistory ? selectedP50Raw : na
selectedP10 = hasSelectedHistory ? selectedP10Raw : na
selectedP05 = hasSelectedHistory ? selectedP05Raw : na
// ============================================================================
// DECISION FRAMEWORK
// ============================================================================
// Overall valuation status is based on the selected 1Y or 3Y percentile rank.
string overallValuationText = "Insufficient history"
color overallValuationColor = clrGrayLine
color overallValuationBg = clrLightGray
if not na(linkedForwardPE) and hasSelectedHistory and not na(selectedRank)
if selectedRank >= 95
overallValuationText := "Extreme Expensive"
overallValuationColor := clrRed
overallValuationBg := clrLightRed
else if selectedRank >= 90
overallValuationText := "Expensive"
overallValuationColor := clrOrange
overallValuationBg := clrLightAmber
else if selectedRank >= 75
overallValuationText := "Above Normal"
overallValuationColor := clrAmber
overallValuationBg := clrLightAmber
else if selectedRank <= 5
overallValuationText := "Deep Discount"
overallValuationColor := clrBlue
overallValuationBg := clrLightCyan
else if selectedRank <= 10
overallValuationText := "Cheap"
overallValuationColor := clrAqua
overallValuationBg := clrLightCyan
else if selectedRank <= 25
overallValuationText := "Below Normal"
overallValuationColor := clrTeal
overallValuationBg := clrLightCyan
else
overallValuationText := "Normal"
overallValuationColor := clrGrayLine
overallValuationBg := clrLightGray
cheapValuation = hasSelectedHistory and not na(selectedRank) and selectedRank <= 25
premiumValuation = hasSelectedHistory and not na(selectedRank) and selectedRank >= 75
veryExpensiveValuation = hasSelectedHistory and not na(selectedRank) and selectedRank >= 90
growthPositive =
(not na(forwardEPSGrowthProxy) and forwardEPSGrowthProxy >= 10.0) or
estimateTrendText == "Rising"
growthStrong =
(not na(forwardEPSGrowthProxy) and forwardEPSGrowthProxy >= growthSupportThreshold) or
(not na(linkedPEG) and linkedPEG <= attractivePEGThreshold)
growthWeak =
(not na(forwardEPSGrowthProxy) and forwardEPSGrowthProxy <= 0.0) or
estimateTrendText == "Falling"
// Combines valuation, expected growth, estimate direction, and linked PEG.
string valuationGrowthText = "Awaiting data"
color valuationGrowthColor = clrGrayLine
color valuationGrowthBg = clrLightGray
if hasSelectedHistory and not na(selectedRank)
if cheapValuation
if growthWeak
valuationGrowthText := "Value-Trap Risk"
valuationGrowthColor := clrRed
valuationGrowthBg := clrLightRed
else if growthPositive or growthStrong
valuationGrowthText := "Attractive Discount"
valuationGrowthColor := clrGreen
valuationGrowthBg := clrLightMint
else
valuationGrowthText := "Potential Value"
valuationGrowthColor := clrTeal
valuationGrowthBg := clrLightCyan
else if premiumValuation
if growthWeak
valuationGrowthText := "High-Risk Premium"
valuationGrowthColor := clrRed
valuationGrowthBg := clrLightRed
else if growthStrong
valuationGrowthText := "Growth-Supported Premium"
valuationGrowthColor := clrAmber
valuationGrowthBg := clrLightAmber
else
valuationGrowthText := "Multiple Risk"
valuationGrowthColor := clrOrange
valuationGrowthBg := clrLightAmber
else
if estimateTrendText == "Rising"
valuationGrowthText := "Improving Fundamentals"
valuationGrowthColor := clrGreen
valuationGrowthBg := clrLightMint
else if estimateTrendText == "Falling"
valuationGrowthText := "Estimate Deterioration"
valuationGrowthColor := clrRed
valuationGrowthBg := clrLightRed
else
valuationGrowthText := "Balanced"
valuationGrowthColor := clrGrayLine
valuationGrowthBg := clrLightGray
// A direct matrix combining the valuation regime with estimate direction.
string valuationEstimateText = "Awaiting data"
color valuationEstimateColor = clrGrayLine
color valuationEstimateBg = clrLightGray
if hasSelectedHistory and not na(selectedRank)
string valuationBucket = cheapValuation ? "Discount" : premiumValuation ? "Premium" : "Normal"
string directionBucket = estimateTrendText == "Rising" ? "Upgrades" : estimateTrendText == "Falling" ? "Cuts" : "Stable Estimates"
valuationEstimateText := valuationBucket + " + " + directionBucket
if cheapValuation and estimateTrendText == "Rising"
valuationEstimateColor := clrGreen
valuationEstimateBg := clrLightMint
else if cheapValuation and estimateTrendText == "Falling"
valuationEstimateColor := clrRed
valuationEstimateBg := clrLightRed
else if premiumValuation and estimateTrendText == "Falling"
valuationEstimateColor := clrRed
valuationEstimateBg := clrLightRed
else if premiumValuation and estimateTrendText == "Rising"
valuationEstimateColor := clrAmber
valuationEstimateBg := clrLightAmber
else if estimateTrendText == "Rising"
valuationEstimateColor := clrGreen
valuationEstimateBg := clrLightMint
else if estimateTrendText == "Falling"
valuationEstimateColor := clrRed
valuationEstimateBg := clrLightRed
else
valuationEstimateColor := clrGrayLine
valuationEstimateBg := clrLightGray
// Primary driver compares price, implied forward EPS, and forward P/E changes.
priceChangePct =
not na(close ) and close != 0.0 ?
((close / close ) - 1.0) * 100.0 :
na
forwardEPSChangePct =
not na(impliedForwardEPS) and
not na(impliedForwardEPS ) and
impliedForwardEPS != 0.0 ?
((impliedForwardEPS / impliedForwardEPS ) - 1.0) * 100.0 :
na
forwardPEChangePct =
not na(linkedForwardPE) and
not na(linkedForwardPE ) and
linkedForwardPE != 0.0 ?
((linkedForwardPE / linkedForwardPE ) - 1.0) * 100.0 :
na
string primaryDriverText = "Insufficient data"
color primaryDriverColor = clrGrayLine
color primaryDriverBg = clrLightGray
if not na(priceChangePct) and not na(forwardEPSChangePct) and not na(forwardPEChangePct)
bool priceUp = priceChangePct > primaryDriverThreshold
bool priceDown = priceChangePct < -primaryDriverThreshold
bool epsUp = forwardEPSChangePct > primaryDriverThreshold
bool epsDown = forwardEPSChangePct < -primaryDriverThreshold
bool peUp = forwardPEChangePct > primaryDriverThreshold
bool peDown = forwardPEChangePct < -primaryDriverThreshold
if priceUp and epsUp
primaryDriverText := peUp ? "Price + Estimate Expansion" : "Earnings-Led Advance"
primaryDriverColor := clrGreen
primaryDriverBg := clrLightMint
else if priceDown and epsDown
primaryDriverText := peDown ? "Price + Estimate Deterioration" : "Estimate Cuts Dominate"
primaryDriverColor := clrRed
primaryDriverBg := clrLightRed
else if priceUp and epsDown
primaryDriverText := "Price Up Despite Estimate Cuts"
primaryDriverColor := clrOrange
primaryDriverBg := clrLightAmber
else if priceDown and epsUp
primaryDriverText := "Estimate Upgrades / Price Lag"
primaryDriverColor := clrTeal
primaryDriverBg := clrLightCyan
else if peUp and priceUp
primaryDriverText := "Price-Led Multiple Expansion"
primaryDriverColor := clrAmber
primaryDriverBg := clrLightAmber
else if peDown and priceDown
primaryDriverText := "Price-Led Multiple Compression"
primaryDriverColor := clrTeal
primaryDriverBg := clrLightCyan
else if epsUp
primaryDriverText := "Estimate Upgrades"
primaryDriverColor := clrGreen
primaryDriverBg := clrLightMint
else if epsDown
primaryDriverText := "Estimate Cuts"
primaryDriverColor := clrRed
primaryDriverBg := clrLightRed
else if peUp
primaryDriverText := "Multiple Expansion"
primaryDriverColor := clrAmber
primaryDriverBg := clrLightAmber
else if peDown
primaryDriverText := "Multiple Compression"
primaryDriverColor := clrTeal
primaryDriverBg := clrLightCyan
else
primaryDriverText := "Stable / Consolidation"
primaryDriverColor := clrGrayLine
primaryDriverBg := clrLightGray
// ============================================================================
// MODEL CONFIDENCE
// ============================================================================
chartIsDaily = timeframe.isdaily and timeframe.multiplier == 1
int confidenceScore = 0
confidenceScore += not na(linkedForwardPE) ? 40 : 0
confidenceScore += has3Y ? 25 : has1Y ? 15 : 0
confidenceScore += not na(impliedForwardEPS) ? 10 : 0
// Internally calculated trailing P/E contributes to confidence when available.
confidenceScore += not na(currentPERatio) ? 5 : 0
confidenceScore += not na(linkedPEG) ? 5 : 0
confidenceScore +=
not na(estimateAgeDays) ?
estimateAgeDays <= freshDays ? 10 :
estimateAgeDays <= staleDays ? 5 : 1 :
0
confidenceScore += chartIsDaily ? 5 : 0
confidenceScore := int(math.max(0, math.min(100, confidenceScore)))
string confidenceLevel =
confidenceScore >= 80 ? "High" :
confidenceScore >= 60 ? "Medium" :
"Low"
color confidenceColor =
confidenceScore >= 80 ? clrGreen :
confidenceScore >= 60 ? clrAmber :
clrRed
historyCoverageText =
has3Y ? "Full 3Y" :
has1Y ? "1Y available" :
"Limited"
sourceStatusText =
confirmForwardPELinked and confirmPEGLinked ? "2/2 linked" :
confirmForwardPELinked ? "1/2 linked" :
"Set P/E forward source"
// ============================================================================
// DISPLAY TEXT
// ============================================================================
rankText = f_rank_text(rank1Y) + " / " + f_rank_text(rank3Y)
medianText = f_x(median1Y) + " / " + f_x(median3Y)
estimateTrendContext =
na(estimateRevisionPct) ?
"Awaiting second revision" :
"Last revision: " + f_pct(estimateRevisionPct)
freshnessContext =
na(estimateAgeDays) ?
"No implied EPS revision observed" :
str.tostring(estimateAgeDays, "#") + " calendar days"
confidenceContext =
historyCoverageText + " / " + (chartIsDaily ? "1D chart" : "Use 1D chart")
overallValuationContext =
na(selectedRank) ?
"Selected rank unavailable" :
chartLookback + " rank: " + f_rank_text(selectedRank)
valuationGrowthContext =
"Growth: " + f_pct(forwardEPSGrowthProxy) + " / PEG: " + f_x(linkedPEG)
valuationEstimateContext =
overallValuationText + " / EPS trend: " + estimateTrendText
primaryDriverContext =
"Price " + f_pct(priceChangePct) + " / EPS " + f_pct(forwardEPSChangePct) + " / P/E " + f_pct(forwardPEChangePct)
// ============================================================================
// PLOTS
// ============================================================================
lineColor = f_rank_color(selectedRank, hasSelectedHistory)
plot(
linkedForwardPE,
title="Linked TradingView Forward P/E",
color=lineColor,
linewidth=3,
display=display.pane)
medianPlot = plot(
showMedianLine ? selectedP50 : na,
title="Selected Historical Median",
color=color.new(clrGrayLine, 5),
linewidth=2,
display=display.pane)
upperPlot = plot(
showPercentileBands ? selectedP90 : na,
title="Selected 90th Percentile",
color=color.new(clrOrange, 20),
linewidth=1,
display=display.pane)
lowerPlot = plot(
showPercentileBands ? selectedP10 : na,
title="Selected 10th Percentile",
color=color.new(clrAqua, 20),
linewidth=1,
display=display.pane)
plot(
showPercentileBands ? selectedP95 : na,
title="Selected 95th Percentile",
color=color.new(clrRed, 10),
linewidth=1,
display=display.pane)
plot(
showPercentileBands ? selectedP05 : na,
title="Selected 5th Percentile",
color=color.new(clrBlue, 10),
linewidth=1,
display=display.pane)
fill(
upperPlot,
lowerPlot,
color=showPercentileBands and showNormalZoneFill ? color.new(clrAqua, 91) : na,
title="Historical Normal Zone")
isExtremeExpensive = hasSelectedHistory and selectedRank >= 95
isDeepDiscount = hasSelectedHistory and selectedRank <= 5
bgcolor(
showExtremeBackground and isExtremeExpensive ? color.new(clrRed, 90) :
showExtremeBackground and isDeepDiscount ? color.new(clrBlue, 90) :
na)
// ============================================================================
// DASHBOARD
// ============================================================================
var table dash = table.new(
f_position(dashboardPosition),
3,
15,
border_width=1,
border_color=color.new(clrMuted, 75))
if showDashboard and barstate.islast
color bgHeader = clrSlate0
color bgDark = clrSlate1
color bgMed = clrSlate2
color peBg = f_rank_fill_color(selectedRank, hasSelectedHistory)
color epsBg = clrLightGray
color currentPEBg = clrLightBlue
color growthBg = not na(forwardEPSGrowthProxy) and forwardEPSGrowthProxy >= 0 ? clrLightMint : clrLightRed
color pegBg = clrLightBlue
color rankBg = f_rank_fill_color(selectedRank, hasSelectedHistory)
color medianBg = clrLightGray
color trendBg = estimateTrendText == "Rising" ? clrLightMint : estimateTrendText == "Falling" ? clrLightRed : clrLightAmber
color freshBg = freshnessText == "Fresh" ? clrLightMint : freshnessText == "Aging" ? clrLightAmber : freshnessText == "Stale" ? clrLightRed : clrLightGray
color confBg = confidenceScore >= 80 ? clrLightMint : confidenceScore >= 60 ? clrLightAmber : clrLightRed
table.cell(dash, 0, 0, "Metric", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgHeader)
table.cell(dash, 1, 0, "Current", text_color=clrText, text_size=size.small, text_halign=text.align_center, bgcolor=bgHeader)
table.cell(dash, 2, 0, "Context", text_color=clrText, text_size=size.small, text_halign=text.align_right, bgcolor=bgHeader)
table.cell(dash, 0, 1, "Overall Valuation Status", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgDark)
table.cell(dash, 1, 1, overallValuationText, text_color=overallValuationColor, text_size=size.normal, text_halign=text.align_center, bgcolor=overallValuationBg)
table.cell(dash, 2, 1, overallValuationContext, text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgDark)
table.cell(dash, 0, 2, "Valuation + Growth Signal", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgMed)
table.cell(dash, 1, 2, valuationGrowthText, text_color=valuationGrowthColor, text_size=size.normal, text_halign=text.align_center, bgcolor=valuationGrowthBg)
table.cell(dash, 2, 2, valuationGrowthContext, text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgMed)
table.cell(dash, 0, 3, "Valuation + Estimate Direction", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgDark)
table.cell(dash, 1, 3, valuationEstimateText, text_color=valuationEstimateColor, text_size=size.normal, text_halign=text.align_center, bgcolor=valuationEstimateBg)
table.cell(dash, 2, 3, valuationEstimateContext, text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgDark)
table.cell(dash, 0, 4, "Primary Driver", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgMed)
table.cell(dash, 1, 4, primaryDriverText, text_color=primaryDriverColor, text_size=size.small, text_halign=text.align_center, bgcolor=primaryDriverBg)
table.cell(dash, 2, 4, primaryDriverContext, text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgMed)
table.cell(dash, 0, 5, "TradingView Forward P/E", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgDark)
table.cell(dash, 1, 5, f_x(linkedForwardPE), text_color=clrDarkText, text_size=size.normal, text_halign=text.align_center, bgcolor=peBg)
table.cell(dash, 2, 5, "Direct linked P/E forward plot", text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgDark)
table.cell(dash, 0, 6, "Implied Forward EPS", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgMed)
table.cell(dash, 1, 6, f_eps(impliedForwardEPS), text_color=clrDarkText, text_size=size.normal, text_halign=text.align_center, bgcolor=epsBg)
table.cell(dash, 2, 6, "Price ÷ linked forward P/E", text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgMed)
table.cell(dash, 0, 7, "Current P/E Ratio", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgDark)
table.cell(dash, 1, 7, f_x(currentPERatio), text_color=clrDarkText, text_size=size.normal, text_halign=text.align_center, bgcolor=currentPEBg)
table.cell(dash, 2, 7, "Price ÷ trailing 12M EPS", text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgDark)
table.cell(dash, 0, 8, "Forward EPS Growth Proxy", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgMed)
table.cell(dash, 1, 8, f_pct(forwardEPSGrowthProxy), text_color=not na(forwardEPSGrowthProxy) and forwardEPSGrowthProxy >= 0 ? clrGreenText : clrRedText, text_size=size.normal, text_halign=text.align_center, bgcolor=growthBg)
table.cell(dash, 2, 8, "Implied forward EPS vs prior FY", text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgMed)
table.cell(dash, 0, 9, "PEG Ratio", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgDark)
table.cell(dash, 1, 9, f_x(linkedPEG), text_color=clrDarkText, text_size=size.normal, text_halign=text.align_center, bgcolor=pegBg)
table.cell(dash, 2, 9, na(pegImpliedGrowthPct) ? "Direct linked PEG plot" : "TTM P/E ÷ PEG = " + f_pct(pegImpliedGrowthPct), text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgDark)
table.cell(dash, 0, 10, "1Y / 3Y P/E Rank", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgMed)
table.cell(dash, 1, 10, rankText, text_color=clrDarkText, text_size=size.small, text_halign=text.align_center, bgcolor=rankBg)
table.cell(dash, 2, 10, "Lower percentile = cheaper", text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgMed)
table.cell(dash, 0, 11, "1Y / 3Y Median P/E", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgDark)
table.cell(dash, 1, 11, medianText, text_color=clrDarkText, text_size=size.small, text_halign=text.align_center, bgcolor=medianBg)
table.cell(dash, 2, 11, "Linked forward P/E history", text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgDark)
table.cell(dash, 0, 12, "Forward EPS Trend", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgMed)
table.cell(dash, 1, 12, estimateTrendText, text_color=estimateTrendText == "Rising" ? clrGreenText : estimateTrendText == "Falling" ? clrRedText : clrAmberText, text_size=size.normal, text_halign=text.align_center, bgcolor=trendBg)
table.cell(dash, 2, 12, estimateTrendContext, text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgMed)
table.cell(dash, 0, 13, "Estimate Freshness", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgDark)
table.cell(dash, 1, 13, freshnessText, text_color=freshnessText == "Fresh" ? clrGreenText : freshnessText == "Aging" ? clrAmberText : freshnessText == "Stale" ? clrRedText : clrDarkText, text_size=size.normal, text_halign=text.align_center, bgcolor=freshBg)
table.cell(dash, 2, 13, freshnessContext, text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgDark)
table.cell(dash, 0, 14, "Model Confidence", text_color=clrText, text_size=size.small, text_halign=text.align_left, bgcolor=bgMed)
table.cell(dash, 1, 14, confidenceLevel + " (" + str.tostring(confidenceScore) + "%)", text_color=confidenceScore >= 80 ? clrGreenText : confidenceScore >= 60 ? clrAmberText : clrRedText, text_size=size.normal, text_halign=text.align_center, bgcolor=confBg)
table.cell(dash, 2, 14, sourceStatusText + " / " + confidenceContext, text_color=clrMuted, text_size=size.small, text_halign=text.align_right, bgcolor=bgMed)
if not showDashboard and barstate.islast
table.clear(dash, 0, 0, 2, 14)
// ============================================================================
// ALERTS
// ============================================================================
crossedAbove90 = ta.crossover(selectedRank, 90)
crossedBelow10 = ta.crossunder(selectedRank, 10)
enteredExpensive = hasSelectedHistory and crossedAbove90
enteredCheap = hasSelectedHistory and crossedBelow10
newEstimateIncrease = impliedEPSChanged and not na(estimateRevisionPct) and estimateRevisionPct > trendThreshold
newEstimateDecrease = impliedEPSChanged and not na(estimateRevisionPct) and estimateRevisionPct < -trendThreshold
newStaleEstimate =
not na(estimateAgeDays) and
not na(estimateAgeDays ) and
estimateAgeDays > staleDays and
estimateAgeDays <= staleDays
newAttractiveDiscount =
valuationGrowthText == "Attractive Discount" and
valuationGrowthText != "Attractive Discount"
newValueTrapRisk =
valuationGrowthText == "Value-Trap Risk" and
valuationGrowthText != "Value-Trap Risk"
newHighRiskPremium =
valuationGrowthText == "High-Risk Premium" and
valuationGrowthText != "High-Risk Premium"
alertcondition(
enteredExpensive,
title="Forward P/E Entered Expensive Zone",
message="Linked TradingView forward P/E entered the selected lookback's 90th-percentile expensive zone.")
alertcondition(
enteredCheap,
title="Forward P/E Entered Cheap Zone",
message="Linked TradingView forward P/E entered the selected lookback's 10th-percentile cheap zone.")
alertcondition(
newEstimateIncrease,
title="Implied Forward EPS Increased",
message="The forward EPS implied by TradingView's linked forward P/E increased by more than the configured trend threshold.")
alertcondition(
newEstimateDecrease,
title="Implied Forward EPS Decreased",
message="The forward EPS implied by TradingView's linked forward P/E decreased by more than the configured trend threshold.")
alertcondition(
newStaleEstimate,
title="Implied Forward EPS Became Stale",
message="The implied forward EPS has not changed within the configured stale-data threshold.")
alertcondition(
newAttractiveDiscount,
title="Attractive Discount Signal",
message="Forward P/E is historically discounted while growth and estimate direction remain supportive.")
alertcondition(
newValueTrapRisk,
title="Value-Trap Risk Signal",
message="Forward P/E is historically discounted, but growth or forward EPS estimates are deteriorating.")
alertcondition(
newHighRiskPremium,
title="High-Risk Premium Signal",
message="Forward P/E is historically elevated while growth or forward EPS estimates are deteriorating.")
指标
RTI Trend State + MacroCoverRTI Trend State + MacroCover
A trend-state oscillator built on the Relative Trend Index (RTI) — a stochastic-position measure of where price sits inside its recent high/low range, then EMA-smoothed:
raw = 100 * (close - lowest(low, n)) / (highest(high, n) - lowest(low, n))
RTI = EMA(raw, smooth) -> a 0-100 line
How the state works
The 0-100 RTI is converted into a persistent LONG / FLAT / SHORT state through a hysteresis band , so it does not flip on noise around the mid-line:
RTI above the upper band -> LONG
RTI below the lower band -> SHORT
in between -> holds the last state
The gap between the two bands is the hysteresis — widen it for fewer, steadier flips; narrow it for a more reactive read.
MacroCover (optional long bias)
When the state would be SHORT but price trades above a slow EMA (default 200), the short is covered to FLAT — i.e. it won't fight the higher-timeframe uptrend. Turn MacroCover off for a symmetric long/short reading.
On the chart
The RTI line (0-100) colored by state: green long, red short, gray flat.
Dashed upper/lower bands and a dotted mid-line.
State background tint and flip markers where the state changes.
A compact table with the current RTI value, state and macro side.
The RTI value plus state_-1_0_1 and ema_macro are available in the Data Window for tooltips and cross-checks.
Inputs
RTI engine — Lookback n (30), EMA smoothing (3), upper/lower bands (55 / 45).
MacroCover — on/off and macro EMA length (200).
Timeframe — use the chart timeframe, or lock the calculation to a fixed resolution.
Visual — toggle the state background, flip markers and table.
Notes
Works on any symbol and any timeframe.
Non-repainting : values are computed on confirmed bars, and the optional higher-timeframe request uses lookahead_off.
This is a discretionary / confluence tool, not financial advice or a complete trading system.
指标
Buy/Sell Signals [WynTrader]Buy/Sell Signals
Hello dear Friend
Here is my Buy/Sell Signals indicator that may help you easily run a Buy/Sell backtest Strategy, seeing, at a glance, performance results.
█ OVERVIEW
This indicator identifies trend changes and generates Buy/Sell signals as accurately as possible. Its strength lies in the results Table, which lets you evaluate signal performance directly on the chart — compared to a simple Buy & Hold strategy — without running a full backtest.
█ CONCEPTS
This Buy/Sell Signals , compared to other tools that detect trend shifts, is simple, easy to use, and demonstrates its efficiency on its own, at a glance.
The Table results allow you to quickly evaluate signal performance, both on their own and compared to a Buy & Hold strategy. The Table calculations are fully s ynchronized with the visible chart (WYSIWYG – What You See Is What You Get). You can also scroll the chart across different date ranges to see how a stock or product performs under various market conditions.
You can adjust the variables to suit your goals. The design is simple, with clear parameters and instant readability of Buy/Sell Signals on the chart and in the Table results, without complex interpretation needed.
A Table shows the effectiveness of the signals on the current visible chart, providing immediate, realistic feedback performance. The Buy & Hold strategy results are also included for comparison with the Buy/Sell swing strategy. The Buy & Hold results start from the first Buy signal to ensure a fair comparison. Changing the parameters instantly updates the Table, giving a quick, immediate performance check.
█ FILTERS (Buy/Sell parameters)
This indicator generates Buy/Sell signals using optional and adjustable filters:
- Bollinger Bands Lookback Trend Filter
- High-Low vs Candle Range Threshold %
- Distance from Fast and Slow MAs Threshold %
Results are displayed in a Table on the chart, based on the currently visible start and end dates.
█ TABLE RESULTS (Buy/Sell signals performance)
The Results Calculation presented in the Table is based on the Current Chart Visible Range . The Table shows the:
- Calculation Results of the Buy and Sell Signals activated on the chart
- Number of Trades (Signals)
- Winning Points
- Win Rate %
The Buy & Hold calculation starts at the first Buy encountered.
█ CAUTION
The Graal Indicator, even with AI, doesn't exist yet — maybe one day, but not now — depending on the chart product, volatility, probabilities, and unpredictable market behaviour. Don't rely on this tool to make trade decision, it's only a tool to, maybe, help assess a change of trend.
Seeing Buy/Sell signals on a chart is appealing, but assessing their performance in a Table makes it even more convincing — and without running a full backtest, you get a clear overview of performance immediately.
█ WYNTRADER
My name is WynTrader. I cumulate 24 years of experience. In 2001, I took an intensive technical analysis course taught by an exceptional friend, Cyril, who taught me everything I know.
After testing thousands of TradingView indicators over these 24 years, I've found none to be 100% accurate all the time. This Buy/Sell Signals indicator may outperform some others but is still not perfect. So, just be aware, and don't be fooled by this tool.
Enjoy!
WynTrader
指标
Breakout & Retest Entry Signals & the Break-vs-RetestOVERVIEW
"Wait for the retest" is the most repeated piece of advice in breakout trading. It is also, as far as I can tell, completely untested by the people who repeat it.
This tool settles it — on your instrument, with your settings — by taking BOTH entries on the SAME breaks and grading them against the same control:
PER-TRADE EDGE expectancy vs control · n
Break entry +0.09R +0.02R · n=412
Retest — CLEAN +0.31R +0.02R · n=118
Retest — DEEP -0.04R +0.02R · n=76
clean vs deep (t) 3.41 CLEAN IS BETTER
BUT — HOW OFTEN DO YOU GET IT?
Breaks that ever retested 47.0% (194/412)
after a run of >3 closes 31.2% vs 55.8% otherwise
False-break rate 13.3%
EXPECTED VALUE PER BREAK
Take every break +0.09R (100% of breaks)
Wait for the retest +0.06R (47% of breaks)
VERDICT NO DIFFERENCE — pick either
That last block is the entire point. A better per-trade edge is worthless if you only get the trade half the time — so the WAIT policy is scored as P(retest) x E , because on every break that never retests you get NOTHING. The two are then compared with a significance test, and the verdict is allowed to be "no difference".
It is a research and framing tool. NOT a strategy, NOT a signal service, NOT a validated edge.
WHAT IT ALREADY FOUND — measured live on NIFTY futures
timeframe breaks retested false breaks verdict
1m 334 49.4% 29.6% NO DIFFERENCE
3m 323 53.3% 13.6% NO DIFFERENCE
5m 328 53.4% 14.0% NO DIFFERENCE
15m 306 51.0% 12.7% TAKE THE BREAK
1h 274 50.0% 16.4% NO DIFFERENCE
TWO THINGS JUMP OUT.
The retest rate is 50-53% on every timeframe. Bulkowski, measuring throwbacks across 10,348 chart patterns on US daily stocks, found 50-60%. A completely different market, a completely different method, and the same number. That is a real phenomenon, not an artefact of the detector.
The false-break rate is 26.5% on the 1m and 13-15% everywhere else. THE ONE-MINUTE BREAK IS TWICE AS LIKELY TO BE A LIE. That is not folklore, it is this instrument's own number, and it is exactly the kind of thing a trader should know before choosing a timeframe.
And the verdict, on four of the five: NO DIFFERENCE — pick either. Once the geometry is honest and the test is a real one, the great break-versus-retest argument simply does not resolve on this instrument at most speeds. On the 15m it does resolve — and it says TAKE THE BREAK, which is the opposite of what almost everyone will tell you.
That is what a measurement looks like. It disagrees with the folklore on one timeframe, refuses to take a side on four others, and does not care what you were hoping for. No tool that needs to sell you a signal would ever print "NO DIFFERENCE".
THE ONE THING EVERYONE GETS BACKWARDS
Thomas Bulkowski measured throwbacks and pullbacks across 10,348 chart patterns. His finding:
"Do throwbacks hurt performance? YES: 97% of the time chart patterns with upward breakouts
perform better post-breakout WITHOUT a throwback."
"Do pullbacks hurt performance? YES: 91% of chart pattern types with downward breakouts
perform better if a pullback does NOT occur."
Read that again. The retest is not a gift. It is a SYMPTOM — evidence that the move is weak, that supply came back, that the break did not have the strength to run.
And yet "wait for the retest" is good advice for a completely different reason: it gives you a better price and a tighter stop.
BOTH ARE TRUE AT ONCE. They are two opposing effects on the same trade, and they have never been put on one scale and netted out. That is what this script does. The retest may still win — a better entry can outweigh a weaker move — but nobody has ever checked, and the answer is different on every instrument and every timeframe.
A CLEAN RETEST AND A DEEP ONE ARE NOT THE SAME EVENT
Bulkowski again, and this is his sharpest single finding on the subject: during a throwback, if price REMAINS ABOVE the breakout price the subsequent rise averages 40%. If it drops BELOW the breakout price and then recovers, the rise averages 29%. That is 400 samples versus 2,767.
Pooling those two throws away the strongest signal in the whole idea. So they are separated:
CLEAN retest — price came back and touched the level, but never CLOSED back through it.
DEEP retest — price CLOSED back through the level, then recovered.
They are graded separately, tested against each other, and labelled separately on the chart. If clean beats deep on your instrument, then "wait for the retest" is not one rule — it is two, and only one of them works.
AND CAN YOU SEE IT COMING?
The real, unpriced cost of a WAIT policy is that roughly half the time you never get filled. So it matters enormously whether you can predict which breaks will retest.
Bulkowski found that if price has more than three consecutively higher closes ending the day before the breakout, the throwback probability drops materially. So the panel reports the retest rate SPLIT BY THAT:
after a run of >3 closes 31.2% vs 55.8% otherwise
If the split is real on your instrument, then after a strong run into the break you should simply TAKE IT — because the retest you are waiting for is probably never coming.
IS YOUR VOLUME FILTER EARNING ITS KEEP?
Every trader is taught that a breakout must be confirmed by volume. Bulkowski's volume study says that after an ABOVE-average-volume breakout, FAILURES DOUBLE and the likelihood of a throwback TRIPLES, while the move itself is barely better.
That is testable — but only if the low-volume breaks are allowed into the sample. So VOLUME IS NOT A GATE ON THE RECORD. Every break is recorded; volume gates only the SIGNAL. The panel then reports what your filter is actually worth:
Break ON volume +0.11R n=246
Break OFF volume +0.06R n=166
on vs off (t) 0.82 no difference — it is doing nothing
The record is a fact about the market. The filter is a decision about the trade. They are kept apart, and this is what happens when you stop assuming and start measuring.
IDENTICAL GEOMETRY — and why this is not a detail
The target used to be THE NEXT OPPOSING LEVEL. That quietly destroyed the entire experiment.
The BREAK entry sits PAST the level (it closed through it). The RETEST entry sits BACK AT the level. So the retest is systematically FARTHER from the next opposing level, and was therefore being handed a BIGGER R:R for the SAME RISK — on every single trade, by construction. Live, that produced an R:R of 5.0 on one timeframe and 0.66 on another, and the on-chart key was cheerfully claiming "identical geometry" while the geometry was tilted toward the retest.
The trade now uses a FIXED R multiple, identical for the break, the retest and the control. The next opposing level is still drawn, and still tested — separately, as a descriptive statistic, with its hit rate reported next to its distance in R.
THE ANTI-BIAS GUARDS
ENTRY IS THE CLOSE, for both entries and for the control. Entering the retest AT the level — a better price than the close — while the break enters at its close would hand the retest a free head start on every trade, and settle the oldest argument in trading by rigging it.
THE CONTROL IS DIRECTION-MATCHED. Breaks run with the trend, so a direction-skewed event set measured against a symmetric 50/50 control inherits the drift for free and calls it an edge. Longs are compared only with control longs, shorts only with control shorts, and the control is blended back using the events' OWN direction mix.
EVERY VERDICT IS A TEST, NOT A COMPARISON. Break-vs-wait, clean-vs-deep, volume-on-vs-off — each is a Welch t-test that has to clear |t| > 1.96 before it is allowed to be a finding. For the wait policy, the variance of P(retest) x E is propagated by the delta method, because it is a product of two estimates and both carry error. A verdict that flips on a tenth of an R is not a verdict, it is noise wearing a costume.
Both barriers on one bar: the STOP is assumed first — conservative, and the only assumption that cannot flatter the result. Unresolved trades at the horizon are marked to market, not booked as losses.
THE LEVELS
Levels come from the extrema of a KERNEL-SMOOTHED price series (Nadaraya-Watson) rather than raw pivots, so they track the structure rather than the noise. A break requires a CLOSE beyond the level with displacement, not a wick. A false break is one that closes back inside quickly. All of it is computed on confirmed bars; the kernel is causal and never looks forward.
NON-REPAINT
The kernel confirms an extremum a half-window late, so a level appears some bars AFTER the swing that created it. That lag is the price of not repainting and it is paid deliberately. Levels, breaks, false breaks, retests, signals and every calibration event are computed on CONFIRMED bars only. Nothing is drawn and then moved.
DATA AND SCOPE
Any symbol, any timeframe. ATR-normalised throughout. Volume improves the SIGNAL but is not required, and it never gates the RECORD.
EXPORTS (Data Window — consume from other scripts via input.source())
EXP_Level, EXP_Break, EXP_FalseBreak, EXP_Retest, EXP_Entry, EXP_Stop, EXP_Target, EXP_NextLevel, EXP_WaitEdge
CONCEPT CREDIT
Support/resistance, polarity and the breakout-retest idea are long-standing public trading concepts with no single author; the written tradition runs through Charles Dow, Richard Wyckoff and Edwards & Magee. The formal TRADING-RANGE BREAK was first tested at scale by William Brock, Josef Lakonishok and Blake LeBaron, Journal of Finance 47(5), 1992 — and their results were later shown to be vulnerable to data-snooping (Sullivan, Timmermann and White, 1999), which is exactly why this tool measures the rule on YOUR instrument rather than asserting it.
The throwback and pullback statistics that motivate the clean/deep split, the run-length predictor and the volume test are from Thomas Bulkowski ("Encyclopedia of Chart Patterns"; thepatternsite.com). His numbers are measured on US daily stocks. Whether they hold on YOUR instrument is precisely the question this script exists to answer — and it may well answer "no".
Nadaraya-Watson kernel regression — Nadaraya and Watson (1964); its use for technical pattern recognition — Lo, Mamaysky and Wang, Journal of Finance 55(4), 2000. Triple-barrier forward labelling — Marcos Lopez de Prado. Welch's t-test — B. L. Welch. ATR — J. Welles Wilder.
The break-vs-wait availability weighting, the delta-method significance test, the clean/deep retest split, the volume-filter test and the direction-matched control are the author's own. Clean-room implementation; no third-party Pine code is reused. Not affiliated with, nor endorsed by, any of the above.
HONESTY AND LIMITATIONS
Calibration is IN-SAMPLE, with no costs or slippage, and uses overlapping windows. A proven in-sample edge is NOT a guarantee out-of-sample. Real fills, spreads and commissions will reduce it — and they will hurt the break entry more than the retest entry, because the break enters into momentum.
Bulkowski's throwback statistics are measured on US daily stocks over decades. They are the reason the questions are asked. They are NOT the answer, and this tool will tell you so if your instrument disagrees.
The verdict is allowed to be "NO DIFFERENCE — pick either", and on many instruments it will be. That is a real result. A tool that cannot report its own failure is an advertisement, not a measurement.
Nothing in this script predicts price.
DISCLAIMER
Research and educational tool only. NOT financial advice, NOT a recommendation, and NO guarantee of results. Entry, stop and target output is arithmetic, not advice. Trading carries risk of loss. Test out-of-sample and make your own decisions. The author accepts no liability for any use.
指标
Anchored VWAP Hand-Off 2.03Anchored VWAP Hand-Off 2.03 is a multi-leg cascading VWAP indicator. It starts with a classic Anchored VWAP from a user-selected date (Leg 1), then automatically creates new "hand-off" VWAP legs (up to 24) every time price crosses the previous VWAP. Each new leg resets its calculation from the bar of the cross, creating a dynamic chain of VWAPs that follow price action.
Key Features:
Source: Typically close (customizable).
Trigger: EMA(1) of the source (essentially price itself).
Color Logic: Each VWAP leg changes color based on whether price is above (bullish) or below (bearish) it. Supports unified color mode.
Up to 24 cascading legs (user controls how many are shown).
Visual anchor line at the start date.
Main Use Cases:
Dynamic Support & Resistance
The multiple VWAP legs act as adaptive moving support/resistance zones. Traders watch for bounces off these lines or breaks through several legs at once.
Trend Strength & Momentum
Strong trends often break multiple hand-off legs quickly.
Choppy/consolidating markets produce many frequent hand-offs (more lines clustering).
Mean Reversion Setups
Price tends to return to the nearest active VWAP legs. Useful for fade-the-extreme strategies.
Breakout / Breakdown Confirmation
When price decisively breaks through several VWAP legs in sequence, it often signals a high-probability directional move.
Intraday & Swing Trading
Particularly popular on stocks, futures, and crypto for finding "fair value" shifts after news events or strong moves. The hand-off mechanism makes it more responsive than a single static anchored VWAP.
Visual Market Structure
Helps traders see how "value" is migrating over time as new legs form.
Best Timeframes: Works on all, but especially useful on 5min to daily charts.Pro Tip: Start with 8–12 legs. Too many legs can make the chart noisy. Use the anchor date on significant events (earnings, breakout days, macro events, etc.).This indicator is an evolution of standard Anchored VWAP, designed to solve the problem of a single anchored VWAP becoming stale after big moves.
指标
Mr.Trends Monthly Demand Areas V6 Mr.Trends Monthly Demand Areas V6
Overview
Mr.Trends Monthly Demand Areas V6 (Fixed) is a higher-timeframe demand zone indicator designed to identify potential institutional buying areas based on monthly price action. The indicator combines long-term demand zones with MACD momentum confirmation to provide higher-quality BUY signals.
Features
Automatically detects monthly demand zones.
Configurable lookback period for identifying major monthly lows.
Requires consecutive bearish monthly candles before the demand zone is formed.
Draws demand zones using the monthly candle body.
Generates BUY signals when price revisits the demand zone and the MACD produces a bullish crossover.
Optional restriction to display BUY signals only on the 4-hour timeframe.
Optional background highlighting while price is trading inside the demand zone.
Includes OBV, MFI, and Pivot calculations for future divergence analysis.
Built using Pine Script® Version 6.
How to Use
This indicator is designed to be used as a higher-timeframe market structure tool rather than a standalone trading system.
A typical workflow is:
Wait for price to return to a Monthly Demand Zone.
Watch for a bullish MACD crossover.
Use your own price action or risk management rules before entering a trade.
For best results, combine this indicator with market structure, trend analysis, and proper risk management.
🇸🇦 Mr.Trends Monthly Demand Areas V6
نبذة عن المؤشر
مؤشر يعتمد على مناطق الطلب الشهرية بهدف تحديد المناطق التي قد يظهر منها اهتمام شرائي قوي. يجمع المؤشر بين مناطق الطلب على الفريم الشهري وتأكيد الزخم باستخدام مؤشر MACD للحصول على إشارات شراء ذات جودة أعلى.
المميزات
اكتشاف تلقائي لمناطق الطلب الشهرية.
إمكانية تحديد عدد الأشهر المستخدمة للبحث عن القيعان.
يشترط وجود عدد محدد من الشموع الشهرية الهابطة قبل تكوين منطقة الطلب.
رسم منطقة الطلب باستخدام جسم الشمعة الشهرية.
إصدار إشارة BUY عند دخول السعر داخل المنطقة مع حدوث تقاطع إيجابي للـ MACD.
إمكانية قصر الإشارات على فريم الأربع ساعات أو إظهارها على جميع الفريمات.
تلوين خلفية الشارت عند دخول السعر داخل منطقة الطلب.
يتضمن حسابات OBV و MFI و Pivot لاستخدامها في تطوير وتحليل الدايفرجنس مستقبلاً.
مطور باستخدام Pine Script® Version 6.
طريقة الاستخدام
هذا المؤشر مخصص لمساعدة المتداول في تحديد مناطق الطلب ذات الأهمية على الفريم الشهري، وليس كنظام تداول مستقل.
يفضل استخدامه بالشكل التالي:
انتظار وصول السعر إلى منطقة الطلب الشهرية.
انتظار ظهور تقاطع إيجابي لمؤشر MACD.
تأكيد الدخول باستخدام إدارة رأس المال وتحليل حركة السعر قبل اتخاذ قرار الشراء.
للحصول على أفضل النتائج، يوصى باستخدام المؤشر مع تحليل الاتجاه، وهيكل السوق، وإدارة المخاطر المناسبة.
指标
Market Order Bubbles [MTF]Market Order Bubbles is a CVD (Cumulative Volume Delta) style indicator that detects aggressive buying or selling volume surges using a statistical Z-Score approach. It estimates buy and sell volume from candle structure (body + wicks), then measures how far the current volume deviates from its recent average (Z-Score). When the surge is strong enough, it plots colored bubbles (circles) on the chart: Pink/Red bubbles → Strong Buy volume surge (often signals exhaustion → contrarian short)
Green bubbles → Strong Sell volume surge (often signals exhaustion → contrarian long)
The indicator is Multi-Timeframe (MTF), so you can display higher-timeframe bubbles on your current chart. It also draws connecting rays, sloped extension rays, and horizontal rays from the bubbles, plus an optional Linear Regression bias filter.
指标
Machine Learning Price Bands Kernel Regression SignalsOVERVIEW
Every "AI band" on this platform draws two lines and asserts them. None of them can tell you how often price actually stays inside.
This one can — because it is built on a method that comes with a MATHEMATICAL COVERAGE GUARANTEE, and then it CHECKS WHETHER IT KEPT THE PROMISE, live, on your chart:
Coverage (empirical vs nominal) 89.1% vs 90% n = 20,266
Is the miss REAL? -0.9 pp z = -4.3 (real)
Verdict undercovering — real, but small
That is not a band. That is a prediction interval that has been audited, and it is the whole reason this tool exists.
It is a research and framing tool. NOT a strategy, NOT a signal service, NOT a validated edge.
THE MACHINE LEARNING, SPELLED OUT — no buzzwords, here is the actual model
1. NADARAYA-WATSON KERNEL REGRESSION. Non-parametric: no functional form is assumed, the data chooses the shape. Each past bar votes on the current estimate with a Gaussian weight that decays with distance. This is the same estimator Lo, Mamaysky and Wang used in the Journal of Finance to make chart-pattern recognition objective. It is real machine learning, and it is sixty years old.
The kernel here is CAUSAL. It only ever looks backwards. A centred kernel — the kind most "Nadaraya-Watson envelope" scripts use — peeks at bars that have not happened yet, and that is why their historical fit looks so much better than their live one.
2. BANDWIDTH BY PREDICTIVE MODEL SELECTION. The bandwidth h is the only real parameter, and it is not a magic number: several candidates are run in parallel and scored on their ROLLING ONE-STEP-AHEAD SQUARED ERROR. The winner is used. That is honest model selection — the criterion you would use to choose any forecaster — rather than a knob you turn until the chart looks nice.
3. CONFORMAL PREDICTION INTERVALS. The half-width is the (1-alpha) empirical quantile of the recent ABSOLUTE one-step-ahead errors. Under exchangeability this carries a FINITE-SAMPLE coverage guarantee, with NO distributional assumption at all: no normality, no GARCH, no volatility model. The model's own recent mistakes size the band — which is why it widens when the model starts being WRONG, not merely when price starts moving.
4. ADAPTIVE CONFORMAL INFERENCE — Gibbs and Candes, NeurIPS 2021.
Here is the problem with plain conformal prediction on markets, stated plainly: its guarantee holds under EXCHANGEABILITY, and financial returns are the textbook counterexample. Volatility CLUSTERS. So a residual quantile computed over a trailing window is always a step behind, the band is too narrow exactly when it matters, and the misses bunch together. Coverage lands quietly under nominal. Measured live on NIFTY futures before this was added: 89.1% against a nominal 90%, on the 1m, the 3m and the 1h, every one of them roughly four standard errors below target. Not a bug. The assumption breaking.
ACI makes the miscoverage level a LEARNED parameter:
alpha(t+1) = alpha(t) + gamma * (alpha - err(t))
Miss the interval and alpha falls, so the quantile rises and the band WIDENS. Cover it and alpha creeps back, so the band TIGHTENS. Long-run coverage provably converges to the target IRRESPECTIVE OF THE DATA GENERATING PROCESS — no exchangeability assumption anywhere.
A band that notices it is undercovering and fixes itself. Watch the alpha row: where it settles BELOW nominal is a direct measurement of how badly exchangeability fails on your instrument.
MEASURED, ON THE SAME INSTRUMENT, BEFORE AND AFTER:
timeframe plain conformal with ACI
1m 89.1% 90.1%
3m 89.1% 90.1%
5m 89.1% 90.1%
15m 90.1% 90.1%
1h 89.1% 90.1%
(nominal 90%)
Five timeframes, a four-standard-error undercoverage on four of them, closed. The binomial test now returns "calibrated — within sampling noise" and means it. That is not a backtest of a trading rule. That is a mathematical promise being kept, and being checked.
5. NORMALISED NONCONFORMITY — Papadopoulos et al. (2008), Lei et al. (2018).
The plain score |price - fit| is a SCALAR, which means the band is THE SAME WIDTH in a dead tape and in a crash. It therefore OVERCOVERS in calm and UNDERCOVERS in chaos — and the single marginal coverage figure is the average of those two errors, looking correct while being wrong in both directions.
Normalising divides each residual by a local scale estimate before taking the quantile, and multiplies it back when drawing:
score = |price - fit| / sigma band = fit +/- q * sigma
The band now scales with LOCAL DIFFICULTY — and note it is the MODEL'S difficulty, not the market's volatility. Related, but not the same thing, and the first one is what a prediction interval is actually about.
6. THE COVERAGE AUDIT. A guarantee you do not verify is just a claim.
TWO QUESTIONS ABOUT THE COVERAGE, AND THE PANEL ANSWERS BOTH
IS THE MISS REAL? That is a binomial z-test and it needs no tolerance at all. Each bar is a Bernoulli trial with p = nominal, so the standard error of the observed coverage is sqrt(p(1-p)/n).
IS THE MISS BIG ENOUGH TO CARE ABOUT? That is a judgement, and you set it.
These are NOT the same question, and conflating them is how a band gets waved through as "calibrated". Measured live on NIFTY futures: at n = 20,266 the standard error is 0.21 pp, so an empirical coverage of 89.1% against a nominal 90% is a 0.9 pp miss — FOUR STANDARD ERRORS. Unmistakably real. Arguably too small to trade differently. A 5 pp tolerance called that "calibrated", which was the headline row of the script asserting the one thing the script exists to verify, and asserting it wrongly.
The panel now reports the size of the miss, its significance, and a verdict that distinguishes "within sampling noise" from "real, but small" from "MISCALIBRATED — do not trust the band". You get to decide which of those matters to you, and you get the numbers to decide with.
AND THEN THE ROW NOBODY HAS: CONDITIONAL COVERAGE
Coverage 90.0% vs 90% n = 20,178
calm / normal / turbulent 96.4% · 90.1% · 83.2%
A single marginal number can read a perfect 90% while the interval covers 96% of quiet bars and 83% of violent ones. Ninety per cent is then the AVERAGE OF TWO ERRORS — it looks right while being wrong in both directions, and it is wrong in the direction that costs you money exactly when it costs you money.
Exact conditional coverage is provably impossible without strong assumptions. But you can always MEASURE it, and almost nobody does. Bars are split into calm, normal and turbulent thirds by the percentile rank of ATR, and coverage is scored inside each. If the three numbers fan apart, the band is not breathing — and the normalised score is what closes the gap.
Turn the normalised score off and watch those three fan out. That is the demonstration.
FADE OR FOLLOW? THE TOOL DOES NOT PRETEND TO KNOW
Price leaving a 90% interval is statistically unusual. Whether to FADE it (an outlier, so bet on reversion) or FOLLOW it (the model has broken, so bet on the new regime) is an EMPIRICAL question, and the honest answer is often neither.
So both are logged, both are graded, and BOTH ARE TESTED AGAINST EACH OTHER.
That last part matters more than it sounds. Knowing that fading beats an unconditional control, and that following also beats an unconditional control, does not answer the question a trader is actually asking at a band break — which of the two should I do? They are mutually exclusive responses to the SAME event. So they are run head to head with a Welch t-test, and the answer is allowed to be:
FADE or FOLLOW? NEITHER — the break does not tell you which
If the difference does not clear the noise, then on this instrument the break carries no directional information, and saying so IS the finding. A tool that cannot report its own failure is an advertisement, not a measurement.
And the chart agrees with the panel. An unproven direction is still drawn — it is arithmetic, and you may want it — but it is drawn MUTED and labelled "(not proven)". It used to print "Follow the break" in full colour while the panel directly beneath it said "neither proven". The paint has to agree with the code.
THE ANTI-BIAS GUARDS
ENTRY IS THE CLOSE, for the event and for the control alike. A band break is a SIGNAL, not a fill. Entering at the band — a better price — while the control enters at the close hands every signal a free head start and manufactures an edge out of nothing.
THE CONTROL IS DIRECTION-MATCHED. In a downtrend there are more break-downs than break-ups, so FOLLOW skews short and FADE skews long. A direction-skewed event set measured against a 50/50 control inherits the index drift for free and calls it an edge. Longs are compared only with control longs, shorts only with control shorts, and the control is blended back using the events' OWN direction mix.
IDENTICAL GEOMETRY. Every event and every control trade uses the same stop and the same R multiple, so the comparison is apples to apples.
Both barriers on one bar: the STOP is assumed first — conservative, and the only assumption that cannot flatter the result. Unresolved trades at the horizon are marked to market, not booked as losses. Nothing is marked proven below t = 1.96.
NON-REPAINT
The kernel is causal, the bandwidth is chosen on past error only, the interval is built from past residuals, and coverage is scored by asking whether the actual close landed inside the interval that was published BEFORE it. Everything is computed on confirmed bars. Nothing is drawn and then moved.
WHY THESE PARTS ARE ONE TOOL
The regression gives the trend. Without the interval, a band is a guess. Without model selection, the bandwidth is a knob you turn until you like the picture. Without the coverage audit, a conformal interval is an unverified promise. And without the signal calibration, "price left the band" is folklore. Each piece is worthless alone — which is exactly why they ship together.
DATA AND SCOPE
Any symbol, any timeframe. ATR-normalised throughout. No volume required.
EXPORTS (Data Window — consume from other scripts via input.source())
EXP_Fit, EXP_Upper, EXP_Lower, EXP_Bandwidth, EXP_Coverage, EXP_Miscal, EXP_Signal, EXP_Entry, EXP_Stop, EXP_Target
CONCEPT CREDIT
Nadaraya-Watson kernel regression — E. A. Nadaraya and G. S. Watson (1964). Its use for technical pattern recognition in finance — Andrew W. Lo, Harry Mamaysky and Jiang Wang, "Foundations of Technical Analysis", Journal of Finance 55(4), 2000. Conformal prediction — Vladimir Vovk, Alexander Gammerman and Glenn Shafer; the split/inductive form used here follows Papadopoulos et al. and Lei et al. Triple-barrier forward labelling — Marcos Lopez de Prado. Welch's t-test — B. L. Welch. ATR — J. Welles Wilder.
The causal-kernel implementation, the parallel bandwidth selection, the live coverage audit, the binomial calibration test and the fade-versus-follow head-to-head are the author's own. Clean-room implementation; no third-party Pine code is reused. Not affiliated with, nor endorsed by, any of the above.
HONESTY AND LIMITATIONS
Conformal coverage is guaranteed under EXCHANGEABILITY. Financial returns are NOT exchangeable — volatility clusters, regimes shift — so the guarantee is approximate in practice. THAT IS PRECISELY WHY THE COVERAGE IS AUDITED LIVE INSTEAD OF ASSUMED. When empirical coverage drifts from nominal you are watching the assumption break, in real time, and you should believe what you see rather than the label.
A prediction interval says where price is LIKELY TO BE. It says nothing about DIRECTION, and it is not a forecast. Coverage being correct does not make band breaks tradeable — those are two different claims, and the tool tests them separately for exactly that reason.
Calibration figures are IN-SAMPLE, with no costs or slippage, and use overlapping windows. A proven in-sample edge is NOT a guarantee out-of-sample. Nothing here predicts price.
DISCLAIMER
Research and educational tool only. NOT financial advice, NOT a recommendation, and NO guarantee of results. Entry, stop and target output is arithmetic, not advice. Trading carries risk of loss. Test out-of-sample and make your own decisions. The author accepts no liability for any use.
指标
Seller Exhaustion DetectorSeller Exhaustion Detector (SED)
Overview
Seller Exhaustion Detector identifies the point where a downtrend's selling pressure is spent and buyers begin absorbing supply — the transition from distribution to accumulation. Instead of reacting to a single pattern, it scores seven independent exhaustion footprints and only confirms a signal when structural gates prove the low is actually holding.
How It Works
The detector scores confluence across a 16-point scale:
Liquidity Sweep + Reclaim (3 pts) — tracks untapped pivot-low liquidity pools; a wick below a pool followed by a close back above it marks a stop run absorbed by passive buyers.
CVD Bullish Divergence (3 pts) — price makes a lower low while session-reset cumulative volume delta makes a higher low: sell orders are no longer moving price.
RSI Bullish Divergence (2 pts) — momentum fails to confirm the new price low.
Sell-Volume Dry-Up (2 pts) — red-candle volume contracts near the lows; motivated sellers are done.
Absorption (2 pts) — elevated volume, compressed range, close in the upper half: supply being eaten without downside progress.
Higher Low (2 pts) — first structural higher pivot after the low.
Selling Climax Watch (1 pt) and Confirmed Wick Rejection (1 pt) — capitulation context and next-bar-confirmed hammer rejections.
A score alone never fires a signal. Three hard gates must also pass: the low must have held for a configurable number of bars (or a fresh sweep-reclaim substitutes as confirmation), price must be above a rising/flat EMA9, and fast volume delta must be positive. This eliminates premature signals printed while price is still making new lows.
Signals
Orange circle — selling climax (capitulation bar; watch window begins)
Gold diamond — liquidity pool swept and reclaimed
EXHAUSTION label — confirmed exhaustion (score + all gates)
ACCUMULATE label — post-exhaustion structure reclaim with positive delta
STOP-OUT label — the exhaustion low broke; the signal is invalid
Dashboard — live score breakdown and gate status, with selectable text size
Recommended Use
Built for 1-minute to 5-minute intraday charts on liquid symbols. Use EXHAUSTION as location, ACCUMULATE as trigger, and the invalidation print as a hard exit reference. Tune Climax Multiplier down (~1.7) and Pivot Left/Right to 3–4 for faster symbols.
Limitations
Volume delta is approximated from candle direction (up-volume minus down-volume), not exchange bid/ask data, so absorption and CVD reads are estimates. All components are derived from OHLCV and confirm after the fact by design — the detector locates high-probability reversal conditions; it does not predict bottoms. Not financial advice.
指标
Supply & Demand Zones + Liquidity MapOverview
Supply & Demand Zones + Liquidity Map plots the two halves of the intraday order-flow map on one chart: where imbalance originated (supply/demand zones) and where resting stop liquidity sits now (equal highs/lows and prior-day extremes). Its signature signal fires when a liquidity run terminates inside a fresh opposing zone — the classic institutional entry footprint.
How It Works
Zones. A zone is born from base-and-departure structure: two to six consecutive tight-range candles (each under a configurable ATR fraction) followed by an impulse bar exceeding 1.5× ATR with a dominant body. The base range becomes the zone. Departure volume above the volume-SMA multiplier marks the zone strong (● tag, heavier border).
Lifecycle. Every zone is a state machine: FRESH (full color) → TESTED (faded on first touch) → BROKEN (removed, or greyed if "Keep Broken Zones" is enabled, when price closes through). Zones expire after a configurable age so the chart never accumulates stale levels.
Liquidity. Equal highs and equal lows — two pivots within an ATR-scaled tolerance — are drawn as dotted stop-pool lines with EQH/EQL tags. Prior-day high and low are plotted as session reference levels.
Confluence. A triangle prints only when sell-side liquidity (prior-day low or an equal-lows pool) is swept and reclaimed while price is inside a fresh demand zone — mirrored for buy-side liquidity into fresh supply.
Signals
Teal/red boxes — demand and supply zones with FRESH/tested/broken states
Dotted orange lines + EQH/EQL tags — resting stop pools
Red/teal horizontal lines — prior-day high and low
Green triangle up / red triangle down — liquidity run terminating inside a fresh zone
Alerts for zone tests, confluence events, and new equal-high/low formation
Recommended Use
Designed for 1-minute to 15-minute intraday trading. Treat fresh strong zones as locations, liquidity pools as targets and traps, and the confluence triangle as the highest-quality context the script can identify. On low-volatility sessions, raise Impulse Range toward 1.8× ATR to filter marginal zones. Pairs naturally with an exhaustion or order-flow confirmation tool for entries.
Limitations
Zone detection is a structural heuristic on OHLCV — it approximates institutional activity and cannot see actual resting orders. Volume profile nodes are intentionally excluded for performance. Signals mark context, not guaranteed reversals. Not financial advice.
指标
MoChen - Sessions + D/W/M OpensOVERVIEW
MoChen - Sessions + D/W/M Opens is an overlay indicator designed for 24/7 cryptocurrency markets.
It combines three major market-session ranges with Daily, Weekly, and Monthly opening levels, allowing traders to observe how price behaves around different regional trading periods and higher-timeframe opening references.
The script is intended for BTC, ETH, and other continuously traded cryptocurrency pairs.
CORE FEATURES
1. Three market sessions
- Asia: 09:00-13:30, using Asia/Taipei
- London: 08:00-16:30, using Europe/London
- New York: 09:30-16:00, using America/New_York
The London and New York sessions use IANA time zones, allowing daylight-saving-time changes to be handled automatically.
Each active session displays a simplified price range. The upper and lower boundaries update while the session is active and stop updating after the session is completed.
Session settings include:
- Enable or disable each session
- Custom session name
- Custom session time
- Custom color and opacity
- Session range background
- Session open level
- Optional close, high, and low levels
- Configurable line style and width
- Configurable number of completed sessions retained
2. Daily, Weekly, and Monthly opens
The indicator displays three UTC-based opening levels:
- D: Daily open at 00:00 UTC
- W: Weekly open on Monday at 00:00 UTC
- M: Monthly open on the first calendar day at 00:00 UTC
For users in UTC+8, the Daily Open appears at 08:00 local time.
Default styles:
- D: Blue, solid line, width 1
- W: Cyan, solid line, width 2
- M: Yellow, solid line, width 3
Each opening level can be enabled or disabled independently. Its color, width, line style, label, extension behavior, and historical retention can also be adjusted.
HOW TO USE
The session ranges are designed to show when regional market participation becomes active.
They can be used to observe:
- Session range expansion
- Breakouts above or below a completed session
- Price reactions near session opens
- Relationships between the Asia, London, and New York sessions
- Whether price is trading above or below the Daily, Weekly, or Monthly open
These levels are reference points only. They are not automatic entry or exit signals and should be combined with market structure, liquidity, risk management, and the trader's own analysis.
TIMEFRAME GUIDANCE
The indicator is primarily designed for intraday charts.
Recommended timeframes:
- 1 minute
- 3 minutes
- 5 minutes
- 15 minutes
- 30 minutes
The script can be displayed on higher timeframes, but session boundaries may not align precisely with the chart's candles. For example, a 09:30 session start cannot always be represented exactly on a 1-hour or 4-hour chart.
Use lower intraday timeframes when precise session boundaries are important.
REPAINTING AND REAL-TIME BEHAVIOR
The script does not use future data or lookahead calculations.
While a session is active, its high and low boundaries update as new price data becomes available. This is expected real-time behavior.
After a session ends, its completed range stops updating.
Daily, Weekly, and Monthly opening levels are recorded when their corresponding UTC period begins.
ORIGINALITY AND DEVELOPMENT
This version was redesigned specifically for 24/7 cryptocurrency markets.
Compared with the original reference implementation, this version focuses on:
- Three dedicated cryptocurrency market sessions
- Separate session-state management
- Simplified range visualization
- Automatic London and New York daylight-saving-time handling
- Daily, Weekly, and Monthly UTC opening levels
- Controlled historical object retention
- Reduced chart clutter
- Pine Script v6 compatibility
ATTRIBUTION
This script is a derivative work based on concepts and portions of the open-source "ICT Killzones Toolkit " by LuxAlgo.
Original work Copyright LuxAlgo.
Original license: CC BY-NC-SA 4.0.
The session structure, object management, user interface, historical retention, and Daily/Weekly/Monthly opening-level system were substantially modified for this version.
This publication remains open-source and is shared under the applicable attribution, non-commercial, and share-alike requirements.
DISCLAIMER
This indicator is provided for educational and analytical purposes only.
It does not provide financial advice, investment recommendations, or guaranteed trading results. Users are responsible for their own trading decisions and risk management.
中文說明
MoChen - Sessions + D/W/M Opens 是一套為 24 小時加密貨幣市場設計的 TradingView 圖表指標。
它整合亞洲、倫敦、紐約三個主要市場時段,以及每日、每週與每月開盤價,方便交易者觀察不同市場時段與重要開盤基準附近的價格反應。
適用商品包括 BTC、ETH 與其他全天候交易的加密貨幣。
主要功能
一、三大市場時段
- 亞洲:09:00-13:30,Asia/Taipei
- 倫敦:08:00-16:30,Europe/London
- 紐約:09:30-16:00,America/New_York
倫敦與紐約使用 IANA 當地時區,因此可以自動處理夏令時間與冬令時間切換。
時段進行中,區間上緣與下緣會隨最高價及最低價即時更新;時段完成後停止變動。
每個時段可分別設定:
- 顯示或隱藏
- 時段名稱
- 開始與結束時間
- 顏色與不透明度
- 區間背景
- 時段開盤價
- 選配的收盤價、最高價與最低價
- 線型與線寬
- 歷史保留數量
二、每日、每週與每月開盤價
指標使用 UTC 作為週期開盤基準:
- D:每日 UTC 00:00
- W:每週一 UTC 00:00
- M:每月第一天 UTC 00:00
對 UTC+8 使用者而言,每日開盤價會出現在當地時間 08:00。
預設樣式:
- D:藍色實線,線寬 1
- W:青色實線,線寬 2
- M:黃色實線,線寬 3
D、W、M 可以分別調整顯示、顏色、線寬、線型、標籤、延伸方式與歷史保留數量。
使用方式
三個時段區間可用來觀察:
- 時段區間擴張
- 已完成區間的向上或向下突破
- 價格對時段開盤價的反應
- 亞洲、倫敦與紐約時段之間的延續或反轉
- 價格位於日開、週開或月開上方還是下方
本指標提供的是時間與價格參考位置,不是自動進出場訊號。
實際使用時仍應結合市場結構、流動性、風險管理與個人交易計畫。
週期限制
建議使用:
- 1 分鐘
- 3 分鐘
- 5 分鐘
- 15 分鐘
- 30 分鐘
高週期仍可顯示,但時段開始與結束時間未必能精準對齊 K 棒。
例如紐約 09:30 開盤,在 1 小時或 4 小時圖表中不一定存在完全對應的 K 棒,因此需要精確時段邊界時,應使用較低的日內週期。
重繪說明
本指標沒有使用未來資料或 lookahead 計算。
時段進行中,最高價與最低價會隨即時行情更新,這屬於正常的進行中計算。
時段結束後,已完成區間不再變動。
日開、週開與月開會在相對應的 UTC 週期開始時建立。
免責聲明
本指標僅供交易研究、教育與市場分析使用,不構成任何投資建議,也不保證任何交易結果。
使用者應自行完成分析並做好風險管理。
指标
Sector SweeperRanks the 11 sectors and 12 key industries by performance — strongest at the top — so you know where to hunt before you pick a stock.
Strong stocks tend to come from strong groups. Sector Sweeper shows which sectors and industries are leading the market right now, ranked top to bottom on one clean board — so you start your search in the right place instead of guessing.
It works on its own — nothing else required.
How it measures — no black box
Each row pulls that ETF's closing prices and computes its percent change over your lookback window; the lists are then sorted strongest to weakest. No smoothing, no proprietary formula — the value is having all 23 groups measured by the same yardstick, on one board, updated every bar, instead of flipping through 23 charts to build the same picture by hand.
What it shows — two tables
•SECTORS — the 11 S&P sector ETFs (Technology, Financials, Energy, Health Care, …), ranked by performance over your lookback.
•SUB-INDUSTRIES — 12 sharper themes (Semiconductors, Software, Biotech, Oil Services, Gold Miners, Airlines, …), ranked the same way.
Each row shows the ETF and its % move over the lookback. Green = up, red = down, and the #1 in each list is highlighted in gold
How to read it
• Top of the list = where money is flowing. Bottom = what's lagging.
• Use it **top-down**: spot the strongest sector or industry here, then go find the leading stocks inside that group.
• Watch it over time — a group climbing the board is rotating into favor; one sliding down is falling out of it.
Settings — defaults work out of the box
• Lookback (bars ) — the performance window (20 by default ≈ about a month on a daily chart).
• Each table has its own position (default: Sectors = Middle Left, Sub-Industries = Middle Right) plus table size , dark/light theme, and colors.
⚠ Educational tool for market context and planning. It ranks performance — it does not give buy/sell signals or predict price. Not financial advice.
指标
Adaptive Reaction Zones Adaptive Reaction Zones is an adaptive price-reaction level indicator designed to automatically identify areas where the market has repeatedly reversed, slowed down, or changed direction.
Rather than plotting every local high and low, the indicator:
detects confirmed price reactions;
evaluates the quality of each reaction;
groups nearby reactions into price clusters;
ranks the resulting areas;
displays only the most relevant support and resistance levels.
The chart shows the calculated center of each identified reaction area:
🔴 Red lines represent levels above the current price.
🟢 Green lines represent levels below the current price.
Each label displays the exact level price and its percentage distance from the current market price.
🎯 Purpose of the Indicator
Adaptive Reaction Zones provides a structured map of nearby price areas that have previously generated meaningful market reactions.
The indicator can be used to:
identify nearby support and resistance areas;
measure the distance to potentially significant price levels;
plan possible profit-taking areas;
locate zones where future price behavior may require closer observation;
analyze level breakouts and potential role reversals;
create alerts for crossings of relevant price areas.
The indicator is not a standalone trading strategy and does not generate mandatory buy or sell signals.
Its purpose is to provide an objective map of historical price reactions that traders can combine with trend analysis, market structure, volume, volatility, and other forms of analysis.
⚙️ How the Algorithm Works
1. Detecting Confirmed Price Reactions
The calculation begins with confirmed local highs and lows.
Users can select one of two reaction sources:
High / Low
The algorithm analyzes the full high and low values of each candle, including its wicks.
Candle body
The algorithm uses the boundaries of the candle body and excludes the extreme wick values.
The Pivot confirmation setting determines how many bars are required on each side of a local high or low before the reaction is confirmed.
As a result, a reaction is not included in the calculations at the exact moment the extreme occurs. It is added only after subsequent bars confirm that the point was a local high or low.
A lower setting:
increases the sensitivity of the algorithm;
produces more confirmed reactions;
allows the indicator to respond to smaller local movements.
A higher setting:
selects more pronounced market extremes;
reduces the number of secondary reactions;
increases the confirmation delay.
2. Evaluating Reaction Quality
The algorithm does not treat every confirmed local high or low as equally important.
Each reaction receives an individual quality score based on two components.
Reaction Candle Structure
For a reaction from a local high, the algorithm evaluates the upper wick relative to the candle’s total range.
For a reaction from a local low, it evaluates the lower wick.
A pronounced wick may indicate that price was rejected from that area by market participants.
Subsequent Price Movement
The algorithm also measures how far price moved away from the detected extreme during the period required to confirm the reaction.
This movement is normalized using ATR, allowing reactions formed under different volatility conditions to be compared on a consistent basis.
In the final calculation, the subsequent price movement receives slightly more weight than the candle structure.
This means that an isolated or insignificant extreme receives a lower score than a reaction followed by a meaningful price move in the opposite direction.
3. Adaptive Reaction Clustering
The market rarely reacts several times at exactly the same price.
More commonly, reactions occur within the same broader price area but at slightly different values. For this reason, Adaptive Reaction Zones groups nearby reactions into adaptive price clusters.
The cluster width is not fixed. It is calculated using:
the current ATR value;
the market range over the selected lookback period;
the instrument’s minimum tick size.
The algorithm compares the width calculated from ATR with a percentage of the broader market range and uses the larger value.
This allows the clustering distance to adapt automatically to:
current volatility;
the scale of movement in the selected instrument;
the characteristics of the market and timeframe.
ATR is not used as a separate trading signal in this indicator. It is used to normalize volatility, determine the adaptive cluster width, and calculate the minimum spacing between displayed levels.
4. Calculating the Center of a Price Area
When a new reaction is confirmed, the algorithm searches for the nearest suitable cluster.
If the distance to an existing cluster is within the calculated tolerance, the reaction is added to that cluster.
If no suitable cluster exists, a new price area is created.
The center of each cluster is calculated as a weighted average of all reactions included in it.
More recent reactions receive greater weight. The influence of older reactions gradually decreases according to the Historical reaction weight setting.
For each cluster, the algorithm stores:
the number of reactions;
the combined reaction-quality value;
the upper and lower boundaries of the area;
the bar of the most recent reaction;
the number of reactions from local highs;
the number of reactions from local lows.
🧠 How Level Significance Is Evaluated
After the clusters have been created, each cluster receives a composite score.
The score is based on five main characteristics.
Number of Reactions
The more confirmed reactions that have occurred within the same price area, the higher its base significance.
Reaction Quality
Clusters containing pronounced candle rejections and stronger subsequent price movements receive a higher score.
Recency
Recent reactions receive more weight than areas that have not interacted with price for a long time.
Cluster Tightness
Reactions concentrated within a relatively narrow price range receive a higher score than reactions spread across a wider area.
Role Reversal
A cluster receives additional weight when the same price area has generated reactions from both local highs and local lows.
This allows the algorithm to recognize areas that have acted as resistance during one period and as support during another.
The significance of a level is therefore not determined by a single condition. It is based on a combination of:
repetition;
reaction quality;
recency;
cluster tightness;
historical role reversal.
📊 How Displayed Levels Are Selected
Support and resistance levels are selected independently.
Resistance levels are selected from clusters located above the current price.
Support levels are selected from clusters located below the current price.
The selection process considers:
the minimum required number of reactions;
the maximum permitted distance from the current price;
the composite cluster-quality score;
proximity to the current price;
the minimum spacing between neighboring levels.
The Proximity priority setting increases the preference given to clusters located closer to the current price.
Proximity does not replace the underlying quality score. It is added to the cluster’s base score as an additional selection factor.
The Minimum spacing setting prevents several nearly identical levels from being displayed close together.
Users can separately define the maximum number of resistance and support levels.
When fewer qualifying clusters are available, the indicator displays only the levels that meet the selected requirements rather than forcing a fixed number of lines onto the chart.
🖥 Chart Display
For every active level, the indicator displays:
the calculated center of the reaction area;
the percentage distance from the current price;
a color based on the level’s current position relative to price.
A positive percentage means that the level is above the current price.
A negative percentage means that the level is below the current price.
The percentage distance is updated dynamically as the current price changes.
Level Origin Options
From last reaction
The line begins at the most recent confirmed reaction included in the cluster.
Across chart
The line extends across the entire chart.
Users can also customize:
support and resistance colors;
line style;
line thickness;
transparency;
label position;
horizontal spacing between labels.
🔄 Why Levels May Change
Adaptive Reaction Zones is a dynamic indicator.
Whenever a new reaction is confirmed, the price clusters are recalculated.
A new reaction may:
strengthen an existing cluster;
change the calculated center of a cluster;
create a new price area;
change the ranking of previously identified areas;
cause one displayed level to be replaced by another.
The number of stored reactions is limited by the Reaction memory setting.
When older reactions move outside the selected memory limit, they are removed from the calculation.
Displayed lines should therefore not be interpreted as permanent levels that must remain unchanged on the chart.
They represent the current result of the algorithm’s analysis of the available history of confirmed price reactions.
🛠 Main Settings
Reaction Detection
Pivot confirmation
Defines the number of bars required on each side of a local reaction before it is confirmed.
Lower values increase sensitivity. Higher values select more pronounced market extremes.
Reaction memory
Defines the maximum number of recent confirmed reactions included in the calculation.
Minimum reactions
Defines the minimum number of reactions required for a price cluster to qualify as a level.
Reaction source
Selects the source used to identify reactions:
High / Low;
Candle body.
Show confirmed reactions
Displays markers for confirmed local reactions directly on the chart.
Adaptive Clustering
ATR period
Defines the ATR period used to adapt the algorithm to changing volatility.
ATR cluster width
Defines the ATR multiplier used to determine how close reactions must be to belong to the same cluster.
Market range lookback
Defines the number of bars used to calculate the broader market range.
Range cluster width
Defines the percentage of the market range used as an additional measure of cluster width.
Historical reaction weight
Controls how quickly the influence of older reactions decreases.
Lower values cause historical reactions to lose influence more rapidly.
Level Selection
Resistance levels
Defines the maximum number of displayed resistance levels.
Support levels
Defines the maximum number of displayed support levels.
Maximum distance from price
Excludes clusters located too far from the current price.
Minimum spacing
Prevents several closely positioned levels from being displayed together.
Proximity priority
Controls how strongly proximity to the current price influences the final level selection.
Premium Appearance
This section allows users to customize:
support and resistance colors;
line style;
line thickness;
line transparency;
label transparency;
label position;
spacing between labels;
the starting point of each level line.
📌 Practical Use
A conservative approach is to treat each line as the calculated center of a broader area of interest rather than as an exact price for an automatic trade entry.
When price approaches a level, traders may additionally evaluate:
candle behavior;
trend direction;
market structure;
volume;
current volatility;
the nature of the initial interaction;
a breakout and subsequent retest of the area.
To Display Fewer but More Selective Levels
Consider increasing:
Pivot confirmation;
Minimum reactions;
Minimum spacing.
To Create a More Sensitive Market Map
Consider decreasing:
Pivot confirmation;
Minimum reactions.
Higher sensitivity may also increase the number of less significant reaction areas.
For highly volatile instruments, the ATR cluster width setting may require adjustment.
For markets with broad long-term price ranges, the Range cluster width setting may have a greater influence on the calculations.
🔔 Alerts
The indicator includes two alert conditions:
price crossing above an active reaction level;
price crossing below an active reaction level.
A crossing is determined by comparing the previous bar’s closing price with the current bar’s closing price.
To receive alerts only after a candle has been confirmed, select Once Per Bar Close when creating the TradingView alert.
✨ Originality of the Method
Adaptive Reaction Zones is not a simple combination of several standard indicators.
Confirmed pivots and ATR are used only as individual components within a unified calculation process.
Pivots provide confirmed price-reaction points, while ATR allows the calculations to adapt to changing market volatility.
The core methodology follows a structured sequence:
detecting confirmed price reactions;
evaluating the quality of each reaction;
adaptively grouping nearby reactions into clusters;
weighting reactions according to their recency;
evaluating cluster tightness and historical role reversal;
calculating a composite cluster score;
selecting support and resistance levels independently;
filtering out overlapping and excessively distant levels.
The purpose of this approach is not to display every possible market extreme.
Instead, the algorithm identifies a limited number of price areas that have the highest relevance according to the combined history, quality, density, and recency of previous market reactions.
⚠️ Limitations
The indicator uses price data only and does not account for:
fundamental events;
market news;
corporate reports;
macroeconomic factors.
Confirmed pivots always appear with a delay equal to the selected Pivot confirmation value.
This delay is a necessary part of confirming a local extreme and is not a calculation error.
New reactions may change:
the composition of a cluster;
the calculated center of an area;
the ranking of a level;
the set of lines displayed on the chart.
Results may be less stable on instruments with low liquidity, large price gaps, or insufficient historical data.
A historical reaction does not mean that price will necessarily reverse from the same area in the future.
The indicator highlights algorithmically identified areas of previous price interaction, but it does not guarantee the outcome of the next interaction with a level.
指标
RSL Wert (Levy)Although Robert Levy originally designed the indicator purely as a trend-following tool (true to the motto: "Buy the strongest and stick to assets with an RSL greater than 1.0"), mathematically it measures exactly what you described: the percentage deviation of the current price from its moving average (MA 130).If you use the RSL as an overbought indicator (an oscillator for extreme zones), you should pay attention to two main things:1. Historical Context of the Individual AssetAn RSL of, for example, $1.25$ means that the price is trading 25% above its 130-day moving average.For a sluggish blue-chip stock, this can already represent extreme overheating, which historically has almost always led to a correction (mean reversion).For a highly volatile tech stock or crypto asset in a massive trend phase, an RSL of $1.25$ might be completely normal, with actual overheating only setting in at $1.40$ or higher.2. Interplay with the Trend DirectionIn a bull market: A high RSL does signal overheating, but it is often a sign of extreme momentum. Here, "overheating" frequently leads to a sideways consolidation where the moving average catches up, rather than a sharp crash.At a trend reversal: If the RSL spikes to historical extremes during an already mature trend phase and then abruptly loses momentum, it serves as a classic warning sign to take profits.Rule of thumb: The further the price stretches away from the MA 130 like a rubber band (resulting in a high RSL), the greater the short-term risk of a pullback to the average.
Robert Levy hat den Indikator zwar ursprünglich als reines Trendfolgewerkzeug konzipiert (frei nach dem Motto: „Kaufe das Stärkste und halte dich an Werte mit einer RSL größer als 1,0“), aber mathematisch misst er genau das, was du beschreibst: die prozentuale Abweichung des aktuellen Kurses von seinem gleitenden Durchschnitt (GD 130).
Wenn man den RSL als Überhitzungs-Indikator (Oszillator für Extremzonen) nutzt, sollte man auf zwei Dinge achten:1.
Historischer Kontext des einzelnen WertesEin RSL von z. B. 1,25 bedeutet, dass der Kurs 25% über seinem 130-Tage-Durchschnitt notiert.Für eine träge Standardaktie kann das bereits eine extreme Überhitzung sein, die historisch fast immer zu einer Korrektur (Mean Reversion) geführt hat.
Für einen hochvolatilen Tech-Wert oder Krypto-Asset in einer massiven Trendphase kann ein RSL von 1,25 dagegen völlig normal sein, bevor die eigentliche Überhitzung erst bei 1,40 oder höher ansetzt.2.
Das Zusammenspiel mit der TrendrichtungIm Bullenmarkt: Ein hoher RSL zeigt zwar Überhitzung an, ist aber oft ein Zeichen von extremer Dynamik (Momentum). Hier führt die „Überhitzung“ häufig eher zu einer Seitwärtskonsolidierung, bei der der Durchschnitt nachzieht, anstatt zu einem scharfen Crash.Bei der Trendwende: Schießt der RSL in einer ohnehin schon reifen Trendphase auf historische Extremwerte und verliert dann schlagartig an Dynamik, ist das ein klassisches Warnsignal für Gewinnmitnahmen.Als Daumenregel lässt sich festhalten: Je weiter sich der Kurs elastisch wie ein Gummiband vom GD 130 nach oben entfernt (hoher RSL), desto größer wird kurzfristig das Risiko eines Rücksetzers zum Durchschnitt.
指标
mgc (propfirmpinescripts)Daily Regime + VWAP Reclaim Trend Strategy
A trend-following intraday strategy that trades pullback reclaims within an established daily regime.
How it works:
Daily regime filter: Uses daily EMA(5)/EMA(10) to establish a higher-timeframe bias (only trades long in uptrends, short in downtrends)
EMA stack confirmation: Requires 9/21/34/50 EMA alignment on the trading timeframe to confirm trend structure
Session VWAP + 1 SD bands: Calculated from RTH session start; entries require price to reclaim beyond the 1-SD band
Volume filter: Entry bar must exceed the 20-period volume average
Risk management: Stop placed beyond the entry bar's high/low (capped at 50 ticks), fixed 3:1 reward-to-risk target
Session/frequency limits: Trades only within a defined RTH window, max 3 entries per day, force-flat at session end
Notes:
Designed and tested on futures — backtest thoroughly on your instrument/timeframe before live use
No repainting: all higher-timeframe data uses lookahead_off
This is a mechanical trend/pullback system, not a reversal or mean-reversion strategy
Past performance in backtesting does not guarantee future results — use proper risk management and position sizing
策略















