Hoàng già — Hoàng giàSimplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Simplify it based on the structure of the frame price
Băng tần và kênh
THE BATATAH SAUCE BTC.PERP TRADING STRAT12hr hour is the sweet spot
great profit factor
decent risk management avg losing (back tested for 5 yrs and does alright till even 2018)trade 8.21% vs avg winning 174.87% (back tested for 5 yrs and does alright since even start2018)
Its alright on daily as well as 6hr but lower just gets more noisy
Pump/Dump Detector [Modular]//@version=5
indicator("Pump/Dump Detector ", overlay=true)
// ————— Inputs —————
risk_pct = input.float(1.0, "Risk %", minval=0.1)
capital = input.float(100000, "Capital")
stop_multiplier = input.float(1.5, "Stop Multiplier")
target_multiplier = input.float(2.0, "Target Multiplier")
volume_mult = input.float(2.0, "Volume Spike Multiplier")
rsi_low_thresh = input.int(15, "RSI Oversold Threshold")
rsi_high_thresh = input.int(85, "RSI Overbought Threshold")
rsi_len = input.int(2, "RSI Length")
bb_len = input.int(20, "BB Length")
bb_mult = input.float(2.0, "BB Multiplier")
atr_len = input.int(14, "ATR Length")
show_signals = input.bool(true, "Show Entry Signals")
use_orderflow = input.bool(true, "Use Order Flow Proxy")
use_ml_flag = input.bool(false, "Use ML Risk Flag")
use_session_filter = input.bool(true, "Use Volatility Sessions")
// ————— Symbol Filter (Optional) —————
symbol_nq = input.bool(true, "Enable NQ")
symbol_es = input.bool(true, "Enable ES")
symbol_gold = input.bool(true, "Enable Gold")
is_nq = str.contains(syminfo.ticker, "NQ")
is_es = str.contains(syminfo.ticker, "ES")
is_gold = str.contains(syminfo.ticker, "GC")
symbol_filter = (symbol_nq and is_nq) or (symbol_es and is_es) or (symbol_gold and is_gold)
// ————— Calculations —————
rsi = ta.rsi(close, rsi_len)
atr = ta.atr(atr_len)
basis = ta.sma(close, bb_len)
dev = bb_mult * ta.stdev(close, bb_len)
bb_upper = basis + dev
bb_lower = basis - dev
rolling_vol = ta.sma(volume, 20)
vol_spike = volume > volume_mult * rolling_vol
// ————— Session Filter (EST) —————
est_offset = -5
est_hour = (hour + est_offset + 24) % 24
session_filter = (est_hour >= 18 or est_hour < 6) or (est_hour >= 14 and est_hour < 17)
session_ok = not use_session_filter or session_filter
// ————— Order Flow Proxy —————
mfi = ta.mfi(close, 14)
buy_imbalance = ta.crossover(mfi, 50)
sell_imbalance = ta.crossunder(mfi, 50)
reversal_candle = close > open and close > ta.highest(close , 3)
// ————— ML Risk Flag (Placeholder) —————
ml_risk_flag = use_ml_flag and (ta.sma(close, 5) > ta.sma(close, 20))
// ————— Entry Conditions —————
long_cond = symbol_filter and session_ok and vol_spike and rsi < rsi_low_thresh and close < bb_lower and (not use_orderflow or (buy_imbalance and reversal_candle)) and (not use_ml_flag or ml_risk_flag)
short_cond = symbol_filter and session_ok and vol_spike and rsi > rsi_high_thresh and (not use_orderflow or sell_imbalance) and (not use_ml_flag or ml_risk_flag)
// ————— Position Sizing —————
risk_amt = capital * (risk_pct / 100)
position_size = risk_amt / atr
// ————— Plot Signals —————
plotshape(show_signals and long_cond, title="Long Signal", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(show_signals and short_cond, title="Short Signal", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)
// ————— Alerts —————
alertcondition(long_cond, title="Long Entry Alert", message="Pump fade detected: Long setup triggered")
alertcondition(short_cond, title="Short Entry Alert", message="Dump detected: Short setup triggered")
Auto S/R 1H - Stable Simplethat is a script to find out the support and resistance as trendlines for stocks in one hour timeframe for swing trading.
LUCEO Monday Range V3LUCEO Monday Range 지표는 매주 월요일의 고점(Monday High), 저점(Monday Low), 균형값(Equilibrium)을 자동으로 표시해 주는 도구입니다.
ICT, 런던 브레이크아웃 등 월요일 범위를 기준으로 삼는 전략에 적합하며, 과거 데이터를 통해 이전 여러 주 월요일 범위를 시각화할 수 있습니다.
기능 요약:
월요일 고점(MH), 저점(ML), 균형가(EQ) 자동 표시
최대 52주까지 과거 월요일 범위 표시 가능
각 레벨 터치 시 알림 기능 지원
라벨/라인 색상, 스타일, 크기 사용자 지정 가능
주간/월간 차트에서는 자동으로 표시 비활성화
활용 예시:
월요일 고점을 상향 돌파하는 돌파 전략 분석
주간 유동성 중심 레벨인 EQ를 기준으로 방향성 판단
주요 반전 구간 탐지에 사용
---------------------------------------------------------------------------------------------------------
Monday Range (Lines) indicator automatically displays each Monday’s High (MH), Low (ML), and Equilibrium (EQ) levels on the chart.
It is useful for ICT-based setups, London breakout strategies, or any system that relies on weekly liquidity levels. The indicator supports visualization of up to 52 past Mondays.
Key Features:
Automatic plotting of Monday High, Low, and Equilibrium
Displays Monday ranges from multiple past weeks
Real-time alerts when price touches MH, ML, or EQ
Customizable line and label styles, colors, and sizes
Automatically disables display on weekly and monthly charts
Use Cases:
Validate London session breakout with Monday High breakout
Use EQ as a liquidity balance reference
Identify key reversal zones using weekly range extremes
HawkEye EMA Cloud
# HawkEye EMA Cloud - Enhanced Multi-Timeframe EMA Analysis
## Overview
The HawkEye EMA Cloud is an advanced technical analysis indicator that visualizes multiple Exponential Moving Average (EMA) relationships through dynamic color-coded cloud formations. This enhanced version builds upon the original Ripster EMA Clouds concept with full customization capabilities.
## Credits
**Original Author:** Ripster47 (Ripster EMA Clouds)
**Enhanced Version:** HawkEye EMA Cloud with advanced customization features
## Key Features
### 🎨 **Full Color Customization**
- Individual bullish and bearish colors for each of the 5 EMA clouds
- Customizable rising and falling colors for EMA lines
- Adjustable opacity levels (0-100%) for each cloud independently
### 📊 **Multi-Layer EMA Analysis**
- **5 Configurable EMA Cloud Pairs:**
- Cloud 1: 8/9 EMAs (default)
- Cloud 2: 5/12 EMAs (default)
- Cloud 3: 34/50 EMAs (default)
- Cloud 4: 72/89 EMAs (default)
- Cloud 5: 180/200 EMAs (default)
### ⚙️ **Advanced Customization Options**
- Toggle individual clouds on/off
- Adjustable EMA periods for all timeframes
- Optional EMA line display with color coding
- Leading period offset for cloud projection
- Choice between EMA and SMA calculations
- Configurable source data (HL2, Close, Open, etc.)
## How It Works
### Cloud Formation
Each cloud is formed by the area between two EMAs of different periods. The cloud color dynamically changes based on:
- **Bullish (Green/Custom):** When the shorter EMA is above the longer EMA
- **Bearish (Red/Custom):** When the shorter EMA is below the longer EMA
### Multiple Timeframe Analysis
The indicator provides a comprehensive view of trend strength across multiple timeframes:
- **Short-term:** Clouds 1-2 (faster EMAs)
- **Medium-term:** Cloud 3 (intermediate EMAs)
- **Long-term:** Clouds 4-5 (slower EMAs)
## Trading Applications
### Trend Identification
- **Strong Uptrend:** Multiple clouds stacked bullishly with price above
- **Strong Downtrend:** Multiple clouds stacked bearishly with price below
- **Consolidation:** Mixed cloud colors indicating sideways movement
### Entry Signals
- **Bullish Entry:** Price breaking above bearish clouds turning bullish
- **Bearish Entry:** Price breaking below bullish clouds turning bearish
- **Confluence:** Multiple cloud confirmations strengthen signal reliability
### Support/Resistance Levels
- Cloud boundaries often act as dynamic support and resistance
- Thicker clouds (higher opacity) may provide stronger S/R levels
- Multiple cloud intersections create significant price levels
## Customization Guide
### Color Schemes
Create your own visual style by customizing:
1. **Bullish/Bearish colors** for each cloud pair
2. **Rising/Falling colors** for EMA lines
3. **Opacity levels** to layer clouds effectively
### Recommended Settings
- **Day Trading:** Focus on Clouds 1-2 with higher opacity
- **Swing Trading:** Use Clouds 1-3 with moderate opacity
- **Position Trading:** Emphasize Clouds 3-5 with lower opacity
## Technical Specifications
- **Version:** Pine Script v6
- **Type:** Overlay indicator
- **Calculations:** Real-time EMA computations
- **Performance:** Optimized for all timeframes
- **Alerts:** Configurable long/short alerts available
## Risk Disclaimer
This indicator is for educational and informational purposes only. Always combine with proper risk management and additional analysis before making trading decisions. Past performance does not guarantee future results.
---
*Enhanced and customized version of the original Ripster EMA Clouds by Ripster47. This modification adds comprehensive color customization and enhanced user control while preserving the core analytical framework.*
Arena TP Manager//@version=5
indicator("Arena TP Manager", overlay=true, max_labels_count=500)
// === INPUTS ===
entryPrice = input.float(0.0, "Entry Price", step=0.1)
stopLossPerc = input.float(5.0, "Stop Loss %", step=0.1)
tp1Perc = input.float(10.0, "TP1 %", step=0.1)
tp2Perc = input.float(20.0, "TP2 %", step=0.1)
tp3Perc = input.float(30.0, "TP3 %", step=0.1)
// === CALCULATIONS ===
stopLoss = entryPrice * (1 - stopLossPerc/100)
tp1 = entryPrice * (1 + tp1Perc/100)
tp2 = entryPrice * (1 + tp2Perc/100)
tp3 = entryPrice * (1 + tp3Perc/100)
// === PLOTTING ===
plot(entryPrice > 0 ? entryPrice : na, title="Entry", color=color.yellow, linewidth=2, style=plot.style_linebr)
plot(entryPrice > 0 ? stopLoss : na, title="Stop Loss", color=color.red, linewidth=2, style=plot.style_linebr)
plot(entryPrice > 0 ? tp1 : na, title="TP1", color=color.green, linewidth=2, style=plot.style_linebr)
plot(entryPrice > 0 ? tp2 : na, title="TP2", color=color.green, linewidth=2, style=plot.style_linebr)
plot(entryPrice > 0 ? tp3 : na, title="TP3", color=color.green, linewidth=2, style=plot.style_linebr)
// === LABELS ===
if (entryPrice > 0)
label.new(bar_index, entryPrice, "ENTRY: " + str.tostring(entryPrice), style=label.style_label_up, color=color.yellow, textcolor=color.black)
label.new(bar_index, stopLoss, "SL: " + str.tostring(stopLoss), style=label.style_label_down, color=color.red, textcolor=color.white)
label.new(bar_index, tp1, "TP1: " + str.tostring(tp1), style=label.style_label_up, color=color.green, textcolor=color.white)
label.new(bar_index, tp2, "TP2: " + str.tostring(tp2), style=label.style_label_up, color=color.green, textcolor=color.white)
label.new(bar_index, tp3, "TP3: " + str.tostring(tp3), style=label.style_label_up, color=color.green, textcolor=color.white)
Energy Across TimePrivate Use-Only Version
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, lectus nec varius dictum, nibh arcu imperdiet augue, ac tristique odio nulla nec ligula. Vivamus ac odio nec lorem faucibus posuere. Proin sed sapien dignissim, laoreet velit vitae, vehicula justo. Curabitur et viverra lectus. Ut sit amet rhoncus ligula. Nullam nec posuere nisl. Morbi faucibus mattis sem, nec faucibus neque tristique vitae. Praesent malesuada nisl nec lectus congue, sit amet fringilla mauris vulputate. Ut quis felis vitae arcu varius ultrices non vel metus. Duis ac posuere nulla. Sed quis odio arcu. Etiam sodales eros libero, eget finibus elit bibendum nec. Cras ac justo sed justo facilisis suscipit. Nullam faucibus tortor vitae lorem eleifend, ut rhoncus lacus imperdiet.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Integer sagittis mi ut leo efficitur, vel feugiat nibh suscipit. Morbi sed vulputate risus, eu volutpat massa. Vestibulum luctus, nisl non posuere vehicula, enim urna bibendum est, sit amet luctus libero sapien a massa. Nullam blandit nulla non massa pretium, nec fermentum turpis vestibulum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam condimentum congue feugiat. Donec commodo, libero nec congue finibus, augue mi malesuada mi, sed suscipit erat sem ut orci. Phasellus dictum justo at ligula tincidunt, nec dictum libero scelerisque. Nulla et faucibus nulla, id aliquet magna. Fusce congue, justo in luctus iaculis, lectus dolor ultrices nunc, nec euismod lectus lorem ac lectus.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam dictum sapien non mattis aliquet. Integer semper venenatis libero, sit amet posuere magna laoreet at. Aliquam erat volutpat. Aenean congue luctus felis, vel blandit velit posuere nec. Aenean feugiat, purus at vulputate posuere, ipsum nulla dignissim arcu, nec sollicitudin quam est sed purus. Aenean bibendum, ligula a luctus venenatis, erat nisl sagittis eros, id ultrices purus nibh ac nunc. Sed egestas sodales dui, vitae volutpat mauris facilisis vitae. Nam sit amet dolor ac lorem luctus luctus. Morbi iaculis fringilla bibendum. Mauris ut ullamcorper leo. Sed fringilla fermentum nunc, eget egestas orci porttitor a. Aenean sit amet mi ligula. Suspendisse sed efficitur odio. Quisque in turpis eget mauris ullamcorper faucibus. Sed euismod turpis ut arcu posuere tincidunt.
Shock!The Shock Indicator is a volatility-banding model that forecasts price ranges with a dynamically widening/shrinking system. Fundamentally, it uses an exponentially weighted moving average of returns, adjusting for time-of-day patterns, to estimate a baseline volatility (i.e. The ‘prior’ in Bayesian theory). It detects jumps by comparing realized variance with “bipower variation”, temporarily widening the bands when shocks occur, and decaying the width of the bands as the shock subsides. In order to keep the coverage as calibrated and honest as possible, it continuously checks how often each bar’s closing prices stay inside the predicted bands, and adapts tail multipliers using a “scoring” system, avoiding the “cheat” of inflating bands everywhere to include as many candles as possible. It also uses a simple decaying mechanism to shrink bands exponentially faster when realized ranges are calm, preventing long periods of unjustified overshooting. In practice, this design keeps the empirical coverage probability close to a user-selected target. By default, the target is set to 95%. Across various 5 minute, 10 minute, 15 minute, and 30 minute timeframes on assets such as USDJPY, ES and NQ Futures, QQQ, NVDA, TSLA, BTCUSD, the empirical coverage consistently stays within -10%/+4% of the default 95% target coverage, while staying extremely responsive to shocks.
At the open of each candle, the range is drawn. The range is “frozen” the moment it is drawn, meaning it cannot utilize “cheating” methods such as repainting or future-looking to artificially inflate the accuracy and calibration. The indicator then tracks how accurate and well-calibrated it was for that given candle, optimizing the bands for future bars.
Ham | Reversal Wick @ Trend End v6
“This indicator is a precise tool for identifying market reversal signals. It works across all timeframes, with 5-minute and 15-minute charts recommended for scalping.”
MONETRA• “Ensures trades follow precise stop-loss, entry, and take-profit rules.”
• “Helps traders stick to predefined stop, entry, and partial profit targets with accuracy.”
9:30 AM 1-Minute Open HighlightScript Description
This script highlights the first 1-minute candle of the New York session (09:30 ET) on every trading day.
It automatically detects the opening bar and marks its full range (high–low) with a box that remains visible across all timeframes.
The script keeps only the most recent 30 trading days on the chart, so older markers are automatically removed.
This makes it easy to track the NY open consistently and use it as a reference point for daily analysis and trading setups.
EMA Crossover Buy/Sell with Switchable TimeframeCreated to Set a buy and Sell SIgnal Off the 15m TF/ with the Ema's set to 1 and 7. will kick the signal 1 candle before the move or on the move itself.
Multi-Symbol Options Trading IndicatorSymbol Configuration: User can input three different symbols (INDEX, CE, PE) with individual timeframes
Customizable Settings: Fully editable MACD and Stochastic parameters
Signal Generation:
BUY CE: When INDEX shows bullish signals AND CE option shows bullish signals
BUY PE: When INDEX shows bearish signals AND PE option shows bullish signals
Signal Conditions:
BUY CE Signal (all must be true):
INDEX: Stochastic %K > %D
INDEX: MACD line > Signal line
INDEX: Histogram shows bullish trend over specified bars
CE: Stochastic %K > %D
CE: MACD line > Signal line
CE: Histogram shows bullish trend over specified bars
BUY PE Signal (all must be true):
INDEX: Stochastic %K < %D
INDEX: MACD line < Signal line
INDEX: Histogram shows bearish trend over specified bars
PE: Stochastic %K > %D
PE: MACD line > Signal line
PE: Histogram shows bullish trend over specified bars
Visual Elements:
Green triangle up with "BUY CE" text when CE signal triggers
Red triangle down with "BUY PE" text when PE signal triggers
Background coloring on signal candles
Conditions table showing real-time status of all conditions
Alerts for both signal types
Usage Instructions:
Add the indicator to your chart
Configure your three symbols (INDEX, CE option, PE option)
Set timeframes for each symbol
Adjust MACD and Stochastic parameters as needed
Set the number of histogram bars for trend analysis
Enable/disable the conditions table and choose its position
The table will show you exactly which conditions are met (✓) or not met (✗) for both signal types, making it easy to monitor the setup in real-time.
EMA and BB Analysis for US100 V250829This TradingView strategy generates buy and sell signals based on exponential moving average (EMA) crossovers, limited by other factors such as Bollinger Bands, volume, and EMA distance.
It uses EMAs of 16, 24, 32, and 64 periods, as well as the angles of each of these EMAs.
Entry Conditions:
EMA Crossover Entry:
When EMA16 crosses EMA64 and the following conditions are met:
EMA16, EMA24, EMA32 are aligned — for a buy signal:
EMA16 > EMA24
EMA24 > EMA32
EMA32 > EMA48
(and the opposite for a sell signal)
EMA Angles:
The angles of the EMAs must also follow the same alignment.
Divergence Entry:
When the distance between EMAs 16, 24, 32, and 48 increases.
Entry Limitations:
Once an entry is detected, it is filtered by several conditions:
When the distance between the entry candle and EMA96 is more than two candles of the maximum size over three periods.
The stop loss is set as two candles of the maximum size over three periods. If this stop loss exceeds 6,000 points (adjustable parameter), the entry is invalid.
When the price is at the edge of the Bollinger Band with a 1200-period setting (equivalent to a 1-hour Bollinger Band).
When the Bollinger Band's middle line is descending and a buy signal is triggered (and vice versa).
When volume drops below a certain threshold.
When a sideways market movement is detected.
All these entry limitations are configurable parameters and can be enabled or disabled.
🏆 AI Gold Master IndicatorsAI Gold Master Indicators - Technical Overview
Core Purpose: Advanced Pine Script indicator that analyzes 20 technical indicators simultaneously for XAUUSD (Gold) trading, generating automated buy/sell signals through a sophisticated scoring system.
Key Features
📊 Multi-Indicator Analysis
Processes 20 indicators: RSI, MACD, Bollinger Bands, EMA crossovers, Stochastic, Williams %R, CCI, ATR, Volume, ADX, Parabolic SAR, Ichimoku, MFI, ROC, Fibonacci retracements, Support/Resistance, Candlestick patterns, MA Ribbon, VWAP, Market Structure, and Cloud MA
Each indicator generates BUY (🟢), SELL (🔴), or NEUTRAL (⚪) signals
⚖️ Dual Scoring Systems
Weighted System: Each indicator has configurable weights (10-200 points, total 1000), with higher weights for critical indicators like RSI (150) and MACD (150)
Simple Count System: Basic counting of BUY vs SELL signals across all indicators
🎯 Signal Generation
Configurable thresholds for both systems (weighted score threshold: 400-600 recommended)
Dynamic risk management with ATR-based TP/SL levels
Signal strength filtering to reduce false positives
📈 Advanced Configuration
Customizable thresholds for all 20 indicators (RSI levels, Stochastic bounds, Williams %R zones, etc.)
Dynamic weight bonuses that adapt to dominant market trends
Risk management with configurable TP1/TP2 multipliers and stop losses
🎛️ Visual Interface
Real-time master table displaying all indicators, their values, weights, and current signals
Visual trading signals (triangles) with detailed labels
Optional TP/SL lines and performance statistics
💡 Optimization Features
Gold-specific parameter tuning
Trend analysis with configurable lookback periods
Volume spike detection and volatility analysis
Multi-timeframe compatibility (15m, 1H, 4H recommended)
The system combines traditional technical analysis with modern weighting algorithms to provide comprehensive market analysis specifically optimized for gold trading.
Ragazzi è una meraviglia, pronto all uso, già configurato provatelo divertitevi e fate tanti soldoni poi magari una piccola donazione spontanea sarebbe molto gradita visto il tempo, risorse e gli insulti della moglie che mi diceva che perdevo tempo, fatemi sapere se vi piace.
nel codice troverete una descrizione del funzionamento se vi vengono in mente delle idee per migliorarlo contattatemi troverete i mie contatti in tabella un saluto.
BankNifty Institutional Zone MapperBankNifty Institutional Zone Mapper is a powerful support–resistance mapping tool designed to reveal the hidden grid where institutions are most likely placing their orders.
Instead of random lines, this indicator uses dual baselines with equidistant spacing to create highly accurate zones that act as magnets for price.
🔹 Why try it?
Detect institutional reaction levels instantly.
Spot high-probability support & resistance zones without guesswork.
Works seamlessly across intraday & positional trading.
Eliminates chart clutter while keeping the levels precise & repeatable.
Whether you’re trading BankNifty options, futures, or intraday moves, these zones will help you identify where real market battles are happening.
Add it once to your chart, and you’ll immediately see why price respects these levels again and again.
Snapfront WCTφ Coherence BandsSnapfront Coherence Bands — WCTφ (v6)
The Snapfront Coherence Bands (SCB) extend classic ATR-style bands with a coherence-driven engine. Instead of simple volatility envelopes, SCB adapt dynamically to market entropy, trend stability, and regime detection.
Core Features:
📊 WCTφ (Weighted Coherence Tracking) to measure entropy & disorder
🔍 Adaptive band width scaling with chaos factor (ATR × coherence)
🎯 Regime coloring:
Trend (lime)
Breakout (aqua)
Mean reversion (yellow)
Exhaustion (orange)
⚡ Squeeze detector with percentile-based compression zones
🟢/🔴 Entry/exit arrows on crossovers (optional)
Use Cases:
Spot high-clarity trend moves vs. noisy ranges
Anticipate volatility squeezes & breakout setups
Filter trades by regime classification
Visualize price stability with adaptive banding
⚠️ Invite-Only Access:
Available exclusively via SnapfrontTech. Subscription required.
P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R//@version=6
indicator("P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R", overlay=true, max_lines_count=500, max_labels_count=500)
// ====== General =====
side = input.string("Long", "Position Side", options= )
usd_dp = input.int(2, "USD decimals", minval=0, maxval=6)
// ====== HUD Settings ======
hud_font = input.string("large", "HUD font size", options= )
hud_bg = input.color(color.new(color.black, 0), "HUD background color")
hud_txtc = input.color(color.white, "HUD text color")
hud_side = input.string("Right of price", "HUD side", options= )
hud_off_bars = input.int(3, "Horizontal offset (bars)", minval=0, maxval=50)
hud_off_atr = input.float(0.2, "Vertical offset from price (ATR)", step=0.1)
atr_len = input.int(14, "ATR length for vertical offset", minval=1)
lock_to_last_bar = input.bool(true, "Lock HUD to the last bar")
// Show HUD even when there are no entries (test text)
force_show_hud = input.bool(true, "🔍 Show HUD even with no entries")
// ====== Shared SL & Targets ======
stop_inp = input.float(0.0, "Stop Loss (shared, optional)", step=0.0001)
use_tp1 = input.bool(false, "Enable Target 1")
tp1 = input.float(0.0, "Target 1 price", step=0.0001)
use_tp2 = input.bool(false, "Enable Target 2")
tp2 = input.float(0.0, "Target 2 price", step=0.0001)
use_tp3 = input.bool(false, "Enable Target 3")
tp3 = input.float(0.0, "Target 3 price", step=0.0001)
use_tp4 = input.bool(false, "Enable Target 4")
tp4 = input.float(0.0, "Target 4 price", step=0.0001)
use_tp5 = input.bool(false, "Enable Target 5")
tp5 = input.float(0.0, "Target 5 price", step=0.0001)
// ====== Four Independent Entries ======
group1 = "Entry 1"
en1 = input.bool(true, "Enable Entry 1", inline=group1)
lev1 = input.int(10, "Leverage", minval=1, maxval=200, inline=group1)
entry1 = input.float(0.0, "Entry 1 price", step=0.0001)
set_now1 = input.bool(false, "⚡ Set Entry1 = Current Price")
mode1 = input.string("USD (USDT)", "Size unit 1", options= )
sem1 = input.string("Margin (apply leverage)", "Size meaning 1", options= )
size1 = input.float(0.0, "Position size 1", step=0.0001)
baseLev1 = input.bool(false, "Apply leverage to 'Coin Quantity' (1)")
group2 = "Entry 2"
en2 = input.bool(false, "Enable Entry 2", inline=group2)
lev2 = input.int(10, "Leverage", minval=1, maxval=200, inline=group2)
entry2 = input.float(0.0, "Entry 2 price", step=0.0001)
set_now2 = input.bool(false, "⚡ Set Entry2 = Current Price")
mode2 = input.string("USD (USDT)", "Size unit 2", options= )
sem2 = input.string("Margin (apply leverage)", "Size meaning 2", options= )
size2 = input.float(0.0, "Position size 2", step=0.0001)
baseLev2 = input.bool(false, "Apply leverage to 'Coin Quantity' (2)")
group3 = "Entry 3"
en3 = input.bool(false, "Enable Entry 3", inline=group3)
lev3 = input.int(10, "Leverage", minval=1, maxval=200, inline=group3)
entry3 = input.float(0.0, "Entry 3 price", step=0.0001)
set_now3 = input.bool(false, "⚡ Set Entry3 = Current Price")
mode3 = input.string("USD (USDT)", "Size unit 3", options= )
sem3 = input.string("Margin (apply leverage)", "Size meaning 3", options= )
size3 = input.float(0.0, "Position size 3", step=0.0001)
baseLev3 = input.bool(false, "Apply leverage to 'Coin Quantity' (3)")
group4 = "Entry 4"
en4 = input.bool(false, "Enable Entry 4", inline=group4)
lev4 = input.int(10, "Leverage", minval=1, maxval=200, inline=group4)
entry4 = input.float(0.0, "Entry 4 price", step=0.0001)
set_now4 = input.bool(false, "⚡ Set Entry4 = Current Price")
mode4 = input.string("USD (USDT)", "Size unit 4", options= )
sem4 = input.string("Margin (apply leverage)", "Size meaning 4", options= )
size4 = input.float(0.0, "Position size 4", step=0.0001)
baseLev4 = input.bool(false, "Apply leverage to 'Coin Quantity' (4)")
// Quick set entries = current price
entry1 := (en1 and set_now1) ? close : entry1
entry2 := (en2 and set_now2) ? close : entry2
entry3 := (en3 and set_now3) ? close : entry3
entry4 := (en4 and set_now4) ? close : entry4
// ====== Helpers ======
to_size(s) =>
s == "tiny" ? size.tiny : s == "small" ? size.small : s == "normal" ? size.normal : s == "large" ? size.large : size.huge
f_usd_str(_val, _decimals) =>
na(_val) ? "—" : str.tostring(math.round(_val * math.pow(10, _decimals)) / math.pow(10, _decimals))
f_qty_base(mode, sem, size, entry, baseLev, lev) =>
float _qty = na
if mode == "USD (USDT)"
_qty := (size > 0 and entry > 0) ? ((sem == "Margin (apply leverage)" ? size * lev : size) / entry) : na
else
_qty := size > 0 ? (baseLev ? size * lev : size) : na
_qty
f_notional_quote(mode, sem, size, entry, lev, baseLev) =>
if mode == "USD (USDT)"
sem == "Margin (apply leverage)" ? size * lev : size
else
(baseLev ? size * lev : size) * entry
f_pnl_quote(side, entry, qty) =>
na(qty) or na(entry) ? na : (side=="Long" ? (close - entry) : (entry - close)) * qty
f_pct(side, entry) =>
na(entry) ? na : ((close - entry) / entry * 100.0) * (side=="Long" ? 1 : -1)
f_roi_pct(side, entry, lev) =>
na(entry) ? na : f_pct(side, entry) * lev
// NOTE: _lineIn must be a line, not a float
f_stickyHLine(_price, _lineIn, _color, _width) =>
var line _out = na
_out := _lineIn
if na(_out)
_out := line.new(bar_index-1, _price, bar_index+1, _price, xloc=xloc.bar_index, extend=extend.both, width=_width, style=line.style_dashed, color=_color)
else
line.set_xy1(_out, bar_index-1, _price)
line.set_xy2(_out, bar_index+1, _price)
line.set_color(_out, _color)
line.set_width(_out, _width)
_out
// ====== 4 Entries Calculations ======
var color entryCols = array.from(color.new(color.yellow, 0), color.new(color.orange, 0), color.new(color.teal, 0), color.new(color.fuchsia, 0))
bool ens = array.from(en1, en2, en3, en4)
float entries = array.from(entry1, entry2, entry3, entry4)
int levs = array.from(lev1, lev2, lev3, lev4)
string modes = array.from(mode1, mode2, mode3, mode4)
string sems = array.from(sem1, sem2, sem3, sem4)
float sizes = array.from(size1, size2, size3, size4)
bool baseLevs = array.from(baseLev1, baseLev2, baseLev3, baseLev4)
float qtys = array.new_float(4, na)
float pnls = array.new_float(4, na)
float pcts = array.new_float(4, na)
float rois = array.new_float(4, na)
float notionals = array.new_float(4, na)
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
ent = array.get(entries, i)
levX = array.get(levs, i)
modeX= array.get(modes, i)
semX = array.get(sems, i)
sizeX= array.get(sizes, i)
bLev = array.get(baseLevs, i)
qty = f_qty_base(modeX, semX, sizeX, ent, bLev, levX)
array.set(qtys, i, qty)
pnlq = f_pnl_quote(side, ent, qty)
array.set(pnls, i, pnlq)
pct = f_pct(side, ent)
array.set(pcts, i, pct)
roi = f_roi_pct(side, ent, levX)
array.set(rois, i, roi)
notq = f_notional_quote(modeX, semX, sizeX, ent, levX, bLev)
array.set(notionals, i, notq)
// ====== Totals & Weighted Avg Entry ======
float totalPnlUSD = 0.0
float totalNotional = 0.0
float totalQty = 0.0
float wAvgEntry = na
for i = 0 to 3
if not na(array.get(pnls, i))
totalPnlUSD += array.get(pnls, i)
if not na(array.get(notionals, i))
totalNotional += array.get(notionals, i)
if not na(array.get(qtys, i)) and array.get(entries, i) > 0
totalQty += array.get(qtys, i)
if totalQty > 0
num = 0.0
for i = 0 to 3
qi = array.get(qtys, i)
ei = array.get(entries, i)
if not na(qi) and ei > 0
num += qi * ei
wAvgEntry := num / totalQty
totalROIweighted = totalNotional > 0 ? (totalPnlUSD / totalNotional) * 100.0 : na
// ====== Nearest TP & R:R ======
float nearestTP = na
float nearestDistPrice = na
float nearestDistPct = na
float risk_pct = na
float reward_pct = na
float rr = na
var float tps = array.new_float()
array.clear(tps)
if use_tp1 and tp1 > 0
array.push(tps, tp1)
if use_tp2 and tp2 > 0
array.push(tps, tp2)
if use_tp3 and tp3 > 0
array.push(tps, tp3)
if use_tp4 and tp4 > 0
array.push(tps, tp4)
if use_tp5 and tp5 > 0
array.push(tps, tp5)
// nearest target in the trade direction (from current price)
if array.size(tps) > 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
cond = side=="Long" ? (_tp > close) : (_tp < close)
if cond
distP = math.abs(_tp - close)
if na(nearestDistPrice) or distP < nearestDistPrice
nearestDistPrice := distP
nearestTP := _tp
if not na(nearestDistPrice) and close != 0
nearestDistPct := (nearestDistPrice / close) * 100.0
float stop = stop_inp > 0 ? stop_inp : na
if not na(wAvgEntry) and not na(stop)
rawRisk = (side=="Long" ? (stop - wAvgEntry) : (wAvgEntry - stop)) / wAvgEntry * 100.0
risk_pct := math.abs(rawRisk)
if not na(wAvgEntry) and not na(nearestTP)
reward_pct := math.abs((side=="Long" ? (nearestTP - wAvgEntry) : (wAvgEntry - nearestTP)) / wAvgEntry * 100.0)
rr := (not na(risk_pct) and not na(reward_pct) and risk_pct != 0) ? reward_pct / risk_pct : na
// ====== Average R:R across all valid targets ======
float rr_avg = na
if not na(wAvgEntry) and not na(stop) and array.size(tps) > 0 and not na(risk_pct) and risk_pct != 0
float sum_rr = 0.0
int cnt_rr = 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
bool validDir = side=="Long" ? (_tp > wAvgEntry) : (_tp < wAvgEntry)
if validDir
_reward = math.abs((side=="Long" ? (_tp - wAvgEntry) : (wAvgEntry - _tp)) / wAvgEntry * 100.0)
_rr = _reward / risk_pct
sum_rr += _rr
cnt_rr += 1
rr_avg := cnt_rr > 0 ? (sum_rr / cnt_rr) : na
// ====== Entry/SL/TP Lines ======
var line entryLines = array.new_line(4, na)
for i = 0 to 3
ln = array.get(entryLines, i)
if array.get(ens, i) and array.get(entries, i) > 0
col = array.get(entryCols, i)
ent = array.get(entries, i)
ln := f_stickyHLine(ent, ln, col, 2)
array.set(entryLines, i, ln)
else
if not na(ln)
line.delete(ln)
array.set(entryLines, i, na)
var line slLine = na
if not na(stop)
slLine := f_stickyHLine(stop, slLine, color.new(color.red, 0), 1)
else
if not na(slLine)
line.delete(slLine)
slLine := na
var line tpLine1 = na
var line tpLine2 = na
var line tpLine3 = na
var line tpLine4 = na
var line tpLine5 = na
if use_tp1 and tp1 > 0
tpLine1 := f_stickyHLine(tp1, tpLine1, color.new(color.teal, 0), 1)
else
if not na(tpLine1)
line.delete(tpLine1)
tpLine1 := na
if use_tp2 and tp2 > 0
tpLine2 := f_stickyHLine(tp2, tpLine2, color.new(color.teal, 0), 1)
else
if not na(tpLine2)
line.delete(tpLine2)
tpLine2 := na
if use_tp3 and tp3 > 0
tpLine3 := f_stickyHLine(tp3, tpLine3, color.new(color.teal, 0), 1)
else
if not na(tpLine3)
line.delete(tpLine3)
tpLine3 := na
if use_tp4 and tp4 > 0
tpLine4 := f_stickyHLine(tp4, tpLine4, color.new(color.teal, 0), 1)
else
if not na(tpLine4)
line.delete(tpLine4)
tpLine4 := na
if use_tp5 and tp5 > 0
tpLine5 := f_stickyHLine(tp5, tpLine5, color.new(color.teal, 0), 1)
else
if not na(tpLine5)
line.delete(tpLine5)
tpLine5 := na
// ====== Build HUD Text ======
string txt = ""
// Per-entry rows
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
idx = i + 1
ent = array.get(entries, i)
pct = array.get(pcts, i)
pnlq = array.get(pnls, i)
roi = array.get(rois, i)
levX = array.get(levs, i)
txt += (txt=="" ? "" : " ") + "📌 Entry " + str.tostring(idx) + ": " + str.tostring(ent, format.mintick)
txt += " 📊 Live: " + (na(pct) ? "—" : str.tostring(pct, format.mintick) + "%") + " | 💵 " + (na(pnlq) ? "—" : "$" + f_usd_str(pnlq, usd_dp))
txt += " 🧮 ROI(x" + str.tostring(levX) + "): " + (na(roi) ? "—" : str.tostring(roi, format.mintick) + "%")
// Summary or test HUD
if txt != ""
if totalQty > 0
txt += " — — —"
txt += " ⚖️ Weighted Avg Entry: " + str.tostring(wAvgEntry, format.mintick)
if not na(stop)
txt += " ❌ SL: " + str.tostring(stop, format.mintick)
// Nearest target (from current price)
string tpInfo = "—"
if not na(nearestTP)
tpInfo := str.tostring(nearestTP, format.mintick) + (na(nearestDistPct) ? "" : " (Δ " + str.tostring(nearestDistPct, format.mintick) + "%)")
txt += " 🎯 Nearest: " + tpInfo
// R:R (nearest)
if not na(rr)
txt += " 📐 R:R (nearest): " + str.tostring(rr, format.mintick)
// Avg R:R across all valid TPs (by direction from weighted entry)
if not na(rr_avg)
txt += " 📐 Avg R:R (all valid TPs): " + str.tostring(rr_avg, format.mintick)
// Totals
txt += " 🧾 Total P/L: " + "$" + f_usd_str(totalPnlUSD, usd_dp)
txt += " 🧮 Weighted ROI (by Notional): " + (na(totalROIweighted) ? "—" : str.tostring(totalROIweighted, format.mintick) + "%")
else if force_show_hud
txt := "🧪 HUD is active. Fill Entry prices or tick ⚡. Enable TP/SL to see lines."
// ====== HUD Placement (near live price) ======
var label hud = na
atr_val = nz(ta.atr(atr_len), 0.0)
anchor_price = close
y_pos = na(anchor_price) ? na : anchor_price + (atr_val * hud_off_atr)
x_pos_base = bar_index
off = hud_side == "Right of price" ? hud_off_bars : -hud_off_bars
x_pos = lock_to_last_bar ? (barstate.islast ? (x_pos_base + off) : x_pos_base) : (x_pos_base + off)
// Pick label style by side:
// - Right of price → pointer on LEFT edge → style_label_left
// - Left of price → pointer on RIGHT edge → style_label_right
label_style = hud_side == "Right of price" ? label.style_label_left : label.style_label_right
if not na(y_pos) and txt != ""
if na(hud)
hud := label.new(x_pos, y_pos, txt, xloc=xloc.bar_index, style=label_style, textcolor=hud_txtc, color=hud_bg, size=to_size(hud_font))
else
label.set_x(hud, x_pos)
label.set_y(hud, y_pos)
label.set_text(hud, txt)
label.set_textcolor(hud, hud_txtc)
label.set_color(hud, hud_bg)
label.set_style(hud, label_style)
label.set_size(hud, to_size(hud_font))
else
if not na(hud)
label.delete(hud)
hud := na
P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R//@version=6
indicator("P/L Panel + Multi Targets (4 Entries) – HUD near Price + Avg R:R", overlay=true, max_lines_count=500, max_labels_count=500)
// ====== General ======
side = input.string("Long", "Position Side", options= )
usd_dp = input.int(2, "USD decimals", minval=0, maxval=6)
// ====== HUD Settings ======
hud_font = input.string("large", "HUD font size", options= )
hud_bg = input.color(color.new(color.black, 0), "HUD background color")
hud_txtc = input.color(color.white, "HUD text color")
hud_side = input.string("Right of price", "HUD side", options= )
hud_off_bars = input.int(3, "Horizontal offset (bars)", minval=0, maxval=50)
hud_off_atr = input.float(0.2, "Vertical offset from price (ATR)", step=0.1)
atr_len = input.int(14, "ATR length for vertical offset", minval=1)
lock_to_last_bar = input.bool(true, "Lock HUD to the last bar")
// Show HUD even when there are no entries (test text)
force_show_hud = input.bool(true, "🔍 Show HUD even with no entries")
// ====== Shared SL & Targets ======
stop_inp = input.float(0.0, "Stop Loss (shared, optional)", step=0.0001)
use_tp1 = input.bool(false, "Enable Target 1")
tp1 = input.float(0.0, "Target 1 price", step=0.0001)
use_tp2 = input.bool(false, "Enable Target 2")
tp2 = input.float(0.0, "Target 2 price", step=0.0001)
use_tp3 = input.bool(false, "Enable Target 3")
tp3 = input.float(0.0, "Target 3 price", step=0.0001)
use_tp4 = input.bool(false, "Enable Target 4")
tp4 = input.float(0.0, "Target 4 price", step=0.0001)
use_tp5 = input.bool(false, "Enable Target 5")
tp5 = input.float(0.0, "Target 5 price", step=0.0001)
// ====== Four Independent Entries ======
group1 = "Entry 1"
en1 = input.bool(true, "Enable Entry 1", inline=group1)
lev1 = input.int(10, "Leverage", minval=1, maxval=200, inline=group1)
entry1 = input.float(0.0, "Entry 1 price", step=0.0001)
set_now1 = input.bool(false, "⚡ Set Entry1 = Current Price")
mode1 = input.string("USD (USDT)", "Size unit 1", options= )
sem1 = input.string("Margin (apply leverage)", "Size meaning 1", options= )
size1 = input.float(0.0, "Position size 1", step=0.0001)
baseLev1 = input.bool(false, "Apply leverage to 'Coin Quantity' (1)")
group2 = "Entry 2"
en2 = input.bool(false, "Enable Entry 2", inline=group2)
lev2 = input.int(10, "Leverage", minval=1, maxval=200, inline=group2)
entry2 = input.float(0.0, "Entry 2 price", step=0.0001)
set_now2 = input.bool(false, "⚡ Set Entry2 = Current Price")
mode2 = input.string("USD (USDT)", "Size unit 2", options= )
sem2 = input.string("Margin (apply leverage)", "Size meaning 2", options= )
size2 = input.float(0.0, "Position size 2", step=0.0001)
baseLev2 = input.bool(false, "Apply leverage to 'Coin Quantity' (2)")
group3 = "Entry 3"
en3 = input.bool(false, "Enable Entry 3", inline=group3)
lev3 = input.int(10, "Leverage", minval=1, maxval=200, inline=group3)
entry3 = input.float(0.0, "Entry 3 price", step=0.0001)
set_now3 = input.bool(false, "⚡ Set Entry3 = Current Price")
mode3 = input.string("USD (USDT)", "Size unit 3", options= )
sem3 = input.string("Margin (apply leverage)", "Size meaning 3", options= )
size3 = input.float(0.0, "Position size 3", step=0.0001)
baseLev3 = input.bool(false, "Apply leverage to 'Coin Quantity' (3)")
group4 = "Entry 4"
en4 = input.bool(false, "Enable Entry 4", inline=group4)
lev4 = input.int(10, "Leverage", minval=1, maxval=200, inline=group4)
entry4 = input.float(0.0, "Entry 4 price", step=0.0001)
set_now4 = input.bool(false, "⚡ Set Entry4 = Current Price")
mode4 = input.string("USD (USDT)", "Size unit 4", options= )
sem4 = input.string("Margin (apply leverage)", "Size meaning 4", options= )
size4 = input.float(0.0, "Position size 4", step=0.0001)
baseLev4 = input.bool(false, "Apply leverage to 'Coin Quantity' (4)")
// Quick set entries = current price
entry1 := (en1 and set_now1) ? close : entry1
entry2 := (en2 and set_now2) ? close : entry2
entry3 := (en3 and set_now3) ? close : entry3
entry4 := (en4 and set_now4) ? close : entry4
// ====== Helpers ======
to_size(s) =>
s == "tiny" ? size.tiny : s == "small" ? size.small : s == "normal" ? size.normal : s == "large" ? size.large : size.huge
f_usd_str(_val, _decimals) =>
na(_val) ? "—" : str.tostring(math.round(_val * math.pow(10, _decimals)) / math.pow(10, _decimals))
f_qty_base(mode, sem, size, entry, baseLev, lev) =>
float _qty = na
if mode == "USD (USDT)"
_qty := (size > 0 and entry > 0) ? ((sem == "Margin (apply leverage)" ? size * lev : size) / entry) : na
else
_qty := size > 0 ? (baseLev ? size * lev : size) : na
_qty
f_notional_quote(mode, sem, size, entry, lev, baseLev) =>
if mode == "USD (USDT)"
sem == "Margin (apply leverage)" ? size * lev : size
else
(baseLev ? size * lev : size) * entry
f_pnl_quote(side, entry, qty) =>
na(qty) or na(entry) ? na : (side=="Long" ? (close - entry) : (entry - close)) * qty
f_pct(side, entry) =>
na(entry) ? na : ((close - entry) / entry * 100.0) * (side=="Long" ? 1 : -1)
f_roi_pct(side, entry, lev) =>
na(entry) ? na : f_pct(side, entry) * lev
// NOTE: _lineIn must be a line, not a float
f_stickyHLine(_price, _lineIn, _color, _width) =>
var line _out = na
_out := _lineIn
if na(_out)
_out := line.new(bar_index-1, _price, bar_index+1, _price, xloc=xloc.bar_index, extend=extend.both, width=_width, style=line.style_dashed, color=_color)
else
line.set_xy1(_out, bar_index-1, _price)
line.set_xy2(_out, bar_index+1, _price)
line.set_color(_out, _color)
line.set_width(_out, _width)
_out
// ====== 4 Entries Calculations ======
var color entryCols = array.from(color.new(color.yellow, 0), color.new(color.orange, 0), color.new(color.teal, 0), color.new(color.fuchsia, 0))
bool ens = array.from(en1, en2, en3, en4)
float entries = array.from(entry1, entry2, entry3, entry4)
int levs = array.from(lev1, lev2, lev3, lev4)
string modes = array.from(mode1, mode2, mode3, mode4)
string sems = array.from(sem1, sem2, sem3, sem4)
float sizes = array.from(size1, size2, size3, size4)
bool baseLevs = array.from(baseLev1, baseLev2, baseLev3, baseLev4)
float qtys = array.new_float(4, na)
float pnls = array.new_float(4, na)
float pcts = array.new_float(4, na)
float rois = array.new_float(4, na)
float notionals = array.new_float(4, na)
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
ent = array.get(entries, i)
levX = array.get(levs, i)
modeX= array.get(modes, i)
semX = array.get(sems, i)
sizeX= array.get(sizes, i)
bLev = array.get(baseLevs, i)
qty = f_qty_base(modeX, semX, sizeX, ent, bLev, levX)
array.set(qtys, i, qty)
pnlq = f_pnl_quote(side, ent, qty)
array.set(pnls, i, pnlq)
pct = f_pct(side, ent)
array.set(pcts, i, pct)
roi = f_roi_pct(side, ent, levX)
array.set(rois, i, roi)
notq = f_notional_quote(modeX, semX, sizeX, ent, levX, bLev)
array.set(notionals, i, notq)
// ====== Totals & Weighted Avg Entry ======
float totalPnlUSD = 0.0
float totalNotional = 0.0
float totalQty = 0.0
float wAvgEntry = na
for i = 0 to 3
if not na(array.get(pnls, i))
totalPnlUSD += array.get(pnls, i)
if not na(array.get(notionals, i))
totalNotional += array.get(notionals, i)
if not na(array.get(qtys, i)) and array.get(entries, i) > 0
totalQty += array.get(qtys, i)
if totalQty > 0
num = 0.0
for i = 0 to 3
qi = array.get(qtys, i)
ei = array.get(entries, i)
if not na(qi) and ei > 0
num += qi * ei
wAvgEntry := num / totalQty
totalROIweighted = totalNotional > 0 ? (totalPnlUSD / totalNotional) * 100.0 : na
// ====== Nearest TP & R:R ======
float nearestTP = na
float nearestDistPrice = na
float nearestDistPct = na
float risk_pct = na
float reward_pct = na
float rr = na
var float tps = array.new_float()
array.clear(tps)
if use_tp1 and tp1 > 0
array.push(tps, tp1)
if use_tp2 and tp2 > 0
array.push(tps, tp2)
if use_tp3 and tp3 > 0
array.push(tps, tp3)
if use_tp4 and tp4 > 0
array.push(tps, tp4)
if use_tp5 and tp5 > 0
array.push(tps, tp5)
// nearest target in the trade direction (from current price)
if array.size(tps) > 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
cond = side=="Long" ? (_tp > close) : (_tp < close)
if cond
distP = math.abs(_tp - close)
if na(nearestDistPrice) or distP < nearestDistPrice
nearestDistPrice := distP
nearestTP := _tp
if not na(nearestDistPrice) and close != 0
nearestDistPct := (nearestDistPrice / close) * 100.0
float stop = stop_inp > 0 ? stop_inp : na
if not na(wAvgEntry) and not na(stop)
rawRisk = (side=="Long" ? (stop - wAvgEntry) : (wAvgEntry - stop)) / wAvgEntry * 100.0
risk_pct := math.abs(rawRisk)
if not na(wAvgEntry) and not na(nearestTP)
reward_pct := math.abs((side=="Long" ? (nearestTP - wAvgEntry) : (wAvgEntry - nearestTP)) / wAvgEntry * 100.0)
rr := (not na(risk_pct) and not na(reward_pct) and risk_pct != 0) ? reward_pct / risk_pct : na
// ====== Average R:R across all valid targets ======
float rr_avg = na
if not na(wAvgEntry) and not na(stop) and array.size(tps) > 0 and not na(risk_pct) and risk_pct != 0
float sum_rr = 0.0
int cnt_rr = 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
bool validDir = side=="Long" ? (_tp > wAvgEntry) : (_tp < wAvgEntry)
if validDir
_reward = math.abs((side=="Long" ? (_tp - wAvgEntry) : (wAvgEntry - _tp)) / wAvgEntry * 100.0)
_rr = _reward / risk_pct
sum_rr += _rr
cnt_rr += 1
rr_avg := cnt_rr > 0 ? (sum_rr / cnt_rr) : na
// ====== Entry/SL/TP Lines ======
var line entryLines = array.new_line(4, na)
for i = 0 to 3
ln = array.get(entryLines, i)
if array.get(ens, i) and array.get(entries, i) > 0
col = array.get(entryCols, i)
ent = array.get(entries, i)
ln := f_stickyHLine(ent, ln, col, 2)
array.set(entryLines, i, ln)
else
if not na(ln)
line.delete(ln)
array.set(entryLines, i, na)
var line slLine = na
if not na(stop)
slLine := f_stickyHLine(stop, slLine, color.new(color.red, 0), 1)
else
if not na(slLine)
line.delete(slLine)
slLine := na
var line tpLine1 = na
var line tpLine2 = na
var line tpLine3 = na
var line tpLine4 = na
var line tpLine5 = na
if use_tp1 and tp1 > 0
tpLine1 := f_stickyHLine(tp1, tpLine1, color.new(color.teal, 0), 1)
else
if not na(tpLine1)
line.delete(tpLine1)
tpLine1 := na
if use_tp2 and tp2 > 0
tpLine2 := f_stickyHLine(tp2, tpLine2, color.new(color.teal, 0), 1)
else
if not na(tpLine2)
line.delete(tpLine2)
tpLine2 := na
if use_tp3 and tp3 > 0
tpLine3 := f_stickyHLine(tp3, tpLine3, color.new(color.teal, 0), 1)
else
if not na(tpLine3)
line.delete(tpLine3)
tpLine3 := na
if use_tp4 and tp4 > 0
tpLine4 := f_stickyHLine(tp4, tpLine4, color.new(color.teal, 0), 1)
else
if not na(tpLine4)
line.delete(tpLine4)
tpLine4 := na
if use_tp5 and tp5 > 0
tpLine5 := f_stickyHLine(tp5, tpLine5, color.new(color.teal, 0), 1)
else
if not na(tpLine5)
line.delete(tpLine5)
tpLine5 := na
// ====== Build HUD Text ======
string txt = ""
// Per-entry rows
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
idx = i + 1
ent = array.get(entries, i)
pct = array.get(pcts, i)
pnlq = array.get(pnls, i)
roi = array.get(rois, i)
levX = array.get(levs, i)
txt += (txt=="" ? "" : " ") + "📌 Entry " + str.tostring(idx) + ": " + str.tostring(ent, format.mintick)
txt += " 📊 Live: " + (na(pct) ? "—" : str.tostring(pct, format.mintick) + "%") + " | 💵 " + (na(pnlq) ? "—" : "$" + f_usd_str(pnlq, usd_dp))
txt += " 🧮 ROI(x" + str.tostring(levX) + "): " + (na(roi) ? "—" : str.tostring(roi, format.mintick) + "%")
// Summary or test HUD
if txt != ""
if totalQty > 0
txt += " — — —"
txt += " ⚖️ Weighted Avg Entry: " + str.tostring(wAvgEntry, format.mintick)
if not na(stop)
txt += " ❌ SL: " + str.tostring(stop, format.mintick)
// Nearest target (from current price)
string tpInfo = "—"
if not na(nearestTP)
tpInfo := str.tostring(nearestTP, format.mintick) + (na(nearestDistPct) ? "" : " (Δ " + str.tostring(nearestDistPct, format.mintick) + "%)")
txt += " 🎯 Nearest: " + tpInfo
// R:R (nearest)
if not na(rr)
txt += " 📐 R:R (nearest): " + str.tostring(rr, format.mintick)
// Avg R:R across all valid TPs (by direction from weighted entry)
if not na(rr_avg)
txt += " 📐 Avg R:R (all valid TPs): " + str.tostring(rr_avg, format.mintick)
// Totals
txt += " 🧾 Total P/L: " + "$" + f_usd_str(totalPnlUSD, usd_dp)
txt += " 🧮 Weighted ROI (by Notional): " + (na(totalROIweighted) ? "—" : str.tostring(totalROIweighted, format.mintick) + "%")
else if force_show_hud
txt := "🧪 HUD is active. Fill Entry prices or tick ⚡. Enable TP/SL to see lines."
// ====== HUD Placement (near live price) ======
var label hud = na
atr_val = nz(ta.atr(atr_len), 0.0)
anchor_price = close
y_pos = na(anchor_price) ? na : anchor_price + (atr_val * hud_off_atr)
x_pos_base = bar_index
off = hud_side == "Right of price" ? hud_off_bars : -hud_off_bars
x_pos = lock_to_last_bar ? (barstate.islast ? (x_pos_base + off) : x_pos_base) : (x_pos_base + off)
// Pick label style by side:
// - Right of price → pointer on LEFT edge → style_label_left
// - Left of price → pointer on RIGHT edge → style_label_right
label_style = hud_side == "Right of price" ? label.style_label_left : label.style_label_right
if not na(y_pos) and txt != ""
if na(hud)
hud := label.new(x_pos, y_pos, txt, xloc=xloc.bar_index, style=label_style, textcolor=hud_txtc, color=hud_bg, size=to_size(hud_font))
else
label.set_x(hud, x_pos)
label.set_y(hud, y_pos)
label.set_text(hud, txt)
label.set_textcolor(hud, hud_txtc)
label.set_color(hud, hud_bg)
label.set_style(hud, label_style)
label.set_size(hud, to_size(hud_font))
else
if not na(hud)
label.delete(hud)
hud := na
پنل سود/زیان + چند تارگت R:R//@version=6
indicator("پنل سود/زیان + چند تارگت (۴ ورود مستقل) - پنل چپ نزدیک قیمت + میانگین R:R", overlay=true, max_lines_count=500, max_labels_count=500)
// ====== تنظیمات عمومی ======
side = input.string("لانگ", "نوع پوزیشن", options= )
usd_dp = input.int(2, "تعداد اعشار نمایش دلار", minval=0, maxval=6)
// ====== تنظیمات پنل ======
hud_font = input.string("large", "اندازۀ فونت پنل", options= )
hud_bg = input.color(color.new(color.black, 0), "رنگ پسزمینه پنل")
hud_txtc = input.color(color.white, "رنگ متن پنل")
// محل پنل: کمی «چپِ» آخرین کندل + کمی فاصله عمودی از قیمت
hud_off_bars = input.int(3, "فاصلۀ افقی از قیمت به سمت چپ (تعداد کندل، فقط روی آخرین کندل)", minval=0, maxval=50)
hud_off_atr = input.float(0.2, "فاصلۀ عمودی از قیمت (ATR)", step=0.1)
atr_len = input.int(14, "طول ATR برای فاصله عمودی", minval=1)
// نمایش اجباری پنل حتی بدون ورود
force_show_hud = input.bool(true, "🔍 نمایش اجباری پنل حتی بدون ورود")
// ====== حد ضرر و تارگتهای مشترک ======
stop_inp = input.float(0.0, "حد ضرر (مشترک، اختیاری)", step=0.0001)
use_tp1 = input.bool(false, "فعالسازی تارگت ۱")
tp1 = input.float(0.0, "قیمت تارگت ۱", step=0.0001)
use_tp2 = input.bool(false, "فعالسازی تارگت ۲")
tp2 = input.float(0.0, "قیمت تارگت ۲", step=0.0001)
use_tp3 = input.bool(false, "فعالسازی تارگت ۳")
tp3 = input.float(0.0, "قیمت تارگت ۳", step=0.0001)
use_tp4 = input.bool(false, "فعالسازی تارگت ۴")
tp4 = input.float(0.0, "قیمت تارگت ۴", step=0.0001)
use_tp5 = input.bool(false, "فعالسازی تارگت ۵")
tp5 = input.float(0.0, "قیمت تارگت ۵", step=0.0001)
// ====== ورودیهای ۴ ورود مستقل ======
group1 = "ورود ۱"
en1 = input.bool(true, "فعالسازی ورود ۱", inline=group1)
lev1 = input.int(10, "لوریج", minval=1, maxval=200, inline=group1)
entry1 = input.float(0.0, "قیمت ورود ۱", step=0.0001)
set_now1 = input.bool(false, "⚡ ثبت ورود۱ = قیمت فعلی")
mode1 = input.string("دلاری (USDT)", "واحد اندازه ۱", options= )
sem1 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۱", options= )
size1 = input.float(0.0, "اندازه پوزیشن ۱", step=0.0001)
baseLev1 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۱)")
group2 = "ورود ۲"
en2 = input.bool(false, "فعالسازی ورود ۲", inline=group2)
lev2 = input.int(10, "لوریج", minval=1, maxval=200, inline=group2)
entry2 = input.float(0.0, "قیمت ورود ۲", step=0.0001)
set_now2 = input.bool(false, "⚡ ثبت ورود۲ = قیمت فعلی")
mode2 = input.string("دلاری (USDT)", "واحد اندازه ۲", options= )
sem2 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۲", options= )
size2 = input.float(0.0, "اندازه پوزیشن ۲", step=0.0001)
baseLev2 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۲)")
group3 = "ورود ۳"
en3 = input.bool(false, "فعالسازی ورود ۳", inline=group3)
lev3 = input.int(10, "لوریج", minval=1, maxval=200, inline=group3)
entry3 = input.float(0.0, "قیمت ورود ۳", step=0.0001)
set_now3 = input.bool(false, "⚡ ثبت ورود۳ = قیمت فعلی")
mode3 = input.string("دلاری (USDT)", "واحد اندازه ۳", options= )
sem3 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۳", options= )
size3 = input.float(0.0, "اندازه پوزیشن ۳", step=0.0001)
baseLev3 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۳)")
group4 = "ورود ۴"
en4 = input.bool(false, "فعالسازی ورود ۴", inline=group4)
lev4 = input.int(10, "لوریج", minval=1, maxval=200, inline=group4)
entry4 = input.float(0.0, "قیمت ورود ۴", step=0.0001)
set_now4 = input.bool(false, "⚡ ثبت ورود۴ = قیمت فعلی")
mode4 = input.string("دلاری (USDT)", "واحد اندازه ۴", options= )
sem4 = input.string("مارجین (اعمال لوریج)", "تعبیر اندازه ۴", options= )
size4 = input.float(0.0, "اندازه پوزیشن ۴", step=0.0001)
baseLev4 = input.bool(false, "اعمال لوریج روی حالت «تعداد کوین» (۴)")
// ثبت سریع ورود = قیمت فعلی
entry1 := (en1 and set_now1) ? close : entry1
entry2 := (en2 and set_now2) ? close : entry2
entry3 := (en3 and set_now3) ? close : entry3
entry4 := (en4 and set_now4) ? close : entry4
// ====== کمکتابعها ======
to_size(s) =>
s == "tiny" ? size.tiny : s == "small" ? size.small : s == "normal" ? size.normal : s == "large" ? size.large : size.huge
f_usd_str(_val, _decimals) =>
na(_val) ? "—" : str.tostring(math.round(_val * math.pow(10, _decimals)) / math.pow(10, _decimals))
f_qty_base(mode, sem, size, entry, baseLev, lev) =>
float _qty = na
if mode == "دلاری (USDT)"
_qty := (size > 0 and entry > 0) ? ((sem == "مارجین (اعمال لوریج)" ? size * lev : size) / entry) : na
else
_qty := size > 0 ? (baseLev ? size * lev : size) : na
_qty
f_notional_quote(mode, sem, size, entry, lev, baseLev) =>
if mode == "دلاری (USDT)"
sem == "مارجین (اعمال لوریج)" ? size * lev : size
else
(baseLev ? size * lev : size) * entry
f_pnl_quote(side, entry, qty) =>
na(qty) or na(entry) ? na : (side=="لانگ" ? (close - entry) : (entry - close)) * qty
f_pct(side, entry) =>
na(entry) ? na : ((close - entry) / entry * 100.0) * (side=="لانگ" ? 1 : -1)
f_roi_pct(side, entry, lev) =>
na(entry) ? na : f_pct(side, entry) * lev
f_stickyHLine(_price, _lineIn, _color, _width) =>
var line _out = na
_out := _lineIn
if na(_out)
_out := line.new(bar_index-1, _price, bar_index+1, _price, xloc=xloc.bar_index, extend=extend.both, width=_width, style=line.style_dashed, color=_color)
else
line.set_xy1(_out, bar_index-1, _price)
line.set_xy2(_out, bar_index+1, _price)
line.set_color(_out, _color)
line.set_width(_out, _width)
_out
// ====== محاسبات ۴ ورود ======
var color entryCols = array.from(color.new(color.yellow, 0), color.new(color.orange, 0), color.new(color.teal, 0), color.new(color.fuchsia, 0))
bool ens = array.from(en1, en2, en3, en4)
float entries = array.from(entry1, entry2, entry3, entry4)
int levs = array.from(lev1, lev2, lev3, lev4)
string modes = array.from(mode1, mode2, mode3, mode4)
string sems = array.from(sem1, sem2, sem3, sem4)
float sizes = array.from(size1, size2, size3, size4)
bool baseLevs = array.from(baseLev1, baseLev2, baseLev3, baseLev4)
float qtys = array.new_float(4, na)
float pnls = array.new_float(4, na)
float pcts = array.new_float(4, na)
float rois = array.new_float(4, na)
float notionals = array.new_float(4, na)
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
ent = array.get(entries, i)
levX = array.get(levs, i)
modeX= array.get(modes, i)
semX = array.get(sems, i)
sizeX= array.get(sizes, i)
bLev = array.get(baseLevs, i)
qty = f_qty_base(modeX, semX, sizeX, ent, bLev, levX)
array.set(qtys, i, qty)
pnlq = f_pnl_quote(side, ent, qty)
array.set(pnls, i, pnlq)
pct = f_pct(side, ent)
array.set(pcts, i, pct)
roi = f_roi_pct(side, ent, levX)
array.set(rois, i, roi)
notq = f_notional_quote(modeX, semX, sizeX, ent, levX, bLev)
array.set(notionals, i, notq)
// ====== مجموع و میانگین ورود وزنی ======
float totalPnlUSD = 0.0
float totalNotional = 0.0
float totalQty = 0.0
float wAvgEntry = na
for i = 0 to 3
if not na(array.get(pnls, i))
totalPnlUSD += array.get(pnls, i)
if not na(array.get(notionals, i))
totalNotional += array.get(notionals, i)
if not na(array.get(qtys, i)) and array.get(entries, i) > 0
totalQty += array.get(qtys, i)
if totalQty > 0
num = 0.0
for i = 0 to 3
qi = array.get(qtys, i)
ei = array.get(entries, i)
if not na(qi) and ei > 0
num += qi * ei
wAvgEntry := num / totalQty
totalROIweighted = totalNotional > 0 ? (totalPnlUSD / totalNotional) * 100.0 : na
// ====== نزدیکترین تارگت و R:R ======
float nearestTP = na
float nearestDistPrice = na
float nearestDistPct = na
float risk_pct = na
float reward_pct = na
float rr = na
var float tps = array.new_float()
array.clear(tps)
if use_tp1 and tp1 > 0
array.push(tps, tp1)
if use_tp2 and tp2 > 0
array.push(tps, tp2)
if use_tp3 and tp3 > 0
array.push(tps, tp3)
if use_tp4 and tp4 > 0
array.push(tps, tp4)
if use_tp5 and tp5 > 0
array.push(tps, tp5)
// نزدیکترین تارگت همسو با جهت
if array.size(tps) > 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
cond = side=="لانگ" ? (_tp > close) : (_tp < close)
if cond
distP = math.abs(_tp - close)
if na(nearestDistPrice) or distP < nearestDistPrice
nearestDistPrice := distP
nearestTP := _tp
if not na(nearestDistPrice) and close != 0
nearestDistPct := (nearestDistPrice / close) * 100.0
float stop = stop_inp > 0 ? stop_inp : na
if not na(wAvgEntry) and not na(stop)
rawRisk = (side=="لانگ" ? (stop - wAvgEntry) : (wAvgEntry - stop)) / wAvgEntry * 100.0
risk_pct := math.abs(rawRisk)
if not na(wAvgEntry) and not na(nearestTP)
reward_pct := math.abs((side=="لانگ" ? (nearestTP - wAvgEntry) : (wAvgEntry - nearestTP)) / wAvgEntry * 100.0)
rr := (not na(risk_pct) and not na(reward_pct) and risk_pct != 0) ? reward_pct / risk_pct : na
// ====== «میانگین R:R» روی همه تارگتهای معتبر ======
float rr_avg = na
if not na(wAvgEntry) and not na(stop) and array.size(tps) > 0 and not na(risk_pct) and risk_pct != 0
float sum_rr = 0.0
int cnt_rr = 0
for i = 0 to array.size(tps) - 1
_tp = array.get(tps, i)
bool validDir = side=="لانگ" ? (_tp > wAvgEntry) : (_tp < wAvgEntry)
if validDir
_reward = math.abs((side=="لانگ" ? (_tp - wAvgEntry) : (wAvgEntry - _tp)) / wAvgEntry * 100.0)
_rr = _reward / risk_pct
sum_rr += _rr
cnt_rr += 1
rr_avg := cnt_rr > 0 ? (sum_rr / cnt_rr) : na
// ====== خطوط ورود/SL/TP ======
var line entryLines = array.new_line(4, na)
for i = 0 to 3
ln = array.get(entryLines, i)
if array.get(ens, i) and array.get(entries, i) > 0
col = array.get(entryCols, i)
ent = array.get(entries, i)
ln := f_stickyHLine(ent, ln, col, 2)
array.set(entryLines, i, ln)
else
if not na(ln)
line.delete(ln)
array.set(entryLines, i, na)
var line slLine = na
if not na(stop)
slLine := f_stickyHLine(stop, slLine, color.new(color.red, 0), 1)
else
if not na(slLine)
line.delete(slLine)
slLine := na
var line tpLine1 = na
var line tpLine2 = na
var line tpLine3 = na
var line tpLine4 = na
var line tpLine5 = na
if use_tp1 and tp1 > 0
tpLine1 := f_stickyHLine(tp1, tpLine1, color.new(color.teal, 0), 1)
else
if not na(tpLine1)
line.delete(tpLine1)
tpLine1 := na
if use_tp2 and tp2 > 0
tpLine2 := f_stickyHLine(tp2, tpLine2, color.new(color.teal, 0), 1)
else
if not na(tpLine2)
line.delete(tpLine2)
tpLine2 := na
if use_tp3 and tp3 > 0
tpLine3 := f_stickyHLine(tp3, tpLine3, color.new(color.teal, 0), 1)
else
if not na(tpLine3)
line.delete(tpLine3)
tpLine3 := na
if use_tp4 and tp4 > 0
tpLine4 := f_stickyHLine(tp4, tpLine4, color.new(color.teal, 0), 1)
else
if not na(tpLine4)
line.delete(tpLine4)
tpLine4 := na
if use_tp5 and tp5 > 0
tpLine5 := f_stickyHLine(tp5, tpLine5, color.new(color.teal, 0), 1)
else
if not na(tpLine5)
line.delete(tpLine5)
tpLine5 := na
// ====== ساخت متن پنل ======
string txt = ""
// ردیفهای هر ورود
for i = 0 to 3
if array.get(ens, i) and array.get(entries, i) > 0
idx = i + 1
ent = array.get(entries, i)
pct = array.get(pcts, i)
pnlq = array.get(pnls, i)
roi = array.get(rois, i)
levX = array.get(levs, i)
txt += (txt=="" ? "" : " ") + "📌 ورود " + str.tostring(idx) + ": " + str.tostring(ent, format.mintick)
txt += " 📊 لحظهای: " + (na(pct) ? "—" : str.tostring(pct, format.mintick) + "%") + " | 💵 " + (na(pnlq) ? "—" : "$" + f_usd_str(pnlq, usd_dp))
txt += " 🧮 ROI(x" + str.tostring(levX) + "): " + (na(roi) ? "—" : str.tostring(roi, format.mintick) + "%")
// خلاصه پایانی یا پنل تست
if txt != ""
if totalQty > 0
txt += " — — —"
txt += " ⚖️ میانگین ورود وزنی: " + str.tostring(wAvgEntry, format.mintick)
if not na(stop)
txt += " ❌ SL: " + str.tostring(stop, format.mintick)
// نزدیکترین تارگت
string tpInfo = "—"
if not na(nearestTP)
tpInfo := str.tostring(nearestTP, format.mintick) + (na(nearestDistPct) ? "" : " (Δ " + str.tostring(nearestDistPct, format.mintick) + "%)")
txt += " 🎯 نزدیکترین: " + tpInfo
// R:R نزدیکترین
if not na(rr)
txt += " 📐 R:R نزدیکترین: " + str.tostring(rr, format.mintick)
// میانگین R:R روی همه تارگتهای معتبر
if not na(rr_avg)
txt += " 📐 میانگین R:R (همۀ تارگتهای معتبر): " + str.tostring(rr_avg, format.mintick)
// مجموعها
txt += " 🧾 مجموع سود/زیان: " + "$" + f_usd_str(totalPnlUSD, usd_dp)
txt += " 🧮 ROĪ وزنی (بر اساس ناتیونال): " + (na(totalROIweighted) ? "—" : str.tostring(totalROIweighted, format.mintick) + "%")
else if force_show_hud
txt := "🧪 پنل فعال است. از فیلدهای «قیمت ورود» استفاده کن یا تیکهای ⚡ را بزن. برای دیدن TP/SL خطوط، تیکهای مربوطه را فعال کن."
// ====== HUD (پنل سمت چپ، نوک اشاره نزدیک قیمت لحظهای) ======
// ====== HUD (پنل سمت راست، نوک اشاره نزدیک قیمت لحظهای) ======
var label hud = na
atr_val = ta.atr(atr_len)
// لنگر عمودی روی قیمت لحظهای با کمی فاصله عمودی
anchor_price = close
y_pos = na(anchor_price) ? na : anchor_price + (atr_val * hud_off_atr)
// فقط روی آخرین کندل، چند بار به «راست» میبریم تا نوک پنل نزدیک کندل باشد
x_pos_base = bar_index
x_pos = barstate.islast ? (x_pos_base + hud_off_bars) : x_pos_base
if not na(y_pos) and txt != ""
if na(hud)
// ⚠️ style_label_left = نوک پنل سمت چپ است ⇒ متن به راست باز میشود ⇒ کل پنل در «راستِ» قیمت قرار میگیرد
hud := label.new(x_pos, y_pos, txt,xloc=xloc.bar_index,style=label.style_label_left, textcolor=hud_txtc, color=hud_bg, size=to_size(hud_font))
else
label.set_x(hud, x_pos)
label.set_y(hud, y_pos)
label.set_text(hud, txt)
label.set_textcolor(hud, hud_txtc)
label.set_color(hud, hud_bg)
label.set_style(hud, label.style_label_left)
label.set_size(hud, to_size(hud_font))
else
if not na(hud)
label.delete(hud)
hud := na