Reversal Point Dynamics

DskyzInvestments · study · 633 行 · 点赞 3,705 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

//@version=5
indicator("Reversal Point Dynamics",shorttitle="⇋ RPD",overlay=true,max_bars_back=5000,precision=4,max_labels_count=500,max_lines_count=500,max_boxes_count=500)
//==============================================================================
// 📚 COMPREHENSIVE USER GUIDE & CONCEPTUAL FRAMEWORK
//==============================================================================
//
// Reversal Point Dynamics - PROBABILITY-BASED REVERSAL ENGINE (Enhanced Real-Time Version)
//
// Welcome to Reversal Point Dynamics (RPD), a sophisticated trading algorithm designed to
// identify high-probability market turning points. RPD moves beyond simple
// overbought/oversold indicators by calculating a quantifiable "Probability Score"
// for every potential reversal.
//
// ⚡ WHAT MAKES THIS DIFFERENT:
//
// Traditional indicators provide signals. RPD provides a multi-faceted decision framework.
//
// 1. PROBABILITY-BASED SIGNALS:
// - Instead of just a "buy" or "sell" arrow, RPD computes a probability percentage (0-99%)
// that the current candle is a peak or valley. Only signals surpassing a user-defined
// minProbability are shown.
//
// 2. ADAPTIVE ANALYSIS ENGINE:
// - RPD's core feature. It analyzes recent performance and market conditions
// in real-time. If conditions are favorable, it can boost signal confidence. If not,
// it becomes more selective to protect capital.
//
// 3. MULTI-FACTOR CONFLUENCE CORE:
// - The core probability score is derived from a confluence of momentum, volatility, and price
// action analysis over the Adaptive Analysis Period. It looks for conditions where momentum is
// exhausted and volatility suggests a turn.
//
// 4. INTELLIGENT ENTROPY & VOLUME FILTERS:
// - Automatically disqualifies signals in disordered, high-entropy markets (Entropy Threshold).
// - Validates signals with significant volume spikes, ensuring there is conviction
// behind the potential reversal (Volume Filter).
//
// 5. STATE ANALYSIS BALANCING:
// - Acknowledges that bull and bear markets behave differently. Users can adjust sensitivity
// for peak (short) and valley (long) signals via state levels and edge sensitivity.
//
// 6. LIVE SIGNAL MODE (NEW):
// - Enables intra-bar signal projection for no-lag detection. Tentative signals on current bar are marked '!' and confirm on close.
//
// 7. FIBONACCI TARGET ENGINE (NEW):
// - Displays adaptive Fibonacci levels (8,13,21,34,55 periods) for targets and support/resistance.
// - Active Fib Channel: Green zone post-signal for entry area, with red stop zone.
// - Static R2R Zone: 3 static fib lines on signal for risk-to-reward visualization, disappear on breach.
//
// 8. ENHANCED VISUALS (NEW):
// - Harmonic Wave: Smoothed bands around price for flow visualization.
// - Entropy Particles: Dynamic dots indicating flow strength and direction.
//
// 🎯 HUD & KEY METRICS DEEP DIVE:
//
// The Dashboard displays the engine's internal calculations, giving you full transparency. Size options (Small/Normal/Large) show progressive info.
//
// 📈 PROBABILITY SCORE (%):
// Mathematical Basis: A weighted composite score of multiple internal metrics, normalized to a 0-99% scale.
// • Measures the real-time confidence of a potential turning point.
// • > minProbability: A valid signal is triggered.
// • High Score (e.g., 90%+): Indicates a very strong confluence of factors for a reversal.
//
// 🎯 TREND DIRECTION:
// Mathematical Basis: Derived from Supertrend calculations.
// • The core metric for aligning signals with market trend.
// • A signal is more likely if it aligns with a trend flip.
 
// 🌪️ ENTROPY:
// Mathematical Basis: A measure of market order/disorder based on price changes.
// • Measures market choppiness.
// • Low Value: Ordered, directional price action (good for signals).
// • High Value: Disordered, choppy price action (bad for signals, filter will engage).
 
// 🧮 THE MATHEMATICS IN BRIEF:
//
// The final signal is a result of a multi-stage calculation:
//
// 1. BASE SCORE CALCULATION:
// - The engine analyzes price action, momentum (PSR velocity/acceleration), and volatility metrics within the Adaptive Analysis Period.
// - It identifies exhaustion patterns (e.g., slowing momentum at price extremes) to generate a raw BaseScore.
//
// 2. FILTER MODIFICATION:
// - The BaseScore is penalized or nullified if entropy exceeds the Entropy Threshold.
// - Volume and RSI bonuses are added if conditions are met.
 
// 3. STATE ANALYSIS MODIFICATION:
// - State levels divide the price range, and edge sensitivity determines how close to extremes a signal must be.
 
// 4. FINAL PROBABILITY:
// Probability = (BaseScore + Entropy Score + Divergence Bonus + RSI/Volume Bonuses)
// A signal is plotted IF Probability >= minProbability.
//
// 💡 TRADING PHILOSOPHY WITH RPD:
//
// Markets move in waves, creating peaks and valleys. RPD is not designed to catch every small move but to identify the most statistically probable turning points—the "turning points"—where the risk/reward is skewed in your favor. It operates on the principle of confluence and adaptive confirmation. A signal isn't just a pattern; it's a pattern that has been validated by entropy, volume, and state analysis.
 
// 🎯 HOW TO USE THIS INDICATOR:
//
// 1. SIGNAL IDENTIFICATION:
// - Primary signals are the Peak (▼) and Valley (▲) labels on the chart. These have already passed all internal checks.
// - Use the dashboard to see the Probability % of the signal. Higher is better.
//
// 2. CONTEXTUAL ANALYSIS (VIA DASHBOARD):
// - Check the Trend direction. Signals aligning with trend flips are stronger.
// - Note the Entropy and Volume Spike. Low entropy and spikes add confluence.
//
// 3. ENTRY & MANAGEMENT:
// - Consider entering after the signal candle closes.
// - Use the signal's location for stop-loss placement (e.g., above a Peak, below a Valley).
// - Profit targets can be based on Fibonacci levels or a fixed Risk/Reward ratio.
//
// 4. OPTIMIZATION & CUSTOMIZATION:
// - For volatile markets (Crypto), you may need a higher Adaptive Analysis Period and stricter Entropy Threshold.
// - For trending markets (Indices), adjust State Levels to focus on significant turns.
// - Monitor the dashboard for real-time feedback on metrics like RSI and Entropy.
//
// ⚠️ ADVANCED CONSIDERATIONS:
// • High-Impact News: No indicator can predict the outcome of fundamental events. Be cautious around major news releases.
// • Strong Trends: In a powerful, parabolic trend, reversal indicators will naturally struggle. RPD's filters and state analysis are designed to minimize false signals in these conditions, but no system is perfect. Use trend analysis to complement signals.
// • Parameter Tuning: While the defaults are robust, the ideal settings can vary by asset and timeframe. Use strategy testing to find optimal parameters for your specific use case.
 
//==================================================================
// INPUTS & ADVANCED SETTINGS
//==================================================================
groupCore = "🧠 Core Algorithm"
 
adaptivePeriod = input.int(25, "Adaptive Analysis Period", minval=5, maxval=100, group=groupCore, tooltip="🎯 WHAT IT IS: The primary lookback period for state analysis, momentum, and entropy calculations.\n\n⚡ HOW IT WORKS: Defines the number of past bars used to compute highs/lows, states, and entropy. Shorter periods are more responsive; longer ones provide broader context.\n\n📈 LONGER VALUES (50-100): Focuses on major turns, fewer signals. Good for swing trading.\n📉 SHORTER VALUES (5-20): More sensitive to local extremes, more signals. Ideal for scalping.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping (1-5min): 5-15.\n• Day Trading (15min-1H): 20-40.\n• Swing Trading (4H-1D): 50-100.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Crypto (Volatile): 10-30.\n• Stocks (Stable): 30-50.\n• Forex (Varied): 20-40.\n• Indices (Trending): 40-60.\n\n💡 PRO TIP: Start with 30 and adjust based on backtesting. Shorter periods increase signals but may add noise.")
fractalStrength = input.int(2, "Fractal Strength (Bars)", minval=1, maxval=5, group=groupCore, tooltip="🎯 WHAT IT IS: Defines the number of bars on each side for fractal pattern detection.\n\n⚡ HOW IT WORKS: Checks if the center bar is higher/lower than surrounding bars to identify fractals, enhancing pivot detection.\n\n📈 HIGHER VALUES (3-5): Stricter fractals, fewer but stronger signals.\n📉 LOWER VALUES (1-2): More sensitive, detects smaller patterns.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping (1-5min): 1-2 for quick patterns.\n• Day Trading (15min-1H): 2-3 for balance.\n• Swing Trading (4H-1D): 4-5 for major fractals.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Crypto (Volatile): Lower for micro-fractals.\n• Stocks (Stable): Higher for reliable patterns.\n• Forex (Varied): 2-3 standard.\n• Indices (Trending): Higher to filter noise.\n\n💡 PRO TIP: Pair with Predictive Mode; test 3 for most assets.")
mtfMultiplier = input.int(4, "MTF Multiplier (e.g., 4 for 4x TF)", minval=1, group=groupCore, tooltip="🎯 WHAT IT IS: Multiplier to derive a higher timeframe for multi-timeframe (MTF) analysis.\n\n⚡ HOW IT WORKS: Multiplies current timeframe (e.g., 1H * 4 = 4H) to incorporate higher TF pivots into signals.\n\n📈 HIGHER VALUES (4-8): Incorporates broader context, stronger confluence.\n📉 LOWER VALUES (1-3): Closer to current TF, more responsive but less filtered.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping (1-5min): 2-4 for quick MTF.\n• Day Trading (15min-1H): 4-6 for daily view.\n• Swing Trading (4H-1D): 2-4 for weekly.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Crypto (Volatile): Lower for speed.\n• Stocks (Stable): Higher for trend confirmation.\n• Forex (Varied): 4 standard.\n• Indices (Trending): Higher for macro view.\n\n💡 PRO TIP: Set to 4; align with your strategy's higher TF.")
groupSignal = "🎯 Signal Settings"
minProbThreshold = input.int(65, "Min Probability %", minval=50, maxval=95, group=groupSignal, tooltip="🎯 WHAT IT IS: The minimum probability score required for a signal to be displayed.\n\n⚡ HOW IT WORKS: Calculated score must exceed this threshold after factoring entropy, divergence, RSI, and volume.\n\n📈 HIGHER VALUES (80-95): Fewer, higher-quality signals.\n📉 LOWER VALUES (50-65): More signals, including lower-confidence ones.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping: 50-60 for more opportunities.\n• Swing Trading: 80-90 for reliability.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Volatile assets: Lower to capture quick turns.\n\n💡 PRO TIP: Set to 70 for balance; monitor dashboard for score trends.")
minSignalDistance = input.int(10, "Min Signal Distance (Bars)", minval=1, maxval=30, group=groupSignal, tooltip="🎯 WHAT IT IS: Minimum bars between consecutive signals to prevent clustering.\n\n⚡ HOW IT WORKS: Ensures signals are spaced out, avoiding noise in choppy markets.\n\n📈 HIGHER VALUES (10-20): Fewer signals, focuses on major turns.\n📉 LOWER VALUES (1-5): Allows closer signals for active trading.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Lower TFs: 3-5.\n• Higher TFs: 10-15.\n\n💡 PRO TIP: Use 5 for most cases; increase in ranging markets.")
entropyThreshold = input.float(0.85, "Entropy Threshold", minval=0.1, maxval=1.0, step=0.05, group=groupSignal, tooltip="🎯 WHAT IT IS: Threshold for market disorder; higher values allow signals in choppier conditions.\n\n⚡ HOW IT WORKS: Entropy measures price change randomness; signals require entropy below this for orderliness.\n\n📈 HIGHER VALUES (0.7-1.0): More lenient, more signals in varied conditions.\n📉 LOWER VALUES (0.1-0.4): Strict, only in highly ordered markets.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Volatile TFs: Higher to avoid missing turns.\n\n💡 PRO TIP: 0.6 is balanced; adjust based on asset volatility.")
groupState = "📊 State Analysis"
analysisLevels = input.int(6, "Analysis Levels", minval=3, maxval=9, group=groupState, tooltip="🎯 WHAT IT IS: Number of discrete levels for dividing the price range in state analysis.\n\n⚡ HOW IT WORKS: Price is quantized into these levels based on recent high/low; extremes trigger signals.\n\n📈 HIGHER VALUES (7-9): Finer granularity, more precise extremes.\n📉 LOWER VALUES (3-5): Broader, fewer but stronger signals.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Short TFs: 7-9 for detail.\n• Long TFs: 5-7 for major levels.\n\n💡 PRO TIP: 9 for most assets; reduce if too many signals.")
edgeSensitivity = input.int(3, "Edge Sensitivity", minval=0, maxval=4, group=groupState, tooltip="🎯 WHAT IT IS: How close to range edges (high/low) price must be for state requirement.\n\n⚡ HOW IT WORKS: 0 is strictest (must be at absolute edge); 4 is lenient.\n\n📈 HIGHER VALUES (3-4): More signals, allows near-extremes.\n📉 LOWER VALUES (0-2): Fewer, requires true extremes.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Volatile: Higher for flexibility.\n\n💡 PRO TIP: 3 for balance; increase if missing turns.")
predictiveMode = input.bool(true, "Predictive Mode (Early Detection)", group=groupState, tooltip="🎯 WHAT IT IS: Toggles the predictive detection mode for early reversal anticipation.\n\n⚡ HOW IT WORKS: Analyzes current bar state, acceleration, entropy, and trend to forecast potential turns before full confirmation. Signals appear as '?' on the current bar.\n\n📈 ENABLED (true): Activates early signals for proactive trading. Recommended for scalping or volatile markets.\n📉 DISABLED (false): Only shows confirmed signals after bar close. Safer but less timely.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping (1-5min): Enable for intra-bar alerts.\n• Day Trading (15min-1H): Enable for early entries.\n• Swing Trading (4H-1D): Disable to avoid false positives.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Crypto (Volatile): Enable to catch fast reversals.\n• Stocks (Stable): Optional, depending on timeframe.\n• Forex (Varied): Enable for major pairs.\n• Indices (Trending): Disable in strong trends.\n\n💡 PRO TIP: Use with alerts for real-time notifications. Combine with confirmed signals for validation.")
liveSignalMode = input.bool(false, "Live Signal Mode (Current Bar)", group=groupState, tooltip="🎯 WHAT IT IS: Toggles real-time signal detection on the current open bar for immediate trading insights.\n\n⚡ HOW IT WORKS: Projects tentative signals intra-bar based on projected high/low and momentum. Signals are marked '!' and confirm on bar close; may repaint as the bar develops.\n\n📈 ENABLED (true): Activates live projections for no-lag detection. Ideal for high-frequency or real-time trading.\n📉 DISABLED (false): Signals only on confirmed closed bars. Reduces repaint risk but delays detection.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping (1-5min): Enable for instant alerts on fast moves.\n• Day Trading (15min-1H): Enable if monitoring live; disable for backtesting.\n• Swing Trading (4H-1D): Disable to avoid intra-bar noise.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Crypto (Volatile): Enable for rapid reversals.\n• Stocks (Stable): Optional; use if trading intraday.\n• Forex (Varied): Enable for liquid pairs.\n• Indices (Trending): Disable in low-vol sessions.\n\n💡 PRO TIP: Combine with alerts for notifications on tentative signals. Use in conjunction with Predictive Mode for enhanced early detection.")
adaptiveEntropy = input.bool(true, "Adaptive Entropy (Auto-Adjust)", group=groupSignal, tooltip="🎯 WHAT IT IS: Enables automatic adjustment of the entropy threshold based on market conditions.\n\n⚡ HOW IT WORKS: Dynamically modifies the entropy filter using trend strength and volatility, making it stricter in noisy markets and more lenient in ordered ones.\n\n📈 ENABLED (true): Auto-adjusts for adaptive filtering, improving signal quality across varying conditions.\n📉 DISABLED (false): Uses fixed Entropy Threshold; consistent but less responsive to changes.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping (1-5min): Enable for quick adaptations to volatility spikes.\n• Day Trading (15min-1H): Enable for intraday shifts.\n• Swing Trading (4H-1D): Optional; disable if preferring manual control.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Crypto (Volatile): Enable to handle sudden disorder.\n• Stocks (Stable): Enable for earnings volatility.\n• Forex (Varied): Enable during news events.\n• Indices (Trending): Disable in steady trends.\n\n💡 PRO TIP: Pair with a moderate Entropy Threshold (e.g., 0.7) as a base; monitor dashboard entropy for effectiveness.")
aggressiveMode = input.bool(false, "Aggressive Mode (Catch All)", group=groupSignal, tooltip="🎯 WHAT IT IS: Activates a mode that relaxes filters to capture more potential signals.\n\n⚡ HOW IT WORKS: Increases edge sensitivity, raises entropy threshold, and reduces min distance, allowing more signals in varied conditions while maintaining core probability checks.\n\n📈 ENABLED (true): Generates more signals, ideal for active trading or low-signal environments.\n📉 DISABLED (false): Stricter filtering for higher-quality, fewer signals.\n\n🕒 TIMEFRAME OPTIMIZATION:\n• Scalping (1-5min): Enable for frequent opportunities.\n• Day Trading (15min-1H): Enable in ranging markets.\n• Swing Trading (4H-1D): Disable to focus on major turns.\n\n🏦 SECTOR RECOMMENDATIONS:\n• Crypto (Volatile): Enable to catch all micro-turns.\n• Stocks (Stable): Disable to avoid noise.\n• Forex (Varied): Enable during quiet hours.\n• Indices (Trending): Disable in bull/bear runs.\n\n💡 PRO TIP: Use with higher Min Probability (e.g., 75) to filter low-quality extras; backtest to balance quantity vs. quality.")
groupFilters = "📈 Additional Filters"
enableRSI = input.bool(true, "Enable RSI Filter", group=groupFilters, tooltip="🎯 WHAT IT IS: Toggles RSI-based bonuses for probability calculation.\n\n⚡ HOW IT WORKS: Adds bonus if RSI is overbought (peaks) or oversold (valleys).\n\n📈 ENABLED: Enhances signals in extremes.\n📉 DISABLED: Ignores RSI.\n\n💡 PRO TIP: Enable for momentum confirmation.")
rsiLen = input.int(17, "RSI Length", group=groupFilters, tooltip="🎯 WHAT IT IS: Period for RSI calculation.\n\n⚡ HOW IT WORKS: Standard RSI length.\n\n💡 PRO TIP: 14 is classic; adjust for sensitivity.")
rsiTop = input.int(65, "Overbought Threshold", group=groupFilters, tooltip="🎯 WHAT IT IS: RSI level for overbought bonus (peaks).\n\n⚡ HOW IT WORKS: RSI > this adds probability bonus.\n\n💡 PRO TIP: 70 for strict; 65 for more signals.")
rsiBot = input.int(40, "Oversold Threshold", group=groupFilters, tooltip="🎯 WHAT IT IS: RSI level for oversold bonus (valleys).\n\n⚡ HOW IT WORKS: RSI < this adds probability bonus.\n\n💡 PRO TIP: 30 for strict; 35 for more signals.")
volLookback = input.int(17, "Volume Lookback", group=groupFilters, tooltip="🎯 WHAT IT IS: Period for average volume calculation.\n\n⚡ HOW IT WORKS: SMA(volume, this) for spike detection.\n\n💡 PRO TIP: 22 for balance.")
volMultiplier = input.float(1.2, "Volume Multiplier", step=0.1, group=groupFilters, tooltip="🎯 WHAT IT IS: Multiplier for volume spike bonus.\n\n⚡ HOW IT WORKS: Volume > avg * this adds bonus.\n\n💡 PRO TIP: 1.3 for moderate spikes.")
groupVisual = "🌈 Visual Design"
signalSize = input.string("Normal", "Signal Size", options=["Tiny", "Small", "Normal", "Large"], group=groupVisual, tooltip="🎯 WHAT IT IS: Size of signal labels (▼/▲/?) on the chart.\n\n⚡ HOW IT WORKS: Adjusts visual prominence of signals.\n\n📈 LARGER: Easier to see on busy charts.\n📉 SMALLER: Minimalist view.\n\n💡 PRO TIP: 'Normal' for most setups.")
showHarmonicWave = input.bool(true, "Show Harmonic Wave", group=groupVisual, inline="viz1", tooltip="🎯 WHAT IT IS: Toggles the harmonic wave visualization around price.\n\n⚡ HOW IT WORKS: Plots smoothed wave bands based on sine functions and stddev for visual flow.\n\n📈 ENABLED: Adds aesthetic bands.\n📉 DISABLED: Cleaner chart.\n\n💡 PRO TIP: Enable for visual trend feel.")
showEntropyParticles = input.bool(true, "Show Entropy Particles", group=groupVisual, inline="viz1", tooltip="🎯 WHAT IT IS: Toggles particle effects based on entropy and velocity.\n\n⚡ HOW IT WORKS: Visualizes flow strength with colored particles.\n\n📈 ENABLED: Dynamic visual aid.\n📉 DISABLED: Reduce clutter.\n\n💡 PRO TIP: Useful for entropy intuition.")
colorTheme = input.string("Ocean", "Color Theme", options=["Neon", "Cyber", "Solar", "Ocean", "Aurora", "Plasma"], group=groupVisual, tooltip="🎯 WHAT IT IS: Selects the color scheme for signals, waves, and particles.\n\n⚡ HOW IT WORKS: Applies theme colors to visuals (e.g., bull/bear/quantum).\n\nOPTIONS:\n• Neon: Vibrant greens/pinks/blues.\n• Cyber: Cool cyan/magenta/purple.\n• Solar: Warm yellows/oranges/reds.\n• Ocean: Calming teals/pinks/blues.\n• Aurora: Dynamic greens/purples/blues (northern lights vibe).\n• Plasma: Energetic purples/blues/pinks (plasma energy feel).\n\n💡 PRO TIP: Choose based on chart background; 'Aurora' for dark themes.")
groupFib = "🔮 Fibonacci Target Engine"
showFibLevels = input.bool(true, "Show Fibonacci Levels", group=groupFib, inline="fib1", tooltip="🎯 WHAT IT IS: Toggles display of Fibonacci-based high/low lines.\n\n⚡ HOW IT WORKS: Plots recent highs/lows over fib periods (8,13,21,34,55).\n\n📈 ENABLED: Shows levels for targets/support.\n📉 DISABLED: Hides for simplicity.\n\n💡 PRO TIP: Use with channels for trade management.")
showActiveChannel = input.bool(true, "Show Active Fib Channel", group=groupFib, inline="fib1", tooltip="🎯 WHAT IT IS: Toggles the active fib channel and stop zone after signals.\n\n⚡ HOW IT WORKS: Creates green channel around price post-signal, with red stop zone.\n\n📈 ENABLED: Visual trade zones.\n📉 DISABLED: No channels.\n\n💡 PRO TIP: Essential for visualizing entries/exits.")
c_f8 = input.color(color.new(#3B82F6, 30), "F8 Color", group=groupFib, inline="fib_c", tooltip="🎯 WHAT IT IS: Color for 8-period fib line.\n\n⚡ HOW IT WORKS: Customizes visual appearance.\n\n💡 PRO TIP: Match to theme.")
c_f13 = input.color(color.new(#8B5CF6, 30), "F13 Color", group=groupFib, inline="fib_c", tooltip="🎯 WHAT IT IS: Color for 13-period fib line.\n\n⚡ HOW IT WORKS: Customizes visual appearance.\n\n💡 PRO TIP: Match to theme.")
c_f21 = input.color(color.new(#F59E0B, 30), "F21 Color", group=groupFib, inline="fib_c", tooltip="🎯 WHAT IT IS: Color for 21-period fib line.\n\n⚡ HOW IT WORKS: Customizes visual appearance.\n\n💡 PRO TIP: Match to theme.")
c_f34 = input.color(color.new(#10B981, 30), "F34 Color", group=groupFib, inline="fib_c", tooltip="🎯 WHAT IT IS: Color for 34-period fib line.\n\n⚡ HOW IT WORKS: Customizes visual appearance.\n\n💡 PRO TIP: Match to theme.")
c_f55 = input.color(color.new(#EF4444, 30), "F55 Color", group=groupFib, inline="fib_c", tooltip="🎯 WHAT IT IS: Color for 55-period fib line.\n\n⚡ HOW IT WORKS: Customizes visual appearance.\n\n💡 PRO TIP: Match to theme.")
group_dashboard_main = "📊 Dashboard Configuration"
show_dashboard = input.bool(true, "📋 Show Enhanced Dashboard", group=group_dashboard_main, tooltip="🎯 WHAT IT IS: Master toggle for displaying the main dashboard on your chart.\n\n⚡ HOW IT WORKS: Enabling it shows the key data panels.\n\n📈 ENABLED (true): Shows the dashboard with all its analytical components.\n📉 DISABLED (false): Hides the dashboard for a minimalist chart view.\n\n💡 PRO TIP: Keep enabled to leverage the full analytical power of the indicator's real-time feedback.")
dashboard_size = input.string("Large", "📏 Dashboard Size", options=["Small", "Normal", "Large"], group=group_dashboard_main, tooltip="🎯 WHAT IT IS: Controls the amount of information displayed in the dashboard and its overall size.\n\n⚡ HOW IT WORKS:\n• Small: Displays only the most critical metrics.\n• Normal: Shows a detailed analysis.\n• Large: Presents all available data.\n\n💡 PRO TIP: Use 'Normal' for most desktop trading. Switch to 'Small' on your phone. Use 'Large' when you are doing a deep dive or fine-tuning the indicator settings.")
dashboard_position_input = input.string("Top Right", "📍 Dashboard Position", options=["Top Left", "Top Right", "Bottom Left", "Bottom Right"], group=group_dashboard_main, tooltip="🎯 WHAT IT IS: Sets the corner of the chart where the main dashboard will be anchored.\n\n⚡ HOW IT WORKS: Select the desired position from the dropdown menu to place the dashboard in the corner that best suits your chart layout.\n\n📈 OPTIONS: Top Left, Top Right, Bottom Left, Bottom Right.\n\n💡 PRO TIP: Place the dashboard in a corner where it won't obscure recent price action or other essential indicators. 'Top Right' is a common default as price action typically develops from the right.")
//==================================================================
// VISUAL DESIGN SYSTEM
//==================================================================
f_getColors(theme) =>
    if theme == "Cyber"
        [#00F0FF, #FF00F7, #7B61FF]
    else if theme == "Solar"
        [#FFB300, #FF4161, #FF8E00]
    else if theme == "Ocean"
        [#00F5E9, #FF7BAC, #7DF9FF]
    else if theme == "Aurora"
        [#00FF7F, #9370DB, #20B2AA]
    else if theme == "Plasma"
        [#FF00FF, #00BFFF, #FF1493]
    else
        [#39FF14, #FF10F0, #00F5FF]
[bullColor, bearColor, quantumColor] = f_getColors(colorTheme)
//==================================================================
// HELPER FUNCTIONS
//==================================================================
f_get_size(s) =>
    if s == "Tiny"
        size.tiny
    else if s == "Small"
        size.small
    else if s == "Normal"
        size.normal
    else if s == "Large"
        size.large
    else
        size.tiny
getSupertrend(_src, _mult, _len) =>
    atr = ta.atr(_len)
    upper = _src - _mult * atr
    lower = _src + _mult * atr
    upper := close[1] > upper[1] ? math.max(upper, upper[1]) : upper
    lower := close[1] < lower[1] ? math.min(lower, lower[1]) : lower
    var int trend = 1
    trend := trend == -1 and close > lower[1] ? 1 : trend == 1 and close < upper[1] ? -1 : trend
    [trend, upper, lower]
[rTrend, rUp, rDn] = getSupertrend(hlcc4, 1.1, 16)
//==================================================================
// CORE SIGNAL ENGINE
//==================================================================
hlc3_smooth = ta.wma((high + low + close) / 3, 3)
atrValue = ta.atr(14)
calculateEntropy(series, length) =>
    priceChanges = series - series[1]
    upChanges = 0.0
    total = 0.0
    int i = 0
    while i < length
        if not na(priceChanges[i])
            total += 1
            if priceChanges[i] > 0
                upChanges += 1
        i += 1
    p = upChanges / math.max(total, 1)
    p > 0 and p < 1 ? (-p * math.log(p) - (1 - p) * math.log(1 - p)) / math.log(2) : 0.5
quantumStateAnalysis(price, states, period) =>
    hi = ta.highest(price, period)
    lo = ta.lowest(price, period)
    priceRangeVal = hi - lo
    state = priceRangeVal > 0 ? math.round((price - lo) / priceRangeVal * (states - 1)) : 0
    [state, priceRangeVal > 0 ? (price - lo) / priceRangeVal : 0]
psr(series, period) =>
    velocity = series - series[math.round(period / 2)]
    [velocity, velocity - velocity[1]]
[state, statePercent] = quantumStateAnalysis(hlc3_smooth, analysisLevels, adaptivePeriod)
[psr_velocity, psr_acceleration] = psr(hlc3_smooth, adaptivePeriod)
entropy = calculateEntropy(hlc3_smooth, adaptivePeriod)
rsi = ta.rsi(close, rsiLen)
rsiTopCond = enableRSI ? rsi > rsiTop : false
rsiBotCond = enableRSI ? rsi < rsiBot : false
volSpike = volume > volMultiplier * ta.sma(volume, volLookback)
isPivotHigh = high[1] > high[2] and high[1] > high
isPivotLow = low[1] < low[2] and low[1] < low
isFractalHigh = false
isFractalLow = false
if bar_index >= fractalStrength * 2
    center = fractalStrength
    isFractalHigh := true
    isFractalLow := true
    int i = 1
    while i <= fractalStrength
        if nz(high[center]) <= nz(high[center + i]) or nz(high[center]) <= nz(high[center - i])
            isFractalHigh := false
        if nz(low[center]) >= nz(low[center + i]) or nz(low[center]) >= nz(low[center - i])
            isFractalLow := false
        i += 1
isPeakEvent = (isPivotHigh or isFractalHigh[1]) and close < low[1]
isValleyEvent = (isPivotLow or isFractalLow[1]) and close > high[1]
peak_price_at_pivot = high[1]
valley_price_at_pivot = low[1]
var float last_valid_peak_price = na
var float last_valid_peak_velocity = na
var float last_valid_valley_price = na
var float last_valid_valley_velocity = na
isBearishDivergence = isPeakEvent and not na(last_valid_peak_price) and (peak_price_at_pivot > last_valid_peak_price) and (psr_velocity[1] < last_valid_peak_velocity)
isBullishDivergence = isValleyEvent and not na(last_valid_valley_price) and (valley_price_at_pivot < last_valid_valley_price) and (psr_velocity[1] > last_valid_valley_velocity)
isPeakStateReqMet = isPeakEvent and (state[1] >= analysisLevels - 1 - edgeSensitivity) and (rTrend == -1 or ta.change(rTrend) < 0)
isValleyStateReqMet = isValleyEvent and (state[1] <= edgeSensitivity) and (rTrend == 1 or ta.change(rTrend) > 0)
isPotentialPeak = predictiveMode and state >= analysisLevels - 1 - edgeSensitivity and psr_acceleration < 0 and entropy < entropyThreshold and rTrend == -1
isPotentialValley = predictiveMode and state <= edgeSensitivity and psr_acceleration > 0 and entropy < entropyThreshold and rTrend == 1
currentTFSeconds = timeframe.in_seconds()
mtfTFSeconds = currentTFSeconds * mtfMultiplier
string mtfTF = timeframe.from_seconds(mtfTFSeconds)
[mtfHigh, mtfLow, mtfClose] = request.security(syminfo.tickerid, mtfTF, [high, low, close], gaps=barmerge.gaps_on)
mtfIsPeak = not na(mtfHigh[1]) and mtfHigh[1] > nz(mtfHigh[2], mtfHigh[1]) and mtfHigh[1] > nz(mtfHigh, mtfHigh[1])
mtfIsValley = not na(mtfLow[1]) and mtfLow[1] < nz(mtfLow[2], mtfLow[1]) and mtfLow[1] < nz(mtfLow, mtfLow[1])
isPeakEvent := isPeakEvent or (mtfIsPeak and close < nz(mtfLow[1], low[1]))
isValleyEvent := isValleyEvent or (mtfIsValley and close > nz(mtfHigh[1], high[1]))
trendStrength = math.abs(ta.ema(psr_velocity, 10))
avgVolRecent = ta.sma(volume, 5)
calculateProbability(p_entropy, isDivergence) =>
    base_score = 40 + (trendStrength / atrValue * 30) + (1 - p_entropy) * 10
    entropy_score = p_entropy < entropyThreshold ? 10 + (1 - p_entropy) * 5 : -5
    divergence_bonus = isDivergence ? 20 + math.abs(psr_acceleration) * 2 : 0
    rsi_bonus = (rsiTopCond and isPeakEvent) or (rsiBotCond and isValleyEvent) ? 8 + (rsi - 50) / 5 : 0
    vol_bonus = volSpike ? 5 + (volume / avgVolRecent - 1) * 3 : 0
    adaptive_bonus = adaptiveEntropy and trendStrength > atrValue ? 10 + trendStrength * 0.5 : 0
    mtf_bonus = (mtfIsPeak and isPeakEvent) or (mtfIsValley and isValleyEvent) ? 12 : 0
    barRangeFactor = (high - low) / atrValue
    variation = barRangeFactor * 3 - 1.5
    raw_prob = base_score + entropy_score + divergence_bonus + rsi_bonus + vol_bonus + adaptive_bonus + mtf_bonus + variation
    math.min(99, math.max(40, math.round(raw_prob, 1)))
peakProb = isPeakStateReqMet or isPotentialPeak ? calculateProbability(entropy[1], isBearishDivergence) : na
valleyProb = isValleyStateReqMet or isPotentialValley ? calculateProbability(entropy[1], isBullishDivergence) : na
effectiveMinProb = minProbThreshold - (adaptiveEntropy ? (trendStrength / atrValue * 5) : 0)
effectiveMinDistance = aggressiveMode ? 1 : minSignalDistance
effectiveEdgeSens = aggressiveMode ? 4 : edgeSensitivity
effectiveEntropyThresh = aggressiveMode ? 0.95 : entropyThreshold
var int lastSignalBar = na
validPeak = (isPeakStateReqMet or isPotentialPeak) and peakProb >= effectiveMinProb and (na(lastSignalBar) or (bar_index - lastSignalBar > effectiveMinDistance))
validValley = (isValleyStateReqMet or isPotentialValley) and valleyProb >= effectiveMinProb and (na(lastSignalBar) or (bar_index - lastSignalBar > effectiveMinDistance))
if validPeak
    lastSignalBar := bar_index
    last_valid_peak_price := peak_price_at_pivot
    last_valid_peak_velocity := psr_velocity[1]
if validValley
    lastSignalBar := bar_index
    last_valid_valley_price := valley_price_at_pivot
    last_valid_valley_velocity := psr_velocity[1]
var bool livePeakEvent = false
var bool liveValleyEvent = false
var float livePeakProb = na
var float liveValleyProb = na
var label livePeakLabel = na
var label livePeakProbLabel = na
var label liveValleyLabel = na
var label liveValleyProbLabel = na
projectedClose = ta.linreg(close, 5, 0)
tentativePeakProb = calculateProbability(entropy, isBearishDivergence)
tentativeValleyProb = calculateProbability(entropy, isBullishDivergence)
if liveSignalMode and barstate.isrealtime
    projectedHigh = math.max(high, open)
    projectedLow = math.min(low, open)
    intraVelocity = close - open
    intraAcceleration = intraVelocity - (close[1] - open[1])
    livePeakEvent := projectedHigh > high[1] and projectedClose < projectedLow and intraAcceleration < 0 and entropy < effectiveEntropyThresh
    liveValleyEvent := projectedLow < low[1] and projectedClose > projectedHigh and intraAcceleration > 0 and entropy < effectiveEntropyThresh
    livePeakProb := livePeakEvent ? tentativePeakProb : na
    liveValleyProb := liveValleyEvent ? tentativeValleyProb : na
    if livePeakEvent and livePeakProb >= effectiveMinProb
        label.delete(livePeakLabel)
        label.delete(livePeakProbLabel)
        livePeakLabel := label.new(bar_index, projectedHigh + atrValue * 0.7, "!", color=color.new(color.black, 100), textcolor=color.new(bearColor, 70), style=label.style_none, size=f_get_size(signalSize))
        livePeakProbLabel := label.new(bar_index, projectedHigh + atrValue * 1.2, str.tostring(livePeakProb) + "%", color=color.new(color.black, 100), textcolor=color.new(bearColor, 70), style=label.style_none, size=f_get_size(signalSize))
    else
        label.delete(livePeakLabel)
        label.delete(livePeakProbLabel)
    if liveValleyEvent and liveValleyProb >= effectiveMinProb
        label.delete(liveValleyLabel)
        label.delete(liveValleyProbLabel)
        liveValleyLabel := label.new(bar_index, projectedLow - atrValue * 0.7, "!", color=color.new(color.black, 100), textcolor=color.new(bullColor, 70), style=label.style_none, size=f_get_size(signalSize))
        liveValleyProbLabel := label.new(bar_index, projectedLow - atrValue * 1.2, str.tostring(liveValleyProb) + "%", color=color.new(color.black, 100), textcolor=color.new(bullColor, 70), style=label.style_none, size=f_get_size(signalSize))
    else
        label.delete(liveValleyLabel)
        label.delete(liveValleyProbLabel)
else
    livePeakEvent := false
    liveValleyEvent := false
    livePeakProb := na
    liveValleyProb := na
if barstate.isconfirmed
    label.delete(livePeakLabel)
    label.delete(livePeakProbLabel)
    label.delete(liveValleyLabel)
    label.delete(liveValleyProbLabel)
var bool livePending = false
livePending := liveSignalMode and barstate.isrealtime and (not na(livePeakProb) or not na(liveValleyProb))
//==================================================================
// FIBONACCI LEVEL ENGINE & ACTIVE CHANNEL
//==================================================================
fib8_high = ta.highest(high, 8)
fib8_low = ta.lowest(low, 8)
fib13_high = ta.highest(high, 13)
fib13_low = ta.lowest(low, 13)
fib21_high = ta.highest(high, 21)
fib21_low = ta.lowest(low, 21)
fib34_high = ta.highest(high, 34)
fib34_low = ta.lowest(low, 34)
fib55_high = ta.highest(high, 55)
fib55_low = ta.lowest(low, 55)
var box activeChannelBox = na
var box stopZoneBox = na
var bool isTradeActive = false
var string activeSignalDirection = ""
if validPeak or validValley
    isTradeActive := true
    activeSignalDirection := validValley ? "long" : "short"
    if not na(activeChannelBox)
        box.delete(activeChannelBox)
        activeChannelBox := na
    if not na(stopZoneBox)
        box.delete(stopZoneBox)
        stopZoneBox := na
if barstate.isconfirmed
    if showFibLevels
        fib_periods_display = array.from(8, 13, 21, 34, 55)
        fib_highs_display_arr = array.from(fib8_high, fib13_high, fib21_high, fib34_high, fib55_high)
        fib_lows_display_arr = array.from(fib8_low, fib13_low, fib21_low, fib34_low, fib55_low)
        fib_colors_arr = array.from(c_f8, c_f13, c_f21, c_f34, c_f55)
        var array<line> fibLines = array.new<line>()
        var array<label> fibLabels = array.new<label>()
        if array.size(fibLines) > 0
            for i = 0 to array.size(fibLines) - 1
                line.delete(array.get(fibLines, i))
        if array.size(fibLabels) > 0
            for i = 0 to array.size(fibLabels) - 1
                label.delete(array.get(fibLabels, i))
        array.clear(fibLines)
        array.clear(fibLabels)
        right_boundary = bar_index + 60
        used_positions = array.new<float>()
        min_spacing = atrValue * 0.5
        for i = 0 to array.size(fib_periods_display) - 1
            hi_val = array.get(fib_highs_display_arr, i)
            lo_val = array.get(fib_lows_display_arr, i)
            line_color = array.get(fib_colors_arr, i)
            period = array.get(fib_periods_display, i)
            if not na(hi_val)
                array.push(fibLines, line.new(bar_index, hi_val, right_boundary, hi_val, color=color.new(color.white, 75), width=3))
                array.push(fibLines, line.new(bar_index, hi_val, right_boundary, hi_val, color=color.new(line_color, 40), width=1, style=line.style_dotted))
                can_place_label = true
                for used_pos in used_positions
                    if math.abs(hi_val - used_pos) < min_spacing
                        can_place_label := false
                if can_place_label
                    label_text = "F" + str.tostring(period) + "/" + timeframe.period + " - RSI: " + str.tostring(rsi, "#.0")
                    array.push(fibLabels, label.new(right_boundary + 1, hi_val, label_text, color=color.new(line_color, 85), textcolor=color.new(line_color, 20), style=label.style_label_left, size=size.small))
                    array.push(used_positions, hi_val)
            if not na(lo_val)
                array.push(fibLines, line.new(bar_index, lo_val, right_boundary, lo_val, color=color.new(color.white, 75), width=3))
                array.push(fibLines, line.new(bar_index, lo_val, right_boundary, lo_val, color=color.new(line_color, 40), width=1, style=line.style_dotted))
                can_place_label = true
                for used_pos in used_positions
                    if math.abs(lo_val - used_pos) < min_spacing
                        can_place_label := false
                if can_place_label
                    label_text = "F" + str.tostring(period) + "/" + timeframe.period + " - RSI: " + str.tostring(rsi, "#.0")
                    array.push(fibLabels, label.new(right_boundary + 1, lo_val, label_text, color=color.new(line_color, 85), textcolor=color.new(line_color, 20), style=label.style_label_left, size=size.small))
                    array.push(used_positions, lo_val)
    if not na(activeChannelBox)
        box.delete(activeChannelBox)
        activeChannelBox := na
    if not na(stopZoneBox)
        box.delete(stopZoneBox)
        stopZoneBox := na
    if showActiveChannel and isTradeActive
        fib_highs_all = array.from(fib8_high, fib13_high, fib21_high, fib34_high, fib55_high)
        fib_lows_all = array.from(fib8_low, fib13_low, fib21_low, fib34_low, fib55_low)
        bool foundChannelThisBar = false
        for i = 0 to array.size(fib_highs_all) - 1
            hi_channel = array.get(fib_highs_all, i)
            lo_channel = array.get(fib_lows_all, i)
            if not na(hi_channel) and not na(lo_channel)
                if close > lo_channel and close < hi_channel
                    activeChannelBox := box.new(bar_index, lo_channel, bar_index + 40, hi_channel, bgcolor=color.new(#39FF14, 85), border_color=na)
                    if activeSignalDirection == "long"
                        float lowerBoundary = na
                        for j = 0 to array.size(fib_highs_all) - 1
                            prev_hi = array.get(fib_highs_all, j)
                            if not na(prev_hi) and prev_hi < lo_channel and (na(lowerBoundary) or prev_hi > lowerBoundary)
                                lowerBoundary := prev_hi
                        if not na(lowerBoundary)
                            stopZoneBox := box.new(bar_index, lowerBoundary, bar_index + 40, lo_channel, bgcolor=color.new(#FF0000, 85), border_color=na)
                    else if activeSignalDirection == "short"
                        float upperBoundary = na
                        for j = 0 to array.size(fib_lows_all) - 1
                            next_lo = array.get(fib_lows_all, j)
                            if not na(next_lo) and next_lo > hi_channel and (na(upperBoundary) or next_lo < upperBoundary)
                                upperBoundary := next_lo
                        if not na(upperBoundary)
                            stopZoneBox := box.new(bar_index, hi_channel, bar_index + 40, upperBoundary, bgcolor=color.new(#FF0000, 85), border_color=na)
                    foundChannelThisBar := true
                    break
        if not foundChannelThisBar
            isTradeActive := false
//==================================================================
// VISUALS
//==================================================================
wave_period = math.round(adaptivePeriod * 1.5)
wave_outer = ta.sma(math.sin(2 * math.pi * bar_index / wave_period) * ta.stdev(hlc3_smooth, wave_period) * 1.5 + hlc3_smooth, 3)
wave_mid = hlc3_smooth + (wave_outer - hlc3_smooth) * 0.66
wave_core = hlc3_smooth + (wave_outer - hlc3_smooth) * 0.33
p_price = plot(showHarmonicWave ? hlc3_smooth : na, "Price", display=display.none)
p_core_fill = plot(showHarmonicWave ? wave_core : na, "Core", display=display.none)
p_mid_fill = plot(showHarmonicWave ? wave_mid : na, "Mid", display=display.none)
p_outer_fill = plot(showHarmonicWave ? wave_outer : na, "Outer", display=display.none)
fill(p_price, p_core_fill, color=showHarmonicWave ? color.new(quantumColor, 75) : na)
fill(p_core_fill, p_mid_fill, color=showHarmonicWave ? color.new(quantumColor, 85) : na)
fill(p_mid_fill, p_outer_fill, color=showHarmonicWave ? color.new(quantumColor, 95) : na)
if showEntropyParticles
    flow_strength = 1.0 - (entropy / effectiveEntropyThresh)
    if flow_strength > 0
        particle_color = psr_velocity > 0 ? bullColor : bearColor
        y_pos = psr_velocity > 0 ? low - atrValue * 0.1 : high + atrValue * 0.1
        particleSize = flow_strength > 0.7 ? size.small : size.tiny
        label.new(bar_index, y_pos, '•', color=color.new(#2b52bc, 100), textcolor=color.new(particle_color, 50), style=label.style_none, size=particleSize)
var int plotBarIndex = na
plotBarIndex := bar_index
if validPeak
    isPredictive = isPotentialPeak and not isPeakStateReqMet
    peak_icon = isBearishDivergence ? '◈' : (isPredictive ? '?' : '▼')
    icon_y_pos = (isPredictive ? high : peak_price_at_pivot) + atrValue * 0.7
    text_y_pos = icon_y_pos + atrValue * 0.5
    icon_color = isPredictive ? color.new(bearColor, 50) : bearColor
    label.new(plotBarIndex, icon_y_pos, text=peak_icon, color=color.new(color.black, 100), textcolor=icon_color, style=label.style_none, size=f_get_size(signalSize))
    label.new(plotBarIndex, text_y_pos, text=str.tostring(peakProb, "#.0") + "%", color=color.new(color.black, 100), textcolor=icon_color, style=label.style_none, size=f_get_size(signalSize))
if validValley
    isPredictive = isPotentialValley and not isValleyStateReqMet
    valley_icon = isBullishDivergence ? '◈' : (isPredictive ? '?' : '▲')
    icon_y_pos = (isPredictive ? low : valley_price_at_pivot) - atrValue * 0.7
    text_y_pos = icon_y_pos - atrValue * 0.5
    icon_color = isPredictive ? color.new(bullColor, 50) : bullColor
    label.new(plotBarIndex, icon_y_pos, text=valley_icon, color=color.new(color.black, 100), textcolor=icon_color, style=label.style_none, size=f_get_size(signalSize))
    label.new(plotBarIndex, text_y_pos, text=str.tostring(valleyProb, "#.0") + "%", color=color.new(color.black, 100), textcolor=icon_color, style=label.style_none, size=f_get_size(signalSize))
//==================================================================
// 🖥️ DASHBOARD
//==================================================================
var table dashboard = na
var string lastSignalType = "None"
var float lastPeakProb = 0
var float lastValleyProb = 0
var int barsSinceSignal = na
if validPeak
    lastSignalType := "Peak"
    lastPeakProb := peakProb
    barsSinceSignal := 0
else if validValley
    lastSignalType := "Valley"
    lastValleyProb := valleyProb
    barsSinceSignal := 0
else if not na(lastSignalBar)
    barsSinceSignal := bar_index - lastSignalBar
if show_dashboard and barstate.islast
    dashboard_pos = dashboard_position_input == "Top Left" ? position.top_left : dashboard_position_input == "Top Right" ? position.top_right : dashboard_position_input == "Bottom Left" ? position.bottom_left : position.bottom_right
    cols = 4
    rows = dashboard_size == "Small" ? 8 : dashboard_size == "Normal" ? 20 : 40
    if not na(dashboard)
        table.delete(dashboard)
    dashboard := table.new(dashboard_pos, cols, rows, border_width = 1, border_color = color.new(color.gray, 50), bgcolor = color.new(#1e222d, 20))
    dc_white = color.white
    dc_gray = #B2B5BE
    dc_green = #26A69A
    dc_red = #EF5350
    dc_gold = #FFD700
    dc_purple = quantumColor
    dc_aqua = bullColor
    dc_orange = #FF8C00
    dc_cyan = #00FFFF
    bg_header = color.new(color.black, 30)
    bg_section = color.new(color.gray, 85)
    header_size = size.small
    value_size = size.small
    label_size = size.tiny
    current_row = 0
    table.merge_cells(dashboard, 0, current_row, cols - 1, current_row)
    table.cell(dashboard, 0, current_row, "⇋ Reversal Point Dynamics  | " + syminfo.ticker, text_halign=text.align_center, text_color=dc_white, bgcolor=bg_header, text_size=header_size)
    current_row += 1
    table.merge_cells(dashboard, 0, current_row, cols - 1, current_row)
    table.cell(dashboard, 0, current_row, "═══ 🎯 UNIFIED PROB SCORE ═══", text_halign=text.align_center, text_color=dc_gold, bgcolor=bg_section, text_size=label_size)
    current_row += 1
    totalScore = math.max(nz(peakProb, lastPeakProb), nz(valleyProb, lastValleyProb))
    signalQuality = totalScore >= 90 ? "EXCEPTIONAL" : totalScore >= 75 ? "STRONG" : totalScore >= 60 ? "MODERATE" : totalScore >= 30 ? "BUILDING" : "WEAK"
    scoreColor = signalQuality == "EXCEPTIONAL" ? dc_gold : signalQuality == "STRONG" ? dc_green : signalQuality == "MODERATE" ? dc_aqua : signalQuality == "BUILDING" ? dc_orange : dc_gray
    table.cell(dashboard, 0, current_row, "TOTAL SCORE", text_color=dc_gray, text_size=label_size)
    table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
    table.cell(dashboard, 1, current_row, str.tostring(totalScore, "#.##"), text_halign=text.align_right, text_color=scoreColor, text_size=value_size)
    current_row += 1
    table.cell(dashboard, 0, current_row, "Quality", text_color=dc_gray, text_size=label_size)
    table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
    qualityEmoji = signalQuality == "EXCEPTIONAL" ? "🌟" : signalQuality == "STRONG" ? "💪" : signalQuality == "MODERATE" ? "👍" : "⚠️"
    table.cell(dashboard, 1, current_row, qualityEmoji + " " + signalQuality, text_halign=text.align_right, text_color=scoreColor, text_size=value_size)
    current_row += 1
    if dashboard_size != "Small"
        table.merge_cells(dashboard, 0, current_row, cols - 1, current_row)
        table.cell(dashboard, 0, current_row, "═══ 📊 ORDER FLOW ═══", text_halign=text.align_center, text_color=dc_gold, bgcolor=bg_section, text_size=label_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "Volume Spike", text_color=dc_gray, text_size=label_size)
        table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
        table.cell(dashboard, 1, current_row, volSpike ? "YES (" + str.tostring(volume / avgVolRecent, "#.#") + "x)" : "NO", text_halign=text.align_right, text_color=volSpike ? dc_green : dc_red, text_size=value_size)
        current_row += 1
        table.merge_cells(dashboard, 0, current_row, cols - 1, current_row)
        table.cell(dashboard, 0, current_row, "📊 Component Analysis", text_halign=text.align_center, text_color=dc_aqua, text_size=label_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "Peak Conf", text_color=dc_gray, text_size=label_size)
        peakColor = peakProb > 70 ? dc_red : peakProb > 40 ? dc_orange : dc_gray
        table.cell(dashboard, 1, current_row, str.tostring(peakProb, "#.#"), text_halign=text.align_right, text_color=peakColor, text_size=label_size)
        table.cell(dashboard, 2, current_row, "Valley Conf", text_color=dc_gray, text_size=label_size)
        valleyColor = valleyProb > 70 ? dc_green : valleyProb > 40 ? dc_aqua : dc_gray
        table.cell(dashboard, 3, current_row, str.tostring(valleyProb, "#.#"), text_halign=text.align_right, text_color=valleyColor, text_size=label_size)
        current_row += 1
        table.merge_cells(dashboard, 0, current_row, cols - 1, current_row)
        table.cell(dashboard, 0, current_row, "═══ 🌌 MARKET STRUCTURE ═══", text_halign=text.align_center, text_color=dc_gold, bgcolor=bg_section, text_size=label_size)
        current_row += 1
        trendDirection = rTrend == 1 ? 1 : -1
        table.cell(dashboard, 0, current_row, "HTF Trend", text_color=dc_gray, text_size=label_size)
        htfText = trendDirection > 0 ? "📈 BULL (" + str.tostring(trendStrength, "#.#") + "%)" : "📉 BEAR (" + str.tostring(trendStrength, "#.#") + "%)"
        htfColor = trendDirection > 0 ? dc_green : dc_red
        table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
        table.cell(dashboard, 1, current_row, htfText, text_halign=text.align_right, text_color=htfColor, text_size=label_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "Entropy", text_color=dc_gray, text_size=label_size)
        entropyText = entropy < effectiveEntropyThresh ? "🔥 LOW" : entropy < 0.8 ? "📊 MED" : "😴 HIGH"
        entropyColor = entropy < effectiveEntropyThresh ? dc_green : entropy < 0.8 ? dc_gold : dc_red
        table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
        table.cell(dashboard, 1, current_row, entropyText + " (" + str.tostring(entropy, "#.##") + ")", text_halign=text.align_right, text_color=entropyColor, text_size=value_size)
        current_row += 1
    if dashboard_size == "Large"
        table.merge_cells(dashboard, 0, current_row, cols - 1, current_row)
        table.cell(dashboard, 0, current_row, "═══ 🛡️ FILTERS & PREDICTIVES ═══", text_halign=text.align_center, text_color=dc_gold, bgcolor=bg_section, text_size=label_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "RSI Status", text_color=dc_gray, text_size=label_size)
        rsiText = rsi > rsiTop ? "Overbought" : rsi < rsiBot ? "Oversold" : "Neutral"
        rsiColor = rsi > rsiTop ? dc_red : rsi < rsiBot ? dc_green : dc_gray
        table.cell(dashboard, 1, current_row, rsiText + " (" + str.tostring(rsi, "#.##") + ")", text_halign=text.align_right, text_color=rsiColor, text_size=label_size)
        table.cell(dashboard, 2, current_row, "Divergence", text_color=dc_gray, text_size=label_size)
        divText = isBearishDivergence ? "Bearish" : isBullishDivergence ? "Bullish" : "None"
        divColor = isBearishDivergence ? dc_red : isBullishDivergence ? dc_green : dc_gray
        table.cell(dashboard, 3, current_row, divText, text_halign=text.align_right, text_color=divColor, text_size=label_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "Live Pending", text_color=dc_gray, text_size=label_size)
        table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
        table.cell(dashboard, 1, current_row, livePending ? "YES (" + (not na(livePeakProb) ? "Peak " + str.tostring(livePeakProb, "#.#") : "Valley " + str.tostring(liveValleyProb, "#.#")) + "%)" : "NO", text_halign=text.align_right, text_color=livePending ? dc_gold : dc_gray, text_size=value_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "Predictive Mode", text_color=dc_gray, text_size=label_size)
        table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
        table.cell(dashboard, 1, current_row, predictiveMode ? "ON" : "OFF", text_halign=text.align_right, text_color=predictiveMode ? dc_green : dc_red, text_size=value_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "Last Signal", text_color=dc_gray, text_size=label_size)
        table.cell(dashboard, 1, current_row, lastSignalType, text_halign=text.align_right, text_color=lastSignalType == "Valley" ? dc_green : lastSignalType == "Peak" ? dc_red : dc_gray, text_size=label_size)
        table.cell(dashboard, 2, current_row, "Bars Since", text_color=dc_gray, text_size=label_size)
        table.cell(dashboard, 3, current_row, str.tostring(barsSinceSignal), text_halign=text.align_right, text_color=dc_white, text_size=label_size)
        current_row += 1
        table.cell(dashboard, 0, current_row, "Entropy Particles", text_color=dc_gray, text_size=label_size)
        table.merge_cells(dashboard, 1, current_row, cols - 1, current_row)
        table.cell(dashboard, 1, current_row, showEntropyParticles ? "ON (Strength: " + str.tostring(1.0 - entropy, "#.#") + ")" : "OFF", text_halign=text.align_right, text_color=showEntropyParticles ? dc_purple : dc_gray, text_size=label_size)
        current_row += 1
//==================================================================
// WATERMARK
//==================================================================
var table watermarkTable = na
if na(watermarkTable)
    watermarkTable := table.new(position.bottom_center, 1, 1, bgcolor=color.new(color.black, 90), border_color=color.new(color.purple, 80), border_width=1)
table.clear(watermarkTable, 0, 0)
table.cell(watermarkTable, 0, 0, "⇋ Reversal Point Dynamics (DAFE)", text_color=color.rgb(200, 200, 255), text_size=size.normal)

← 返回列表