← К каталогу
Исходный код · ID 4134

FVG Retest Entry Engine

indicator fvg retest entry engine for tradingview.pine
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Публичное название продукта подтверждено заголовком индикатора в исходном коде: FVG Retest Entry Engine. Это индикатор для TradingView, написанный на Pine Script v6 и работающий на графике в виде наложения. Он выполняет технические расчёты средствами Pine Script, получает данные другого таймфрейма через request.security(), отображает линии, метки и области на графике и задаёт условия для оповещений TradingView.

Логика построена вокруг анализа структуры рынка и областей имбаланса (FVG): индикатор отслеживает подтверждённые пробои свинговых уровней, запоминает сформированные ценовые разрывы, оценивает их качество и ожидает возврата цены в выбранную зону. При подтверждённом возврате формируется модель сделки с расчётными уровнями входа, защитной остановки и трёх целей, которые отображаются на графике линиями, областями и метками. Все сигналы и оповещения фиксируются только после закрытия свечи.

Индикатор предоставляет несколько профилей работы (Original Sync, Balanced Flow, Precision Flow, Fast Flow, Position Flow, Custom Lab), а также набор фильтров: проверка объёма, направленной силы (DI/ADX), старшего таймфрейма и минимального качества сетапа. Доступны настройки внешнего вида, темы оформления, панель состояния и центр оповещений с несколькими пакетами доставки, включая структурированный JSON для вебхуков.

Важно: индикатор не является автоматическим советником и не совершает сделок; он выполняет анализ и отображение, а также формирует условия для оповещений. Описанные возможности подтверждены исходным кодом.

Настройки программы

НастройкаОписание
tws_engine_profile Выбирает профиль работы: Original Sync сохраняет первую проверенную карту сигналов, остальные профили применяют разные модели чувствительности, а Custom Lab открывает все расширенные параметры.
tws_allow_longs Разрешает формировать модели входа по подтверждённым бычьим реакциям на разрыв.
tws_allow_shorts Разрешает формировать модели входа по подтверждённым медвежьим реакциям на разрыв.
tws_passport_mode Добавляет идентификацию сетапа к каждому подтверждённому ретесту: компактный режим показывает возраст и глубину, подробный также структуру, размер разрыва и статус фильтров.
tws_show_blocker_lens Поясняет текущее состояние движка, включая ожидание структуры, задержку ретеста, блокировки объёма, DI, старшего таймфрейма, слабую реакцию, блокировку оценки и готовность к закрытию.
tws_signal_timing_mode Оба режима фиксируют входы, метки и оповещения только после закрытия свечи; режим предпросмотра обновляет панель внутри бара, не превращая промежуточные условия в исторические сигналы.
tws_classic_preset Воспроизводит первую проверенную калибровку сигналов; ручной режим открывает базовые значения, а рыночные карты применяют соответствующие переопределения.
tws_classic_structure_len_input Управляет тем, насколько быстро распознаются подтверждённые свинговые точки.
tws_classic_min_fvg_atr_input Минимальная ширина трёхсвечного разрыва относительно ATR.
tws_classic_max_fvg_age_input Удаляет активные разрывы после заданного числа свечей.
tws_classic_max_fvg_zones_input Ограничивает число активных объектов разрывов для производительности.
tws_classic_max_fvg_distance_input Ограничивает расстояние от связанного события структуры до формирования разрыва.
tws_classic_post_break_scan_input Продолжает поиск подходящего разрыва после подтверждения пробоя.
tws_classic_retest_mode_input Определяет, как Original Sync распознаёт допустимый возврат в выбранный разрыв.
tws_classic_touch_tolerance_input Добавляет небольшой ценовой запас вокруг границы выбранного разрыва.
tws_classic_min_retest_delay_input Блокирует реакции, возникающие слишком рано после события структуры.
tws_classic_max_bars_to_wait_input Отменяет выбранный сетап, если допустимая реакция не появилась вовремя.
tws_classic_volume_multiplier_input Требование к объёму относительно выбранной базовой линии.
tws_classic_minimum_adx_input Минимальная сила направленного движения, требуемая проверкой.
tws_classic_minimum_stars Задаёт минимальный рейтинг Original Sync, необходимый для выпуска сигнала.
tws_classic_minimum_stop_input Предотвращает нереалистично близкие защитные остановки.
tws_structure_len_input Управляет тем, насколько быстро распознаются подтверждённые свинговые точки.
tws_show_structure Показывает необязательные метки пробоев структуры на графике; по умолчанию отключено для более чистого вида.
tws_require_body_close Требует закрытия свечи за уровнем структуры; при отключении допускаются пробои по теням.
tws_use_break_displacement Требует заметного импульса на свече, пробивающей свинговый уровень.
tws_minimum_break_body_atr_input Минимальное расширение тела свечи для допустимого пробоя структуры.
tws_break_buffer_atr_input Добавляет расстояние на основе волатильности за свинговым уровнем до подтверждения пробоя.
tws_min_fvg_atr_input Минимальная ширина трёхсвечного разрыва относительно ATR.
tws_use_fvg_displacement_filter Отфильтровывает разрывы, сформированные без сильного направленного импульса.
tws_minimum_fvg_displacement_input Минимальный импульс, требуемый при формировании разрыва.
tws_minimum_zone_quality_input Наименьшая внутренняя оценка разрыва, допускаемая в движок реакции.
tws_maximum_prior_touches_input Управляет тем, сколько предыдущих реакций может содержать разрыв до отклонения.
tws_max_fvg_age_input Удаляет активные разрывы после заданного числа свечей.
tws_max_fvg_zones_input Ограничивает число активных объектов разрывов для производительности.
tws_max_fvg_distance_input Ограничивает расстояние от связанного события структуры до формирования разрыва.
tws_post_break_scan_bars_input Продолжает поиск подходящего разрыва после подтверждения пробоя.
tws_remove_invalid_fvgs Удаляет бычий разрыв после закрытия ниже него и медвежий разрыв после закрытия выше него.
tws_retest_mode_input Выбирает модель распознавания реакции: первое касание, направленное восстановление, возврат границы или строгая модель отклонения.
tws_touch_tolerance_input Добавляет небольшой ценовой запас вокруг границы выбранного разрыва.
tws_minimum_reaction_score_input Задаёт минимальное качество свечи реакции, требуемое движком.
tws_min_retest_delay_input Блокирует реакции, возникающие слишком рано после события структуры.
tws_max_bars_to_wait_input Отменяет выбранный сетап, если допустимая реакция не появилась вовремя.
tws_cooldown_after_close Предотвращает немедленный повторный вход после закрытия предыдущей модели сделки.
tws_use_volume_filter Требует, чтобы объём свечи подтверждения превышал базовую линию.
tws_volume_length Задаёт длину скользящей средней, используемой в проверке объёма.
tws_volume_multiplier_input Требование к объёму относительно выбранной базовой линии.
tws_use_di_filter Требует, чтобы направление DI и сила тренда поддерживали сетап.
tws_di_length Период расчёта направленной силы (DI).
tws_adx_smoothing Период сглаживания для расчёта силы тренда в проверке направленной силы.
tws_minimum_adx_input Минимальная сила тренда, требуемая проверкой направленной силы.
tws_use_htf_filter Разрешает входы только тогда, когда выбранный старший таймфрейм подтверждает то же смещение.
tws_htf_timeframe Выбирает таймфрейм выше графика для проверки смещения; равные или меньшие значения игнорируются.
tws_htf_fast_length Период быстрой EMA на выбранном старшем таймфрейме для определения смещения.
tws_htf_slow_length Период медленной EMA на выбранном старшем таймфрейме для определения смещения.
tws_minimum_grade_input Выбирает наименьшую оценку сетапа, допустимую для создания модели сделки.
tws_atr_length Период расчёта ATR, используемого для оценки волатильности и расстояний.
tws_stop_mode Выбирает модель размещения защиты: за выбранным разрывом или на расстоянии от цены входа по волатильности.
tws_atr_stop_multiplier Множитель ATR для расчёта расстояния защитной остановки от цены входа в режиме волатильности.
tws_fvg_stop_buffer_atr Добавляет запас на основе ATR за границей выбранного разрыва для защитной остановки.
tws_minimum_stop_percent_input Предотвращает нереалистично близкие защитные остановки.
tws_tp1_r Множитель риска для расчёта первой цели.
tws_tp2_r Множитель риска для расчёта второй цели.
tws_tp3_r Множитель риска для расчёта третьей цели.
tws_tp1_close_percent Доля позиции, закрываемая при достижении первой цели.
tws_tp2_close_percent Доля позиции, закрываемая при достижении второй цели.
tws_tp3_close_percent Доля позиции, закрываемая при достижении третьей цели; TP3 закрывает оставшуюся часть.
tws_move_to_breakeven Переводит активную остановку в цену входа на свече после достижения TP1.
tws_intrabar_priority Определяет приоритет при обработке целей и остановки внутри одной свечи.
tws_theme_input Переключает полную визуальную тему оформления графика.
tws_fvg_display_mode Управляет отображением разрывов: только связанный с текущим сетапом, все активные или скрытие.
tws_show_executed_fvg_retests Оставляет только те разрывы, которые привели к подтверждённому входу по ретесту; каждый сохранённый прямоугольник заканчивается на свече входа.
tws_show_trade_boxes Отображает области целей и защитной остановки на графике.
tws_show_historical_trade_boxes Сохраняет завершённые области TP и SL для последующего просмотра на графике.
tws_max_historical_trades Ограничивает число сохраняемых завершённых торговых областей для производительности графика.
tws_trade_projection_bars Задаёт, на сколько баров вперёд проецируются активные торговые области и линии.
tws_layout_mode Выбирает макет графика: на мобильном панель и маркеры сигнала увеличиваются, а ценовые метки сокращаются.
tws_signal_label_size_input Выбирает размер метки сигнала.
tws_dashboard_size_input Выбирает размер текста панели состояния.
tws_show_htf_trend Отображает быструю EMA старшего таймфрейма на графике.
tws_show_engine_dashboard Показывает подтверждённое смещение, состояние линзы блокировок и активные цены входа, TP1, TP2, TP3 и стопа.
tws_alert_package Выбирает набор доставляемых оповещений: только подтверждённые входы, премиальные входы, полный жизненный цикл или структурированный JSON для вебхуков.
tws_alert_direction Ограничивает доставку оповещений выбранным направлением, не изменяя сигналы на графике.
tws_alert_minimum_grade Фильтрует оповещения по оценке сетапа, не изменяя логику входа индикатора.
tws_alert_on_armed_setup Отправляет раннее уведомление, когда связанный со структурой разрыв переходит в состояние готовности.
tws_alert_on_breakeven Отправляет уведомление жизненного цикла, когда после достижения TP1 активируется правило безубытка.
Получить полный код

Поиск по коду файла

indicator(
     "FVG Retest Entry Engine",
     shorttitle="FVG Retest Entry Engine",
     overlay=true,
     behind_chart=false,
     max_bars_back=5000,
     max_boxes_count=500,
     max_lines_count=500,
     max_labels_count=500,
     format=format.price
 )

const string TWS_SIGNATURE = "trade_w_samet"

tws_group_mode    = "⚡ Signal Blueprint"
tws_group_experience = "🪪 Retest Experience"
tws_group_classic = "🧬 Original Sync Engine"
tws_group_structure = "🧭 Structure Pulse"
tws_group_imbalance       = "🧱 Gap Intelligence"
tws_group_return    = "🎯 Reaction Trigger"
tws_group_gate   = "🛂 Quality Checkpoints"
tws_group_defense      = "🛡️ Position Architecture"
tws_group_visuals    = "🎨 Chart Design"
tws_group_delivery    = "📡 Alert Center"

tws_engine_profile = input.string(
     "Original Sync",
     "Engine Style",
     options=["Original Sync", "Balanced Flow", "Precision Flow", "Fast Flow", "Position Flow", "Custom Lab"],
     tooltip="Original Sync preserves the first validated signal map. Balanced Flow, Precision Flow, Fast Flow and Position Flow apply different trade_w_samet sensitivity models. Custom Lab unlocks every advanced parameter.",
     group=tws_group_mode,
     display=display.none
 )

bool tws_classic_profile = tws_engine_profile == "Original Sync"
bool tws_custom_profile = tws_engine_profile == "Custom Lab"

tws_allow_longs = input.bool(
     true,
     "Allow Bullish Setups",
     tooltip="Allows validated bullish gap reactions to create an entry model.",
     group=tws_group_mode,
     display=display.none
 )

tws_allow_shorts = input.bool(
     true,
     "Allow Bearish Setups",
     tooltip="Allows validated bearish gap reactions to create an entry model.",
     group=tws_group_mode,
     display=display.none
 )

tws_passport_mode = input.string(
     "Compact",
     "FVG Retest Passport",
     options=["Off", "Compact", "Detailed"],
     tooltip="Adds a clear setup identity to every confirmed retest. Compact shows age and depth; Detailed also shows structure, FVG size and filter status.",
     group=tws_group_experience,
     display=display.none
 )

tws_show_blocker_lens = input.bool(
     true,
     "Show Blocker Lens",
     tooltip="Explains the engine's current state, including waiting for structure, retest delay, volume block, DI block, HTF block, weak reaction, grade block and ready-at-close states.",
     group=tws_group_experience,
     display=display.none
 )

tws_signal_timing_mode = input.string(
     "Confirmed Close",
     "Signal Timing",
     options=["Confirmed Close", "Live Preview"],
     tooltip="Both modes commit entries, labels and alerts only after the chart candle closes. Live Preview only updates the dashboard intrabar, so provisional conditions never become historical signals and do not repaint.",
     group=tws_group_experience,
     display=display.none
 )

tws_classic_preset = input.string(
     "Manual Sync",
     "Original Signal Calibration",
     options=["Manual Sync", "Bitcoin Map", "Ethereum Map", "Solana Map", "Gold Map"],
     tooltip="Recreates the first validated signal calibration. Manual Sync exposes the base values; market maps apply the matching original overrides.",
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_profile
 )

bool tws_classic_manual = tws_classic_profile and tws_classic_preset == "Manual Sync"

tws_classic_structure_len_input = input.int(
     8,
     "Structure Window",
     minval=5,
     maxval=19,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_min_fvg_atr_input = input.float(
     0.20,
     "Minimum Gap Footprint — ATR",
     minval=0.01,
     maxval=3.00,
     step=0.01,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_max_fvg_age_input = input.int(
     150,
     "Gap Lifetime",
     minval=10,
     maxval=1000,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_max_fvg_zones_input = input.int(
     30,
     "Gap Memory Capacity",
     minval=5,
     maxval=100,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_max_fvg_distance_input = input.int(
     30,
     "Break-to-Gap Distance",
     minval=1,
     maxval=200,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_post_break_scan_input = input.int(
     4,
     "After-Break Scan Window",
     minval=0,
     maxval=20,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_retest_mode_input = input.string(
     "Reaction Reclaim",
     "Reaction Pattern",
     options=["Any Wick Contact", "Real Body Contact", "Close Within Gap", "Reaction Reclaim"],
     tooltip="Chooses how Original Sync recognizes a valid return into the selected gap.",
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_profile
 )

tws_classic_touch_tolerance_input = input.float(
     0.025,
     "Reaction Margin %",
     minval=0.000,
     maxval=1.000,
     step=0.001,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_min_retest_delay_input = input.int(
     2,
     "Minimum Reaction Delay",
     minval=1,
     maxval=50,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_max_bars_to_wait_input = input.int(
     20,
     "Reaction Expiry Bars",
     minval=2,
     maxval=200,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_volume_multiplier_input = input.float(
     1.00,
     "Participation Multiplier",
     minval=0.10,
     maxval=5.00,
     step=0.05,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_minimum_adx_input = input.float(
     10.0,
     "Minimum Directional Force",
     minval=0.0,
     maxval=100.0,
     step=0.5,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_classic_minimum_stars = input.int(
     1,
     "Minimum Sync Rating",
     minval=1,
     maxval=4,
     tooltip="Sets the minimum Original Sync rating required before a signal is released.",
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_profile
 )

tws_classic_minimum_stop_input = input.float(
     1.00,
     "Minimum Risk Distance %",
     minval=0.00,
     maxval=20.00,
     step=0.05,
     group=tws_group_classic,
     display=display.none,
     active=tws_classic_manual
 )

tws_structure_len_input = input.int(
     8,
     "Structure Sensitivity",
     minval=5,
     maxval=19,
     tooltip="Controls how quickly Custom Lab recognizes confirmed swing points.",
     group=tws_group_structure,
     display=display.none,
     active=tws_custom_profile
 )

tws_show_structure = input.bool(
     false,
     "Display Structure Tags",
     tooltip="Shows optional structure-break tags on the chart. This is disabled by default for a cleaner layout.",
     group=tws_group_structure,
     display=display.none
 )

tws_require_body_close = input.bool(
     true,
     "Close-Lock Breaks",
     tooltip="Requires a candle close beyond structure. Disable it to allow wick-based breaks.",
     group=tws_group_structure,
     display=display.none
 )

tws_use_break_displacement = input.bool(
     true,
     "Break Momentum Check",
     tooltip="Requires visible momentum on the candle that clears the swing level.",
     group=tws_group_structure,
     display=display.none
 )

tws_minimum_break_body_atr_input = input.float(
     0.35,
     "Break Body Threshold — ATR",
     minval=0.00,
     maxval=3.00,
     step=0.05,
     tooltip="Custom Lab minimum body expansion for a valid structure break.",
     group=tws_group_structure,
     display=display.none,
     active=tws_custom_profile and tws_use_break_displacement
 )

tws_break_buffer_atr_input = input.float(
     0.02,
     "Break Clearance — ATR",
     minval=0.00,
     maxval=1.00,
     step=0.01,
     tooltip="Adds volatility-based distance beyond the swing before confirmation.",
     group=tws_group_structure,
     display=display.none,
     active=tws_custom_profile
 )

tws_min_fvg_atr_input = input.float(
     0.20,
     "Minimum Gap Width — ATR",
     minval=0.01,
     maxval=3.00,
     step=0.01,
     tooltip="Custom Lab minimum three-candle gap width relative to ATR.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile
 )

tws_use_fvg_displacement_filter = input.bool(
     true,
     "Gap Impulse Check",
     tooltip="Filters gaps that form without a strong directional impulse.",
     group=tws_group_imbalance,
     display=display.none
 )

tws_minimum_fvg_displacement_input = input.float(
     0.25,
     "Minimum Gap Impulse",
     minval=0.00,
     maxval=1.00,
     step=0.05,
     tooltip="Custom Lab minimum impulse score required at gap creation.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile and tws_use_fvg_displacement_filter
 )

tws_minimum_zone_quality_input = input.float(
     0.42,
     "Minimum Gap Score",
     minval=0.00,
     maxval=1.00,
     step=0.01,
     tooltip="Lowest internal gap score allowed into the reaction engine.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile
 )

tws_maximum_prior_touches_input = input.int(
     1,
     "Allowed Prior Reactions",
     minval=0,
     maxval=10,
     tooltip="Controls how many previous reactions a gap may contain before rejection.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile
 )

tws_max_fvg_age_input = input.int(
     150,
     "Gap Expiry Bars",
     minval=10,
     maxval=1000,
     tooltip="Removes active gaps after the selected candle count.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile
 )

tws_max_fvg_zones_input = input.int(
     24,
     "Active Gap Capacity",
     minval=5,
     maxval=100,
     tooltip="Limits active gap objects to protect TradingView performance.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile
 )

tws_max_fvg_distance_input = input.int(
     30,
     "Maximum Structure Link",
     minval=1,
     maxval=200,
     tooltip="Limits how far a gap may form from its linked structure event.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile
 )

tws_post_break_scan_bars_input = input.int(
     4,
     "Break Follow-Through Window",
     minval=0,
     maxval=20,
     tooltip="Keeps scanning for a matching gap after the break is confirmed.",
     group=tws_group_imbalance,
     display=display.none,
     active=tws_custom_profile
 )

tws_remove_invalid_fvgs = input.bool(
     true,
     "Delete Invalidated Gaps",
     tooltip="Deletes a bullish gap after a close below it and a bearish gap after a close above it.",
     group=tws_group_imbalance,
     display=display.none
 )

tws_retest_mode_input = input.string(
     "Directional Recovery",
     "Reaction Model",
     options=["First Contact", "Directional Recovery", "Edge Reclaim", "Rejection Wick"],
     tooltip="First Contact accepts overlap. Directional Recovery requires movement back with the setup. Edge Reclaim requires a close through the gap boundary. Rejection Wick applies the strictest rejection model.",
     group=tws_group_return,
     display=display.none,
     active=tws_custom_profile
 )

tws_touch_tolerance_input = input.float(
     0.025,
     "Gap Interaction Margin %",
     minval=0.000,
     maxval=1.000,
     step=0.001,
     tooltip="Adds a small price margin around the selected gap boundary.",
     group=tws_group_return,
     display=display.none,
     active=tws_custom_profile
 )

tws_minimum_reaction_score_input = input.float(
     0.35,
     "Minimum Reaction Strength",
     minval=0.00,
     maxval=1.00,
     step=0.01,
     tooltip="Sets the minimum reaction-candle quality required by Custom Lab.",
     group=tws_group_return,
     display=display.none,
     active=tws_custom_profile
 )

tws_min_retest_delay_input = input.int(
     2,
     "Reaction Delay Bars",
     minval=1,
     maxval=50,
     tooltip="Blocks reactions that occur too soon after the structure event.",
     group=tws_group_return,
     display=display.none,
     active=tws_custom_profile
 )

tws_max_bars_to_wait_input = input.int(
     20,
     "Setup Expiry Bars",
     minval=2,
     maxval=200,
     tooltip="Cancels the selected setup when no valid reaction appears in time.",
     group=tws_group_return,
     display=display.none,
     active=tws_custom_profile
 )

tws_cooldown_after_close = input.int(
     0,
     "Signal Cooldown Bars",
     minval=0,
     maxval=100,
     tooltip="Prevents immediate re-entry after the previous trade model closes.",
     group=tws_group_return,
     display=display.none
 )

tws_use_volume_filter = input.bool(
     true,
     "Volume Participation Check",
     tooltip="Requires confirmation-candle volume to expand above its baseline.",
     group=tws_group_gate,
     display=display.none
 )

tws_volume_length = input.int(
     21,
     "Volume Baseline Length",
     minval=2,
     maxval=200,
     tooltip="Defines the moving-average length used by the volume check.",
     group=tws_group_gate,
     display=display.none
 )

tws_volume_multiplier_input = input.float(
     1.00,
     "Required Volume Expansion",
     minval=0.10,
     maxval=5.00,
     step=0.05,
     tooltip="Custom Lab volume requirement relative to the selected baseline.",
     group=tws_group_gate,
     display=display.none,
     active=tws_custom_profile and tws_use_volume_filter
 )

tws_use_di_filter = input.bool(
     true,
     "Directional Force Check",
     tooltip="Requires DI direction and trend strength to support the setup.",
     group=tws_group_gate,
     display=display.none
 )

tws_di_length = input.int(
     14,
     "Directional Force Length",
     minval=2,
     maxval=100,
     group=tws_group_gate,
     display=display.none
 )

tws_adx_smoothing = input.int(
     14,
     "Trend Strength Smoothing",
     minval=2,
     maxval=100,
     group=tws_group_gate,
     display=display.none
 )

tws_minimum_adx_input = input.float(
     10.0,
     "Minimum Trend Strength",
     minval=0.0,
     maxval=100.0,
     step=0.5,
     tooltip="Custom Lab minimum ADX strength required by the directional check.",
     group=tws_group_gate,
     display=display.none,
     active=tws_custom_profile and tws_use_di_filter
 )

tws_use_htf_filter = input.bool(
     true,
     "Higher-Timeframe Bias Check",
     tooltip="Allows entries only when the selected higher timeframe confirms the same bias.",
     group=tws_group_gate,
     display=display.none
 )

tws_htf_timeframe = input.timeframe(
     "60",
     "Bias Timeframe",
     tooltip="Select a timeframe above the chart timeframe. Equal or lower selections are ignored.",
     group=tws_group_gate,
     display=display.none
 )

tws_htf_fast_length = input.int(
     50,
     "Bias Fast EMA",
     minval=2,
     maxval=500,
     group=tws_group_gate,
     display=display.none
 )

tws_htf_slow_length = input.int(
     200,
     "Bias Slow EMA",
     minval=3,
     maxval=1000,
     group=tws_group_gate,
     display=display.none
 )

tws_minimum_grade_input = input.string(
     "B Grade or Better",
     "Minimum Setup Grade",
     options=["B Grade or Better", "A Grade or Better", "A+ Only"],
     tooltip="Selects the lowest setup grade allowed to create a trade model.",
     group=tws_group_gate,
     display=display.none,
     active=tws_custom_profile
 )

tws_atr_length = input.int(
     14,
     "ATR Calculation Length",
     minval=2,
     maxval=200,
     group=tws_group_defense,
     display=display.none
 )

tws_stop_mode = input.string(
     "Gap-Protected Stop",
     "Stop Placement Model",
     options=["Gap-Protected Stop", "Volatility Stop"],
     tooltip="Gap-Protected Stop places protection beyond the selected gap. Volatility Stop measures distance directly from entry.",
     group=tws_group_defense,
     display=display.none
 )

tws_atr_stop_multiplier = input.float(
     1.50,
     "Volatility Stop Multiplier",
     minval=0.10,
     maxval=10.00,
     step=0.05,
     group=tws_group_defense,
     display=display.none
 )

tws_fvg_stop_buffer_atr = input.float(
     0.15,
     "Gap Stop Buffer — ATR",
     minval=0.00,
     maxval=5.00,
     step=0.05,
     tooltip="Adds ATR-based clearance beyond the selected gap boundary.",
     group=tws_group_defense,
     display=display.none
 )

tws_minimum_stop_percent_input = input.float(
     0.80,
     "Minimum Stop Distance %",
     minval=0.00,
     maxval=20.00,
     step=0.05,
     tooltip="Prevents unrealistically tight stops in Custom Lab.",
     group=tws_group_defense,
     display=display.none,
     active=tws_custom_profile
 )

tws_tp1_r = input.float(
     1.0,
     "TP1 Risk Multiple",
     minval=0.10,
     maxval=20.00,
     step=0.10,
     group=tws_group_defense,
     display=display.none
 )

tws_tp2_r = input.float(
     2.0,
     "TP2 Risk Multiple",
     minval=0.20,
     maxval=30.00,
     step=0.10,
     group=tws_group_defense,
     display=display.none
 )

tws_tp3_r = input.float(
     3.0,
     "TP3 Risk Multiple",
     minval=0.30,
     maxval=50.00,
     step=0.10,
     group=tws_group_defense,
     display=display.none
 )

tws_tp1_close_percent = input.float(
     60.0,
     "TP1 Position Share %",
     minval=0.0,
     maxval=100.0,
     step=0.1,
     group=tws_group_defense,
     display=display.none
 )

tws_tp2_close_percent = input.float(
     25.0,
     "TP2 Position Share %",
     minval=0.0,
     maxval=100.0,
     step=0.1,
     group=tws_group_defense,
     display=display.none
 )

tws_tp3_close_percent = input.float(
     15.0,
     "TP3 Position Share %",
     minval=0.0,
     maxval=100.0,
     step=0.1,
     tooltip="TP3 closes any remaining simulated position share.",
     group=tws_group_defense,
     display=display.none
 )

tws_move_to_breakeven = input.bool(
     true,
     "Move Stop to Entry After TP1",
     tooltip="Moves the active stop to entry on the candle after TP1 is reached.",
     group=tws_group_defense,
     display=display.none
 )

tws_intrabar_priority = input.string(
     "Protective First",
     "Same-Candle Priority",
     options=["Protective First", "Target First"],
     tooltip="Protective First assumes the stop is hit first. Target First assumes targets are processed first.",
     group=tws_group_defense,
     display=display.none
 )

tws_theme_input = input.string(
     "Ivory Pulse",
     "Color System",
     options=["Obsidian Signal", "Carbon Grid", "Ivory Pulse", "Neon Voltage", "Acid Circuit", "Violet Flux"],
     tooltip="Switches the full visual identity. The new themes add high-contrast, crazy color packs for a more aggressive design.",
     group=tws_group_visuals,
     display=display.none
 )

tws_fvg_display_mode = input.string(
     "Selected Gap",
     "Gap Display Mode",
     options=["Hidden", "Selected Gap", "All Active Gaps"],
     tooltip="Selected Gap shows only the gap linked to the current setup. All Active Gaps displays every valid stored gap.",
     group=tws_group_visuals,
     display=display.none
 )

tws_show_executed_fvg_retests = input.bool(
     true,
     "Show Executed FVG Retests",
     tooltip="Keeps only the Fair Value Gaps that produced a confirmed retest entry. Each retained box ends on the exact entry candle.",
     group=tws_group_visuals,
     display=display.none
 )

tws_show_trade_boxes = input.bool(
     true,
     "Display TP / SL Areas",
     group=tws_group_visuals,
     display=display.none
 )

tws_show_historical_trade_boxes = input.bool(
     true,
     "Keep Completed Trade Areas",
     tooltip="Preserves completed TP and SL areas for later chart review.",
     group=tws_group_visuals,
     display=display.none,
     active=tws_show_trade_boxes
 )

tws_max_historical_trades = input.int(
     40,
     "Completed Trade History Limit",
     minval=1,
     maxval=150,
     tooltip="Limits retained completed trade areas to protect chart performance.",
     group=tws_group_visuals,
     display=display.none,
     active=tws_show_trade_boxes and tws_show_historical_trade_boxes
 )

tws_trade_projection_bars = input.int(
     35,
     "Active Area Projection",
     minval=5,
     maxval=200,
     group=tws_group_visuals,
     display=display.none
 )

tws_layout_mode = input.string(
     "Desktop",
     "Chart Layout",
     options=["Desktop", "Mobile"],
     tooltip="Mobile enlarges the dashboard and signal marker while showing only Entry, TP3 and SL price tags to reduce chart clutter.",
     group=tws_group_visuals,
     display=display.none
 )

tws_signal_label_size_input = input.string(
     "Compact",
     "Signal Label Size",
     options=["Micro", "Compact", "Standard", "Large"],
     group=tws_group_visuals,
     display=display.none
 )

tws_dashboard_size_input = input.string(
     "Compact",
     "Dashboard Size",
     options=["Micro", "Compact", "Standard"],
     group=tws_group_visuals,
     display=display.none
 )

tws_show_htf_trend = input.bool(
     false,
     "Display Bias EMA",
     group=tws_group_visuals,
     display=display.none
 )

tws_show_engine_dashboard = input.bool(
     true,
     "Display Setup Dashboard",
     tooltip="Shows confirmed bias, Blocker Lens state, Entry, TP1, TP2, TP3 and active SL prices.",
     group=tws_group_visuals,
     display=display.none
 )

tws_alert_package = input.string(
     "Qualified Entries",
     "Alert Package",
     options=["Off", "Qualified Entries", "Premium Entries", "Full Lifecycle", "Webhook JSON"],
     tooltip="Qualified Entries sends confirmed entries. Premium Entries restricts entries to A/A+. Full Lifecycle adds armed, TP, breakeven and exit events. Webhook JSON sends the same lifecycle in structured JSON.",
     group=tws_group_delivery,
     display=display.none
 )

tws_alert_direction = input.string(
     "Both Directions",
     "Alert Direction",
     options=["Both Directions", "Bullish Only", "Bearish Only"],
     tooltip="Limits alert delivery without changing chart signals.",
     group=tws_group_delivery,
     display=display.none,
     active=tws_alert_package != "Off"
 )

tws_alert_minimum_grade = input.string(
     "All Qualified",
     "Minimum Alert Grade",
     options=["All Qualified", "A / A+", "A+ Only"],
     tooltip="Filters alerts by setup grade without changing the indicator's entry logic.",
     group=tws_group_delivery,
     display=display.none,
     active=tws_alert_package != "Off"
 )

tws_alert_on_armed_setup = input.bool(
     false,
     "Alert When FVG Is Armed",
     tooltip="Sends an early notification when a structure-linked FVG becomes armed. Available in Full Lifecycle and Webhook JSON packages.",
     group=tws_group_delivery,
     display=display.none,
     active=tws_alert_package == "Full Lifecycle" or tws_alert_package == "Webhook JSON"
 )

tws_alert_on_breakeven = input.bool(
     true,
     "Alert When Stop Moves to Entry",
     tooltip="Sends a lifecycle notification when TP1 has activated the breakeven rule.",
     group=tws_group_delivery,
     display=display.none,
     active=tws_alert_package == "Full Lifecycle" or tws_alert_package == "Webhook JSON"
 )

bool tws_profile_balanced = tws_engine_profile == "Balanced Flow"
bool tws_profile_precision = tws_engine_profile == "Precision Flow"
bool tws_profile_scalping = tws_engine_profile == "Fast Flow"
bool tws_profile_swing = tws_engine_profile == "Position Flow"

bool tws_classic_btc = tws_classic_profile and tws_classic_preset == "Bitcoin Map"
bool tws_classic_eth = tws_classic_profile and tws_classic_preset == "Ethereum Map"
bool tws_classic_sol = tws_classic_profile and tws_classic_preset == "Solana Map"
bool tws_classic_xau = tws_classic_profile and tws_classic_preset == "Gold Map"

int tws_structure_len =
     tws_classic_profile ?
         (tws_classic_btc ? 8 : tws_classic_eth ? 9 : tws_classic_sol ? 7 : tws_classic_xau ? 12 : tws_classic_structure_len_input) :
     tws_profile_precision ? 12 :
     tws_profile_scalping ? 6 :
     tws_profile_swing ? 14 :
     tws_profile_balanced ? 8 :
     tws_structure_len_input

float tws_minimum_break_body_atr =
     tws_classic_profile ? 0.0 :
     tws_profile_precision ? 0.55 :
     tws_profile_scalping ? 0.20 :
     tws_profile_swing ? 0.45 :
     tws_profile_balanced ? 0.35 :
     tws_minimum_break_body_atr_input

float tws_break_buffer_atr =
     tws_classic_profile ? 0.0 :
     tws_profile_precision ? 0.05 :
     tws_profile_scalping ? 0.00 :
     tws_profile_swing ? 0.04 :
     tws_profile_balanced ? 0.02 :
     tws_break_buffer_atr_input

float tws_min_fvg_atr =
     tws_classic_profile ?
         (tws_classic_btc ? 0.25 : tws_classic_eth ? 0.22 : tws_classic_sol ? 0.30 : tws_classic_xau ? 0.18 : tws_classic_min_fvg_atr_input) :
     tws_profile_precision ? 0.35 :
     tws_profile_scalping ? 0.12 :
     tws_profile_swing ? 0.28 :
     tws_profile_balanced ? 0.20 :
     tws_min_fvg_atr_input

float tws_minimum_fvg_displacement =
     tws_classic_profile ? 0.0 :
     tws_profile_precision ? 0.40 :
     tws_profile_scalping ? 0.15 :
     tws_profile_swing ? 0.30 :
     tws_profile_balanced ? 0.25 :
     tws_minimum_fvg_displacement_input

float tws_minimum_zone_quality =
     tws_classic_profile ? 0.0 :
     tws_profile_precision ? 0.58 :
     tws_profile_scalping ? 0.34 :
     tws_profile_swing ? 0.50 :
     tws_profile_balanced ? 0.42 :
     tws_minimum_zone_quality_input

int tws_maximum_prior_touches =
     tws_classic_profile ? 1000000 :
     tws_profile_precision ? 0 :
     tws_profile_scalping ? 2 :
     tws_profile_swing ? 1 :
     tws_profile_balanced ? 1 :
     tws_maximum_prior_touches_input

int tws_max_fvg_age =
     tws_classic_profile ?
         (tws_classic_btc ? 160 : tws_classic_eth ? 149 : tws_classic_sol ? 196 : tws_classic_xau ? 200 : tws_classic_max_fvg_age_input) :
     tws_profile_precision ? 120 :
     tws_profile_scalping ? 90 :
     tws_profile_swing ? 240 :
     tws_profile_balanced ? 150 :
     tws_max_fvg_age_input

int tws_max_fvg_zones =
     tws_classic_profile ?
         (tws_classic_btc ? 20 : tws_classic_eth ? 14 : tws_classic_sol ? 22 : tws_classic_xau ? 25 : tws_classic_max_fvg_zones_input) :
     tws_profile_precision ? 18 :
     tws_profile_scalping ? 28 :
     tws_profile_swing ? 24 :
     tws_profile_balanced ? 24 :
     tws_max_fvg_zones_input

int tws_max_fvg_distance =
     tws_classic_profile ?
         (tws_classic_btc ? 28 : tws_classic_eth ? 30 : tws_classic_sol ? 22 : tws_classic_xau ? 35 : tws_classic_max_fvg_distance_input) :
     tws_profile_precision ? 18 :
     tws_profile_scalping ? 18 :
     tws_profile_swing ? 45 :
     tws_profile_balanced ? 30 :
     tws_max_fvg_distance_input

int tws_post_break_scan_bars =
     tws_classic_profile ? tws_classic_post_break_scan_input :
     tws_profile_precision ? 3 :
     tws_profile_scalping ? 3 :
     tws_profile_swing ? 6 :
     tws_profile_balanced ? 4 :
     tws_post_break_scan_bars_input

string tws_retest_mode =
     tws_classic_profile ? tws_classic_retest_mode_input :
     tws_profile_precision ? "Rejection Wick" :
     tws_profile_scalping ? "First Contact" :
     tws_profile_swing ? "Edge Reclaim" :
     tws_profile_balanced ? "Directional Recovery" :
     tws_retest_mode_input

float tws_touch_tolerance_percent =
     tws_classic_profile ?
         (tws_classic_btc ? 0.030 : tws_classic_eth ? 0.025 : tws_classic_sol ? 0.035 : tws_classic_xau ? 0.050 : tws_classic_touch_tolerance_input) :
     tws_profile_precision ? 0.015 :
     tws_profile_scalping ? 0.050 :
     tws_profile_swing ? 0.020 :
     tws_profile_balanced ? 0.025 :
     tws_touch_tolerance_input

float tws_minimum_reaction_score =
     tws_classic_profile ? 0.0 :
     tws_profile_precision ? 0.55 :
     tws_profile_scalping ? 0.20 :
     tws_profile_swing ? 0.45 :
     tws_profile_balanced ? 0.35 :
     tws_minimum_reaction_score_input

int tws_min_retest_delay =
     tws_classic_profile ? tws_classic_min_retest_delay_input :
     tws_profile_precision ? 2 :
     tws_profile_scalping ? 1 :
     tws_profile_swing ? 3 :
     tws_profile_balanced ? 2 :
     tws_min_retest_delay_input

int tws_max_bars_to_wait =
     tws_classic_profile ?
         (tws_classic_btc ? 18 : tws_classic_eth ? 20 : tws_classic_sol ? 14 : tws_classic_xau ? 25 : tws_classic_max_bars_to_wait_input) :
     tws_profile_precision ? 14 :
     tws_profile_scalping ? 10 :
     tws_profile_swing ? 32 :
     tws_profile_balanced ? 20 :
     tws_max_bars_to_wait_input

float tws_volume_multiplier =
     tws_classic_profile ?
         (tws_classic_btc ? 1.00 : tws_classic_eth ? 1.05 : tws_classic_sol ? 1.15 : tws_classic_xau ? 0.90 : tws_classic_volume_multiplier_input) :
     tws_profile_precision ? 1.20 :
     tws_profile_scalping ? 0.80 :
     tws_profile_swing ? 1.00 :
     tws_profile_balanced ? 1.00 :
     tws_volume_multiplier_input

float tws_minimum_adx =
     tws_classic_profile ? tws_classic_minimum_adx_input :
     tws_profile_precision ? 18.0 :
     tws_profile_scalping ? 8.0 :
     tws_profile_swing ? 14.0 :
     tws_profile_balanced ? 10.0 :
     tws_minimum_adx_input

string tws_minimum_grade =
     tws_profile_precision ? "A Grade or Better" :
     tws_profile_scalping ? "B Grade or Better" :
     tws_profile_swing ? "A Grade or Better" :
     tws_profile_balanced ? "B Grade or Better" :
     tws_minimum_grade_input

float tws_minimum_stop_percent =
     tws_classic_profile ?
         (tws_classic_btc ? 1.20 : tws_classic_eth ? 1.10 : tws_classic_sol ? 1.50 : tws_classic_xau ? 0.35 : tws_classic_minimum_stop_input) :
     tws_profile_precision ? 0.90 :
     tws_profile_scalping ? 0.35 :
     tws_profile_swing ? 1.20 :
     tws_profile_balanced ? 0.80 :
     tws_minimum_stop_percent_input

bool tws_theme_obsidian = tws_theme_input == "Obsidian Signal"
bool tws_theme_terminal = tws_theme_input == "Carbon Grid"
bool tws_theme_ivory = tws_theme_input == "Ivory Pulse"
bool tws_theme_neon = tws_theme_input == "Neon Voltage"
bool tws_theme_toxic = tws_theme_input == "Acid Circuit"
bool tws_theme_ultra = tws_theme_input == "Violet Flux"

bool tws_is_dark_theme = not tws_theme_ivory
bool tws_header_dark_text = tws_theme_terminal or tws_theme_toxic
bool tws_label_dark_text = tws_theme_obsidian or tws_theme_terminal or tws_theme_ivory or tws_theme_toxic

color tws_panel_color =
     tws_theme_obsidian ? color.rgb(8, 8, 10) :
     tws_theme_terminal ? color.rgb(0, 0, 0) :
     tws_theme_ivory ? color.rgb(246, 243, 239) :
     tws_theme_neon ? color.rgb(14, 8, 26) :
     tws_theme_toxic ? color.rgb(10, 14, 8) :
     color.rgb(17, 8, 34)

color tws_panel_alt_color =
     tws_theme_obsidian ? color.rgb(18, 18, 22) :
     tws_theme_terminal ? color.rgb(14, 14, 16) :
     tws_theme_ivory ? color.rgb(226, 221, 216) :
     tws_theme_neon ? color.rgb(26, 14, 42) :
     tws_theme_toxic ? color.rgb(18, 24, 14) :
     color.rgb(28, 16, 50)

color tws_border_color =
     tws_theme_obsidian ? color.rgb(224, 22, 48) :
     tws_theme_terminal ? color.rgb(245, 245, 245) :
     tws_theme_ivory ? color.rgb(180, 12, 36) :
     tws_theme_neon ? color.rgb(0, 245, 255) :
     tws_theme_toxic ? color.rgb(214, 255, 64) :
     color.rgb(173, 85, 255)

color tws_primary_text_color =
     tws_is_dark_theme ? color.rgb(248, 248, 248) : color.rgb(18, 18, 20)

color tws_muted_text_color =
     tws_theme_obsidian ? color.rgb(145, 145, 152) :
     tws_theme_terminal ? color.rgb(170, 170, 176) :
     tws_theme_ivory ? color.rgb(96, 92, 90) :
     tws_theme_neon ? color.rgb(214, 175, 255) :
     tws_theme_toxic ? color.rgb(174, 210, 120) :
     color.rgb(198, 174, 255)

color tws_bullish_color =
     tws_theme_obsidian ? color.rgb(242, 242, 244) :
     tws_theme_terminal ? color.rgb(242, 242, 244) :
     tws_theme_ivory ? color.rgb(20, 20, 22) :
     tws_theme_neon ? color.rgb(255, 70, 200) :
     tws_theme_toxic ? color.rgb(214, 255, 64) :
     color.rgb(122, 245, 255)

color tws_bearish_color =
     tws_theme_obsidian ? color.rgb(224, 22, 48) :
     tws_theme_terminal ? color.rgb(224, 22, 48) :
     tws_theme_ivory ? color.rgb(224, 22, 48) :
     tws_theme_neon ? color.rgb(0, 245, 255) :
     tws_theme_toxic ? color.rgb(255, 106, 0) :
     color.rgb(255, 86, 166)

color tws_entry_color =
     tws_theme_obsidian ? color.white :
     tws_theme_terminal ? color.white :
     tws_theme_ivory ? color.rgb(18, 18, 20) :
     tws_theme_neon ? color.rgb(255, 240, 84) :
     tws_theme_toxic ? color.rgb(255, 255, 255) :
     color.rgb(255, 255, 255)

color tws_stop_color =
     tws_theme_obsidian ? color.rgb(224, 22, 48) :
     tws_theme_terminal ? color.rgb(224, 22, 48) :
     tws_theme_ivory ? color.rgb(224, 22, 48) :
     tws_theme_neon ? color.rgb(255, 120, 0) :
     tws_theme_toxic ? color.rgb(255, 64, 64) :
     color.rgb(255, 86, 166)

color tws_breakeven_color =
     tws_theme_obsidian ? color.rgb(190, 190, 196) :
     tws_theme_terminal ? color.rgb(190, 190, 196) :
     tws_theme_ivory ? color.rgb(65, 65, 70) :
     tws_theme_neon ? color.rgb(168, 255, 71) :
     tws_theme_toxic ? color.rgb(0, 255, 209) :
     color.rgb(183, 153, 255)

color tws_closed_profit_fill = tws_theme_neon ? color.rgb(36, 14, 58) : tws_theme_toxic ? color.rgb(24, 30, 14) : tws_theme_ultra ? color.rgb(28, 16, 50) : color.rgb(12, 12, 15)
color tws_closed_loss_fill = tws_stop_color
color tws_closed_flat_fill = tws_theme_neon ? color.rgb(48, 30, 68) : tws_theme_toxic ? color.rgb(46, 54, 28) : tws_theme_ultra ? color.rgb(44, 30, 70) : color.rgb(52, 52, 58)
color tws_grade_a_plus_color = tws_border_color
color tws_grade_a_color = tws_bullish_color
color tws_grade_b_color = tws_is_dark_theme ? color.rgb(165, 165, 172) : color.rgb(85, 85, 90)
color tws_filtered_color = tws_muted_text_color

color tws_bull_fvg_fill = color.new(tws_bullish_color, tws_theme_neon or tws_theme_toxic or tws_theme_ultra ? 88 : 93)
color tws_bear_fvg_fill = color.new(tws_bearish_color, tws_theme_neon or tws_theme_toxic or tws_theme_ultra ? 84 : 89)

color tws_target_guide_color =
     tws_theme_obsidian ? color.rgb(38, 154, 255) :
     tws_theme_terminal ? color.rgb(0, 191, 255) :
     tws_theme_ivory ? color.rgb(45, 135, 255) :
     tws_theme_neon ? color.rgb(0, 225, 255) :
     tws_theme_toxic ? color.rgb(60, 170, 255) :
     color.rgb(92, 142, 255)

color tws_target_label_fill =
     tws_theme_obsidian ? color.rgb(12, 54, 118) :
     tws_theme_terminal ? color.rgb(0, 58, 92) :
     tws_theme_ivory ? color.rgb(24, 72, 145) :
     tws_theme_neon ? color.rgb(20, 42, 112) :
     tws_theme_toxic ? color.rgb(22, 64, 132) :
     color.rgb(45, 34, 124)

color tws_reward_fill = color.new(
     tws_target_guide_color,
     tws_theme_ivory ? 80 : tws_theme_neon or tws_theme_toxic or tws_theme_ultra ? 82 : 84
 )

color tws_risk_fill =
     tws_theme_obsidian ? color.new(tws_bearish_color, 88) :
     tws_theme_terminal ? color.new(tws_bearish_color, 88) :
     tws_theme_ivory ? color.new(tws_bearish_color, 86) :
     tws_theme_neon ? color.new(color.rgb(255, 120, 0), 84) :
     tws_theme_toxic ? color.new(color.rgb(255, 64, 64), 84) :
     color.new(color.rgb(255, 86, 166), 84)
int tws_box_border_width = tws_theme_neon or tws_theme_toxic or tws_theme_ultra ? 2 : 1
int tws_major_line_width = tws_theme_neon or tws_theme_toxic or tws_theme_ultra ? 3 : 2
int tws_minor_line_width = tws_theme_neon or tws_theme_toxic or tws_theme_ultra ? 2 : 1

bool tws_mobile_layout = tws_layout_mode == "Mobile"
bool tws_live_preview_mode = tws_signal_timing_mode == "Live Preview"

string tws_signal_label_size =
     tws_mobile_layout ? size.normal :
     tws_signal_label_size_input == "Micro" ? size.tiny :
     tws_signal_label_size_input == "Standard" ? size.normal :
     tws_signal_label_size_input == "Large" ? size.large :
     size.small

string tws_dashboard_text_size =
     tws_mobile_layout ? size.normal :
     tws_dashboard_size_input == "Micro" ? size.tiny :
     tws_dashboard_size_input == "Standard" ? size.normal :
     size.small

float tws_atr = ta.atr(tws_atr_length)
float tws_volume_average = ta.sma(volume, tws_volume_length)
bool tws_volume_available = not na(volume) and not na(tws_volume_average) and tws_volume_average > 0

[tws_plus_di, tws_minus_di, tws_adx_value] = ta.dmi(tws_di_length, tws_adx_smoothing)

float tws_htf_close = request.security(
     syminfo.tickerid,
     tws_htf_timeframe,
     close[1],
     barmerge.gaps_off,
     barmerge.lookahead_on
 )

float tws_htf_fast_ema = request.security(
     syminfo.tickerid,
     tws_htf_timeframe,
     ta.ema(close, tws_htf_fast_length)[1],
     barmerge.gaps_off,
     barmerge.lookahead_on
 )

float tws_htf_slow_ema = request.security(
     syminfo.tickerid,
     tws_htf_timeframe,
     ta.ema(close, tws_htf_slow_length)[1],
     barmerge.gaps_off,
     barmerge.lookahead_on
 )

float tws_chart_seconds = timeframe.in_seconds()
float tws_selected_htf_seconds = timeframe.in_seconds(tws_htf_timeframe)

bool tws_valid_higher_timeframe =
     na(tws_chart_seconds) or
     na(tws_selected_htf_seconds) or
     tws_selected_htf_seconds > tws_chart_seconds

plot(
     tws_show_htf_trend and tws_valid_higher_timeframe ? tws_htf_fast_ema : na,
     title="Bias Fast EMA",
     color=color.new(tws_border_color, 15),
     linewidth=2,
     display=display.pane
 )

tws_bound(float tws_value, float tws_minimum, float tws_maximum) =>
    math.max(tws_minimum, math.min(tws_maximum, tws_value))

tws_weighted_result(
     int tws_direction,
     float tws_entry_price,
     float tws_exit_price,
     float tws_close_percent
 ) =>
    float tws_fraction = tws_close_percent / 100.0
    float tws_price_change =
         tws_direction == 1 ?
         (tws_exit_price - tws_entry_price) / tws_entry_price :
         (tws_entry_price - tws_exit_price) / tws_entry_price

    tws_price_change * tws_fraction

tws_quality_tier(float tws_score) =>
    tws_score >= 0.82 ? "A+" :
     tws_score >= 0.68 ? "A" :
     tws_score >= 0.55 ? "B" :
     "FILTERED"

tws_tier_allowed(string tws_grade, string tws_required_grade) =>
    tws_required_grade == "A+ Only" ? tws_grade == "A+" :
     tws_required_grade == "A Grade or Better" ? tws_grade == "A+" or tws_grade == "A" :
     tws_grade == "A+" or tws_grade == "A" or tws_grade == "B"

tws_tier_color(string tws_grade) =>
    tws_grade == "A+" ? tws_grade_a_plus_color :
     tws_grade == "A" ? tws_grade_a_color :
     tws_grade == "B" ? tws_grade_b_color :
     tws_filtered_color

tws_alert_grade_allowed(string tws_grade, string tws_required_grade) =>
    tws_required_grade == "A+ Only" ? tws_grade == "A+" :
     tws_required_grade == "A / A+" ? tws_grade == "A+" or tws_grade == "A" :
     tws_grade == "A+" or tws_grade == "A" or tws_grade == "B"

tws_alert_direction_allowed(int tws_direction, string tws_direction_filter) =>
    tws_direction_filter == "Bullish Only" ? tws_direction == 1 :
     tws_direction_filter == "Bearish Only" ? tws_direction == -1 :
     true

tws_filter_status(bool tws_enabled, bool tws_available, bool tws_passed) =>
    not tws_enabled ? "BYPASS" :
     not tws_available ? "NO DATA" :
     tws_passed ? "PASS" :
     "*****"

tws_zone_contact(
     int tws_direction,
     float tws_zone_top,
     float tws_zone_bottom,
     string tws_selected_mode,
     float tws_tolerance
 ) =>
    float tws_zone_mid = (tws_zone_top + tws_zone_bottom) / 2.0
    float tws_body_high = math.max(open, close)
    float tws_body_low = math.min(open, close)
    float tws_candle_range = math.max(high - low, syminfo.mintick)
    float tws_lower_wick = math.min(open, close) - low
    float tws_upper_wick = high - math.max(open, close)

    bool tws_wick_overlap =
         low <= tws_zone_top + tws_tolerance and
         high >= tws_zone_bottom - tws_tolerance

    bool tws_body_overlap =
         tws_body_low <= tws_zone_top + tws_tolerance and
         tws_body_high >= tws_zone_bottom - tws_tolerance

    bool tws_directional_recovery =
         tws_direction == 1 ?
         tws_wick_overlap and close >= tws_zone_mid and close > open :
         tws_wick_overlap and close <= tws_zone_mid and close < open

    bool tws_boundary_reclaim =
         tws_direction == 1 ?
         low <= tws_zone_top + tws_tolerance and close > tws_zone_top :
         high >= tws_zone_bottom - tws_tolerance and close < tws_zone_bottom

    bool tws_strict_rejection =
         tws_direction == 1 ?
         tws_boundary_reclaim and close > open and tws_lower_wick / tws_candle_range >= 0.30 :
         tws_boundary_reclaim and close < open and tws_upper_wick / tws_candle_range >= 0.30

    tws_selected_mode == "First Contact" ? tws_wick_overlap :
     tws_selected_mode == "Directional Recovery" ? tws_directional_recovery or (tws_body_overlap and tws_boundary_reclaim) :
     tws_selected_mode == "Edge Reclaim" ? tws_boundary_reclaim :
     tws_strict_rejection

tws_classic_zone_contact(
     int tws_direction,
     float tws_zone_top,
     float tws_zone_bottom,
     string tws_selected_mode,
     float tws_tolerance
 ) =>
    float tws_body_high = math.max(open, close)
    float tws_body_low = math.min(open, close)

    bool tws_wick_touch =
         low <= tws_zone_top + tws_tolerance and
         high >= tws_zone_bottom - tws_tolerance

    bool tws_body_touch =
         tws_body_low <= tws_zone_top + tws_tolerance and
         tws_body_high >= tws_zone_bottom - tws_tolerance

    bool tws_close_inside =
         close <= tws_zone_top + tws_tolerance and
         close >= tws_zone_bottom - tws_tolerance

    bool tws_mixed_long =
         low <= tws_zone_top + tws_tolerance and
         close > tws_zone_top and
         close > open

    bool tws_mixed_short =
         high >= tws_zone_bottom - tws_tolerance and
         close < tws_zone_bottom and
         close < open

    tws_selected_mode == "Any Wick Contact" ? tws_wick_touch :
     tws_selected_mode == "Real Body Contact" ? tws_body_touch :
     tws_selected_mode == "Close Within Gap" ? tws_close_inside :
     tws_direction == 1 ? tws_mixed_long : tws_mixed_short

tws_return_strength(
     int tws_direction,
     float tws_zone_top,
     float tws_zone_bottom
 ) =>
    float tws_candle_range = math.max(high - low, syminfo.mintick)
    float tws_body_size = math.abs(close - open)
    float tws_lower_wick = math.min(open, close) - low
    float tws_upper_wick = high - math.max(open, close)
    float tws_close_location = tws_direction == 1 ? (close - low) / tws_candle_range : (high - close) / tws_candle_range
    float tws_wick_quality = tws_direction == 1 ? tws_lower_wick / tws_candle_range : tws_upper_wick / tws_candle_range
    float tws_body_quality = tws_bound(tws_body_size / math.max(tws_atr * 0.75, syminfo.mintick), 0.0, 1.0)
    float tws_directional_quality = tws_direction == 1 ? (close > open ? 1.0 : 0.0) : (close < open ? 1.0 : 0.0)
    float tws_zone_height = math.max(tws_zone_top - tws_zone_bottom, syminfo.mintick)
    float tws_penetration = tws_direction == 1 ? tws_bound((tws_zone_top - low) / tws_zone_height, 0.0, 1.0) : tws_bound((high - tws_zone_bottom) / tws_zone_height, 0.0, 1.0)
    float tws_penetration_quality = 1.0 - math.abs(tws_penetration - 0.50) * 2.0

    tws_bound(
         tws_close_location * 0.25 +
         tws_wick_quality * 0.25 +
         tws_body_quality * 0.20 +
         tws_directional_quality * 0.20 +
         tws_bound(tws_penetration_quality, 0.0, 1.0) * 0.10,
         0.0,
         1.0
     )

float tws_pivot_high = ta.pivothigh(high, tws_structure_len, tws_structure_len)
float tws_pivot_low = ta.pivotlow(low, tws_structure_len, tws_structure_len)

var float tws_last_swing_high = na
var float tws_last_swing_low = na
var int tws_last_swing_high_bar = na
var int tws_last_swing_low_bar = na
var bool tws_swing_high_broken = false
var bool tws_swing_low_broken = false
var int tws_structure_bias = 0

if not na(tws_pivot_high)
    tws_last_swing_high := tws_pivot_high
    tws_last_swing_high_bar := bar_index - tws_structure_len
    tws_swing_high_broken := false

if not na(tws_pivot_low)
    tws_last_swing_low := tws_pivot_low
    tws_last_swing_low_bar := bar_index - tws_structure_len
    tws_swing_low_broken := false

float tws_break_body_atr = tws_atr > 0 ? math.abs(close - open) / tws_atr : 0.0
float tws_bullish_break_level = not na(tws_last_swing_high) ? tws_last_swing_high + tws_atr * tws_break_buffer_atr : na
float tws_bearish_break_level = not na(tws_last_swing_low) ? tws_last_swing_low - tws_atr * tws_break_buffer_atr : na

bool tws_bullish_price_break =
     not na(tws_last_swing_high) and
     not tws_swing_high_broken and
     (
         tws_require_body_close ?
         close > tws_bullish_break_level and close[1] <= tws_bullish_break_level :
         high > tws_bullish_break_level and high[1] <= tws_bullish_break_level
     )

bool tws_bearish_price_break =
     not na(tws_last_swing_low) and
     not tws_swing_low_broken and
     (
         tws_require_body_close ?
         close < tws_bearish_break_level and close[1] >= tws_bearish_break_level :
         low < tws_bearish_break_level and low[1] >= tws_bearish_break_level
     )

bool tws_bullish_break = tws_bullish_price_break and (tws_classic_profile or not tws_use_break_displacement or tws_break_body_atr >= tws_minimum_break_body_atr)
bool tws_bearish_break = tws_bearish_price_break and (tws_classic_profile or not tws_use_break_displacement or tws_break_body_atr >= tws_minimum_break_body_atr)

float tws_bullish_break_expansion = tws_bullish_break and tws_atr > 0 ? math.max(close - tws_last_swing_high, 0.0) / tws_atr : 0.0
float tws_bearish_break_expansion = tws_bearish_break and tws_atr > 0 ? math.max(tws_last_swing_low - close, 0.0) / tws_atr : 0.0

float tws_bullish_break_strength = tws_bound(tws_bound(tws_break_body_atr / 1.50, 0.0, 1.0) * 0.65 + tws_bound(tws_bullish_break_expansion / 0.50, 0.0, 1.0) * 0.35, 0.0, 1.0)
float tws_bearish_break_strength = tws_bound(tws_bound(tws_break_body_atr / 1.50, 0.0, 1.0) * 0.65 + tws_bound(tws_bearish_break_expansion / 0.50, 0.0, 1.0) * 0.35, 0.0, 1.0)

string tws_bullish_break_type = tws_structure_bias == -1 ? "CHoCH" : "BOS"
string tws_bearish_break_type = tws_structure_bias == 1 ? "CHoCH" : "BOS"

if barstate.isconfirmed and tws_bullish_break
    tws_swing_high_broken := true
    tws_structure_bias := 1

    if tws_show_structure
        label.new(
             bar_index,
             high,
             "BULLISH " + tws_bullish_break_type + "\nQ " + str.tostring(tws_bullish_break_strength * 100.0, "#") + "%",
             style=label.style_label_down,
             color=tws_target_guide_color,
             textcolor=tws_label_dark_text ? color.black : color.white,
             size=size.tiny,
             tooltip="Structure confirmation\nConfirmed bullish " + tws_bullish_break_type + "\nBreak quality: " + str.tostring(tws_bullish_break_strength * 100.0, "#.0") + "%",
             text_formatting=text.format_bold + text.format_italic
         )

if barstate.isconfirmed and tws_bearish_break
    tws_swing_low_broken := true
    tws_structure_bias := -1

    if tws_show_structure
        label.new(
             bar_index,
             low,
             "BEARISH " + tws_bearish_break_type + "\nQ " + str.tostring(tws_bearish_break_strength * 100.0, "#") + "%",
             style=label.style_label_up,
             color=tws_bearish_color,
             textcolor=color.white,
             size=size.tiny,
             tooltip="Structure confirmation\nConfirmed bearish " + tws_bearish_break_type + "\nBreak quality: " + str.tostring(tws_bearish_break_strength * 100.0, "#.0") + "%",
             text_formatting=text.format_bold + text.format_italic
         )

var float[] tws_fvg_tops = array.new_float()
var float[] tws_fvg_bottoms = array.new_float()
var int[] tws_fvg_directions = array.new_int()
var int[] tws_fvg_birth_bars = array.new_int()
var float[] tws_fvg_displacement_scores = array.new_float()
var float[] tws_fvg_volume_scores = array.new_float()
var int[] tws_fvg_touch_counts = array.new_int()
var bool[] tws_fvg_was_touching = array.new_bool()
var box[] tws_fvg_boxes = array.new_box()

bool tws_bullish_fvg = bar_index >= 2 and low > high[2]
bool tws_bearish_fvg = bar_index >= 2 and high < low[2]

float tws_bullish_fvg_top = low
float tws_bullish_fvg_bottom = high[2]
float tws_bearish_fvg_top = low[2]
float tws_bearish_fvg_bottom = high

float tws_bullish_fvg_size = tws_bullish_fvg_top - tws_bullish_fvg_bottom
float tws_bearish_fvg_size = tws_bearish_fvg_top - tws_bearish_fvg_bottom

float tws_formation_atr = math.max(nz(tws_atr[1], tws_atr), syminfo.mintick)
float tws_formation_body = math.abs(close[1] - open[1])
float tws_formation_displacement_score = tws_bound(tws_formation_body / (tws_formation_atr * 1.50), 0.0, 1.0)
float tws_formation_volume_score = tws_volume_available and not na(tws_volume_average[1]) and tws_volume_average[1] > 0 ? tws_bound(volume[1] / (tws_volume_average[1] * 2.0), 0.0, 1.0) : 0.50

bool tws_valid_bullish_fvg =
     tws_bullish_fvg and
     tws_bullish_fvg_size >= tws_atr * tws_min_fvg_atr and
     (tws_classic_profile or not tws_use_fvg_displacement_filter or tws_formation_displacement_score >= tws_minimum_fvg_displacement)

bool tws_valid_bearish_fvg =
     tws_bearish_fvg and
     tws_bearish_fvg_size >= tws_atr * tws_min_fvg_atr and
     (tws_classic_profile or not tws_use_fvg_displacement_filter or tws_formation_displacement_score >= tws_minimum_fvg_displacement)

bool tws_show_all_fvgs = tws_fvg_display_mode == "All Active Gaps"

if barstate.isconfirmed and tws_valid_bullish_fvg
    box tws_bullish_box = box.new(
         left=bar_index - 2,
         top=tws_bullish_fvg_top,
         right=bar_index,
         bottom=tws_bullish_fvg_bottom,
         xloc=xloc.bar_index,
         bgcolor=tws_show_all_fvgs ? tws_bull_fvg_fill : color.new(tws_bullish_color, 100),
         border_color=tws_show_all_fvgs ? color.new(tws_bullish_color, 55) : color.new(tws_bullish_color, 100),
         border_width=1
     )

    array.push(tws_fvg_tops, tws_bullish_fvg_top)
    array.push(tws_fvg_bottoms, tws_bullish_fvg_bottom)
    array.push(tws_fvg_directions, 1)
    array.push(tws_fvg_birth_bars, bar_index)
    array.push(tws_fvg_displacement_scores, tws_formation_displacement_score)
    array.push(tws_fvg_volume_scores, tws_formation_volume_score)
    array.push(tws_fvg_touch_counts, 0)
    array.push(tws_fvg_was_touching, false)
    array.push(tws_fvg_boxes, tws_bullish_box)

if barstate.isconfirmed and tws_valid_bearish_fvg
    box tws_bearish_box = box.new(
         left=bar_index - 2,
         top=tws_bearish_fvg_top,
         right=bar_index,
         bottom=tws_bearish_fvg_bottom,
         xloc=xloc.bar_index,
         bgcolor=tws_show_all_fvgs ? tws_bear_fvg_fill : color.new(tws_bearish_color, 100),
         border_color=tws_show_all_fvgs ? color.new(tws_bearish_color, 55) : color.new(tws_bearish_color, 100),
         border_width=1
     )

    array.push(tws_fvg_tops, tws_bearish_fvg_top)
    array.push(tws_fvg_bottoms, tws_bearish_fvg_bottom)
    array.push(tws_fvg_directions, -1)
    array.push(tws_fvg_birth_bars, bar_index)
    array.push(tws_fvg_displacement_scores, tws_formation_displacement_score)
    array.push(tws_fvg_volume_scores, tws_formation_volume_score)
    array.push(tws_fvg_touch_counts, 0)
    array.push(tws_fvg_was_touching, false)
    array.push(tws_fvg_boxes, tws_bearish_box)

int tws_cleanup_index = array.size(tws_fvg_tops) - 1

while tws_cleanup_index >= 0
    float tws_stored_top = array.get(tws_fvg_tops, tws_cleanup_index)
    float tws_stored_bottom = array.get(tws_fvg_bottoms, tws_cleanup_index)
    int tws_stored_direction = array.get(tws_fvg_directions, tws_cleanup_index)
    int tws_stored_birth = array.get(tws_fvg_birth_bars, tws_cleanup_index)
    int tws_stored_touch_count = array.get(tws_fvg_touch_counts, tws_cleanup_index)
    bool tws_was_touching = array.get(tws_fvg_was_touching, tws_cleanup_index)
    box tws_stored_box = array.get(tws_fvg_boxes, tws_cleanup_index)

    bool tws_touching_now =
         bar_index > tws_stored_birth and
         low <= tws_stored_top and
         high >= tws_stored_bottom

    if barstate.isconfirmed and tws_touching_now and not tws_was_touching
        tws_stored_touch_count += 1
        array.set(tws_fvg_touch_counts, tws_cleanup_index, tws_stored_touch_count)

    array.set(tws_fvg_was_touching, tws_cleanup_index, tws_touching_now)

    bool tws_expired = bar_index - tws_stored_birth > tws_max_fvg_age
    bool tws_invalidated =
         barstate.isconfirmed and
         tws_remove_invalid_fvgs and
         (
             tws_stored_direction == 1 ?
             close < tws_stored_bottom :
             close > tws_stored_top
         )

    if tws_expired or tws_invalidated
        box.delete(tws_stored_box)
        array.remove(tws_fvg_tops, tws_cleanup_index)
        array.remove(tws_fvg_bottoms, tws_cleanup_index)
        array.remove(tws_fvg_directions, tws_cleanup_index)
        array.remove(tws_fvg_birth_bars, tws_cleanup_index)
        array.remove(tws_fvg_displacement_scores, tws_cleanup_index)
        array.remove(tws_fvg_volume_scores, tws_cleanup_index)
        array.remove(tws_fvg_touch_counts, tws_cleanup_index)
        array.remove(tws_fvg_was_touching, tws_cleanup_index)
        array.remove(tws_fvg_boxes, tws_cleanup_index)
    else
        box.set_right(tws_stored_box, bar_index)
        box.set_bgcolor(tws_stored_box, tws_show_all_fvgs ? tws_stored_direction == 1 ? tws_bull_fvg_fill : tws_bear_fvg_fill : color.new(color.black, 100))
        box.set_border_color(tws_stored_box, tws_show_all_fvgs ? color.new(tws_stored_direction == 1 ? tws_bullish_color : tws_bearish_color, 55) : color.new(color.black, 100))

    tws_cleanup_index -= 1

while array.size(tws_fvg_tops) > tws_max_fvg_zones
    box tws_oldest_box = array.shift(tws_fvg_boxes)
    box.delete(tws_oldest_box)
    array.shift(tws_fvg_tops)
    array.shift(tws_fvg_bottoms)
    array.shift(tws_fvg_directions)
    array.shift(tws_fvg_birth_bars)
    array.shift(tws_fvg_displacement_scores)
    array.shift(tws_fvg_volume_scores)
    array.shift(tws_fvg_touch_counts)
    array.shift(tws_fvg_was_touching)

var bool tws_pending_break = false
var int tws_pending_direction = 0
var int tws_pending_break_bar = na
var float tws_pending_break_price = na
var float tws_pending_break_strength = na
var string tws_pending_break_type = "—"

bool tws_armed_event = false
bool tws_no_eligible_fvg_event = false
bool tws_setup_expired_event = false
bool tws_fvg_invalidated_event = false

var bool tws_setup_armed = false
var int tws_armed_direction = 0
var int tws_armed_break_bar = na
var int tws_armed_fvg_birth_bar = na
var float tws_armed_top = na
var float tws_armed_bottom = na
var float tws_armed_score = na
var int tws_armed_stars = 0
var int tws_armed_prior_touches = 0
var string tws_armed_break_type = "—"
var float tws_armed_break_strength = na

var box tws_selected_fvg_box = na
var int tws_last_trade_close_bar = na

bool tws_cooldown_complete = na(tws_last_trade_close_bar) or bar_index - tws_last_trade_close_bar >= tws_cooldown_after_close

if barstate.isconfirmed and tws_bullish_break and tws_allow_longs and tws_cooldown_complete
    tws_pending_break := true
    tws_pending_direction := 1
    tws_pending_break_bar := bar_index
    tws_pending_break_price := tws_last_swing_high
    tws_pending_break_strength := tws_bull

Показано первые 50% кода (символов: 86994)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
8 699,40₽ ≈ $106.32