AshICT

chatgpt code

Jul 11th, 2026
7
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 143.62 KB | None | 0 0
  1. //@version=6
  2. indicator(
  3. title = "Ash ICT CRT — Protocol Engine v20.2 Narrative Candidate State Tracker",
  4. shorttitle = "Ash CRT Protocol v20.2",
  5. overlay = true,
  6. dynamic_requests = true,
  7. max_lines_count = 500,
  8. max_labels_count = 500
  9. )
  10.  
  11. //======================================================================
  12. // 1. CORE CRT SETTINGS
  13. //======================================================================
  14. groupCore = "1. Core CRT Detection"
  15.  
  16. useSelectedHours = input.bool(
  17. true,
  18. "Use Market-Specific CRT Time Protocol",
  19. group = groupCore,
  20. tooltip = "The time model is a quality protocol, not a mandatory trade signal. Daily, Weekly and Monthly candles automatically pass the time protocol."
  21. )
  22.  
  23. marketTimeProfile = input.string(
  24. "Auto",
  25. "Market Time Profile",
  26. options = ["Auto", "Forex", "Indices", "Futures", "Crypto", "Commodities", "Manual"],
  27. group = groupCore,
  28. tooltip = "Auto uses TradingView symbol metadata and ticker keywords. Use a manual profile when a broker classifies the symbol differently."
  29. )
  30.  
  31. timezoneInput = input.string(
  32. "America/New_York",
  33. "CRT Model Timezone",
  34. options = [
  35. "America/New_York",
  36. "Etc/UTC",
  37. "Europe/London",
  38. "Asia/Dubai",
  39. "Asia/Kolkata"
  40. ],
  41. group = groupCore
  42. )
  43.  
  44. timeMatchToleranceHours = input.int(
  45. 0,
  46. "Time Match Tolerance (Hours)",
  47. minval = 0,
  48. maxval = 2,
  49. group = groupCore,
  50. tooltip = "0 requires an exact model-hour open. Increase to 1 for brokers whose 2H/3H candle alignment is shifted by one hour."
  51. )
  52.  
  53. forexHour1 = input.int(1, "Forex Hour 1", minval = 0, maxval = 23, group = groupCore)
  54. forexHour2 = input.int(5, "Forex Hour 2", minval = 0, maxval = 23, group = groupCore)
  55. forexHour3 = input.int(9, "Forex Hour 3", minval = 0, maxval = 23, group = groupCore)
  56.  
  57. indicesHour1 = input.int(2, "Indices Hour 1", minval = 0, maxval = 23, group = groupCore)
  58. indicesHour2 = input.int(6, "Indices Hour 2", minval = 0, maxval = 23, group = groupCore)
  59. indicesHour3 = input.int(10, "Indices Hour 3", minval = 0, maxval = 23, group = groupCore)
  60.  
  61. futuresHour1 = input.int(2, "Futures Hour 1", minval = 0, maxval = 23, group = groupCore)
  62. futuresHour2 = input.int(6, "Futures Hour 2", minval = 0, maxval = 23, group = groupCore)
  63. futuresHour3 = input.int(10, "Futures Hour 3", minval = 0, maxval = 23, group = groupCore)
  64.  
  65. cryptoHour1 = input.int(1, "Crypto Hour 1", minval = 0, maxval = 23, group = groupCore)
  66. cryptoHour2 = input.int(5, "Crypto Hour 2", minval = 0, maxval = 23, group = groupCore)
  67. cryptoHour3 = input.int(9, "Crypto Hour 3", minval = 0, maxval = 23, group = groupCore)
  68.  
  69. commoditiesHour1 = input.int(1, "Commodities Hour 1", minval = 0, maxval = 23, group = groupCore)
  70. commoditiesHour2 = input.int(5, "Commodities Hour 2", minval = 0, maxval = 23, group = groupCore)
  71. commoditiesHour3 = input.int(9, "Commodities Hour 3", minval = 0, maxval = 23, group = groupCore)
  72.  
  73. manualHour1 = input.int(1, "Manual Hour 1", minval = 0, maxval = 23, group = groupCore)
  74. manualHour2 = input.int(5, "Manual Hour 2", minval = 0, maxval = 23, group = groupCore)
  75. manualHour3 = input.int(9, "Manual Hour 3", minval = 0, maxval = 23, group = groupCore)
  76.  
  77. requireCloseInside = input.bool(
  78. true,
  79. "Manipulation Must Close Back Inside Range",
  80. group = groupCore
  81. )
  82.  
  83. rejectDoubleSweep = input.bool(
  84. true,
  85. "Reject Manipulation Sweeping Both Sides",
  86. group = groupCore
  87. )
  88.  
  89. requireDirectionalClose = input.bool(
  90. false,
  91. "Require Directional Manipulation Close",
  92. group = groupCore,
  93. tooltip = "Bullish setup: manipulation candle must close bullish. Bearish setup: manipulation candle must close bearish."
  94. )
  95.  
  96. //======================================================================
  97. // 2. PROTOCOL ENGINE
  98. //======================================================================
  99. groupProtocol = "2. Protocol Engine"
  100.  
  101. minimumProtocols = input.int(
  102. 3,
  103. "Minimum Protocols Required",
  104. minval = 1,
  105. maxval = 9,
  106. group = groupProtocol,
  107. tooltip = "The blue/yellow sequence appears only when the setup passes at least this many enabled quality protocols."
  108. )
  109.  
  110. useTimeProtocol = input.bool(true, "Protocol 1 — Valid CRT Time", group = groupProtocol)
  111. useKeyLevelProtocol = input.bool(true, "Protocol 2 — HTF Key-Level Interaction", group = groupProtocol)
  112. useRejectionProtocol = input.bool(true, "Protocol 3 — Strong Rejection Wick", group = groupProtocol)
  113. useMidpointProtocol = input.bool(true, "Protocol 4 — Midpoint Reclaim", group = groupProtocol)
  114. useRangeSizeProtocol = input.bool(true, "Protocol 5 — Controlled Range Size", group = groupProtocol)
  115. useBodyProtocol = input.bool(true, "Protocol 6 — Healthy Range Body", group = groupProtocol)
  116. usePOIProtocol = input.bool(true, "Protocol 7 — Directional HTF POI Confluence", group = groupProtocol, tooltip = "Requires POI direction to agree with the CRT purge direction. Bullish CRTs seek bullish POIs after sell-side purge; bearish CRTs seek bearish POIs after buy-side purge.")
  117.  
  118. useHierarchyProtocol = input.bool(
  119. true,
  120. "Protocol 8 — Higher-Timeframe CRT Alignment",
  121. group = groupProtocol,
  122. tooltip = "Compares the candidate CRT direction with the latest confirmed structural CRT direction on its parent timeframe."
  123. )
  124.  
  125. neutralHierarchyPass = input.bool(
  126. true,
  127. "Allow CRT When Parent Direction Is Neutral",
  128. group = groupProtocol
  129. )
  130.  
  131. rejectOpposingHierarchy = input.bool(
  132. true,
  133. "Reject Opposing Parent CRT Direction",
  134. group = groupProtocol,
  135. tooltip = "Example: a bearish H1 CRT is rejected while the latest H4 CRT context remains bullish."
  136. )
  137.  
  138. string groupLifecycle = "CRT Lifecycle Engine"
  139.  
  140. lifecycleExpiryBars = input.int(
  141. 12,
  142. "Expire CRT After Bars",
  143. minval = 1,
  144. maxval = 100,
  145. group = groupLifecycle,
  146. tooltip = "An active CRT stops influencing hierarchy when its opposite-side target has not been reached within this many source-timeframe candles."
  147. )
  148.  
  149. targetRequiresClose = input.bool(
  150. false,
  151. "Target Requires Candle Close",
  152. group = groupLifecycle,
  153. tooltip = "Off: touching the opposite side completes the CRT. On: price must close through the opposite side."
  154. )
  155.  
  156. invalidationRequiresClose = input.bool(
  157. true,
  158. "Invalidation Requires Candle Close",
  159. group = groupLifecycle,
  160. tooltip = "Bullish CRT invalidates below the Range low; bearish CRT invalidates above the Range high. Keeping this enabled avoids wick-only invalidations."
  161. )
  162.  
  163. replaceWithNewestCRT = input.bool(
  164. true,
  165. "Newest CRT Replaces Previous CRT",
  166. group = groupLifecycle,
  167. tooltip = "A newer qualified CRT on the same timeframe becomes the active lifecycle context."
  168. )
  169.  
  170. // v19.8 Narrative Reset / Re-Arm controls
  171. enableNarrativeRearmEngine = input.bool(
  172. true,
  173. "Enable Narrative Reset / Re-Arm Engine",
  174. group = groupLifecycle,
  175. tooltip = "After a parent objective is completed, invalidated, or expired, execution remains stood down until a genuinely newer qualified parent CRT creates a fresh narrative."
  176. )
  177.  
  178. rearmDisplayParentBars = input.int(
  179. 2,
  180. "Show RE-ARMED State for Parent Bars",
  181. minval = 1,
  182. maxval = 10,
  183. group = groupLifecycle,
  184. tooltip = "Controls how long the dashboard highlights the newly re-armed parent narrative after the fresh qualified parent CRT."
  185. )
  186.  
  187. // v19.9 Narrative Transition Memory / Freshness controls
  188. enableNarrativeFreshnessEngine = input.bool(
  189. true,
  190. "Enable Narrative Transition Memory / Freshness Engine",
  191. group = groupLifecycle,
  192. tooltip = "Assigns a unique sequential identity to each qualified source-timeframe CRT. After a terminal story, only a later narrative identity can be treated as fresh and re-arm execution."
  193. )
  194.  
  195. freshNarrativeDisplayBars = input.int(
  196. 4,
  197. "Fresh Narrative Highlight (Parent Bars)",
  198. minval = 1,
  199. maxval = 20,
  200. group = groupLifecycle,
  201. tooltip = "Number of parent-timeframe bars during which a newly created narrative is labelled FRESH. The narrative remains active afterward, but the freshness highlight ends."
  202. )
  203.  
  204. // v20.0 Fresh Narrative Validation Engine
  205. enableFreshNarrativeValidation = input.bool(
  206. true,
  207. "Enable Fresh Narrative Validation Engine",
  208. group = groupLifecycle,
  209. tooltip = "A post-reset parent CRT must validate direction, HTF context, delivery, and an undelivered objective before execution can re-arm."
  210. )
  211.  
  212. freshValidationWindowBars = input.int(
  213. 4,
  214. "Fresh Narrative Validation Window (Parent Bars)",
  215. minval = 1,
  216. maxval = 20,
  217. group = groupLifecycle,
  218. tooltip = "Maximum number of parent bars allowed for delivery confirmation. A fresh narrative that does not begin directional delivery inside this window is rejected."
  219. )
  220.  
  221. requireFreshHierarchyAlignment = input.bool(
  222. true,
  223. "Require HTF Context Alignment",
  224. group = groupLifecycle,
  225. tooltip = "Rejects a fresh parent CRT when it opposes the active higher-timeframe structural CRT. Neutral higher-timeframe context is allowed."
  226. )
  227.  
  228. requireFreshDeliveryConfirmation = input.bool(
  229. true,
  230. "Require Delivery Confirmation",
  231. group = groupLifecycle,
  232. tooltip = "Requires the existing displacement/delivery engine to confirm movement away from the manipulated side before execution re-arms."
  233. )
  234.  
  235. // Directional POI context controls
  236. poiLookback = input.int(
  237. 80,
  238. "POI Detection Lookback",
  239. minval = 10,
  240. maxval = 300,
  241. group = groupProtocol
  242. )
  243.  
  244. poiToleranceATR = input.float(
  245. 0.05,
  246. "POI Touch Tolerance (ATR)",
  247. minval = 0.0,
  248. step = 0.01,
  249. group = groupProtocol
  250. )
  251.  
  252. minimumPOITypes = input.int(
  253. 1,
  254. "Minimum Aligned POI Types Required",
  255. minval = 1,
  256. maxval = 5,
  257. group = groupProtocol
  258. )
  259.  
  260. minimumDirectionalPOIScore = input.int(
  261. 2,
  262. "Minimum Directional POI Score",
  263. minval = 1,
  264. maxval = 10,
  265. group = groupProtocol,
  266. tooltip = "FVG/Order Block = 2 points. IFVG/Breaker/Rejection Block = 3 points."
  267. )
  268.  
  269. rejectOpposingPOIDominance = input.bool(
  270. true,
  271. "Reject Opposing POI Dominance",
  272. group = groupProtocol
  273. )
  274.  
  275. useFVGPOI = input.bool(true, "Include Fair Value Gaps", group = groupProtocol)
  276. useIFVGPOI = input.bool(true, "Include Inverse FVGs", group = groupProtocol)
  277. useOrderBlockPOI = input.bool(true, "Include Order Blocks", group = groupProtocol)
  278. useBreakerPOI = input.bool(true, "Include Breaker Blocks", group = groupProtocol)
  279. useRejectionBlockPOI = input.bool(true, "Include Rejection Blocks", group = groupProtocol)
  280.  
  281. keyLevelToleranceATR = input.float(
  282. 0.10,
  283. "Key-Level Touch Tolerance (ATR)",
  284. minval = 0.0,
  285. step = 0.01,
  286. group = groupProtocol
  287. )
  288.  
  289. minimumRejectionPercent = input.float(
  290. 35.0,
  291. "Minimum Manipulation Rejection Wick %",
  292. minval = 0.0,
  293. maxval = 100.0,
  294. step = 1.0,
  295. group = groupProtocol
  296. )
  297.  
  298. requireMidpointReclaim = input.bool(
  299. true,
  300. "Require Range Midpoint Reclaim",
  301. group = groupProtocol
  302. )
  303.  
  304. atrLength = input.int(
  305. 20,
  306. "ATR Length",
  307. minval = 1,
  308. group = groupProtocol
  309. )
  310.  
  311. minimumRangeATR = input.float(
  312. 0.4,
  313. "Minimum Range Size (ATR)",
  314. minval = 0.0,
  315. step = 0.1,
  316. group = groupProtocol
  317. )
  318.  
  319. maximumRangeATR = input.float(
  320. 2.0,
  321. "Maximum Range Size (ATR)",
  322. minval = 0.1,
  323. step = 0.1,
  324. group = groupProtocol
  325. )
  326.  
  327. minimumRangeBodyPercent = input.float(
  328. 20.0,
  329. "Minimum Range Body %",
  330. minval = 0.0,
  331. maxval = 100.0,
  332. step = 1.0,
  333. group = groupProtocol
  334. )
  335.  
  336. maximumRangeBodyPercent = input.float(
  337. 80.0,
  338. "Maximum Range Body %",
  339. minval = 0.0,
  340. maxval = 100.0,
  341. step = 1.0,
  342. group = groupProtocol
  343. )
  344.  
  345. string groupLiquidity = "Liquidity Purge Context"
  346.  
  347. useLiquidityPurgeContext = input.bool(
  348. true,
  349. "Protocol 10 — Meaningful Liquidity Purge Context",
  350. group = groupLiquidity,
  351. tooltip = "Bonus context only. It does not reject or hide any CRT that qualified under the stable v16.7 engine."
  352. )
  353.  
  354. liquiditySwingLookback = input.int(
  355. 20,
  356. "Swing Liquidity Lookback",
  357. minval = 3,
  358. maxval = 200,
  359. group = groupLiquidity
  360. )
  361.  
  362. liquidityToleranceATR = input.float(
  363. 0.05,
  364. "Liquidity Equality Tolerance (ATR)",
  365. minval = 0.0,
  366. step = 0.01,
  367. group = groupLiquidity
  368. )
  369.  
  370. minimumLiquidityPurgeScore = input.int(
  371. 1,
  372. "Meaningful Purge Score Threshold",
  373. minval = 1,
  374. maxval = 6,
  375. group = groupLiquidity,
  376. tooltip = "Previous day = 1, previous week = 2, previous month = 3, established swing liquidity = 1."
  377. )
  378.  
  379. string groupNested = "CRT Sequence / Nested HTF Context"
  380.  
  381. useNestedCRTContext = input.bool(
  382. true,
  383. "Protocol 11 — Nested HTF CRT Context",
  384. group = groupNested,
  385. tooltip = "Bonus context only. Detects when the current CRT is nested inside, overlaps, or directionally aligns with an active parent-timeframe CRT. It cannot reject or hide stable v16.9 CRTs."
  386. )
  387.  
  388. requireFullParentContainment = input.bool(
  389. false,
  390. "Require Full Containment for Nested State",
  391. group = groupNested,
  392. tooltip = "Off: overlap with the active parent CRT range qualifies. On: the complete local Range candle must sit inside the parent CRT range."
  393. )
  394.  
  395. useParentPremiumDiscount = input.bool(
  396. true,
  397. "Score Parent Premium / Discount Location",
  398. group = groupNested,
  399. tooltip = "Bullish nested CRTs score when formed in the lower half of the parent range. Bearish nested CRTs score in the upper half."
  400. )
  401.  
  402. minimumNestedContextScore = input.int(
  403. 2,
  404. "Meaningful Nested Context Score",
  405. minval = 1,
  406. maxval = 3,
  407. group = groupNested,
  408. tooltip = "Inside/overlap = 1, direction aligned = 1, correct premium/discount location = 1."
  409. )
  410.  
  411. string groupDelivery = "Displacement / Delivery Confirmation"
  412.  
  413. useDeliveryContext = input.bool(
  414. true,
  415. "Protocol 12 — Displacement and Delivery Confirmation",
  416. group = groupDelivery,
  417. tooltip = "Bonus confirmation only. Evaluates post-manipulation delivery without hiding CRTs qualified by the stable v17.1 engine."
  418. )
  419.  
  420. deliveryWindowBars = input.int(
  421. 3,
  422. "Delivery Confirmation Window (Bars)",
  423. minval = 1,
  424. maxval = 6,
  425. group = groupDelivery
  426. )
  427.  
  428. minimumDeliveryBodyATR = input.float(
  429. 0.50,
  430. "Minimum Displacement Body (ATR)",
  431. minval = 0.0,
  432. step = 0.05,
  433. group = groupDelivery
  434. )
  435.  
  436. requireDeliveryFVG = input.bool(
  437. false,
  438. "Require FVG Creation for Delivery Bonus",
  439. group = groupDelivery
  440. )
  441.  
  442. minimumDeliveryScore = input.int(
  443. 2,
  444. "Meaningful Delivery Score",
  445. minval = 1,
  446. maxval = 4,
  447. group = groupDelivery,
  448. tooltip = "Directional close = 1, strong ATR body = 1, range-mid delivery = 1, FVG creation = 1."
  449. )
  450.  
  451. string groupFailure = "Failed CRT / Reversal Context"
  452.  
  453. useFailedCRTContext = input.bool(
  454. true,
  455. "Protocol 13 — Failed CRT / Reversal Context",
  456. group = groupFailure,
  457. tooltip = "Context only. Tracks a qualified CRT that fails through its manipulated-side boundary and treats that failure as potential opposite-direction information. It does not hide stable v17.4 CRTs."
  458. )
  459.  
  460. failureRequiresClose = input.bool(
  461. true,
  462. "Failure Requires Close Through Boundary",
  463. group = groupFailure
  464. )
  465.  
  466. failureWindowBars = input.int(
  467. 6,
  468. "Failure Detection Window (Bars)",
  469. minval = 1,
  470. maxval = 30,
  471. group = groupFailure
  472. )
  473.  
  474. requireFailureDirectionalClose = input.bool(
  475. true,
  476. "Require Failure Candle Direction",
  477. group = groupFailure,
  478. tooltip = "Bullish CRT failure candle must close bearish; bearish CRT failure candle must close bullish."
  479. )
  480.  
  481. minimumFailureBodyATR = input.float(
  482. 0.25,
  483. "Minimum Failure Body (ATR)",
  484. minval = 0.0,
  485. step = 0.05,
  486. group = groupFailure
  487. )
  488.  
  489. string groupTarget = "CRT Target Delivery / Draw on Liquidity"
  490.  
  491. useTargetDeliveryContext = input.bool(
  492. true,
  493. "Protocol 14 — Target Delivery / Draw on Liquidity",
  494. group = groupTarget,
  495. tooltip = "Context only. Selects the nearest valid opposite-side liquidity objective for each qualified CRT. It does not alter stable v17.5 CRT qualification or candle colors."
  496. )
  497.  
  498. includeOppositeCRTRangeBoundary = input.bool(
  499. true,
  500. "Include Opposite CRT Range Boundary",
  501. group = groupTarget
  502. )
  503.  
  504. includePreviousDayTarget = input.bool(
  505. true,
  506. "Include Previous Day Liquidity",
  507. group = groupTarget
  508. )
  509.  
  510. includePreviousWeekTarget = input.bool(
  511. true,
  512. "Include Previous Week Liquidity",
  513. group = groupTarget
  514. )
  515.  
  516. includePreviousMonthTarget = input.bool(
  517. true,
  518. "Include Previous Month Liquidity",
  519. group = groupTarget
  520. )
  521.  
  522. includeSwingLiquidityTarget = input.bool(
  523. true,
  524. "Include Swing Liquidity",
  525. group = groupTarget
  526. )
  527.  
  528. targetSwingLookback = input.int(
  529. 20,
  530. "Target Swing Lookback",
  531. minval = 3,
  532. maxval = 200,
  533. group = groupTarget
  534. )
  535.  
  536. targetReachToleranceATR = input.float(
  537. 0.05,
  538. "Target Reach Tolerance (ATR)",
  539. minval = 0.0,
  540. step = 0.01,
  541. group = groupTarget
  542. )
  543.  
  544. string groupGrade = "CRT Intelligence Grade Engine"
  545.  
  546. useIntelligenceGrade = input.bool(
  547. true,
  548. "CRT Intelligence Grade Engine",
  549. group = groupGrade,
  550. tooltip = "Grades qualified CRTs from C to A+ using the protocol intelligence already built. Grading is informational and does not alter stable v17.6 CRT qualification."
  551. )
  552.  
  553. gradeAPlusThreshold = input.int(
  554. 8,
  555. "A+ Minimum Intelligence Score",
  556. minval = 1,
  557. maxval = 10,
  558. group = groupGrade
  559. )
  560.  
  561. gradeAThreshold = input.int(
  562. 6,
  563. "A Minimum Intelligence Score",
  564. minval = 1,
  565. maxval = 10,
  566. group = groupGrade
  567. )
  568.  
  569. gradeBThreshold = input.int(
  570. 4,
  571. "B Minimum Intelligence Score",
  572. minval = 1,
  573. maxval = 10,
  574. group = groupGrade
  575. )
  576.  
  577. string groupDashboard = "CRT Intelligence Dashboard"
  578.  
  579. showIntelligenceDashboard = input.bool(
  580. true,
  581. "Show CRT Intelligence Dashboard",
  582. group = groupDashboard
  583. )
  584.  
  585. dashboardPosition = input.string(
  586. "Top Right",
  587. "Dashboard Position",
  588. options = ["Top Right", "Top Left", "Bottom Right", "Bottom Left"],
  589. group = groupDashboard
  590. )
  591.  
  592. dashboardTextSize = input.string(
  593. "Small",
  594. "Dashboard Text Size",
  595. options = ["Tiny", "Small", "Normal"],
  596. group = groupDashboard
  597. )
  598.  
  599. string groupKeyLevel = "Dedicated ICT Key Level Engine"
  600.  
  601. useDedicatedKeyLevelEngine = input.bool(
  602. true,
  603. "Enable Dedicated ICT Key Level Engine",
  604. group = groupKeyLevel,
  605. tooltip = "Detects the dominant FVG, IFVG, Order Block, Breaker, or Rejection Block interacting with the latest CRT Range on the selected source timeframe."
  606. )
  607.  
  608. keyLevelLookback = input.int(
  609. 80,
  610. "Key Level Detection Lookback",
  611. minval = 10,
  612. maxval = 300,
  613. group = groupKeyLevel
  614. )
  615.  
  616. keyLevelTypeToleranceATR = input.float(
  617. 0.05,
  618. "Key Level Zone Tolerance (ATR)",
  619. minval = 0.0,
  620. step = 0.01,
  621. group = groupKeyLevel
  622. )
  623.  
  624. string groupSMT = "SMT / Multi-Asset Matrix"
  625.  
  626. useSMTProtocol = input.bool(
  627. true,
  628. "Protocol 9 — Multi-Asset SMT Matrix",
  629. group = groupSMT,
  630. tooltip = "Checks the candidate CRT against up to two correlated or inversely correlated comparison markets."
  631. )
  632.  
  633. smtMode = input.string(
  634. "Auto Matrix",
  635. "SMT Comparison Mode",
  636. options = ["Auto Matrix", "Manual"],
  637. group = groupSMT
  638. )
  639.  
  640. manualSMTSymbol1 = input.symbol(
  641. "CME_MINI:NQ1!",
  642. "Manual Comparison Symbol 1",
  643. group = groupSMT
  644. )
  645.  
  646. manualSMTRelation1 = input.string(
  647. "Direct",
  648. "Manual Symbol 1 Relation",
  649. options = ["Direct", "Inverse"],
  650. group = groupSMT
  651. )
  652.  
  653. manualSMTSymbol2 = input.symbol(
  654. "CBOT_MINI:YM1!",
  655. "Manual Comparison Symbol 2",
  656. group = groupSMT
  657. )
  658.  
  659. manualSMTRelation2 = input.string(
  660. "Direct",
  661. "Manual Symbol 2 Relation",
  662. options = ["Direct", "Inverse"],
  663. group = groupSMT
  664. )
  665.  
  666. useSecondSMTMarket = input.bool(
  667. true,
  668. "Use Second SMT Market",
  669. group = groupSMT
  670. )
  671.  
  672. smtLookback = input.int(
  673. 20,
  674. "SMT Swing Lookback",
  675. minval = 2,
  676. maxval = 200,
  677. group = groupSMT
  678. )
  679.  
  680. smtToleranceATR = input.float(
  681. 0.05,
  682. "SMT Equality Tolerance (ATR)",
  683. minval = 0.0,
  684. step = 0.01,
  685. group = groupSMT
  686. )
  687.  
  688. minimumSMTConfirmations = input.int(
  689. 1,
  690. "Minimum Aligned SMT Confirmations",
  691. minval = 1,
  692. maxval = 2,
  693. group = groupSMT,
  694. tooltip = "One aligned comparison is enough by default. Set to 2 for stricter multi-market confirmation."
  695. )
  696.  
  697. allowNeutralSMT = input.bool(
  698. true,
  699. "Allow Neutral SMT",
  700. group = groupSMT
  701. )
  702.  
  703. rejectOpposingSMT = input.bool(
  704. false,
  705. "Reject Strong Opposing SMT",
  706. group = groupSMT,
  707. tooltip = "Rejects a CRT when opposing SMT confirmations outnumber aligned SMT confirmations."
  708. )
  709.  
  710. //======================================================================
  711. // 3. VISUAL SETTINGS
  712. //======================================================================
  713. groupVisual = "3. Visual Settings"
  714.  
  715. colorCandles = input.bool(true, "Color Qualified CRT Candles on Source Timeframe", group = groupVisual)
  716. rangeColor = input.color(color.rgb(35, 125, 225), "Range Candle Color", group = groupVisual)
  717. manipulationColor = input.color(color.rgb(255, 195, 0), "Manipulation Candle Color", group = groupVisual)
  718.  
  719. //======================================================================
  720. // 4. MULTI-HTF HIERARCHY + AUTO AMD WINDOWS
  721. //======================================================================
  722. groupProjection = "4. Multi-HTF Hierarchy + AMD Windows"
  723.  
  724. enableHTFProjection = input.bool(
  725. true,
  726. "Show Selected HTF AMD Windows on Lower Timeframes",
  727. group = groupProjection
  728. )
  729.  
  730. hierarchyContext = input.string(
  731. "Auto",
  732. "HTF Context Mode",
  733. options = ["Auto", "Monthly", "Weekly", "Daily", "H4", "H3", "H2", "H1", "30m"],
  734. group = groupProjection,
  735. tooltip = "Auto uses the chart timeframe on Monthly, Weekly, Daily, H4, H3, H2, H1 and 30m charts. On charts below 30m it uses the Lower-TF Projection Context selected below."
  736. )
  737.  
  738. lowerTFProjectionContext = input.string(
  739. "H4",
  740. "Lower-TF Projection Context",
  741. options = ["Monthly", "Weekly", "Daily", "H4", "H3", "H2", "H1", "30m"],
  742. group = groupProjection,
  743. tooltip = "Used only when HTF Context Mode is Auto and the chart timeframe is below 30 minutes."
  744. )
  745.  
  746. f_contextToTF(string context) =>
  747. context == "Monthly" ? "M" :
  748. context == "Weekly" ? "W" :
  749. context == "Daily" ? "D" :
  750. context == "H3" ? "180" :
  751. context == "H2" ? "120" :
  752. context == "H1" ? "60" :
  753. context == "30m" ? "30" : "240"
  754.  
  755. int currentChartSeconds = timeframe.in_seconds(timeframe.period)
  756.  
  757. string autoSelectedHTF =
  758. timeframe.ismonthly ? "M" :
  759. timeframe.isweekly ? "W" :
  760. timeframe.isdaily ? "D" :
  761. not na(currentChartSeconds) and currentChartSeconds >= 14400 ? "240" :
  762. not na(currentChartSeconds) and currentChartSeconds >= 10800 ? "180" :
  763. not na(currentChartSeconds) and currentChartSeconds >= 7200 ? "120" :
  764. not na(currentChartSeconds) and currentChartSeconds >= 3600 ? "60" :
  765. not na(currentChartSeconds) and currentChartSeconds >= 1800 ? "30" :
  766. f_contextToTF(lowerTFProjectionContext)
  767.  
  768. string selectedHTF = hierarchyContext == "Auto" ? autoSelectedHTF : f_contextToTF(hierarchyContext)
  769.  
  770. // Clean-chart mode: no automatic AMD vertical separators or phase labels.
  771. // The selected HTF structure is still tracked internally for LTF unlock logic.
  772.  
  773.  
  774. //======================================================================
  775. // 5. EXECUTION UNLOCK ENGINE
  776. //======================================================================
  777. groupExecution = "5. Execution Unlock Engine"
  778.  
  779. enableExecutionEngine = input.bool(
  780. true,
  781. "Enable LTF Execution Scanner",
  782. group = groupExecution,
  783. tooltip = "After the selected HTF manipulation closes, scan only its Distribution window for aligned lower-timeframe CRT structure."
  784. )
  785.  
  786. maximumExecutionMinutes = input.int(
  787. 15,
  788. "Maximum Execution Chart Timeframe (Minutes)",
  789. minval = 1,
  790. maxval = 60,
  791. group = groupExecution,
  792. tooltip = "Example: 15 allows the scanner on 15m, 5m, 3m, 2m and 1m charts."
  793. )
  794.  
  795. firstExecutionOnly = input.bool(
  796. true,
  797. "Show First Entry Only per HTF Setup",
  798. group = groupExecution
  799. )
  800.  
  801. colorUnlockedLTFStructure = input.bool(
  802. true,
  803. "Color Unlocked LTF Range + Manipulation",
  804. group = groupExecution,
  805. tooltip = "Inside the confirmed HTF Distribution window, color only aligned lower-timeframe CRT structure: blue Range candle and yellow Manipulation candle."
  806. )
  807.  
  808. showRawCRTForTesting = input.bool(
  809. false,
  810. "TEST — Show Raw CRT Without Protocol Filters",
  811. group = groupExecution,
  812. tooltip = "Diagnostic only. Shows every valid close-back-inside CRT before protocol filtering."
  813. )
  814.  
  815. localRequireCloseInside = input.bool(
  816. true,
  817. "LTF Manipulation Must Close Inside Local Range",
  818. group = groupExecution
  819. )
  820.  
  821. localRequireMidpoint = input.bool(
  822. true,
  823. "LTF Manipulation Must Reclaim Local Midpoint",
  824. group = groupExecution
  825. )
  826.  
  827. localMinimumRejection = input.float(
  828. 25.0,
  829. "Minimum LTF Rejection Wick %",
  830. minval = 0.0,
  831. maxval = 100.0,
  832. step = 1.0,
  833. group = groupExecution
  834. )
  835.  
  836. ltfRangeColor = input.color(color.rgb(35, 125, 225), "Unlocked LTF Range Color", group = groupExecution)
  837. ltfManipulationColor = input.color(color.rgb(255, 195, 0), "Unlocked LTF Manipulation Color", group = groupExecution)
  838.  
  839. //======================================================================
  840. // 6. HELPERS — AUTO MARKET TIME PROTOCOL
  841. //======================================================================
  842. f_hourDistance(int a, int b) =>
  843. int directDistance = math.abs(a - b)
  844. math.min(directDistance, 24 - directDistance)
  845.  
  846. f_hourMatches(int candleHour, int modelHour) =>
  847. f_hourDistance(candleHour, modelHour) <= timeMatchToleranceHours
  848.  
  849. f_autoMarketProfile() =>
  850. string tickerUpper = str.upper(syminfo.ticker)
  851. string rootUpper = str.upper(syminfo.root)
  852. bool indexKeyword =
  853. str.contains(tickerUpper, "US100") or
  854. str.contains(tickerUpper, "NAS") or
  855. str.contains(tickerUpper, "SPX") or
  856. str.contains(tickerUpper, "US500") or
  857. str.contains(tickerUpper, "DJI") or
  858. str.contains(tickerUpper, "DAX") or
  859. str.contains(tickerUpper, "FTSE")
  860. bool commodityKeyword =
  861. str.contains(tickerUpper, "XAU") or
  862. str.contains(tickerUpper, "XAG") or
  863. str.contains(rootUpper, "CL") or
  864. str.contains(rootUpper, "MCL") or
  865. str.contains(rootUpper, "GC") or
  866. str.contains(rootUpper, "SI") or
  867. str.contains(tickerUpper, "OIL")
  868. syminfo.type == "forex" ? "Forex" :
  869. syminfo.type == "crypto" ? "Crypto" :
  870. commodityKeyword ? "Commodities" :
  871. syminfo.type == "futures" ? (indexKeyword or str.contains(rootUpper, "ES") or str.contains(rootUpper, "NQ") or str.contains(rootUpper, "YM") or str.contains(rootUpper, "RTY") ? "Indices" : "Futures") :
  872. syminfo.type == "index" or indexKeyword ? "Indices" :
  873. "Manual"
  874.  
  875. f_selectedMarketProfile() =>
  876. marketTimeProfile == "Auto" ? f_autoMarketProfile() : marketTimeProfile
  877.  
  878. f_profileHours(string profile) =>
  879. int h1 =
  880. profile == "Forex" ? forexHour1 :
  881. profile == "Indices" ? indicesHour1 :
  882. profile == "Futures" ? futuresHour1 :
  883. profile == "Crypto" ? cryptoHour1 :
  884. profile == "Commodities" ? commoditiesHour1 : manualHour1
  885. int h2 =
  886. profile == "Forex" ? forexHour2 :
  887. profile == "Indices" ? indicesHour2 :
  888. profile == "Futures" ? futuresHour2 :
  889. profile == "Crypto" ? cryptoHour2 :
  890. profile == "Commodities" ? commoditiesHour2 : manualHour2
  891. int h3 =
  892. profile == "Forex" ? forexHour3 :
  893. profile == "Indices" ? indicesHour3 :
  894. profile == "Futures" ? futuresHour3 :
  895. profile == "Crypto" ? cryptoHour3 :
  896. profile == "Commodities" ? commoditiesHour3 : manualHour3
  897. [h1, h2, h3]
  898.  
  899. isAllowedRangeHour(int candleTime) =>
  900. bool higherCalendarTF = timeframe.isdaily or timeframe.isweekly or timeframe.ismonthly
  901. string activeProfile = f_selectedMarketProfile()
  902. [modelHour1, modelHour2, modelHour3] = f_profileHours(activeProfile)
  903. int candleHour = hour(candleTime, timezoneInput)
  904. not useSelectedHours or higherCalendarTF or
  905. f_hourMatches(candleHour, modelHour1) or
  906. f_hourMatches(candleHour, modelHour2) or
  907. f_hourMatches(candleHour, modelHour3)
  908.  
  909. isNearLevel(float candleHigh, float candleLow, float level, float tolerance) =>
  910. not na(level) and candleHigh >= level - tolerance and candleLow <= level + tolerance
  911.  
  912.  
  913. rangeOverlapsZone(float candleHigh, float candleLow, float zoneHigh, float zoneLow, float tolerance) =>
  914. not na(zoneHigh) and not na(zoneLow) and candleHigh >= zoneLow - tolerance and candleLow <= zoneHigh + tolerance
  915.  
  916. // Directional POI Confluence Engine v2. No zones are drawn.
  917. // Scores are weighted by POI quality and kept directional.
  918. f_detectDirectionalPOIs(float testHigh, float testLow, float tolerance) =>
  919. bool bullFVGTouch = false
  920. bool bearFVGTouch = false
  921. bool bullIFVGTouch = false
  922. bool bearIFVGTouch = false
  923. bool bullOBTouch = false
  924. bool bearOBTouch = false
  925. bool bullBreakerTouch = false
  926. bool bearBreakerTouch = false
  927. bool bullRBTouch = false
  928. bool bearRBTouch = false
  929.  
  930. int maxBack = math.min(poiLookback, bar_index > 10 ? bar_index - 5 : 0)
  931. if maxBack >= 4
  932. for k = 2 to maxBack
  933. bool bullFVG = low[k] > high[k + 2]
  934. bool bearFVG = high[k] < low[k + 2]
  935. float bullFVGHigh = low[k]
  936. float bullFVGLow = high[k + 2]
  937. float bearFVGHigh = low[k + 2]
  938. float bearFVGLow = high[k]
  939. bullFVGTouch := bullFVGTouch or (bullFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance))
  940. bearFVGTouch := bearFVGTouch or (bearFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance))
  941.  
  942. // An invalidated bearish FVG reclaimed upward acts as bullish IFVG.
  943. // An invalidated bullish FVG reclaimed downward acts as bearish IFVG.
  944. bool bullishIFVG = bearFVG and close[k - 1] > bearFVGHigh
  945. bool bearishIFVG = bullFVG and close[k - 1] < bullFVGLow
  946. bullIFVGTouch := bullIFVGTouch or (bullishIFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance))
  947. bearIFVGTouch := bearIFVGTouch or (bearishIFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance))
  948.  
  949. bool bullishDisplacement = close[k] > high[k + 1] and close[k] > open[k]
  950. bool bearishDisplacement = close[k] < low[k + 1] and close[k] < open[k]
  951. bool bullishOB = bullishDisplacement and close[k + 1] < open[k + 1]
  952. bool bearishOB = bearishDisplacement and close[k + 1] > open[k + 1]
  953. bullOBTouch := bullOBTouch or (bullishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  954. bearOBTouch := bearOBTouch or (bearishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  955.  
  956. bool bullishBreaker = close[k + 1] < open[k + 1] and close[k] > high[k + 1]
  957. bool bearishBreaker = close[k + 1] > open[k + 1] and close[k] < low[k + 1]
  958. bullBreakerTouch := bullBreakerTouch or (bullishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  959. bearBreakerTouch := bearBreakerTouch or (bearishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  960.  
  961. float candleRangeK = math.max(high[k] - low[k], syminfo.mintick)
  962. float lowerWickPctK = (math.min(open[k], close[k]) - low[k]) / candleRangeK * 100.0
  963. float upperWickPctK = (high[k] - math.max(open[k], close[k])) / candleRangeK * 100.0
  964. bool bullishRB = lowerWickPctK >= 50.0
  965. bool bearishRB = upperWickPctK >= 50.0
  966. float bullRBHigh = math.min(open[k], close[k])
  967. float bullRBLow = low[k]
  968. float bearRBHigh = high[k]
  969. float bearRBLow = math.max(open[k], close[k])
  970. bullRBTouch := bullRBTouch or (bullishRB and rangeOverlapsZone(testHigh, testLow, bullRBHigh, bullRBLow, tolerance))
  971. bearRBTouch := bearRBTouch or (bearishRB and rangeOverlapsZone(testHigh, testLow, bearRBHigh, bearRBLow, tolerance))
  972.  
  973. int bullTypes =
  974. (useFVGPOI and bullFVGTouch ? 1 : 0) +
  975. (useIFVGPOI and bullIFVGTouch ? 1 : 0) +
  976. (useOrderBlockPOI and bullOBTouch ? 1 : 0) +
  977. (useBreakerPOI and bullBreakerTouch ? 1 : 0) +
  978. (useRejectionBlockPOI and bullRBTouch ? 1 : 0)
  979.  
  980. int bearTypes =
  981. (useFVGPOI and bearFVGTouch ? 1 : 0) +
  982. (useIFVGPOI and bearIFVGTouch ? 1 : 0) +
  983. (useOrderBlockPOI and bearOBTouch ? 1 : 0) +
  984. (useBreakerPOI and bearBreakerTouch ? 1 : 0) +
  985. (useRejectionBlockPOI and bearRBTouch ? 1 : 0)
  986.  
  987. int bullScore =
  988. (useFVGPOI and bullFVGTouch ? 2 : 0) +
  989. (useIFVGPOI and bullIFVGTouch ? 3 : 0) +
  990. (useOrderBlockPOI and bullOBTouch ? 2 : 0) +
  991. (useBreakerPOI and bullBreakerTouch ? 3 : 0) +
  992. (useRejectionBlockPOI and bullRBTouch ? 3 : 0)
  993.  
  994. int bearScore =
  995. (useFVGPOI and bearFVGTouch ? 2 : 0) +
  996. (useIFVGPOI and bearIFVGTouch ? 3 : 0) +
  997. (useOrderBlockPOI and bearOBTouch ? 2 : 0) +
  998. (useBreakerPOI and bearBreakerTouch ? 3 : 0) +
  999. (useRejectionBlockPOI and bearRBTouch ? 3 : 0)
  1000.  
  1001. [bullTypes, bearTypes, bullScore, bearScore]
  1002.  
  1003. //======================================================================
  1004. // 6A. DEDICATED ICT KEY LEVEL TYPE ENGINE
  1005. // Runs in the selected source-timeframe context.
  1006. // Type codes: 0=None, 1=FVG, 2=IFVG, 3=Order Block,
  1007. // 4=Breaker, 5=Rejection Block.
  1008. //======================================================================
  1009. f_keyLevelTypeForRange(float testHigh, float testLow, float tolerance) =>
  1010. int bullishType = 0
  1011. int bearishType = 0
  1012. int bullishWeight = 0
  1013. int bearishWeight = 0
  1014.  
  1015. int maxBack = math.min(keyLevelLookback, bar_index > 10 ? bar_index - 5 : 0)
  1016.  
  1017. if maxBack >= 4
  1018. for k = 2 to maxBack
  1019. bool bullFVG = low[k] > high[k + 2]
  1020. bool bearFVG = high[k] < low[k + 2]
  1021.  
  1022. float bullFVGHigh = low[k]
  1023. float bullFVGLow = high[k + 2]
  1024. float bearFVGHigh = low[k + 2]
  1025. float bearFVGLow = high[k]
  1026.  
  1027. bool bullFVGTouch = bullFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance)
  1028. bool bearFVGTouch = bearFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance)
  1029.  
  1030. bool bullishIFVG = bearFVG and close[k - 1] > bearFVGHigh
  1031. bool bearishIFVG = bullFVG and close[k - 1] < bullFVGLow
  1032.  
  1033. bool bullIFVGTouch = bullishIFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance)
  1034. bool bearIFVGTouch = bearishIFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance)
  1035.  
  1036. bool bullishDisplacement = close[k] > high[k + 1] and close[k] > open[k]
  1037. bool bearishDisplacement = close[k] < low[k + 1] and close[k] < open[k]
  1038. bool bullishOB = bullishDisplacement and close[k + 1] < open[k + 1]
  1039. bool bearishOB = bearishDisplacement and close[k + 1] > open[k + 1]
  1040.  
  1041. bool bullOBTouch = bullishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1042. bool bearOBTouch = bearishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1043.  
  1044. bool bullishBreaker = close[k + 1] < open[k + 1] and close[k] > high[k + 1]
  1045. bool bearishBreaker = close[k + 1] > open[k + 1] and close[k] < low[k + 1]
  1046.  
  1047. bool bullBreakerTouch = bullishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1048. bool bearBreakerTouch = bearishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1049.  
  1050. float candleRangeK = math.max(high[k] - low[k], syminfo.mintick)
  1051. float lowerWickPctK = (math.min(open[k], close[k]) - low[k]) / candleRangeK * 100.0
  1052. float upperWickPctK = (high[k] - math.max(open[k], close[k])) / candleRangeK * 100.0
  1053.  
  1054. bool bullishRB = lowerWickPctK >= 50.0
  1055. bool bearishRB = upperWickPctK >= 50.0
  1056.  
  1057. float bullRBHigh = math.min(open[k], close[k])
  1058. float bullRBLow = low[k]
  1059. float bearRBHigh = high[k]
  1060. float bearRBLow = math.max(open[k], close[k])
  1061.  
  1062. bool bullRBTouch = bullishRB and rangeOverlapsZone(testHigh, testLow, bullRBHigh, bullRBLow, tolerance)
  1063. bool bearRBTouch = bearishRB and rangeOverlapsZone(testHigh, testLow, bearRBHigh, bearRBLow, tolerance)
  1064.  
  1065. if bullFVGTouch and bullishWeight < 2
  1066. bullishType := 1
  1067. bullishWeight := 2
  1068. if bearFVGTouch and bearishWeight < 2
  1069. bearishType := 1
  1070. bearishWeight := 2
  1071.  
  1072. if bullOBTouch and bullishWeight < 2
  1073. bullishType := 3
  1074. bullishWeight := 2
  1075. if bearOBTouch and bearishWeight < 2
  1076. bearishType := 3
  1077. bearishWeight := 2
  1078.  
  1079. if bullIFVGTouch and bullishWeight < 3
  1080. bullishType := 2
  1081. bullishWeight := 3
  1082. if bearIFVGTouch and bearishWeight < 3
  1083. bearishType := 2
  1084. bearishWeight := 3
  1085.  
  1086. if bullBreakerTouch and bullishWeight < 3
  1087. bullishType := 4
  1088. bullishWeight := 3
  1089. if bearBreakerTouch and bearishWeight < 3
  1090. bearishType := 4
  1091. bearishWeight := 3
  1092.  
  1093. if bullRBTouch and bullishWeight < 3
  1094. bullishType := 5
  1095. bullishWeight := 3
  1096. if bearRBTouch and bearishWeight < 3
  1097. bearishType := 5
  1098. bearishWeight := 3
  1099.  
  1100. [bullishType, bearishType, bullishWeight, bearishWeight]
  1101.  
  1102. f_sourceTFKeyLevelState() =>
  1103. float sourceRangeHigh = high[1]
  1104. float sourceRangeLow = low[1]
  1105. float sourceATR = ta.atr(14)
  1106. float sourceTolerance = sourceATR[1] * keyLevelTypeToleranceATR
  1107. [bullType, bearType, bullWeight, bearWeight] = f_keyLevelTypeForRange(sourceRangeHigh, sourceRangeLow, sourceTolerance)
  1108.  
  1109. bool sourceSweptHigh = high > sourceRangeHigh
  1110. bool sourceSweptLow = low < sourceRangeLow
  1111. bool sourceSingleSweep = sourceSweptHigh != sourceSweptLow
  1112. bool sourceClosedInside = close < sourceRangeHigh and close > sourceRangeLow
  1113. bool sourceBase =
  1114. barstate.isconfirmed and
  1115. sourceSingleSweep and
  1116. (not rejectDoubleSweep or not (sourceSweptHigh and sourceSweptLow)) and
  1117. (not requireCloseInside or sourceClosedInside)
  1118.  
  1119. int sourceDirection =
  1120. sourceBase and sourceSweptLow and not sourceSweptHigh ? 1 :
  1121. sourceBase and sourceSweptHigh and not sourceSweptLow ? -1 : 0
  1122.  
  1123. int alignedType =
  1124. sourceDirection == 1 ? bullType :
  1125. sourceDirection == -1 ? bearType : 0
  1126.  
  1127. int opposingType =
  1128. sourceDirection == 1 ? bearType :
  1129. sourceDirection == -1 ? bullType : 0
  1130.  
  1131. int alignedWeight =
  1132. sourceDirection == 1 ? bullWeight :
  1133. sourceDirection == -1 ? bearWeight : 0
  1134.  
  1135. [sourceDirection, alignedType, opposingType, alignedWeight]
  1136.  
  1137. [sourceKeyDirection, sourceKeyLevelType, sourceOpposingKeyLevelType, sourceKeyLevelWeight] =
  1138. request.security(
  1139. syminfo.tickerid,
  1140. selectedHTF,
  1141. f_sourceTFKeyLevelState(),
  1142. gaps = barmerge.gaps_off,
  1143. lookahead = barmerge.lookahead_off
  1144. )
  1145.  
  1146. //======================================================================
  1147. // 7. MULTI-ASSET SMT MATRIX
  1148. // CME, Forex, Crypto, Metals and Energy.
  1149. // v16.7 uses verified exchange prefixes and spot crypto comparison feeds.
  1150. // Relation code: 1 = direct correlation, -1 = inverse correlation.
  1151. //======================================================================
  1152. f_autoSMTSymbol1() =>
  1153. string t = str.upper(syminfo.ticker)
  1154. string r = str.upper(syminfo.root)
  1155.  
  1156. bool es = r == "ES" or str.contains(t, "US500") or str.contains(t, "SPX")
  1157. bool nq = r == "NQ" or str.contains(t, "US100") or str.contains(t, "NAS100")
  1158. bool ym = r == "YM" or str.contains(t, "US30")
  1159. bool rty = r == "RTY"
  1160.  
  1161. bool eurusd = str.contains(t, "EURUSD")
  1162. bool gbpusd = str.contains(t, "GBPUSD")
  1163. bool audusd = str.contains(t, "AUDUSD")
  1164. bool nzdusd = str.contains(t, "NZDUSD")
  1165. bool usdchf = str.contains(t, "USDCHF")
  1166. bool usdcad = str.contains(t, "USDCAD")
  1167. bool usdjpy = str.contains(t, "USDJPY")
  1168. bool eurjpy = str.contains(t, "EURJPY")
  1169. bool gbpjpy = str.contains(t, "GBPJPY")
  1170. bool audjpy = str.contains(t, "AUDJPY")
  1171. bool nzdjpy = str.contains(t, "NZDJPY")
  1172.  
  1173. bool btc = str.contains(t, "BTC")
  1174. bool eth = str.contains(t, "ETH")
  1175. bool sol = str.contains(t, "SOL")
  1176.  
  1177. bool gold = str.contains(t, "XAU") or r == "GC"
  1178. bool silver = str.contains(t, "XAG") or r == "SI"
  1179. bool wti = r == "CL" or str.contains(t, "USOIL") or str.contains(t, "WTI")
  1180. bool brent = r == "BRN" or str.contains(t, "UKOIL") or str.contains(t, "BRENT")
  1181.  
  1182. es ? "CME_MINI:NQ1!" :
  1183. nq ? "CME_MINI:ES1!" :
  1184. ym ? "CME_MINI:ES1!" :
  1185. rty ? "CME_MINI:ES1!" :
  1186. eurusd ? "OANDA:GBPUSD" :
  1187. gbpusd ? "OANDA:EURUSD" :
  1188. audusd ? "OANDA:NZDUSD" :
  1189. nzdusd ? "OANDA:AUDUSD" :
  1190. usdchf ? "TVC:DXY" :
  1191. usdcad ? "TVC:DXY" :
  1192. usdjpy ? "TVC:DXY" :
  1193. eurjpy ? "OANDA:GBPJPY" :
  1194. gbpjpy ? "OANDA:EURJPY" :
  1195. audjpy ? "OANDA:NZDJPY" :
  1196. nzdjpy ? "OANDA:AUDJPY" :
  1197. btc ? "BINANCE:ETHUSDT" :
  1198. eth ? "BINANCE:BTCUSDT" :
  1199. sol ? "BINANCE:BTCUSDT" :
  1200. gold ? "COMEX:SI1!" :
  1201. silver ? "COMEX:GC1!" :
  1202. wti ? "TVC:UKOIL" :
  1203. brent ? "NYMEX:CL1!" :
  1204. manualSMTSymbol1
  1205.  
  1206. f_autoSMTRelation1() =>
  1207. string t = str.upper(syminfo.ticker)
  1208. bool usdchf = str.contains(t, "USDCHF")
  1209. usdchf ? -1 : 1
  1210.  
  1211. f_autoSMTSymbol2() =>
  1212. string t = str.upper(syminfo.ticker)
  1213. string r = str.upper(syminfo.root)
  1214.  
  1215. bool es = r == "ES" or str.contains(t, "US500") or str.contains(t, "SPX")
  1216. bool nq = r == "NQ" or str.contains(t, "US100") or str.contains(t, "NAS100")
  1217. bool ym = r == "YM" or str.contains(t, "US30")
  1218. bool rty = r == "RTY"
  1219.  
  1220. bool eurusd = str.contains(t, "EURUSD")
  1221. bool gbpusd = str.contains(t, "GBPUSD")
  1222. bool audusd = str.contains(t, "AUDUSD")
  1223. bool nzdusd = str.contains(t, "NZDUSD")
  1224. bool usdchf = str.contains(t, "USDCHF")
  1225. bool usdcad = str.contains(t, "USDCAD")
  1226. bool usdjpy = str.contains(t, "USDJPY")
  1227.  
  1228. bool btc = str.contains(t, "BTC")
  1229. bool eth = str.contains(t, "ETH")
  1230. bool sol = str.contains(t, "SOL")
  1231.  
  1232. es ? "CBOT_MINI:YM1!" :
  1233. nq ? "CBOT_MINI:YM1!" :
  1234. ym ? "CME_MINI:NQ1!" :
  1235. rty ? "CME_MINI:NQ1!" :
  1236. eurusd ? "TVC:DXY" :
  1237. gbpusd ? "TVC:DXY" :
  1238. audusd ? "TVC:DXY" :
  1239. nzdusd ? "TVC:DXY" :
  1240. usdchf ? "OANDA:EURUSD" :
  1241. usdcad ? "OANDA:AUDUSD" :
  1242. usdjpy ? "OANDA:EURJPY" :
  1243. btc ? "BINANCE:SOLUSDT" :
  1244. eth ? "BINANCE:SOLUSDT" :
  1245. sol ? "BINANCE:ETHUSDT" :
  1246. manualSMTSymbol2
  1247.  
  1248. f_autoSMTRelation2() =>
  1249. string t = str.upper(syminfo.ticker)
  1250. bool eurusd = str.contains(t, "EURUSD")
  1251. bool gbpusd = str.contains(t, "GBPUSD")
  1252. bool audusd = str.contains(t, "AUDUSD")
  1253. bool nzdusd = str.contains(t, "NZDUSD")
  1254. bool usdchf = str.contains(t, "USDCHF")
  1255. bool usdjpy = str.contains(t, "USDJPY")
  1256.  
  1257. eurusd or gbpusd or audusd or nzdusd or usdchf or usdjpy ? -1 : 1
  1258.  
  1259. string smtSymbol1 = smtMode == "Auto Matrix" ? f_autoSMTSymbol1() : manualSMTSymbol1
  1260. string smtSymbol2 = smtMode == "Auto Matrix" ? f_autoSMTSymbol2() : manualSMTSymbol2
  1261. int smtRelation1 = smtMode == "Auto Matrix" ? f_autoSMTRelation1() : (manualSMTRelation1 == "Direct" ? 1 : -1)
  1262. int smtRelation2 = smtMode == "Auto Matrix" ? f_autoSMTRelation2() : (manualSMTRelation2 == "Direct" ? 1 : -1)
  1263.  
  1264. float smtHigh1 = request.security(smtSymbol1, selectedHTF, high, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1265. float smtLow1 = request.security(smtSymbol1, selectedHTF, low, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1266. float smtATR1 = request.security(smtSymbol1, selectedHTF, ta.atr(14), gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1267.  
  1268. float smtHigh2 = request.security(smtSymbol2, selectedHTF, high, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1269. float smtLow2 = request.security(smtSymbol2, selectedHTF, low, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1270. float smtATR2 = request.security(smtSymbol2, selectedHTF, ta.atr(14), gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1271.  
  1272. float ownPriorHigh = ta.highest(high[1], smtLookback)
  1273. float ownPriorLow = ta.lowest(low[1], smtLookback)
  1274. float ownTolerance = ta.atr(14) * smtToleranceATR
  1275.  
  1276. bool ownHH = high > ownPriorHigh + ownTolerance
  1277. bool ownLL = low < ownPriorLow - ownTolerance
  1278.  
  1279. f_smtState(float comparisonHigh, float comparisonLow, float comparisonATR, int relation) =>
  1280. bool comparisonDataReady =
  1281. not na(comparisonHigh) and
  1282. not na(comparisonLow) and
  1283. not na(comparisonATR)
  1284.  
  1285. float comparisonPriorHigh = ta.highest(comparisonHigh[1], smtLookback)
  1286. float comparisonPriorLow = ta.lowest(comparisonLow[1], smtLookback)
  1287. float comparisonTolerance = comparisonATR * smtToleranceATR
  1288.  
  1289. bool comparisonHistoryReady =
  1290. comparisonDataReady and
  1291. not na(comparisonPriorHigh) and
  1292. not na(comparisonPriorLow)
  1293.  
  1294. bool comparisonHH =
  1295. comparisonHistoryReady and
  1296. comparisonHigh > comparisonPriorHigh + comparisonTolerance
  1297.  
  1298. bool comparisonLL =
  1299. comparisonHistoryReady and
  1300. comparisonLow < comparisonPriorLow - comparisonTolerance
  1301.  
  1302. bool bullishDirect = comparisonHistoryReady and ((ownLL and not comparisonLL) or (comparisonLL and not ownLL))
  1303. bool bearishDirect = comparisonHistoryReady and ((ownHH and not comparisonHH) or (comparisonHH and not ownHH))
  1304.  
  1305. bool bullishInverse = comparisonHistoryReady and ((ownLL and not comparisonHH) or (comparisonHH and not ownLL))
  1306. bool bearishInverse = comparisonHistoryReady and ((ownHH and not comparisonLL) or (comparisonLL and not ownHH))
  1307.  
  1308. int state =
  1309. not comparisonHistoryReady ? 0 :
  1310. relation == 1 ?
  1311. (bullishDirect ? 1 : bearishDirect ? -1 : 0) :
  1312. (bullishInverse ? 1 : bearishInverse ? -1 : 0)
  1313. state
  1314.  
  1315. int smtState1 = f_smtState(smtHigh1, smtLow1, smtATR1, smtRelation1)
  1316. int smtState2 = useSecondSMTMarket ? f_smtState(smtHigh2, smtLow2, smtATR2, smtRelation2) : 0
  1317.  
  1318. int bullishSMTCount = (smtState1 == 1 ? 1 : 0) + (smtState2 == 1 ? 1 : 0)
  1319. int bearishSMTCount = (smtState1 == -1 ? 1 : 0) + (smtState2 == -1 ? 1 : 0)
  1320.  
  1321. bool bullishSMT = bullishSMTCount >= minimumSMTConfirmations
  1322. bool bearishSMT = bearishSMTCount >= minimumSMTConfirmations
  1323.  
  1324. //======================================================================
  1325. // 8. CRT HIERARCHY ALIGNMENT
  1326. //======================================================================
  1327. f_parentTimeframe(string childTF) =>
  1328. childTF == "W" ? "M" :
  1329. childTF == "D" ? "W" :
  1330. childTF == "240" or childTF == "180" or childTF == "120" ? "D" :
  1331. childTF == "60" ? "240" :
  1332. childTF == "30" ? "60" :
  1333. ""
  1334.  
  1335. f_activeStructuralCRTDirection() =>
  1336. float parentRangeHigh = high[1]
  1337. float parentRangeLow = low[1]
  1338. bool parentSweptHigh = high > parentRangeHigh
  1339. bool parentSweptLow = low < parentRangeLow
  1340. bool parentSingleSweep = parentSweptHigh != parentSweptLow
  1341. bool parentClosedInside = close < parentRangeHigh and close > parentRangeLow
  1342.  
  1343. bool parentBase =
  1344. barstate.isconfirmed and
  1345. parentSingleSweep and
  1346. (not rejectDoubleSweep or not (parentSweptHigh and parentSweptLow)) and
  1347. (not requireCloseInside or parentClosedInside)
  1348.  
  1349. int parentEventDirection =
  1350. parentBase and parentSweptLow and not parentSweptHigh ? 1 :
  1351. parentBase and parentSweptHigh and not parentSweptLow ? -1 : 0
  1352.  
  1353. bool parentEvent = parentEventDirection != 0
  1354. int latestParentDirection = nz(ta.valuewhen(parentEvent, parentEventDirection, 0), 0)
  1355. float latestParentRangeHigh = ta.valuewhen(parentEvent, parentRangeHigh, 0)
  1356. float latestParentRangeLow = ta.valuewhen(parentEvent, parentRangeLow, 0)
  1357. int parentBarsSinceEvent = ta.barssince(parentEvent)
  1358.  
  1359. bool hasParentCRT =
  1360. latestParentDirection != 0 and
  1361. not na(latestParentRangeHigh) and
  1362. not na(latestParentRangeLow) and
  1363. not na(parentBarsSinceEvent)
  1364.  
  1365. bool parentTargetReached =
  1366. hasParentCRT and parentBarsSinceEvent > 0 and (
  1367. latestParentDirection == 1 ?
  1368. (targetRequiresClose ? close >= latestParentRangeHigh : high >= latestParentRangeHigh) :
  1369. (targetRequiresClose ? close <= latestParentRangeLow : low <= latestParentRangeLow)
  1370. )
  1371.  
  1372. bool parentInvalidated =
  1373. hasParentCRT and parentBarsSinceEvent > 0 and (
  1374. latestParentDirection == 1 ?
  1375. (invalidationRequiresClose ? close < latestParentRangeLow : low < latestParentRangeLow) :
  1376. (invalidationRequiresClose ? close > latestParentRangeHigh : high > latestParentRangeHigh)
  1377. )
  1378.  
  1379. bool parentExpired = hasParentCRT and parentBarsSinceEvent > lifecycleExpiryBars
  1380. bool parentActive = hasParentCRT and not parentTargetReached and not parentInvalidated and not parentExpired
  1381.  
  1382. parentActive ? latestParentDirection : 0
  1383.  
  1384. f_activeStructuralCRTContext() =>
  1385. float pRangeHigh = high[1]
  1386. float pRangeLow = low[1]
  1387. bool pSweptHigh = high > pRangeHigh
  1388. bool pSweptLow = low < pRangeLow
  1389. bool pSingleSweep = pSweptHigh != pSweptLow
  1390. bool pClosedInside = close < pRangeHigh and close > pRangeLow
  1391.  
  1392. bool pBase =
  1393. barstate.isconfirmed and
  1394. pSingleSweep and
  1395. (not rejectDoubleSweep or not (pSweptHigh and pSweptLow)) and
  1396. (not requireCloseInside or pClosedInside)
  1397.  
  1398. int pEventDirection =
  1399. pBase and pSweptLow and not pSweptHigh ? 1 :
  1400. pBase and pSweptHigh and not pSweptLow ? -1 : 0
  1401.  
  1402. bool pEvent = pEventDirection != 0
  1403. int pLatestDirection = nz(ta.valuewhen(pEvent, pEventDirection, 0), 0)
  1404. float pLatestHigh = ta.valuewhen(pEvent, pRangeHigh, 0)
  1405. float pLatestLow = ta.valuewhen(pEvent, pRangeLow, 0)
  1406. int pBarsSince = ta.barssince(pEvent)
  1407.  
  1408. bool pHasCRT =
  1409. pLatestDirection != 0 and
  1410. not na(pLatestHigh) and
  1411. not na(pLatestLow) and
  1412. not na(pBarsSince)
  1413.  
  1414. bool pTargetReached =
  1415. pHasCRT and pBarsSince > 0 and (
  1416. pLatestDirection == 1 ?
  1417. (targetRequiresClose ? close >= pLatestHigh : high >= pLatestHigh) :
  1418. (targetRequiresClose ? close <= pLatestLow : low <= pLatestLow)
  1419. )
  1420.  
  1421. bool pInvalidated =
  1422. pHasCRT and pBarsSince > 0 and (
  1423. pLatestDirection == 1 ?
  1424. (invalidationRequiresClose ? close < pLatestLow : low < pLatestLow) :
  1425. (invalidationRequiresClose ? close > pLatestHigh : high > pLatestHigh)
  1426. )
  1427.  
  1428. bool pExpired = pHasCRT and pBarsSince > lifecycleExpiryBars
  1429. bool pActive = pHasCRT and not pTargetReached and not pInvalidated and not pExpired
  1430.  
  1431. [pActive ? pLatestDirection : 0, pActive ? pLatestHigh : na, pActive ? pLatestLow : na]
  1432.  
  1433. string parentHierarchyTF = f_parentTimeframe(selectedHTF)
  1434.  
  1435. int parentCRTDirection =
  1436. parentHierarchyTF == "" ? 0 :
  1437. request.security(
  1438. syminfo.tickerid,
  1439. parentHierarchyTF,
  1440. f_activeStructuralCRTDirection(),
  1441. gaps = barmerge.gaps_off,
  1442. lookahead = barmerge.lookahead_off
  1443. )
  1444.  
  1445. string parentContextRequestTF = parentHierarchyTF == "" ? selectedHTF : parentHierarchyTF
  1446.  
  1447. [parentContextDirectionRaw, parentContextHighRaw, parentContextLowRaw] =
  1448. request.security(
  1449. syminfo.tickerid,
  1450. parentContextRequestTF,
  1451. f_activeStructuralCRTContext(),
  1452. gaps = barmerge.gaps_off,
  1453. lookahead = barmerge.lookahead_off
  1454. )
  1455.  
  1456. int parentContextDirection = parentHierarchyTF == "" ? 0 : parentContextDirectionRaw
  1457. float parentContextHigh = parentHierarchyTF == "" ? na : parentContextHighRaw
  1458. float parentContextLow = parentHierarchyTF == "" ? na : parentContextLowRaw
  1459.  
  1460. //======================================================================
  1461. // 9. HIGHER-TIMEFRAME KEY LEVELS
  1462. // Previous completed day/week/month levels; non-repainting.
  1463. //======================================================================
  1464. float previousDayHigh = request.security(syminfo.tickerid, "D", high[1], lookahead = barmerge.lookahead_on)
  1465. float previousDayLow = request.security(syminfo.tickerid, "D", low[1], lookahead = barmerge.lookahead_on)
  1466. float previousWeekHigh = request.security(syminfo.tickerid, "W", high[1], lookahead = barmerge.lookahead_on)
  1467. float previousWeekLow = request.security(syminfo.tickerid, "W", low[1], lookahead = barmerge.lookahead_on)
  1468. float previousMonthHigh = request.security(syminfo.tickerid, "M", high[1], lookahead = barmerge.lookahead_on)
  1469. float previousMonthLow = request.security(syminfo.tickerid, "M", low[1], lookahead = barmerge.lookahead_on)
  1470.  
  1471. //======================================================================
  1472. // 8. RANGE + MANIPULATION STRUCTURE
  1473. // Candle [1] = potential Range candle
  1474. // Candle [0] = potential Manipulation candle
  1475. //======================================================================
  1476. float rangeHigh = high[1]
  1477. float rangeLow = low[1]
  1478. float rangeOpen = open[1]
  1479. float rangeClose = close[1]
  1480. float rangeSize = math.max(rangeHigh - rangeLow, syminfo.mintick)
  1481. float rangeMidpoint = (rangeHigh + rangeLow) * 0.5
  1482. float rangeBodyPercent = math.abs(rangeClose - rangeOpen) / rangeSize * 100.0
  1483.  
  1484. bool sweptHigh = high > rangeHigh
  1485. bool sweptLow = low < rangeLow
  1486. bool sweptBoth = sweptHigh and sweptLow
  1487. bool singleSweep = sweptHigh != sweptLow
  1488. bool closedInside = close < rangeHigh and close > rangeLow
  1489.  
  1490. bool bullishDirectionOK = not requireDirectionalClose or close > open
  1491. bool bearishDirectionOK = not requireDirectionalClose or close < open
  1492.  
  1493. bool baseRules =
  1494. barstate.isconfirmed and
  1495. singleSweep and
  1496. (not rejectDoubleSweep or not sweptBoth) and
  1497. (not requireCloseInside or closedInside)
  1498.  
  1499. bool bullishCandidate = baseRules and sweptLow and not sweptHigh and bullishDirectionOK
  1500. bool bearishCandidate = baseRules and sweptHigh and not sweptLow and bearishDirectionOK
  1501.  
  1502. //======================================================================
  1503. // 8A. PROTOCOL 11 — CRT SEQUENCE / NESTED ACTIVE PARENT RANGE
  1504. // Informational bonus only. Stable v16.9 qualification remains unchanged.
  1505. //======================================================================
  1506. bool parentContextActive =
  1507. useNestedCRTContext and
  1508. parentContextDirection != 0 and
  1509. not na(parentContextHigh) and
  1510. not na(parentContextLow)
  1511.  
  1512. bool localRangeContainedInParent =
  1513. parentContextActive and
  1514. rangeHigh <= parentContextHigh and
  1515. rangeLow >= parentContextLow
  1516.  
  1517. bool localRangeOverlapsParent =
  1518. parentContextActive and
  1519. rangeHigh >= parentContextLow and
  1520. rangeLow <= parentContextHigh
  1521.  
  1522. bool nestedInsideParent =
  1523. requireFullParentContainment ?
  1524. localRangeContainedInParent :
  1525. localRangeOverlapsParent
  1526.  
  1527. bool nestedDirectionAligned =
  1528. parentContextActive and (
  1529. (bullishCandidate and parentContextDirection == 1) or
  1530. (bearishCandidate and parentContextDirection == -1)
  1531. )
  1532.  
  1533. float parentContextMidpoint =
  1534. parentContextActive ? (parentContextHigh + parentContextLow) * 0.5 : na
  1535.  
  1536. bool nestedLocationAligned =
  1537. parentContextActive and
  1538. useParentPremiumDiscount and (
  1539. (bullishCandidate and rangeMidpoint <= parentContextMidpoint) or
  1540. (bearishCandidate and rangeMidpoint >= parentContextMidpoint)
  1541. )
  1542.  
  1543. int nestedContextScore =
  1544. (nestedInsideParent ? 1 : 0) +
  1545. (nestedDirectionAligned ? 1 : 0) +
  1546. (nestedLocationAligned ? 1 : 0)
  1547.  
  1548. bool meaningfulNestedContext =
  1549. useNestedCRTContext and
  1550. nestedContextScore >= minimumNestedContextScore
  1551.  
  1552. //======================================================================
  1553. // 9. SILENT PROTOCOL TESTS
  1554. //======================================================================
  1555. float atr = ta.atr(14)
  1556.  
  1557. //======================================================================
  1558. // 9A. PROTOCOL 10 — MEANINGFUL LIQUIDITY PURGE BONUS CONTEXT
  1559. // This module is informational only and cannot reject a v16.7 CRT.
  1560. //======================================================================
  1561. float liquidityTolerance = atr[1] * liquidityToleranceATR
  1562. float priorSwingHigh = ta.highest(high[2], liquiditySwingLookback)
  1563. float priorSwingLow = ta.lowest(low[2], liquiditySwingLookback)
  1564.  
  1565. bool purgedPDH = bearishCandidate and not na(previousDayHigh[1]) and high > previousDayHigh[1] + liquidityTolerance
  1566. bool purgedPDL = bullishCandidate and not na(previousDayLow[1]) and low < previousDayLow[1] - liquidityTolerance
  1567. bool purgedPWH = bearishCandidate and not na(previousWeekHigh[1]) and high > previousWeekHigh[1] + liquidityTolerance
  1568. bool purgedPWL = bullishCandidate and not na(previousWeekLow[1]) and low < previousWeekLow[1] - liquidityTolerance
  1569. bool purgedPMH = bearishCandidate and not na(previousMonthHigh[1]) and high > previousMonthHigh[1] + liquidityTolerance
  1570. bool purgedPML = bullishCandidate and not na(previousMonthLow[1]) and low < previousMonthLow[1] - liquidityTolerance
  1571. bool purgedSwingHigh = bearishCandidate and not na(priorSwingHigh) and high > priorSwingHigh + liquidityTolerance
  1572. bool purgedSwingLow = bullishCandidate and not na(priorSwingLow) and low < priorSwingLow - liquidityTolerance
  1573.  
  1574. int liquidityPurgeScore =
  1575. (purgedPDH or purgedPDL ? 1 : 0) +
  1576. (purgedPWH or purgedPWL ? 2 : 0) +
  1577. (purgedPMH or purgedPML ? 3 : 0) +
  1578. (purgedSwingHigh or purgedSwingLow ? 1 : 0)
  1579.  
  1580. bool meaningfulLiquidityPurge =
  1581. useLiquidityPurgeContext and
  1582. liquidityPurgeScore >= minimumLiquidityPurgeScore
  1583.  
  1584. float keyTolerance = atr[1] * keyLevelToleranceATR
  1585.  
  1586. bool timeProtocol = isAllowedRangeHour(time[1])
  1587.  
  1588. bool keyLevelProtocol =
  1589. isNearLevel(rangeHigh, rangeLow, previousDayHigh[1], keyTolerance) or
  1590. isNearLevel(rangeHigh, rangeLow, previousDayLow[1], keyTolerance) or
  1591. isNearLevel(rangeHigh, rangeLow, previousWeekHigh[1], keyTolerance) or
  1592. isNearLevel(rangeHigh, rangeLow, previousWeekLow[1], keyTolerance) or
  1593. isNearLevel(rangeHigh, rangeLow, previousMonthHigh[1], keyTolerance) or
  1594. isNearLevel(rangeHigh, rangeLow, previousMonthLow[1], keyTolerance)
  1595.  
  1596. float manipulationRange = math.max(high - low, syminfo.mintick)
  1597. float lowerRejectionPercent = (math.min(open, close) - low) / manipulationRange * 100.0
  1598. float upperRejectionPercent = (high - math.max(open, close)) / manipulationRange * 100.0
  1599.  
  1600. bool rejectionProtocol =
  1601. (bullishCandidate and lowerRejectionPercent >= minimumRejectionPercent) or
  1602. (bearishCandidate and upperRejectionPercent >= minimumRejectionPercent)
  1603.  
  1604. bool midpointProtocol =
  1605. (bullishCandidate and close > rangeMidpoint) or
  1606. (bearishCandidate and close < rangeMidpoint)
  1607.  
  1608. float rangeATRRatio = atr[1] > 0.0 ? rangeSize / atr[1] : 0.0
  1609. bool rangeSizeProtocol = rangeATRRatio >= minimumRangeATR and rangeATRRatio <= maximumRangeATR
  1610.  
  1611. bool bodyProtocol =
  1612. rangeBodyPercent >= minimumRangeBodyPercent and
  1613. rangeBodyPercent <= maximumRangeBodyPercent
  1614.  
  1615. float poiTolerance = atr[1] * poiToleranceATR
  1616. [bullPOITypes, bearPOITypes, bullPOIScore, bearPOIScore] = f_detectDirectionalPOIs(rangeHigh, rangeLow, poiTolerance)
  1617. bool bullishPOIAligned = bullPOITypes >= minimumPOITypes and bullPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or bullPOIScore >= bearPOIScore)
  1618. bool bearishPOIAligned = bearPOITypes >= minimumPOITypes and bearPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or bearPOIScore >= bullPOIScore)
  1619. bool poiProtocol = (bullishCandidate and bullishPOIAligned) or (bearishCandidate and bearishPOIAligned)
  1620. int poiTypeScore = bullishCandidate ? bullPOITypes : bearishCandidate ? bearPOITypes : 0
  1621. int directionalPOIScore = bullishCandidate ? bullPOIScore : bearishCandidate ? bearPOIScore : 0
  1622.  
  1623. bool hierarchyAligned =
  1624. (bullishCandidate and parentCRTDirection == 1) or
  1625. (bearishCandidate and parentCRTDirection == -1)
  1626.  
  1627. bool hierarchyNeutral = parentCRTDirection == 0
  1628.  
  1629. bool hierarchyOpposing =
  1630. (bullishCandidate and parentCRTDirection == -1) or
  1631. (bearishCandidate and parentCRTDirection == 1)
  1632.  
  1633. bool hierarchyProtocol = hierarchyAligned or (hierarchyNeutral and neutralHierarchyPass)
  1634.  
  1635. bool hierarchyHardPass =
  1636. not useHierarchyProtocol or
  1637. not rejectOpposingHierarchy or
  1638. not hierarchyOpposing
  1639.  
  1640. int alignedSMTCount =
  1641. bullishCandidate ? bullishSMTCount :
  1642. bearishCandidate ? bearishSMTCount : 0
  1643.  
  1644. int opposingSMTCount =
  1645. bullishCandidate ? bearishSMTCount :
  1646. bearishCandidate ? bullishSMTCount : 0
  1647.  
  1648. bool smtAligned = alignedSMTCount >= minimumSMTConfirmations
  1649. bool smtOpposing = opposingSMTCount > alignedSMTCount and opposingSMTCount > 0
  1650. bool smtNeutral = alignedSMTCount == 0 and opposingSMTCount == 0
  1651.  
  1652. bool smtProtocol =
  1653. smtAligned or
  1654. (smtNeutral and allowNeutralSMT)
  1655.  
  1656. bool smtHardPass =
  1657. not useSMTProtocol or
  1658. not rejectOpposingSMT or
  1659. not smtOpposing
  1660.  
  1661. int enabledProtocols =
  1662. (useTimeProtocol ? 1 : 0) +
  1663. (useKeyLevelProtocol ? 1 : 0) +
  1664. (useRejectionProtocol ? 1 : 0) +
  1665. (useMidpointProtocol ? 1 : 0) +
  1666. (useRangeSizeProtocol ? 1 : 0) +
  1667. (useBodyProtocol ? 1 : 0) +
  1668. (usePOIProtocol ? 1 : 0) +
  1669. (useHierarchyProtocol ? 1 : 0) +
  1670. (useSMTProtocol ? 1 : 0)
  1671.  
  1672. int protocolScore =
  1673. (useTimeProtocol and timeProtocol ? 1 : 0) +
  1674. (useKeyLevelProtocol and keyLevelProtocol ? 1 : 0) +
  1675. (useRejectionProtocol and rejectionProtocol ? 1 : 0) +
  1676. (useMidpointProtocol and midpointProtocol ? 1 : 0) +
  1677. (useRangeSizeProtocol and rangeSizeProtocol ? 1 : 0) +
  1678. (useBodyProtocol and bodyProtocol ? 1 : 0) +
  1679. (usePOIProtocol and poiProtocol ? 1 : 0) +
  1680. (useHierarchyProtocol and hierarchyProtocol ? 1 : 0) +
  1681. (useSMTProtocol and smtProtocol ? 1 : 0)
  1682.  
  1683. // Protocol 10 is a bonus only and is deliberately excluded from
  1684. // enabledProtocols, protocolScore, effectiveMinimum and protocolQualified.
  1685. int protocolScoreWithLiquidityBonus =
  1686. protocolScore + (meaningfulLiquidityPurge ? 1 : 0)
  1687.  
  1688. int protocolScoreWithContextBonuses =
  1689. protocolScore +
  1690. (meaningfulLiquidityPurge ? 1 : 0) +
  1691. (meaningfulNestedContext ? 1 : 0)
  1692.  
  1693. int effectiveMinimum = math.min(minimumProtocols, math.max(enabledProtocols, 1))
  1694. bool protocolQualified = protocolScore >= effectiveMinimum and hierarchyHardPass and smtHardPass
  1695.  
  1696. bool bullishManipulation = bullishCandidate and protocolQualified
  1697. bool bearishManipulation = bearishCandidate and protocolQualified
  1698. bool qualifiedCRT = bullishManipulation or bearishManipulation
  1699. bool rawQualifiedCRT = bullishCandidate or bearishCandidate
  1700. bool visibleCRT = showRawCRTForTesting ? rawQualifiedCRT : qualifiedCRT
  1701.  
  1702. int currentQualifiedCRTDirection =
  1703. bullishManipulation ? 1 :
  1704. bearishManipulation ? -1 : 0
  1705.  
  1706. bool dedicatedKeyLevelAligned =
  1707. useDedicatedKeyLevelEngine and
  1708. qualifiedCRT and
  1709. sourceKeyLevelType != 0 and
  1710. sourceKeyDirection == currentQualifiedCRTDirection
  1711.  
  1712. int currentKeyLevelType =
  1713. dedicatedKeyLevelAligned ? sourceKeyLevelType : 0
  1714.  
  1715. int latestKeyLevelType =
  1716. nz(ta.valuewhen(qualifiedCRT, currentKeyLevelType, 0), 0)
  1717.  
  1718. int latestKeyLevelDirection =
  1719. nz(ta.valuewhen(qualifiedCRT, currentQualifiedCRTDirection, 0), 0)
  1720.  
  1721. int latestKeyLevelWeight =
  1722. nz(ta.valuewhen(qualifiedCRT, dedicatedKeyLevelAligned ? sourceKeyLevelWeight : 0, 0), 0)
  1723.  
  1724.  
  1725.  
  1726. //======================================================================
  1727. // 11A. PROTOCOL 12 — POST-MANIPULATION DISPLACEMENT / DELIVERY
  1728. // Delayed bonus context only. A CRT is first confirmed normally; the next
  1729. // configured bars are then evaluated for directional delivery.
  1730. //======================================================================
  1731. int barsSinceQualifiedForDelivery = ta.barssince(qualifiedCRT)
  1732. bool deliveryWindowActive =
  1733. useDeliveryContext and
  1734. not na(barsSinceQualifiedForDelivery) and
  1735. barsSinceQualifiedForDelivery >= 1 and
  1736. barsSinceQualifiedForDelivery <= deliveryWindowBars
  1737.  
  1738. int deliveryCRTDirection = nz(ta.valuewhen(qualifiedCRT, bullishManipulation ? 1 : -1, 0), 0)
  1739. float deliveryRangeHigh = ta.valuewhen(qualifiedCRT, rangeHigh, 0)
  1740. float deliveryRangeLow = ta.valuewhen(qualifiedCRT, rangeLow, 0)
  1741. float deliveryRangeMid = not na(deliveryRangeHigh) and not na(deliveryRangeLow) ? (deliveryRangeHigh + deliveryRangeLow) * 0.5 : na
  1742. float deliveryATR = ta.atr(14)
  1743. float deliveryBody = math.abs(close - open)
  1744.  
  1745. bool directionalDelivery =
  1746. deliveryWindowActive and (
  1747. (deliveryCRTDirection == 1 and close > open) or
  1748. (deliveryCRTDirection == -1 and close < open)
  1749. )
  1750.  
  1751. bool strongDeliveryBody =
  1752. deliveryWindowActive and
  1753. deliveryATR > 0 and
  1754. deliveryBody >= deliveryATR * minimumDeliveryBodyATR
  1755.  
  1756. bool deliveredThroughRangeMid =
  1757. deliveryWindowActive and
  1758. not na(deliveryRangeMid) and (
  1759. (deliveryCRTDirection == 1 and close > deliveryRangeMid) or
  1760. (deliveryCRTDirection == -1 and close < deliveryRangeMid)
  1761. )
  1762.  
  1763. bool bullishDeliveryFVG =
  1764. deliveryWindowActive and
  1765. deliveryCRTDirection == 1 and
  1766. bar_index >= 2 and
  1767. low > high[2]
  1768.  
  1769. bool bearishDeliveryFVG =
  1770. deliveryWindowActive and
  1771. deliveryCRTDirection == -1 and
  1772. bar_index >= 2 and
  1773. high < low[2]
  1774.  
  1775. bool deliveryFVGCreated = bullishDeliveryFVG or bearishDeliveryFVG
  1776.  
  1777. int currentDeliveryScore =
  1778. (directionalDelivery ? 1 : 0) +
  1779. (strongDeliveryBody ? 1 : 0) +
  1780. (deliveredThroughRangeMid ? 1 : 0) +
  1781. (deliveryFVGCreated ? 1 : 0)
  1782.  
  1783. var int deliveryContextScore = 0
  1784.  
  1785. if qualifiedCRT
  1786. deliveryContextScore := 0
  1787. else if deliveryWindowActive
  1788. deliveryContextScore := math.max(deliveryContextScore, currentDeliveryScore)
  1789. else
  1790. deliveryContextScore := 0
  1791.  
  1792. bool priorDeliveryFVG =
  1793. bar_index > 0 and deliveryFVGCreated[1]
  1794.  
  1795. bool meaningfulDeliveryContext =
  1796. useDeliveryContext and
  1797. deliveryWindowActive and
  1798. deliveryContextScore >= minimumDeliveryScore and
  1799. (not requireDeliveryFVG or deliveryFVGCreated or priorDeliveryFVG)
  1800.  
  1801. //======================================================================
  1802. // 12. ACTIVE CRT LIFECYCLE
  1803. // Status codes: 0=None, 1=Active Bullish, -1=Active Bearish,
  1804. // 2=Target Reached, -2=Invalidated, 3=Expired.
  1805. //======================================================================
  1806. int newCRTDirection = bullishManipulation ? 1 : bearishManipulation ? -1 : 0
  1807. bool newQualifiedCRT = newCRTDirection != 0
  1808.  
  1809. int latestCRTDirection = nz(ta.valuewhen(newQualifiedCRT, newCRTDirection, 0), 0)
  1810. float latestCRTRangeHigh = ta.valuewhen(newQualifiedCRT, rangeHigh, 0)
  1811. float latestCRTRangeLow = ta.valuewhen(newQualifiedCRT, rangeLow, 0)
  1812. int barsSinceQualifiedCRT = ta.barssince(newQualifiedCRT)
  1813.  
  1814. bool hasTrackedCRT =
  1815. latestCRTDirection != 0 and
  1816. not na(latestCRTRangeHigh) and
  1817. not na(latestCRTRangeLow) and
  1818. not na(barsSinceQualifiedCRT)
  1819.  
  1820. bool crtTargetReached =
  1821. hasTrackedCRT and barsSinceQualifiedCRT > 0 and (
  1822. latestCRTDirection == 1 ?
  1823. (targetRequiresClose ? close >= latestCRTRangeHigh : high >= latestCRTRangeHigh) :
  1824. (targetRequiresClose ? close <= latestCRTRangeLow : low <= latestCRTRangeLow)
  1825. )
  1826.  
  1827. bool crtInvalidated =
  1828. hasTrackedCRT and barsSinceQualifiedCRT > 0 and (
  1829. latestCRTDirection == 1 ?
  1830. (invalidationRequiresClose ? close < latestCRTRangeLow : low < latestCRTRangeLow) :
  1831. (invalidationRequiresClose ? close > latestCRTRangeHigh : high > latestCRTRangeHigh)
  1832. )
  1833.  
  1834. bool crtExpired = hasTrackedCRT and barsSinceQualifiedCRT > lifecycleExpiryBars
  1835.  
  1836. bool crtLifecycleActive =
  1837. hasTrackedCRT and
  1838. not crtTargetReached and
  1839. not crtInvalidated and
  1840. not crtExpired
  1841.  
  1842. int activeCRTDirection = crtLifecycleActive ? latestCRTDirection : 0
  1843.  
  1844. int crtLifecycleStatus =
  1845. crtLifecycleActive ? latestCRTDirection :
  1846. crtTargetReached ? 2 :
  1847. crtInvalidated ? -2 :
  1848. crtExpired ? 3 : 0
  1849.  
  1850.  
  1851. //======================================================================
  1852. // 12A. PROTOCOL 13 — FAILED CRT / REVERSAL CONTEXT
  1853. // A qualified CRT failure is opposite-direction information only.
  1854. // This module is context/alert logic and does not alter CRT qualification.
  1855. //======================================================================
  1856. bool failureWindowActive =
  1857. useFailedCRTContext and
  1858. hasTrackedCRT and
  1859. barsSinceQualifiedCRT > 0 and
  1860. barsSinceQualifiedCRT <= failureWindowBars
  1861.  
  1862. float failedCRTBoundary =
  1863. latestCRTDirection == 1 ? latestCRTRangeLow :
  1864. latestCRTDirection == -1 ? latestCRTRangeHigh : na
  1865.  
  1866. bool failedThroughBoundary =
  1867. failureWindowActive and (
  1868. latestCRTDirection == 1 ?
  1869. (failureRequiresClose ? close < failedCRTBoundary : low < failedCRTBoundary) :
  1870. latestCRTDirection == -1 ?
  1871. (failureRequiresClose ? close > failedCRTBoundary : high > failedCRTBoundary) :
  1872. false
  1873. )
  1874.  
  1875. bool failureDirectionOK =
  1876. not requireFailureDirectionalClose or (
  1877. (latestCRTDirection == 1 and close < open) or
  1878. (latestCRTDirection == -1 and close > open)
  1879. )
  1880.  
  1881. float failureATR = ta.atr(14)
  1882. float failureBody = math.abs(close - open)
  1883. bool failureBodyOK =
  1884. failureATR > 0 and
  1885. failureBody >= failureATR * minimumFailureBodyATR
  1886.  
  1887. bool failedCRTEvent =
  1888. failedThroughBoundary and
  1889. failureDirectionOK and
  1890. failureBodyOK and
  1891. not failedThroughBoundary[1]
  1892.  
  1893. int failedCRTReversalDirection =
  1894. failedCRTEvent ?
  1895. (latestCRTDirection == 1 ? -1 : latestCRTDirection == -1 ? 1 : 0) :
  1896. 0
  1897.  
  1898. int latestFailedCRTReversalDirection =
  1899. nz(ta.valuewhen(failedCRTEvent, failedCRTReversalDirection, 0), 0)
  1900.  
  1901. int barsSinceFailedCRT = ta.barssince(failedCRTEvent)
  1902.  
  1903. bool failedCRTReversalContextActive =
  1904. useFailedCRTContext and
  1905. latestFailedCRTReversalDirection != 0 and
  1906. not na(barsSinceFailedCRT) and
  1907. barsSinceFailedCRT <= failureWindowBars
  1908.  
  1909.  
  1910. //======================================================================
  1911. // 12B. PROTOCOL 14 — CRT TARGET DELIVERY / DRAW ON LIQUIDITY
  1912. // Selects the nearest valid opposite-side objective for the latest
  1913. // qualified CRT. Context only; does not affect CRT qualification.
  1914. // Target type codes:
  1915. // 0=None, 1=Opposite CRT boundary, 2=Previous Day,
  1916. // 3=Previous Week, 4=Previous Month, 5=Swing Liquidity.
  1917. //======================================================================
  1918. float targetATR = ta.atr(14)
  1919. float targetTolerance = targetATR * targetReachToleranceATR
  1920. float targetSwingHigh = ta.highest(high[1], targetSwingLookback)
  1921. float targetSwingLow = ta.lowest(low[1], targetSwingLookback)
  1922.  
  1923. f_pickNearestBullishTarget(
  1924. float referencePrice,
  1925. float crtHigh,
  1926. float pdh,
  1927. float pwh,
  1928. float pmh,
  1929. float swingHigh
  1930. ) =>
  1931. float selectedTarget = na
  1932. int selectedType = 0
  1933. float bestDistance = na
  1934.  
  1935. if includeOppositeCRTRangeBoundary and not na(crtHigh) and crtHigh > referencePrice
  1936. selectedTarget := crtHigh
  1937. selectedType := 1
  1938. bestDistance := crtHigh - referencePrice
  1939.  
  1940. if includePreviousDayTarget and not na(pdh) and pdh > referencePrice
  1941. float distance = pdh - referencePrice
  1942. if na(bestDistance) or distance < bestDistance
  1943. selectedTarget := pdh
  1944. selectedType := 2
  1945. bestDistance := distance
  1946.  
  1947. if includePreviousWeekTarget and not na(pwh) and pwh > referencePrice
  1948. float distance = pwh - referencePrice
  1949. if na(bestDistance) or distance < bestDistance
  1950. selectedTarget := pwh
  1951. selectedType := 3
  1952. bestDistance := distance
  1953.  
  1954. if includePreviousMonthTarget and not na(pmh) and pmh > referencePrice
  1955. float distance = pmh - referencePrice
  1956. if na(bestDistance) or distance < bestDistance
  1957. selectedTarget := pmh
  1958. selectedType := 4
  1959. bestDistance := distance
  1960.  
  1961. if includeSwingLiquidityTarget and not na(swingHigh) and swingHigh > referencePrice
  1962. float distance = swingHigh - referencePrice
  1963. if na(bestDistance) or distance < bestDistance
  1964. selectedTarget := swingHigh
  1965. selectedType := 5
  1966.  
  1967. [selectedTarget, selectedType]
  1968.  
  1969. f_pickNearestBearishTarget(
  1970. float referencePrice,
  1971. float crtLow,
  1972. float pdl,
  1973. float pwl,
  1974. float pml,
  1975. float swingLow
  1976. ) =>
  1977. float selectedTarget = na
  1978. int selectedType = 0
  1979. float bestDistance = na
  1980.  
  1981. if includeOppositeCRTRangeBoundary and not na(crtLow) and crtLow < referencePrice
  1982. selectedTarget := crtLow
  1983. selectedType := 1
  1984. bestDistance := referencePrice - crtLow
  1985.  
  1986. if includePreviousDayTarget and not na(pdl) and pdl < referencePrice
  1987. float distance = referencePrice - pdl
  1988. if na(bestDistance) or distance < bestDistance
  1989. selectedTarget := pdl
  1990. selectedType := 2
  1991. bestDistance := distance
  1992.  
  1993. if includePreviousWeekTarget and not na(pwl) and pwl < referencePrice
  1994. float distance = referencePrice - pwl
  1995. if na(bestDistance) or distance < bestDistance
  1996. selectedTarget := pwl
  1997. selectedType := 3
  1998. bestDistance := distance
  1999.  
  2000. if includePreviousMonthTarget and not na(pml) and pml < referencePrice
  2001. float distance = referencePrice - pml
  2002. if na(bestDistance) or distance < bestDistance
  2003. selectedTarget := pml
  2004. selectedType := 4
  2005. bestDistance := distance
  2006.  
  2007. if includeSwingLiquidityTarget and not na(swingLow) and swingLow < referencePrice
  2008. float distance = referencePrice - swingLow
  2009. if na(bestDistance) or distance < bestDistance
  2010. selectedTarget := swingLow
  2011. selectedType := 5
  2012.  
  2013. [selectedTarget, selectedType]
  2014.  
  2015. float latestQualifiedClose = ta.valuewhen(newQualifiedCRT, close, 0)
  2016.  
  2017. [bullishDrawTarget, bullishDrawType] =
  2018. f_pickNearestBullishTarget(
  2019. latestQualifiedClose,
  2020. latestCRTRangeHigh,
  2021. previousDayHigh,
  2022. previousWeekHigh,
  2023. previousMonthHigh,
  2024. targetSwingHigh
  2025. )
  2026.  
  2027. [bearishDrawTarget, bearishDrawType] =
  2028. f_pickNearestBearishTarget(
  2029. latestQualifiedClose,
  2030. latestCRTRangeLow,
  2031. previousDayLow,
  2032. previousWeekLow,
  2033. previousMonthLow,
  2034. targetSwingLow
  2035. )
  2036.  
  2037. float activeDrawTarget =
  2038. not useTargetDeliveryContext ? na :
  2039. latestCRTDirection == 1 ? bullishDrawTarget :
  2040. latestCRTDirection == -1 ? bearishDrawTarget :
  2041. na
  2042.  
  2043. int activeDrawTargetType =
  2044. not useTargetDeliveryContext ? 0 :
  2045. latestCRTDirection == 1 ? bullishDrawType :
  2046. latestCRTDirection == -1 ? bearishDrawType :
  2047. 0
  2048.  
  2049. bool activeDrawTargetAvailable =
  2050. useTargetDeliveryContext and
  2051. hasTrackedCRT and
  2052. not na(activeDrawTarget) and
  2053. activeDrawTargetType != 0
  2054.  
  2055. bool activeDrawTargetReached =
  2056. activeDrawTargetAvailable and
  2057. barsSinceQualifiedCRT > 0 and (
  2058. latestCRTDirection == 1 ?
  2059. high >= activeDrawTarget - targetTolerance :
  2060. latestCRTDirection == -1 ?
  2061. low <= activeDrawTarget + targetTolerance :
  2062. false
  2063. )
  2064.  
  2065. bool newDrawTargetReached =
  2066. activeDrawTargetReached and
  2067. not activeDrawTargetReached[1]
  2068.  
  2069.  
  2070. //======================================================================
  2071. // 12C. CRT INTELLIGENCE SCORE / GRADE ENGINE
  2072. // Snapshot grade at CRT confirmation. No future-bar information is used
  2073. // in the initial grade, so historical grades do not improve retroactively.
  2074. // Score components:
  2075. // Base qualification=1, protocol depth=0..3, POI=1, SMT=1,
  2076. // liquidity purge=1, nested HTF context=1, target available=1, HTF align=1.
  2077. //======================================================================
  2078. int protocolDepthScore =
  2079. protocolScore >= 7 ? 1 :
  2080. protocolScore >= 5 ? 1 :
  2081. protocolScore >= 3 ? 1 : 0
  2082.  
  2083. // Major context confirmations carry the grade.
  2084. // A neutral or missing context never receives the same weight as alignment.
  2085. int majorContextCount =
  2086. (dedicatedKeyLevelAligned ? 1 : 0) +
  2087. (smtAligned ? 1 : 0) +
  2088. (meaningfulLiquidityPurge ? 1 : 0) +
  2089. (hierarchyAligned ? 1 : 0) +
  2090. (meaningfulNestedContext ? 1 : 0)
  2091.  
  2092. int rawCRTIntelligenceScore =
  2093. qualifiedCRT ?
  2094. protocolDepthScore +
  2095. (dedicatedKeyLevelAligned ? 2 : 0) +
  2096. (smtAligned ? 2 : 0) +
  2097. (meaningfulLiquidityPurge ? 2 : 0) +
  2098. (hierarchyAligned ? 2 : 0) +
  2099. (meaningfulNestedContext ? 1 : 0) :
  2100. 0
  2101.  
  2102. int boundedCRTIntelligenceScore = math.min(rawCRTIntelligenceScore, 10)
  2103.  
  2104. // Hard context gates prevent a technically valid but context-poor CRT
  2105. // from being labelled A or A+.
  2106. bool aPlusGradeGate =
  2107. majorContextCount >= 4 and
  2108. dedicatedKeyLevelAligned and
  2109. (hierarchyAligned or meaningfulNestedContext)
  2110.  
  2111. bool aGradeGate =
  2112. majorContextCount >= 3
  2113.  
  2114. bool bGradeGate =
  2115. majorContextCount >= 1
  2116.  
  2117. int currentCRTGradeCode =
  2118. not useIntelligenceGrade or not qualifiedCRT ? 0 :
  2119. boundedCRTIntelligenceScore >= gradeAPlusThreshold and aPlusGradeGate ? 4 :
  2120. boundedCRTIntelligenceScore >= gradeAThreshold and aGradeGate ? 3 :
  2121. boundedCRTIntelligenceScore >= gradeBThreshold and bGradeGate ? 2 : 1
  2122.  
  2123. int latestCRTIntelligenceScore =
  2124. nz(ta.valuewhen(qualifiedCRT, boundedCRTIntelligenceScore, 0), 0)
  2125.  
  2126. int latestCRTGradeCode =
  2127. nz(ta.valuewhen(qualifiedCRT, currentCRTGradeCode, 0), 0)
  2128.  
  2129. bool gradeAPlusCRT = qualifiedCRT and currentCRTGradeCode == 4
  2130. bool gradeACRT = qualifiedCRT and currentCRTGradeCode == 3
  2131. bool gradeBCRT = qualifiedCRT and currentCRTGradeCode == 2
  2132. bool gradeCCRT = qualifiedCRT and currentCRTGradeCode == 1
  2133.  
  2134. //======================================================================
  2135. // 10. CLEAN SOURCE-TF COLORS + AUTO AMD WINDOWS ON LOWER TIMEFRAMES
  2136. //======================================================================
  2137. int chartSeconds = currentChartSeconds
  2138. int projectionSeconds = timeframe.in_seconds(selectedHTF)
  2139. bool isSourceTimeframe = not na(chartSeconds) and not na(projectionSeconds) and chartSeconds == projectionSeconds
  2140. bool isLowerThanProjection = not na(chartSeconds) and not na(projectionSeconds) and chartSeconds < projectionSeconds
  2141.  
  2142. // Only the selected source timeframe may color CRT candles. Lower timeframes
  2143. // remain untouched so traders cannot confuse HTF projection with LTF CRTs.
  2144. barcolor(
  2145. colorCandles and isSourceTimeframe and visibleCRT ? rangeColor : na,
  2146. offset = -1,
  2147. title = "Qualified CRT Range Candle"
  2148. )
  2149.  
  2150. barcolor(
  2151. colorCandles and isSourceTimeframe and visibleCRT ? manipulationColor : na,
  2152. title = "Qualified CRT Manipulation Candle"
  2153. )
  2154.  
  2155. //----------------------------------------------------------------------
  2156. // HTF qualification mirrored inside the selected source timeframe.
  2157. //----------------------------------------------------------------------
  2158. f_htfQualifiedCRT() =>
  2159. float pRangeHigh = high[1]
  2160. float pRangeLow = low[1]
  2161. float pRangeOpen = open[1]
  2162. float pRangeClose = close[1]
  2163. float pRangeSize = math.max(pRangeHigh - pRangeLow, syminfo.mintick)
  2164. float pRangeMid = (pRangeHigh + pRangeLow) * 0.5
  2165. float pRangeBodyPct = math.abs(pRangeClose - pRangeOpen) / pRangeSize * 100.0
  2166. float pAtr = ta.atr(14)
  2167.  
  2168. bool pSweptHigh = high > pRangeHigh
  2169. bool pSweptLow = low < pRangeLow
  2170. bool pSingleSweep = pSweptHigh != pSweptLow
  2171. bool pClosedInside = close < pRangeHigh and close > pRangeLow
  2172. bool pBullDirection = not requireDirectionalClose or close > open
  2173. bool pBearDirection = not requireDirectionalClose or close < open
  2174.  
  2175. bool pBase =
  2176. barstate.isconfirmed and
  2177. pSingleSweep and
  2178. (not rejectDoubleSweep or not (pSweptHigh and pSweptLow)) and
  2179. (not requireCloseInside or pClosedInside)
  2180.  
  2181. bool pBull = pBase and pSweptLow and not pSweptHigh and pBullDirection
  2182. bool pBear = pBase and pSweptHigh and not pSweptLow and pBearDirection
  2183.  
  2184. float pManipRange = math.max(high - low, syminfo.mintick)
  2185. float pLowerReject = (math.min(open, close) - low) / pManipRange * 100.0
  2186. float pUpperReject = (high - math.max(open, close)) / pManipRange * 100.0
  2187.  
  2188. bool pTime = isAllowedRangeHour(time[1])
  2189. bool pReject = (pBull and pLowerReject >= minimumRejectionPercent) or (pBear and pUpperReject >= minimumRejectionPercent)
  2190. bool pMid = (pBull and close > pRangeMid) or (pBear and close < pRangeMid)
  2191. float pAtrRatio = pAtr[1] > 0.0 ? pRangeSize / pAtr[1] : 0.0
  2192. bool pSize = pAtrRatio >= minimumRangeATR and pAtrRatio <= maximumRangeATR
  2193. bool pBody = pRangeBodyPct >= minimumRangeBodyPercent and pRangeBodyPct <= maximumRangeBodyPercent
  2194. float pPoiTolerance = pAtr[1] * poiToleranceATR
  2195. [pBullPOITypes, pBearPOITypes, pBullPOIScore, pBearPOIScore] = f_detectDirectionalPOIs(pRangeHigh, pRangeLow, pPoiTolerance)
  2196. bool pBullPOIAligned = pBullPOITypes >= minimumPOITypes and pBullPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or pBullPOIScore >= pBearPOIScore)
  2197. bool pBearPOIAligned = pBearPOITypes >= minimumPOITypes and pBearPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or pBearPOIScore >= pBullPOIScore)
  2198. bool pPOI = (pBull and pBullPOIAligned) or (pBear and pBearPOIAligned)
  2199.  
  2200. // Key-level requests are deliberately excluded here to avoid nested MTF requests.
  2201. int pEnabled =
  2202. (useTimeProtocol ? 1 : 0) +
  2203. (useRejectionProtocol ? 1 : 0) +
  2204. (useMidpointProtocol ? 1 : 0) +
  2205. (useRangeSizeProtocol ? 1 : 0) +
  2206. (useBodyProtocol ? 1 : 0) +
  2207. (usePOIProtocol ? 1 : 0)
  2208.  
  2209. int pScore =
  2210. (useTimeProtocol and pTime ? 1 : 0) +
  2211. (useRejectionProtocol and pReject ? 1 : 0) +
  2212. (useMidpointProtocol and pMid ? 1 : 0) +
  2213. (useRangeSizeProtocol and pSize ? 1 : 0) +
  2214. (useBodyProtocol and pBody ? 1 : 0) +
  2215. (usePOIProtocol and pPOI ? 1 : 0)
  2216.  
  2217. int pMinimum = math.min(minimumProtocols, math.max(pEnabled, 1))
  2218. (pBull or pBear) and pScore >= pMinimum
  2219.  
  2220. bool projectedQualified = request.security(
  2221. syminfo.tickerid,
  2222. selectedHTF,
  2223. f_htfQualifiedCRT(),
  2224. gaps = barmerge.gaps_off,
  2225. lookahead = barmerge.lookahead_off
  2226. )
  2227.  
  2228. f_htfDirection() =>
  2229. float pRangeHigh = high[1]
  2230. float pRangeLow = low[1]
  2231. bool pSweptHigh = high > pRangeHigh
  2232. bool pSweptLow = low < pRangeLow
  2233. bool pSingleSweep = pSweptHigh != pSweptLow
  2234. bool pClosedInside = close < pRangeHigh and close > pRangeLow
  2235. bool pBase = barstate.isconfirmed and pSingleSweep and (not requireCloseInside or pClosedInside)
  2236. pBase and pSweptLow and not pSweptHigh ? 1 : pBase and pSweptHigh and not pSweptLow ? -1 : 0
  2237.  
  2238. int projectedDirection = request.security(
  2239. syminfo.tickerid,
  2240. selectedHTF,
  2241. f_htfDirection(),
  2242. gaps = barmerge.gaps_off,
  2243. lookahead = barmerge.lookahead_off
  2244. )
  2245.  
  2246. int projectedRangeStart = request.security(syminfo.tickerid, selectedHTF, time[1], gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2247. int projectedManipulationStart = request.security(syminfo.tickerid, selectedHTF, time, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2248. int projectedDistributionStart = request.security(syminfo.tickerid, selectedHTF, time_close, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2249. int projectedDistributionEnd = request.security(syminfo.tickerid, selectedHTF, time_close + (time_close - time), gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2250.  
  2251. bool newProjectedSetup =
  2252. enableHTFProjection and
  2253. isLowerThanProjection and
  2254. projectedQualified and
  2255. (na(projectedManipulationStart[1]) or projectedManipulationStart != projectedManipulationStart[1])
  2256.  
  2257. // No projection objects are drawn.
  2258. // `newProjectedSetup` is retained only to update the internal HTF direction
  2259. // and Distribution-window timing used by the optional LTF structure engine.
  2260.  
  2261. //======================================================================
  2262. // 11. DIRECTIONAL LTF STRUCTURE UNLOCK
  2263. // After the qualified HTF Manipulation closes, the scanner activates only
  2264. // inside the HTF Distribution window. It does not issue buy/sell signals.
  2265. // It simply colors the aligned LTF CRT Range candle blue and its confirmed
  2266. // Manipulation candle yellow, leaving execution and Fib placement to trader.
  2267. //======================================================================
  2268. var int activeHTFDirection = 0
  2269. var int activeDistributionStart = na
  2270. var int activeDistributionEnd = na
  2271. var int ltfStructuresThisSetup = 0
  2272.  
  2273. if newProjectedSetup
  2274. activeHTFDirection := projectedDirection
  2275. activeDistributionStart := projectedDistributionStart
  2276. activeDistributionEnd := projectedDistributionEnd
  2277. ltfStructuresThisSetup := 0
  2278.  
  2279. float chartMinutes = not na(chartSeconds) ? chartSeconds / 60.0 : na
  2280. bool executionTimeframeAllowed =
  2281. isLowerThanProjection and
  2282. not na(chartMinutes) and
  2283. chartMinutes <= maximumExecutionMinutes
  2284.  
  2285. bool insideDistributionWindow =
  2286. not na(activeDistributionStart) and
  2287. not na(activeDistributionEnd) and
  2288. time >= activeDistributionStart and
  2289. time < activeDistributionEnd
  2290.  
  2291. float localRangeHigh = high[1]
  2292. float localRangeLow = low[1]
  2293. float localRangeMid = (localRangeHigh + localRangeLow) * 0.5
  2294. float localManipulationRange = math.max(high - low, syminfo.mintick)
  2295.  
  2296. bool localSweptLow = low < localRangeLow and high <= localRangeHigh
  2297. bool localSweptHigh = high > localRangeHigh and low >= localRangeLow
  2298. bool localClosedInside = close > localRangeLow and close < localRangeHigh
  2299. float localLowerReject = (math.min(open, close) - low) / localManipulationRange * 100.0
  2300. float localUpperReject = (high - math.max(open, close)) / localManipulationRange * 100.0
  2301.  
  2302. bool localBullishCRT =
  2303. barstate.isconfirmed and
  2304. localSweptLow and
  2305. (not localRequireCloseInside or localClosedInside) and
  2306. (not localRequireMidpoint or close > localRangeMid) and
  2307. localLowerReject >= localMinimumRejection
  2308.  
  2309. bool localBearishCRT =
  2310. barstate.isconfirmed and
  2311. localSweptHigh and
  2312. (not localRequireCloseInside or localClosedInside) and
  2313. (not localRequireMidpoint or close < localRangeMid) and
  2314. localUpperReject >= localMinimumRejection
  2315.  
  2316. bool structureEngineUnlocked =
  2317. enableExecutionEngine and
  2318. executionTimeframeAllowed and
  2319. insideDistributionWindow and
  2320. activeHTFDirection != 0
  2321.  
  2322. bool structureQuotaAvailable = not firstExecutionOnly or ltfStructuresThisSetup == 0
  2323. bool bullishLTFStructure = structureEngineUnlocked and structureQuotaAvailable and activeHTFDirection == 1 and localBullishCRT
  2324. bool bearishLTFStructure = structureEngineUnlocked and structureQuotaAvailable and activeHTFDirection == -1 and localBearishCRT
  2325. bool qualifiedLTFStructure = bullishLTFStructure or bearishLTFStructure
  2326.  
  2327. if qualifiedLTFStructure
  2328. ltfStructuresThisSetup += 1
  2329.  
  2330. // The Range candle is confirmed only when its following Manipulation candle
  2331. // closes, so it is colored retrospectively with offset -1.
  2332. barcolor(
  2333. colorUnlockedLTFStructure and qualifiedLTFStructure ? ltfRangeColor : na,
  2334. offset = -1,
  2335. title = "Unlocked LTF CRT Range Candle"
  2336. )
  2337.  
  2338. barcolor(
  2339. colorUnlockedLTFStructure and qualifiedLTFStructure ? ltfManipulationColor : na,
  2340. title = "Unlocked LTF CRT Manipulation Candle"
  2341. )
  2342.  
  2343. // Scores remain available in TradingView's Data Window only.
  2344. plot(protocolScore, "CRT Protocol Score", display = display.data_window)
  2345. plot(effectiveMinimum, "CRT Minimum Required", display = display.data_window)
  2346. plot(directionalPOIScore, "Directional POI Score", display = display.data_window)
  2347. plot(bullPOIScore, "Bullish POI Weight", display = display.data_window)
  2348. plot(bearPOIScore, "Bearish POI Weight", display = display.data_window)
  2349. plot(timeProtocol ? 1 : 0, "Market Time Protocol Passed", display = display.data_window)
  2350.  
  2351. string activeMarketProfile = f_selectedMarketProfile()
  2352. int activeMarketProfileCode =
  2353. activeMarketProfile == "Forex" ? 1 :
  2354. activeMarketProfile == "Indices" ? 2 :
  2355. activeMarketProfile == "Futures" ? 3 :
  2356. activeMarketProfile == "Crypto" ? 4 :
  2357. activeMarketProfile == "Commodities" ? 5 : 6
  2358. plot(parentCRTDirection, "Parent HTF CRT Direction", display = display.data_window)
  2359. plot(hierarchyAligned ? 1 : hierarchyOpposing ? -1 : 0, "Hierarchy Alignment State", display = display.data_window)
  2360. plot(activeCRTDirection, "Active CRT Direction", display = display.data_window)
  2361. plot(crtLifecycleStatus, "CRT Lifecycle Status", display = display.data_window)
  2362. plot(barsSinceQualifiedCRT, "Bars Since Qualified CRT", display = display.data_window)
  2363. plot(smtState1, "SMT Market 1 State", display = display.data_window)
  2364. plot(smtState2, "SMT Market 2 State", display = display.data_window)
  2365. plot(bullishSMTCount, "Bullish SMT Confirmation Count", display = display.data_window)
  2366. plot(bearishSMTCount, "Bearish SMT Confirmation Count", display = display.data_window)
  2367. plot(smtAligned ? 1 : smtOpposing ? -1 : 0, "SMT Matrix Alignment State", display = display.data_window)
  2368. plot(liquidityPurgeScore, "Liquidity Purge Score", display = display.data_window)
  2369. plot(meaningfulLiquidityPurge ? 1 : 0, "Meaningful Liquidity Purge", display = display.data_window)
  2370. plot(parentContextDirection, "Active Parent CRT Context Direction", display = display.data_window)
  2371. plot(parentContextHigh, "Active Parent CRT Range High", display = display.data_window)
  2372. plot(parentContextLow, "Active Parent CRT Range Low", display = display.data_window)
  2373. plot(nestedContextScore, "Nested HTF CRT Context Score", display = display.data_window)
  2374. plot(meaningfulNestedContext ? 1 : 0, "Meaningful Nested HTF Context", display = display.data_window)
  2375. plot(deliveryContextScore, "Displacement Delivery Score", display = display.data_window)
  2376. plot(meaningfulDeliveryContext ? 1 : 0, "Meaningful Displacement Delivery", display = display.data_window)
  2377. plot(deliveryCRTDirection, "Delivery CRT Direction", display = display.data_window)
  2378. plot(failedCRTEvent ? 1 : 0, "Failed CRT Event", display = display.data_window)
  2379. plot(failedCRTReversalDirection, "Failed CRT Reversal Direction", display = display.data_window)
  2380. plot(latestFailedCRTReversalDirection, "Latest Failed CRT Reversal Direction", display = display.data_window)
  2381. plot(failedCRTReversalContextActive ? 1 : 0, "Failed CRT Reversal Context Active", display = display.data_window)
  2382. plot(barsSinceFailedCRT, "Bars Since Failed CRT", display = display.data_window)
  2383. plot(activeDrawTarget, "Active CRT Draw Target", display = display.data_window)
  2384. plot(activeDrawTargetType, "Active CRT Draw Target Type", display = display.data_window)
  2385. plot(activeDrawTargetAvailable ? 1 : 0, "CRT Draw Target Available", display = display.data_window)
  2386. plot(activeDrawTargetReached ? 1 : 0, "CRT Draw Target Reached", display = display.data_window)
  2387. plot(boundedCRTIntelligenceScore, "CRT Intelligence Score", display = display.data_window)
  2388. plot(currentCRTGradeCode, "CRT Grade Code (4=A+, 3=A, 2=B, 1=C)", display = display.data_window)
  2389. plot(majorContextCount, "Major Grade Context Count", display = display.data_window)
  2390.  
  2391.  
  2392. //======================================================================
  2393. // 14A. CRT INTELLIGENCE DASHBOARD — PREVIEW
  2394. // Latest qualified CRT context only. No chart lines or labels are drawn.
  2395. // Dedicated source-timeframe engine reports exact FVG, IFVG,
  2396. // Order Block, Breaker, or Rejection Block context for the latest CRT.
  2397. //======================================================================
  2398. f_dashboardPosition(string p) =>
  2399. p == "Top Left" ? position.top_left :
  2400. p == "Bottom Right" ? position.bottom_right :
  2401. p == "Bottom Left" ? position.bottom_left :
  2402. position.top_right
  2403.  
  2404. f_dashboardTextSize(string s) =>
  2405. s == "Tiny" ? size.tiny :
  2406. s == "Normal" ? size.normal :
  2407. size.small
  2408.  
  2409. f_gradeText(int gradeCode) =>
  2410. gradeCode == 4 ? "A+" :
  2411. gradeCode == 3 ? "A" :
  2412. gradeCode == 2 ? "B" :
  2413. gradeCode == 1 ? "C" : "—"
  2414.  
  2415. f_keyLevelTypeText(int keyType, int direction) =>
  2416. string directionText =
  2417. direction == 1 ? "BULLISH " :
  2418. direction == -1 ? "BEARISH " : ""
  2419. string typeText =
  2420. keyType == 1 ? "FVG" :
  2421. keyType == 2 ? "IFVG" :
  2422. keyType == 3 ? "ORDER BLOCK" :
  2423. keyType == 4 ? "BREAKER" :
  2424. keyType == 5 ? "REJECTION BLOCK" :
  2425. "NONE"
  2426. keyType == 0 ? "NONE" : directionText + typeText
  2427.  
  2428. f_targetTypeText(int targetType, int direction) =>
  2429. targetType == 1 ? (direction == 1 ? "CRT HIGH" : direction == -1 ? "CRT LOW" : "CRT") :
  2430. targetType == 2 ? (direction == 1 ? "PDH" : direction == -1 ? "PDL" : "PD") :
  2431. targetType == 3 ? (direction == 1 ? "PWH" : direction == -1 ? "PWL" : "PW") :
  2432. targetType == 4 ? (direction == 1 ? "PMH" : direction == -1 ? "PML" : "PM") :
  2433. targetType == 5 ? (direction == 1 ? "SWING HIGH" : direction == -1 ? "SWING LOW" : "SWING") :
  2434. "NONE"
  2435.  
  2436. // v19.0 includes State Colour Intelligence and Multi-Timeframe Execution Guidance.
  2437. // ACTIVE keeps directional colour, DELIVERED is always success-green,
  2438. // FAILED / INVALID are red, and inactive lifecycle states are neutral grey.
  2439. f_stateColor(string state) =>
  2440. state == "BULLISH" or state == "BULLISH ACTIVE" or state == "ALIGNED" or state == "CONFIRMED" or state == "ACTIVE" or state == "REACHED" or state == "STRONG" or state == "BULL REVERSAL" or state == "BULLISH DELIVERED" or state == "BEARISH DELIVERED" or state == "DELIVERED" ? color.new(color.green, 72) :
  2441. state == "BEARISH" or state == "BEARISH ACTIVE" or state == "BULLISH FAILED" or state == "BEARISH FAILED" or state == "BULLISH INVALID" or state == "BEARISH INVALID" or state == "CONFLICT" or state == "FAILED" or state == "INVALID" or state == "BEAR REVERSAL" ? color.new(color.red, 72) :
  2442. state == "NEUTRAL" or state == "MODERATE" ? color.new(color.orange, 72) :
  2443. state == "LTF CRT ALIGNED" ? color.new(color.green, 72) :
  2444. state == "LTF CRT OPPOSED" ? color.new(color.red, 72) :
  2445. state == "EXPIRED" or state == "WAITING" ? color.new(color.gray, 72) :
  2446. color.new(color.gray, 82)
  2447.  
  2448. //======================================================================
  2449. // 14A. TRADE READINESS & ACTION ENGINE — v18.7
  2450. // Converts the existing CRT intelligence into a clear action state.
  2451. // A failed CRT creates reversal context only; it never creates an
  2452. // automatic entry. Reversal entries still require an opposite-direction
  2453. // lower-timeframe CRT confirmation.
  2454. //======================================================================
  2455. // v19.2 Unified lifecycle arbitration.
  2456. // The first terminal event wins for the current CRT. If target delivery
  2457. // occurs before (or on the same bar as) failure, the setup remains DELIVERED.
  2458. // A later failure/invalidation cannot rewrite a completed objective.
  2459. bool crtBoundaryTargetEvent = crtTargetReached and not crtTargetReached[1]
  2460. bool unifiedTargetEvent = crtBoundaryTargetEvent or newDrawTargetReached
  2461. int barsSinceUnifiedTarget = ta.barssince(unifiedTargetEvent)
  2462.  
  2463. bool unifiedTargetBelongsToCurrentCRT =
  2464. hasTrackedCRT and
  2465. not na(barsSinceUnifiedTarget) and
  2466. barsSinceUnifiedTarget <= barsSinceQualifiedCRT
  2467.  
  2468. bool unifiedFailureBelongsToCurrentCRT =
  2469. hasTrackedCRT and
  2470. not na(barsSinceFailedCRT) and
  2471. barsSinceFailedCRT <= barsSinceQualifiedCRT
  2472.  
  2473. // Larger bars-since means the event happened earlier. Equality gives
  2474. // target delivery priority when both events occur on the same candle.
  2475. bool targetWonLifecycle =
  2476. unifiedTargetBelongsToCurrentCRT and
  2477. (not unifiedFailureBelongsToCurrentCRT or barsSinceUnifiedTarget >= barsSinceFailedCRT)
  2478.  
  2479. bool failureWonLifecycle =
  2480. unifiedFailureBelongsToCurrentCRT and
  2481. not targetWonLifecycle
  2482.  
  2483. bool tradeTargetReached = targetWonLifecycle
  2484. bool tradeReversalActive = failedCRTReversalContextActive and failureWonLifecycle
  2485.  
  2486. bool tradeInvalid =
  2487. hasTrackedCRT and
  2488. crtInvalidated and
  2489. not tradeTargetReached and
  2490. not failureWonLifecycle
  2491.  
  2492. bool tradeExpired =
  2493. hasTrackedCRT and
  2494. crtExpired and
  2495. not tradeReversalActive and
  2496. not tradeTargetReached and
  2497. not tradeInvalid
  2498.  
  2499. bool tradeProtocolAligned =
  2500. not hierarchyOpposing and
  2501. not smtOpposing and
  2502. latestCRTIntelligenceScore >= gradeBThreshold
  2503.  
  2504. bool tradeReady =
  2505. not tradeReversalActive and
  2506. crtLifecycleActive and
  2507. meaningfulDeliveryContext and
  2508. tradeProtocolAligned
  2509.  
  2510. bool tradeWatch =
  2511. not tradeReversalActive and
  2512. crtLifecycleActive and
  2513. not tradeReady
  2514.  
  2515. string dashboardTradeStatus =
  2516. tradeReversalActive ? "REVERSAL ACTIVE" :
  2517. tradeTargetReached ? "TARGET REACHED" :
  2518. tradeInvalid ? "INVALID" :
  2519. tradeExpired ? "EXPIRED" :
  2520. tradeReady ? "READY" :
  2521. tradeWatch ? "WATCH" :
  2522. "WAIT"
  2523.  
  2524. int executionDirection =
  2525. tradeReversalActive ? latestFailedCRTReversalDirection :
  2526. crtLifecycleActive ? activeCRTDirection : 0
  2527.  
  2528. string dashboardExecutionBias =
  2529. executionDirection == 1 ? "SEEK LONG" :
  2530. executionDirection == -1 ? "SEEK SHORT" :
  2531. "NEUTRAL"
  2532.  
  2533. string dashboardEntryCondition =
  2534. tradeReversalActive ?
  2535. (executionDirection == 1 ? "WAIT BULLISH LTF CRT" : "WAIT BEARISH LTF CRT") :
  2536. tradeReady ?
  2537. (executionDirection == 1 ? "BULLISH CONFIRMATION" : "BEARISH CONFIRMATION") :
  2538. tradeWatch ?
  2539. (meaningfulDeliveryContext ? "WAIT PROTOCOL ALIGNMENT" : "WAIT FOR DELIVERY") :
  2540. tradeTargetReached ? "NO CHASE • TARGET DONE" :
  2541. tradeInvalid ? "NO TRADE" :
  2542. tradeExpired ? "WAIT NEW CRT" :
  2543. "WAIT QUALIFIED CRT"
  2544.  
  2545. string dashboardRiskState =
  2546. tradeReversalActive ? "ORIGINAL CRT FAILED" :
  2547. tradeTargetReached ? "OBJECTIVE DELIVERED" :
  2548. tradeInvalid ? "INVALIDATED" :
  2549. tradeExpired ? "SETUP EXPIRED" :
  2550. tradeReady ? "CONFIRMED • MANAGE RISK" :
  2551. tradeWatch ? "UNCONFIRMED" :
  2552. "NO ACTIVE RISK"
  2553.  
  2554. string dashboardSetupAge =
  2555. hasTrackedCRT and not na(barsSinceQualifiedCRT) ?
  2556. str.tostring(barsSinceQualifiedCRT) + " / " + str.tostring(lifecycleExpiryBars) + " BARS" :
  2557. "—"
  2558.  
  2559. f_tradeStatusColor(string state, int direction) =>
  2560. state == "READY" or state == "RE-ARMED" ? (direction == -1 ? color.new(color.red, 60) : color.new(color.green, 60)) :
  2561. state == "REVERSAL ACTIVE" ? (direction == -1 ? color.new(color.red, 60) : direction == 1 ? color.new(color.green, 60) : color.new(color.orange, 65)) :
  2562. state == "INVALID" ? color.new(color.red, 58) :
  2563. state == "TARGET REACHED" ? color.new(color.green, 72) :
  2564. state == "WATCH" ? color.new(color.orange, 65) :
  2565. state == "EXPIRED" ? color.new(color.gray, 72) :
  2566. color.new(color.gray, 82)
  2567.  
  2568. //======================================================================
  2569. // 14B. UNIFIED STORY ENGINE — v19.2
  2570. // On execution charts (15m and below by default), the active H1 story
  2571. // controls directional guidance. The LTF may confirm that direction or
  2572. // remain neutral, but an opposing local CRT cannot flip the HTF bias.
  2573. //======================================================================
  2574. f_executionParentTF() =>
  2575. not na(chartMinutes) and chartMinutes <= 15.0 ? "60" :
  2576. not na(chartMinutes) and chartMinutes <= 60.0 ? "240" :
  2577. selectedHTF
  2578.  
  2579. string inheritanceParentTF = f_executionParentTF()
  2580.  
  2581. // v20.0 Narrative Transition Memory + Fresh Narrative Validation.
  2582. // Every qualified CRT receives a monotonically increasing source-timeframe ID.
  2583. // After a terminal narrative, a later ID is considered fresh but remains locked
  2584. // until direction, HTF context, delivery, and objective availability validate.
  2585. int narrativeSerial = int(ta.cum(qualifiedCRT ? 1 : 0))
  2586. int latestQualifiedNarrativeID = nz(ta.valuewhen(qualifiedCRT, narrativeSerial, 0), 0)
  2587. int latestQualifiedNarrativeTime = nz(ta.valuewhen(qualifiedCRT, time, 0), 0)
  2588. int latestNarrativeDirection = nz(ta.valuewhen(qualifiedCRT, currentQualifiedCRTDirection, 0), 0)
  2589. bool latestNarrativeHierarchyPass = ta.valuewhen(qualifiedCRT, hierarchyProtocol and hierarchyHardPass, 0)
  2590.  
  2591. bool terminalNarrativeState = tradeTargetReached or tradeInvalid or tradeExpired
  2592. bool terminalNarrativeEvent = terminalNarrativeState and not terminalNarrativeState[1]
  2593. int latestTerminalNarrativeTime = nz(ta.valuewhen(terminalNarrativeEvent, time, 0), 0)
  2594. int latestTerminalNarrativeID = nz(ta.valuewhen(terminalNarrativeEvent, latestQualifiedNarrativeID, 0), 0)
  2595.  
  2596. bool hasFreshNarrativeIdentity =
  2597. enableNarrativeFreshnessEngine and
  2598. latestTerminalNarrativeTime > 0 and
  2599. latestQualifiedNarrativeID > latestTerminalNarrativeID and
  2600. latestQualifiedNarrativeTime > latestTerminalNarrativeTime
  2601.  
  2602. int freshNarrativeAge =
  2603. hasFreshNarrativeIdentity and not na(barsSinceQualifiedCRT) ?
  2604. barsSinceQualifiedCRT : 100000
  2605.  
  2606. bool freshDirectionConfirmed =
  2607. hasFreshNarrativeIdentity and
  2608. latestNarrativeDirection != 0
  2609.  
  2610. bool freshHTFContextConfirmed =
  2611. hasFreshNarrativeIdentity and
  2612. (not requireFreshHierarchyAlignment or latestNarrativeHierarchyPass)
  2613.  
  2614. bool freshDeliveryConfirmed =
  2615. hasFreshNarrativeIdentity and
  2616. (not requireFreshDeliveryConfirmation or meaningfulDeliveryContext)
  2617.  
  2618. bool freshObjectiveOpen =
  2619. hasFreshNarrativeIdentity and
  2620. crtLifecycleActive and
  2621. not tradeTargetReached and
  2622. not tradeInvalid and
  2623. not tradeExpired
  2624.  
  2625. bool freshValidationTimedOut =
  2626. hasFreshNarrativeIdentity and
  2627. freshNarrativeAge > freshValidationWindowBars and
  2628. not freshDeliveryConfirmed
  2629.  
  2630. // v20.1 Narrative Validation Failure Memory.
  2631. // Once a fresh narrative ID fails validation, that exact ID is permanently
  2632. // rejected. Later changes in delivery or context cannot revive it. Only a
  2633. // strictly newer qualified narrative ID may enter validation.
  2634. var int latestRejectedNarrativeID = 0
  2635.  
  2636. bool freshValidationFailureNow =
  2637. enableFreshNarrativeValidation and
  2638. hasFreshNarrativeIdentity and
  2639. latestQualifiedNarrativeID > latestRejectedNarrativeID and (
  2640. not freshDirectionConfirmed or
  2641. not freshHTFContextConfirmed or
  2642. not freshObjectiveOpen or
  2643. freshValidationTimedOut
  2644. )
  2645.  
  2646. if freshValidationFailureNow
  2647. latestRejectedNarrativeID := latestQualifiedNarrativeID
  2648.  
  2649. bool freshNarrativePermanentlyRejected =
  2650. hasFreshNarrativeIdentity and
  2651. latestQualifiedNarrativeID <= latestRejectedNarrativeID
  2652.  
  2653. bool freshValidationRejected =
  2654. enableFreshNarrativeValidation and
  2655. freshNarrativePermanentlyRejected
  2656.  
  2657. bool freshValidationConfirmed =
  2658. hasFreshNarrativeIdentity and
  2659. not freshNarrativePermanentlyRejected and
  2660. (
  2661. not enableFreshNarrativeValidation or
  2662. (
  2663. freshDirectionConfirmed and
  2664. freshHTFContextConfirmed and
  2665. freshDeliveryConfirmed and
  2666. freshObjectiveOpen and
  2667. not freshValidationTimedOut
  2668. )
  2669. )
  2670.  
  2671. // State codes: 0 = none, 1 = validating, 2 = confirmed, 3 = permanently rejected.
  2672. int freshValidationState =
  2673. not hasFreshNarrativeIdentity ? 0 :
  2674. freshValidationRejected ? 3 :
  2675. freshValidationConfirmed ? 2 : 1
  2676.  
  2677. int freshValidationScore =
  2678. (freshDirectionConfirmed ? 1 : 0) +
  2679. (freshHTFContextConfirmed ? 1 : 0) +
  2680. (freshDeliveryConfirmed ? 1 : 0) +
  2681. (freshObjectiveOpen ? 1 : 0)
  2682.  
  2683. bool localNarrativeFresh =
  2684. hasFreshNarrativeIdentity and
  2685. crtLifecycleActive and
  2686. freshNarrativeAge <= freshNarrativeDisplayBars
  2687.  
  2688. bool localNarrativeRearmed =
  2689. enableNarrativeRearmEngine and
  2690. crtLifecycleActive and
  2691. freshValidationConfirmed and
  2692. freshNarrativeAge <= rearmDisplayParentBars
  2693.  
  2694. [inheritedReversalActiveRaw, inheritedReversalDirectionRaw, inheritedLifecycleActiveRaw, inheritedActiveDirectionRaw, inheritedTargetReachedRaw, inheritedInvalidRaw, inheritedExpiredRaw, inheritedSetupAgeRaw, inheritedQualifiedNarrativeTimeRaw, inheritedTerminalNarrativeTimeRaw, inheritedNarrativeRearmedRaw, inheritedQualifiedNarrativeIDRaw, inheritedTerminalNarrativeIDRaw, inheritedNarrativeFreshRaw, inheritedFreshNarrativeAgeRaw, inheritedFreshValidationStateRaw, inheritedFreshValidationScoreRaw, inheritedFreshDirectionRaw, inheritedRejectedNarrativeIDRaw] =
  2695. request.security(
  2696. syminfo.tickerid,
  2697. inheritanceParentTF,
  2698. [tradeReversalActive, executionDirection, crtLifecycleActive and not tradeTargetReached and not tradeInvalid, activeCRTDirection, tradeTargetReached, tradeInvalid, tradeExpired, nz(barsSinceQualifiedCRT, 0), latestQualifiedNarrativeTime, latestTerminalNarrativeTime, localNarrativeRearmed, latestQualifiedNarrativeID, latestTerminalNarrativeID, localNarrativeFresh, freshNarrativeAge, freshValidationState, freshValidationScore, latestNarrativeDirection, latestRejectedNarrativeID],
  2699. gaps = barmerge.gaps_off,
  2700. lookahead = barmerge.lookahead_off
  2701. )
  2702.  
  2703. // Every execution chart reads a dedicated parent channel. The parent channel
  2704. // is displayed even when it is terminal/neutral, while the local channel is
  2705. // kept separate for entry timing and local expiry.
  2706. bool executionChildMode =
  2707. executionTimeframeAllowed and
  2708. inheritanceParentTF != timeframe.period
  2709.  
  2710. bool inheritedFreshNarrative =
  2711. enableNarrativeRearmEngine and
  2712. enableNarrativeFreshnessEngine and
  2713. inheritedLifecycleActiveRaw and
  2714. inheritedQualifiedNarrativeIDRaw > inheritedTerminalNarrativeIDRaw and
  2715. inheritedQualifiedNarrativeTimeRaw > inheritedTerminalNarrativeTimeRaw
  2716.  
  2717. bool inheritedFreshValidationConfirmed = inheritedFreshValidationStateRaw == 2
  2718. bool inheritedFreshValidationRejected = inheritedFreshValidationStateRaw == 3
  2719. bool inheritedFreshValidationPending = inheritedFreshValidationStateRaw == 1
  2720.  
  2721. bool inheritedNarrativeStandDown =
  2722. enableNarrativeRearmEngine and (
  2723. (
  2724. (inheritedTargetReachedRaw or inheritedInvalidRaw or inheritedExpiredRaw) and
  2725. not inheritedFreshNarrative
  2726. ) or
  2727. (
  2728. inheritedFreshNarrative and
  2729. not inheritedFreshValidationConfirmed
  2730. )
  2731. )
  2732.  
  2733. // v19.8 keeps the v19.7 Parent Completion Stand-Down Lock and adds
  2734. // explicit reset/re-arm identity checking.
  2735. // IMPORTANT: The inherited story is derived directly from the parent timeframe
  2736. // on every bar. It is never stored in a chart-timeframe `var`, so a 1m/5m local
  2737. // expiry cannot erase it and a stale child chart cannot keep an old parent bias.
  2738. // Parent delivery/invalidation clears the inherited bias consistently on every LTF.
  2739. int inheritedParentStoryType =
  2740. inheritedNarrativeStandDown ? 0 :
  2741. inheritedReversalActiveRaw and inheritedReversalDirectionRaw != 0 ? 2 :
  2742. inheritedLifecycleActiveRaw and inheritedActiveDirectionRaw != 0 ? 1 : 0
  2743.  
  2744. int inheritedHTFDirection =
  2745. inheritedParentStoryType == 2 ? inheritedReversalDirectionRaw :
  2746. inheritedParentStoryType == 1 ? inheritedActiveDirectionRaw : 0
  2747.  
  2748. bool htfBiasInheritanceLock =
  2749. executionTimeframeAllowed and
  2750. inheritedHTFDirection != 0
  2751.  
  2752. bool inheritedAlignedLocalCRT =
  2753. htfBiasInheritanceLock and (
  2754. (inheritedHTFDirection == 1 and localBullishCRT) or
  2755. (inheritedHTFDirection == -1 and localBearishCRT)
  2756. )
  2757.  
  2758. bool inheritedOpposingLocalCRT =
  2759. htfBiasInheritanceLock and (
  2760. (inheritedHTFDirection == 1 and localBearishCRT) or
  2761. (inheritedHTFDirection == -1 and localBullishCRT)
  2762. )
  2763.  
  2764. // Classify the complete local story (active CRT or failed-CRT reversal),
  2765. // not only the current two-candle candidate.
  2766. int localStoryDirection =
  2767. tradeReversalActive ? latestFailedCRTReversalDirection :
  2768. crtLifecycleActive ? activeCRTDirection : 0
  2769.  
  2770. bool localStoryAligned =
  2771. htfBiasInheritanceLock and
  2772. localStoryDirection != 0 and
  2773. localStoryDirection == inheritedHTFDirection
  2774.  
  2775. bool localStoryOpposed =
  2776. htfBiasInheritanceLock and
  2777. localStoryDirection != 0 and
  2778. localStoryDirection != inheritedHTFDirection
  2779.  
  2780. int displayExecutionDirection = htfBiasInheritanceLock ? inheritedHTFDirection : executionDirection
  2781.  
  2782. string displayTradeStatus =
  2783. executionChildMode ?
  2784. (htfBiasInheritanceLock ?
  2785. (inheritedNarrativeRearmedRaw ? "RE-ARMED" : inheritedAlignedLocalCRT or localStoryAligned ? "READY" : "WATCH") :
  2786. inheritedTargetReachedRaw ? "TARGET REACHED" :
  2787. inheritedInvalidRaw ? "INVALID" :
  2788. inheritedExpiredRaw ? "EXPIRED" :
  2789. "WAIT") :
  2790. (localNarrativeRearmed ? "RE-ARMED" : dashboardTradeStatus)
  2791.  
  2792. string displayExecutionBias =
  2793. executionChildMode and inheritedTargetReachedRaw ? "STAND DOWN" :
  2794. executionChildMode and (inheritedInvalidRaw or inheritedExpiredRaw) ? "NEUTRAL" :
  2795. displayExecutionDirection == 1 ? "SEEK LONG" :
  2796. displayExecutionDirection == -1 ? "SEEK SHORT" :
  2797. "NEUTRAL"
  2798.  
  2799. string displayEntryCondition =
  2800. executionChildMode ?
  2801. (htfBiasInheritanceLock ?
  2802. (inheritedOpposingLocalCRT or localStoryOpposed ? "IGNORE OPPOSING LTF STORY" :
  2803. inheritedAlignedLocalCRT or localStoryAligned ? "ALIGNED LTF STORY CONFIRMED" :
  2804. displayExecutionDirection == 1 ? "WAIT BULLISH LTF CRT" : "WAIT BEARISH LTF CRT") :
  2805. inheritedTargetReachedRaw ? "NO CHASE • PARENT TARGET DONE" :
  2806. inheritedInvalidRaw ? "WAIT NEW PARENT CRT" :
  2807. inheritedExpiredRaw ? "WAIT NEW PARENT CRT" :
  2808. "WAIT PARENT STORY") :
  2809. dashboardEntryCondition
  2810.  
  2811. string displayRiskState =
  2812. executionChildMode ?
  2813. (inheritedTargetReachedRaw ? "PARENT OBJECTIVE DELIVERED" :
  2814. inheritedInvalidRaw ? "PARENT INVALIDATED" :
  2815. inheritedExpiredRaw ? "PARENT EXPIRED" :
  2816. htfBiasInheritanceLock ? "PARENT STORY ACTIVE" : "NO PARENT RISK") :
  2817. dashboardRiskState
  2818.  
  2819. string displaySetupAge =
  2820. executionChildMode ? str.tostring(inheritedSetupAgeRaw) + " / " + str.tostring(lifecycleExpiryBars) + " PARENT BARS" : dashboardSetupAge
  2821.  
  2822. string inheritedParentStory =
  2823. inheritedNarrativeRearmedRaw and inheritedParentStoryType != 0 ?
  2824. inheritanceParentTF + (inheritedHTFDirection == 1 ? " NEW BULLISH NARRATIVE • RE-ARMED" : " NEW BEARISH NARRATIVE • RE-ARMED") :
  2825. inheritedParentStoryType == 2 ?
  2826. inheritanceParentTF + (inheritedHTFDirection == 1 ? " BULL REVERSAL" : " BEAR REVERSAL") :
  2827. inheritedParentStoryType == 1 ?
  2828. inheritanceParentTF + (inheritedHTFDirection == 1 ? " BULLISH ACTIVE" : " BEARISH ACTIVE") :
  2829. inheritedTargetReachedRaw ? inheritanceParentTF + " OBJECTIVE DELIVERED • STAND DOWN" :
  2830. inheritedInvalidRaw ? inheritanceParentTF + " INVALIDATED • RESET" :
  2831. inheritedExpiredRaw ? inheritanceParentTF + " EXPIRED • RESET" :
  2832. inheritanceParentTF + " WAITING FOR NEW NARRATIVE"
  2833.  
  2834. // v18.8 lifecycle clarity: the CRT row describes both direction and lifecycle.
  2835. // This prevents a delivered historical bearish CRT from looking like a live short bias.
  2836. string localLifecycleText =
  2837. tradeReversalActive ?
  2838. (latestCRTDirection == 1 ? "BULLISH FAILED" : latestCRTDirection == -1 ? "BEARISH FAILED" : "FAILED") :
  2839. tradeTargetReached ?
  2840. (latestCRTDirection == 1 ? "BULLISH DELIVERED" : latestCRTDirection == -1 ? "BEARISH DELIVERED" : "DELIVERED") :
  2841. tradeInvalid ?
  2842. (latestCRTDirection == 1 ? "BULLISH INVALID" : latestCRTDirection == -1 ? "BEARISH INVALID" : "INVALID") :
  2843. tradeExpired ? "EXPIRED" :
  2844. crtLifecycleActive ?
  2845. (activeCRTDirection == 1 ? "BULLISH ACTIVE" : activeCRTDirection == -1 ? "BEARISH ACTIVE" : "ACTIVE") :
  2846. "WAITING"
  2847.  
  2848. string dashboardCRTState =
  2849. htfBiasInheritanceLock and (inheritedOpposingLocalCRT or localStoryOpposed) ? "LTF STORY OPPOSED" :
  2850. htfBiasInheritanceLock and (inheritedAlignedLocalCRT or localStoryAligned) ? "LTF STORY ALIGNED" :
  2851. htfBiasInheritanceLock ? "LTF WAITING" :
  2852. localLifecycleText
  2853.  
  2854. string dashboardHTF =
  2855. hierarchyAligned ? "ALIGNED" :
  2856. hierarchyOpposing ? "CONFLICT" :
  2857. "NEUTRAL"
  2858.  
  2859. string dashboardPOI =
  2860. f_keyLevelTypeText(latestKeyLevelType, latestKeyLevelDirection)
  2861.  
  2862. string dashboardKeyLevelTF =
  2863. latestKeyLevelType != 0 ? selectedHTF : "—"
  2864.  
  2865. string dashboardPurge =
  2866. meaningfulLiquidityPurge ?
  2867. (latestCRTDirection == 1 ? "SSL PURGED" : latestCRTDirection == -1 ? "BSL PURGED" : "CONFIRMED") :
  2868. "NONE"
  2869.  
  2870. string dashboardSMT =
  2871. smtAligned ?
  2872. (latestCRTDirection == 1 ? "BULLISH" : latestCRTDirection == -1 ? "BEARISH" : "CONFIRMED") :
  2873. smtOpposing ? "CONFLICT" :
  2874. "NEUTRAL"
  2875.  
  2876. string dashboardNested =
  2877. meaningfulNestedContext ? "ALIGNED" :
  2878. parentContextActive ? "NEUTRAL" :
  2879. "NONE"
  2880.  
  2881. string dashboardDelivery =
  2882. htfBiasInheritanceLock ?
  2883. (localStoryAligned ? "ALIGNED" : localStoryOpposed ? "OPPOSED" : "WAITING") :
  2884. meaningfulDeliveryContext ? "CONFIRMED" :
  2885. tradeReversalActive ? "FAILED" :
  2886. "WAITING"
  2887.  
  2888. string dashboardTarget = f_targetTypeText(activeDrawTargetType, latestCRTDirection)
  2889. string dashboardTargetStatus =
  2890. tradeTargetReached ? "REACHED" :
  2891. activeDrawTargetAvailable and not tradeReversalActive and not tradeInvalid ? "ACTIVE" :
  2892. "NONE"
  2893.  
  2894. string dashboardFailure =
  2895. htfBiasInheritanceLock ?
  2896. (localStoryOpposed ? "OPPOSED TO HTF" : localStoryAligned ? "ALIGNED TO HTF" : "NONE") :
  2897. tradeReversalActive ?
  2898. (latestFailedCRTReversalDirection == 1 ? "BULL REVERSAL" : "BEAR REVERSAL") :
  2899. "NONE"
  2900.  
  2901. //======================================================================
  2902. // 14C. STORY TRANSLATION + CENTRAL STATE MATRIX — v19.7
  2903. // Student-facing explanation of the local CRT, its implication, its
  2904. // alignment with the inherited HTF story, and the practical action.
  2905. // This changes dashboard wording only; detection logic is untouched.
  2906. //======================================================================
  2907. string dashboardLocalCRT =
  2908. tradeReversalActive ?
  2909. (latestCRTDirection == 1 ? "BULLISH CRT FAILED" : latestCRTDirection == -1 ? "BEARISH CRT FAILED" : "CRT FAILED") :
  2910. tradeTargetReached ?
  2911. (latestCRTDirection == 1 ? "BULLISH CRT DELIVERED" : latestCRTDirection == -1 ? "BEARISH CRT DELIVERED" : "CRT DELIVERED") :
  2912. tradeInvalid ?
  2913. (latestCRTDirection == 1 ? "BULLISH CRT INVALID" : latestCRTDirection == -1 ? "BEARISH CRT INVALID" : "CRT INVALID") :
  2914. tradeExpired ? "CRT EXPIRED" :
  2915. crtLifecycleActive ?
  2916. (activeCRTDirection == 1 ? "BULLISH CRT ACTIVE" : activeCRTDirection == -1 ? "BEARISH CRT ACTIVE" : "CRT ACTIVE") :
  2917. "NO LOCAL CRT"
  2918.  
  2919. string dashboardLocalImplication =
  2920. tradeReversalActive ?
  2921. (latestFailedCRTReversalDirection == 1 ? "BULLISH REVERSAL" : "BEARISH REVERSAL") :
  2922. tradeTargetReached ? "OBJECTIVE COMPLETE" :
  2923. tradeInvalid ? "RESET CONTEXT" :
  2924. tradeExpired ? "WAIT NEW CRT" :
  2925. crtLifecycleActive ?
  2926. (activeCRTDirection == 1 ? "BULLISH DELIVERY" : activeCRTDirection == -1 ? "BEARISH DELIVERY" : "ACTIVE DELIVERY") :
  2927. "WAITING"
  2928.  
  2929. string dashboardHTFAlignment =
  2930. not htfBiasInheritanceLock ? dashboardHTF :
  2931. localStoryAligned or inheritedAlignedLocalCRT ? "ALIGNED" :
  2932. localStoryOpposed or inheritedOpposingLocalCRT ? "OPPOSED" :
  2933. "WAITING"
  2934.  
  2935. string dashboardAction =
  2936. not executionChildMode ? (localNarrativeRearmed ? "NEW NARRATIVE • RE-ARMED" : "FOLLOW ENGINE VERDICT") :
  2937. inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? "RE-ARMED • HUNT ALIGNED LTF CRT" :
  2938. inheritedTargetReachedRaw ? "PARENT DONE • NO CHASE" :
  2939. inheritedInvalidRaw or inheritedExpiredRaw ? "WAIT NEW PARENT CRT" :
  2940. not htfBiasInheritanceLock ? "WAIT PARENT STORY" :
  2941. localStoryOpposed or inheritedOpposingLocalCRT ? "IGNORE • WAIT ALIGNED CRT" :
  2942. tradeExpired ? (displayExecutionDirection == 1 ? "LOCAL RESET • WAIT BULL CRT" : "LOCAL RESET • WAIT BEAR CRT") :
  2943. not insideDistributionWindow ? "WAIT EXECUTION WINDOW" :
  2944. localStoryAligned or inheritedAlignedLocalCRT ? "CONFIRM ENTRY + RISK" :
  2945. displayExecutionDirection == 1 ? "WAIT BULLISH LTF CRT" :
  2946. displayExecutionDirection == -1 ? "WAIT BEARISH LTF CRT" :
  2947. "WAIT HTF BIAS"
  2948.  
  2949. //======================================================================
  2950. // 14B. MULTI-TIMEFRAME EXECUTION GUIDANCE — v19.2
  2951. // Translates the HTF lifecycle into the next practical timeframe, the
  2952. // structure to hunt, and whether the existing LTF execution scanner is
  2953. // locked, open, or has confirmed an aligned CRT. This is guidance only.
  2954. //======================================================================
  2955. f_nextExecutionTF(string sourceTF) =>
  2956. sourceTF == "M" ? "W / D" :
  2957. sourceTF == "W" ? "D / H4" :
  2958. sourceTF == "D" ? "H4 / H1" :
  2959. sourceTF == "240" or sourceTF == "180" or sourceTF == "120" ? "H1 / 15M" :
  2960. sourceTF == "60" ? "15M / 5M" :
  2961. sourceTF == "30" ? "5M / 3M" :
  2962. "5M / 3M / 2M / 1M"
  2963.  
  2964. // v20.2 Narrative Candidate State Tracker.
  2965. // Makes every fresh narrative transition visible:
  2966. // WAIT ID -> CANDIDATE ID -> VALIDATING score -> CONFIRMED/RE-ARMED
  2967. // or -> REJECTED ID (permanent).
  2968. string dashboardFreshValidation =
  2969. executionChildMode ?
  2970. (not inheritedFreshNarrative ? "WAIT FRESH PARENT ID" :
  2971. inheritedFreshValidationConfirmed ?
  2972. "CONFIRMED #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • " +
  2973. str.tostring(inheritedFreshValidationScoreRaw) + "/4 • " +
  2974. (inheritedFreshDirectionRaw == 1 ? "BULLISH" : "BEARISH") :
  2975. inheritedFreshValidationRejected ?
  2976. "REJECTED #" + str.tostring(inheritedRejectedNarrativeIDRaw) + " • PERMANENT" :
  2977. "CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) +
  2978. " • VALIDATING " + str.tostring(inheritedFreshValidationScoreRaw) + "/4") :
  2979. not hasFreshNarrativeIdentity ? "WAIT FRESH ID" :
  2980. freshValidationConfirmed ?
  2981. "CONFIRMED #" + str.tostring(latestQualifiedNarrativeID) + " • " +
  2982. str.tostring(freshValidationScore) + "/4 • " +
  2983. (latestNarrativeDirection == 1 ? "BULLISH" : "BEARISH") :
  2984. freshValidationRejected ?
  2985. "REJECTED #" + str.tostring(latestRejectedNarrativeID) + " • PERMANENT" :
  2986. "CANDIDATE #" + str.tostring(latestQualifiedNarrativeID) +
  2987. " • VALIDATING " + str.tostring(freshValidationScore) + "/4"
  2988.  
  2989. string dashboardNarrativeMemory =
  2990. executionChildMode ?
  2991. (inheritedFreshValidationPending ?
  2992. "CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • AGE " + str.tostring(inheritedFreshNarrativeAgeRaw) :
  2993. inheritedNarrativeFreshRaw ?
  2994. "FRESH #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • AGE " + str.tostring(inheritedFreshNarrativeAgeRaw) :
  2995. inheritedFreshValidationRejected ?
  2996. "REJECTED #" + str.tostring(inheritedRejectedNarrativeIDRaw) + " • WAIT NEWER ID" :
  2997. inheritedFreshNarrative ?
  2998. "ACTIVE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) :
  2999. inheritedTargetReachedRaw or inheritedInvalidRaw or inheritedExpiredRaw ?
  3000. "RESET #" + str.tostring(inheritedTerminalNarrativeIDRaw) + " • WAIT NEXT ID" :
  3001. inheritedQualifiedNarrativeIDRaw > 0 ?
  3002. "CURRENT #" + str.tostring(inheritedQualifiedNarrativeIDRaw) :
  3003. "NO NARRATIVE ID") :
  3004. freshValidationState == 1 and hasFreshNarrativeIdentity ?
  3005. "CANDIDATE #" + str.tostring(latestQualifiedNarrativeID) + " • AGE " + str.tostring(freshNarrativeAge) :
  3006. localNarrativeFresh ?
  3007. "FRESH #" + str.tostring(latestQualifiedNarrativeID) + " • AGE " + str.tostring(freshNarrativeAge) :
  3008. freshValidationRejected ?
  3009. "REJECTED #" + str.tostring(latestRejectedNarrativeID) + " • WAIT NEWER ID" :
  3010. hasFreshNarrativeIdentity and crtLifecycleActive ?
  3011. "ACTIVE #" + str.tostring(latestQualifiedNarrativeID) :
  3012. tradeTargetReached or tradeInvalid or tradeExpired ?
  3013. "RESET #" + str.tostring(latestTerminalNarrativeID) + " • WAIT NEXT ID" :
  3014. latestQualifiedNarrativeID > 0 ?
  3015. "CURRENT #" + str.tostring(latestQualifiedNarrativeID) :
  3016. "NO NARRATIVE ID"
  3017.  
  3018. string dashboardNarrativeState =
  3019. executionChildMode ?
  3020. (inheritedFreshNarrative and inheritedFreshValidationPending ?
  3021. "CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • PARENT VALIDATING" :
  3022. inheritedFreshNarrative and inheritedFreshValidationRejected ?
  3023. "REJECTED #" + str.tostring(inheritedRejectedNarrativeIDRaw) + " • WAIT NEWER PARENT" :
  3024. inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ?
  3025. "RE-ARMED #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • PARENT CONFIRMED" :
  3026. inheritedTargetReachedRaw ? "STAND DOWN • PARENT TARGET DONE" :
  3027. inheritedInvalidRaw or inheritedExpiredRaw ? "RESET • WAIT NEW PARENT CRT" :
  3028. htfBiasInheritanceLock ? "ARMED • PARENT STORY ACTIVE" :
  3029. "WAIT NEW PARENT NARRATIVE") :
  3030. hasFreshNarrativeIdentity and freshValidationState == 1 ?
  3031. "CANDIDATE #" + str.tostring(latestQualifiedNarrativeID) + " • VALIDATING" :
  3032. hasFreshNarrativeIdentity and freshValidationState == 3 ?
  3033. "REJECTED #" + str.tostring(latestRejectedNarrativeID) + " • WAIT NEWER ID" :
  3034. localNarrativeRearmed ?
  3035. "RE-ARMED #" + str.tostring(latestQualifiedNarrativeID) + " • FRESH CONFIRMED" :
  3036. tradeTargetReached ? "STAND DOWN • TARGET DONE" :
  3037. tradeInvalid or tradeExpired ? "RESET • WAIT NEW CRT" :
  3038. crtLifecycleActive or tradeReversalActive ? "ARMED • NARRATIVE ACTIVE" :
  3039. "WAIT NEW NARRATIVE"
  3040.  
  3041. string dashboardHTFStory =
  3042. executionChildMode ? inheritedParentStory :
  3043. tradeReversalActive ? dashboardCRTState + " → " + dashboardFailure :
  3044. tradeTargetReached ? dashboardCRTState + " → OBJECTIVE DONE" :
  3045. tradeInvalid ? dashboardCRTState + " → RESET" :
  3046. tradeExpired ? "CRT EXPIRED → RESET" :
  3047. crtLifecycleActive ? dashboardCRTState + " → " + dashboardDelivery :
  3048. "WAIT QUALIFIED HTF CRT"
  3049.  
  3050. string dashboardNextTF =
  3051. executionChildMode ? timeframe.period + " LOCAL EXECUTION" :
  3052. tradeInvalid or tradeExpired ? selectedHTF :
  3053. f_nextExecutionTF(selectedHTF)
  3054.  
  3055. string dashboardHunt =
  3056. executionChildMode ?
  3057. (inheritedFreshNarrative and inheritedFreshValidationPending ? "WAIT PARENT VALIDATION" :
  3058. inheritedFreshNarrative and inheritedFreshValidationRejected ? "WAIT NEXT PARENT CRT" :
  3059. inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? "ALIGNED CRT CONTEXT" :
  3060. inheritedTargetReachedRaw ? "WAIT NEW PARENT CRT" :
  3061. inheritedInvalidRaw or inheritedExpiredRaw ? "WAIT NEW PARENT CRT" :
  3062. htfBiasInheritanceLock ?
  3063. (displayExecutionDirection == 1 ? "BULLISH LTF CRT" : "BEARISH LTF CRT") :
  3064. "WAIT PARENT STORY") :
  3065. hasFreshNarrativeIdentity and freshValidationState == 1 ? "WAIT VALIDATION" :
  3066. hasFreshNarrativeIdentity and freshValidationState == 3 ? "WAIT NEXT QUALIFIED CRT" :
  3067. localNarrativeRearmed ? "ALIGNED CRT CONTEXT" :
  3068. tradeReversalActive ?
  3069. (executionDirection == 1 ? "BULLISH LTF CRT" : "BEARISH LTF CRT") :
  3070. tradeTargetReached ? "WAIT NEW PARENT CRT" :
  3071. tradeInvalid or tradeExpired ? "WAIT NEW QUALIFIED CRT" :
  3072. tradeReady or tradeWatch ?
  3073. (executionDirection == 1 ? "ALIGNED BULLISH CRT" : executionDirection == -1 ? "ALIGNED BEARISH CRT" : "ALIGNED LTF CRT") :
  3074. "HTF RANGE + PURGE"
  3075.  
  3076. string dashboardExecutionState =
  3077. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationPending ? "LOCKED • VALIDATING PARENT" :
  3078. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationRejected ? "LOCKED • PARENT REJECTED" :
  3079. executionChildMode and inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? "RE-ARMED • SCANNING NEW STORY" :
  3080. executionChildMode and inheritedTargetReachedRaw ? "LOCKED • PARENT OBJECTIVE DONE" :
  3081. executionChildMode and (inheritedInvalidRaw or inheritedExpiredRaw) ? "LOCKED • WAIT PARENT CRT" :
  3082. htfBiasInheritanceLock and (inheritedOpposingLocalCRT or localStoryOpposed) ? "OPPOSED • IGNORE" :
  3083. htfBiasInheritanceLock and (inheritedAlignedLocalCRT or localStoryAligned) ? "CONFIRMED" :
  3084. qualifiedLTFStructure ? "CONFIRMED" :
  3085. structureEngineUnlocked ? "UNLOCKED • SCANNING" :
  3086. executionTimeframeAllowed and not insideDistributionWindow ? "LOCKED • WAIT WINDOW" :
  3087. tradeTargetReached ? "LOCKED • OBJECTIVE DONE" :
  3088. tradeInvalid or tradeExpired ? "LOCKED • WAIT NEW CRT" :
  3089. tradeReversalActive or crtLifecycleActive ? "LOCKED • MOVE TO LTF" :
  3090. "LOCKED"
  3091.  
  3092. color dashboardExecutionStateColor =
  3093. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationPending ? color.new(color.orange, 62) :
  3094. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationRejected ? color.new(color.red, 58) :
  3095. executionChildMode and inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? color.new(color.green, 58) :
  3096. executionChildMode and inheritedTargetReachedRaw ? color.new(color.green, 72) :
  3097. executionChildMode and (inheritedInvalidRaw or inheritedExpiredRaw) ? color.new(color.gray, 72) :
  3098. htfBiasInheritanceLock and (inheritedOpposingLocalCRT or localStoryOpposed) ? color.new(color.red, 58) :
  3099. htfBiasInheritanceLock and (inheritedAlignedLocalCRT or localStoryAligned) ? color.new(color.green, 58) :
  3100. qualifiedLTFStructure ? color.new(color.green, 58) :
  3101. structureEngineUnlocked ? color.new(color.orange, 62) :
  3102. color.new(color.gray, 78)
  3103.  
  3104.  
  3105. string dashboardGrade = f_gradeText(latestCRTGradeCode)
  3106.  
  3107. string dashboardVerdict =
  3108. executionChildMode ?
  3109. (htfBiasInheritanceLock ?
  3110. (localStoryOpposed or inheritedOpposingLocalCRT ?
  3111. inheritedParentStory + " • LOCAL STORY OPPOSED • IGNORE" :
  3112. localStoryAligned or inheritedAlignedLocalCRT ?
  3113. inheritedParentStory + " • LTF ALIGNED • CONFIRM RISK" :
  3114. inheritedParentStory + " • WAIT ALIGNED LTF CRT") :
  3115. inheritedTargetReachedRaw ? inheritedParentStory + " • NO CHASE" :
  3116. inheritedInvalidRaw ? inheritedParentStory + " • WAIT NEW PARENT CRT" :
  3117. inheritedExpiredRaw ? inheritedParentStory + " • WAIT NEW PARENT CRT" :
  3118. inheritedParentStory) :
  3119. tradeTargetReached ?
  3120. localLifecycleText + " • OBJECTIVE DELIVERED • NO CHASE" :
  3121. tradeReversalActive ?
  3122. localLifecycleText + " • " + dashboardFailure + " • WAIT LTF CONFIRMATION" :
  3123. tradeInvalid ?
  3124. localLifecycleText + " • WAIT NEW CRT" :
  3125. tradeExpired ?
  3126. "CRT EXPIRED • WAIT NEW QUALIFIED CRT" :
  3127. localLifecycleText == "WAITING" ?
  3128. "WAITING FOR QUALIFIED CRT" :
  3129. dashboardGrade + " " + localLifecycleText + " • " +
  3130. (dashboardDelivery == "CONFIRMED" ? "DELIVERY CONFIRMED" : "WAIT FOR DELIVERY") +
  3131. (dashboardTarget != "NONE" ? " • DRAW " + dashboardTarget : "")
  3132.  
  3133. var table intelligenceDashboard = table.new(
  3134. f_dashboardPosition(dashboardPosition),
  3135. 2,
  3136. 27,
  3137. border_width = 1
  3138. )
  3139.  
  3140. if barstate.islast
  3141. if showIntelligenceDashboard
  3142. table.clear(intelligenceDashboard, 0, 0, 1, 26)
  3143. color headerBg = color.new(color.rgb(25, 25, 35), 5)
  3144. color labelBg = color.new(color.rgb(40, 40, 50), 15)
  3145. color verdictBg = color.new(color.rgb(20, 20, 30), 0)
  3146. color actionLabelBg = color.new(color.rgb(20, 20, 30), 0)
  3147. string marketTF = syminfo.ticker + " • " + timeframe.period
  3148. string txtSize = f_dashboardTextSize(dashboardTextSize)
  3149.  
  3150. table.cell(intelligenceDashboard, 0, 0, "ASH CRT INTELLIGENCE", bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3151. table.cell(intelligenceDashboard, 1, 0, marketTF, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3152.  
  3153. table.cell(intelligenceDashboard, 0, 1, "TRADE STATUS", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3154. table.cell(intelligenceDashboard, 1, 1, displayTradeStatus, bgcolor = f_tradeStatusColor(displayTradeStatus, displayExecutionDirection), text_color = color.white, text_size = txtSize)
  3155.  
  3156. table.cell(intelligenceDashboard, 0, 2, "HTF STORY", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3157. table.cell(intelligenceDashboard, 1, 2, dashboardHTFStory, bgcolor = displayExecutionDirection == 1 ? color.new(color.green, 72) : displayExecutionDirection == -1 ? color.new(color.red, 72) : f_stateColor(dashboardCRTState), text_color = color.white, text_size = txtSize)
  3158.  
  3159. table.cell(intelligenceDashboard, 0, 3, "NEXT TF", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3160. table.cell(intelligenceDashboard, 1, 3, dashboardNextTF, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3161.  
  3162. table.cell(intelligenceDashboard, 0, 4, "HUNT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3163. table.cell(intelligenceDashboard, 1, 4, dashboardHunt, bgcolor = displayExecutionDirection == 1 ? color.new(color.green, 72) : displayExecutionDirection == -1 ? color.new(color.red, 72) : headerBg, text_color = color.white, text_size = txtSize)
  3164.  
  3165. table.cell(intelligenceDashboard, 0, 5, "EXECUTION", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3166. table.cell(intelligenceDashboard, 1, 5, dashboardExecutionState, bgcolor = dashboardExecutionStateColor, text_color = color.white, text_size = txtSize)
  3167.  
  3168. table.cell(intelligenceDashboard, 0, 6, "EXECUTION BIAS", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3169. table.cell(intelligenceDashboard, 1, 6, displayExecutionBias, bgcolor = displayExecutionDirection == 1 ? color.new(color.green, 72) : displayExecutionDirection == -1 ? color.new(color.red, 72) : color.new(color.gray, 82), text_color = color.white, text_size = txtSize)
  3170.  
  3171. table.cell(intelligenceDashboard, 0, 7, "ENTRY CONDITION", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3172. table.cell(intelligenceDashboard, 1, 7, displayEntryCondition, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3173.  
  3174. table.cell(intelligenceDashboard, 0, 8, "RISK STATE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3175. table.cell(intelligenceDashboard, 1, 8, displayRiskState, bgcolor = executionChildMode and inheritedTargetReachedRaw ? color.new(color.green, 72) : executionChildMode and inheritedInvalidRaw ? color.new(color.red, 72) : tradeInvalid ? color.new(color.red, 72) : tradeTargetReached ? color.new(color.green, 72) : headerBg, text_color = color.white, text_size = txtSize)
  3176.  
  3177. table.cell(intelligenceDashboard, 0, 9, "SETUP AGE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3178. table.cell(intelligenceDashboard, 1, 9, displaySetupAge, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3179.  
  3180. table.cell(intelligenceDashboard, 0, 10, executionChildMode ? "LOCAL CRT" : "CRT STATE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3181. table.cell(intelligenceDashboard, 1, 10, executionChildMode ? dashboardLocalCRT : dashboardCRTState, bgcolor = f_stateColor(executionChildMode ? dashboardLocalImplication : dashboardCRTState), text_color = color.white, text_size = txtSize)
  3182.  
  3183. table.cell(intelligenceDashboard, 0, 11, "GRADE / SCORE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3184. table.cell(intelligenceDashboard, 1, 11, dashboardGrade + " • " + str.tostring(latestCRTIntelligenceScore) + "/10", bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3185.  
  3186. table.cell(intelligenceDashboard, 0, 12, "HTF CONTEXT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3187. table.cell(intelligenceDashboard, 1, 12, dashboardHTF, bgcolor = f_stateColor(dashboardHTF), text_color = color.white, text_size = txtSize)
  3188.  
  3189. table.cell(intelligenceDashboard, 0, 13, "KEY LEVEL / POI", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3190. table.cell(intelligenceDashboard, 1, 13, dashboardPOI, bgcolor = f_stateColor(dashboardPOI), text_color = color.white, text_size = txtSize)
  3191.  
  3192. table.cell(intelligenceDashboard, 0, 14, "LIQUIDITY PURGE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3193. table.cell(intelligenceDashboard, 1, 14, dashboardPurge, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3194.  
  3195. table.cell(intelligenceDashboard, 0, 15, "SMT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3196. table.cell(intelligenceDashboard, 1, 15, dashboardSMT, bgcolor = f_stateColor(dashboardSMT), text_color = color.white, text_size = txtSize)
  3197.  
  3198. table.cell(intelligenceDashboard, 0, 16, "NESTED CRT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3199. table.cell(intelligenceDashboard, 1, 16, dashboardNested, bgcolor = f_stateColor(dashboardNested), text_color = color.white, text_size = txtSize)
  3200.  
  3201. table.cell(intelligenceDashboard, 0, 17, htfBiasInheritanceLock ? "LOCAL IMPLICATION" : "DELIVERY", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3202. table.cell(intelligenceDashboard, 1, 17, executionChildMode ? dashboardLocalImplication : dashboardDelivery, bgcolor = f_stateColor(executionChildMode ? dashboardLocalImplication : dashboardDelivery), text_color = color.white, text_size = txtSize)
  3203.  
  3204. table.cell(intelligenceDashboard, 0, 18, "DRAW ON LIQUIDITY", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3205. table.cell(intelligenceDashboard, 1, 18, dashboardTarget, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3206.  
  3207. table.cell(intelligenceDashboard, 0, 19, "TARGET STATUS", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3208. table.cell(intelligenceDashboard, 1, 19, dashboardTargetStatus, bgcolor = f_stateColor(dashboardTargetStatus), text_color = color.white, text_size = txtSize)
  3209.  
  3210. table.cell(intelligenceDashboard, 0, 20, htfBiasInheritanceLock ? "HTF ALIGNMENT" : "FAILURE CONTEXT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3211. table.cell(intelligenceDashboard, 1, 20, executionChildMode ? dashboardHTFAlignment : dashboardFailure, bgcolor = f_stateColor(executionChildMode ? dashboardHTFAlignment : dashboardFailure), text_color = color.white, text_size = txtSize)
  3212.  
  3213. table.cell(intelligenceDashboard, 0, 21, htfBiasInheritanceLock ? "ACTION" : "ENGINE VERDICT", bgcolor = verdictBg, text_color = color.white, text_size = txtSize)
  3214. table.cell(intelligenceDashboard, 1, 21, executionChildMode ? dashboardAction : dashboardVerdict, bgcolor = verdictBg, text_color = color.white, text_size = txtSize)
  3215.  
  3216. table.cell(intelligenceDashboard, 0, 22, "KEY LEVEL TF", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3217. table.cell(intelligenceDashboard, 1, 22, dashboardKeyLevelTF, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3218.  
  3219. table.cell(intelligenceDashboard, 0, 23, "KEY LEVEL ENGINE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3220. table.cell(intelligenceDashboard, 1, 23, latestKeyLevelType != 0 ? "TYPE CONFIRMED" : "NONE", bgcolor = latestKeyLevelType != 0 ? color.new(color.green, 72) : color.new(color.gray, 82), text_color = color.white, text_size = txtSize)
  3221.  
  3222. table.cell(intelligenceDashboard, 0, 24, "NARRATIVE ENGINE", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3223. table.cell(intelligenceDashboard, 1, 24, dashboardNarrativeState, bgcolor = str.contains(dashboardNarrativeState, "REJECTED") ? color.new(color.red, 58) : str.contains(dashboardNarrativeState, "CANDIDATE") ? color.new(color.orange, 58) : str.contains(dashboardNarrativeState, "RE-ARMED") or str.contains(dashboardNarrativeState, "ARMED") ? color.new(color.green, 65) : str.contains(dashboardNarrativeState, "STAND DOWN") ? color.new(color.orange, 65) : color.new(color.gray, 78), text_color = color.white, text_size = txtSize)
  3224.  
  3225. table.cell(intelligenceDashboard, 0, 25, "NARRATIVE MEMORY", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3226. table.cell(intelligenceDashboard, 1, 25, dashboardNarrativeMemory, bgcolor = str.contains(dashboardNarrativeMemory, "REJECTED") ? color.new(color.red, 58) : str.contains(dashboardNarrativeMemory, "CANDIDATE") ? color.new(color.orange, 58) : str.contains(dashboardNarrativeMemory, "FRESH") ? color.new(color.green, 58) : str.contains(dashboardNarrativeMemory, "RESET") ? color.new(color.orange, 65) : color.new(color.gray, 78), text_color = color.white, text_size = txtSize)
  3227.  
  3228. table.cell(intelligenceDashboard, 0, 26, "FRESH VALIDATION", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3229. table.cell(intelligenceDashboard, 1, 26, dashboardFreshValidation, bgcolor = str.contains(dashboardFreshValidation, "CONFIRMED") ? color.new(color.green, 58) : str.contains(dashboardFreshValidation, "REJECTED") ? color.new(color.red, 58) : str.contains(dashboardFreshValidation, "VALIDATING") ? color.new(color.orange, 62) : color.new(color.gray, 78), text_color = color.white, text_size = txtSize)
  3230. else
  3231. table.clear(intelligenceDashboard, 0, 0, 1, 24)
  3232.  
  3233. //======================================================================
  3234. // 15. ALERTS
  3235. //======================================================================
  3236. bool narrativeRearmSignal =
  3237. executionChildMode ? inheritedNarrativeRearmedRaw : localNarrativeRearmed
  3238.  
  3239. alertcondition(
  3240. narrativeRearmSignal and not narrativeRearmSignal[1],
  3241. "Ash CRT — Narrative Re-Armed",
  3242. "A genuinely newer qualified parent CRT created a fresh bullish or bearish narrative on {{ticker}} {{interval}}. Execution is re-armed; wait for aligned lower-timeframe confirmation."
  3243. )
  3244.  
  3245. alertcondition(
  3246. tradeReady and not tradeReady[1],
  3247. "Ash CRT — Trade Status READY",
  3248. "CRT Trade Readiness Engine changed to READY on {{ticker}} {{interval}}. Confirm execution and risk before entry."
  3249. )
  3250.  
  3251. alertcondition(
  3252. tradeReversalActive and not tradeReversalActive[1],
  3253. "Ash CRT — Reversal Context Active",
  3254. "CRT failure created an opposite-direction reversal context on {{ticker}} {{interval}}. Wait for aligned lower-timeframe CRT confirmation."
  3255. )
  3256.  
  3257. alertcondition(
  3258. tradeInvalid and not tradeInvalid[1],
  3259. "Ash CRT — Trade Status INVALID",
  3260. "The tracked CRT trade state changed to INVALID on {{ticker}} {{interval}}."
  3261. )
  3262.  
  3263. alertcondition(
  3264. tradeTargetReached and not tradeTargetReached[1],
  3265. "Ash CRT — Trade Status TARGET REACHED",
  3266. "The tracked CRT trade state changed to TARGET REACHED on {{ticker}} {{interval}}. Avoid chasing completed delivery."
  3267. )
  3268.  
  3269. alertcondition(
  3270. gradeAPlusCRT,
  3271. "Ash CRT — A+ Intelligence Grade",
  3272. "A+ CRT intelligence grade confirmed on {{ticker}} {{interval}}."
  3273. )
  3274.  
  3275. alertcondition(
  3276. gradeACRT,
  3277. "Ash CRT — A Intelligence Grade",
  3278. "A-grade CRT intelligence setup confirmed on {{ticker}} {{interval}}."
  3279. )
  3280.  
  3281.  
  3282. alertcondition(
  3283. newDrawTargetReached,
  3284. "Ash CRT — Draw on Liquidity Target Reached",
  3285. "The active CRT reached its selected draw-on-liquidity target on {{ticker}} {{interval}}."
  3286. )
  3287.  
  3288.  
  3289. alertcondition(
  3290. failedCRTEvent and failedCRTReversalDirection == 1,
  3291. "Ash CRT — Failed Bearish CRT / Bullish Reversal Context",
  3292. "A qualified bearish CRT failed through its manipulated-side boundary. Bullish reversal context detected on {{ticker}} {{interval}}."
  3293. )
  3294.  
  3295. alertcondition(
  3296. failedCRTEvent and failedCRTReversalDirection == -1,
  3297. "Ash CRT — Failed Bullish CRT / Bearish Reversal Context",
  3298. "A qualified bullish CRT failed through its manipulated-side boundary. Bearish reversal context detected on {{ticker}} {{interval}}."
  3299. )
  3300.  
  3301.  
  3302. alertcondition(
  3303. meaningfulDeliveryContext and not meaningfulDeliveryContext[1],
  3304. "Ash CRT — Displacement Delivery Confirmed",
  3305. "Post-manipulation displacement and directional delivery confirmed on {{ticker}} {{interval}}."
  3306. )
  3307.  
  3308.  
  3309. alertcondition(
  3310. qualifiedCRT and meaningfulLiquidityPurge,
  3311. "Ash CRT — Qualified CRT with Meaningful Liquidity Purge",
  3312. "Qualified CRT also purged meaningful external liquidity on {{ticker}} {{interval}}."
  3313. )
  3314.  
  3315. alertcondition(
  3316. qualifiedCRT and meaningfulNestedContext,
  3317. "Ash CRT — Qualified CRT Nested in Active HTF Context",
  3318. "Qualified CRT is nested or aligned inside an active parent-timeframe CRT context on {{ticker}} {{interval}}."
  3319. )
  3320.  
  3321.  
  3322. alertcondition(
  3323. bullishManipulation,
  3324. "Ash CRT — Qualified Bullish Manipulation",
  3325. "Qualified bullish CRT manipulation confirmed on {{ticker}} {{interval}}. Range low was purged."
  3326. )
  3327.  
  3328. alertcondition(
  3329. bearishManipulation,
  3330. "Ash CRT — Qualified Bearish Manipulation",
  3331. "Qualified bearish CRT manipulation confirmed on {{ticker}} {{interval}}. Range high was purged."
  3332. )
  3333.  
  3334.  
  3335. alertcondition(
  3336. crtTargetReached and not crtTargetReached[1],
  3337. "Ash CRT — Opposite-Side Target Reached",
  3338. "The active CRT reached its opposite-side Range target on {{ticker}} {{interval}}."
  3339. )
  3340.  
  3341. alertcondition(
  3342. crtInvalidated and not crtInvalidated[1],
  3343. "Ash CRT — Active CRT Invalidated",
  3344. "The active CRT was invalidated through its manipulated-side boundary on {{ticker}} {{interval}}."
  3345. )
  3346.  
  3347. alertcondition(
  3348. crtExpired and not crtExpired[1],
  3349. "Ash CRT — Active CRT Expired",
  3350. "The active CRT expired before opposite-side delivery on {{ticker}} {{interval}}."
  3351. )
  3352.  
  3353.  
  3354. alertcondition(
  3355. bullishSMT and not bullishSMT[1],
  3356. "Ash CRT — Bullish SMT Detected",
  3357. "Bullish SMT divergence detected between {{ticker}} and the configured comparison market on {{interval}}."
  3358. )
  3359.  
  3360. alertcondition(
  3361. bearishSMT and not bearishSMT[1],
  3362. "Ash CRT — Bearish SMT Detected",
  3363. "Bearish SMT divergence detected between {{ticker}} and the configured comparison market on {{interval}}."
  3364. )
  3365.  
  3366. alertcondition(
  3367. bullishLTFStructure,
  3368. "Ash CRT — Bullish LTF Structure Confirmed",
  3369. "Bullish lower-timeframe CRT structure confirmed inside the qualified HTF Distribution window on {{ticker}} {{interval}}."
  3370. )
  3371.  
  3372. alertcondition(
  3373. bearishLTFStructure,
  3374. "Ash CRT — Bearish LTF Structure Confirmed",
  3375. "Bearish lower-timeframe CRT structure confirmed inside the qualified HTF Distribution window on {{ticker}} {{interval}}."
  3376. )
  3377.  
  3378.  
Add Comment
Please, Sign In to add comment