AshICT

🚨 ASH ICT CRT PROTOCOL ENGINE — BETA TEST 🚨

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