Luxy UT GOD - UT-BOT Forecast
Похожие материалы по тегам
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «indicator_luxy_ut_god_mode_ut_bot_forecast,_signals,_zones_and_risk.pine» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Это индикатор для TradingView, написанный на Pine Script v6 и предназначенный для отображения на графике сигналов Buy/Sell, линий скользящего стопа, уровней стоп-лосса и тейк-профита, а также информационной панели. Индикатор не является торговым советником и не совершает сделок; он только визуализирует расчётные уровни и условия.
В основе лежит расчёт трейлинг-стопа на основе ATR с адаптацией к волатильности и типу актива. Сигналы фильтруются набором условий: режим ADX, кулдаун, подтверждение по барам, фильтры волатильности, объёма, RSI, Hull MA, SuperTrend, зоны поддержки/сопротивления, а также подтверждение по старшему таймфрейму. Дополнительно отображаются дивергенции RSI и прогноз длительности тренда на основе исторических данных.
Индикатор предоставляет множество пользовательских настроек для управления отображением, фильтрами, расчётом стоп-лосса и тейк-профита, а также калькулятором риска. Все расчёты выполняются на стороне TradingView, оповещения формируются через alertcondition и alert.
Настройки программы
| Настройка | Описание |
|---|---|
| utShowLabels | Показывает метки Buy/Sell на графике. |
| labelSizeStr | Размер меток на графике. |
| utShowLine | Показывает линию трейлинг-стопа UT. |
| utShowRibbon | Показывает градиентную заливку между ценой и линией UT. |
| utColorBars | Окрашивает бары в зависимости от направления тренда. |
| i_showTable | Показывает информационную таблицу на графике. |
| i_tablePos | Позиция таблицы на графике. |
| i_tableSize | Размер текста таблицы. |
| utAtrPeriod | Период ATR для расчёта трейлинг-стопа. |
| i_enableLayer1 | Включает фильтр Anti-Whipsaw на основе ADX. |
| i_adxPeriod | Период расчёта ADX для определения режима тренда. |
| i_adxThreshold | Порог ADX, выше которого рынок считается трендовым. |
| i_cooldownBars | Минимальное количество баров между сигналами. |
| i_confirmBars | Количество баров для подтверждения направления тренда. |
| i_assetType | Тип актива для автоматической или ручной настройки множителя чувствительности. |
| i_adaptiveMode | Режим адаптации ключевого значения к волатильности: Fixed (без адаптации), Dynamic (умеренная), Aggressive (широкая). |
| i_useVolatility | Включает фильтр высокой волатильности. |
| i_volLookback | Период для расчёта среднего ATR при фильтре волатильности. |
| i_volThresh | Порог отношения текущего ATR к среднему для фильтра волатильности. |
| utUseSwingFilter | Включает фильтр свинг-структуры. |
| swingLen | Период поиска свинг-максимумов и минимумов. |
| utUsePctFilter | Включает фильтр минимального процентного изменения. |
| utPctThr | Минимальное процентное изменение между барами для фильтра. |
| utUseDelay | Требует 2 последовательных бара для подтверждения направления. |
| i_useVolFilter | Включает фильтр объёма. |
| i_volSmaLen | Период SMA для среднего объёма. |
| i_volThreshold | Порог отношения объёма к среднему для фильтра объёма. |
| i_useRsiFilter | Включает фильтр RSI. |
| i_rsiLen | Период RSI для фильтра. |
| i_rsiOB | Уровень перекупленности RSI, выше которого блокируются покупки. |
| i_rsiOS | Уровень перепроданности RSI, ниже которого блокируются продажи. |
| i_useHullConfirm | Включает подтверждение по Hull MA. |
| i_hullPeriod | Период Hull MA для подтверждения направления. |
| i_useSuperTrend | Включает фильтр SuperTrend. |
| i_stAtrPeriod | Период ATR для расчёта SuperTrend. |
| i_stMult | Множитель ATR для SuperTrend. |
| i_showStLine | Показывает линию SuperTrend на графике. |
| i_useFullCandle | Требует, чтобы вся свеча находилась выше или ниже линии UT. |
| utShowZones | Показывает зоны поддержки и сопротивления на графике. |
| i_useZoneFilter | Блокирует покупки в зоне сопротивления и продажи в зоне поддержки. |
| i_zoneWidthMult | Ширина зоны как множитель ATR. |
| i_zonePivotLen | Количество баров для подтверждения пивота при построении зон. |
| entryShow | Показывает линию входа на графике. |
| linesLimit10 | Ограничивает линии SL, TP и Entry 10 барами. |
| slShow | Показывает линию стоп-лосса на графике. |
| slMethod | Метод расчёта стоп-лосса: ATR, процент, тики, свинг, масштабированный ATR, Smart Adaptive, Safer. |
| tpDisplayMode | Стиль отображения тейк-профитов: Minimal или Detailed. |
| tpFreezeOnTouch | Замораживает линии тейк-профита при касании. |
| slAtrLen | Период ATR для расчёта стоп-лосса. |
| slAtrMult | Множитель ATR для расчёта стоп-лосса. |
| slPctStop | Процент от цены входа для стоп-лосса. |
| slTickStop | Количество тиков от цены входа для стоп-лосса. |
| slExtraTicks | Дополнительные тики буфера за расчётным стоп-лоссом. |
| tpShow | Показывает линии тейк-профита на графике. |
| tp1On | Включает уровень тейк-профита 1R. |
| tp15On | Включает уровень тейк-профита 1.5R. |
| tp2On | Включает уровень тейк-профита 2R. |
| tp3On | Включает уровень тейк-профита 3R. |
| i_useMTF | Включает подтверждение по старшему таймфрейму. |
| i_mtfTimeframe | Старший таймфрейм для подтверждения сигналов. |
| i_statsLookback | Количество дней для сбора статистики сделок. |
| i_showDivergence | Показывает дивергенции RSI на графике. |
| i_divRsiLen | Период RSI для расчёта дивергенции. |
| i_divLookback | Количество баров для подтверждения пивота при поиске дивергенции. |
| i_showRisk | Показывает калькулятор риска в таблице. |
| i_riskMode | Режим расчёта риска: процент от счёта или фиксированная сумма. |
| i_riskPct | Процент от счёта для риска на сделку. |
| i_riskFixed | Фиксированная сумма риска на сделку при режиме Fixed Amount. |
| i_useLiveRates | Использовать живые курсы валют для калькулятора риска. |
| i_manualRate | Ручной обменный курс для калькулятора риска. |
| i_enablePrediction | Включает прогноз длительности тренда на основе исторических данных. |
| i_predMode | Режим прогноза: Simple, Standard, Advanced. |
| i_predSamples | Количество прошлых трендов для анализа при прогнозе. |
| i_showPredBoxes | Показывает градиентные блоки прогноза длительности тренда. |
| i_showPredLabels | Показывает метки вероятности на прогнозе. |
Поиск по коду файла
indicator("Luxy UT GOD - UT-BOT Forecast", shorttitle="Luxy UT God Mode", overlay=true, max_bars_back=5000, max_lines_count=500, max_labels_count=500, max_boxes_count=500)
GROUP_UT = "================== UT Bot Settings =================="
GROUP_L1 = "🛡️ Anti-Whipsaw (Regime) ___________________________"
GROUP_FILTERS = "🎯 Signal Filters __________________________________"
GROUP_SL = "💵 Stoploss and Take Profit_________________________"
GROUP_L2 = "🔄 Adaptive Parameters _____________________________"
GROUP_L3 = "📈 MTF Confirmation ________________________________"
GROUP_CALC = "🔢 Risk Calculator _________________________________"
GROUP_PRED = "🔮 Trend Prediction ________________________________"
const float TP1 = 1.0
const float TP1_5 = 1.5
const float TP2 = 2.0
const float TP3 = 3.0
const string ASSET_AUTO = "Auto-Detect"
const string ASSET_STOCK = "Stock"
const string ASSET_CRYPTO = "Crypto"
const string ASSET_FOREX = "Forex"
const string ASSET_FUTURES = "Futures"
const string ASSET_INDEX = "Index"
const string ASSET_FUND = "Fund/ETF"
const string ASSET_CFD = "CFD"
const string ASSET_BOND = "Bond"
const string ADAPT_FIXED = "Fixed"
const string ADAPT_DYNAMIC = "Dynamic"
const string ADAPT_AGGRESSIVE = "Aggressive"
const string MTF_AUTO = "Auto (×4)"
const string MTF_5M = "5m"
const string MTF_15M = "15m"
const string MTF_30M = "30m"
const string MTF_1H = "1H"
const string MTF_4H = "4H"
const string MTF_D = "D"
const string MTF_W = "W"
utShowLabels = input.bool(true, "Buy/Sell Labels", group=GROUP_UT, inline="ut2")
labelSizeStr = input.string("Small", "| Size", options=["Tiny", "Small", "Normal", "Large"], group=GROUP_UT, inline="ut2", tooltip = "Size of all labels on chart\n• Tiny: Minimal\n• Small: Default ⭐\n• Normal: Medium\n• Large: Easy to see")
utShowLine = input.bool(false, "UT Line", group=GROUP_UT, inline="ut3")
utShowRibbon = input.bool(false, "Ribbon Fill", group=GROUP_UT, inline="ut3", tooltip = "Buy/Sell Labels: Show BUY/SELL signals on chart\nUT Line: Plot the ATR trailing stop line\nColor Bars: Aqua=bullish, Orange=bearish\nRibbon Fill: Gradient fill between price and UT line")
utColorBars = input.bool(false, "Color Bars", group=GROUP_UT, inline="ut3")
i_showTable = input.bool(true, "Show Table", group=GROUP_UT, inline="tb1")
i_tablePos = input.string("Top Right", "Position", options=["Top Left", "Top Right", "Bottom Left", "Bottom Right"], group=GROUP_UT, inline="tb1")
i_tableSize = input.string("Normal", "Size", options=["Tiny", "Small", "Normal", "Large"], group=GROUP_UT, inline="tb1", tooltip = "Table text size\n• Tiny: Minimal footprint\n• Small: Balanced ⭐\n• Normal: Easy to read")
utKey = input.float(1.2, "Sensitivity", group=GROUP_UT, step=0.1, minval=0.1, inline="ut1")
utAtrPeriod = input.int(7, "/ ATR Period", group=GROUP_UT, minval=1, inline="ut1", tooltip = "SENSITIVITY (Key × ATR):\nMultiplier for trailing stop distance\n• Higher = wider stop, fewer flips\n• Lower = tighter stop, more signals\n\nATR PERIOD:\nLookback for volatility\n\nPRESETS:\n• Scalp (1-5m): Key 0.9-1.2, ATR 5-7\n• Intraday (5-15m): Key 1.3-1.6, ATR 7-10 ⭐\n• Swing (D/W): Key 1.7-2.2, ATR 10-14")
labelSize = switch labelSizeStr
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
=> size.small
i_enableLayer1 = input.bool(true, "Enable Anti-Whipsaw", group=GROUP_L1, inline="L1a", tooltip = "Master switch for Anti-Whipsaw filter\n\nWhen ON: Signals filtered by ADX regime\nWhen OFF: All UT signals pass through")
i_adxPeriod = input.int(14, "ADX", minval=5, maxval=50, group=GROUP_L1, inline="L1b")
i_adxThreshold = input.int(20, "/ Thresh", minval=10, maxval=40, group=GROUP_L1, inline="L1b", tooltip = "ADX PERIOD: Lookback for calculation\n• 10-14: Responsive ⭐\n• 20+: Smoother\n\nTHRESHOLD: Min ADX for 'trending'\n• < Threshold = Choppy (signals blocked)\n• >= Threshold = Trending (signals allowed)\n• 20-25: Typical ⭐")
i_cooldownBars = input.int(3, "Cooldown", minval=0, maxval=20, group=GROUP_L1, inline="L1c")
i_confirmBars = input.int(1, "/ Confirm", minval=1, maxval=5, group=GROUP_L1, inline="L1c", tooltip = "COOLDOWN: Min bars between signals\n• 0 = Disabled\n• 2-5 = Typical ⭐\n• Prevents rapid flip-flop\n\nCONFIRM: Bars to confirm direction\n• 1 = Immediate ⭐\n• 2-3 = Conservative")
i_assetType = input.string(ASSET_AUTO, "Asset Type", options=[ASSET_AUTO, ASSET_STOCK, ASSET_CRYPTO, ASSET_FOREX, ASSET_FUTURES, ASSET_INDEX, ASSET_FUND, ASSET_CFD, ASSET_BOND], group=GROUP_L2, inline="L2a")
i_adaptiveMode = input.string(ADAPT_DYNAMIC, "| Adaptive Mode", options=[ADAPT_FIXED, ADAPT_DYNAMIC, ADAPT_AGGRESSIVE], group=GROUP_L2, inline="L2a", tooltip = "ASSET TYPE:\nAffects sensitivity multipliers for Key Value\n\n• Auto-Detect: Identifies based on symbol ⭐\n• Stock: Standard (1.0×)\n• Crypto: Wider stops (1.5×) - high volatility\n• Forex: Tighter stops (0.8×) - low volatility\n• Futures: Moderate (1.2×)\n• Index: Slightly tighter (0.9×)\n• Fund/ETF: Slightly tighter (0.9×)\n• CFD: Standard (1.0×)\n• Bond: Much tighter (0.5×) - low volatility\n\n" + "ADAPTIVE MODE:\nHow Key Value adjusts to market volatility\n\n• Fixed: Use input values as-is (no auto-adjustment)\n• Dynamic: Auto-adjust based on volatility ⭐\n - Low vol (< 0.8×): Key × 0.85\n - Normal (0.8-1.2×): Key × 1.0\n - High vol (> 1.2×): Key × 1.15\n• Aggressive: Wider adjustments\n - Low vol: Key × 0.7\n - High vol: Key × 1.3")
i_useVolatility = input.bool(false, "High Vol Filter", group=GROUP_FILTERS, inline="L1d")
i_volLookback = input.int(50, "/ Lookback", minval=10, maxval=200, group=GROUP_FILTERS, inline="L1d")
i_volThresh = input.float(1.2, "× Avg", minval=1.0, maxval=3.0, step=0.1, group=GROUP_FILTERS, inline="L1d", tooltip = "HIGH VOLATILITY FILTER:\nDetects when current ATR is above average\n\nLOOKBACK: Bars to calculate average ATR\n• 50: Standard ⭐\n• 100+: Smoother\n\nTHRESHOLD:\n• 1.2×: Slightly elevated ⭐\n• 1.5×: High volatility\n• 2.0×: Extreme volatility\n\nWhen ON: Only allow signals in high volatility")
utUseSwingFilter= input.bool(true, "Swing Filter", group=GROUP_FILTERS, inline="sf1")
swingLen = input.int(8, "/ Lookback", group=GROUP_FILTERS, minval=1, inline="sf1", tooltip = "SWING FILTER:\nOnly signals aligned with swing structure\n\nLOOKBACK: Bars to find swing high/low\n• 5-10: Scalp/Day trading ⭐\n• 10-20: Swing trading")
utUsePctFilter = input.bool(false, "% Filter", group=GROUP_FILTERS, inline="sf2")
utPctThr = input.float(0.05, "/ Min %", group=GROUP_FILTERS, step=0.05, minval=0, inline="sf2", tooltip = "% CHANGE FILTER:\nRequire minimum bar-to-bar % change\n\nMIN %: Threshold in percent\n• 0.1-0.5%: Intraday\n• 0.3-1.0%: Swing")
utUseDelay = input.bool(false, "2-Bar Confirm", group=GROUP_FILTERS, inline="sf3", tooltip = "Require 2 consecutive bars to confirm trend direction\n\n• Reduces false signals\n• Adds slight lag\n• Good for volatile markets")
i_useVolFilter = input.bool(false, "Volume Filter", group=GROUP_FILTERS, inline="sf4")
i_volSmaLen = input.int(20, "/ SMA", minval=5, maxval=100, group=GROUP_FILTERS, inline="sf4")
i_volThreshold = input.float(1.0, "× Avg", minval=0.5, maxval=3.0, step=0.1, group=GROUP_FILTERS, inline="sf4", tooltip = "Require volume above average to confirm signals\n\nSMA: Lookback period for average volume\n• 20: Standard ⭐\n\nTHRESHOLD:\n• 0.8×: Relaxed\n• 1.0×: Above average ⭐\n• 1.5×: Strong volume required")
i_useRsiFilter = input.bool(false, "RSI Filter", group=GROUP_FILTERS, inline="sf5")
i_rsiLen = input.int(14, "/ Len", minval=5, maxval=50, group=GROUP_FILTERS, inline="sf5", tooltip = "RSI MOMENTUM FILTER:\nConfirm signals with RSI direction\n\nLEN: RSI period (14 standard ⭐)")
i_rsiOB = input.int(70, "Overbought", minval=60, maxval=90, group=GROUP_FILTERS, inline="sf9")
i_rsiOS = input.int(30, "Oversold", minval=10, maxval=40, group=GROUP_FILTERS, inline="sf9", tooltip = "Overbought: Block BUY above this\n• 70: Standard ⭐\n• 80: Relaxed\n\nOversold: Block SELL below this\n• 30: Standard ⭐\n• 20: Relaxed")
i_useHullConfirm = input.bool(false, "Hull MA", group=GROUP_FILTERS, inline="sf6")
i_hullPeriod = input.int(20, "/ Period", minval=5, maxval=100, group=GROUP_FILTERS, inline="sf6", tooltip = "HULL MA CONFIRMATION:\nRequire Hull MA direction alignment\n\nPERIOD: Hull MA lookback\n• 14-20: Responsive ⭐\n• 30-50: Smoother\n\nBUY: Price must be above Hull MA\nSELL: Price must be below Hull MA")
i_useSuperTrend = input.bool(false, "SuperTrend", group=GROUP_FILTERS, inline="sf7")
i_stAtrPeriod = input.int(10, "/ ATR", minval=5, maxval=50, group=GROUP_FILTERS, inline="sf7")
i_stMult = input.float(3.0, "×", minval=1.0, maxval=5.0, step=0.1, group=GROUP_FILTERS, inline="sf7")
i_showStLine = input.bool(false, "Line", group=GROUP_FILTERS, inline="sf7", tooltip = "SUPERTREND FILTER:\nRequire SuperTrend confirmation\n\nBUY: Only when SuperTrend is bullish\nSELL: Only when SuperTrend is bearish\n\nATR: Period for volatility (10 standard ⭐)\nMULT: Multiplier (3.0 standard ⭐)\nLINE: Show SuperTrend line on chart")
i_useFullCandle = input.bool(true, "Full Candle", group=GROUP_FILTERS, inline="sf8", tooltip = "FULL CANDLE CONFIRMATION:\nRequire entire candle above/below UT line\n\n• BUY: Low must be above trailing stop\n• SELL: High must be below trailing stop\n\nPrevents signals on candles 'straddling' the line\nReduces false signals that quickly reverse")
utShowZones = input.bool(true, "S/R Zones", group=GROUP_FILTERS, inline="sfz")
i_useZoneFilter = input.bool(false, "| Zone Filter", group=GROUP_FILTERS, inline="sfz")
i_zoneWidthMult = input.float(0.5, "/ Width×ATR", group=GROUP_FILTERS, minval=0.1, maxval=2.0, step=0.1, inline="sfz", tooltip = "SUPPORT/RESISTANCE ZONES:\nClusters recent pivot highs/lows into persistent price zones (unlike the rolling Structure line above, these stay fixed until price revisits and breaks them)\n\nS/R ZONES: Show zone boxes on chart\nZONE FILTER: Block BUY inside a resistance zone, SELL inside a support zone\nWIDTH: Zone half-width as ATR multiple\n• 0.3-0.5: Tight zones ⭐\n• 0.8-1.2: Wide zones")
i_zonePivotLen = input.int(10, "/ Pivot Strength", minval=3, maxval=50, group=GROUP_FILTERS, inline="sfz2", tooltip = "S/R PIVOT STRENGTH:\nBars each side required to confirm a swing high/low for zone clustering.\n\n• 5-7: Minor swings (more, weaker zones)\n• 10: Balanced ⭐\n• 15-20: Only major swings (fewer, stronger zones)\n\nHigher than the Divergence pivot on purpose - S/R levels should be more significant than divergence pivots.")
entryShow = input.bool(true, "Show Entry Line", group=GROUP_SL, inline="SHOW")
linesLimit10 = input.bool(true, "Limit 10 bars", group=GROUP_SL, inline="SHOW", tooltip = "Limit all lines (SL, TP, Entry) to 10 bars\n• ON: Cleaner chart ⭐\n• OFF: Lines extend until next signal")
slShow = input.bool(true, "Show Stop Loss Line", group=GROUP_SL, inline="sl1")
slMethod = input.string("Smart Adaptive", "| SL Method", options=["ATR", "% Based", "Tick Based", "Swing", "Scaled ATR", "Smart Adaptive", "Safer"], group=GROUP_SL, inline="sl1", tooltip = "Stop Loss calculation method:\n\n⭐ SMART ADAPTIVE (Recommended):\n• Auto-adjusts to volatility\n• Low vol: 0.7× ATR | Med: 1.0× | High: 1.5×\n\nATR:\n• Standard ATR × Multiplier\n\n% BASED:\n• Fixed % from entry price\n• Good for high-price stocks\n\nTICK BASED:\n• Fixed number of ticks\n• Consistent dollar risk\n\nSWING:\n• Recent swing high/low\n\nSCALED ATR:\n• Dynamic multiplier by volatility\n\nSAFER:\n• Widest of ATR/Swing/% methods")
tpDisplayMode = input.string("Minimal", "TP Style", options=["Minimal", "Detailed"], group=GROUP_SL, inline="DIS")
tpFreezeOnTouch = input.bool(true, "Freeze Lines on Hit", group=GROUP_SL, inline="DIS", tooltip = "LINE DISPLAY STYLE:\n\n• Minimal: Clean labels (TP1, TP2, etc.)\n• Detailed: Shows price + % gain on label\n - Easier for trading execution\n - Example: 'TP1 $150.25 (+2.5%)'\n\nWhen ON: marks TP with ✅ when price touches it\nUseful for trade journaling and review")
slAtrLen = input.int(14, "ATR", minval=5, maxval=50, group=GROUP_SL, inline="sl3")
slAtrMult = input.float(1.5, "×", minval=0.5, maxval=3, step=0.1, group=GROUP_SL, inline="sl3", tooltip = "ATR Period & Multiplier\n• 7-10 / 1.0×: Day trading\n• 14 / 1.5×: Standard ⭐\n• 20+ / 2.0×: Swing trading")
slPctStop = input.float(5.0, "% Stop", minval=0.1, maxval=10.0, step=0.1, group=GROUP_SL, inline="sl5", tooltip = "Fixed % distance from entry\n• LONG: SL = Entry × (1 - %)\n• SHORT: SL = Entry × (1 + %)\n\n• 0.5%: Tight (scalping)\n• 1.0%: Balanced ⭐\n• 2.0%: Wide (swing)")
slTickStop = input.int(50, "Ticks", minval=5, maxval=500, step=5, group=GROUP_SL, inline="sl5", tooltip = "Fixed ticks from entry\n• Tick = minimum price movement\n• 20-50: Tight\n• 50-100: Normal ⭐\n• 100+: Wide")
slExtraTicks = input.int(0, "Buffer", minval=0, group=GROUP_SL, inline="sl6", tooltip = "Extra ticks beyond calculated SL\n• Protects against stop hunts\n• 0 = No buffer\n• 2-5 = Typical")
tpShow = input.bool(true, "Show TP Lines", group=GROUP_SL, inline="tp1")
tp1On = input.bool(true, "TP×1 (1R) |", group=GROUP_SL, inline="tp2")
tp15On = input.bool(false, "TP×1.5 |", group=GROUP_SL, inline="tp2")
tp2On = input.bool(true, "TP×2 |", group=GROUP_SL, inline="tp2")
tp3On = input.bool(false, "TP×3", group=GROUP_SL, inline="tp2", tooltip = "R = Risk Units (distance from entry to SL)\n\nTP1 (1R): Conservative, 1:1 risk/reward\nTP1.5 (1.5R): Intermediate target\nTP2 (2R): Balanced, 2:1 R:R ⭐\nTP3 (3R): Aggressive, 3:1 R:R\n\nRECOMMENDED:\n• Scalping: TP1 + TP1.5\n• Day Trading: TP1 + TP2 ⭐\n• Swing: TP2 + TP3")
i_useMTF = input.bool(false, "Enable MTF", group=GROUP_L3, inline="L3a", tooltip = "Multi-Timeframe Confirmation\n\nWhen ON: Only allow signals aligned with higher timeframe trend\n• BUY: HTF must be bullish\n• SELL: HTF must be bearish\n\nReduces counter-trend entries")
i_mtfTimeframe = input.string(MTF_AUTO, "Timeframe", options=[MTF_AUTO, MTF_5M, MTF_15M, MTF_30M, MTF_1H, MTF_4H, MTF_D, MTF_W], group=GROUP_L3, inline="L3a", tooltip = "HIGHER TIMEFRAME:\n\n• Auto (×4): 4× current TF ⭐\n - 1m → 5m\n - 5m → 15m\n - 15m → 1H\n - 1H → 4H\n - 4H → D\n - D → W\n\n• Manual: Select specific timeframe")
i_statsLookback = input.int(60, "Stats Days", minval=1, maxval=365, group=GROUP_L3, inline="L3b", tooltip = "STATISTICS LOOKBACK:\n\nHow many days back to count trades for Win Rate and Avg Bars.\n\n• 5: Recent performance ⭐\n• 30: Monthly view\n• 90: Quarterly view")
i_showDivergence = input.bool(true, "Show Divergence", group=GROUP_L3, inline="L3c", tooltip = "DIVERGENCE DETECTION:\n\nShows RSI divergences on chart\n\n• Bullish: Price ↓ + RSI ↑ (reversal up)\n• Bearish: Price ↑ + RSI ↓ (reversal down)\n\nUseful for spotting potential reversals")
i_divRsiLen = input.int(14, "RSI", minval=5, maxval=50, group=GROUP_L3, inline="L3c")
i_divLookback = input.int(5, "/ Pivot", minval=2, maxval=20, group=GROUP_L3, inline="L3c", tooltip = "RSI: Period for RSI calculation (14 standard)\n\nPIVOT: Bars to confirm pivot high/low\n• 3-5: More signals\n• 5-10: Fewer, stronger signals ⭐")
i_showRisk = input.bool(true, "Show Risk Calc", group=GROUP_CALC, inline="L3d", tooltip = "RISK CALCULATOR:\n\nCalculates position size based on:\n• Account size\n• Risk percentage OR fixed amount\n• Stop loss distance\n\nShows how many shares/contracts to buy")
i_riskMode = input.string("% of Account", "Risk Mode", options=["% of Account", "Fixed Amount"], group=GROUP_CALC, inline="L3d", tooltip = "RISK MODE:\n\n• % of Account: Risk X% of total account\n• Fixed Amount: Risk fixed $ amount per trade\n\nFixed is useful for consistent risk across all trades")
i_accountSize = input.float(10000, "Account $", minval=100, step=1000, group=GROUP_CALC, inline="L3e", tooltip = "Your total trading account size in account currency\n\nUsed to calculate:\n• Risk amount per trade (when using %)\n• Position size\n• Max position value")
i_riskPct = input.float(1.0, "Risk %", minval=0.1, maxval=10, step=0.1, group=GROUP_CALC, inline="L3e", tooltip = "Percentage of account to risk per trade\n(Only used when Risk Mode = '% of Account')\n\n• 0.5-1%: Conservative ⭐\n• 1-2%: Moderate\n• 2-3%: Aggressive")
i_riskFixed = input.float(100, "/ Fixed $", minval=1, step=10, group=GROUP_CALC, inline="L3e", tooltip = "Fixed amount to risk per trade\n(Only used when Risk Mode = 'Fixed Amount')\n\nExamples:\n• $50: Small accounts\n• $100: Medium ⭐\n• $200+: Larger accounts")
i_accountCurrency = input.string("USD", "Currency", options=["USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF"], group=GROUP_CALC, inline="L3f", tooltip = "Your account currency\n\nAffects position sizing calculations")
i_useLiveRates = input.bool(true, "Live Rates", group=GROUP_CALC, inline="L3f")
i_manualRate = input.float(1.0, "/ Manual $1=", minval=0.001, maxval=10000, step=0.01, group=GROUP_CALC, inline="L3f", tooltip = "Manual exchange rate (USD to your currency)\n\nExamples:\n• USD to ILS = 3.7\n• USD to EUR = 0.92\n• USD to JPY = 150\n\nUsed when Live Rates is OFF or unavailable")
i_enablePrediction = input.bool(true, "Enable Prediction", group=GROUP_PRED, inline="pred1", tooltip = "TREND PREDICTION:\n\nPredicts how long the current trend may last based on historical patterns.\n\n• Gradient boxes show expected duration\n• Labels show survival probability %\n• Dashboard shows prediction stats")
i_predMode = input.string("Standard", "Mode", options=["Simple", "Standard", "Advanced"], group=GROUP_PRED, inline="pred1", tooltip = "PREDICTION MODE:\n\n• Simple: Uses median duration only\n• Standard: EWA + standard deviation ⭐\n• Advanced: Adds 5 adaptive multipliers:\n - Structure (S/R proximity)\n - Stock Type (volatility profile)\n - Flip Strength (volume + filters)\n - Error Learning (self-correction)\n - Regime (trend vs chop)")
i_predSamples = input.int(50, "History", minval=10, maxval=100, group=GROUP_PRED, inline="pred2", tooltip = "HISTORY SIZE:\n\nNumber of past trends to analyze\n\n• 10-30: Responsive to recent changes\n• 50: Balanced ⭐\n• 100: Smoother, more stable")
i_showPredBoxes = input.bool(true, "Boxes", group=GROUP_PRED, inline="pred2", tooltip = "Show gradient boxes visualizing predicted trend duration\n\n• Fades from solid to transparent\n• Position: Below (bull) or above (bear) UT line")
i_showPredLabels = input.bool(true, "Labels", group=GROUP_PRED, inline="pred2", tooltip = "Show probability labels at key points\n\n• Shows survival % at 25%, 50%, 75%, 90%, 100% of prediction\n• Weibull probability distribution")
var line slLine = na
var label slLbl = na
var int slStartBar = na
var float baseSl = na
var float slPrice = na
var color slColor = na
var line tp1Line = na
var line tp15Line = na
var line tp2Line = na
var line tp3Line = na
var label tp1Lbl = na
var label tp15Lbl = na
var label tp2Lbl = na
var label tp3Lbl = na
var float tp1Y = na
var float tp15Y = na
var float tp2Y = na
var float tp3Y = na
var float tpInitRisk = na
var line entryLine = na
var label entryLbl = na
var int entryBar = na
var float entryPx = na
var color entryCol = na
var int statTotalTrades = 0
var int statWins = 0
var int statLosses = 0
var int statTotalBars = 0 // Sum of bars to TP (for avg calculation)
var int statWinBars = 0 // Count of wins with bar data
var bool statTradeOpen = false
var array<int> pred_bull_durations = array.new<int>()
var array<int> pred_bear_durations = array.new<int>()
var array<int> pred_all_durations = array.new<int>()
var array<bool> pred_all_is_bullish = array.new<bool>()
var int pred_current_bars = 0
var bool pred_is_bullish = true
var float pred_avg = na
var float pred_end = na
var bool pred_using_fallback = false
var array<float> pred_last10_predicted = array.new<float>()
var array<int> pred_last10_actual = array.new<int>()
var array<bool> pred_last10_bullish = array.new<bool>()
var array<float> pred_vol_ratios = array.new<float>()
var array<float> pred_quality_scores = array.new<float>()
var array<float> pred_error_ratios = array.new<float>()
var array<box> pred_boxes = array.new<box>()
var array<label> pred_labels = array.new<label>()
var array<float> zoneResPrice = array.new<float>()
var array<int> zoneResTouch = array.new<int>()
var array<int> zoneResStartBar = array.new<int>()
var array<box> zoneResBoxes = array.new<box>()
var array<label> zoneResLabels = array.new<label>()
var array<float> zoneSupPrice = array.new<float>()
var array<int> zoneSupTouch = array.new<int>()
var array<int> zoneSupStartBar = array.new<int>()
var array<box> zoneSupBoxes = array.new<box>()
var array<label> zoneSupLabels = array.new<label>()
detectRegime() =>
[diplus, diminus, adxValue] = ta.dmi(i_adxPeriod, i_adxPeriod)
bool isTrending = adxValue >= i_adxThreshold
isTrending
var int lastSignalBar = na
var int lastSignalDir = 0 // 1 = BUY, -1 = SELL, 0 = none
checkCooldown() =>
bool cooldownOk = na(lastSignalBar) or (bar_index - lastSignalBar >= i_cooldownBars)
cooldownOk
checkVolumeFilter() =>
if not i_useVolFilter
true
else
float volSma = ta.sma(volume, i_volSmaLen)
volume >= volSma * i_volThreshold
checkRSIFilter(_isBuy) =>
if not i_useRsiFilter
true
else
float rsiVal = ta.rsi(close, i_rsiLen)
_isBuy ? rsiVal < i_rsiOB : rsiVal > i_rsiOS
hullMA(series float src, simple int length) =>
ta.wma(2 * ta.wma(src, length / 2) - ta.wma(src, length), math.round(math.sqrt(length)))
hullValue = i_useHullConfirm ? hullMA(close, i_hullPeriod) : close
checkHullFilter(_isBuy) =>
if not i_useHullConfirm
true
else
_isBuy ? close > hullValue : close < hullValue
currentATR = ta.atr(14)
avgATR = ta.sma(currentATR, i_volLookback)
volatilityRatio = avgATR > 0 ? currentATR / avgATR : 1.0
isHighVol = volatilityRatio >= i_volThresh
checkVolatilityFilter() =>
if not i_useVolatility
true
else
isHighVol
stAtr = ta.atr(i_stAtrPeriod)
float stUp = hl2 - (i_stMult * stAtr)
float stDn = hl2 + (i_stMult * stAtr)
var float stUpperBand = na
var float stLowerBand = na
var int stDirection = 1 // 1 = bullish, -1 = bearish
stUpperBand := na(stUpperBand[1]) ? stUp : (stUp > stUpperBand[1] or close[1] < stUpperBand[1]) ? stUp : stUpperBand[1]
stLowerBand := na(stLowerBand[1]) ? stDn : (stDn < stLowerBand[1] or close[1] > stLowerBand[1]) ? stDn : stLowerBand[1]
stDirection := na(stDirection[1]) ? 1 :
stDirection[1] == -1 and close > stLowerBand[1] ? 1 :
stDirection[1] == 1 and close < stUpperBand[1] ? -1 :
stDirection[1]
float stValue = stDirection == 1 ? stUpperBand : stLowerBand
bool stBullish = stDirection == 1
bool stBearish = stDirection == -1
float stDistance = math.abs(close - stValue)
float stStrength = math.min(100, (stDistance / stAtr) * 25)
bool stFlipBull = stDirection == 1 and stDirection[1] == -1
bool stFlipBear = stDirection == -1 and stDirection[1] == 1
checkSuperTrendFilter(_isBuy) =>
if not i_useSuperTrend
true
else
_isBuy ? stBullish : stBearish
float sbSwingHigh = ta.highest(high, swingLen)
float sbSwingLow = ta.lowest(low, swingLen)
bool sbBullishBreak = close > sbSwingHigh[1] // Closed above previous swing high
bool sbBearishBreak = close < sbSwingLow[1] // Closed below previous swing low
float sbAtr = ta.atr(14)
float sbMid = (sbSwingHigh[1] + sbSwingLow[1]) / 2
float sbHalfRange = (sbSwingHigh[1] - sbSwingLow[1]) / 2
float sbBullDistance = sbBullishBreak ? (close - sbSwingHigh[1]) : 0
float sbBearDistance = sbBearishBreak ? (sbSwingLow[1] - close) : 0
float sbBreakStrength = math.min(100, math.max(sbBullDistance, sbBearDistance) / sbAtr * 30)
float sbPositionStrength = sbHalfRange > 0 ? math.min(100, math.abs(close - sbMid) / sbHalfRange * 100) : 0
float sbStrength = sbBullishBreak or sbBearishBreak ? sbBreakStrength : sbPositionStrength
bool sbBullish = close > sbMid // Above midpoint = bullish structure
bool sbBearish = close <= sbMid // At or below midpoint = bearish structure
bool l1_regimeOk = not i_enableLayer1 or detectRegime()
bool l1_cooldownOk = i_cooldownBars == 0 or checkCooldown()
bool l1_volumeOk = checkVolumeFilter()
bool l1_volatilityOk = checkVolatilityFilter()
detectAssetType() =>
if i_assetType != ASSET_AUTO
i_assetType
else
switch syminfo.type
"crypto" => ASSET_CRYPTO
"forex" => ASSET_FOREX
"futures" => ASSET_FUTURES
"index" => ASSET_INDEX
"fund" => ASSET_FUND
"cfd" => ASSET_CFD
"bond" => ASSET_BOND
=> ASSET_STOCK // stock or unknown → treat as stock
getAssetMultiplier(string assetType) =>
switch assetType
ASSET_CRYPTO => 1.5 // Crypto: wider stops (high volatility)
ASSET_FOREX => 0.8 // Forex: tighter stops (low volatility)
ASSET_FUTURES => 1.2 // Futures: moderate
ASSET_INDEX => 0.9 // Index: slightly tighter (diversified, less volatile)
ASSET_FUND => 0.9 // Fund/ETF: slightly tighter (diversified)
ASSET_CFD => 1.0 // CFD: standard (mirrors underlying)
ASSET_BOND => 0.5 // Bond: much tighter (very low volatility)
ASSET_STOCK => 1.0 // Stock: standard
=> 1.0
getAdaptiveMultiplier(float volRatio) =>
if i_adaptiveMode == ADAPT_FIXED
1.0
else if i_adaptiveMode == ADAPT_DYNAMIC
if volRatio < 0.8
0.85 // Low volatility: tighter stops
else if volRatio > 1.2
1.15 // High volatility: wider stops
else
1.0 // Normal volatility
else // ADAPT_AGGRESSIVE
if volRatio < 0.8
0.7 // Low volatility: much tighter
else if volRatio > 1.2
1.3 // High volatility: much wider
else
1.0 // Normal volatility
string detectedAsset = detectAssetType()
float assetMult = getAssetMultiplier(detectedAsset)
float adaptiveMult = getAdaptiveMultiplier(volatilityRatio)
getAutoHTF() =>
string htf = ""
if timeframe.isintraday
int mins = timeframe.multiplier
if timeframe.isseconds
mins := 1
else if timeframe.isminutes
mins := timeframe.multiplier
int htfMins = mins * 4
if htfMins < 60
htf := str.tostring(htfMins)
else if htfMins < 240
htf := str.tostring(htfMins / 60) + "H"
else if htfMins < 1440
htf := "4H"
else
htf := "D"
else if timeframe.isdaily
htf := "W"
else if timeframe.isweekly
htf := "M"
else
htf := "D"
htf
getSelectedHTF() =>
if i_mtfTimeframe == MTF_AUTO
getAutoHTF()
else
switch i_mtfTimeframe
MTF_5M => "5"
MTF_15M => "15"
MTF_30M => "30"
MTF_1H => "60"
MTF_4H => "240"
MTF_D => "D"
MTF_W => "W"
=> "60"
getCurrentTFMins() =>
int mins = 0
if timeframe.isseconds
mins := 1
else if timeframe.isminutes
mins := timeframe.multiplier
else if timeframe.isdaily
mins := 1440
else if timeframe.isweekly
mins := 10080
else if timeframe.ismonthly
mins := 43200
else
mins := timeframe.multiplier
mins
int currentTFMins = getCurrentTFMins()
[htf5mEmaFast, htf5mEmaSlow] = request.security(syminfo.tickerid, "5", [ta.ema(close, 9), ta.ema(close, 21)], lookahead=barmerge.lookahead_off)
[htf15mEmaFast, htf15mEmaSlow] = request.security(syminfo.tickerid, "15", [ta.ema(close, 9), ta.ema(close, 21)], lookahead=barmerge.lookahead_off)
[htf30mEmaFast, htf30mEmaSlow] = request.security(syminfo.tickerid, "30", [ta.ema(close, 9), ta.ema(close, 21)], lookahead=barmerge.lookahead_off)
[htf1hEmaFast, htf1hEmaSlow] = request.security(syminfo.tickerid, "60", [ta.ema(close, 9), ta.ema(close, 21)], lookahead=barmerge.lookahead_off)
[htf4hEmaFast, htf4hEmaSlow] = request.security(syminfo.tickerid, "240", [ta.ema(close, 9), ta.ema(close, 21)], lookahead=barmerge.lookahead_off)
[htfDEmaFast, htfDEmaSlow] = request.security(syminfo.tickerid, "D", [ta.ema(close, 9), ta.ema(close, 21)], lookahead=barmerge.lookahead_off)
[htfWEmaFast, htfWEmaSlow] = request.security(syminfo.tickerid, "W", [ta.ema(close, 9), ta.ema(close, 21)], lookahead=barmerge.lookahead_off)
int htf5mTrend = htf5mEmaFast > htf5mEmaSlow ? 1 : htf5mEmaFast < htf5mEmaSlow ? -1 : 0
int htf15mTrend = htf15mEmaFast > htf15mEmaSlow ? 1 : htf15mEmaFast < htf15mEmaSlow ? -1 : 0
int htf30mTrend = htf30mEmaFast > htf30mEmaSlow ? 1 : htf30mEmaFast < htf30mEmaSlow ? -1 : 0
int htf1hTrend = htf1hEmaFast > htf1hEmaSlow ? 1 : htf1hEmaFast < htf1hEmaSlow ? -1 : 0
int htf4hTrend = htf4hEmaFast > htf4hEmaSlow ? 1 : htf4hEmaFast < htf4hEmaSlow ? -1 : 0
int htfDTrend = htfDEmaFast > htfDEmaSlow ? 1 : htfDEmaFast < htfDEmaSlow ? -1 : 0
int htfWTrend = htfWEmaFast > htfWEmaSlow ? 1 : htfWEmaFast < htfWEmaSlow ? -1 : 0
string htfTimeframe = getSelectedHTF()
int htfTrend = switch htfTimeframe
"5" => htf5mTrend
"15" => htf15mTrend
"30" => htf30mTrend
"60" => htf1hTrend
"240" => htf4hTrend
"D" => htfDTrend
"W" => htfWTrend
=> htf1hTrend
string htfTrendStr = htfTrend == 1 ? "BULL" : htfTrend == -1 ? "BEAR" : "NEUTRAL"
trendEmoji(int t) => t == 1 ? "🟢" : t == -1 ? "🔴" : "⚪"
trendStr(int t) => t == 1 ? "BULL" : t == -1 ? "BEAR" : "NEUTRAL"
checkMTFFilter(_isBuy) =>
if not i_useMTF
true
else
_isBuy ? htfTrend >= 0 : htfTrend <= 0 // Allow neutral
float divRsi = ta.rsi(close, i_divRsiLen)
float pivotLow = ta.pivotlow(low, i_divLookback, i_divLookback)
float pivotHigh = ta.pivothigh(high, i_divLookback, i_divLookback)
float rsiPivotLow = ta.pivotlow(divRsi, i_divLookback, i_divLookback)
float rsiPivotHigh = ta.pivothigh(divRsi, i_divLookback, i_divLookback)
var float prevPriceLow = na
var float prevPriceHigh = na
var float prevRsiLow = na
var float prevRsiHigh = na
var int prevLowBar = na
var int prevHighBar = na
var bool bullishDiv = false
var bool bearishDiv = false
bullishDiv := false
bearishDiv := false
if not na(pivotLow) and not na(rsiPivotLow)
if not na(prevPriceLow) and not na(prevRsiLow)
bool priceLowerLow = pivotLow < prevPriceLow
bool rsiHigherLow = rsiPivotLow > prevRsiLow
if priceLowerLow and rsiHigherLow
bullishDiv := true
prevPriceLow := pivotLow
prevRsiLow := rsiPivotLow
prevLowBar := bar_index - i_divLookback
if not na(pivotHigh) and not na(rsiPivotHigh)
if not na(prevPriceHigh) and not na(prevRsiHigh)
bool priceHigherHigh = pivotHigh > prevPriceHigh
bool rsiLowerHigh = rsiPivotHigh < prevRsiHigh
if priceHigherHigh and rsiLowerHigh
bearishDiv := true
prevPriceHigh := pivotHigh
prevRsiHigh := rsiPivotHigh
prevHighBar := bar_index - i_divLookback
var string lastDivType = "None"
var int lastDivBar = na
if bullishDiv
lastDivType := "BULL"
lastDivBar := bar_index
if bearishDiv
lastDivType := "BEAR"
lastDivBar := bar_index
int barsSinceDiv = na(lastDivBar) ? 999 : bar_index - lastDivBar
const int ZONE_MAX = 3
registerZone(array<float> _prices, array<int> _touches, array<int> _startBars, float _pivotPrice, float _tolerance, int _startBar, float _currentPrice) =>
int n = array.size(_prices)
int matchIdx = -1
if n > 0
for i = 0 to n - 1
if math.abs(_pivotPrice - array.get(_prices, i)) <= _tolerance
matchIdx := i
if matchIdx >= 0
array.set(_prices, matchIdx, (array.get(_prices, matchIdx) + _pivotPrice) / 2)
array.set(_touches, matchIdx, array.get(_touches, matchIdx) + 1)
else
if n >= ZONE_MAX
int worstIdx = 0
float worstDist = math.abs(_currentPrice - array.get(_prices, 0))
for i = 1 to n - 1
float d = math.abs(_currentPrice - array.get(_prices, i))
if d > worstDist
worstDist := d
worstIdx := i
array.remove(_prices, worstIdx)
array.remove(_touches, worstIdx)
array.remove(_startBars, worstIdx)
array.push(_prices, _pivotPrice)
array.push(_touches, 1)
array.push(_startBars, _startBar)
zoneMatch(array<float> _prices, array<int> _touches, float _tolerance, float _price) =>
bool inside = false
int touchCount = 0
if array.size(_prices) > 0
for i = 0 to array.size(_prices) - 1
if math.abs(_price - array.get(_prices, i)) <= _tolerance
inside := true
touchCount := array.get(_touches, i)
[inside, touchCount]
nearestZoneIdx(array<float> _prices, float _price, bool _wantAbove) =>
int bestIdx = -1
float bestDist = 0.0
if array.size(_prices) > 0
for i = 0 to array.size(_prices) - 1
float zp = array.get(_prices, i)
bool onSide = _wantAbove ? zp > _price : zp < _price
float d = math.abs(_price - zp)
if onSide and (bestIdx == -1 or d < bestDist)
bestDist := d
bestIdx := i
bestIdx
const float ZONE_STALE_PCT = 0.06
pruneStaleZones(array<float> _prices, array<int> _touches, array<int> _startBars, float _currentPrice, float _maxDist) =>
int idx = array.size(_prices) - 1
while idx >= 0
if math.abs(_currentPrice - array.get(_prices, idx)) > _maxDist
array.remove(_prices, idx)
array.remove(_touches, idx)
array.remove(_startBars, idx)
idx -= 1
float zoneTol = sbAtr * i_zoneWidthMult
float zoneStaleDist = close * ZONE_STALE_PCT
float zonePivotHigh = ta.pivothigh(high, i_zonePivotLen, i_zonePivotLen)
float zonePivotLow = ta.pivotlow(low, i_zonePivotLen, i_zonePivotLen)
pruneStaleZones(zoneResPrice, zoneResTouch, zoneResStartBar, close, zoneStaleDist)
pruneStaleZones(zoneSupPrice, zoneSupTouch, zoneSupStartBar, close, zoneStaleDist)
if not na(zonePivotHigh)
registerZone(zoneResPrice, zoneResTouch, zoneResStartBar, zonePivotHigh, zoneTol, bar_index - i_zonePivotLen, close)
if not na(zonePivotLow)
registerZone(zoneSupPrice, zoneSupTouch, zoneSupStartBar, zonePivotLow, zoneTol, bar_index - i_zonePivotLen, close)
[nearResistance, nearResTouches] = zoneMatch(zoneResPrice, zoneResTouch, zoneTol, close)
[nearSupport, nearSupTouches] = zoneMatch(zoneSupPrice, zoneSupTouch, zoneTol, close)
checkZoneFilter(_isBuy) =>
if not i_useZoneFilter
true
else
_isBuy ? not nearResistance : not nearSupport
getCurrencySymbol(string curr) =>
switch curr
"USD" => "$"
"EUR" => "€"
"GBP" => "£"
"ILS" => "₪"
"JPY" => "¥"
"CAD" => "C$"
"AUD" => "A$"
"CHF" => "Fr"
=> "$"
string currSymbol = getCurrencySymbol(i_accountCurrency)
string fxPair = switch i_accountCurrency
"EUR" => "EURUSD"
"GBP" => "GBPUSD"
"ILS" => "USDILS"
"JPY" => "USDJPY"
"CAD" => "USDCAD"
"AUD" => "AUDUSD"
"CHF" => "USDCHF"
=> ""
float liveRate = na
if i_useLiveRates and fxPair != "" and i_accountCurrency != "USD"
liveRate := request.security(fxPair, "D", close, lookahead=barmerge.lookahead_off)
float defaultRate = switch i_accountCurrency
"EUR" => 0.92
"GBP" => 0.79
"ILS" => 3.70
"JPY" => 150.0
"CAD" => 1.38
"AUD" => 1.55
"CHF" => 0.90
=> 1.0
float exchangeRate = i_accountCurrency == "USD" ? 1.0 :
not i_useLiveRates ? i_manualRate :
na(liveRate) ? (i_manualRate != 1.0 ? i_manualRate : defaultRate) :
(i_accountCurrency == "EUR" or i_accountCurrency == "GBP" or i_accountCurrency == "AUD") ?
1/liveRate : liveRate
calcPositionSize(float _entry, float _sl) =>
float riskAmount = i_riskMode == "Fixed Amount" ? i_riskFixed : i_accountSize * (i_riskPct / 100)
string symbolCurr = syminfo.currency
if symbolCurr != i_accountCurrency and i_accountCurrency != "USD"
riskAmount := riskAmount / exchangeRate // Convert to USD first if symbol is USD-based
float riskPerShare = math.abs(_entry - _sl)
float shares = riskPerShare > 0 ? math.floor(riskAmount / riskPerShare) : 0
float posValue = shares * _entry
float maxLoss = shares * riskPerShare
[shares, posValue, maxLoss, riskAmount]
ewa_avg(array<int> arr, float decay) =>
float sum_w = 0.0
float sum_v = 0.0
int n = array.size(arr)
for i = 0 to n - 1
float w = math.pow(decay, n - 1 - i)
sum_w += w
sum_v += array.get(arr, i) * w
sum_w > 0 ? sum_v / sum_w : 0.0
ewa_stdev(array<int> arr, float avg, float decay) =>
float sum_w = 0.0
float sum_sq = 0.0
int n = array.size(arr)
for i = 0 to n - 1
float w = math.pow(decay, n - 1 - i)
float diff = array.get(arr, i) - avg
sum_w += w
sum_sq += w * diff * diff
sum_w > 0 ? math.sqrt(sum_sq / sum_w) : 0.0
array_median(array<int> arr) =>
int n = array.size(arr)
if n == 0
0.0
else
array<int> sorted = array.copy(arr)
array.sort(sorted)
n % 2 == 1 ? float(array.get(sorted, n/2)) : (array.get(sorted, n/2-1) + array.get(sorted, n/2)) / 2.0
get_structure_mult() =>
float pivotHi = ta.pivothigh(high, 10, 10)
float pivotLo = ta.pivotlow(low, 10, 10)
float atr = ta.atr(14)
bool nearLevel = (not na(pivotHi) and math.abs(close - pivotHi) < atr) or
(not na(pivotLo) and math.abs(close - pivotLo) < atr)
nearLevel ? 0.7 : 1.0
get_stock_type_mult(string _asset) =>
switch _asset
ASSET_CRYPTO => 0.60
ASSET_FOREX => 0.80
ASSET_FUTURES => 0.90
ASSET_BOND => 1.35
=> 1.0 // Stock, Index, Fund, CFD
get_flip_strength_mult(bool _regimeOk, bool _volFilterOk, bool _stFilterOk, float _currentATR, float _avgATR) =>
float vol_score = math.min(40, (volume / ta.sma(volume, 20) - 1) * 40)
float atr_score = math.min(30, ((_currentATR / _avgATR) - 1) * 30)
int filters_passed = 0
if _regimeOk
filters_passed += 1
if _volFilterOk
filters_passed += 1
if _stFilterOk
filters_passed += 1
float filter_score = filters_passed * 10 // 0-30 points
float total = vol_score + atr_score + filter_score
0.5 + (total / 100) * 1.5 // Range: 0.5x to 2.0x
get_learning_mult() =>
int n = array.size(pred_error_ratios)
if n < 3
1.0
else
float avg_err = array.avg(pred_error_ratios)
if avg_err > 1.0
1.0 - math.min((avg_err - 1.0) * 0.5, 0.15)
else
1.0 + math.min((1.0 - avg_err) * 0.5, 0.15)
get_regime_mult(bool _isBullish) =>
array<int> recent = _isBullish ? pred_bull_durations : pred_bear_durations
int n = array.size(recent)
if n < 6
1.0
else
float recent_avg = (array.get(recent, n-1) + array.get(recent, n-2) + array.get(recent, n-3)) / 3
float hist_avg = array.avg(recent)
float ratio = recent_avg / hist_avg
ratio >= 1.3 ? 1.2 : ratio >= 1.1 ? 1.1 : ratio <= 0.7 ? 0.8 : ratio <= 0.9 ? 0.9 : 1.0
srcUT = close
xATR = ta.atr(utAtrPeriod)
var float xATRTrailingStop = na
float momentum = ta.mom(srcUT, 5) / srcUT
float volRatio = volume / ta.sma(volume, 20)
float baseKey = utKey * assetMult * adaptiveMult
float adaptiveKey = baseKey * (1 + math.abs(momentum) * 2) * math.max(0.8, math.min(1.2, volRatio))
float trailDist = xATR * adaptiveKey
if na(xATRTrailingStop)
xATRTrailingStop := srcUT
else
float targetTrail = srcUT > xATRTrailingStop ? srcUT - trailDist : srcUT + trailDist
float smoothing = 0.3
xATRTrailingStop := xATRTrailingStop * (1 - smoothing) + targetTrail * smoothing
checkConfirmation(_isBuy) =>
bool confirmed = true
if i_confirmBars > 1
for i = 1 to i_confirmBars - 1
if _isBuy
if close[i] <= xATRTrailingStop[i]
confirmed := false
break
else
if close[i] >= xATRTrailingStop[i]
confirmed := false
break
confirmed
above = ta.crossover(srcUT, xATRTrailingStop)
below = ta.crossunder(srcUT, xATRTrailingStop)
atrPct = srcUT != 0 ? (xATR / srcUT * 100.0) : 0.0
float atrPctSafe = math.min(atrPct, 20.0)
kUT = 0.50
thr = math.max(utPctThr, atrPctSafe * kUT)
barbuy = srcUT > xATRTrailingStop
barsell = srcUT < xATRTrailingStop
bool pred_flip_to_bull = barbuy and not barbuy[1]
bool pred_flip_to_bear = barsell and not barsell[1]
bool pred_flip = pred_flip_to_bull or pred_flip_to_bear
int pred_completed_duration = pred_current_bars
pred_current_bars := pred_flip ? 1 : pred_current_bars + 1
if pred_flip
if pred_completed_duration > 1
if pred_is_bullish
array.push(pred_bull_durations, pred_completed_duration)
else
array.push(pred_bear_durations, pred_completed_duration)
array.push(pred_all_durations, pred_completed_duration)
array.push(pred_all_is_bullish, pred_is_bullish)
if array.size(pred_all_durations) > i_predSamples
array.shift(pred_all_durations)
array.shift(pred_all_is_bullish)
if array.size(pred_bull_durations) > i_predSamples
array.shift(pred_bull_durations)
if array.size(pred_bear_durations) > i_predSamples
array.shift(pred_bear_durations)
if i_enablePrediction and not na(pred_end) and pred_completed_duration > 1
array.push(pred_last10_predicted, pred_end)
array.push(pred_last10_actual, pred_completed_duration)
array.push(pred_last10_bullish, pred_is_bullish)
float error_ratio = pred_end > 0 ? float(pred_completed_duration) / pred_end : 1.0
array.push(pred_error_ratios, error_ratio)
if array.size(pred_last10_predicted) > 10
array.shift(pred_last10_predicted)
array.shift(pred_last10_actual)
array.shift(pred_last10_bullish)
if array.size(pred_error_ratios) > 10
array.shift(pred_error_ratios)
pred_is_bullish := pred_flip_to_bull
if i_enablePrediction
array<int> relevant = pred_is_bullish ? pred_bull_durations : pred_bear_durations
int samples = array.size(relevant)
if samples >= 3
pred_using_fallback := false
if i_predMode == "Simple"
float median = array_median(relevant)
pred_avg := median
pred_end := median * 2.5
else
float avg = ewa_avg(relevant, 0.9)
float stdev = ewa_stdev(relevant, avg, 0.9)
pred_avg := avg
pred_end := avg + 2.0 * stdev
if i_predMode == "Advanced"
float total_mult = 1.0
total_mult *= get_structure_mult()
total_mult *= get_stock_type_mult(detectedAsset)
total_mult *= get_flip_strength_mult(l1_regimeOk, checkVolumeFilter(), checkSuperTrendFilter(pred_is_bullish), currentATR, avgATR)
total_mult *= get_learning_mult()
total_mult *= get_regime_mult(pred_is_bullish)
total_mult := math.max(0.4, math.min(2.0, total_mult))
pred_end *= total_mult
else
pred_using_fallback := true
int allSamples = array.size(pred_all_durations)
if allSamples >= 3
float avgAll = ewa_avg(pred_all_durations, 0.9)
float stdevAll = ewa_stdev(pred_all_durations, avgAll, 0.9)
pred_avg := avgAll
pred_end := avgAll + 2.0 * stdevAll
else if allSamples >= 1
float avgAll = ewa_avg(pred_all_durations, 0.9)
pred_avg := avgAll
pred_end := avgAll * 2.5
else
pred_avg := 8.0
pred_end := 16.0
array<int> capArr = pred_all_durations
if samples >= 3
capArr := relevant
if not na(pred_end) and array.size(capArr) >= 3
float p90dur = array.percentile_nearest_rank(capArr, 90)
if p90dur > 0
pred_end := math.min(pred_end, p90dur)
chgOk = not utUsePctFilter or (math.abs(srcUT - srcUT[1]) / srcUT[1] * 100.0 > thr)
float _lo = na
float _hi = na
if utUseSwingFilter
_lo := ta.lowest(srcUT, swingLen)
_hi := ta.highest(srcUT, swingLen)
swingOkBuy = not utUseSwingFilter or srcUT > _lo * 1.01
swingOkSell = not utUseSwingFilter or srcUT < _hi * 0.99
flipUp = above
flipDn = below
utBuy = (utUseDelay ? ((bar_index > 1 ? flipUp[2] : false) and (bar_index > 0 ? barbuy[1] : false) and (bar_index > 1 ? barbuy[2] : false)) : flipUp) and chgOk and swingOkBuy
utSell = (utUseDelay ? ((bar_index > 1 ? flipDn[2] : false) and (bar_index > 0 ? barsell[1] : false) and (bar_index > 1 ? barsell[2] : false)) : flipDn) and chgOk and swingOkSell
bool fullCandleBuyOk = not i_useFullCandle or low > xATRTrailingStop // Entire candle above line
bool fullCandleSellOk = not i_useFullCandle or high < xATRTrailingStop // Entire candle below line
confirmRealBuy = close > xATRTrailingStop and fullCandleBuyOk
confirmRealSell = close < xATRTrailingStop and fullCandleSellOk
bool l1_confirmBuy = checkConfirmation(true)
bool l1_confirmSell = checkConfirmation(false)
utBuy := utBuy and confirmRealBuy and l1_regimeOk and l1_cooldownOk and l1_confirmBuy and l1_volumeOk and l1_volatilityOk and checkRSIFilter(true) and checkHullFilter(true) and checkSuperTrendFilter(true) and checkMTFFilter(true) and checkZoneFilter(true)
utSell := utSell and confirmRealSell and l1_regimeOk and l1_cooldownOk and l1_confirmSell and l1_volumeOk and l1_volatilityOk and checkRSIFilter(false) and checkHullFilter(false) and checkSuperTrendFilter(false) and checkMTFFilter(false) and checkZoneFilter(false)
utBuy := utBuy and lastSignalDir != 1
utSell := utSell and lastSignalDir != -1
if utBuy and barstate.isconfirmed
lastSignalBar := bar_index
lastSignalDir := 1
if utSell and barstate.isconfirmed
lastSignalBar := bar_index
lastSignalDir := -1
bool utVizGate = barstate.isconfirmed or not barstate.isrealtime
bool slFeatureOn = slShow and utShowLabels
bool tpFeatureOn = tpShow and utShowLabels
bool entryFeatureOn = entryShow
ensureSLObjects(line _ln, label _lb, int _x, float _y, color _c) =>
line ln_result = _ln
label lb_result = _lb
if na(ln_result) and not na(_x) and not na(_y)
ln_result := line.new(_x, _y, _x, _y, xloc=xloc.bar_index, extend=extend.none, color=_c, width=2)
if na(lb_result) and not na(_x) and not na(_y)
lb_result := label.new(_x, _y, "Suggested Stop Loss", xloc=xloc.bar_index, style=label.style_label_left, textcolor=color.white, color=_c, size=labelSize)
[ln_result, lb_result]
var bool legDone = false
var int legDoneBar = na
var bool slFrozen = false
var bool entryFrozen = false
var bool tp1Frozen = false
var bool tp15Frozen = false
var bool tp2Frozen = false
var bool tp3Frozen = false
bool slShowVis = slFeatureOn and (utVizGate or slFrozen or legDone)
bool tpShowVis = tpFeatureOn and (utVizGate or tp1Frozen or tp15Frozen or tp2Frozen or tp3Frozen or legDone)
bool entryShowVis = entryFeatureOn and (utVizGate or entryFrozen or legDone)
var bool tp1Hit = false
var bool tp15Hit = false
var bool tp2Hit = false
var bool tp3Hit = false
const int MAX_SIGNAL_LABELS = 30
var array<label> signalLabels = array.new<label>()
capX2(int x) =>
not na(legDoneBar) ? math.min(x, legDoneBar) : x
var table wm = table.new(position.bottom_right, 1, 1)
if barstate.isfirst
table.cell(wm, 0, 0, "Telegram @SimpleForexTools", text_color = color.new(color.gray, 70), text_size = size.large)
plot(utShowLine ? xATRTrailingStop : na, title="UT Trailing Stop", color=color.orange, linewidth=2)
plot(i_showStLine ? stValue : na, title="SuperTrend", color=stBullish ? color.green : color.red, linewidth=2, style=plot.style_linebr)
bool utPlotGate = utShowLabels and utVizGate
if utPlotGate and utBuy
label newLbl = label.new(bar_index, low, "Buy", style=label.style_label_up, color=color.aqua, textcolor=color.white, size=labelSize)
array.push(signalLabels, newLbl)
if array.size(signalLabels) > MAX_SIGNAL_LABELS
label.delete(array.shift(signalLabels))
if utPlotGate and utSell
label newLbl = label.new(bar_index, high, "Sell", style=label.style_label_down, color=color.orange, textcolor=color.white, size=labelSize)
array.push(signalLabels, newLbl)
if array.size(signalLabels) > MAX_SIGNAL_LABELS
label.delete(array.shift(signalLabels))
barcolor(utColorBars ? (barbuy ? color.aqua : barsell ? color.orange : na) : na)
bool ribbon_active = utShowRibbon
color ribbonBaseColor = barbuy ? #00CED1 : #FF6B6B
get_ribbon_layer(float _start, float _end, int _step) =>
(_start * (15 - _step) + _end * _step) / 15
float rl1 = ribbon_active ? close : na
float rl2 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 1) : na
float rl3 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 2) : na
float rl4 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 3) : na
float rl5 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 4) : na
float rl6 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 5) : na
float rl7 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 6) : na
float rl8 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 7) : na
float rl9 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 8) : na
float rl10 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 9) : na
float rl11 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 10) : na
float rl12 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 11) : na
float rl13 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 12) : na
float rl14 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 13) : na
float rl15 = ribbon_active ? get_ribbon_layer(close, xATRTrailingStop, 14) : na
float rl16 = ribbon_active ? xATRTrailingStop : na
color rc1 = ribbon_active ? color.new(ribbonBaseColor, 85) : na
color rc2 = ribbon_active ? color.new(ribbonBaseColor, 81) : na
color rc3 = ribbon_active ? color.new(ribbonBaseColor, 77) : na
color rc4 = ribbon_active ? color.new(ribbonBaseColor, 73) : na
color rc5 = ribbon_active ? color.new(ribbonBaseColor, 69) : na
color rc6 = ribbon_active ? color.new(ribbonBaseColor, 65) : na
color rc7 = ribbon_active ? color.new(ribbonBaseColor, 61) : na
color rc8 = ribbon_active ? color.new(ribbonBaseColor, 57) : na
color rc9 = ribbon_active ? color.new(ribbonBaseColor, 53) : na
color rc10 = ribbon_active ? color.new(ribbonBaseColor, 49) : na
color rc11 = ribbon_active ? color.new(ribbonBaseColor, 45) : na
color rc12 = ribbon_active ? color.new(ribbonBaseColor, 41) : na
color rc13 = ribbon_active ? color.new(ribbonBaseColor, 37) : na
color rc14 = ribbon_active ? color.new(ribbonBaseColor, 33) : na
color rc15 = ribbon_active ? color.new(ribbonBaseColor, 30) : na
rp1 = plot(rl1, display=display.none, editable=false)
rp2 = plot(rl2, display=display.none, editable=false)
rp3 = plot(rl3, display=display.none, editable=false)
rp4 = plot(rl4, display=display.none, editable=false)
rp5 = plot(rl5, display=display.none, editable=false)
rp6 = plot(rl6, display=display.none, editable=false)
rp7 = plot(rl7, display=display.none, editable=false)
rp8 = plot(rl8, display=display.none, editable=false)
rp9 = plot(rl9, display=display.none, editable=false)
rp10 = plot(rl10, display=display.none, editable=false)
rp11 = plot(rl11, display=display.none, editable=false)
rp12 = plot(rl12, display=display.none, editable=false)
rp13 = plot(rl13, display=display.none, editable=false)
rp14 = plot(rl14, display=display.none, editable=false)
rp15 = plot(rl15, display=display.none, editable=false)
rp16 = plot(rl16, display=display.none, editable=false)
fill(rp1, rp2, ribbon_active ? rc1 : na, editable=false)
fill(rp2, rp3, ribbon_active ? rc2 : na, editable=false)
fill(rp3, rp4, ribbon_active ? rc3 : na, editable=false)
fill(rp4, rp5, ribbon_active ? rc4 : na, editable=false)
fill(rp5, rp6, ribbon_active ? rc5 : na, editable=false)
fill(rp6, rp7, ribbon_active ? rc6 : na, editable=false)
fill(rp7, rp8, ribbon_active ? rc7 : na, editable=false)
fill(rp8, rp9, ribbon_active ? rc8 : na, editable=false)
fill(rp9, rp10, ribbon_active ? rc9 : na, editable=false)
fill(rp10, rp11, ribbon_active ? rc10 : na, editable=false)
fill(rp11, rp12, ribbon_active ? rc11 : na, editable=false)
fill(rp12, rp13, ribbon_active ? rc12 : na, editable=false)
fill(rp13, rp14, ribbon_active ? rc13 : na, editable=false)
fill(rp14, rp15, ribbon_active ? rc14 : na, editable=false)
fill(rp15, rp16, ribbon_active ? rc15 : na, editable=false)
int PRED_BOXES_PER_SET = 30
bool pred_draw_flip = pred_flip and utVizGate
if i_enablePrediction and pred_draw_flip
float pe = (na(pred_end) or pred_end <= 0) ? 16.0 : pred_end
float pa = na(pred_avg) ? pe / 2.0 : pred_avg
bool peFallback = pred_using_fallback or na(pred_end) or pred_end <= 0
bool isBull = pred_is_bullish
color base_col = isBull ? color.green : color.red
if array.size(pred_boxes) > 0
for i = 0 to array.size(pred_boxes) - 1
box.delete(array.get(pred_boxes, i))
array.clear(pred_boxes)
if array.size(pred_labels) > 0
for i = 0 to array.size(pred_labels) - 1
label.delete(array.get(pred_labels, i))
array.clear(pred_labels)
float predATR = ta.atr(14)
float box_height = predATR * 0.12
float box_top = na
float box_bottom = na
if isBull
box_top := xATRTrailingStop - predATR * 0.03
box_bottom := box_top - box_height
else
box_bottom := xATRTrailingStop + predATR * 0.03
box_top := box_bottom + box_height
float box_width = pe / PRED_BOXES_PER_SET
array<int> relevant = isBull ? pred_bull_durations : pred_bear_durations
array<int> survArr = array.size(relevant) >= 3 ? relevant : pred_all_durations
if i_showPredBoxes
for i = 0 to PRED_BOXES_PER_SET - 1
int box_left = bar_index + int(i * box_width)
int box_right = bar_index + math.max(int((i + 1) * box_width), int(i * box_width) + 1)
int opacity = 5 + int((i / 29.0) * 90)
box nb = box.new(box_left, box_top, box_right, box_bottom, bgcolor=color.new(base_col, opacity), border_color=na)
array.push(pred_boxes, nb)
int header_samples = peFallback ? array.size(pred_all_durations) : array.size(relevant)
string direction_str = isBull ? "BULLISH" : "BEARISH"
string confidence_str = header_samples >= 30 ? "High" : header_samples >= 15 ? "Medium" : "Low"
string fallback_note = peFallback ? "\n⚠️ Not enough " + direction_str + "-only history yet - rough estimate, sharpens as more trends complete.\n" : ""
string header_tooltip = "📊 TREND FORECAST\n═══════════════════════\n\n🎯 Direction: " + direction_str + "\n📈 Mode: " + i_predMode + "\n\n⏱️ DURATION ESTIMATE:\n• Predicted total: " + str.tostring(pe, "#") + " bars\n• Average: " + str.tostring(pa, "#.#") + " bars\n" + fallback_note + "\n📊 DATA:\n• Sample Size: " + str.tostring(header_samples) + " trends\n• Confidence: " + confidence_str + "\n\n" + (i_predMode == "Advanced" and not peFallback ? "🔬 ADVANCED MULTIPLIERS:\n• Structure • Asset Type • Flip Strength\n• Error Learning • Regime\n\n" : "") + "💡 % labels = share of past " + direction_str + " trends that lasted at least that long.\n\n⚠️ Historical analysis, not a guarantee."
int center_bar = bar_index + int(pe / 2)
label lbl_center = label.new(center_bar, box_top, "🔮 Trend Analysis", style=isBull ? label.style_label_down : label.style_label_up, color=color.new(color.blue, 0), textcolor=color.white, size=size.small, tooltip=header_tooltip, yloc=yloc.price)
array.push(pred_labels, lbl_center)
if i_showPredLabels
int survN = array.size(survArr)
array<int> survPct = array.from(25, 50, 75, 90)
float lbl_y = isBull ? box_bottom - predATR * 0.15 : low - predATR * 0.5
for q in survPct
int surv = 100 - q
float dur = survN >= 4 ? array.percentile_nearest_rank(survArr, q) : pe * (q / 100.0)
int x = bar_index + math.max(1, int(dur))
string direction = isBull ? "BULL" : "BEAR"
string lbl_tooltip = "🎯 Trend Survival\n\n" + str.tostring(surv) + "% of past " + direction + " trends lasted at least ~" + str.tostring(int(dur)) + " bars from the flip.\n\nBased on " + str.tostring(survN) + " past trends" + (survN >= 4 ? "" : " (modeled - low history)")
label lbl_prob = label.new(x, lbl_y, str.tostring(surv) + "%", style=label.style_none, textcolor=base_col, text_formatting=text.format_bold, size=size.small, yloc=yloc.price, tooltip=lbl_tooltip)
array.push(pred_labels, lbl_prob)
if i_showDivergence and bullishDiv
string bullDivTooltip = "🟢 BULLISH DIVERGENCE\n\nPrice: Lower Low ↘\nRSI: Higher Low ↗\n\nPrevious Price Low: " + str.tostring(prevPriceLow, "#.##") + "\n" + "Current Price Low: " + str.tostring(pivotLow, "#.##") + "\n" + "Previous RSI Low: " + str.tostring(prevRsiLow, "#.#") + "\n" + "Current RSI Low: " + str.tostring(rsiPivotLow, "#.#") + "\n\n" + "📈 SIGNAL: Potential reversal UP\n" + "Selling pressure weakening despite lower prices"
label.new(bar_index - i_divLookback, low[i_divLookback], "Bull\nDiv",
style=label.style_label_up, color=color.new(color.green, 30),
textcolor=color.white, size=labelSize, tooltip=bullDivTooltip)
if i_showDivergence and bearishDiv
string bearDivTooltip = "🔴 BEARISH DIVERGENCE\n\n" + "Price: Higher High ↗\n" + "RSI: Lower High ↘\n\n" + "Previous Price High: " + str.tostring(prevPriceHigh, "#.##") + "\n" + "Current Price High: " + str.tostring(pivotHigh, "#.##") + "\n" + "Previous RSI High: " + str.tostring(prevRsiHigh, "#.#") + "\n" + "Current RSI High: " + str.tostring(rsiPivotHigh, "#.#") + "\n\n" + "📉 SIGNAL: Potential reversal DOWN\n" + "Buying pressure weakening despite higher prices"
label.new(bar_index - i_divLookback, high[i_divLookback], "Bear\nDiv",
style=label.style_label_down, color=color.new(color.red, 30),
textcolor=color.white, size=labelSize, tooltip=bearDivTooltip)
slBuf = xATR * 0.10
slATR = ta.atr(slAtrLen)
atrPercent = close != 0 ? (slATR / close * 100) : 1.0
calcLongSL(_entry) =>
float sl = na
float tickValue = syminfo.mintick
if slMethod == "ATR"
sl := _entry - (slATR * slAtrMult)
else if slMethod == "% Based"
sl := _entry * (1 - slPctStop / 100)
else if slMethod == "Tick Based"
sl := _entry - (slTickStop * tickValue)
else if slMethod == "Swing"
float swingFloor = ta.lowest(low, swingLen)
sl := not na(swingFloor) and swingFloor < _entry ? swingFloor : _entry - slATR * 1.5
else if slMethod == "Scaled ATR"
float scaledMult = atrPercent > 5 ? 2.5 :
atrPercent > 3 ? 2.0 :
atrPercent > 1.5 ? 1.5 : 1.2
float atrDist = slATR * sПоказано первые 50% кода (символов: 94087)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.