AshICT

"Ash ICT CRT — Protocol Engine v20.9.2 Visual History"

Jul 11th, 2026
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 186.84 KB | None | 0 0
  1. //@version=6
  2. indicator(
  3. title = "Ash ICT CRT — Protocol Engine v20.9.2 Visual History",
  4. shorttitle = "Ash CRT Protocol v20.9.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. // v20.3 Narrative Delivery & Objective Tracker
  236. enableNarrativeObjectiveTracker = input.bool(
  237. true,
  238. "Enable Narrative Delivery & Objective Tracker",
  239. group = groupLifecycle,
  240. tooltip = "Tracks whether the active fresh narrative is validating, delivering, approaching its objective, completed, invalidated, expired, or permanently rejected."
  241. )
  242.  
  243. objectiveNearThresholdATR = input.float(
  244. 0.25,
  245. "Objective Near Threshold (ATR)",
  246. minval = 0.0,
  247. step = 0.05,
  248. group = groupLifecycle,
  249. tooltip = "The objective is labelled NEAR when price is within this ATR distance of the selected draw-on-liquidity target."
  250. )
  251.  
  252. // Directional POI context controls
  253. poiLookback = input.int(
  254. 80,
  255. "POI Detection Lookback",
  256. minval = 10,
  257. maxval = 300,
  258. group = groupProtocol
  259. )
  260.  
  261. poiToleranceATR = input.float(
  262. 0.05,
  263. "POI Touch Tolerance (ATR)",
  264. minval = 0.0,
  265. step = 0.01,
  266. group = groupProtocol
  267. )
  268.  
  269. minimumPOITypes = input.int(
  270. 1,
  271. "Minimum Aligned POI Types Required",
  272. minval = 1,
  273. maxval = 5,
  274. group = groupProtocol
  275. )
  276.  
  277. minimumDirectionalPOIScore = input.int(
  278. 2,
  279. "Minimum Directional POI Score",
  280. minval = 1,
  281. maxval = 10,
  282. group = groupProtocol,
  283. tooltip = "FVG/Order Block = 2 points. IFVG/Breaker/Rejection Block = 3 points."
  284. )
  285.  
  286. rejectOpposingPOIDominance = input.bool(
  287. true,
  288. "Reject Opposing POI Dominance",
  289. group = groupProtocol
  290. )
  291.  
  292. useFVGPOI = input.bool(true, "Include Fair Value Gaps", group = groupProtocol)
  293. useIFVGPOI = input.bool(true, "Include Inverse FVGs", group = groupProtocol)
  294. useOrderBlockPOI = input.bool(true, "Include Order Blocks", group = groupProtocol)
  295. useBreakerPOI = input.bool(true, "Include Breaker Blocks", group = groupProtocol)
  296. useRejectionBlockPOI = input.bool(true, "Include Rejection Blocks", group = groupProtocol)
  297.  
  298. keyLevelToleranceATR = input.float(
  299. 0.10,
  300. "Key-Level Touch Tolerance (ATR)",
  301. minval = 0.0,
  302. step = 0.01,
  303. group = groupProtocol
  304. )
  305.  
  306. minimumRejectionPercent = input.float(
  307. 35.0,
  308. "Minimum Manipulation Rejection Wick %",
  309. minval = 0.0,
  310. maxval = 100.0,
  311. step = 1.0,
  312. group = groupProtocol
  313. )
  314.  
  315. requireMidpointReclaim = input.bool(
  316. true,
  317. "Require Range Midpoint Reclaim",
  318. group = groupProtocol
  319. )
  320.  
  321. atrLength = input.int(
  322. 20,
  323. "ATR Length",
  324. minval = 1,
  325. group = groupProtocol
  326. )
  327.  
  328. minimumRangeATR = input.float(
  329. 0.4,
  330. "Minimum Range Size (ATR)",
  331. minval = 0.0,
  332. step = 0.1,
  333. group = groupProtocol
  334. )
  335.  
  336. maximumRangeATR = input.float(
  337. 2.0,
  338. "Maximum Range Size (ATR)",
  339. minval = 0.1,
  340. step = 0.1,
  341. group = groupProtocol
  342. )
  343.  
  344. minimumRangeBodyPercent = input.float(
  345. 20.0,
  346. "Minimum Range Body %",
  347. minval = 0.0,
  348. maxval = 100.0,
  349. step = 1.0,
  350. group = groupProtocol
  351. )
  352.  
  353. maximumRangeBodyPercent = input.float(
  354. 80.0,
  355. "Maximum Range Body %",
  356. minval = 0.0,
  357. maxval = 100.0,
  358. step = 1.0,
  359. group = groupProtocol
  360. )
  361.  
  362. string groupLiquidity = "Liquidity Purge Context"
  363.  
  364. useLiquidityPurgeContext = input.bool(
  365. true,
  366. "Protocol 10 — Meaningful Liquidity Purge Context",
  367. group = groupLiquidity,
  368. tooltip = "Bonus context only. It does not reject or hide any CRT that qualified under the stable v16.7 engine."
  369. )
  370.  
  371. liquiditySwingLookback = input.int(
  372. 20,
  373. "Swing Liquidity Lookback",
  374. minval = 3,
  375. maxval = 200,
  376. group = groupLiquidity
  377. )
  378.  
  379. liquidityToleranceATR = input.float(
  380. 0.05,
  381. "Liquidity Equality Tolerance (ATR)",
  382. minval = 0.0,
  383. step = 0.01,
  384. group = groupLiquidity
  385. )
  386.  
  387. minimumLiquidityPurgeScore = input.int(
  388. 1,
  389. "Meaningful Purge Score Threshold",
  390. minval = 1,
  391. maxval = 6,
  392. group = groupLiquidity,
  393. tooltip = "Previous day = 1, previous week = 2, previous month = 3, established swing liquidity = 1."
  394. )
  395.  
  396. string groupNested = "CRT Sequence / Nested HTF Context"
  397.  
  398. useNestedCRTContext = input.bool(
  399. true,
  400. "Protocol 11 — Nested HTF CRT Context",
  401. group = groupNested,
  402. 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."
  403. )
  404.  
  405. requireFullParentContainment = input.bool(
  406. false,
  407. "Require Full Containment for Nested State",
  408. group = groupNested,
  409. tooltip = "Off: overlap with the active parent CRT range qualifies. On: the complete local Range candle must sit inside the parent CRT range."
  410. )
  411.  
  412. useParentPremiumDiscount = input.bool(
  413. true,
  414. "Score Parent Premium / Discount Location",
  415. group = groupNested,
  416. tooltip = "Bullish nested CRTs score when formed in the lower half of the parent range. Bearish nested CRTs score in the upper half."
  417. )
  418.  
  419. minimumNestedContextScore = input.int(
  420. 2,
  421. "Meaningful Nested Context Score",
  422. minval = 1,
  423. maxval = 3,
  424. group = groupNested,
  425. tooltip = "Inside/overlap = 1, direction aligned = 1, correct premium/discount location = 1."
  426. )
  427.  
  428. string groupDelivery = "Displacement / Delivery Confirmation"
  429.  
  430. useDeliveryContext = input.bool(
  431. true,
  432. "Protocol 12 — Displacement and Delivery Confirmation",
  433. group = groupDelivery,
  434. tooltip = "Bonus confirmation only. Evaluates post-manipulation delivery without hiding CRTs qualified by the stable v17.1 engine."
  435. )
  436.  
  437. deliveryWindowBars = input.int(
  438. 3,
  439. "Delivery Confirmation Window (Bars)",
  440. minval = 1,
  441. maxval = 6,
  442. group = groupDelivery
  443. )
  444.  
  445. minimumDeliveryBodyATR = input.float(
  446. 0.50,
  447. "Minimum Displacement Body (ATR)",
  448. minval = 0.0,
  449. step = 0.05,
  450. group = groupDelivery
  451. )
  452.  
  453. requireDeliveryFVG = input.bool(
  454. false,
  455. "Require FVG Creation for Delivery Bonus",
  456. group = groupDelivery
  457. )
  458.  
  459. minimumDeliveryScore = input.int(
  460. 2,
  461. "Meaningful Delivery Score",
  462. minval = 1,
  463. maxval = 4,
  464. group = groupDelivery,
  465. tooltip = "Directional close = 1, strong ATR body = 1, range-mid delivery = 1, FVG creation = 1."
  466. )
  467.  
  468. string groupFailure = "Failed CRT / Reversal Context"
  469.  
  470. useFailedCRTContext = input.bool(
  471. true,
  472. "Protocol 13 — Failed CRT / Reversal Context",
  473. group = groupFailure,
  474. 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."
  475. )
  476.  
  477. failureRequiresClose = input.bool(
  478. true,
  479. "Failure Requires Close Through Boundary",
  480. group = groupFailure
  481. )
  482.  
  483. failureWindowBars = input.int(
  484. 6,
  485. "Failure Detection Window (Bars)",
  486. minval = 1,
  487. maxval = 30,
  488. group = groupFailure
  489. )
  490.  
  491. requireFailureDirectionalClose = input.bool(
  492. true,
  493. "Require Failure Candle Direction",
  494. group = groupFailure,
  495. tooltip = "Bullish CRT failure candle must close bearish; bearish CRT failure candle must close bullish."
  496. )
  497.  
  498. minimumFailureBodyATR = input.float(
  499. 0.25,
  500. "Minimum Failure Body (ATR)",
  501. minval = 0.0,
  502. step = 0.05,
  503. group = groupFailure
  504. )
  505.  
  506. string groupTarget = "CRT Target Delivery / Draw on Liquidity"
  507.  
  508. useTargetDeliveryContext = input.bool(
  509. true,
  510. "Protocol 14 — Target Delivery / Draw on Liquidity",
  511. group = groupTarget,
  512. 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."
  513. )
  514.  
  515. includeOppositeCRTRangeBoundary = input.bool(
  516. true,
  517. "Include Opposite CRT Range Boundary",
  518. group = groupTarget
  519. )
  520.  
  521. includePreviousDayTarget = input.bool(
  522. true,
  523. "Include Previous Day Liquidity",
  524. group = groupTarget
  525. )
  526.  
  527. includePreviousWeekTarget = input.bool(
  528. true,
  529. "Include Previous Week Liquidity",
  530. group = groupTarget
  531. )
  532.  
  533. includePreviousMonthTarget = input.bool(
  534. true,
  535. "Include Previous Month Liquidity",
  536. group = groupTarget
  537. )
  538.  
  539. includeSwingLiquidityTarget = input.bool(
  540. true,
  541. "Include Swing Liquidity",
  542. group = groupTarget
  543. )
  544.  
  545. targetSwingLookback = input.int(
  546. 20,
  547. "Target Swing Lookback",
  548. minval = 3,
  549. maxval = 200,
  550. group = groupTarget
  551. )
  552.  
  553. targetReachToleranceATR = input.float(
  554. 0.05,
  555. "Target Reach Tolerance (ATR)",
  556. minval = 0.0,
  557. step = 0.01,
  558. group = groupTarget
  559. )
  560.  
  561. string groupGrade = "CRT Intelligence Grade Engine"
  562.  
  563. useIntelligenceGrade = input.bool(
  564. true,
  565. "CRT Intelligence Grade Engine",
  566. group = groupGrade,
  567. 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."
  568. )
  569.  
  570. gradeAPlusThreshold = input.int(
  571. 8,
  572. "A+ Minimum Intelligence Score",
  573. minval = 1,
  574. maxval = 10,
  575. group = groupGrade
  576. )
  577.  
  578. gradeAThreshold = input.int(
  579. 6,
  580. "A Minimum Intelligence Score",
  581. minval = 1,
  582. maxval = 10,
  583. group = groupGrade
  584. )
  585.  
  586. gradeBThreshold = input.int(
  587. 4,
  588. "B Minimum Intelligence Score",
  589. minval = 1,
  590. maxval = 10,
  591. group = groupGrade
  592. )
  593.  
  594. string groupDashboard = "CRT Intelligence Dashboard"
  595.  
  596. showIntelligenceDashboard = input.bool(
  597. true,
  598. "Show CRT Intelligence Dashboard",
  599. group = groupDashboard
  600. )
  601.  
  602. dashboardPosition = input.string(
  603. "Top Right",
  604. "Dashboard Position",
  605. options = ["Top Right", "Top Left", "Bottom Right", "Bottom Left"],
  606. group = groupDashboard
  607. )
  608.  
  609. dashboardTextSize = input.string(
  610. "Small",
  611. "Dashboard Text Size",
  612. options = ["Tiny", "Small", "Normal"],
  613. group = groupDashboard
  614. )
  615.  
  616. string groupKeyLevel = "Dedicated ICT Key Level Engine"
  617.  
  618. useDedicatedKeyLevelEngine = input.bool(
  619. true,
  620. "Enable Dedicated ICT Key Level Engine",
  621. group = groupKeyLevel,
  622. tooltip = "Detects the dominant FVG, IFVG, Order Block, Breaker, or Rejection Block interacting with the latest CRT Range on the selected source timeframe."
  623. )
  624.  
  625. keyLevelLookback = input.int(
  626. 80,
  627. "Key Level Detection Lookback",
  628. minval = 10,
  629. maxval = 300,
  630. group = groupKeyLevel
  631. )
  632.  
  633. keyLevelTypeToleranceATR = input.float(
  634. 0.05,
  635. "Key Level Zone Tolerance (ATR)",
  636. minval = 0.0,
  637. step = 0.01,
  638. group = groupKeyLevel
  639. )
  640.  
  641. string groupSMT = "SMT / Multi-Asset Matrix"
  642.  
  643. useSMTProtocol = input.bool(
  644. true,
  645. "Protocol 9 — Multi-Asset SMT Matrix",
  646. group = groupSMT,
  647. tooltip = "Checks the candidate CRT against up to two correlated or inversely correlated comparison markets."
  648. )
  649.  
  650. smtMode = input.string(
  651. "Auto Matrix",
  652. "SMT Comparison Mode",
  653. options = ["Auto Matrix", "Manual"],
  654. group = groupSMT
  655. )
  656.  
  657. manualSMTSymbol1 = input.symbol(
  658. "CME_MINI:NQ1!",
  659. "Manual Comparison Symbol 1",
  660. group = groupSMT
  661. )
  662.  
  663. manualSMTRelation1 = input.string(
  664. "Direct",
  665. "Manual Symbol 1 Relation",
  666. options = ["Direct", "Inverse"],
  667. group = groupSMT
  668. )
  669.  
  670. manualSMTSymbol2 = input.symbol(
  671. "CBOT_MINI:YM1!",
  672. "Manual Comparison Symbol 2",
  673. group = groupSMT
  674. )
  675.  
  676. manualSMTRelation2 = input.string(
  677. "Direct",
  678. "Manual Symbol 2 Relation",
  679. options = ["Direct", "Inverse"],
  680. group = groupSMT
  681. )
  682.  
  683. useSecondSMTMarket = input.bool(
  684. true,
  685. "Use Second SMT Market",
  686. group = groupSMT
  687. )
  688.  
  689. smtLookback = input.int(
  690. 20,
  691. "SMT Swing Lookback",
  692. minval = 2,
  693. maxval = 200,
  694. group = groupSMT
  695. )
  696.  
  697. smtToleranceATR = input.float(
  698. 0.05,
  699. "SMT Equality Tolerance (ATR)",
  700. minval = 0.0,
  701. step = 0.01,
  702. group = groupSMT
  703. )
  704.  
  705. minimumSMTConfirmations = input.int(
  706. 1,
  707. "Minimum Aligned SMT Confirmations",
  708. minval = 1,
  709. maxval = 2,
  710. group = groupSMT,
  711. tooltip = "One aligned comparison is enough by default. Set to 2 for stricter multi-market confirmation."
  712. )
  713.  
  714. allowNeutralSMT = input.bool(
  715. true,
  716. "Allow Neutral SMT",
  717. group = groupSMT
  718. )
  719.  
  720. rejectOpposingSMT = input.bool(
  721. false,
  722. "Reject Strong Opposing SMT",
  723. group = groupSMT,
  724. tooltip = "Rejects a CRT when opposing SMT confirmations outnumber aligned SMT confirmations."
  725. )
  726.  
  727. //======================================================================
  728. // 3. VISUAL SETTINGS
  729. //======================================================================
  730. groupVisual = "3. Visual Settings"
  731.  
  732. colorCandles = input.bool(true, "Color Qualified CRT Candles on Source Timeframe", group = groupVisual)
  733. rangeColor = input.color(color.rgb(35, 125, 225), "Range Candle Color", group = groupVisual)
  734. manipulationColor = input.color(color.rgb(255, 195, 0), "Manipulation Candle Color", group = groupVisual)
  735.  
  736. // v20.9.2 visual-history controls. These settings change chart visibility only.
  737. // All CRT detection, narrative memory, validation, objectives, and alerts continue
  738. // calculating from the full available history in the background.
  739. crtVisualHistoryMode = input.string(
  740. "Current Week",
  741. "CRT Candle Visual History",
  742. options = ["All History", "Current Week", "Last N Chart Candles"],
  743. group = groupVisual,
  744. tooltip = "All History shows every historical coloured CRT. Current Week shows only CRTs belonging to the latest chart week. Last N Chart Candles limits colours to the most recent number of candles on the chart timeframe. This does not change detection or alerts."
  745. )
  746.  
  747. crtVisualRecentBars = input.int(
  748. 4,
  749. "CRT — Last N Chart Candles",
  750. minval = 2,
  751. maxval = 5000,
  752. group = groupVisual,
  753. tooltip = "Used only when CRT Candle Visual History is set to Last N Chart Candles. Example: 4 on a 1H chart means the latest four 1H candles."
  754. )
  755.  
  756. //======================================================================
  757. // 4. MULTI-HTF HIERARCHY + AUTO AMD WINDOWS
  758. //======================================================================
  759. groupProjection = "4. Multi-HTF Hierarchy + AMD Windows"
  760.  
  761. enableHTFProjection = input.bool(
  762. true,
  763. "Show Selected HTF AMD Windows on Lower Timeframes",
  764. group = groupProjection
  765. )
  766.  
  767. hierarchyContext = input.string(
  768. "Auto",
  769. "HTF Context Mode",
  770. options = ["Auto", "Monthly", "Weekly", "Daily", "H4", "H3", "H2", "H1", "30m"],
  771. group = groupProjection,
  772. 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."
  773. )
  774.  
  775. lowerTFProjectionContext = input.string(
  776. "H4",
  777. "Lower-TF Projection Context",
  778. options = ["Monthly", "Weekly", "Daily", "H4", "H3", "H2", "H1", "30m"],
  779. group = groupProjection,
  780. tooltip = "Used only when HTF Context Mode is Auto and the chart timeframe is below 30 minutes."
  781. )
  782.  
  783. f_contextToTF(string context) =>
  784. context == "Monthly" ? "M" :
  785. context == "Weekly" ? "W" :
  786. context == "Daily" ? "D" :
  787. context == "H3" ? "180" :
  788. context == "H2" ? "120" :
  789. context == "H1" ? "60" :
  790. context == "30m" ? "30" : "240"
  791.  
  792. int currentChartSeconds = timeframe.in_seconds(timeframe.period)
  793.  
  794. string autoSelectedHTF =
  795. timeframe.ismonthly ? "M" :
  796. timeframe.isweekly ? "W" :
  797. timeframe.isdaily ? "D" :
  798. not na(currentChartSeconds) and currentChartSeconds >= 14400 ? "240" :
  799. not na(currentChartSeconds) and currentChartSeconds >= 10800 ? "180" :
  800. not na(currentChartSeconds) and currentChartSeconds >= 7200 ? "120" :
  801. not na(currentChartSeconds) and currentChartSeconds >= 3600 ? "60" :
  802. not na(currentChartSeconds) and currentChartSeconds >= 1800 ? "30" :
  803. f_contextToTF(lowerTFProjectionContext)
  804.  
  805. string selectedHTF = hierarchyContext == "Auto" ? autoSelectedHTF : f_contextToTF(hierarchyContext)
  806.  
  807. // Clean-chart mode: no automatic AMD vertical separators or phase labels.
  808. // The selected HTF structure is still tracked internally for LTF unlock logic.
  809.  
  810.  
  811. //======================================================================
  812. // 5. EXECUTION UNLOCK ENGINE
  813. //======================================================================
  814. groupExecution = "5. Execution Unlock Engine"
  815.  
  816. enableExecutionEngine = input.bool(
  817. true,
  818. "Enable LTF Execution Scanner",
  819. group = groupExecution,
  820. tooltip = "After the selected HTF manipulation closes, scan only its Distribution window for aligned lower-timeframe CRT structure."
  821. )
  822.  
  823. maximumExecutionMinutes = input.int(
  824. 15,
  825. "Maximum Execution Chart Timeframe (Minutes)",
  826. minval = 1,
  827. maxval = 60,
  828. group = groupExecution,
  829. tooltip = "Example: 15 allows the scanner on 15m, 5m, 3m, 2m and 1m charts."
  830. )
  831.  
  832. firstExecutionOnly = input.bool(
  833. true,
  834. "Show First Entry Only per HTF Setup",
  835. group = groupExecution
  836. )
  837.  
  838. colorUnlockedLTFStructure = input.bool(
  839. true,
  840. "Color Unlocked LTF Range + Manipulation",
  841. group = groupExecution,
  842. tooltip = "Inside the confirmed HTF Distribution window, color only aligned lower-timeframe CRT structure: blue Range candle and yellow Manipulation candle."
  843. )
  844.  
  845. showRawCRTForTesting = input.bool(
  846. false,
  847. "TEST — Show Raw CRT Without Protocol Filters",
  848. group = groupExecution,
  849. tooltip = "Diagnostic only. Shows every valid close-back-inside CRT before protocol filtering."
  850. )
  851.  
  852. localRequireCloseInside = input.bool(
  853. true,
  854. "LTF Manipulation Must Close Inside Local Range",
  855. group = groupExecution
  856. )
  857.  
  858. localRequireMidpoint = input.bool(
  859. true,
  860. "LTF Manipulation Must Reclaim Local Midpoint",
  861. group = groupExecution
  862. )
  863.  
  864. localMinimumRejection = input.float(
  865. 25.0,
  866. "Minimum LTF Rejection Wick %",
  867. minval = 0.0,
  868. maxval = 100.0,
  869. step = 1.0,
  870. group = groupExecution
  871. )
  872.  
  873. ltfRangeColor = input.color(color.rgb(35, 125, 225), "Unlocked LTF Range Color", group = groupExecution)
  874. ltfManipulationColor = input.color(color.rgb(255, 195, 0), "Unlocked LTF Manipulation Color", group = groupExecution)
  875.  
  876. // v20.7 Execution Authorization Engine (core logic retained unchanged in v20.9.2)
  877. enableExecutionAuthorizationEngine = input.bool(
  878. true,
  879. "Enable One-Shot Execution Authorization",
  880. group = groupExecution,
  881. tooltip = "After a parent narrative is active, authorizes one aligned qualified LTF CRT per parent narrative ID. This is permission guidance only; it does not place orders."
  882. )
  883.  
  884. authorizationRequireLiquidityOrPOI = input.bool(
  885. true,
  886. "Authorization Requires Liquidity Purge or Key-Level Reaction",
  887. group = groupExecution,
  888. tooltip = "The aligned LTF CRT must also confirm a meaningful liquidity purge or a directional FVG/IFVG, order block, breaker, rejection block, or tracked external level."
  889. )
  890.  
  891. authorizationRequireObjectiveRoom = input.bool(
  892. true,
  893. "Authorization Requires Room to Parent Objective",
  894. group = groupExecution,
  895. tooltip = "Blocks authorization when the parent objective is already behind price, unavailable, completed, or too close to justify chasing."
  896. )
  897.  
  898. authorizationMinimumRoomATR = input.float(
  899. 0.50,
  900. "Minimum Room to Parent Objective (LTF ATR)",
  901. minval = 0.0,
  902. maxval = 10.0,
  903. step = 0.05,
  904. group = groupExecution,
  905. tooltip = "Minimum remaining distance from current price to the parent objective, measured with the execution-chart ATR."
  906. )
  907.  
  908. authorizationRequireDistributionWindow = input.bool(
  909. false,
  910. "Authorization Requires Active HTF Distribution Window",
  911. group = groupExecution,
  912. tooltip = "Optional strict mode. When enabled, authorization is allowed only inside the existing projected HTF Distribution window."
  913. )
  914.  
  915. //======================================================================
  916. // 6. FORWARD-TEST ALERT ENGINE
  917. //======================================================================
  918. string groupForwardAlerts = "6. Forward-Test Alert Engine"
  919.  
  920. enableForwardTestAlerts = input.bool(
  921. true,
  922. "Enable Forward-Test Runtime Alerts",
  923. group = groupForwardAlerts,
  924. tooltip = "Uses Pine alert() calls so the execution milestones can be monitored without consuming additional plot slots. Create one TradingView alert using: Any alert() function call."
  925. )
  926.  
  927. alertParentConfirmed = input.bool(true, "Alert — Parent Narrative Confirmed 4/4", group = groupForwardAlerts)
  928. alertExecutionArmed = input.bool(true, "Alert — Execution Armed", group = groupForwardAlerts)
  929. alertEntryConfirmed = input.bool(true, "Alert — Entry Confirmed", group = groupForwardAlerts)
  930. alertDeliveryNoReentry = input.bool(true, "Alert — Delivery / No Re-Entry", group = groupForwardAlerts)
  931. alertParentObjectiveCompleted = input.bool(true, "Alert — Parent Objective Completed", group = groupForwardAlerts)
  932. alertParentRejectedInvalidated = input.bool(true, "Alert — Parent Rejected / Invalidated / Expired", group = groupForwardAlerts)
  933. alertNoChase = input.bool(true, "Alert — No Chase / Objective Too Near", group = groupForwardAlerts)
  934.  
  935. //======================================================================
  936. // 7. ASH ICT FRACTAL
  937. //======================================================================
  938. string groupFractal = "7. Ash ICT Fractal"
  939.  
  940. showAshICTFractal = input.bool(
  941. true,
  942. "Show Ash ICT Fractal",
  943. group = groupFractal,
  944. tooltip = "Displays the original clean Ash ICT Fractal markers on every chart timeframe. Signals are confirmed only after the required right-side candles close."
  945. )
  946.  
  947. ashICTFractalPeriods = input.int(
  948. 2,
  949. "Fractal Period",
  950. minval = 1,
  951. maxval = 10,
  952. group = groupFractal,
  953. tooltip = "Original default is 2 candles on each side of the centre candle."
  954. )
  955.  
  956. ashICTFractalUseHighLow = input.bool(
  957. true,
  958. "Use High/Low",
  959. group = groupFractal,
  960. tooltip = "On: fractals use candle wicks. Off: fractals use candle body highs and lows."
  961. )
  962.  
  963. showAshICTFractalHigh = input.bool(true, "Show Fractal High", group = groupFractal)
  964. showAshICTFractalLow = input.bool(true, "Show Fractal Low", group = groupFractal)
  965. ashICTFractalHighColor = input.color(color.rgb(170, 170, 0), "Fractal High Color", group = groupFractal)
  966. ashICTFractalLowColor = input.color(color.rgb(180, 0, 120), "Fractal Low Color", group = groupFractal)
  967.  
  968. ashICTFractalHistoryMode = input.string(
  969. "Current Week",
  970. "Fractal Visual History",
  971. options = ["All History", "Current Week", "Last N Chart Candles"],
  972. group = groupFractal,
  973. tooltip = "Controls only how many Ash ICT Fractal markers remain visible. The fractal calculations themselves are unchanged."
  974. )
  975.  
  976. ashICTFractalRecentBars = input.int(
  977. 50,
  978. "Fractal — Last N Chart Candles",
  979. minval = 2,
  980. maxval = 5000,
  981. group = groupFractal,
  982. tooltip = "Used only when Fractal Visual History is set to Last N Chart Candles. Set this to 3 or 4 for an extremely clean chart, or use a larger number such as 50 for more swing context."
  983. )
  984.  
  985. //======================================================================
  986. // 8. HELPERS — AUTO MARKET TIME PROTOCOL
  987. //======================================================================
  988. // Returns true when a visual belongs to the selected display window.
  989. // `last_bar_time` and `last_bar_index` anchor the filter to the latest bar
  990. // loaded on the chart, which also keeps the filter useful on closed markets.
  991. f_visualHistoryPass(string mode, int recentBars, int targetBarIndex, int targetTime) =>
  992. bool validTarget = not na(targetTime) and targetBarIndex >= 0
  993. bool inLatestChartWeek =
  994. validTarget and
  995. year(targetTime, timezoneInput) == year(last_bar_time, timezoneInput) and
  996. weekofyear(targetTime, timezoneInput) == weekofyear(last_bar_time, timezoneInput)
  997. bool inRecentChartBars =
  998. validTarget and
  999. targetBarIndex >= math.max(last_bar_index - recentBars + 1, 0)
  1000. mode == "All History" or
  1001. (mode == "Current Week" and inLatestChartWeek) or
  1002. (mode == "Last N Chart Candles" and inRecentChartBars)
  1003.  
  1004. f_hourDistance(int a, int b) =>
  1005. int directDistance = math.abs(a - b)
  1006. math.min(directDistance, 24 - directDistance)
  1007.  
  1008. f_hourMatches(int candleHour, int modelHour) =>
  1009. f_hourDistance(candleHour, modelHour) <= timeMatchToleranceHours
  1010.  
  1011. f_autoMarketProfile() =>
  1012. string tickerUpper = str.upper(syminfo.ticker)
  1013. string rootUpper = str.upper(syminfo.root)
  1014. bool indexKeyword =
  1015. str.contains(tickerUpper, "US100") or
  1016. str.contains(tickerUpper, "NAS") or
  1017. str.contains(tickerUpper, "SPX") or
  1018. str.contains(tickerUpper, "US500") or
  1019. str.contains(tickerUpper, "DJI") or
  1020. str.contains(tickerUpper, "DAX") or
  1021. str.contains(tickerUpper, "FTSE")
  1022. bool commodityKeyword =
  1023. str.contains(tickerUpper, "XAU") or
  1024. str.contains(tickerUpper, "XAG") or
  1025. str.contains(rootUpper, "CL") or
  1026. str.contains(rootUpper, "MCL") or
  1027. str.contains(rootUpper, "GC") or
  1028. str.contains(rootUpper, "SI") or
  1029. str.contains(tickerUpper, "OIL")
  1030. syminfo.type == "forex" ? "Forex" :
  1031. syminfo.type == "crypto" ? "Crypto" :
  1032. commodityKeyword ? "Commodities" :
  1033. 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") :
  1034. syminfo.type == "index" or indexKeyword ? "Indices" :
  1035. "Manual"
  1036.  
  1037. f_selectedMarketProfile() =>
  1038. marketTimeProfile == "Auto" ? f_autoMarketProfile() : marketTimeProfile
  1039.  
  1040. f_profileHours(string profile) =>
  1041. int h1 =
  1042. profile == "Forex" ? forexHour1 :
  1043. profile == "Indices" ? indicesHour1 :
  1044. profile == "Futures" ? futuresHour1 :
  1045. profile == "Crypto" ? cryptoHour1 :
  1046. profile == "Commodities" ? commoditiesHour1 : manualHour1
  1047. int h2 =
  1048. profile == "Forex" ? forexHour2 :
  1049. profile == "Indices" ? indicesHour2 :
  1050. profile == "Futures" ? futuresHour2 :
  1051. profile == "Crypto" ? cryptoHour2 :
  1052. profile == "Commodities" ? commoditiesHour2 : manualHour2
  1053. int h3 =
  1054. profile == "Forex" ? forexHour3 :
  1055. profile == "Indices" ? indicesHour3 :
  1056. profile == "Futures" ? futuresHour3 :
  1057. profile == "Crypto" ? cryptoHour3 :
  1058. profile == "Commodities" ? commoditiesHour3 : manualHour3
  1059. [h1, h2, h3]
  1060.  
  1061. isAllowedRangeHour(int candleTime) =>
  1062. bool higherCalendarTF = timeframe.isdaily or timeframe.isweekly or timeframe.ismonthly
  1063. string activeProfile = f_selectedMarketProfile()
  1064. [modelHour1, modelHour2, modelHour3] = f_profileHours(activeProfile)
  1065. int candleHour = hour(candleTime, timezoneInput)
  1066. not useSelectedHours or higherCalendarTF or
  1067. f_hourMatches(candleHour, modelHour1) or
  1068. f_hourMatches(candleHour, modelHour2) or
  1069. f_hourMatches(candleHour, modelHour3)
  1070.  
  1071. isNearLevel(float candleHigh, float candleLow, float level, float tolerance) =>
  1072. not na(level) and candleHigh >= level - tolerance and candleLow <= level + tolerance
  1073.  
  1074.  
  1075. rangeOverlapsZone(float candleHigh, float candleLow, float zoneHigh, float zoneLow, float tolerance) =>
  1076. not na(zoneHigh) and not na(zoneLow) and candleHigh >= zoneLow - tolerance and candleLow <= zoneHigh + tolerance
  1077.  
  1078. // Directional POI Confluence Engine v2. No zones are drawn.
  1079. // Scores are weighted by POI quality and kept directional.
  1080. f_detectDirectionalPOIs(float testHigh, float testLow, float tolerance) =>
  1081. bool bullFVGTouch = false
  1082. bool bearFVGTouch = false
  1083. bool bullIFVGTouch = false
  1084. bool bearIFVGTouch = false
  1085. bool bullOBTouch = false
  1086. bool bearOBTouch = false
  1087. bool bullBreakerTouch = false
  1088. bool bearBreakerTouch = false
  1089. bool bullRBTouch = false
  1090. bool bearRBTouch = false
  1091.  
  1092. int maxBack = math.min(poiLookback, bar_index > 10 ? bar_index - 5 : 0)
  1093. if maxBack >= 4
  1094. for k = 2 to maxBack
  1095. bool bullFVG = low[k] > high[k + 2]
  1096. bool bearFVG = high[k] < low[k + 2]
  1097. float bullFVGHigh = low[k]
  1098. float bullFVGLow = high[k + 2]
  1099. float bearFVGHigh = low[k + 2]
  1100. float bearFVGLow = high[k]
  1101. bullFVGTouch := bullFVGTouch or (bullFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance))
  1102. bearFVGTouch := bearFVGTouch or (bearFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance))
  1103.  
  1104. // An invalidated bearish FVG reclaimed upward acts as bullish IFVG.
  1105. // An invalidated bullish FVG reclaimed downward acts as bearish IFVG.
  1106. bool bullishIFVG = bearFVG and close[k - 1] > bearFVGHigh
  1107. bool bearishIFVG = bullFVG and close[k - 1] < bullFVGLow
  1108. bullIFVGTouch := bullIFVGTouch or (bullishIFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance))
  1109. bearIFVGTouch := bearIFVGTouch or (bearishIFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance))
  1110.  
  1111. bool bullishDisplacement = close[k] > high[k + 1] and close[k] > open[k]
  1112. bool bearishDisplacement = close[k] < low[k + 1] and close[k] < open[k]
  1113. bool bullishOB = bullishDisplacement and close[k + 1] < open[k + 1]
  1114. bool bearishOB = bearishDisplacement and close[k + 1] > open[k + 1]
  1115. bullOBTouch := bullOBTouch or (bullishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  1116. bearOBTouch := bearOBTouch or (bearishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  1117.  
  1118. bool bullishBreaker = close[k + 1] < open[k + 1] and close[k] > high[k + 1]
  1119. bool bearishBreaker = close[k + 1] > open[k + 1] and close[k] < low[k + 1]
  1120. bullBreakerTouch := bullBreakerTouch or (bullishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  1121. bearBreakerTouch := bearBreakerTouch or (bearishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance))
  1122.  
  1123. float candleRangeK = math.max(high[k] - low[k], syminfo.mintick)
  1124. float lowerWickPctK = (math.min(open[k], close[k]) - low[k]) / candleRangeK * 100.0
  1125. float upperWickPctK = (high[k] - math.max(open[k], close[k])) / candleRangeK * 100.0
  1126. bool bullishRB = lowerWickPctK >= 50.0
  1127. bool bearishRB = upperWickPctK >= 50.0
  1128. float bullRBHigh = math.min(open[k], close[k])
  1129. float bullRBLow = low[k]
  1130. float bearRBHigh = high[k]
  1131. float bearRBLow = math.max(open[k], close[k])
  1132. bullRBTouch := bullRBTouch or (bullishRB and rangeOverlapsZone(testHigh, testLow, bullRBHigh, bullRBLow, tolerance))
  1133. bearRBTouch := bearRBTouch or (bearishRB and rangeOverlapsZone(testHigh, testLow, bearRBHigh, bearRBLow, tolerance))
  1134.  
  1135. int bullTypes =
  1136. (useFVGPOI and bullFVGTouch ? 1 : 0) +
  1137. (useIFVGPOI and bullIFVGTouch ? 1 : 0) +
  1138. (useOrderBlockPOI and bullOBTouch ? 1 : 0) +
  1139. (useBreakerPOI and bullBreakerTouch ? 1 : 0) +
  1140. (useRejectionBlockPOI and bullRBTouch ? 1 : 0)
  1141.  
  1142. int bearTypes =
  1143. (useFVGPOI and bearFVGTouch ? 1 : 0) +
  1144. (useIFVGPOI and bearIFVGTouch ? 1 : 0) +
  1145. (useOrderBlockPOI and bearOBTouch ? 1 : 0) +
  1146. (useBreakerPOI and bearBreakerTouch ? 1 : 0) +
  1147. (useRejectionBlockPOI and bearRBTouch ? 1 : 0)
  1148.  
  1149. int bullScore =
  1150. (useFVGPOI and bullFVGTouch ? 2 : 0) +
  1151. (useIFVGPOI and bullIFVGTouch ? 3 : 0) +
  1152. (useOrderBlockPOI and bullOBTouch ? 2 : 0) +
  1153. (useBreakerPOI and bullBreakerTouch ? 3 : 0) +
  1154. (useRejectionBlockPOI and bullRBTouch ? 3 : 0)
  1155.  
  1156. int bearScore =
  1157. (useFVGPOI and bearFVGTouch ? 2 : 0) +
  1158. (useIFVGPOI and bearIFVGTouch ? 3 : 0) +
  1159. (useOrderBlockPOI and bearOBTouch ? 2 : 0) +
  1160. (useBreakerPOI and bearBreakerTouch ? 3 : 0) +
  1161. (useRejectionBlockPOI and bearRBTouch ? 3 : 0)
  1162.  
  1163. [bullTypes, bearTypes, bullScore, bearScore]
  1164.  
  1165. //======================================================================
  1166. // 6A. DEDICATED ICT KEY LEVEL TYPE ENGINE
  1167. // Runs in the selected source-timeframe context.
  1168. // Type codes: 0=None, 1=FVG, 2=IFVG, 3=Order Block,
  1169. // 4=Breaker, 5=Rejection Block.
  1170. //======================================================================
  1171. f_keyLevelTypeForRange(float testHigh, float testLow, float tolerance) =>
  1172. int bullishType = 0
  1173. int bearishType = 0
  1174. int bullishWeight = 0
  1175. int bearishWeight = 0
  1176.  
  1177. int maxBack = math.min(keyLevelLookback, bar_index > 10 ? bar_index - 5 : 0)
  1178.  
  1179. if maxBack >= 4
  1180. for k = 2 to maxBack
  1181. bool bullFVG = low[k] > high[k + 2]
  1182. bool bearFVG = high[k] < low[k + 2]
  1183.  
  1184. float bullFVGHigh = low[k]
  1185. float bullFVGLow = high[k + 2]
  1186. float bearFVGHigh = low[k + 2]
  1187. float bearFVGLow = high[k]
  1188.  
  1189. bool bullFVGTouch = bullFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance)
  1190. bool bearFVGTouch = bearFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance)
  1191.  
  1192. bool bullishIFVG = bearFVG and close[k - 1] > bearFVGHigh
  1193. bool bearishIFVG = bullFVG and close[k - 1] < bullFVGLow
  1194.  
  1195. bool bullIFVGTouch = bullishIFVG and rangeOverlapsZone(testHigh, testLow, bearFVGHigh, bearFVGLow, tolerance)
  1196. bool bearIFVGTouch = bearishIFVG and rangeOverlapsZone(testHigh, testLow, bullFVGHigh, bullFVGLow, tolerance)
  1197.  
  1198. bool bullishDisplacement = close[k] > high[k + 1] and close[k] > open[k]
  1199. bool bearishDisplacement = close[k] < low[k + 1] and close[k] < open[k]
  1200. bool bullishOB = bullishDisplacement and close[k + 1] < open[k + 1]
  1201. bool bearishOB = bearishDisplacement and close[k + 1] > open[k + 1]
  1202.  
  1203. bool bullOBTouch = bullishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1204. bool bearOBTouch = bearishOB and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1205.  
  1206. bool bullishBreaker = close[k + 1] < open[k + 1] and close[k] > high[k + 1]
  1207. bool bearishBreaker = close[k + 1] > open[k + 1] and close[k] < low[k + 1]
  1208.  
  1209. bool bullBreakerTouch = bullishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1210. bool bearBreakerTouch = bearishBreaker and rangeOverlapsZone(testHigh, testLow, high[k + 1], low[k + 1], tolerance)
  1211.  
  1212. float candleRangeK = math.max(high[k] - low[k], syminfo.mintick)
  1213. float lowerWickPctK = (math.min(open[k], close[k]) - low[k]) / candleRangeK * 100.0
  1214. float upperWickPctK = (high[k] - math.max(open[k], close[k])) / candleRangeK * 100.0
  1215.  
  1216. bool bullishRB = lowerWickPctK >= 50.0
  1217. bool bearishRB = upperWickPctK >= 50.0
  1218.  
  1219. float bullRBHigh = math.min(open[k], close[k])
  1220. float bullRBLow = low[k]
  1221. float bearRBHigh = high[k]
  1222. float bearRBLow = math.max(open[k], close[k])
  1223.  
  1224. bool bullRBTouch = bullishRB and rangeOverlapsZone(testHigh, testLow, bullRBHigh, bullRBLow, tolerance)
  1225. bool bearRBTouch = bearishRB and rangeOverlapsZone(testHigh, testLow, bearRBHigh, bearRBLow, tolerance)
  1226.  
  1227. if bullFVGTouch and bullishWeight < 2
  1228. bullishType := 1
  1229. bullishWeight := 2
  1230. if bearFVGTouch and bearishWeight < 2
  1231. bearishType := 1
  1232. bearishWeight := 2
  1233.  
  1234. if bullOBTouch and bullishWeight < 2
  1235. bullishType := 3
  1236. bullishWeight := 2
  1237. if bearOBTouch and bearishWeight < 2
  1238. bearishType := 3
  1239. bearishWeight := 2
  1240.  
  1241. if bullIFVGTouch and bullishWeight < 3
  1242. bullishType := 2
  1243. bullishWeight := 3
  1244. if bearIFVGTouch and bearishWeight < 3
  1245. bearishType := 2
  1246. bearishWeight := 3
  1247.  
  1248. if bullBreakerTouch and bullishWeight < 3
  1249. bullishType := 4
  1250. bullishWeight := 3
  1251. if bearBreakerTouch and bearishWeight < 3
  1252. bearishType := 4
  1253. bearishWeight := 3
  1254.  
  1255. if bullRBTouch and bullishWeight < 3
  1256. bullishType := 5
  1257. bullishWeight := 3
  1258. if bearRBTouch and bearishWeight < 3
  1259. bearishType := 5
  1260. bearishWeight := 3
  1261.  
  1262. [bullishType, bearishType, bullishWeight, bearishWeight]
  1263.  
  1264. f_sourceTFKeyLevelState() =>
  1265. float sourceRangeHigh = high[1]
  1266. float sourceRangeLow = low[1]
  1267. float sourceATR = ta.atr(14)
  1268. float sourceTolerance = sourceATR[1] * keyLevelTypeToleranceATR
  1269. [bullType, bearType, bullWeight, bearWeight] = f_keyLevelTypeForRange(sourceRangeHigh, sourceRangeLow, sourceTolerance)
  1270.  
  1271. bool sourceSweptHigh = high > sourceRangeHigh
  1272. bool sourceSweptLow = low < sourceRangeLow
  1273. bool sourceSingleSweep = sourceSweptHigh != sourceSweptLow
  1274. bool sourceClosedInside = close < sourceRangeHigh and close > sourceRangeLow
  1275. bool sourceBase =
  1276. barstate.isconfirmed and
  1277. sourceSingleSweep and
  1278. (not rejectDoubleSweep or not (sourceSweptHigh and sourceSweptLow)) and
  1279. (not requireCloseInside or sourceClosedInside)
  1280.  
  1281. int sourceDirection =
  1282. sourceBase and sourceSweptLow and not sourceSweptHigh ? 1 :
  1283. sourceBase and sourceSweptHigh and not sourceSweptLow ? -1 : 0
  1284.  
  1285. int alignedType =
  1286. sourceDirection == 1 ? bullType :
  1287. sourceDirection == -1 ? bearType : 0
  1288.  
  1289. int opposingType =
  1290. sourceDirection == 1 ? bearType :
  1291. sourceDirection == -1 ? bullType : 0
  1292.  
  1293. int alignedWeight =
  1294. sourceDirection == 1 ? bullWeight :
  1295. sourceDirection == -1 ? bearWeight : 0
  1296.  
  1297. [sourceDirection, alignedType, opposingType, alignedWeight]
  1298.  
  1299. [sourceKeyDirection, sourceKeyLevelType, sourceOpposingKeyLevelType, sourceKeyLevelWeight] =
  1300. request.security(
  1301. syminfo.tickerid,
  1302. selectedHTF,
  1303. f_sourceTFKeyLevelState(),
  1304. gaps = barmerge.gaps_off,
  1305. lookahead = barmerge.lookahead_off
  1306. )
  1307.  
  1308. //======================================================================
  1309. // 7. MULTI-ASSET SMT MATRIX
  1310. // CME, Forex, Crypto, Metals and Energy.
  1311. // v16.7 uses verified exchange prefixes and spot crypto comparison feeds.
  1312. // Relation code: 1 = direct correlation, -1 = inverse correlation.
  1313. //======================================================================
  1314. f_autoSMTSymbol1() =>
  1315. string t = str.upper(syminfo.ticker)
  1316. string r = str.upper(syminfo.root)
  1317.  
  1318. bool es = r == "ES" or str.contains(t, "US500") or str.contains(t, "SPX")
  1319. bool nq = r == "NQ" or str.contains(t, "US100") or str.contains(t, "NAS100")
  1320. bool ym = r == "YM" or str.contains(t, "US30")
  1321. bool rty = r == "RTY"
  1322.  
  1323. bool eurusd = str.contains(t, "EURUSD")
  1324. bool gbpusd = str.contains(t, "GBPUSD")
  1325. bool audusd = str.contains(t, "AUDUSD")
  1326. bool nzdusd = str.contains(t, "NZDUSD")
  1327. bool usdchf = str.contains(t, "USDCHF")
  1328. bool usdcad = str.contains(t, "USDCAD")
  1329. bool usdjpy = str.contains(t, "USDJPY")
  1330. bool eurjpy = str.contains(t, "EURJPY")
  1331. bool gbpjpy = str.contains(t, "GBPJPY")
  1332. bool audjpy = str.contains(t, "AUDJPY")
  1333. bool nzdjpy = str.contains(t, "NZDJPY")
  1334.  
  1335. bool btc = str.contains(t, "BTC")
  1336. bool eth = str.contains(t, "ETH")
  1337. bool sol = str.contains(t, "SOL")
  1338.  
  1339. bool gold = str.contains(t, "XAU") or r == "GC"
  1340. bool silver = str.contains(t, "XAG") or r == "SI"
  1341. bool wti = r == "CL" or str.contains(t, "USOIL") or str.contains(t, "WTI")
  1342. bool brent = r == "BRN" or str.contains(t, "UKOIL") or str.contains(t, "BRENT")
  1343.  
  1344. es ? "CME_MINI:NQ1!" :
  1345. nq ? "CME_MINI:ES1!" :
  1346. ym ? "CME_MINI:ES1!" :
  1347. rty ? "CME_MINI:ES1!" :
  1348. eurusd ? "OANDA:GBPUSD" :
  1349. gbpusd ? "OANDA:EURUSD" :
  1350. audusd ? "OANDA:NZDUSD" :
  1351. nzdusd ? "OANDA:AUDUSD" :
  1352. usdchf ? "TVC:DXY" :
  1353. usdcad ? "TVC:DXY" :
  1354. usdjpy ? "TVC:DXY" :
  1355. eurjpy ? "OANDA:GBPJPY" :
  1356. gbpjpy ? "OANDA:EURJPY" :
  1357. audjpy ? "OANDA:NZDJPY" :
  1358. nzdjpy ? "OANDA:AUDJPY" :
  1359. btc ? "BINANCE:ETHUSDT" :
  1360. eth ? "BINANCE:BTCUSDT" :
  1361. sol ? "BINANCE:BTCUSDT" :
  1362. gold ? "COMEX:SI1!" :
  1363. silver ? "COMEX:GC1!" :
  1364. wti ? "TVC:UKOIL" :
  1365. brent ? "NYMEX:CL1!" :
  1366. manualSMTSymbol1
  1367.  
  1368. f_autoSMTRelation1() =>
  1369. string t = str.upper(syminfo.ticker)
  1370. bool usdchf = str.contains(t, "USDCHF")
  1371. usdchf ? -1 : 1
  1372.  
  1373. f_autoSMTSymbol2() =>
  1374. string t = str.upper(syminfo.ticker)
  1375. string r = str.upper(syminfo.root)
  1376.  
  1377. bool es = r == "ES" or str.contains(t, "US500") or str.contains(t, "SPX")
  1378. bool nq = r == "NQ" or str.contains(t, "US100") or str.contains(t, "NAS100")
  1379. bool ym = r == "YM" or str.contains(t, "US30")
  1380. bool rty = r == "RTY"
  1381.  
  1382. bool eurusd = str.contains(t, "EURUSD")
  1383. bool gbpusd = str.contains(t, "GBPUSD")
  1384. bool audusd = str.contains(t, "AUDUSD")
  1385. bool nzdusd = str.contains(t, "NZDUSD")
  1386. bool usdchf = str.contains(t, "USDCHF")
  1387. bool usdcad = str.contains(t, "USDCAD")
  1388. bool usdjpy = str.contains(t, "USDJPY")
  1389.  
  1390. bool btc = str.contains(t, "BTC")
  1391. bool eth = str.contains(t, "ETH")
  1392. bool sol = str.contains(t, "SOL")
  1393.  
  1394. es ? "CBOT_MINI:YM1!" :
  1395. nq ? "CBOT_MINI:YM1!" :
  1396. ym ? "CME_MINI:NQ1!" :
  1397. rty ? "CME_MINI:NQ1!" :
  1398. eurusd ? "TVC:DXY" :
  1399. gbpusd ? "TVC:DXY" :
  1400. audusd ? "TVC:DXY" :
  1401. nzdusd ? "TVC:DXY" :
  1402. usdchf ? "OANDA:EURUSD" :
  1403. usdcad ? "OANDA:AUDUSD" :
  1404. usdjpy ? "OANDA:EURJPY" :
  1405. btc ? "BINANCE:SOLUSDT" :
  1406. eth ? "BINANCE:SOLUSDT" :
  1407. sol ? "BINANCE:ETHUSDT" :
  1408. manualSMTSymbol2
  1409.  
  1410. f_autoSMTRelation2() =>
  1411. string t = str.upper(syminfo.ticker)
  1412. bool eurusd = str.contains(t, "EURUSD")
  1413. bool gbpusd = str.contains(t, "GBPUSD")
  1414. bool audusd = str.contains(t, "AUDUSD")
  1415. bool nzdusd = str.contains(t, "NZDUSD")
  1416. bool usdchf = str.contains(t, "USDCHF")
  1417. bool usdjpy = str.contains(t, "USDJPY")
  1418.  
  1419. eurusd or gbpusd or audusd or nzdusd or usdchf or usdjpy ? -1 : 1
  1420.  
  1421. string smtSymbol1 = smtMode == "Auto Matrix" ? f_autoSMTSymbol1() : manualSMTSymbol1
  1422. string smtSymbol2 = smtMode == "Auto Matrix" ? f_autoSMTSymbol2() : manualSMTSymbol2
  1423. int smtRelation1 = smtMode == "Auto Matrix" ? f_autoSMTRelation1() : (manualSMTRelation1 == "Direct" ? 1 : -1)
  1424. int smtRelation2 = smtMode == "Auto Matrix" ? f_autoSMTRelation2() : (manualSMTRelation2 == "Direct" ? 1 : -1)
  1425.  
  1426. float smtHigh1 = request.security(smtSymbol1, selectedHTF, high, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1427. float smtLow1 = request.security(smtSymbol1, selectedHTF, low, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1428. float smtATR1 = request.security(smtSymbol1, selectedHTF, ta.atr(14), gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1429.  
  1430. float smtHigh2 = request.security(smtSymbol2, selectedHTF, high, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1431. float smtLow2 = request.security(smtSymbol2, selectedHTF, low, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1432. float smtATR2 = request.security(smtSymbol2, selectedHTF, ta.atr(14), gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = true)
  1433.  
  1434. float ownPriorHigh = ta.highest(high[1], smtLookback)
  1435. float ownPriorLow = ta.lowest(low[1], smtLookback)
  1436. float ownTolerance = ta.atr(14) * smtToleranceATR
  1437.  
  1438. bool ownHH = high > ownPriorHigh + ownTolerance
  1439. bool ownLL = low < ownPriorLow - ownTolerance
  1440.  
  1441. f_smtState(float comparisonHigh, float comparisonLow, float comparisonATR, int relation) =>
  1442. bool comparisonDataReady =
  1443. not na(comparisonHigh) and
  1444. not na(comparisonLow) and
  1445. not na(comparisonATR)
  1446.  
  1447. float comparisonPriorHigh = ta.highest(comparisonHigh[1], smtLookback)
  1448. float comparisonPriorLow = ta.lowest(comparisonLow[1], smtLookback)
  1449. float comparisonTolerance = comparisonATR * smtToleranceATR
  1450.  
  1451. bool comparisonHistoryReady =
  1452. comparisonDataReady and
  1453. not na(comparisonPriorHigh) and
  1454. not na(comparisonPriorLow)
  1455.  
  1456. bool comparisonHH =
  1457. comparisonHistoryReady and
  1458. comparisonHigh > comparisonPriorHigh + comparisonTolerance
  1459.  
  1460. bool comparisonLL =
  1461. comparisonHistoryReady and
  1462. comparisonLow < comparisonPriorLow - comparisonTolerance
  1463.  
  1464. bool bullishDirect = comparisonHistoryReady and ((ownLL and not comparisonLL) or (comparisonLL and not ownLL))
  1465. bool bearishDirect = comparisonHistoryReady and ((ownHH and not comparisonHH) or (comparisonHH and not ownHH))
  1466.  
  1467. bool bullishInverse = comparisonHistoryReady and ((ownLL and not comparisonHH) or (comparisonHH and not ownLL))
  1468. bool bearishInverse = comparisonHistoryReady and ((ownHH and not comparisonLL) or (comparisonLL and not ownHH))
  1469.  
  1470. int state =
  1471. not comparisonHistoryReady ? 0 :
  1472. relation == 1 ?
  1473. (bullishDirect ? 1 : bearishDirect ? -1 : 0) :
  1474. (bullishInverse ? 1 : bearishInverse ? -1 : 0)
  1475. state
  1476.  
  1477. int smtState1 = f_smtState(smtHigh1, smtLow1, smtATR1, smtRelation1)
  1478. int smtState2 = useSecondSMTMarket ? f_smtState(smtHigh2, smtLow2, smtATR2, smtRelation2) : 0
  1479.  
  1480. int bullishSMTCount = (smtState1 == 1 ? 1 : 0) + (smtState2 == 1 ? 1 : 0)
  1481. int bearishSMTCount = (smtState1 == -1 ? 1 : 0) + (smtState2 == -1 ? 1 : 0)
  1482.  
  1483. bool bullishSMT = bullishSMTCount >= minimumSMTConfirmations
  1484. bool bearishSMT = bearishSMTCount >= minimumSMTConfirmations
  1485.  
  1486. //======================================================================
  1487. // 8. CRT HIERARCHY ALIGNMENT
  1488. //======================================================================
  1489. f_parentTimeframe(string childTF) =>
  1490. childTF == "W" ? "M" :
  1491. childTF == "D" ? "W" :
  1492. childTF == "240" or childTF == "180" or childTF == "120" ? "D" :
  1493. childTF == "60" ? "240" :
  1494. childTF == "30" ? "60" :
  1495. ""
  1496.  
  1497. f_activeStructuralCRTDirection() =>
  1498. float parentRangeHigh = high[1]
  1499. float parentRangeLow = low[1]
  1500. bool parentSweptHigh = high > parentRangeHigh
  1501. bool parentSweptLow = low < parentRangeLow
  1502. bool parentSingleSweep = parentSweptHigh != parentSweptLow
  1503. bool parentClosedInside = close < parentRangeHigh and close > parentRangeLow
  1504.  
  1505. bool parentBase =
  1506. barstate.isconfirmed and
  1507. parentSingleSweep and
  1508. (not rejectDoubleSweep or not (parentSweptHigh and parentSweptLow)) and
  1509. (not requireCloseInside or parentClosedInside)
  1510.  
  1511. int parentEventDirection =
  1512. parentBase and parentSweptLow and not parentSweptHigh ? 1 :
  1513. parentBase and parentSweptHigh and not parentSweptLow ? -1 : 0
  1514.  
  1515. bool parentEvent = parentEventDirection != 0
  1516. int latestParentDirection = nz(ta.valuewhen(parentEvent, parentEventDirection, 0), 0)
  1517. float latestParentRangeHigh = ta.valuewhen(parentEvent, parentRangeHigh, 0)
  1518. float latestParentRangeLow = ta.valuewhen(parentEvent, parentRangeLow, 0)
  1519. int parentBarsSinceEvent = ta.barssince(parentEvent)
  1520.  
  1521. bool hasParentCRT =
  1522. latestParentDirection != 0 and
  1523. not na(latestParentRangeHigh) and
  1524. not na(latestParentRangeLow) and
  1525. not na(parentBarsSinceEvent)
  1526.  
  1527. bool parentTargetReached =
  1528. hasParentCRT and parentBarsSinceEvent > 0 and (
  1529. latestParentDirection == 1 ?
  1530. (targetRequiresClose ? close >= latestParentRangeHigh : high >= latestParentRangeHigh) :
  1531. (targetRequiresClose ? close <= latestParentRangeLow : low <= latestParentRangeLow)
  1532. )
  1533.  
  1534. bool parentInvalidated =
  1535. hasParentCRT and parentBarsSinceEvent > 0 and (
  1536. latestParentDirection == 1 ?
  1537. (invalidationRequiresClose ? close < latestParentRangeLow : low < latestParentRangeLow) :
  1538. (invalidationRequiresClose ? close > latestParentRangeHigh : high > latestParentRangeHigh)
  1539. )
  1540.  
  1541. bool parentExpired = hasParentCRT and parentBarsSinceEvent > lifecycleExpiryBars
  1542. bool parentActive = hasParentCRT and not parentTargetReached and not parentInvalidated and not parentExpired
  1543.  
  1544. parentActive ? latestParentDirection : 0
  1545.  
  1546. f_activeStructuralCRTContext() =>
  1547. float pRangeHigh = high[1]
  1548. float pRangeLow = low[1]
  1549. bool pSweptHigh = high > pRangeHigh
  1550. bool pSweptLow = low < pRangeLow
  1551. bool pSingleSweep = pSweptHigh != pSweptLow
  1552. bool pClosedInside = close < pRangeHigh and close > pRangeLow
  1553.  
  1554. bool pBase =
  1555. barstate.isconfirmed and
  1556. pSingleSweep and
  1557. (not rejectDoubleSweep or not (pSweptHigh and pSweptLow)) and
  1558. (not requireCloseInside or pClosedInside)
  1559.  
  1560. int pEventDirection =
  1561. pBase and pSweptLow and not pSweptHigh ? 1 :
  1562. pBase and pSweptHigh and not pSweptLow ? -1 : 0
  1563.  
  1564. bool pEvent = pEventDirection != 0
  1565. int pLatestDirection = nz(ta.valuewhen(pEvent, pEventDirection, 0), 0)
  1566. float pLatestHigh = ta.valuewhen(pEvent, pRangeHigh, 0)
  1567. float pLatestLow = ta.valuewhen(pEvent, pRangeLow, 0)
  1568. int pBarsSince = ta.barssince(pEvent)
  1569.  
  1570. bool pHasCRT =
  1571. pLatestDirection != 0 and
  1572. not na(pLatestHigh) and
  1573. not na(pLatestLow) and
  1574. not na(pBarsSince)
  1575.  
  1576. bool pTargetReached =
  1577. pHasCRT and pBarsSince > 0 and (
  1578. pLatestDirection == 1 ?
  1579. (targetRequiresClose ? close >= pLatestHigh : high >= pLatestHigh) :
  1580. (targetRequiresClose ? close <= pLatestLow : low <= pLatestLow)
  1581. )
  1582.  
  1583. bool pInvalidated =
  1584. pHasCRT and pBarsSince > 0 and (
  1585. pLatestDirection == 1 ?
  1586. (invalidationRequiresClose ? close < pLatestLow : low < pLatestLow) :
  1587. (invalidationRequiresClose ? close > pLatestHigh : high > pLatestHigh)
  1588. )
  1589.  
  1590. bool pExpired = pHasCRT and pBarsSince > lifecycleExpiryBars
  1591. bool pActive = pHasCRT and not pTargetReached and not pInvalidated and not pExpired
  1592.  
  1593. [pActive ? pLatestDirection : 0, pActive ? pLatestHigh : na, pActive ? pLatestLow : na]
  1594.  
  1595. string parentHierarchyTF = f_parentTimeframe(selectedHTF)
  1596.  
  1597. int parentCRTDirection =
  1598. parentHierarchyTF == "" ? 0 :
  1599. request.security(
  1600. syminfo.tickerid,
  1601. parentHierarchyTF,
  1602. f_activeStructuralCRTDirection(),
  1603. gaps = barmerge.gaps_off,
  1604. lookahead = barmerge.lookahead_off
  1605. )
  1606.  
  1607. string parentContextRequestTF = parentHierarchyTF == "" ? selectedHTF : parentHierarchyTF
  1608.  
  1609. [parentContextDirectionRaw, parentContextHighRaw, parentContextLowRaw] =
  1610. request.security(
  1611. syminfo.tickerid,
  1612. parentContextRequestTF,
  1613. f_activeStructuralCRTContext(),
  1614. gaps = barmerge.gaps_off,
  1615. lookahead = barmerge.lookahead_off
  1616. )
  1617.  
  1618. int parentContextDirection = parentHierarchyTF == "" ? 0 : parentContextDirectionRaw
  1619. float parentContextHigh = parentHierarchyTF == "" ? na : parentContextHighRaw
  1620. float parentContextLow = parentHierarchyTF == "" ? na : parentContextLowRaw
  1621.  
  1622. //======================================================================
  1623. // 9. HIGHER-TIMEFRAME KEY LEVELS
  1624. // Previous completed day/week/month levels; non-repainting.
  1625. //======================================================================
  1626. float previousDayHigh = request.security(syminfo.tickerid, "D", high[1], lookahead = barmerge.lookahead_on)
  1627. float previousDayLow = request.security(syminfo.tickerid, "D", low[1], lookahead = barmerge.lookahead_on)
  1628. float previousWeekHigh = request.security(syminfo.tickerid, "W", high[1], lookahead = barmerge.lookahead_on)
  1629. float previousWeekLow = request.security(syminfo.tickerid, "W", low[1], lookahead = barmerge.lookahead_on)
  1630. float previousMonthHigh = request.security(syminfo.tickerid, "M", high[1], lookahead = barmerge.lookahead_on)
  1631. float previousMonthLow = request.security(syminfo.tickerid, "M", low[1], lookahead = barmerge.lookahead_on)
  1632.  
  1633. //======================================================================
  1634. // 8. RANGE + MANIPULATION STRUCTURE
  1635. // Candle [1] = potential Range candle
  1636. // Candle [0] = potential Manipulation candle
  1637. //======================================================================
  1638. float rangeHigh = high[1]
  1639. float rangeLow = low[1]
  1640. float rangeOpen = open[1]
  1641. float rangeClose = close[1]
  1642. float rangeSize = math.max(rangeHigh - rangeLow, syminfo.mintick)
  1643. float rangeMidpoint = (rangeHigh + rangeLow) * 0.5
  1644. float rangeBodyPercent = math.abs(rangeClose - rangeOpen) / rangeSize * 100.0
  1645.  
  1646. bool sweptHigh = high > rangeHigh
  1647. bool sweptLow = low < rangeLow
  1648. bool sweptBoth = sweptHigh and sweptLow
  1649. bool singleSweep = sweptHigh != sweptLow
  1650. bool closedInside = close < rangeHigh and close > rangeLow
  1651.  
  1652. bool bullishDirectionOK = not requireDirectionalClose or close > open
  1653. bool bearishDirectionOK = not requireDirectionalClose or close < open
  1654.  
  1655. bool baseRules =
  1656. barstate.isconfirmed and
  1657. singleSweep and
  1658. (not rejectDoubleSweep or not sweptBoth) and
  1659. (not requireCloseInside or closedInside)
  1660.  
  1661. bool bullishCandidate = baseRules and sweptLow and not sweptHigh and bullishDirectionOK
  1662. bool bearishCandidate = baseRules and sweptHigh and not sweptLow and bearishDirectionOK
  1663.  
  1664. //======================================================================
  1665. // 8A. PROTOCOL 11 — CRT SEQUENCE / NESTED ACTIVE PARENT RANGE
  1666. // Informational bonus only. Stable v16.9 qualification remains unchanged.
  1667. //======================================================================
  1668. bool parentContextActive =
  1669. useNestedCRTContext and
  1670. parentContextDirection != 0 and
  1671. not na(parentContextHigh) and
  1672. not na(parentContextLow)
  1673.  
  1674. bool localRangeContainedInParent =
  1675. parentContextActive and
  1676. rangeHigh <= parentContextHigh and
  1677. rangeLow >= parentContextLow
  1678.  
  1679. bool localRangeOverlapsParent =
  1680. parentContextActive and
  1681. rangeHigh >= parentContextLow and
  1682. rangeLow <= parentContextHigh
  1683.  
  1684. bool nestedInsideParent =
  1685. requireFullParentContainment ?
  1686. localRangeContainedInParent :
  1687. localRangeOverlapsParent
  1688.  
  1689. bool nestedDirectionAligned =
  1690. parentContextActive and (
  1691. (bullishCandidate and parentContextDirection == 1) or
  1692. (bearishCandidate and parentContextDirection == -1)
  1693. )
  1694.  
  1695. float parentContextMidpoint =
  1696. parentContextActive ? (parentContextHigh + parentContextLow) * 0.5 : na
  1697.  
  1698. bool nestedLocationAligned =
  1699. parentContextActive and
  1700. useParentPremiumDiscount and (
  1701. (bullishCandidate and rangeMidpoint <= parentContextMidpoint) or
  1702. (bearishCandidate and rangeMidpoint >= parentContextMidpoint)
  1703. )
  1704.  
  1705. int nestedContextScore =
  1706. (nestedInsideParent ? 1 : 0) +
  1707. (nestedDirectionAligned ? 1 : 0) +
  1708. (nestedLocationAligned ? 1 : 0)
  1709.  
  1710. bool meaningfulNestedContext =
  1711. useNestedCRTContext and
  1712. nestedContextScore >= minimumNestedContextScore
  1713.  
  1714. //======================================================================
  1715. // 9. SILENT PROTOCOL TESTS
  1716. //======================================================================
  1717. float atr = ta.atr(14)
  1718.  
  1719. //======================================================================
  1720. // 9A. PROTOCOL 10 — MEANINGFUL LIQUIDITY PURGE BONUS CONTEXT
  1721. // This module is informational only and cannot reject a v16.7 CRT.
  1722. //======================================================================
  1723. float liquidityTolerance = atr[1] * liquidityToleranceATR
  1724. float priorSwingHigh = ta.highest(high[2], liquiditySwingLookback)
  1725. float priorSwingLow = ta.lowest(low[2], liquiditySwingLookback)
  1726.  
  1727. bool purgedPDH = bearishCandidate and not na(previousDayHigh[1]) and high > previousDayHigh[1] + liquidityTolerance
  1728. bool purgedPDL = bullishCandidate and not na(previousDayLow[1]) and low < previousDayLow[1] - liquidityTolerance
  1729. bool purgedPWH = bearishCandidate and not na(previousWeekHigh[1]) and high > previousWeekHigh[1] + liquidityTolerance
  1730. bool purgedPWL = bullishCandidate and not na(previousWeekLow[1]) and low < previousWeekLow[1] - liquidityTolerance
  1731. bool purgedPMH = bearishCandidate and not na(previousMonthHigh[1]) and high > previousMonthHigh[1] + liquidityTolerance
  1732. bool purgedPML = bullishCandidate and not na(previousMonthLow[1]) and low < previousMonthLow[1] - liquidityTolerance
  1733. bool purgedSwingHigh = bearishCandidate and not na(priorSwingHigh) and high > priorSwingHigh + liquidityTolerance
  1734. bool purgedSwingLow = bullishCandidate and not na(priorSwingLow) and low < priorSwingLow - liquidityTolerance
  1735.  
  1736. int liquidityPurgeScore =
  1737. (purgedPDH or purgedPDL ? 1 : 0) +
  1738. (purgedPWH or purgedPWL ? 2 : 0) +
  1739. (purgedPMH or purgedPML ? 3 : 0) +
  1740. (purgedSwingHigh or purgedSwingLow ? 1 : 0)
  1741.  
  1742. bool meaningfulLiquidityPurge =
  1743. useLiquidityPurgeContext and
  1744. liquidityPurgeScore >= minimumLiquidityPurgeScore
  1745.  
  1746. float keyTolerance = atr[1] * keyLevelToleranceATR
  1747.  
  1748. bool timeProtocol = isAllowedRangeHour(time[1])
  1749.  
  1750. bool keyLevelProtocol =
  1751. isNearLevel(rangeHigh, rangeLow, previousDayHigh[1], keyTolerance) or
  1752. isNearLevel(rangeHigh, rangeLow, previousDayLow[1], keyTolerance) or
  1753. isNearLevel(rangeHigh, rangeLow, previousWeekHigh[1], keyTolerance) or
  1754. isNearLevel(rangeHigh, rangeLow, previousWeekLow[1], keyTolerance) or
  1755. isNearLevel(rangeHigh, rangeLow, previousMonthHigh[1], keyTolerance) or
  1756. isNearLevel(rangeHigh, rangeLow, previousMonthLow[1], keyTolerance)
  1757.  
  1758. float manipulationRange = math.max(high - low, syminfo.mintick)
  1759. float lowerRejectionPercent = (math.min(open, close) - low) / manipulationRange * 100.0
  1760. float upperRejectionPercent = (high - math.max(open, close)) / manipulationRange * 100.0
  1761.  
  1762. bool rejectionProtocol =
  1763. (bullishCandidate and lowerRejectionPercent >= minimumRejectionPercent) or
  1764. (bearishCandidate and upperRejectionPercent >= minimumRejectionPercent)
  1765.  
  1766. bool midpointProtocol =
  1767. (bullishCandidate and close > rangeMidpoint) or
  1768. (bearishCandidate and close < rangeMidpoint)
  1769.  
  1770. float rangeATRRatio = atr[1] > 0.0 ? rangeSize / atr[1] : 0.0
  1771. bool rangeSizeProtocol = rangeATRRatio >= minimumRangeATR and rangeATRRatio <= maximumRangeATR
  1772.  
  1773. bool bodyProtocol =
  1774. rangeBodyPercent >= minimumRangeBodyPercent and
  1775. rangeBodyPercent <= maximumRangeBodyPercent
  1776.  
  1777. float poiTolerance = atr[1] * poiToleranceATR
  1778. [bullPOITypes, bearPOITypes, bullPOIScore, bearPOIScore] = f_detectDirectionalPOIs(rangeHigh, rangeLow, poiTolerance)
  1779. bool bullishPOIAligned = bullPOITypes >= minimumPOITypes and bullPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or bullPOIScore >= bearPOIScore)
  1780. bool bearishPOIAligned = bearPOITypes >= minimumPOITypes and bearPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or bearPOIScore >= bullPOIScore)
  1781. bool poiProtocol = (bullishCandidate and bullishPOIAligned) or (bearishCandidate and bearishPOIAligned)
  1782. int poiTypeScore = bullishCandidate ? bullPOITypes : bearishCandidate ? bearPOITypes : 0
  1783. int directionalPOIScore = bullishCandidate ? bullPOIScore : bearishCandidate ? bearPOIScore : 0
  1784.  
  1785. bool hierarchyAligned =
  1786. (bullishCandidate and parentCRTDirection == 1) or
  1787. (bearishCandidate and parentCRTDirection == -1)
  1788.  
  1789. bool hierarchyNeutral = parentCRTDirection == 0
  1790.  
  1791. bool hierarchyOpposing =
  1792. (bullishCandidate and parentCRTDirection == -1) or
  1793. (bearishCandidate and parentCRTDirection == 1)
  1794.  
  1795. bool hierarchyProtocol = hierarchyAligned or (hierarchyNeutral and neutralHierarchyPass)
  1796.  
  1797. bool hierarchyHardPass =
  1798. not useHierarchyProtocol or
  1799. not rejectOpposingHierarchy or
  1800. not hierarchyOpposing
  1801.  
  1802. int alignedSMTCount =
  1803. bullishCandidate ? bullishSMTCount :
  1804. bearishCandidate ? bearishSMTCount : 0
  1805.  
  1806. int opposingSMTCount =
  1807. bullishCandidate ? bearishSMTCount :
  1808. bearishCandidate ? bullishSMTCount : 0
  1809.  
  1810. bool smtAligned = alignedSMTCount >= minimumSMTConfirmations
  1811. bool smtOpposing = opposingSMTCount > alignedSMTCount and opposingSMTCount > 0
  1812. bool smtNeutral = alignedSMTCount == 0 and opposingSMTCount == 0
  1813.  
  1814. bool smtProtocol =
  1815. smtAligned or
  1816. (smtNeutral and allowNeutralSMT)
  1817.  
  1818. bool smtHardPass =
  1819. not useSMTProtocol or
  1820. not rejectOpposingSMT or
  1821. not smtOpposing
  1822.  
  1823. int enabledProtocols =
  1824. (useTimeProtocol ? 1 : 0) +
  1825. (useKeyLevelProtocol ? 1 : 0) +
  1826. (useRejectionProtocol ? 1 : 0) +
  1827. (useMidpointProtocol ? 1 : 0) +
  1828. (useRangeSizeProtocol ? 1 : 0) +
  1829. (useBodyProtocol ? 1 : 0) +
  1830. (usePOIProtocol ? 1 : 0) +
  1831. (useHierarchyProtocol ? 1 : 0) +
  1832. (useSMTProtocol ? 1 : 0)
  1833.  
  1834. int protocolScore =
  1835. (useTimeProtocol and timeProtocol ? 1 : 0) +
  1836. (useKeyLevelProtocol and keyLevelProtocol ? 1 : 0) +
  1837. (useRejectionProtocol and rejectionProtocol ? 1 : 0) +
  1838. (useMidpointProtocol and midpointProtocol ? 1 : 0) +
  1839. (useRangeSizeProtocol and rangeSizeProtocol ? 1 : 0) +
  1840. (useBodyProtocol and bodyProtocol ? 1 : 0) +
  1841. (usePOIProtocol and poiProtocol ? 1 : 0) +
  1842. (useHierarchyProtocol and hierarchyProtocol ? 1 : 0) +
  1843. (useSMTProtocol and smtProtocol ? 1 : 0)
  1844.  
  1845. // Protocol 10 is a bonus only and is deliberately excluded from
  1846. // enabledProtocols, protocolScore, effectiveMinimum and protocolQualified.
  1847. int protocolScoreWithLiquidityBonus =
  1848. protocolScore + (meaningfulLiquidityPurge ? 1 : 0)
  1849.  
  1850. int protocolScoreWithContextBonuses =
  1851. protocolScore +
  1852. (meaningfulLiquidityPurge ? 1 : 0) +
  1853. (meaningfulNestedContext ? 1 : 0)
  1854.  
  1855. int effectiveMinimum = math.min(minimumProtocols, math.max(enabledProtocols, 1))
  1856. bool protocolQualified = protocolScore >= effectiveMinimum and hierarchyHardPass and smtHardPass
  1857.  
  1858. bool bullishManipulation = bullishCandidate and protocolQualified
  1859. bool bearishManipulation = bearishCandidate and protocolQualified
  1860. bool qualifiedCRT = bullishManipulation or bearishManipulation
  1861. bool rawQualifiedCRT = bullishCandidate or bearishCandidate
  1862. bool visibleCRT = showRawCRTForTesting ? rawQualifiedCRT : qualifiedCRT
  1863.  
  1864. int currentQualifiedCRTDirection =
  1865. bullishManipulation ? 1 :
  1866. bearishManipulation ? -1 : 0
  1867.  
  1868. bool dedicatedKeyLevelAligned =
  1869. useDedicatedKeyLevelEngine and
  1870. qualifiedCRT and
  1871. sourceKeyLevelType != 0 and
  1872. sourceKeyDirection == currentQualifiedCRTDirection
  1873.  
  1874. int currentKeyLevelType =
  1875. dedicatedKeyLevelAligned ? sourceKeyLevelType : 0
  1876.  
  1877. int latestKeyLevelType =
  1878. nz(ta.valuewhen(qualifiedCRT, currentKeyLevelType, 0), 0)
  1879.  
  1880. int latestKeyLevelDirection =
  1881. nz(ta.valuewhen(qualifiedCRT, currentQualifiedCRTDirection, 0), 0)
  1882.  
  1883. int latestKeyLevelWeight =
  1884. nz(ta.valuewhen(qualifiedCRT, dedicatedKeyLevelAligned ? sourceKeyLevelWeight : 0, 0), 0)
  1885.  
  1886.  
  1887.  
  1888. //======================================================================
  1889. // 11A. PROTOCOL 12 — POST-MANIPULATION DISPLACEMENT / DELIVERY
  1890. // Delayed bonus context only. A CRT is first confirmed normally; the next
  1891. // configured bars are then evaluated for directional delivery.
  1892. //======================================================================
  1893. int barsSinceQualifiedForDelivery = ta.barssince(qualifiedCRT)
  1894. bool deliveryWindowActive =
  1895. useDeliveryContext and
  1896. not na(barsSinceQualifiedForDelivery) and
  1897. barsSinceQualifiedForDelivery >= 1 and
  1898. barsSinceQualifiedForDelivery <= deliveryWindowBars
  1899.  
  1900. int deliveryCRTDirection = nz(ta.valuewhen(qualifiedCRT, bullishManipulation ? 1 : -1, 0), 0)
  1901. float deliveryRangeHigh = ta.valuewhen(qualifiedCRT, rangeHigh, 0)
  1902. float deliveryRangeLow = ta.valuewhen(qualifiedCRT, rangeLow, 0)
  1903. float deliveryRangeMid = not na(deliveryRangeHigh) and not na(deliveryRangeLow) ? (deliveryRangeHigh + deliveryRangeLow) * 0.5 : na
  1904. float deliveryATR = ta.atr(14)
  1905. float deliveryBody = math.abs(close - open)
  1906.  
  1907. bool directionalDelivery =
  1908. deliveryWindowActive and (
  1909. (deliveryCRTDirection == 1 and close > open) or
  1910. (deliveryCRTDirection == -1 and close < open)
  1911. )
  1912.  
  1913. bool strongDeliveryBody =
  1914. deliveryWindowActive and
  1915. deliveryATR > 0 and
  1916. deliveryBody >= deliveryATR * minimumDeliveryBodyATR
  1917.  
  1918. bool deliveredThroughRangeMid =
  1919. deliveryWindowActive and
  1920. not na(deliveryRangeMid) and (
  1921. (deliveryCRTDirection == 1 and close > deliveryRangeMid) or
  1922. (deliveryCRTDirection == -1 and close < deliveryRangeMid)
  1923. )
  1924.  
  1925. bool bullishDeliveryFVG =
  1926. deliveryWindowActive and
  1927. deliveryCRTDirection == 1 and
  1928. bar_index >= 2 and
  1929. low > high[2]
  1930.  
  1931. bool bearishDeliveryFVG =
  1932. deliveryWindowActive and
  1933. deliveryCRTDirection == -1 and
  1934. bar_index >= 2 and
  1935. high < low[2]
  1936.  
  1937. bool deliveryFVGCreated = bullishDeliveryFVG or bearishDeliveryFVG
  1938.  
  1939. int currentDeliveryScore =
  1940. (directionalDelivery ? 1 : 0) +
  1941. (strongDeliveryBody ? 1 : 0) +
  1942. (deliveredThroughRangeMid ? 1 : 0) +
  1943. (deliveryFVGCreated ? 1 : 0)
  1944.  
  1945. var int deliveryContextScore = 0
  1946.  
  1947. if qualifiedCRT
  1948. deliveryContextScore := 0
  1949. else if deliveryWindowActive
  1950. deliveryContextScore := math.max(deliveryContextScore, currentDeliveryScore)
  1951. else
  1952. deliveryContextScore := 0
  1953.  
  1954. bool priorDeliveryFVG =
  1955. bar_index > 0 and deliveryFVGCreated[1]
  1956.  
  1957. bool meaningfulDeliveryContext =
  1958. useDeliveryContext and
  1959. deliveryWindowActive and
  1960. deliveryContextScore >= minimumDeliveryScore and
  1961. (not requireDeliveryFVG or deliveryFVGCreated or priorDeliveryFVG)
  1962.  
  1963. //======================================================================
  1964. // 12. ACTIVE CRT LIFECYCLE
  1965. // Status codes: 0=None, 1=Active Bullish, -1=Active Bearish,
  1966. // 2=Target Reached, -2=Invalidated, 3=Expired.
  1967. //======================================================================
  1968. int newCRTDirection = bullishManipulation ? 1 : bearishManipulation ? -1 : 0
  1969. bool newQualifiedCRT = newCRTDirection != 0
  1970.  
  1971. int latestCRTDirection = nz(ta.valuewhen(newQualifiedCRT, newCRTDirection, 0), 0)
  1972. float latestCRTRangeHigh = ta.valuewhen(newQualifiedCRT, rangeHigh, 0)
  1973. float latestCRTRangeLow = ta.valuewhen(newQualifiedCRT, rangeLow, 0)
  1974. int barsSinceQualifiedCRT = ta.barssince(newQualifiedCRT)
  1975.  
  1976. bool hasTrackedCRT =
  1977. latestCRTDirection != 0 and
  1978. not na(latestCRTRangeHigh) and
  1979. not na(latestCRTRangeLow) and
  1980. not na(barsSinceQualifiedCRT)
  1981.  
  1982. bool crtTargetReached =
  1983. hasTrackedCRT and barsSinceQualifiedCRT > 0 and (
  1984. latestCRTDirection == 1 ?
  1985. (targetRequiresClose ? close >= latestCRTRangeHigh : high >= latestCRTRangeHigh) :
  1986. (targetRequiresClose ? close <= latestCRTRangeLow : low <= latestCRTRangeLow)
  1987. )
  1988.  
  1989. bool crtInvalidated =
  1990. hasTrackedCRT and barsSinceQualifiedCRT > 0 and (
  1991. latestCRTDirection == 1 ?
  1992. (invalidationRequiresClose ? close < latestCRTRangeLow : low < latestCRTRangeLow) :
  1993. (invalidationRequiresClose ? close > latestCRTRangeHigh : high > latestCRTRangeHigh)
  1994. )
  1995.  
  1996. bool crtExpired = hasTrackedCRT and barsSinceQualifiedCRT > lifecycleExpiryBars
  1997.  
  1998. bool crtLifecycleActive =
  1999. hasTrackedCRT and
  2000. not crtTargetReached and
  2001. not crtInvalidated and
  2002. not crtExpired
  2003.  
  2004. int activeCRTDirection = crtLifecycleActive ? latestCRTDirection : 0
  2005.  
  2006. int crtLifecycleStatus =
  2007. crtLifecycleActive ? latestCRTDirection :
  2008. crtTargetReached ? 2 :
  2009. crtInvalidated ? -2 :
  2010. crtExpired ? 3 : 0
  2011.  
  2012.  
  2013. //======================================================================
  2014. // 12A. PROTOCOL 13 — FAILED CRT / REVERSAL CONTEXT
  2015. // A qualified CRT failure is opposite-direction information only.
  2016. // This module is context/alert logic and does not alter CRT qualification.
  2017. //======================================================================
  2018. bool failureWindowActive =
  2019. useFailedCRTContext and
  2020. hasTrackedCRT and
  2021. barsSinceQualifiedCRT > 0 and
  2022. barsSinceQualifiedCRT <= failureWindowBars
  2023.  
  2024. float failedCRTBoundary =
  2025. latestCRTDirection == 1 ? latestCRTRangeLow :
  2026. latestCRTDirection == -1 ? latestCRTRangeHigh : na
  2027.  
  2028. bool failedThroughBoundary =
  2029. failureWindowActive and (
  2030. latestCRTDirection == 1 ?
  2031. (failureRequiresClose ? close < failedCRTBoundary : low < failedCRTBoundary) :
  2032. latestCRTDirection == -1 ?
  2033. (failureRequiresClose ? close > failedCRTBoundary : high > failedCRTBoundary) :
  2034. false
  2035. )
  2036.  
  2037. bool failureDirectionOK =
  2038. not requireFailureDirectionalClose or (
  2039. (latestCRTDirection == 1 and close < open) or
  2040. (latestCRTDirection == -1 and close > open)
  2041. )
  2042.  
  2043. float failureATR = ta.atr(14)
  2044. float failureBody = math.abs(close - open)
  2045. bool failureBodyOK =
  2046. failureATR > 0 and
  2047. failureBody >= failureATR * minimumFailureBodyATR
  2048.  
  2049. bool failedCRTEvent =
  2050. failedThroughBoundary and
  2051. failureDirectionOK and
  2052. failureBodyOK and
  2053. not failedThroughBoundary[1]
  2054.  
  2055. int failedCRTReversalDirection =
  2056. failedCRTEvent ?
  2057. (latestCRTDirection == 1 ? -1 : latestCRTDirection == -1 ? 1 : 0) :
  2058. 0
  2059.  
  2060. int latestFailedCRTReversalDirection =
  2061. nz(ta.valuewhen(failedCRTEvent, failedCRTReversalDirection, 0), 0)
  2062.  
  2063. int barsSinceFailedCRT = ta.barssince(failedCRTEvent)
  2064.  
  2065. bool failedCRTReversalContextActive =
  2066. useFailedCRTContext and
  2067. latestFailedCRTReversalDirection != 0 and
  2068. not na(barsSinceFailedCRT) and
  2069. barsSinceFailedCRT <= failureWindowBars
  2070.  
  2071.  
  2072. //======================================================================
  2073. // 12B. PROTOCOL 14 — CRT TARGET DELIVERY / DRAW ON LIQUIDITY
  2074. // Selects the nearest valid opposite-side objective for the latest
  2075. // qualified CRT. Context only; does not affect CRT qualification.
  2076. // Target type codes:
  2077. // 0=None, 1=Opposite CRT boundary, 2=Previous Day,
  2078. // 3=Previous Week, 4=Previous Month, 5=Swing Liquidity.
  2079. //======================================================================
  2080. float targetATR = ta.atr(14)
  2081. float targetTolerance = targetATR * targetReachToleranceATR
  2082. float targetSwingHigh = ta.highest(high[1], targetSwingLookback)
  2083. float targetSwingLow = ta.lowest(low[1], targetSwingLookback)
  2084.  
  2085. f_pickNearestBullishTarget(
  2086. float referencePrice,
  2087. float crtHigh,
  2088. float pdh,
  2089. float pwh,
  2090. float pmh,
  2091. float swingHigh
  2092. ) =>
  2093. float selectedTarget = na
  2094. int selectedType = 0
  2095. float bestDistance = na
  2096.  
  2097. if includeOppositeCRTRangeBoundary and not na(crtHigh) and crtHigh > referencePrice
  2098. selectedTarget := crtHigh
  2099. selectedType := 1
  2100. bestDistance := crtHigh - referencePrice
  2101.  
  2102. if includePreviousDayTarget and not na(pdh) and pdh > referencePrice
  2103. float distance = pdh - referencePrice
  2104. if na(bestDistance) or distance < bestDistance
  2105. selectedTarget := pdh
  2106. selectedType := 2
  2107. bestDistance := distance
  2108.  
  2109. if includePreviousWeekTarget and not na(pwh) and pwh > referencePrice
  2110. float distance = pwh - referencePrice
  2111. if na(bestDistance) or distance < bestDistance
  2112. selectedTarget := pwh
  2113. selectedType := 3
  2114. bestDistance := distance
  2115.  
  2116. if includePreviousMonthTarget and not na(pmh) and pmh > referencePrice
  2117. float distance = pmh - referencePrice
  2118. if na(bestDistance) or distance < bestDistance
  2119. selectedTarget := pmh
  2120. selectedType := 4
  2121. bestDistance := distance
  2122.  
  2123. if includeSwingLiquidityTarget and not na(swingHigh) and swingHigh > referencePrice
  2124. float distance = swingHigh - referencePrice
  2125. if na(bestDistance) or distance < bestDistance
  2126. selectedTarget := swingHigh
  2127. selectedType := 5
  2128.  
  2129. [selectedTarget, selectedType]
  2130.  
  2131. f_pickNearestBearishTarget(
  2132. float referencePrice,
  2133. float crtLow,
  2134. float pdl,
  2135. float pwl,
  2136. float pml,
  2137. float swingLow
  2138. ) =>
  2139. float selectedTarget = na
  2140. int selectedType = 0
  2141. float bestDistance = na
  2142.  
  2143. if includeOppositeCRTRangeBoundary and not na(crtLow) and crtLow < referencePrice
  2144. selectedTarget := crtLow
  2145. selectedType := 1
  2146. bestDistance := referencePrice - crtLow
  2147.  
  2148. if includePreviousDayTarget and not na(pdl) and pdl < referencePrice
  2149. float distance = referencePrice - pdl
  2150. if na(bestDistance) or distance < bestDistance
  2151. selectedTarget := pdl
  2152. selectedType := 2
  2153. bestDistance := distance
  2154.  
  2155. if includePreviousWeekTarget and not na(pwl) and pwl < referencePrice
  2156. float distance = referencePrice - pwl
  2157. if na(bestDistance) or distance < bestDistance
  2158. selectedTarget := pwl
  2159. selectedType := 3
  2160. bestDistance := distance
  2161.  
  2162. if includePreviousMonthTarget and not na(pml) and pml < referencePrice
  2163. float distance = referencePrice - pml
  2164. if na(bestDistance) or distance < bestDistance
  2165. selectedTarget := pml
  2166. selectedType := 4
  2167. bestDistance := distance
  2168.  
  2169. if includeSwingLiquidityTarget and not na(swingLow) and swingLow < referencePrice
  2170. float distance = referencePrice - swingLow
  2171. if na(bestDistance) or distance < bestDistance
  2172. selectedTarget := swingLow
  2173. selectedType := 5
  2174.  
  2175. [selectedTarget, selectedType]
  2176.  
  2177. float latestQualifiedClose = ta.valuewhen(newQualifiedCRT, close, 0)
  2178.  
  2179. [bullishDrawTarget, bullishDrawType] =
  2180. f_pickNearestBullishTarget(
  2181. latestQualifiedClose,
  2182. latestCRTRangeHigh,
  2183. previousDayHigh,
  2184. previousWeekHigh,
  2185. previousMonthHigh,
  2186. targetSwingHigh
  2187. )
  2188.  
  2189. [bearishDrawTarget, bearishDrawType] =
  2190. f_pickNearestBearishTarget(
  2191. latestQualifiedClose,
  2192. latestCRTRangeLow,
  2193. previousDayLow,
  2194. previousWeekLow,
  2195. previousMonthLow,
  2196. targetSwingLow
  2197. )
  2198.  
  2199. float activeDrawTarget =
  2200. not useTargetDeliveryContext ? na :
  2201. latestCRTDirection == 1 ? bullishDrawTarget :
  2202. latestCRTDirection == -1 ? bearishDrawTarget :
  2203. na
  2204.  
  2205. int activeDrawTargetType =
  2206. not useTargetDeliveryContext ? 0 :
  2207. latestCRTDirection == 1 ? bullishDrawType :
  2208. latestCRTDirection == -1 ? bearishDrawType :
  2209. 0
  2210.  
  2211. bool activeDrawTargetAvailable =
  2212. useTargetDeliveryContext and
  2213. hasTrackedCRT and
  2214. not na(activeDrawTarget) and
  2215. activeDrawTargetType != 0
  2216.  
  2217. bool activeDrawTargetReached =
  2218. activeDrawTargetAvailable and
  2219. barsSinceQualifiedCRT > 0 and (
  2220. latestCRTDirection == 1 ?
  2221. high >= activeDrawTarget - targetTolerance :
  2222. latestCRTDirection == -1 ?
  2223. low <= activeDrawTarget + targetTolerance :
  2224. false
  2225. )
  2226.  
  2227. bool newDrawTargetReached =
  2228. activeDrawTargetReached and
  2229. not activeDrawTargetReached[1]
  2230.  
  2231.  
  2232. //======================================================================
  2233. // 12C. CRT INTELLIGENCE SCORE / GRADE ENGINE
  2234. // Snapshot grade at CRT confirmation. No future-bar information is used
  2235. // in the initial grade, so historical grades do not improve retroactively.
  2236. // Score components:
  2237. // Base qualification=1, protocol depth=0..3, POI=1, SMT=1,
  2238. // liquidity purge=1, nested HTF context=1, target available=1, HTF align=1.
  2239. //======================================================================
  2240. int protocolDepthScore =
  2241. protocolScore >= 7 ? 1 :
  2242. protocolScore >= 5 ? 1 :
  2243. protocolScore >= 3 ? 1 : 0
  2244.  
  2245. // Major context confirmations carry the grade.
  2246. // A neutral or missing context never receives the same weight as alignment.
  2247. int majorContextCount =
  2248. (dedicatedKeyLevelAligned ? 1 : 0) +
  2249. (smtAligned ? 1 : 0) +
  2250. (meaningfulLiquidityPurge ? 1 : 0) +
  2251. (hierarchyAligned ? 1 : 0) +
  2252. (meaningfulNestedContext ? 1 : 0)
  2253.  
  2254. int rawCRTIntelligenceScore =
  2255. qualifiedCRT ?
  2256. protocolDepthScore +
  2257. (dedicatedKeyLevelAligned ? 2 : 0) +
  2258. (smtAligned ? 2 : 0) +
  2259. (meaningfulLiquidityPurge ? 2 : 0) +
  2260. (hierarchyAligned ? 2 : 0) +
  2261. (meaningfulNestedContext ? 1 : 0) :
  2262. 0
  2263.  
  2264. int boundedCRTIntelligenceScore = math.min(rawCRTIntelligenceScore, 10)
  2265.  
  2266. // Hard context gates prevent a technically valid but context-poor CRT
  2267. // from being labelled A or A+.
  2268. bool aPlusGradeGate =
  2269. majorContextCount >= 4 and
  2270. dedicatedKeyLevelAligned and
  2271. (hierarchyAligned or meaningfulNestedContext)
  2272.  
  2273. bool aGradeGate =
  2274. majorContextCount >= 3
  2275.  
  2276. bool bGradeGate =
  2277. majorContextCount >= 1
  2278.  
  2279. int currentCRTGradeCode =
  2280. not useIntelligenceGrade or not qualifiedCRT ? 0 :
  2281. boundedCRTIntelligenceScore >= gradeAPlusThreshold and aPlusGradeGate ? 4 :
  2282. boundedCRTIntelligenceScore >= gradeAThreshold and aGradeGate ? 3 :
  2283. boundedCRTIntelligenceScore >= gradeBThreshold and bGradeGate ? 2 : 1
  2284.  
  2285. int latestCRTIntelligenceScore =
  2286. nz(ta.valuewhen(qualifiedCRT, boundedCRTIntelligenceScore, 0), 0)
  2287.  
  2288. int latestCRTGradeCode =
  2289. nz(ta.valuewhen(qualifiedCRT, currentCRTGradeCode, 0), 0)
  2290.  
  2291. bool gradeAPlusCRT = qualifiedCRT and currentCRTGradeCode == 4
  2292. bool gradeACRT = qualifiedCRT and currentCRTGradeCode == 3
  2293. bool gradeBCRT = qualifiedCRT and currentCRTGradeCode == 2
  2294. bool gradeCCRT = qualifiedCRT and currentCRTGradeCode == 1
  2295.  
  2296. //======================================================================
  2297. // 10. CLEAN SOURCE-TF COLORS + AUTO AMD WINDOWS ON LOWER TIMEFRAMES
  2298. //======================================================================
  2299. int chartSeconds = currentChartSeconds
  2300. int projectionSeconds = timeframe.in_seconds(selectedHTF)
  2301. bool isSourceTimeframe = not na(chartSeconds) and not na(projectionSeconds) and chartSeconds == projectionSeconds
  2302. bool isLowerThanProjection = not na(chartSeconds) and not na(projectionSeconds) and chartSeconds < projectionSeconds
  2303.  
  2304. // Only the selected source timeframe may color CRT candles. Lower timeframes
  2305. // remain untouched so traders cannot confuse HTF projection with LTF CRTs.
  2306. // The history gate changes visibility only; `visibleCRT` and the full protocol
  2307. // engine continue calculating on every available bar.
  2308. bool crtVisualHistoryPass = f_visualHistoryPass(
  2309. crtVisualHistoryMode,
  2310. crtVisualRecentBars,
  2311. bar_index,
  2312. time
  2313. )
  2314.  
  2315. barcolor(
  2316. colorCandles and isSourceTimeframe and visibleCRT and crtVisualHistoryPass ? rangeColor : na,
  2317. offset = -1,
  2318. title = "Qualified CRT Range Candle"
  2319. )
  2320.  
  2321. barcolor(
  2322. colorCandles and isSourceTimeframe and visibleCRT and crtVisualHistoryPass ? manipulationColor : na,
  2323. title = "Qualified CRT Manipulation Candle"
  2324. )
  2325.  
  2326. //----------------------------------------------------------------------
  2327. // Ash ICT Fractal — exact original confirmed swing logic.
  2328. // The centre candle is evaluated only after `periods` candles have closed
  2329. // on its right, then the tiny marker is plotted back on that centre candle.
  2330. //----------------------------------------------------------------------
  2331. float ashICTFractalSourceHigh = ashICTFractalUseHighLow ? high : math.max(open, close)
  2332. float ashICTFractalSourceLow = ashICTFractalUseHighLow ? low : math.min(open, close)
  2333.  
  2334. bool ashICTFractalHigh = true
  2335. bool ashICTFractalLow = true
  2336.  
  2337. for ashFractalIndex = 1 to ashICTFractalPeriods
  2338. ashICTFractalHigh :=
  2339. ashICTFractalHigh and
  2340. ashICTFractalSourceHigh[ashICTFractalPeriods] > ashICTFractalSourceHigh[ashICTFractalPeriods + ashFractalIndex] and
  2341. ashICTFractalSourceHigh[ashICTFractalPeriods] >= ashICTFractalSourceHigh[ashICTFractalPeriods - ashFractalIndex]
  2342.  
  2343. ashICTFractalLow :=
  2344. ashICTFractalLow and
  2345. ashICTFractalSourceLow[ashICTFractalPeriods] < ashICTFractalSourceLow[ashICTFractalPeriods + ashFractalIndex] and
  2346. ashICTFractalSourceLow[ashICTFractalPeriods] <= ashICTFractalSourceLow[ashICTFractalPeriods - ashFractalIndex]
  2347.  
  2348. // Label objects preserve the original tiny triangle appearance without
  2349. // consuming plot slots. This keeps the full engine below TradingView's
  2350. // 64-plot runtime limit.
  2351. int ashICTFractalCentreBar = bar_index - ashICTFractalPeriods
  2352. int ashICTFractalCentreTime = time[ashICTFractalPeriods]
  2353. bool ashICTFractalHistoryPass = f_visualHistoryPass(
  2354. ashICTFractalHistoryMode,
  2355. ashICTFractalRecentBars,
  2356. ashICTFractalCentreBar,
  2357. ashICTFractalCentreTime
  2358. )
  2359.  
  2360. if showAshICTFractal and showAshICTFractalHigh and ashICTFractalHigh and ashICTFractalHistoryPass
  2361. label.new(
  2362. x = ashICTFractalCentreBar,
  2363. y = ashICTFractalSourceHigh[ashICTFractalPeriods],
  2364. text = "",
  2365. xloc = xloc.bar_index,
  2366. yloc = yloc.abovebar,
  2367. color = ashICTFractalHighColor,
  2368. style = label.style_triangleup,
  2369. textcolor = ashICTFractalHighColor,
  2370. size = size.tiny
  2371. )
  2372.  
  2373. if showAshICTFractal and showAshICTFractalLow and ashICTFractalLow and ashICTFractalHistoryPass
  2374. label.new(
  2375. x = ashICTFractalCentreBar,
  2376. y = ashICTFractalSourceLow[ashICTFractalPeriods],
  2377. text = "",
  2378. xloc = xloc.bar_index,
  2379. yloc = yloc.belowbar,
  2380. color = ashICTFractalLowColor,
  2381. style = label.style_triangledown,
  2382. textcolor = ashICTFractalLowColor,
  2383. size = size.tiny
  2384. )
  2385.  
  2386. //----------------------------------------------------------------------
  2387. // HTF qualification mirrored inside the selected source timeframe.
  2388. //----------------------------------------------------------------------
  2389. f_htfQualifiedCRT() =>
  2390. float pRangeHigh = high[1]
  2391. float pRangeLow = low[1]
  2392. float pRangeOpen = open[1]
  2393. float pRangeClose = close[1]
  2394. float pRangeSize = math.max(pRangeHigh - pRangeLow, syminfo.mintick)
  2395. float pRangeMid = (pRangeHigh + pRangeLow) * 0.5
  2396. float pRangeBodyPct = math.abs(pRangeClose - pRangeOpen) / pRangeSize * 100.0
  2397. float pAtr = ta.atr(14)
  2398.  
  2399. bool pSweptHigh = high > pRangeHigh
  2400. bool pSweptLow = low < pRangeLow
  2401. bool pSingleSweep = pSweptHigh != pSweptLow
  2402. bool pClosedInside = close < pRangeHigh and close > pRangeLow
  2403. bool pBullDirection = not requireDirectionalClose or close > open
  2404. bool pBearDirection = not requireDirectionalClose or close < open
  2405.  
  2406. bool pBase =
  2407. barstate.isconfirmed and
  2408. pSingleSweep and
  2409. (not rejectDoubleSweep or not (pSweptHigh and pSweptLow)) and
  2410. (not requireCloseInside or pClosedInside)
  2411.  
  2412. bool pBull = pBase and pSweptLow and not pSweptHigh and pBullDirection
  2413. bool pBear = pBase and pSweptHigh and not pSweptLow and pBearDirection
  2414.  
  2415. float pManipRange = math.max(high - low, syminfo.mintick)
  2416. float pLowerReject = (math.min(open, close) - low) / pManipRange * 100.0
  2417. float pUpperReject = (high - math.max(open, close)) / pManipRange * 100.0
  2418.  
  2419. bool pTime = isAllowedRangeHour(time[1])
  2420. bool pReject = (pBull and pLowerReject >= minimumRejectionPercent) or (pBear and pUpperReject >= minimumRejectionPercent)
  2421. bool pMid = (pBull and close > pRangeMid) or (pBear and close < pRangeMid)
  2422. float pAtrRatio = pAtr[1] > 0.0 ? pRangeSize / pAtr[1] : 0.0
  2423. bool pSize = pAtrRatio >= minimumRangeATR and pAtrRatio <= maximumRangeATR
  2424. bool pBody = pRangeBodyPct >= minimumRangeBodyPercent and pRangeBodyPct <= maximumRangeBodyPercent
  2425. float pPoiTolerance = pAtr[1] * poiToleranceATR
  2426. [pBullPOITypes, pBearPOITypes, pBullPOIScore, pBearPOIScore] = f_detectDirectionalPOIs(pRangeHigh, pRangeLow, pPoiTolerance)
  2427. bool pBullPOIAligned = pBullPOITypes >= minimumPOITypes and pBullPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or pBullPOIScore >= pBearPOIScore)
  2428. bool pBearPOIAligned = pBearPOITypes >= minimumPOITypes and pBearPOIScore >= minimumDirectionalPOIScore and (not rejectOpposingPOIDominance or pBearPOIScore >= pBullPOIScore)
  2429. bool pPOI = (pBull and pBullPOIAligned) or (pBear and pBearPOIAligned)
  2430.  
  2431. // Key-level requests are deliberately excluded here to avoid nested MTF requests.
  2432. int pEnabled =
  2433. (useTimeProtocol ? 1 : 0) +
  2434. (useRejectionProtocol ? 1 : 0) +
  2435. (useMidpointProtocol ? 1 : 0) +
  2436. (useRangeSizeProtocol ? 1 : 0) +
  2437. (useBodyProtocol ? 1 : 0) +
  2438. (usePOIProtocol ? 1 : 0)
  2439.  
  2440. int pScore =
  2441. (useTimeProtocol and pTime ? 1 : 0) +
  2442. (useRejectionProtocol and pReject ? 1 : 0) +
  2443. (useMidpointProtocol and pMid ? 1 : 0) +
  2444. (useRangeSizeProtocol and pSize ? 1 : 0) +
  2445. (useBodyProtocol and pBody ? 1 : 0) +
  2446. (usePOIProtocol and pPOI ? 1 : 0)
  2447.  
  2448. int pMinimum = math.min(minimumProtocols, math.max(pEnabled, 1))
  2449. (pBull or pBear) and pScore >= pMinimum
  2450.  
  2451. bool projectedQualified = request.security(
  2452. syminfo.tickerid,
  2453. selectedHTF,
  2454. f_htfQualifiedCRT(),
  2455. gaps = barmerge.gaps_off,
  2456. lookahead = barmerge.lookahead_off
  2457. )
  2458.  
  2459. f_htfDirection() =>
  2460. float pRangeHigh = high[1]
  2461. float pRangeLow = low[1]
  2462. bool pSweptHigh = high > pRangeHigh
  2463. bool pSweptLow = low < pRangeLow
  2464. bool pSingleSweep = pSweptHigh != pSweptLow
  2465. bool pClosedInside = close < pRangeHigh and close > pRangeLow
  2466. bool pBase = barstate.isconfirmed and pSingleSweep and (not requireCloseInside or pClosedInside)
  2467. pBase and pSweptLow and not pSweptHigh ? 1 : pBase and pSweptHigh and not pSweptLow ? -1 : 0
  2468.  
  2469. int projectedDirection = request.security(
  2470. syminfo.tickerid,
  2471. selectedHTF,
  2472. f_htfDirection(),
  2473. gaps = barmerge.gaps_off,
  2474. lookahead = barmerge.lookahead_off
  2475. )
  2476.  
  2477. int projectedRangeStart = request.security(syminfo.tickerid, selectedHTF, time[1], gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2478. int projectedManipulationStart = request.security(syminfo.tickerid, selectedHTF, time, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2479. int projectedDistributionStart = request.security(syminfo.tickerid, selectedHTF, time_close, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2480. int projectedDistributionEnd = request.security(syminfo.tickerid, selectedHTF, time_close + (time_close - time), gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
  2481.  
  2482. bool newProjectedSetup =
  2483. enableHTFProjection and
  2484. isLowerThanProjection and
  2485. projectedQualified and
  2486. (na(projectedManipulationStart[1]) or projectedManipulationStart != projectedManipulationStart[1])
  2487.  
  2488. // No projection objects are drawn.
  2489. // `newProjectedSetup` is retained only to update the internal HTF direction
  2490. // and Distribution-window timing used by the optional LTF structure engine.
  2491.  
  2492. //======================================================================
  2493. // 11. DIRECTIONAL LTF STRUCTURE UNLOCK
  2494. // After the qualified HTF Manipulation closes, the scanner activates only
  2495. // inside the HTF Distribution window. It does not issue buy/sell signals.
  2496. // It simply colors the aligned LTF CRT Range candle blue and its confirmed
  2497. // Manipulation candle yellow, leaving execution and Fib placement to trader.
  2498. //======================================================================
  2499. var int activeHTFDirection = 0
  2500. var int activeDistributionStart = na
  2501. var int activeDistributionEnd = na
  2502. var int ltfStructuresThisSetup = 0
  2503.  
  2504. if newProjectedSetup
  2505. activeHTFDirection := projectedDirection
  2506. activeDistributionStart := projectedDistributionStart
  2507. activeDistributionEnd := projectedDistributionEnd
  2508. ltfStructuresThisSetup := 0
  2509.  
  2510. float chartMinutes = not na(chartSeconds) ? chartSeconds / 60.0 : na
  2511.  
  2512. // v20.5 — Explicit native-timeframe boundary guard.
  2513. // TradingView reports 15m as both 900 seconds and a native minute interval.
  2514. // Accept either representation so the exact 15m boundary cannot fall
  2515. // between the HTF-analysis and LTF-execution dashboard branches.
  2516. bool executionChartByNativeTF =
  2517. timeframe.isminutes and
  2518. timeframe.multiplier <= maximumExecutionMinutes
  2519.  
  2520. bool executionChartBySeconds =
  2521. not na(chartMinutes) and
  2522. chartMinutes <= maximumExecutionMinutes
  2523.  
  2524. bool executionTimeframeAllowed =
  2525. isLowerThanProjection and
  2526. (executionChartByNativeTF or executionChartBySeconds)
  2527.  
  2528. bool insideDistributionWindow =
  2529. not na(activeDistributionStart) and
  2530. not na(activeDistributionEnd) and
  2531. time >= activeDistributionStart and
  2532. time < activeDistributionEnd
  2533.  
  2534. float localRangeHigh = high[1]
  2535. float localRangeLow = low[1]
  2536. float localRangeMid = (localRangeHigh + localRangeLow) * 0.5
  2537. float localManipulationRange = math.max(high - low, syminfo.mintick)
  2538.  
  2539. bool localSweptLow = low < localRangeLow and high <= localRangeHigh
  2540. bool localSweptHigh = high > localRangeHigh and low >= localRangeLow
  2541. bool localClosedInside = close > localRangeLow and close < localRangeHigh
  2542. float localLowerReject = (math.min(open, close) - low) / localManipulationRange * 100.0
  2543. float localUpperReject = (high - math.max(open, close)) / localManipulationRange * 100.0
  2544.  
  2545. bool localBullishCRT =
  2546. barstate.isconfirmed and
  2547. localSweptLow and
  2548. (not localRequireCloseInside or localClosedInside) and
  2549. (not localRequireMidpoint or close > localRangeMid) and
  2550. localLowerReject >= localMinimumRejection
  2551.  
  2552. bool localBearishCRT =
  2553. barstate.isconfirmed and
  2554. localSweptHigh and
  2555. (not localRequireCloseInside or localClosedInside) and
  2556. (not localRequireMidpoint or close < localRangeMid) and
  2557. localUpperReject >= localMinimumRejection
  2558.  
  2559. bool structureEngineUnlocked =
  2560. enableExecutionEngine and
  2561. executionTimeframeAllowed and
  2562. insideDistributionWindow and
  2563. activeHTFDirection != 0
  2564.  
  2565. bool structureQuotaAvailable = not firstExecutionOnly or ltfStructuresThisSetup == 0
  2566. bool bullishLTFStructure = structureEngineUnlocked and structureQuotaAvailable and activeHTFDirection == 1 and localBullishCRT
  2567. bool bearishLTFStructure = structureEngineUnlocked and structureQuotaAvailable and activeHTFDirection == -1 and localBearishCRT
  2568. bool qualifiedLTFStructure = bullishLTFStructure or bearishLTFStructure
  2569.  
  2570. if qualifiedLTFStructure
  2571. ltfStructuresThisSetup += 1
  2572.  
  2573. // The Range candle is confirmed only when its following Manipulation candle
  2574. // closes, so it is colored retrospectively with offset -1.
  2575. barcolor(
  2576. colorUnlockedLTFStructure and qualifiedLTFStructure and crtVisualHistoryPass ? ltfRangeColor : na,
  2577. offset = -1,
  2578. title = "Unlocked LTF CRT Range Candle"
  2579. )
  2580.  
  2581. barcolor(
  2582. colorUnlockedLTFStructure and qualifiedLTFStructure and crtVisualHistoryPass ? ltfManipulationColor : na,
  2583. title = "Unlocked LTF CRT Manipulation Candle"
  2584. )
  2585.  
  2586. // Scores remain available in TradingView's Data Window only.
  2587. plot(protocolScore, "CRT Protocol Score", display = display.data_window)
  2588. plot(effectiveMinimum, "CRT Minimum Required", display = display.data_window)
  2589. plot(directionalPOIScore, "Directional POI Score", display = display.data_window)
  2590. plot(timeProtocol ? 1 : 0, "Market Time Protocol Passed", display = display.data_window)
  2591.  
  2592. string activeMarketProfile = f_selectedMarketProfile()
  2593. int activeMarketProfileCode =
  2594. activeMarketProfile == "Forex" ? 1 :
  2595. activeMarketProfile == "Indices" ? 2 :
  2596. activeMarketProfile == "Futures" ? 3 :
  2597. activeMarketProfile == "Crypto" ? 4 :
  2598. activeMarketProfile == "Commodities" ? 5 : 6
  2599. plot(parentCRTDirection, "Parent HTF CRT Direction", display = display.data_window)
  2600. plot(hierarchyAligned ? 1 : hierarchyOpposing ? -1 : 0, "Hierarchy Alignment State", display = display.data_window)
  2601. plot(activeCRTDirection, "Active CRT Direction", display = display.data_window)
  2602. plot(crtLifecycleStatus, "CRT Lifecycle Status", display = display.data_window)
  2603. plot(barsSinceQualifiedCRT, "Bars Since Qualified CRT", display = display.data_window)
  2604. plot(bullishSMTCount, "Bullish SMT Confirmation Count", display = display.data_window)
  2605. plot(bearishSMTCount, "Bearish SMT Confirmation Count", display = display.data_window)
  2606. plot(smtAligned ? 1 : smtOpposing ? -1 : 0, "SMT Matrix Alignment State", display = display.data_window)
  2607. plot(liquidityPurgeScore, "Liquidity Purge Score", display = display.data_window)
  2608. plot(meaningfulLiquidityPurge ? 1 : 0, "Meaningful Liquidity Purge", display = display.data_window)
  2609. plot(parentContextDirection, "Active Parent CRT Context Direction", display = display.data_window)
  2610. plot(nestedContextScore, "Nested HTF CRT Context Score", display = display.data_window)
  2611. plot(meaningfulNestedContext ? 1 : 0, "Meaningful Nested HTF Context", display = display.data_window)
  2612. plot(deliveryContextScore, "Displacement Delivery Score", display = display.data_window)
  2613. plot(meaningfulDeliveryContext ? 1 : 0, "Meaningful Displacement Delivery", display = display.data_window)
  2614. plot(deliveryCRTDirection, "Delivery CRT Direction", display = display.data_window)
  2615. plot(failedCRTEvent ? 1 : 0, "Failed CRT Event", display = display.data_window)
  2616. plot(failedCRTReversalContextActive ? 1 : 0, "Failed CRT Reversal Context Active", display = display.data_window)
  2617. plot(barsSinceFailedCRT, "Bars Since Failed CRT", display = display.data_window)
  2618. plot(activeDrawTarget, "Active CRT Draw Target", display = display.data_window)
  2619. plot(activeDrawTargetType, "Active CRT Draw Target Type", display = display.data_window)
  2620. plot(activeDrawTargetAvailable ? 1 : 0, "CRT Draw Target Available", display = display.data_window)
  2621. plot(activeDrawTargetReached ? 1 : 0, "CRT Draw Target Reached", display = display.data_window)
  2622. plot(boundedCRTIntelligenceScore, "CRT Intelligence Score", display = display.data_window)
  2623. plot(currentCRTGradeCode, "CRT Grade Code (4=A+, 3=A, 2=B, 1=C)", display = display.data_window)
  2624. plot(majorContextCount, "Major Grade Context Count", display = display.data_window)
  2625.  
  2626.  
  2627. //======================================================================
  2628. // 14A. CRT INTELLIGENCE DASHBOARD — PREVIEW
  2629. // Latest qualified CRT context only. No chart lines or labels are drawn.
  2630. // Dedicated source-timeframe engine reports exact FVG, IFVG,
  2631. // Order Block, Breaker, or Rejection Block context for the latest CRT.
  2632. //======================================================================
  2633. f_dashboardPosition(string p) =>
  2634. p == "Top Left" ? position.top_left :
  2635. p == "Bottom Right" ? position.bottom_right :
  2636. p == "Bottom Left" ? position.bottom_left :
  2637. position.top_right
  2638.  
  2639. f_dashboardTextSize(string s) =>
  2640. s == "Tiny" ? size.tiny :
  2641. s == "Normal" ? size.normal :
  2642. size.small
  2643.  
  2644. f_gradeText(int gradeCode) =>
  2645. gradeCode == 4 ? "A+" :
  2646. gradeCode == 3 ? "A" :
  2647. gradeCode == 2 ? "B" :
  2648. gradeCode == 1 ? "C" : "—"
  2649.  
  2650. f_keyLevelTypeText(int keyType, int direction) =>
  2651. string directionText =
  2652. direction == 1 ? "BULLISH " :
  2653. direction == -1 ? "BEARISH " : ""
  2654. string typeText =
  2655. keyType == 1 ? "FVG" :
  2656. keyType == 2 ? "IFVG" :
  2657. keyType == 3 ? "ORDER BLOCK" :
  2658. keyType == 4 ? "BREAKER" :
  2659. keyType == 5 ? "REJECTION BLOCK" :
  2660. "NONE"
  2661. keyType == 0 ? "NONE" : directionText + typeText
  2662.  
  2663. f_targetTypeText(int targetType, int direction) =>
  2664. targetType == 1 ? (direction == 1 ? "CRT HIGH" : direction == -1 ? "CRT LOW" : "CRT") :
  2665. targetType == 2 ? (direction == 1 ? "PDH" : direction == -1 ? "PDL" : "PD") :
  2666. targetType == 3 ? (direction == 1 ? "PWH" : direction == -1 ? "PWL" : "PW") :
  2667. targetType == 4 ? (direction == 1 ? "PMH" : direction == -1 ? "PML" : "PM") :
  2668. targetType == 5 ? (direction == 1 ? "SWING HIGH" : direction == -1 ? "SWING LOW" : "SWING") :
  2669. "NONE"
  2670.  
  2671. // v19.0 includes State Colour Intelligence and Multi-Timeframe Execution Guidance.
  2672. // ACTIVE keeps directional colour, DELIVERED is always success-green,
  2673. // FAILED / INVALID are red, and inactive lifecycle states are neutral grey.
  2674. f_stateColor(string state) =>
  2675. 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) :
  2676. 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) :
  2677. state == "NEUTRAL" or state == "MODERATE" ? color.new(color.orange, 72) :
  2678. state == "LTF CRT ALIGNED" ? color.new(color.green, 72) :
  2679. state == "LTF CRT OPPOSED" ? color.new(color.red, 72) :
  2680. state == "EXPIRED" or state == "WAITING" ? color.new(color.gray, 72) :
  2681. color.new(color.gray, 82)
  2682.  
  2683. //======================================================================
  2684. // 14A. TRADE READINESS & ACTION ENGINE — v18.7
  2685. // Converts the existing CRT intelligence into a clear action state.
  2686. // A failed CRT creates reversal context only; it never creates an
  2687. // automatic entry. Reversal entries still require an opposite-direction
  2688. // lower-timeframe CRT confirmation.
  2689. //======================================================================
  2690. // v19.2 Unified lifecycle arbitration.
  2691. // The first terminal event wins for the current CRT. If target delivery
  2692. // occurs before (or on the same bar as) failure, the setup remains DELIVERED.
  2693. // A later failure/invalidation cannot rewrite a completed objective.
  2694. bool crtBoundaryTargetEvent = crtTargetReached and not crtTargetReached[1]
  2695. bool unifiedTargetEvent = crtBoundaryTargetEvent or newDrawTargetReached
  2696. int barsSinceUnifiedTarget = ta.barssince(unifiedTargetEvent)
  2697.  
  2698. bool unifiedTargetBelongsToCurrentCRT =
  2699. hasTrackedCRT and
  2700. not na(barsSinceUnifiedTarget) and
  2701. barsSinceUnifiedTarget <= barsSinceQualifiedCRT
  2702.  
  2703. bool unifiedFailureBelongsToCurrentCRT =
  2704. hasTrackedCRT and
  2705. not na(barsSinceFailedCRT) and
  2706. barsSinceFailedCRT <= barsSinceQualifiedCRT
  2707.  
  2708. // Larger bars-since means the event happened earlier. Equality gives
  2709. // target delivery priority when both events occur on the same candle.
  2710. bool targetWonLifecycle =
  2711. unifiedTargetBelongsToCurrentCRT and
  2712. (not unifiedFailureBelongsToCurrentCRT or barsSinceUnifiedTarget >= barsSinceFailedCRT)
  2713.  
  2714. bool failureWonLifecycle =
  2715. unifiedFailureBelongsToCurrentCRT and
  2716. not targetWonLifecycle
  2717.  
  2718. bool tradeTargetReached = targetWonLifecycle
  2719. bool tradeReversalActive = failedCRTReversalContextActive and failureWonLifecycle
  2720.  
  2721. bool tradeInvalid =
  2722. hasTrackedCRT and
  2723. crtInvalidated and
  2724. not tradeTargetReached and
  2725. not failureWonLifecycle
  2726.  
  2727. bool tradeExpired =
  2728. hasTrackedCRT and
  2729. crtExpired and
  2730. not tradeReversalActive and
  2731. not tradeTargetReached and
  2732. not tradeInvalid
  2733.  
  2734. bool tradeProtocolAligned =
  2735. not hierarchyOpposing and
  2736. not smtOpposing and
  2737. latestCRTIntelligenceScore >= gradeBThreshold
  2738.  
  2739. bool tradeReady =
  2740. not tradeReversalActive and
  2741. crtLifecycleActive and
  2742. meaningfulDeliveryContext and
  2743. tradeProtocolAligned
  2744.  
  2745. bool tradeWatch =
  2746. not tradeReversalActive and
  2747. crtLifecycleActive and
  2748. not tradeReady
  2749.  
  2750. string dashboardTradeStatus =
  2751. tradeReversalActive ? "REVERSAL ACTIVE" :
  2752. tradeTargetReached ? "TARGET REACHED" :
  2753. tradeInvalid ? "INVALID" :
  2754. tradeExpired ? "EXPIRED" :
  2755. tradeReady ? "READY" :
  2756. tradeWatch ? "WATCH" :
  2757. "WAIT"
  2758.  
  2759. int executionDirection =
  2760. tradeReversalActive ? latestFailedCRTReversalDirection :
  2761. crtLifecycleActive ? activeCRTDirection : 0
  2762.  
  2763. string dashboardExecutionBias =
  2764. executionDirection == 1 ? "SEEK LONG" :
  2765. executionDirection == -1 ? "SEEK SHORT" :
  2766. "NEUTRAL"
  2767.  
  2768. string dashboardEntryCondition =
  2769. tradeReversalActive ?
  2770. (executionDirection == 1 ? "WAIT BULLISH LTF CRT" : "WAIT BEARISH LTF CRT") :
  2771. tradeReady ?
  2772. (executionDirection == 1 ? "BULLISH CONFIRMATION" : "BEARISH CONFIRMATION") :
  2773. tradeWatch ?
  2774. (meaningfulDeliveryContext ? "WAIT PROTOCOL ALIGNMENT" : "WAIT FOR DELIVERY") :
  2775. tradeTargetReached ? "NO CHASE • TARGET DONE" :
  2776. tradeInvalid ? "NO TRADE" :
  2777. tradeExpired ? "WAIT NEW CRT" :
  2778. "WAIT QUALIFIED CRT"
  2779.  
  2780. string dashboardRiskState =
  2781. tradeReversalActive ? "ORIGINAL CRT FAILED" :
  2782. tradeTargetReached ? "OBJECTIVE DELIVERED" :
  2783. tradeInvalid ? "INVALIDATED" :
  2784. tradeExpired ? "SETUP EXPIRED" :
  2785. tradeReady ? "CONFIRMED • MANAGE RISK" :
  2786. tradeWatch ? "UNCONFIRMED" :
  2787. "NO ACTIVE RISK"
  2788.  
  2789. string dashboardSetupAge =
  2790. hasTrackedCRT and not na(barsSinceQualifiedCRT) ?
  2791. str.tostring(barsSinceQualifiedCRT) + " / " + str.tostring(lifecycleExpiryBars) + " BARS" :
  2792. "—"
  2793.  
  2794. f_tradeStatusColor(string state, int direction) =>
  2795. state == "READY" or state == "RE-ARMED" or state == "EXECUTION ARMED" or state == "ENTRY CONFIRMED" or state == "DELIVERING" ? (direction == -1 ? color.new(color.red, 60) : color.new(color.green, 60)) :
  2796. state == "REVERSAL ACTIVE" ? (direction == -1 ? color.new(color.red, 60) : direction == 1 ? color.new(color.green, 60) : color.new(color.orange, 65)) :
  2797. state == "INVALID" ? color.new(color.red, 58) :
  2798. state == "TARGET REACHED" ? color.new(color.green, 72) :
  2799. state == "WATCH" ? color.new(color.orange, 65) :
  2800. state == "EXPIRED" ? color.new(color.gray, 72) :
  2801. color.new(color.gray, 82)
  2802.  
  2803. //======================================================================
  2804. // 14B. UNIFIED STORY ENGINE — v19.2
  2805. // On execution charts (15m and below by default), the active H1 story
  2806. // controls directional guidance. The LTF may confirm that direction or
  2807. // remain neutral, but an opposing local CRT cannot flip the HTF bias.
  2808. //======================================================================
  2809. f_executionParentTF() =>
  2810. timeframe.isminutes and timeframe.multiplier <= 15 ? "60" :
  2811. timeframe.isminutes and timeframe.multiplier <= 60 ? "240" :
  2812. not na(chartMinutes) and chartMinutes <= 15.0 ? "60" :
  2813. not na(chartMinutes) and chartMinutes <= 60.0 ? "240" :
  2814. selectedHTF
  2815.  
  2816. string inheritanceParentTF = f_executionParentTF()
  2817.  
  2818. // v20.0 Narrative Transition Memory + Fresh Narrative Validation.
  2819. // Every qualified CRT receives a monotonically increasing source-timeframe ID.
  2820. // After a terminal narrative, a later ID is considered fresh but remains locked
  2821. // until direction, HTF context, delivery, and objective availability validate.
  2822. int narrativeSerial = int(ta.cum(qualifiedCRT ? 1 : 0))
  2823. int latestQualifiedNarrativeID = nz(ta.valuewhen(qualifiedCRT, narrativeSerial, 0), 0)
  2824. int latestQualifiedNarrativeTime = nz(ta.valuewhen(qualifiedCRT, time, 0), 0)
  2825. int latestNarrativeDirection = nz(ta.valuewhen(qualifiedCRT, currentQualifiedCRTDirection, 0), 0)
  2826. bool latestNarrativeHierarchyPass = ta.valuewhen(qualifiedCRT, hierarchyProtocol and hierarchyHardPass, 0)
  2827.  
  2828. bool terminalNarrativeState = tradeTargetReached or tradeInvalid or tradeExpired
  2829. bool terminalNarrativeEvent = terminalNarrativeState and not terminalNarrativeState[1]
  2830. int latestTerminalNarrativeTime = nz(ta.valuewhen(terminalNarrativeEvent, time, 0), 0)
  2831. int latestTerminalNarrativeID = nz(ta.valuewhen(terminalNarrativeEvent, latestQualifiedNarrativeID, 0), 0)
  2832.  
  2833. bool hasFreshNarrativeIdentity =
  2834. enableNarrativeFreshnessEngine and
  2835. latestTerminalNarrativeTime > 0 and
  2836. latestQualifiedNarrativeID > latestTerminalNarrativeID and
  2837. latestQualifiedNarrativeTime > latestTerminalNarrativeTime
  2838.  
  2839. int freshNarrativeAge =
  2840. hasFreshNarrativeIdentity and not na(barsSinceQualifiedCRT) ?
  2841. barsSinceQualifiedCRT : 100000
  2842.  
  2843. bool freshDirectionConfirmed =
  2844. hasFreshNarrativeIdentity and
  2845. latestNarrativeDirection != 0
  2846.  
  2847. bool freshHTFContextConfirmed =
  2848. hasFreshNarrativeIdentity and
  2849. (not requireFreshHierarchyAlignment or latestNarrativeHierarchyPass)
  2850.  
  2851. bool freshDeliveryConfirmed =
  2852. hasFreshNarrativeIdentity and
  2853. (not requireFreshDeliveryConfirmation or meaningfulDeliveryContext)
  2854.  
  2855. bool freshObjectiveOpen =
  2856. hasFreshNarrativeIdentity and
  2857. crtLifecycleActive and
  2858. not tradeTargetReached and
  2859. not tradeInvalid and
  2860. not tradeExpired
  2861.  
  2862. bool freshValidationTimedOut =
  2863. hasFreshNarrativeIdentity and
  2864. freshNarrativeAge > freshValidationWindowBars and
  2865. not freshDeliveryConfirmed
  2866.  
  2867. // v20.1 Narrative Validation Failure Memory.
  2868. // Once a fresh narrative ID fails validation, that exact ID is permanently
  2869. // rejected. Later changes in delivery or context cannot revive it. Only a
  2870. // strictly newer qualified narrative ID may enter validation.
  2871. var int latestRejectedNarrativeID = 0
  2872.  
  2873. bool freshValidationFailureNow =
  2874. enableFreshNarrativeValidation and
  2875. hasFreshNarrativeIdentity and
  2876. latestQualifiedNarrativeID > latestRejectedNarrativeID and (
  2877. not freshDirectionConfirmed or
  2878. not freshHTFContextConfirmed or
  2879. not freshObjectiveOpen or
  2880. freshValidationTimedOut
  2881. )
  2882.  
  2883. if freshValidationFailureNow
  2884. latestRejectedNarrativeID := latestQualifiedNarrativeID
  2885.  
  2886. bool freshNarrativePermanentlyRejected =
  2887. hasFreshNarrativeIdentity and
  2888. latestQualifiedNarrativeID <= latestRejectedNarrativeID
  2889.  
  2890. bool freshValidationRejected =
  2891. enableFreshNarrativeValidation and
  2892. freshNarrativePermanentlyRejected
  2893.  
  2894. bool freshValidationConfirmed =
  2895. hasFreshNarrativeIdentity and
  2896. not freshNarrativePermanentlyRejected and
  2897. (
  2898. not enableFreshNarrativeValidation or
  2899. (
  2900. freshDirectionConfirmed and
  2901. freshHTFContextConfirmed and
  2902. freshDeliveryConfirmed and
  2903. freshObjectiveOpen and
  2904. not freshValidationTimedOut
  2905. )
  2906. )
  2907.  
  2908. // State codes: 0 = none, 1 = validating, 2 = confirmed, 3 = permanently rejected.
  2909. int freshValidationState =
  2910. not hasFreshNarrativeIdentity ? 0 :
  2911. freshValidationRejected ? 3 :
  2912. freshValidationConfirmed ? 2 : 1
  2913.  
  2914. int freshValidationScore =
  2915. (freshDirectionConfirmed ? 1 : 0) +
  2916. (freshHTFContextConfirmed ? 1 : 0) +
  2917. (freshDeliveryConfirmed ? 1 : 0) +
  2918. (freshObjectiveOpen ? 1 : 0)
  2919.  
  2920. //======================================================================
  2921. // 20.3 NARRATIVE DELIVERY & OBJECTIVE TRACKER
  2922. // State codes:
  2923. // 0=Waiting, 1=Candidate validating, 2=Confirmed,
  2924. // 3=Delivery active, 4=Objective near, 5=Objective completed,
  2925. // 6=Invalidated, 7=Expired, 8=Permanently rejected.
  2926. //======================================================================
  2927. float narrativeTrackerATR = ta.atr(14)
  2928.  
  2929. float narrativeObjectiveDistance =
  2930. activeDrawTargetAvailable ? math.abs(activeDrawTarget - close) : na
  2931.  
  2932. bool narrativeObjectiveNear =
  2933. enableNarrativeObjectiveTracker and
  2934. activeDrawTargetAvailable and
  2935. not activeDrawTargetReached and
  2936. narrativeTrackerATR > 0 and
  2937. narrativeObjectiveDistance <= narrativeTrackerATR * objectiveNearThresholdATR
  2938.  
  2939. bool narrativeDeliveryStarted =
  2940. enableNarrativeObjectiveTracker and
  2941. freshValidationConfirmed and
  2942. crtLifecycleActive and
  2943. meaningfulDeliveryContext
  2944.  
  2945. int narrativeTrackerState =
  2946. not enableNarrativeObjectiveTracker ? 0 :
  2947. freshValidationRejected ? 8 :
  2948. tradeTargetReached ? 5 :
  2949. tradeInvalid ? 6 :
  2950. tradeExpired ? 7 :
  2951. hasFreshNarrativeIdentity and freshValidationState == 1 ? 1 :
  2952. freshValidationConfirmed and narrativeObjectiveNear ? 4 :
  2953. narrativeDeliveryStarted ? 3 :
  2954. freshValidationConfirmed ? 2 :
  2955. 0
  2956.  
  2957. string narrativeTrackerStateText =
  2958. narrativeTrackerState == 1 ? "CANDIDATE VALIDATING" :
  2959. narrativeTrackerState == 2 ? "CONFIRMED • WAIT DELIVERY" :
  2960. narrativeTrackerState == 3 ? "DELIVERY ACTIVE" :
  2961. narrativeTrackerState == 4 ? "OBJECTIVE NEAR" :
  2962. narrativeTrackerState == 5 ? "OBJECTIVE COMPLETED" :
  2963. narrativeTrackerState == 6 ? "NARRATIVE INVALIDATED" :
  2964. narrativeTrackerState == 7 ? "NARRATIVE EXPIRED" :
  2965. narrativeTrackerState == 8 ? "PERMANENTLY REJECTED" :
  2966. "WAIT NEW NARRATIVE"
  2967.  
  2968. string narrativeObjectiveTypeText =
  2969. activeDrawTargetType == 1 ? (latestCRTDirection == 1 ? "CRT HIGH" : latestCRTDirection == -1 ? "CRT LOW" : "CRT") :
  2970. activeDrawTargetType == 2 ? (latestCRTDirection == 1 ? "PDH" : latestCRTDirection == -1 ? "PDL" : "PD") :
  2971. activeDrawTargetType == 3 ? (latestCRTDirection == 1 ? "PWH" : latestCRTDirection == -1 ? "PWL" : "PW") :
  2972. activeDrawTargetType == 4 ? (latestCRTDirection == 1 ? "PMH" : latestCRTDirection == -1 ? "PML" : "PM") :
  2973. activeDrawTargetType == 5 ? (latestCRTDirection == 1 ? "SWING HIGH" : latestCRTDirection == -1 ? "SWING LOW" : "SWING") :
  2974. "NONE"
  2975.  
  2976. string narrativeObjectiveText =
  2977. not enableNarrativeObjectiveTracker ? "DISABLED" :
  2978. narrativeTrackerState == 8 ? "WAIT NEWER NARRATIVE ID" :
  2979. narrativeTrackerState == 5 ? "DELIVERED • NO CHASE" :
  2980. narrativeTrackerState == 6 or narrativeTrackerState == 7 ? "CLOSED • WAIT NEW CRT" :
  2981. not activeDrawTargetAvailable ? "NO OPEN OBJECTIVE" :
  2982. narrativeObjectiveTypeText + " • " + str.tostring(activeDrawTarget, format.mintick)
  2983.  
  2984. color narrativeTrackerColor =
  2985. narrativeTrackerState == 3 or narrativeTrackerState == 4 or narrativeTrackerState == 5 ? color.new(color.green, 58) :
  2986. narrativeTrackerState == 1 or narrativeTrackerState == 2 ? color.new(color.orange, 62) :
  2987. narrativeTrackerState == 6 or narrativeTrackerState == 8 ? color.new(color.red, 58) :
  2988. color.new(color.gray, 78)
  2989.  
  2990. plot(narrativeTrackerState, "Narrative Delivery Tracker State", display = display.data_window)
  2991.  
  2992. bool localNarrativeFresh =
  2993. hasFreshNarrativeIdentity and
  2994. crtLifecycleActive and
  2995. freshNarrativeAge <= freshNarrativeDisplayBars
  2996.  
  2997. bool localNarrativeRearmed =
  2998. enableNarrativeRearmEngine and
  2999. crtLifecycleActive and
  3000. freshValidationConfirmed and
  3001. freshNarrativeAge <= rearmDisplayParentBars
  3002.  
  3003. [inheritedReversalActiveRaw, inheritedReversalDirectionRaw, inheritedLifecycleActiveRaw, inheritedActiveDirectionRaw, inheritedTargetReachedRaw, inheritedInvalidRaw, inheritedExpiredRaw, inheritedSetupAgeRaw, inheritedQualifiedNarrativeTimeRaw, inheritedTerminalNarrativeTimeRaw, inheritedNarrativeRearmedRaw, inheritedQualifiedNarrativeIDRaw, inheritedTerminalNarrativeIDRaw, inheritedNarrativeFreshRaw, inheritedFreshNarrativeAgeRaw, inheritedFreshValidationStateRaw, inheritedFreshValidationScoreRaw, inheritedFreshDirectionRaw, inheritedRejectedNarrativeIDRaw, inheritedNarrativeTrackerStateRaw, inheritedNarrativeObjectiveRaw, inheritedNarrativeObjectiveTypeRaw] =
  3004. request.security(
  3005. syminfo.tickerid,
  3006. inheritanceParentTF,
  3007. [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, narrativeTrackerState, activeDrawTarget, activeDrawTargetType],
  3008. gaps = barmerge.gaps_off,
  3009. lookahead = barmerge.lookahead_off
  3010. )
  3011.  
  3012. // Every execution chart reads a dedicated parent channel. The parent channel
  3013. // is displayed even when it is terminal/neutral, while the local channel is
  3014. // kept separate for entry timing and local expiry.
  3015. bool executionChildMode =
  3016. executionTimeframeAllowed and
  3017. inheritanceParentTF != timeframe.period
  3018.  
  3019. bool inheritedFreshNarrative =
  3020. enableNarrativeRearmEngine and
  3021. enableNarrativeFreshnessEngine and
  3022. inheritedLifecycleActiveRaw and
  3023. inheritedQualifiedNarrativeIDRaw > inheritedTerminalNarrativeIDRaw and
  3024. inheritedQualifiedNarrativeTimeRaw > inheritedTerminalNarrativeTimeRaw
  3025.  
  3026. bool inheritedFreshValidationConfirmed = inheritedFreshValidationStateRaw == 2
  3027. bool inheritedFreshValidationRejected = inheritedFreshValidationStateRaw == 3
  3028. bool inheritedFreshValidationPending = inheritedFreshValidationStateRaw == 1
  3029.  
  3030. //======================================================================
  3031. // v20.4 NARRATIVE GENERATION HANDOFF ENGINE
  3032. // A terminal narrative remains available in memory for audit, but it is
  3033. // archived and loses ownership of all live guidance until a newer ID
  3034. // qualifies and validates.
  3035. //======================================================================
  3036. bool localNarrativeArchived =
  3037. enableNarrativeRearmEngine and
  3038. terminalNarrativeState and
  3039. not hasFreshNarrativeIdentity
  3040.  
  3041. bool inheritedNarrativeArchived =
  3042. enableNarrativeRearmEngine and
  3043. (inheritedTargetReachedRaw or inheritedInvalidRaw or inheritedExpiredRaw) and
  3044. not inheritedFreshNarrative
  3045.  
  3046. bool narrativeGenerationWaiting =
  3047. executionChildMode ? inheritedNarrativeArchived : localNarrativeArchived
  3048.  
  3049. // v20.5 — One display lock controls every student-facing dashboard row.
  3050. // Local diagnostics may continue running in the background, but no local
  3051. // event is presented as actionable while the owning narrative is archived.
  3052. bool parentStandDownDisplay = executionChildMode and inheritedNarrativeArchived
  3053. bool localStandDownDisplay = not executionChildMode and localNarrativeArchived
  3054. bool dashboardStandDownDisplay = parentStandDownDisplay or localStandDownDisplay
  3055.  
  3056. int archivedNarrativeID =
  3057. executionChildMode ? inheritedTerminalNarrativeIDRaw : latestTerminalNarrativeID
  3058.  
  3059. string archivedNarrativeReason =
  3060. executionChildMode ?
  3061. (inheritedTargetReachedRaw ? "OBJECTIVE COMPLETE" :
  3062. inheritedInvalidRaw ? "INVALIDATED" :
  3063. inheritedExpiredRaw ? "EXPIRED" :
  3064. "TERMINAL") :
  3065. (tradeTargetReached ? "OBJECTIVE COMPLETE" :
  3066. tradeInvalid ? "INVALIDATED" :
  3067. tradeExpired ? "EXPIRED" :
  3068. "TERMINAL")
  3069.  
  3070. string inheritedNarrativeTrackerText =
  3071. inheritedNarrativeTrackerStateRaw == 1 ? "CANDIDATE VALIDATING" :
  3072. inheritedNarrativeTrackerStateRaw == 2 ? "CONFIRMED • WAIT DELIVERY" :
  3073. inheritedNarrativeTrackerStateRaw == 3 ? "DELIVERY ACTIVE" :
  3074. inheritedNarrativeTrackerStateRaw == 4 ? "OBJECTIVE NEAR" :
  3075. inheritedNarrativeTrackerStateRaw == 5 ? "OBJECTIVE COMPLETED" :
  3076. inheritedNarrativeTrackerStateRaw == 6 ? "NARRATIVE INVALIDATED" :
  3077. inheritedNarrativeTrackerStateRaw == 7 ? "NARRATIVE EXPIRED" :
  3078. inheritedNarrativeTrackerStateRaw == 8 ? "PERMANENTLY REJECTED" :
  3079. "WAIT NEW NARRATIVE"
  3080.  
  3081. string inheritedObjectiveTypeText =
  3082. inheritedNarrativeObjectiveTypeRaw == 1 ? (inheritedActiveDirectionRaw == 1 ? "CRT HIGH" : inheritedActiveDirectionRaw == -1 ? "CRT LOW" : "CRT") :
  3083. inheritedNarrativeObjectiveTypeRaw == 2 ? (inheritedActiveDirectionRaw == 1 ? "PDH" : inheritedActiveDirectionRaw == -1 ? "PDL" : "PD") :
  3084. inheritedNarrativeObjectiveTypeRaw == 3 ? (inheritedActiveDirectionRaw == 1 ? "PWH" : inheritedActiveDirectionRaw == -1 ? "PWL" : "PW") :
  3085. inheritedNarrativeObjectiveTypeRaw == 4 ? (inheritedActiveDirectionRaw == 1 ? "PMH" : inheritedActiveDirectionRaw == -1 ? "PML" : "PM") :
  3086. inheritedNarrativeObjectiveTypeRaw == 5 ? (inheritedActiveDirectionRaw == 1 ? "SWING HIGH" : inheritedActiveDirectionRaw == -1 ? "SWING LOW" : "SWING") :
  3087. "NONE"
  3088.  
  3089. string inheritedNarrativeObjectiveText =
  3090. inheritedNarrativeTrackerStateRaw == 8 ? "WAIT NEWER PARENT ID" :
  3091. inheritedNarrativeTrackerStateRaw == 5 ? "DELIVERED • NO CHASE" :
  3092. inheritedNarrativeTrackerStateRaw == 6 or inheritedNarrativeTrackerStateRaw == 7 ? "CLOSED • WAIT NEW PARENT CRT" :
  3093. not na(inheritedNarrativeObjectiveRaw) and inheritedNarrativeObjectiveTypeRaw != 0 ?
  3094. inheritedObjectiveTypeText + " • " + str.tostring(inheritedNarrativeObjectiveRaw, format.mintick) :
  3095. "NO OPEN OBJECTIVE"
  3096.  
  3097. bool inheritedNarrativeStandDown =
  3098. enableNarrativeRearmEngine and (
  3099. (
  3100. (inheritedTargetReachedRaw or inheritedInvalidRaw or inheritedExpiredRaw) and
  3101. not inheritedFreshNarrative
  3102. ) or
  3103. (
  3104. inheritedFreshNarrative and
  3105. not inheritedFreshValidationConfirmed
  3106. )
  3107. )
  3108.  
  3109. // v19.8 keeps the v19.7 Parent Completion Stand-Down Lock and adds
  3110. // explicit reset/re-arm identity checking.
  3111. // IMPORTANT: The inherited story is derived directly from the parent timeframe
  3112. // on every bar. It is never stored in a chart-timeframe `var`, so a 1m/5m local
  3113. // expiry cannot erase it and a stale child chart cannot keep an old parent bias.
  3114. // Parent delivery/invalidation clears the inherited bias consistently on every LTF.
  3115. int inheritedParentStoryType =
  3116. inheritedNarrativeStandDown ? 0 :
  3117. inheritedReversalActiveRaw and inheritedReversalDirectionRaw != 0 ? 2 :
  3118. inheritedLifecycleActiveRaw and inheritedActiveDirectionRaw != 0 ? 1 : 0
  3119.  
  3120. int inheritedHTFDirection =
  3121. inheritedParentStoryType == 2 ? inheritedReversalDirectionRaw :
  3122. inheritedParentStoryType == 1 ? inheritedActiveDirectionRaw : 0
  3123.  
  3124. bool htfBiasInheritanceLock =
  3125. executionTimeframeAllowed and
  3126. inheritedHTFDirection != 0
  3127.  
  3128. bool inheritedAlignedLocalCRT =
  3129. htfBiasInheritanceLock and (
  3130. (inheritedHTFDirection == 1 and localBullishCRT) or
  3131. (inheritedHTFDirection == -1 and localBearishCRT)
  3132. )
  3133.  
  3134. bool inheritedOpposingLocalCRT =
  3135. htfBiasInheritanceLock and (
  3136. (inheritedHTFDirection == 1 and localBearishCRT) or
  3137. (inheritedHTFDirection == -1 and localBullishCRT)
  3138. )
  3139.  
  3140. // Classify the complete local story (active CRT or failed-CRT reversal),
  3141. // not only the current two-candle candidate.
  3142. int localStoryDirection =
  3143. tradeReversalActive ? latestFailedCRTReversalDirection :
  3144. crtLifecycleActive ? activeCRTDirection : 0
  3145.  
  3146. bool localStoryAligned =
  3147. htfBiasInheritanceLock and
  3148. localStoryDirection != 0 and
  3149. localStoryDirection == inheritedHTFDirection
  3150.  
  3151. bool localStoryOpposed =
  3152. htfBiasInheritanceLock and
  3153. localStoryDirection != 0 and
  3154. localStoryDirection != inheritedHTFDirection
  3155.  
  3156. //======================================================================
  3157. // 20.7 ONE-SHOT EXECUTION AUTHORIZATION ENGINE — CORE RETAINED IN v20.9.1
  3158. // State codes:
  3159. // 0=Locked/Waiting, 1=Parent active / setup building, 2=Execution armed,
  3160. // 3=Entry confirmed, 4=Delivery in progress, 5=Target reached,
  3161. // 6=Invalidated, 7=Expired.
  3162. //
  3163. // The engine never places an order. It grants one execution permission per
  3164. // inherited parent narrative ID only after:
  3165. // • the parent narrative owns a confirmed directional bias,
  3166. // • an undelivered objective remains with sufficient room,
  3167. // • an aligned qualified LTF CRT confirms, and
  3168. // • the LTF CRT reacts from liquidity or a directional key level/POI.
  3169. //======================================================================
  3170. int executionAuthorizationCurrentParentID = inheritedQualifiedNarrativeIDRaw
  3171.  
  3172. bool executionAuthorizationParentValidationPass =
  3173. not inheritedFreshNarrative or inheritedFreshValidationConfirmed
  3174.  
  3175. bool executionAuthorizationParentActive =
  3176. enableExecutionAuthorizationEngine and
  3177. executionChildMode and
  3178. htfBiasInheritanceLock and
  3179. executionAuthorizationCurrentParentID > 0 and
  3180. executionAuthorizationParentValidationPass and
  3181. not inheritedTargetReachedRaw and
  3182. not inheritedInvalidRaw and
  3183. not inheritedExpiredRaw and
  3184. not inheritedNarrativeArchived
  3185.  
  3186. float executionAuthorizationATR = ta.atr(14)
  3187. float executionAuthorizationObjectiveDistance =
  3188. inheritedHTFDirection == 1 and not na(inheritedNarrativeObjectiveRaw) ? inheritedNarrativeObjectiveRaw - close :
  3189. inheritedHTFDirection == -1 and not na(inheritedNarrativeObjectiveRaw) ? close - inheritedNarrativeObjectiveRaw :
  3190. na
  3191.  
  3192. bool executionAuthorizationObjectiveOpen =
  3193. executionAuthorizationParentActive and
  3194. not na(executionAuthorizationObjectiveDistance) and
  3195. executionAuthorizationObjectiveDistance > 0
  3196.  
  3197. bool executionAuthorizationRoomPass =
  3198. not authorizationRequireObjectiveRoom or
  3199. (
  3200. executionAuthorizationObjectiveOpen and
  3201. executionAuthorizationATR > 0 and
  3202. executionAuthorizationObjectiveDistance >= executionAuthorizationATR * authorizationMinimumRoomATR and
  3203. inheritedNarrativeTrackerStateRaw != 4
  3204. )
  3205.  
  3206. bool executionAuthorizationWindowPass =
  3207. not authorizationRequireDistributionWindow or insideDistributionWindow
  3208.  
  3209. bool executionAuthorizationAlignedQualifiedCRT =
  3210. barstate.isconfirmed and
  3211. qualifiedCRT and
  3212. currentQualifiedCRTDirection != 0 and
  3213. currentQualifiedCRTDirection == inheritedHTFDirection
  3214.  
  3215. bool executionAuthorizationLiquidityPass =
  3216. executionAuthorizationAlignedQualifiedCRT and meaningfulLiquidityPurge
  3217.  
  3218. bool executionAuthorizationPOIPass =
  3219. executionAuthorizationAlignedQualifiedCRT and
  3220. dedicatedKeyLevelAligned and
  3221. currentKeyLevelType != 0
  3222.  
  3223. bool executionAuthorizationContextPass =
  3224. not authorizationRequireLiquidityOrPOI or
  3225. executionAuthorizationLiquidityPass or
  3226. executionAuthorizationPOIPass
  3227.  
  3228. bool executionAuthorizationSetupArmed =
  3229. executionAuthorizationParentActive and
  3230. executionAuthorizationRoomPass and
  3231. executionAuthorizationWindowPass
  3232.  
  3233. bool executionAuthorizationTrigger =
  3234. executionAuthorizationSetupArmed and
  3235. executionAuthorizationAlignedQualifiedCRT and
  3236. executionAuthorizationContextPass
  3237.  
  3238. var int executionAuthorizationState = 0
  3239. var int executionAuthorizationParentID = 0
  3240. var int executionAuthorizationDirection = 0
  3241. var int executionAuthorizationConsumedParentID = 0
  3242. var int executionAuthorizationEntryBar = na
  3243. var float executionAuthorizationEntryPrice = na
  3244.  
  3245. bool executionAuthorizationIdentityChanged =
  3246. executionChildMode and
  3247. executionAuthorizationCurrentParentID > 0 and
  3248. executionAuthorizationCurrentParentID != executionAuthorizationParentID
  3249.  
  3250. if executionAuthorizationIdentityChanged
  3251. executionAuthorizationParentID := executionAuthorizationCurrentParentID
  3252. executionAuthorizationDirection := inheritedFreshDirectionRaw != 0 ? inheritedFreshDirectionRaw : inheritedHTFDirection
  3253. executionAuthorizationState := 0
  3254. executionAuthorizationEntryBar := na
  3255. executionAuthorizationEntryPrice := na
  3256.  
  3257. if not enableExecutionAuthorizationEngine or not executionChildMode
  3258. executionAuthorizationState := 0
  3259. else if inheritedTargetReachedRaw and executionAuthorizationParentID > 0
  3260. executionAuthorizationState := 5
  3261. else if inheritedInvalidRaw and executionAuthorizationParentID > 0
  3262. executionAuthorizationState := 6
  3263. else if inheritedExpiredRaw and executionAuthorizationParentID > 0
  3264. executionAuthorizationState := 7
  3265. else if inheritedFreshValidationPending or inheritedFreshValidationRejected or inheritedNarrativeArchived
  3266. executionAuthorizationState := 0
  3267. else if executionAuthorizationParentActive
  3268. bool executionAuthorizationAlreadyConsumed =
  3269. executionAuthorizationConsumedParentID == executionAuthorizationCurrentParentID
  3270.  
  3271. if executionAuthorizationAlreadyConsumed
  3272. executionAuthorizationState := not na(executionAuthorizationEntryBar) and bar_index == executionAuthorizationEntryBar ? 3 : 4
  3273. else if executionAuthorizationTrigger
  3274. executionAuthorizationState := 3
  3275. executionAuthorizationConsumedParentID := executionAuthorizationCurrentParentID
  3276. executionAuthorizationDirection := inheritedHTFDirection
  3277. executionAuthorizationEntryBar := bar_index
  3278. executionAuthorizationEntryPrice := close
  3279. else if executionAuthorizationSetupArmed
  3280. executionAuthorizationState := 2
  3281. else
  3282. executionAuthorizationState := 1
  3283. else
  3284. executionAuthorizationState := 0
  3285.  
  3286. bool executionAuthorizationConsumed =
  3287. executionAuthorizationCurrentParentID > 0 and
  3288. executionAuthorizationConsumedParentID == executionAuthorizationCurrentParentID
  3289.  
  3290. bool executionAuthorizationNoChase =
  3291. executionAuthorizationParentActive and
  3292. authorizationRequireObjectiveRoom and
  3293. not executionAuthorizationRoomPass
  3294.  
  3295. string executionAuthorizationStateText =
  3296. not enableExecutionAuthorizationEngine ? "AUTHORIZATION DISABLED" :
  3297. not executionChildMode ? "PARENT-TF GUIDANCE ONLY" :
  3298. inheritedFreshValidationPending ? "LOCKED • VALIDATING PARENT" :
  3299. inheritedFreshValidationRejected ? "LOCKED • PARENT REJECTED" :
  3300. inheritedNarrativeArchived ? "LOCKED • OLD PARENT ARCHIVED" :
  3301. inheritedTargetReachedRaw or executionAuthorizationState == 5 ? "TARGET REACHED • STAND DOWN" :
  3302. inheritedInvalidRaw or executionAuthorizationState == 6 ? "INVALIDATED • WAIT NEW PARENT" :
  3303. inheritedExpiredRaw or executionAuthorizationState == 7 ? "EXPIRED • WAIT NEW PARENT" :
  3304. not htfBiasInheritanceLock ? "LOCKED • WAIT PARENT STORY" :
  3305. executionAuthorizationNoChase ? "LOCKED • NO CHASE • OBJECTIVE NEAR" :
  3306. authorizationRequireDistributionWindow and not executionAuthorizationWindowPass ? "LOCKED • WAIT DISTRIBUTION WINDOW" :
  3307. executionAuthorizationState == 4 ? "DELIVERY #" + str.tostring(executionAuthorizationParentID) + " IN PROGRESS • NO RE-ENTRY" :
  3308. executionAuthorizationState == 3 ? "ENTRY CONFIRMED #" + str.tostring(executionAuthorizationParentID) + " • ONE-SHOT AUTHORIZED" :
  3309. executionAuthorizationState == 2 ? "EXECUTION ARMED #" + str.tostring(executionAuthorizationParentID) + " • WAIT ALIGNED CRT" :
  3310. executionAuthorizationState == 1 ? "PARENT #" + str.tostring(executionAuthorizationParentID) + " ACTIVE • BUILDING SETUP" :
  3311. "LOCKED"
  3312.  
  3313. color executionAuthorizationStateColor =
  3314. inheritedFreshValidationPending ? color.new(color.orange, 62) :
  3315. inheritedFreshValidationRejected ? color.new(color.red, 58) :
  3316. inheritedNarrativeArchived ? color.new(color.orange, 65) :
  3317. executionAuthorizationState == 3 or executionAuthorizationState == 4 ? color.new(color.green, 55) :
  3318. executionAuthorizationState == 2 ? color.new(color.orange, 55) :
  3319. executionAuthorizationState == 5 ? color.new(color.green, 72) :
  3320. executionAuthorizationState == 6 ? color.new(color.red, 55) :
  3321. executionAuthorizationState == 7 ? color.new(color.gray, 68) :
  3322. executionAuthorizationNoChase ? color.new(color.orange, 62) :
  3323. color.new(color.gray, 78)
  3324.  
  3325. int displayExecutionDirection = htfBiasInheritanceLock ? inheritedHTFDirection : executionDirection
  3326.  
  3327. string displayTradeStatus =
  3328. parentStandDownDisplay ? "STAND DOWN" :
  3329. localStandDownDisplay ? "STAND DOWN" :
  3330. executionChildMode and enableExecutionAuthorizationEngine ?
  3331. (inheritedTargetReachedRaw or executionAuthorizationState == 5 ? "TARGET REACHED" :
  3332. inheritedInvalidRaw or executionAuthorizationState == 6 ? "INVALID" :
  3333. inheritedExpiredRaw or executionAuthorizationState == 7 ? "EXPIRED" :
  3334. executionAuthorizationState == 4 ? "DELIVERING" :
  3335. executionAuthorizationState == 3 ? "ENTRY CONFIRMED" :
  3336. executionAuthorizationState == 2 ? "EXECUTION ARMED" :
  3337. executionAuthorizationState == 1 ? "WATCH" :
  3338. "WAIT") :
  3339. executionChildMode ?
  3340. (inheritedTargetReachedRaw ? "TARGET REACHED" :
  3341. inheritedInvalidRaw ? "INVALID" :
  3342. inheritedExpiredRaw ? "EXPIRED" :
  3343. htfBiasInheritanceLock ?
  3344. (inheritedNarrativeRearmedRaw ? "RE-ARMED" : inheritedAlignedLocalCRT or localStoryAligned ? "READY" : "WATCH") :
  3345. "WAIT") :
  3346. (tradeTargetReached ? "TARGET REACHED" :
  3347. tradeInvalid ? "INVALID" :
  3348. tradeExpired ? "EXPIRED" :
  3349. localNarrativeRearmed ? "RE-ARMED" :
  3350. dashboardTradeStatus)
  3351.  
  3352. string displayExecutionBias =
  3353. dashboardStandDownDisplay ? "STAND DOWN" :
  3354. executionChildMode and inheritedTargetReachedRaw ? "STAND DOWN" :
  3355. executionChildMode and (inheritedInvalidRaw or inheritedExpiredRaw) ? "NEUTRAL" :
  3356. not executionChildMode and tradeTargetReached ? "STAND DOWN" :
  3357. not executionChildMode and (tradeInvalid or tradeExpired) ? "NEUTRAL" :
  3358. displayExecutionDirection == 1 ? "SEEK LONG" :
  3359. displayExecutionDirection == -1 ? "SEEK SHORT" :
  3360. "NEUTRAL"
  3361.  
  3362. string displayEntryCondition =
  3363. parentStandDownDisplay ? "NO CHASE • WAIT PARENT RE-ARM" :
  3364. localStandDownDisplay ? "NO CHASE • WAIT NEW CRT" :
  3365. executionChildMode and enableExecutionAuthorizationEngine ?
  3366. (inheritedTargetReachedRaw ? "NO CHASE • PARENT TARGET DONE" :
  3367. inheritedInvalidRaw or inheritedExpiredRaw ? "WAIT NEW PARENT CRT" :
  3368. inheritedFreshValidationPending ? "WAIT PARENT VALIDATION" :
  3369. inheritedFreshValidationRejected ? "WAIT NEWER PARENT ID" :
  3370. executionAuthorizationState == 4 ? "NO RE-ENTRY • MANAGE DELIVERY" :
  3371. executionAuthorizationState == 3 ? "ENTRY CONFIRMED • APPLY RISK PLAN" :
  3372. executionAuthorizationNoChase ? "NO CHASE • INSUFFICIENT OBJECTIVE ROOM" :
  3373. authorizationRequireDistributionWindow and not executionAuthorizationWindowPass ? "WAIT HTF DISTRIBUTION WINDOW" :
  3374. executionAuthorizationState == 2 ?
  3375. (authorizationRequireLiquidityOrPOI ? "WAIT ALIGNED QUALIFIED CRT AT LIQUIDITY / POI" : "WAIT ALIGNED QUALIFIED LTF CRT") :
  3376. executionAuthorizationState == 1 ? "WAIT SETUP CONDITIONS" :
  3377. "WAIT PARENT STORY") :
  3378. executionChildMode ?
  3379. (inheritedTargetReachedRaw ? "NO CHASE • PARENT TARGET DONE" :
  3380. inheritedInvalidRaw ? "WAIT NEW PARENT CRT" :
  3381. inheritedExpiredRaw ? "WAIT NEW PARENT CRT" :
  3382. htfBiasInheritanceLock ?
  3383. (inheritedOpposingLocalCRT or localStoryOpposed ? "IGNORE OPPOSING LTF STORY" :
  3384. inheritedAlignedLocalCRT or localStoryAligned ? "ALIGNED LTF STORY CONFIRMED" :
  3385. displayExecutionDirection == 1 ? "WAIT BULLISH LTF CRT" : "WAIT BEARISH LTF CRT") :
  3386. "WAIT PARENT STORY") :
  3387. tradeTargetReached ? "NO CHASE • TARGET DONE" :
  3388. tradeInvalid ? "NO TRADE • WAIT NEW CRT" :
  3389. tradeExpired ? "WAIT NEW QUALIFIED CRT" :
  3390. dashboardEntryCondition
  3391.  
  3392. string displayRiskState =
  3393. parentStandDownDisplay ? "PARENT NARRATIVE ARCHIVED" :
  3394. localStandDownDisplay ? "NARRATIVE ARCHIVED" :
  3395. executionChildMode and enableExecutionAuthorizationEngine ?
  3396. (inheritedTargetReachedRaw ? "PARENT OBJECTIVE DELIVERED" :
  3397. inheritedInvalidRaw ? "PARENT INVALIDATED" :
  3398. inheritedExpiredRaw ? "PARENT EXPIRED" :
  3399. executionAuthorizationState == 4 ? "ACTIVE EXECUTION • ONE-SHOT CONSUMED" :
  3400. executionAuthorizationState == 3 ? "AUTHORIZED • APPLY RISK PLAN" :
  3401. executionAuthorizationState == 2 ? "NO POSITION • AUTHORIZATION ARMED" :
  3402. executionAuthorizationNoChase ? "NO RISK • NO CHASE" :
  3403. htfBiasInheritanceLock ? "NO ACTIVE RISK • PARENT ACTIVE" : "NO PARENT RISK") :
  3404. executionChildMode ?
  3405. (inheritedTargetReachedRaw ? "PARENT OBJECTIVE DELIVERED" :
  3406. inheritedInvalidRaw ? "PARENT INVALIDATED" :
  3407. inheritedExpiredRaw ? "PARENT EXPIRED" :
  3408. htfBiasInheritanceLock ? "PARENT STORY ACTIVE" : "NO PARENT RISK") :
  3409. dashboardRiskState
  3410.  
  3411. string displaySetupAge =
  3412. parentStandDownDisplay ? "ARCHIVED PARENT #" + str.tostring(inheritedTerminalNarrativeIDRaw) :
  3413. localStandDownDisplay ? "ARCHIVED NARRATIVE #" + str.tostring(latestTerminalNarrativeID) :
  3414. executionChildMode ? str.tostring(inheritedSetupAgeRaw) + " / " + str.tostring(lifecycleExpiryBars) + " PARENT BARS" : dashboardSetupAge
  3415.  
  3416. // v20.6 Parent Story Synchronization (retained in v20.9.1).
  3417. // Candidate state is displayed before the inherited directional lock is allowed
  3418. // to activate. This keeps child dashboards synchronized with the live parent ID
  3419. // and validation score without weakening the validation safety lock.
  3420. string inheritedFreshDirectionText =
  3421. inheritedFreshDirectionRaw == 1 ? "BULLISH" :
  3422. inheritedFreshDirectionRaw == -1 ? "BEARISH" :
  3423. "DIRECTIONAL"
  3424.  
  3425. string inheritedParentStory =
  3426. inheritedFreshNarrative and inheritedFreshValidationPending ?
  3427. inheritanceParentTF + " " + inheritedFreshDirectionText +
  3428. " CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) +
  3429. " • VALIDATING " + str.tostring(inheritedFreshValidationScoreRaw) + "/4" :
  3430. inheritedFreshNarrative and inheritedFreshValidationRejected ?
  3431. inheritanceParentTF + " " + inheritedFreshDirectionText +
  3432. " CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) +
  3433. " • REJECTED" :
  3434. inheritedFreshNarrative and inheritedFreshValidationConfirmed and inheritedParentStoryType != 0 ?
  3435. inheritanceParentTF + " " + inheritedFreshDirectionText +
  3436. " NARRATIVE ACTIVE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) +
  3437. (inheritedNarrativeRearmedRaw ? " • RE-ARMED" : "") :
  3438. inheritedParentStoryType == 2 ?
  3439. inheritanceParentTF + (inheritedHTFDirection == 1 ? " BULL REVERSAL" : " BEAR REVERSAL") :
  3440. inheritedParentStoryType == 1 ?
  3441. inheritanceParentTF + (inheritedHTFDirection == 1 ? " BULLISH NARRATIVE ACTIVE" : " BEARISH NARRATIVE ACTIVE") :
  3442. inheritedTargetReachedRaw ? inheritanceParentTF + " OBJECTIVE DELIVERED • STAND DOWN" :
  3443. inheritedInvalidRaw ? inheritanceParentTF + " INVALIDATED • RESET" :
  3444. inheritedExpiredRaw ? inheritanceParentTF + " EXPIRED • RESET" :
  3445. inheritanceParentTF + " WAITING FOR NEW NARRATIVE"
  3446.  
  3447. // v18.8 lifecycle clarity: the CRT row describes both direction and lifecycle.
  3448. // This prevents a delivered historical bearish CRT from looking like a live short bias.
  3449. string localLifecycleText =
  3450. localNarrativeArchived ? "ARCHIVED" :
  3451. tradeReversalActive ?
  3452. (latestCRTDirection == 1 ? "BULLISH FAILED" : latestCRTDirection == -1 ? "BEARISH FAILED" : "FAILED") :
  3453. tradeTargetReached ? "DELIVERED" :
  3454. tradeInvalid ? "INVALID" :
  3455. tradeExpired ? "EXPIRED" :
  3456. crtLifecycleActive ?
  3457. (activeCRTDirection == 1 ? "BULLISH ACTIVE" : activeCRTDirection == -1 ? "BEARISH ACTIVE" : "ACTIVE") :
  3458. "WAITING"
  3459.  
  3460. string dashboardCRTState =
  3461. executionChildMode and inheritedNarrativeArchived ? "PARENT STORY ARCHIVED" :
  3462. not executionChildMode and localNarrativeArchived ? "NARRATIVE ARCHIVED" :
  3463. htfBiasInheritanceLock and (inheritedOpposingLocalCRT or localStoryOpposed) ? "LTF STORY OPPOSED" :
  3464. htfBiasInheritanceLock and (inheritedAlignedLocalCRT or localStoryAligned) ? "LTF STORY ALIGNED" :
  3465. htfBiasInheritanceLock ? "LTF WAITING" :
  3466. localLifecycleText
  3467.  
  3468. string dashboardHTF =
  3469. hierarchyAligned ? "ALIGNED" :
  3470. hierarchyOpposing ? "CONFLICT" :
  3471. "NEUTRAL"
  3472.  
  3473. string dashboardPOI =
  3474. f_keyLevelTypeText(latestKeyLevelType, latestKeyLevelDirection)
  3475.  
  3476. string dashboardKeyLevelTF =
  3477. latestKeyLevelType != 0 ? selectedHTF : "—"
  3478.  
  3479. string dashboardPurge =
  3480. meaningfulLiquidityPurge ?
  3481. (latestCRTDirection == 1 ? "SSL PURGED" : latestCRTDirection == -1 ? "BSL PURGED" : "CONFIRMED") :
  3482. "NONE"
  3483.  
  3484. string dashboardSMT =
  3485. smtAligned ?
  3486. (latestCRTDirection == 1 ? "BULLISH" : latestCRTDirection == -1 ? "BEARISH" : "CONFIRMED") :
  3487. smtOpposing ? "CONFLICT" :
  3488. "NEUTRAL"
  3489.  
  3490. string dashboardNested =
  3491. meaningfulNestedContext ? "ALIGNED" :
  3492. parentContextActive ? "NEUTRAL" :
  3493. "NONE"
  3494.  
  3495. string dashboardDelivery =
  3496. executionChildMode and inheritedTargetReachedRaw ? "DELIVERED" :
  3497. executionChildMode and inheritedInvalidRaw ? "INVALID" :
  3498. executionChildMode and inheritedExpiredRaw ? "EXPIRED" :
  3499. not executionChildMode and tradeTargetReached ? "DELIVERED" :
  3500. not executionChildMode and tradeInvalid ? "INVALID" :
  3501. not executionChildMode and tradeExpired ? "EXPIRED" :
  3502. htfBiasInheritanceLock ?
  3503. (localStoryAligned ? "ALIGNED" : localStoryOpposed ? "OPPOSED" : "WAITING") :
  3504. meaningfulDeliveryContext ? "CONFIRMED" :
  3505. tradeReversalActive ? "FAILED" :
  3506. "WAITING"
  3507.  
  3508. string dashboardTarget =
  3509. narrativeGenerationWaiting ? "ARCHIVED" :
  3510. f_targetTypeText(activeDrawTargetType, latestCRTDirection)
  3511.  
  3512. string dashboardTargetStatus =
  3513. narrativeGenerationWaiting ? "CLOSED" :
  3514. tradeTargetReached ? "REACHED" :
  3515. activeDrawTargetAvailable and not tradeReversalActive and not tradeInvalid ? "ACTIVE" :
  3516. "NONE"
  3517.  
  3518. //======================================================================
  3519. // 20.8 DASHBOARD CLARITY LAYER
  3520. // Display-only separation of the owning parent objective from local CRT
  3521. // diagnostics. The authorization state machine and room threshold are not
  3522. // modified here.
  3523. //======================================================================
  3524. bool dashboardRoomFilterFailed =
  3525. executionChildMode and
  3526. enableExecutionAuthorizationEngine and
  3527. executionAuthorizationNoChase
  3528.  
  3529. string dashboardObjectiveLabel =
  3530. executionChildMode ? "PARENT OBJECTIVE" : "DRAW ON LIQUIDITY"
  3531.  
  3532. string dashboardObjectiveDisplay =
  3533. executionChildMode ?
  3534. (inheritedNarrativeObjectiveText + (dashboardRoomFilterFailed ? " • TOO NEAR" : "")) :
  3535. dashboardTarget
  3536.  
  3537. string dashboardLocalTargetLabel =
  3538. executionChildMode ? "LOCAL TARGET" : "TARGET STATUS"
  3539.  
  3540. string dashboardLocalTargetDisplay =
  3541. executionChildMode ?
  3542. (tradeTargetReached ? "OLD TARGET REACHED • INFO ONLY" :
  3543. tradeInvalid ? "LOCAL TARGET INVALID • INFO ONLY" :
  3544. tradeExpired ? "LOCAL TARGET EXPIRED • INFO ONLY" :
  3545. activeDrawTargetAvailable and not tradeReversalActive ? "LOCAL TARGET ACTIVE • INFO ONLY" :
  3546. "NO ACTIVE LOCAL TARGET") :
  3547. dashboardTargetStatus
  3548.  
  3549. string dashboardFailure =
  3550. htfBiasInheritanceLock ?
  3551. (localStoryOpposed ? "OPPOSED TO HTF" : localStoryAligned ? "ALIGNED TO HTF" : "NONE") :
  3552. tradeReversalActive ?
  3553. (latestFailedCRTReversalDirection == 1 ? "BULL REVERSAL" : "BEAR REVERSAL") :
  3554. "NONE"
  3555.  
  3556. //======================================================================
  3557. // 14C. STORY TRANSLATION + CENTRAL STATE MATRIX — v19.7
  3558. // Student-facing explanation of the local CRT, its implication, its
  3559. // alignment with the inherited HTF story, and the practical action.
  3560. // This changes dashboard wording only; detection logic is untouched.
  3561. //======================================================================
  3562. string dashboardLocalCRT =
  3563. parentStandDownDisplay ? "INFORMATION ONLY • LOCAL CRT IGNORED" :
  3564. localNarrativeArchived ? "OLD CRT ARCHIVED" :
  3565. tradeReversalActive ?
  3566. (latestCRTDirection == 1 ? "BULLISH CRT FAILED" : latestCRTDirection == -1 ? "BEARISH CRT FAILED" : "CRT FAILED") :
  3567. tradeTargetReached ? "CRT DELIVERED" :
  3568. tradeInvalid ? "CRT INVALID" :
  3569. tradeExpired ? "CRT EXPIRED" :
  3570. crtLifecycleActive ?
  3571. (activeCRTDirection == 1 ? "BULLISH CRT ACTIVE" : activeCRTDirection == -1 ? "BEARISH CRT ACTIVE" : "CRT ACTIVE") :
  3572. "NO LOCAL CRT"
  3573.  
  3574. string dashboardLocalImplication =
  3575. parentStandDownDisplay ? "INFORMATION ONLY • PARENT LOCKED" :
  3576. localNarrativeArchived ? "WAIT NEW NARRATIVE" :
  3577. tradeReversalActive ?
  3578. (latestFailedCRTReversalDirection == 1 ? "BULLISH REVERSAL" : "BEARISH REVERSAL") :
  3579. tradeTargetReached ? "OBJECTIVE COMPLETE" :
  3580. tradeInvalid ? "RESET CONTEXT" :
  3581. tradeExpired ? "WAIT NEW CRT" :
  3582. crtLifecycleActive ?
  3583. (activeCRTDirection == 1 ? "BULLISH DELIVERY" : activeCRTDirection == -1 ? "BEARISH DELIVERY" : "ACTIVE DELIVERY") :
  3584. "WAITING"
  3585.  
  3586. string dashboardHTFAlignment =
  3587. parentStandDownDisplay ? "LOCKED • PARENT ARCHIVED" :
  3588. dashboardRoomFilterFailed and htfBiasInheritanceLock ? "CONFIRMED • PARENT ACTIVE" :
  3589. not htfBiasInheritanceLock ? dashboardHTF :
  3590. localStoryAligned or inheritedAlignedLocalCRT ? "ALIGNED" :
  3591. localStoryOpposed or inheritedOpposingLocalCRT ? "OPPOSED" :
  3592. "WAITING"
  3593.  
  3594. string dashboardAction =
  3595. executionChildMode and inheritedNarrativeArchived ? "WAIT NEW QUALIFIED PARENT CRT" :
  3596. not executionChildMode and localNarrativeArchived ? "WAIT NEW QUALIFIED CRT" :
  3597. not executionChildMode ? (localNarrativeRearmed ? "NEW NARRATIVE • RE-ARMED" : "FOLLOW ENGINE VERDICT") :
  3598. enableExecutionAuthorizationEngine and executionAuthorizationState == 4 ? "MANAGE DELIVERY • NO SECOND ENTRY" :
  3599. enableExecutionAuthorizationEngine and executionAuthorizationState == 3 ? "ENTRY AUTHORIZED • EXECUTE RISK PLAN" :
  3600. enableExecutionAuthorizationEngine and executionAuthorizationNoChase ? "STAND DOWN • OBJECTIVE TOO NEAR" :
  3601. enableExecutionAuthorizationEngine and authorizationRequireDistributionWindow and not executionAuthorizationWindowPass ? "WAIT HTF DISTRIBUTION WINDOW" :
  3602. enableExecutionAuthorizationEngine and executionAuthorizationState == 2 ?
  3603. (authorizationRequireLiquidityOrPOI ? "HUNT ALIGNED CRT AT LIQUIDITY / POI" : "HUNT ALIGNED QUALIFIED LTF CRT") :
  3604. enableExecutionAuthorizationEngine and executionAuthorizationState == 1 ? "BUILDING SETUP • WAIT CONDITIONS" :
  3605. inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? "RE-ARMED • HUNT ALIGNED LTF CRT" :
  3606. not htfBiasInheritanceLock ? "WAIT PARENT STORY" :
  3607. localStoryOpposed or inheritedOpposingLocalCRT ? "IGNORE • WAIT ALIGNED CRT" :
  3608. tradeExpired ? (displayExecutionDirection == 1 ? "LOCAL RESET • WAIT BULL CRT" : "LOCAL RESET • WAIT BEAR CRT") :
  3609. not insideDistributionWindow ? "WAIT EXECUTION WINDOW" :
  3610. localStoryAligned or inheritedAlignedLocalCRT ? "CONFIRM ENTRY + RISK" :
  3611. displayExecutionDirection == 1 ? "WAIT BULLISH LTF CRT" :
  3612. displayExecutionDirection == -1 ? "WAIT BEARISH LTF CRT" :
  3613. "WAIT HTF BIAS"
  3614.  
  3615. //======================================================================
  3616. // 14B. MULTI-TIMEFRAME EXECUTION GUIDANCE — v19.2
  3617. // Translates the HTF lifecycle into the next practical timeframe, the
  3618. // structure to hunt, and whether the existing LTF execution scanner is
  3619. // locked, open, or has confirmed an aligned CRT. This is guidance only.
  3620. //======================================================================
  3621. f_nextExecutionTF(string sourceTF) =>
  3622. sourceTF == "M" ? "W / D" :
  3623. sourceTF == "W" ? "D / H4" :
  3624. sourceTF == "D" ? "H4 / H1" :
  3625. sourceTF == "240" or sourceTF == "180" or sourceTF == "120" ? "H1 / 15M" :
  3626. sourceTF == "60" ? "15M / 5M" :
  3627. sourceTF == "30" ? "5M / 3M" :
  3628. "5M / 3M / 2M / 1M"
  3629.  
  3630. // v20.2 Narrative Candidate State Tracker.
  3631. // Makes every fresh narrative transition visible:
  3632. // WAIT ID -> CANDIDATE ID -> VALIDATING score -> CONFIRMED/RE-ARMED
  3633. // or -> REJECTED ID (permanent).
  3634. string dashboardFreshValidation =
  3635. executionChildMode ?
  3636. (not inheritedFreshNarrative ? "WAIT FRESH PARENT ID" :
  3637. inheritedFreshValidationConfirmed ?
  3638. "CONFIRMED #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • " +
  3639. str.tostring(inheritedFreshValidationScoreRaw) + "/4 • " +
  3640. (inheritedFreshDirectionRaw == 1 ? "BULLISH" : "BEARISH") :
  3641. inheritedFreshValidationRejected ?
  3642. "REJECTED #" + str.tostring(inheritedRejectedNarrativeIDRaw) + " • PERMANENT" :
  3643. "CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) +
  3644. " • VALIDATING " + str.tostring(inheritedFreshValidationScoreRaw) + "/4") :
  3645. not hasFreshNarrativeIdentity ? "WAIT FRESH ID" :
  3646. freshValidationConfirmed ?
  3647. "CONFIRMED #" + str.tostring(latestQualifiedNarrativeID) + " • " +
  3648. str.tostring(freshValidationScore) + "/4 • " +
  3649. (latestNarrativeDirection == 1 ? "BULLISH" : "BEARISH") :
  3650. freshValidationRejected ?
  3651. "REJECTED #" + str.tostring(latestRejectedNarrativeID) + " • PERMANENT" :
  3652. "CANDIDATE #" + str.tostring(latestQualifiedNarrativeID) +
  3653. " • VALIDATING " + str.tostring(freshValidationScore) + "/4"
  3654.  
  3655. string dashboardNarrativeMemory =
  3656. executionChildMode ?
  3657. (inheritedFreshValidationPending ?
  3658. "CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • AGE " + str.tostring(inheritedFreshNarrativeAgeRaw) :
  3659. inheritedNarrativeFreshRaw ?
  3660. "FRESH #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • AGE " + str.tostring(inheritedFreshNarrativeAgeRaw) :
  3661. inheritedFreshValidationRejected ?
  3662. "REJECTED #" + str.tostring(inheritedRejectedNarrativeIDRaw) + " • WAIT NEWER ID" :
  3663. inheritedFreshNarrative ?
  3664. "ACTIVE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) :
  3665. inheritedTargetReachedRaw or inheritedInvalidRaw or inheritedExpiredRaw ?
  3666. "RESET #" + str.tostring(inheritedTerminalNarrativeIDRaw) + " • WAIT NEXT ID" :
  3667. inheritedQualifiedNarrativeIDRaw > 0 ?
  3668. "CURRENT #" + str.tostring(inheritedQualifiedNarrativeIDRaw) :
  3669. "NO NARRATIVE ID") :
  3670. freshValidationState == 1 and hasFreshNarrativeIdentity ?
  3671. "CANDIDATE #" + str.tostring(latestQualifiedNarrativeID) + " • AGE " + str.tostring(freshNarrativeAge) :
  3672. localNarrativeFresh ?
  3673. "FRESH #" + str.tostring(latestQualifiedNarrativeID) + " • AGE " + str.tostring(freshNarrativeAge) :
  3674. freshValidationRejected ?
  3675. "REJECTED #" + str.tostring(latestRejectedNarrativeID) + " • WAIT NEWER ID" :
  3676. hasFreshNarrativeIdentity and crtLifecycleActive ?
  3677. "ACTIVE #" + str.tostring(latestQualifiedNarrativeID) :
  3678. tradeTargetReached or tradeInvalid or tradeExpired ?
  3679. "RESET #" + str.tostring(latestTerminalNarrativeID) + " • WAIT NEXT ID" :
  3680. latestQualifiedNarrativeID > 0 ?
  3681. "CURRENT #" + str.tostring(latestQualifiedNarrativeID) :
  3682. "NO NARRATIVE ID"
  3683.  
  3684. string dashboardNarrativeState =
  3685. executionChildMode ?
  3686. (inheritedFreshNarrative and inheritedFreshValidationPending ?
  3687. "CANDIDATE #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • PARENT VALIDATING" :
  3688. inheritedFreshNarrative and inheritedFreshValidationRejected ?
  3689. "REJECTED #" + str.tostring(inheritedRejectedNarrativeIDRaw) + " • WAIT NEWER PARENT" :
  3690. inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ?
  3691. "RE-ARMED #" + str.tostring(inheritedQualifiedNarrativeIDRaw) + " • PARENT CONFIRMED" :
  3692. inheritedNarrativeArchived ?
  3693. "ARCHIVED #" + str.tostring(inheritedTerminalNarrativeIDRaw) + " • WAIT NEW PARENT" :
  3694. htfBiasInheritanceLock ? "ARMED • PARENT STORY ACTIVE" :
  3695. "WAIT NEW PARENT NARRATIVE") :
  3696. hasFreshNarrativeIdentity and freshValidationState == 1 ?
  3697. "CANDIDATE #" + str.tostring(latestQualifiedNarrativeID) + " • VALIDATING" :
  3698. hasFreshNarrativeIdentity and freshValidationState == 3 ?
  3699. "REJECTED #" + str.tostring(latestRejectedNarrativeID) + " • WAIT NEWER ID" :
  3700. localNarrativeRearmed ?
  3701. "RE-ARMED #" + str.tostring(latestQualifiedNarrativeID) + " • FRESH CONFIRMED" :
  3702. localNarrativeArchived ?
  3703. "ARCHIVED #" + str.tostring(latestTerminalNarrativeID) + " • WAIT NEW ID" :
  3704. crtLifecycleActive or tradeReversalActive ? "ARMED • NARRATIVE ACTIVE" :
  3705. "WAIT NEW NARRATIVE"
  3706.  
  3707. string dashboardHTFStory =
  3708. executionChildMode and inheritedNarrativeArchived ?
  3709. inheritanceParentTF + " ARCHIVED #" + str.tostring(inheritedTerminalNarrativeIDRaw) + " → WAIT NEW STORY" :
  3710. executionChildMode ? inheritedParentStory :
  3711. localNarrativeArchived ?
  3712. "ARCHIVED #" + str.tostring(latestTerminalNarrativeID) + " → WAIT NEW QUALIFIED CRT" :
  3713. tradeReversalActive ? dashboardCRTState + " → " + dashboardFailure :
  3714. crtLifecycleActive ? dashboardCRTState + " → " + dashboardDelivery :
  3715. "WAIT QUALIFIED HTF CRT"
  3716.  
  3717. string dashboardNextTF =
  3718. parentStandDownDisplay ? "PARENT RE-ARM REQUIRED" :
  3719. localStandDownDisplay ? "NEW QUALIFIED CRT REQUIRED" :
  3720. executionChildMode ? timeframe.period + " LOCAL EXECUTION" :
  3721. tradeInvalid or tradeExpired ? selectedHTF :
  3722. f_nextExecutionTF(selectedHTF)
  3723.  
  3724. string dashboardHunt =
  3725. executionChildMode and enableExecutionAuthorizationEngine ?
  3726. (inheritedFreshNarrative and inheritedFreshValidationPending ? "WAIT PARENT VALIDATION" :
  3727. inheritedFreshNarrative and inheritedFreshValidationRejected ? "WAIT NEXT PARENT CRT" :
  3728. inheritedNarrativeArchived ? "WAIT NEW QUALIFIED PARENT CRT" :
  3729. executionAuthorizationState == 4 or executionAuthorizationState == 3 ? "DELIVERY TO PARENT OBJECTIVE" :
  3730. executionAuthorizationNoChase ? "NO CHASE • OBJECTIVE TOO NEAR" :
  3731. executionAuthorizationState == 2 ?
  3732. (displayExecutionDirection == 1 ? "BULLISH CRT AT SSL / POI" : "BEARISH CRT AT BSL / POI") :
  3733. executionAuthorizationState == 1 ? "LIQUIDITY / POI + ALIGNED CRT" :
  3734. "WAIT PARENT STORY") :
  3735. executionChildMode ?
  3736. (inheritedFreshNarrative and inheritedFreshValidationPending ? "WAIT PARENT VALIDATION" :
  3737. inheritedFreshNarrative and inheritedFreshValidationRejected ? "WAIT NEXT PARENT CRT" :
  3738. inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? "ALIGNED CRT CONTEXT" :
  3739. inheritedNarrativeArchived ? "WAIT NEW QUALIFIED PARENT CRT" :
  3740. htfBiasInheritanceLock ?
  3741. (displayExecutionDirection == 1 ? "BULLISH LTF CRT" : "BEARISH LTF CRT") :
  3742. "WAIT PARENT STORY") :
  3743. hasFreshNarrativeIdentity and freshValidationState == 1 ? "WAIT VALIDATION" :
  3744. hasFreshNarrativeIdentity and freshValidationState == 3 ? "WAIT NEXT QUALIFIED CRT" :
  3745. localNarrativeRearmed ? "ALIGNED CRT CONTEXT" :
  3746. localNarrativeArchived ? "WAIT NEW QUALIFIED CRT" :
  3747. tradeReversalActive ?
  3748. (executionDirection == 1 ? "BULLISH LTF CRT" : "BEARISH LTF CRT") :
  3749. tradeReady or tradeWatch ?
  3750. (executionDirection == 1 ? "ALIGNED BULLISH CRT" : executionDirection == -1 ? "ALIGNED BEARISH CRT" : "ALIGNED LTF CRT") :
  3751. "HTF RANGE + PURGE"
  3752.  
  3753. string dashboardExecutionState =
  3754. executionChildMode and enableExecutionAuthorizationEngine ? executionAuthorizationStateText :
  3755. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationPending ? "LOCKED • VALIDATING PARENT" :
  3756. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationRejected ? "LOCKED • PARENT REJECTED" :
  3757. executionChildMode and inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? "RE-ARMED • SCANNING NEW STORY" :
  3758. executionChildMode and inheritedNarrativeArchived ? "LOCKED • OLD PARENT ARCHIVED" :
  3759. not executionChildMode and localNarrativeArchived ? "LOCKED • OLD NARRATIVE ARCHIVED" :
  3760. htfBiasInheritanceLock and (inheritedOpposingLocalCRT or localStoryOpposed) ? "OPPOSED • IGNORE" :
  3761. htfBiasInheritanceLock and (inheritedAlignedLocalCRT or localStoryAligned) ? "CONFIRMED" :
  3762. qualifiedLTFStructure ? "CONFIRMED" :
  3763. structureEngineUnlocked ? "UNLOCKED • SCANNING" :
  3764. executionTimeframeAllowed and not insideDistributionWindow ? "LOCKED • WAIT WINDOW" :
  3765. tradeReversalActive or crtLifecycleActive ? "LOCKED • MOVE TO LTF" :
  3766. "LOCKED"
  3767.  
  3768. color dashboardExecutionStateColor =
  3769. parentStandDownDisplay ? color.new(color.orange, 65) :
  3770. localStandDownDisplay ? color.new(color.orange, 65) :
  3771. executionChildMode and enableExecutionAuthorizationEngine ? executionAuthorizationStateColor :
  3772. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationPending ? color.new(color.orange, 62) :
  3773. executionChildMode and inheritedFreshNarrative and inheritedFreshValidationRejected ? color.new(color.red, 58) :
  3774. executionChildMode and inheritedNarrativeRearmedRaw and htfBiasInheritanceLock ? color.new(color.green, 58) :
  3775. executionChildMode and inheritedTargetReachedRaw ? color.new(color.green, 72) :
  3776. executionChildMode and (inheritedInvalidRaw or inheritedExpiredRaw) ? color.new(color.gray, 72) :
  3777. htfBiasInheritanceLock and (inheritedOpposingLocalCRT or localStoryOpposed) ? color.new(color.red, 58) :
  3778. htfBiasInheritanceLock and (inheritedAlignedLocalCRT or localStoryAligned) ? color.new(color.green, 58) :
  3779. qualifiedLTFStructure ? color.new(color.green, 58) :
  3780. structureEngineUnlocked ? color.new(color.orange, 62) :
  3781. color.new(color.gray, 78)
  3782.  
  3783.  
  3784. string dashboardNarrativeDelivery =
  3785. executionChildMode and inheritedNarrativeArchived ? "ARCHIVED • WAIT NEW STORY" :
  3786. not executionChildMode and localNarrativeArchived ? "ARCHIVED • WAIT NEW STORY" :
  3787. executionChildMode ? inheritedNarrativeTrackerText : narrativeTrackerStateText
  3788.  
  3789. string dashboardNarrativeObjective =
  3790. executionChildMode and inheritedNarrativeArchived ? "OLD OBJECTIVE CLOSED" :
  3791. not executionChildMode and localNarrativeArchived ? "OLD OBJECTIVE CLOSED" :
  3792. executionChildMode ? inheritedNarrativeObjectiveText : narrativeObjectiveText
  3793.  
  3794. color dashboardNarrativeTrackerColor =
  3795. dashboardStandDownDisplay ? color.new(color.gray, 72) :
  3796. executionChildMode ?
  3797. (
  3798. inheritedNarrativeTrackerStateRaw == 3 or
  3799. inheritedNarrativeTrackerStateRaw == 4 or
  3800. inheritedNarrativeTrackerStateRaw == 5 ?
  3801. color.new(color.green, 58) :
  3802. inheritedNarrativeTrackerStateRaw == 1 or
  3803. inheritedNarrativeTrackerStateRaw == 2 ?
  3804. color.new(color.orange, 62) :
  3805. inheritedNarrativeTrackerStateRaw == 6 or
  3806. inheritedNarrativeTrackerStateRaw == 8 ?
  3807. color.new(color.red, 58) :
  3808. color.new(color.gray, 78)
  3809. ) :
  3810. narrativeTrackerColor
  3811.  
  3812. string dashboardGrade = f_gradeText(latestCRTGradeCode)
  3813.  
  3814. string dashboardVerdict =
  3815. executionChildMode and inheritedNarrativeArchived ?
  3816. "PARENT #" + str.tostring(inheritedTerminalNarrativeIDRaw) + " ARCHIVED • WAIT NEW QUALIFIED PARENT CRT" :
  3817. not executionChildMode and localNarrativeArchived ?
  3818. "NARRATIVE #" + str.tostring(latestTerminalNarrativeID) + " ARCHIVED • WAIT NEW QUALIFIED CRT" :
  3819. executionChildMode ?
  3820. (htfBiasInheritanceLock ?
  3821. (localStoryOpposed or inheritedOpposingLocalCRT ?
  3822. inheritedParentStory + " • LOCAL STORY OPPOSED • IGNORE" :
  3823. localStoryAligned or inheritedAlignedLocalCRT ?
  3824. inheritedParentStory + " • LTF ALIGNED • CONFIRM RISK" :
  3825. inheritedParentStory + " • WAIT ALIGNED LTF CRT") :
  3826. inheritedParentStory) :
  3827. tradeReversalActive ?
  3828. localLifecycleText + " • " + dashboardFailure + " • WAIT LTF CONFIRMATION" :
  3829. localLifecycleText == "WAITING" ?
  3830. "WAITING FOR QUALIFIED CRT" :
  3831. dashboardGrade + " " + localLifecycleText + " • " +
  3832. (dashboardDelivery == "CONFIRMED" ? "DELIVERY CONFIRMED" : "WAIT FOR DELIVERY") +
  3833. (dashboardTarget != "NONE" ? " • DRAW " + dashboardTarget : "")
  3834.  
  3835. string dashboardDecisionLabel =
  3836. dashboardRoomFilterFailed ? "ROOM FILTER" :
  3837. htfBiasInheritanceLock ? "ACTION" : "ENGINE VERDICT"
  3838.  
  3839. string dashboardDecisionDisplay =
  3840. dashboardRoomFilterFailed ? "FAILED • NO CHASE" :
  3841. executionChildMode ? dashboardAction : dashboardVerdict
  3842.  
  3843. var table intelligenceDashboard = table.new(
  3844. f_dashboardPosition(dashboardPosition),
  3845. 2,
  3846. 29,
  3847. border_width = 1
  3848. )
  3849.  
  3850. if barstate.islast
  3851. if showIntelligenceDashboard
  3852. table.clear(intelligenceDashboard, 0, 0, 1, 28)
  3853. color headerBg = color.new(color.rgb(25, 25, 35), 5)
  3854. color labelBg = color.new(color.rgb(40, 40, 50), 15)
  3855. color verdictBg = color.new(color.rgb(20, 20, 30), 0)
  3856. color actionLabelBg = color.new(color.rgb(20, 20, 30), 0)
  3857. string marketTF = syminfo.ticker + " • " + timeframe.period
  3858. string txtSize = f_dashboardTextSize(dashboardTextSize)
  3859.  
  3860. table.cell(intelligenceDashboard, 0, 0, "ASH CRT INTELLIGENCE", bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3861. table.cell(intelligenceDashboard, 1, 0, marketTF, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3862.  
  3863. table.cell(intelligenceDashboard, 0, 1, "TRADE STATUS", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3864. table.cell(intelligenceDashboard, 1, 1, displayTradeStatus, bgcolor = f_tradeStatusColor(displayTradeStatus, displayExecutionDirection), text_color = color.white, text_size = txtSize)
  3865.  
  3866. table.cell(intelligenceDashboard, 0, 2, "HTF STORY", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3867. 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)
  3868.  
  3869. table.cell(intelligenceDashboard, 0, 3, "NEXT TF", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3870. table.cell(intelligenceDashboard, 1, 3, dashboardNextTF, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3871.  
  3872. table.cell(intelligenceDashboard, 0, 4, "HUNT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3873. 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)
  3874.  
  3875. table.cell(intelligenceDashboard, 0, 5, "EXECUTION", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3876. table.cell(intelligenceDashboard, 1, 5, dashboardExecutionState, bgcolor = dashboardExecutionStateColor, text_color = color.white, text_size = txtSize)
  3877.  
  3878. table.cell(intelligenceDashboard, 0, 6, "EXECUTION BIAS", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3879. 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)
  3880.  
  3881. table.cell(intelligenceDashboard, 0, 7, "ENTRY CONDITION", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3882. table.cell(intelligenceDashboard, 1, 7, displayEntryCondition, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3883.  
  3884. table.cell(intelligenceDashboard, 0, 8, "RISK STATE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3885. table.cell(intelligenceDashboard, 1, 8, displayRiskState, bgcolor = dashboardStandDownDisplay ? color.new(color.orange, 72) : 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)
  3886.  
  3887. table.cell(intelligenceDashboard, 0, 9, "SETUP AGE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3888. table.cell(intelligenceDashboard, 1, 9, displaySetupAge, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3889.  
  3890. table.cell(intelligenceDashboard, 0, 10, parentStandDownDisplay ? "LOCAL CRT (INFO)" : executionChildMode ? "LOCAL CRT" : "CRT STATE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3891. table.cell(intelligenceDashboard, 1, 10, executionChildMode ? dashboardLocalCRT : dashboardCRTState, bgcolor = f_stateColor(executionChildMode ? dashboardLocalImplication : dashboardCRTState), text_color = color.white, text_size = txtSize)
  3892.  
  3893. table.cell(intelligenceDashboard, 0, 11, "GRADE / SCORE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3894. table.cell(intelligenceDashboard, 1, 11, dashboardGrade + " • " + str.tostring(latestCRTIntelligenceScore) + "/10", bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3895.  
  3896. table.cell(intelligenceDashboard, 0, 12, "HTF CONTEXT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3897. table.cell(intelligenceDashboard, 1, 12, dashboardHTF, bgcolor = f_stateColor(dashboardHTF), text_color = color.white, text_size = txtSize)
  3898.  
  3899. table.cell(intelligenceDashboard, 0, 13, "KEY LEVEL / POI", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3900. table.cell(intelligenceDashboard, 1, 13, dashboardPOI, bgcolor = f_stateColor(dashboardPOI), text_color = color.white, text_size = txtSize)
  3901.  
  3902. table.cell(intelligenceDashboard, 0, 14, "LIQUIDITY PURGE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3903. table.cell(intelligenceDashboard, 1, 14, dashboardPurge, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3904.  
  3905. table.cell(intelligenceDashboard, 0, 15, "SMT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3906. table.cell(intelligenceDashboard, 1, 15, dashboardSMT, bgcolor = f_stateColor(dashboardSMT), text_color = color.white, text_size = txtSize)
  3907.  
  3908. table.cell(intelligenceDashboard, 0, 16, "NESTED CRT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3909. table.cell(intelligenceDashboard, 1, 16, dashboardNested, bgcolor = f_stateColor(dashboardNested), text_color = color.white, text_size = txtSize)
  3910.  
  3911. table.cell(intelligenceDashboard, 0, 17, parentStandDownDisplay ? "LOCAL INFO" : htfBiasInheritanceLock ? "LOCAL IMPLICATION" : "DELIVERY", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3912. table.cell(intelligenceDashboard, 1, 17, executionChildMode ? dashboardLocalImplication : dashboardDelivery, bgcolor = f_stateColor(executionChildMode ? dashboardLocalImplication : dashboardDelivery), text_color = color.white, text_size = txtSize)
  3913.  
  3914. table.cell(intelligenceDashboard, 0, 18, dashboardObjectiveLabel, bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3915. table.cell(intelligenceDashboard, 1, 18, dashboardObjectiveDisplay, bgcolor = dashboardRoomFilterFailed ? color.new(color.orange, 62) : headerBg, text_color = color.white, text_size = txtSize)
  3916.  
  3917. table.cell(intelligenceDashboard, 0, 19, dashboardLocalTargetLabel, bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3918. table.cell(intelligenceDashboard, 1, 19, dashboardLocalTargetDisplay, bgcolor = executionChildMode ? color.new(color.gray, 76) : f_stateColor(dashboardLocalTargetDisplay), text_color = color.white, text_size = txtSize)
  3919.  
  3920. table.cell(intelligenceDashboard, 0, 20, parentStandDownDisplay ? "PARENT LOCK" : htfBiasInheritanceLock ? "HTF ALIGNMENT" : "FAILURE CONTEXT", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3921. table.cell(intelligenceDashboard, 1, 20, executionChildMode ? dashboardHTFAlignment : dashboardFailure, bgcolor = dashboardRoomFilterFailed ? color.new(color.green, 68) : f_stateColor(executionChildMode ? dashboardHTFAlignment : dashboardFailure), text_color = color.white, text_size = txtSize)
  3922.  
  3923. table.cell(intelligenceDashboard, 0, 21, dashboardDecisionLabel, bgcolor = verdictBg, text_color = color.white, text_size = txtSize)
  3924. table.cell(intelligenceDashboard, 1, 21, dashboardDecisionDisplay, bgcolor = dashboardRoomFilterFailed ? color.new(color.orange, 55) : verdictBg, text_color = color.white, text_size = txtSize)
  3925.  
  3926. table.cell(intelligenceDashboard, 0, 22, "KEY LEVEL TF", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3927. table.cell(intelligenceDashboard, 1, 22, dashboardKeyLevelTF, bgcolor = headerBg, text_color = color.white, text_size = txtSize)
  3928.  
  3929. table.cell(intelligenceDashboard, 0, 23, "KEY LEVEL ENGINE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3930. 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)
  3931.  
  3932. table.cell(intelligenceDashboard, 0, 24, "NARRATIVE ENGINE", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3933. 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)
  3934.  
  3935. table.cell(intelligenceDashboard, 0, 25, "NARRATIVE MEMORY", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3936. 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)
  3937.  
  3938. table.cell(intelligenceDashboard, 0, 26, "FRESH VALIDATION", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3939. 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)
  3940.  
  3941. table.cell(intelligenceDashboard, 0, 27, "NARRATIVE DELIVERY", bgcolor = actionLabelBg, text_color = color.white, text_size = txtSize)
  3942. table.cell(intelligenceDashboard, 1, 27, dashboardNarrativeDelivery, bgcolor = dashboardNarrativeTrackerColor, text_color = color.white, text_size = txtSize)
  3943.  
  3944. table.cell(intelligenceDashboard, 0, 28, "NARRATIVE OBJECTIVE", bgcolor = labelBg, text_color = color.silver, text_size = txtSize)
  3945. table.cell(intelligenceDashboard, 1, 28, dashboardNarrativeObjective, bgcolor = dashboardNarrativeTrackerColor, text_color = color.white, text_size = txtSize)
  3946. else
  3947. table.clear(intelligenceDashboard, 0, 0, 1, 28)
  3948.  
  3949. //======================================================================
  3950. // 15. ALERTS
  3951. //======================================================================
  3952. bool narrativeRearmSignal =
  3953. executionChildMode ? inheritedNarrativeRearmedRaw : localNarrativeRearmed
  3954.  
  3955. //----------------------------------------------------------------------
  3956. // v20.9.1 Forward-Test Runtime Alert Engine.
  3957. // These alert() calls do not consume plot slots. They are deliberately
  3958. // transition-based and fire once per confirmed bar. In TradingView, create
  3959. // one alert and select: "Any alert() function call".
  3960. //----------------------------------------------------------------------
  3961. int forwardAlertParentID = executionChildMode ? inheritedQualifiedNarrativeIDRaw : latestQualifiedNarrativeID
  3962. int forwardAlertDirection =
  3963. executionChildMode ?
  3964. (inheritedFreshDirectionRaw != 0 ? inheritedFreshDirectionRaw : inheritedHTFDirection) :
  3965. latestNarrativeDirection
  3966. string forwardAlertDirectionText = forwardAlertDirection == 1 ? "BULLISH" : forwardAlertDirection == -1 ? "BEARISH" : "NEUTRAL"
  3967. string forwardAlertParentTF = executionChildMode ? inheritanceParentTF : timeframe.period
  3968. float forwardAlertObjective = executionChildMode ? inheritedNarrativeObjectiveRaw : activeDrawTarget
  3969. string forwardAlertObjectiveText = na(forwardAlertObjective) ? "N/A" : str.tostring(forwardAlertObjective, format.mintick)
  3970. string forwardAlertPrefix = "Ash CRT v20.9.1 | " + syminfo.ticker + " | Chart " + timeframe.period + " | Parent " + forwardAlertParentTF + " | "
  3971.  
  3972. bool forwardParentConfirmedEvent =
  3973. executionChildMode ?
  3974. inheritedFreshValidationConfirmed and (
  3975. not inheritedFreshValidationConfirmed[1] or
  3976. inheritedQualifiedNarrativeIDRaw != inheritedQualifiedNarrativeIDRaw[1]
  3977. ) :
  3978. freshValidationConfirmed and (
  3979. not freshValidationConfirmed[1] or
  3980. latestQualifiedNarrativeID != latestQualifiedNarrativeID[1]
  3981. )
  3982.  
  3983. bool forwardExecutionArmedEvent = executionAuthorizationState == 2 and executionAuthorizationState[1] != 2
  3984. bool forwardEntryConfirmedEvent = executionAuthorizationState == 3 and executionAuthorizationState[1] != 3
  3985. bool forwardDeliveryNoReentryEvent = executionAuthorizationState == 4 and executionAuthorizationState[1] != 4
  3986.  
  3987. bool forwardParentObjectiveCompletedEvent =
  3988. executionChildMode ?
  3989. inheritedNarrativeTrackerStateRaw == 5 and inheritedNarrativeTrackerStateRaw[1] != 5 :
  3990. narrativeTrackerState == 5 and narrativeTrackerState[1] != 5
  3991.  
  3992. bool forwardParentRejectedEvent =
  3993. executionChildMode ?
  3994. inheritedFreshValidationRejected and not inheritedFreshValidationRejected[1] :
  3995. freshValidationRejected and not freshValidationRejected[1]
  3996.  
  3997. bool forwardParentInvalidatedEvent =
  3998. executionChildMode ?
  3999. inheritedInvalidRaw and not inheritedInvalidRaw[1] :
  4000. tradeInvalid and not tradeInvalid[1]
  4001.  
  4002. bool forwardParentExpiredEvent =
  4003. executionChildMode ?
  4004. inheritedExpiredRaw and not inheritedExpiredRaw[1] :
  4005. tradeExpired and not tradeExpired[1]
  4006.  
  4007. bool forwardNoChaseEvent = executionAuthorizationNoChase and not executionAuthorizationNoChase[1]
  4008.  
  4009. if enableForwardTestAlerts and barstate.isconfirmed
  4010. if alertParentConfirmed and forwardParentConfirmedEvent
  4011. alert(
  4012. forwardAlertPrefix + "PARENT CONFIRMED 4/4 | " + forwardAlertDirectionText + " | Narrative #" + str.tostring(forwardAlertParentID) + " | Objective " + forwardAlertObjectiveText,
  4013. alert.freq_once_per_bar_close
  4014. )
  4015.  
  4016. if alertExecutionArmed and forwardExecutionArmedEvent
  4017. alert(
  4018. forwardAlertPrefix + "EXECUTION ARMED | " + forwardAlertDirectionText + " | Narrative #" + str.tostring(executionAuthorizationParentID) + " | Wait aligned qualified LTF CRT",
  4019. alert.freq_once_per_bar_close
  4020. )
  4021.  
  4022. if alertEntryConfirmed and forwardEntryConfirmedEvent
  4023. alert(
  4024. forwardAlertPrefix + "ENTRY CONFIRMED | " + forwardAlertDirectionText + " | Narrative #" + str.tostring(executionAuthorizationParentID) + " | One-shot authorization consumed | Entry " + str.tostring(executionAuthorizationEntryPrice, format.mintick),
  4025. alert.freq_once_per_bar_close
  4026. )
  4027.  
  4028. if alertDeliveryNoReentry and forwardDeliveryNoReentryEvent
  4029. alert(
  4030. forwardAlertPrefix + "DELIVERY IN PROGRESS | Narrative #" + str.tostring(executionAuthorizationParentID) + " | NO RE-ENTRY | Manage the authorized execution",
  4031. alert.freq_once_per_bar_close
  4032. )
  4033.  
  4034. if alertParentObjectiveCompleted and forwardParentObjectiveCompletedEvent
  4035. alert(
  4036. forwardAlertPrefix + "PARENT OBJECTIVE COMPLETED | Narrative #" + str.tostring(forwardAlertParentID) + " | STAND DOWN | No chase",
  4037. alert.freq_once_per_bar_close
  4038. )
  4039.  
  4040. if alertParentRejectedInvalidated and forwardParentRejectedEvent
  4041. alert(
  4042. forwardAlertPrefix + "PARENT CANDIDATE PERMANENTLY REJECTED | Narrative #" + str.tostring(forwardAlertParentID) + " | Wait newer parent CRT",
  4043. alert.freq_once_per_bar_close
  4044. )
  4045.  
  4046. if alertParentRejectedInvalidated and forwardParentInvalidatedEvent
  4047. alert(
  4048. forwardAlertPrefix + "PARENT NARRATIVE INVALIDATED | Narrative #" + str.tostring(forwardAlertParentID) + " | Execution locked",
  4049. alert.freq_once_per_bar_close
  4050. )
  4051.  
  4052. if alertParentRejectedInvalidated and forwardParentExpiredEvent
  4053. alert(
  4054. forwardAlertPrefix + "PARENT NARRATIVE EXPIRED | Narrative #" + str.tostring(forwardAlertParentID) + " | Wait new parent CRT",
  4055. alert.freq_once_per_bar_close
  4056. )
  4057.  
  4058. if alertNoChase and forwardNoChaseEvent
  4059. alert(
  4060. forwardAlertPrefix + "NO CHASE | Parent objective too near or no valid room | Narrative #" + str.tostring(executionAuthorizationParentID) + " | Objective " + forwardAlertObjectiveText,
  4061. alert.freq_once_per_bar_close
  4062. )
  4063.  
  4064. alertcondition(
  4065. narrativeTrackerState == 3 and narrativeTrackerState[1] != 3,
  4066. "Ash CRT — Narrative Delivery Active",
  4067. "The validated CRT narrative has started directional delivery on {{ticker}} {{interval}}."
  4068. )
  4069.  
  4070. alertcondition(
  4071. narrativeTrackerState == 4 and narrativeTrackerState[1] != 4,
  4072. "Ash CRT — Narrative Objective Near",
  4073. "The active CRT narrative is approaching its selected objective on {{ticker}} {{interval}}."
  4074. )
  4075.  
  4076. alertcondition(
  4077. narrativeTrackerState == 5 and narrativeTrackerState[1] != 5,
  4078. "Ash CRT — Narrative Objective Completed",
  4079. "The active CRT narrative completed its selected objective on {{ticker}} {{interval}}. Stand down and avoid chasing."
  4080. )
  4081.  
  4082. alertcondition(
  4083. narrativeTrackerState == 8 and narrativeTrackerState[1] != 8,
  4084. "Ash CRT — Narrative Permanently Rejected",
  4085. "The fresh CRT narrative failed validation and its narrative ID is permanently rejected on {{ticker}} {{interval}}."
  4086. )
  4087.  
  4088. alertcondition(
  4089. narrativeRearmSignal and not narrativeRearmSignal[1],
  4090. "Ash CRT — Narrative Re-Armed",
  4091. "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."
  4092. )
  4093.  
  4094. alertcondition(
  4095. tradeReady and not tradeReady[1],
  4096. "Ash CRT — Trade Status READY",
  4097. "CRT Trade Readiness Engine changed to READY on {{ticker}} {{interval}}. Confirm execution and risk before entry."
  4098. )
  4099.  
  4100. alertcondition(
  4101. tradeReversalActive and not tradeReversalActive[1],
  4102. "Ash CRT — Reversal Context Active",
  4103. "CRT failure created an opposite-direction reversal context on {{ticker}} {{interval}}. Wait for aligned lower-timeframe CRT confirmation."
  4104. )
  4105.  
  4106. alertcondition(
  4107. tradeInvalid and not tradeInvalid[1],
  4108. "Ash CRT — Trade Status INVALID",
  4109. "The tracked CRT trade state changed to INVALID on {{ticker}} {{interval}}."
  4110. )
  4111.  
  4112. alertcondition(
  4113. tradeTargetReached and not tradeTargetReached[1],
  4114. "Ash CRT — Trade Status TARGET REACHED",
  4115. "The tracked CRT trade state changed to TARGET REACHED on {{ticker}} {{interval}}. Avoid chasing completed delivery."
  4116. )
  4117.  
  4118. alertcondition(
  4119. gradeAPlusCRT,
  4120. "Ash CRT — A+ Intelligence Grade",
  4121. "A+ CRT intelligence grade confirmed on {{ticker}} {{interval}}."
  4122. )
  4123.  
  4124. alertcondition(
  4125. gradeACRT,
  4126. "Ash CRT — A Intelligence Grade",
  4127. "A-grade CRT intelligence setup confirmed on {{ticker}} {{interval}}."
  4128. )
  4129.  
  4130.  
  4131. alertcondition(
  4132. newDrawTargetReached,
  4133. "Ash CRT — Draw on Liquidity Target Reached",
  4134. "The active CRT reached its selected draw-on-liquidity target on {{ticker}} {{interval}}."
  4135. )
  4136.  
  4137.  
  4138. alertcondition(
  4139. failedCRTEvent and failedCRTReversalDirection == 1,
  4140. "Ash CRT — Failed Bearish CRT / Bullish Reversal Context",
  4141. "A qualified bearish CRT failed through its manipulated-side boundary. Bullish reversal context detected on {{ticker}} {{interval}}."
  4142. )
  4143.  
  4144. alertcondition(
  4145. failedCRTEvent and failedCRTReversalDirection == -1,
  4146. "Ash CRT — Failed Bullish CRT / Bearish Reversal Context",
  4147. "A qualified bullish CRT failed through its manipulated-side boundary. Bearish reversal context detected on {{ticker}} {{interval}}."
  4148. )
  4149.  
  4150.  
  4151. alertcondition(
  4152. meaningfulDeliveryContext and not meaningfulDeliveryContext[1],
  4153. "Ash CRT — Displacement Delivery Confirmed",
  4154. "Post-manipulation displacement and directional delivery confirmed on {{ticker}} {{interval}}."
  4155. )
  4156.  
  4157.  
  4158. alertcondition(
  4159. qualifiedCRT and meaningfulLiquidityPurge,
  4160. "Ash CRT — Qualified CRT with Meaningful Liquidity Purge",
  4161. "Qualified CRT also purged meaningful external liquidity on {{ticker}} {{interval}}."
  4162. )
  4163.  
  4164. alertcondition(
  4165. qualifiedCRT and meaningfulNestedContext,
  4166. "Ash CRT — Qualified CRT Nested in Active HTF Context",
  4167. "Qualified CRT is nested or aligned inside an active parent-timeframe CRT context on {{ticker}} {{interval}}."
  4168. )
  4169.  
  4170.  
  4171. alertcondition(
  4172. bullishManipulation,
  4173. "Ash CRT — Qualified Bullish Manipulation",
  4174. "Qualified bullish CRT manipulation confirmed on {{ticker}} {{interval}}. Range low was purged."
  4175. )
  4176.  
  4177. alertcondition(
  4178. bearishManipulation,
  4179. "Ash CRT — Qualified Bearish Manipulation",
  4180. "Qualified bearish CRT manipulation confirmed on {{ticker}} {{interval}}. Range high was purged."
  4181. )
  4182.  
  4183.  
  4184. alertcondition(
  4185. crtTargetReached and not crtTargetReached[1],
  4186. "Ash CRT — Opposite-Side Target Reached",
  4187. "The active CRT reached its opposite-side Range target on {{ticker}} {{interval}}."
  4188. )
  4189.  
  4190. alertcondition(
  4191. crtInvalidated and not crtInvalidated[1],
  4192. "Ash CRT — Active CRT Invalidated",
  4193. "The active CRT was invalidated through its manipulated-side boundary on {{ticker}} {{interval}}."
  4194. )
  4195.  
  4196. alertcondition(
  4197. crtExpired and not crtExpired[1],
  4198. "Ash CRT — Active CRT Expired",
  4199. "The active CRT expired before opposite-side delivery on {{ticker}} {{interval}}."
  4200. )
  4201.  
  4202.  
  4203. alertcondition(
  4204. bullishSMT and not bullishSMT[1],
  4205. "Ash CRT — Bullish SMT Detected",
  4206. "Bullish SMT divergence detected between {{ticker}} and the configured comparison market on {{interval}}."
  4207. )
  4208.  
  4209. alertcondition(
  4210. bearishSMT and not bearishSMT[1],
  4211. "Ash CRT — Bearish SMT Detected",
  4212. "Bearish SMT divergence detected between {{ticker}} and the configured comparison market on {{interval}}."
  4213. )
  4214.  
  4215. alertcondition(
  4216. bullishLTFStructure,
  4217. "Ash CRT — Bullish LTF Structure Confirmed",
  4218. "Bullish lower-timeframe CRT structure confirmed inside the qualified HTF Distribution window on {{ticker}} {{interval}}."
  4219. )
  4220.  
  4221. alertcondition(
  4222. bearishLTFStructure,
  4223. "Ash CRT — Bearish LTF Structure Confirmed",
  4224. "Bearish lower-timeframe CRT structure confirmed inside the qualified HTF Distribution window on {{ticker}} {{interval}}."
  4225. )
  4226.  
  4227.  
Add Comment
Please, Sign In to add comment