AshICT

chatgpt code

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