Novelty_ua

Untitled

Nov 30th, 2025
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.30 KB | None | 0 0
  1. //@version=6
  2. indicator("Fractal Model Pro - TTrades (modular, v6)", overlay=true, max_labels_count=500, max_lines_count=500, max_boxes_count=200)
  3.  
  4. // ======================================================
  5. // =============== FRAMEWORK & INPUTS MODULE ============
  6. // ======================================================
  7. enable_module_cisd = input.bool(true, "Enable CISD Module")
  8. enable_module_smt = input.bool(true, "Enable SMT Module")
  9. enable_module_structure = input.bool(true, "Enable Market Structure (CHoCH/BOS)")
  10. enable_module_proj = input.bool(true, "Enable Projections")
  11. enable_module_htf = input.bool(true, "Enable HTF Candles")
  12. enable_module_history = input.bool(true, "Enable History (30 setups)")
  13. enable_info_panel = input.bool(true, "Show Info Panel")
  14.  
  15. use_time_filter = input.bool(true, "Use Time Filters (Hybrid)")
  16. tf1_on = input.bool(true, "Enable Filter 1")
  17. tf1_session = input.session("0000-2359", "Filter 1 Session (hhmm-hhmm)")
  18. tf2_on = input.bool(false, "Enable Filter 2")
  19. tf2_session = input.session("0000-2359", "Filter 2 Session (hhmm-hhmm)")
  20. tf3_on = input.bool(false, "Enable Filter 3")
  21. tf3_session = input.session("0000-2359", "Filter 3 Session (hhmm-hhmm)")
  22.  
  23. ndm_auto_bias = input.bool(true, "Automatic NDM Bias (Auto)")
  24. bias_manual = input.string("Auto", "Manual Bias Override", options=["Auto", "Bullish", "Bearish"])
  25. use_next_day_model = input.bool(true, "Use Next-Day Model (NDM) rules for bias")
  26.  
  27. smt_master_toggle = input.bool(true, "Master SMT Toggle")
  28. smt_require_for_cisd = input.bool(false, "Require SMT to confirm CISD (optional)")
  29. smt1_use = input.bool(true, "Use SMT Pair 1")
  30. smt1_symA = input.symbol("TVC:DXY", "SMT Pair 1 - Symbol A")
  31. smt1_symB = input.symbol("FX:EURUSD", "SMT Pair 1 - Symbol B")
  32. smt1_inverse = input.bool(false, "Invert Pair 1?")
  33. smt_pivot_len = input.int(3, "SMT Pivot Lookback (bars)", minval=1)
  34.  
  35. ms_pivot_len = input.int(3, "Structure Pivot Length (fractal)", minval=1)
  36. ms_min_range = input.float(0.0, "Min range (percent) to count as structure move", step=0.1)
  37. ms_detect_choch = input.bool(true, "Detect CHoCH (Change of Character)")
  38. ms_detect_bos = input.bool(true, "Detect BOS (Break of Structure)")
  39.  
  40. c2_body_ratio_threshold = input.float(0.5, "C2 Body Ratio Threshold (0-1)", step=0.05)
  41. c2_wick_body_ratio = input.float(1.5, "C2 Wick / Body Ratio", step=0.1)
  42. c2_max_bars_to_c3 = input.int(20, "Max bars to wait for C3 (XC2 timeout)")
  43.  
  44. c3_wick_not_through_c2_eq = input.bool(true, "C3 wick must not go through C2 EQ")
  45. c4_max_bars_to_wait = input.int(200, "Max bars to wait for C4 after CISD (XC4 timeout)", minval=1)
  46.  
  47. proj_master_toggle = input.bool(true, "Enable Projections")
  48. proj_mode = input.string("Both", "Projection Mode", options=["Model", "EQ/Fib", "Both"])
  49. proj_show_plus1 = input.bool(true, "+1")
  50. proj_show_0 = input.bool(true, "0 (EQ)")
  51. proj_show_minus1 = input.bool(true, "-1")
  52. proj_show_minus2 = input.bool(true, "-2")
  53. proj_show_minus25 = input.bool(true, "-2.5")
  54. proj_show_minus4 = input.bool(true, "-4")
  55. proj_show_minus45 = input.bool(true, "-4.5")
  56. proj_extend_right = input.bool(true, "Extend Projections Right")
  57. proj_anchor_body_or_wick = input.string("Body", "Projection Anchor", options=["Body", "Wick"])
  58.  
  59. show_htf_overlay = input.bool(true, "Show HTF Candle Overlay")
  60. htf_map = input.string("Auto", "HTF Mapping Mode", options=["Auto", "Manual"])
  61. htf_manual_tf = input.timeframe("60", "Manual HTF timeframe (when HTF Mapping = Manual)")
  62. htf_show_last_n = input.int(3, "Show last n HTF candles", minval=1, maxval=6)
  63. htf_box_fill_opacity = input.int(80, "HTF box fill opacity (0-255)", minval=0, maxval=255)
  64. htf_body_thickness = input.int(8, "HTF body thickness (visual)", minval=1, maxval=50)
  65.  
  66. show_eq_htf = input.bool(true, "Show HTF EQ (0/50/100)")
  67. show_eq_cisd = input.bool(true, "Show CISD EQ (mid-body)")
  68.  
  69. history_enabled = input.bool(true, "Save setups to History")
  70. history_max_entries = input.int(30, "Max History Setups", minval=1, maxval=200)
  71.  
  72. theme_mode = input.string("Modern", "Theme", options=["TTrades Classic", "Modern", "Dark"])
  73. col_proj = input.color(color.new(color.blue, 0), "Projection Color")
  74. col_cisd_bull = input.color(color.new(color.green, 0), "CISD Bull Color")
  75. col_cisd_bear = input.color(color.new(color.red, 0), "CISD Bear Color")
  76. col_htf_bull = input.color(color.new(color.teal, 80), "HTF Bull Fill")
  77. col_htf_bear = input.color(color.new(color.maroon, 80), "HTF Bear Fill")
  78.  
  79. alerts_enabled = input.bool(true, "Enable alerts")
  80. security_request_budget = input.int(12, "Security call budget (max simultaneous)", minval=1, maxval=40)
  81.  
  82. debug_mode = input.bool(false, "Debug mode (show extra labels)")
  83.  
  84. // ------------------------------------------------------
  85. // Helpers
  86. // ------------------------------------------------------
  87. inside_time_filter() =>
  88. if not use_time_filter
  89. true
  90. else
  91. s1 = tf1_on ? not na(time(timeframe.period, tf1_session)) : false
  92. s2 = tf2_on ? not na(time(timeframe.period, tf2_session)) : false
  93. s3 = tf3_on ? not na(time(timeframe.period, tf3_session)) : false
  94. s1 or s2 or s3
  95.  
  96.  
  97. body_size(o,c) => math.abs(c - o)
  98. candle_range(h,l) => (h - l)
  99. body_ratio(o,h,l,c) => (candle_range(h,l) == 0.0) ? 0.0 : math.abs(c - o) / candle_range(h,l)
  100.  
  101. // safe security wrapper (simple)
  102. safe_request(sym, tf, expr) =>
  103. // in heavy scripts we'd gate by security_request_budget
  104. request.security(sym, tf, expr)
  105.  
  106. // ======================================================
  107. // Module A: Market Structure (CHoCH / BOS)
  108. // ======================================================
  109. var float ms_last_swing_high = na
  110. var float ms_last_swing_low = na
  111. var bool ms_bos_bull = false
  112. var bool ms_bos_bear = false
  113. var bool ms_choch_bull = false
  114. var bool ms_choch_bear = false
  115. var int ms_trend = 0
  116.  
  117. if not enable_module_structure
  118. var int ms_trend1 = 0
  119.  
  120.  
  121. else
  122. var float prev_sh_price = na
  123. var int prev_sh_bar = na
  124. var float last_sh_price = na
  125. var int last_sh_bar = na
  126. var float prev_sl_price = na
  127. var int prev_sl_bar = na
  128. var float last_sl_price = na
  129. var int last_sl_bar = na
  130.  
  131.  
  132.  
  133. ph = ta.pivothigh(high, ms_pivot_len, ms_pivot_len)
  134. pl = ta.pivotlow(low, ms_pivot_len, ms_pivot_len)
  135.  
  136. if not na(ph)
  137. pivot_bar = bar_index - ms_pivot_len
  138. pivot_price = ph
  139. prev_sh_price := last_sh_price
  140. prev_sh_bar := last_sh_bar
  141. last_sh_price := pivot_price
  142. last_sh_bar := pivot_bar
  143. if debug_mode
  144. label.new(pivot_bar, pivot_price, "SH", style=label.style_label_down, color=color.orange, textcolor=color.white)
  145.  
  146. if not na(pl)
  147. pivot_bar = bar_index - ms_pivot_len
  148. pivot_price = pl
  149. prev_sl_price := last_sl_price
  150. prev_sl_bar := last_sl_bar
  151. last_sl_price := pivot_price
  152. last_sl_bar := pivot_bar
  153. if debug_mode
  154. label.new(pivot_bar, pivot_price, "SL", style=label.style_label_up, color=color.teal, textcolor=color.white)
  155.  
  156. if not na(prev_sh_price) and not na(last_sh_price) and not na(prev_sl_price) and not na(last_sl_price)
  157. up_condition = (last_sh_price > prev_sh_price) and (last_sl_price > prev_sl_price)
  158. down_condition = (last_sh_price < prev_sh_price) and (last_sl_price < prev_sl_price)
  159. if up_condition
  160. ms_trend := 1
  161. else if down_condition
  162. ms_trend := -1
  163. else
  164. ms_trend := 0
  165. else
  166. ms_trend := 0
  167.  
  168. ms_bos_bull := false
  169. ms_bos_bear := false
  170. if not na(prev_sh_price)
  171. if close > prev_sh_price
  172. ms_bos_bull := true
  173. if not na(prev_sl_price)
  174. if close < prev_sl_price
  175. ms_bos_bear := true
  176.  
  177. ms_choch_bull := false
  178. ms_choch_bear := false
  179. if ms_detect_choch
  180. if ms_trend == 1 and ms_bos_bear
  181. ms_choch_bear := true
  182. if ms_trend == -1 and ms_bos_bull
  183. ms_choch_bull := true
  184.  
  185. if debug_mode
  186. ttxt = ms_trend == 1 ? "Trend: UP" : ms_trend == -1 ? "Trend: DOWN" : "Trend: N"
  187. label.new(bar_index, high, ttxt, style=label.style_label_left, color=color.new(color.blue, 90), textcolor=color.white, size=size.small)
  188.  
  189. if ms_bos_bull and ms_detect_bos
  190. label.new(bar_index, high, "BOS↑", style=label.style_label_down, color=color.new(color.green, 0), textcolor=color.white, size=size.small)
  191. if ms_bos_bear and ms_detect_bos
  192. label.new(bar_index, low, "BOS↓", style=label.style_label_up, color=color.new(color.red, 0), textcolor=color.white, size=size.small)
  193.  
  194. if ms_choch_bull
  195. label.new(bar_index, low, "CHoCH↑", style=label.style_label_up, color=color.new(color.lime, 0), textcolor=color.black, size=size.small)
  196. if ms_choch_bear
  197. label.new(bar_index, high, "CHoCH↓", style=label.style_label_down, color=color.new(color.orange, 0), textcolor=color.black, size=size.small)
  198.  
  199. ms_last_swing_high := last_sh_price
  200. ms_last_swing_low := last_sl_price
  201.  
  202. // ======================================================
  203. // Module B: Liquidity Engine (Pools, Sweeps, Swings)
  204. // ======================================================
  205. liq_pool_lookback = input.int(20, "Liquidity Pool Lookback (bars)", minval=3)
  206. liq_pool_tol_pct = input.float(0.3, "Pool tolerance (%) - e.g. 0.3 = 0.3%", step=0.1)
  207. liq_sweep_threshold_atr = input.float(0.5, "Sweep threshold (ATR multiples)", step=0.1)
  208. liq_min_pool_hits = input.int(2, "Min hits in lookback to count as pool", minval=1)
  209. liq_history_max = input.int(30, "Max liquidity pool history entries", minval=1, maxval=200)
  210.  
  211. tol_price(p) => p * (liq_pool_tol_pct / 100.0)
  212. atr_val = ta.atr(14)
  213.  
  214. var bool liq_pool_high = false
  215. var bool liq_pool_low = false
  216. var bool liq_sweep_bear = false
  217. var bool liq_sweep_bull = false
  218.  
  219. var float last_pool_high_price = na
  220. var float last_pool_low_price = na
  221.  
  222. var float[] liq_pool_high_history = array.new_float()
  223. var float[] liq_pool_low_history = array.new_float()
  224.  
  225. ref_sh = float(na)
  226. ref_sl = float(na)
  227. if not na(ms_last_swing_high)
  228. ref_sh := ms_last_swing_high
  229. if not na(ms_last_swing_low)
  230. ref_sl := ms_last_swing_low
  231.  
  232. calc_pool_high() =>
  233. mh = ta.highest(high, liq_pool_lookback)
  234. t = tol_price(mh)
  235. cnt = 0
  236. for i = 0 to liq_pool_lookback - 1
  237. if math.abs(high[i] - mh) <= t
  238. cnt += 1
  239. [mh, cnt]
  240.  
  241. calc_pool_low() =>
  242. ml = ta.lowest(low, liq_pool_lookback)
  243. t = tol_price(ml)
  244. cnt = 0
  245. for i = 0 to liq_pool_lookback - 1
  246. if math.abs(low[i] - ml) <= t
  247. cnt += 1
  248. [ml, cnt]
  249.  
  250. [mh, mh_count] = calc_pool_high()
  251. [ml, ml_count] = calc_pool_low()
  252.  
  253. if mh_count >= liq_min_pool_hits and math.abs(high - mh) <= tol_price(mh)
  254. liq_pool_high := true
  255. last_pool_high_price := mh
  256. array.push(liq_pool_high_history, mh)
  257. if array.size(liq_pool_high_history) > liq_history_max
  258. array.shift(liq_pool_high_history)
  259. else
  260. liq_pool_high := false
  261.  
  262. if ml_count >= liq_min_pool_hits and math.abs(low - ml) <= tol_price(ml)
  263. liq_pool_low := true
  264. last_pool_low_price := ml
  265. array.push(liq_pool_low_history, ml)
  266. if array.size(liq_pool_low_history) > liq_history_max
  267. array.shift(liq_pool_low_history)
  268. else
  269. liq_pool_low := false
  270.  
  271. liq_sweep_bear := false
  272. liq_sweep_bull := false
  273.  
  274. if not na(ref_sh)
  275. wick_above = (high > ref_sh + (atr_val * liq_sweep_threshold_atr))
  276. close_back_inside = (close < ref_sh)
  277. if wick_above and close_back_inside
  278. liq_sweep_bear := true
  279. if debug_mode
  280. label.new(bar_index, high, "SweepHigh", color=color.red, style=label.style_label_down, textcolor=color.white)
  281.  
  282. if not na(ref_sl)
  283. wick_below = (low < ref_sl - (atr_val * liq_sweep_threshold_atr))
  284. close_back_inside_low = (close > ref_sl)
  285. if wick_below and close_back_inside_low
  286. liq_sweep_bull := true
  287. if debug_mode
  288. label.new(bar_index, low, "SweepLow", color=color.green, style=label.style_label_up, textcolor=color.white)
  289.  
  290. if debug_mode
  291. if not na(last_pool_high_price)
  292. label.new(bar_index, last_pool_high_price, "PoolH", color=color.new(color.orange, 60), style=label.style_label_left, textcolor=color.white)
  293. if not na(last_pool_low_price)
  294. label.new(bar_index, last_pool_low_price, "PoolL", color=color.new(color.blue, 60), style=label.style_label_left, textcolor=color.white)
  295.  
  296. // ======================================================
  297. // Module C: C2 / C3 Engine (Body-% version)
  298. // ======================================================
  299. var bool bullC2 = false
  300. var bool bearC2 = false
  301. var bool bullC3 = false
  302. var bool bearC3 = false
  303. var bool xc2 = false
  304. var bool xc4 = false
  305.  
  306. var int lastC2Bar = na
  307. var float lastC2High = na
  308. var float lastC2Low = na
  309. var float lastC2EQ = na
  310. var int lastC2Dir = 0
  311.  
  312. var int lastC3Bar = na
  313. var float lastC3Close = na
  314.  
  315. var float proj_anchor_price = na
  316. var bool proj_anchor_is_body = true
  317.  
  318. var int c2_wait_start_bar = na
  319. var int c4_wait_start_bar = na
  320. var bool awaiting_c4 = false
  321.  
  322. bullC2 := false
  323. bearC2 := false
  324. bullC3 := false
  325. bearC3 := false
  326. xc2 := false
  327. xc4 := false
  328.  
  329. curr_body_pct = body_ratio(open, high, low, close) * 100.0
  330. curr_body = math.abs(close - open)
  331. top_wick = high - math.max(open, close)
  332. bot_wick = math.min(open, close) - low
  333. wick_body_top_ratio = curr_body == 0 ? 9999.0 : (top_wick / curr_body)
  334. wick_body_bot_ratio = curr_body == 0 ? 9999.0 : (bot_wick / curr_body)
  335.  
  336. is_bull_body = close > open
  337. is_bear_body = open > close
  338.  
  339. cond_body_pct = curr_body_pct >= (c2_body_ratio_threshold * 100.0)
  340. wick_ok = (wick_body_top_ratio <= c2_wick_body_ratio) and (wick_body_bot_ratio <= c2_wick_body_ratio)
  341. tf_ok = inside_time_filter()
  342.  
  343. if tf_ok
  344. if is_bull_body and cond_body_pct and wick_ok
  345. bullC2 := true
  346. lastC2Bar := bar_index
  347. lastC2Dir := 1
  348. lastC2High := high
  349. lastC2Low := low
  350. lastC2EQ := math.min(open, close) + (math.abs(close - open) * 0.5)
  351. c2_wait_start_bar := bar_index
  352. lastC3Bar := na
  353. lastC3Close := na
  354. if debug_mode
  355. label.new(bar_index, low, "C2↑", style=label.style_label_up, color=color.new(color.lime,0), textcolor=color.black)
  356.  
  357. if is_bear_body and cond_body_pct and wick_ok
  358. bearC2 := true
  359. lastC2Bar := bar_index
  360. lastC2Dir := -1
  361. lastC2High := high
  362. lastC2Low := low
  363. lastC2EQ := math.min(open, close) + (math.abs(close - open) * 0.5)
  364. c2_wait_start_bar := bar_index
  365. lastC3Bar := na
  366. lastC3Close := na
  367. if debug_mode
  368. label.new(bar_index, high, "C2↓", style=label.style_label_down, color=color.new(color.orange,0), textcolor=color.white)
  369.  
  370. if not na(lastC2Bar)
  371. if lastC2Dir == 1 and bar_index > lastC2Bar
  372. if close > lastC2High
  373. if not c3_wick_not_through_c2_eq or (low >= lastC2EQ)
  374. bullC3 := true
  375. lastC3Bar := bar_index
  376. lastC3Close := close
  377. proj_anchor_is_body := (proj_anchor_body_or_wick == "Body")
  378. proj_anchor_price := proj_anchor_is_body ? (open + close) / 2.0 : high
  379. c2_wait_start_bar := na
  380. if debug_mode
  381. label.new(bar_index, low, "C3↑", style=label.style_label_up, color=color.new(color.green,0), textcolor=color.white)
  382. if lastC2Dir == -1 and bar_index > lastC2Bar
  383. if close < lastC2Low
  384. if not c3_wick_not_through_c2_eq or (high <= lastC2EQ)
  385. bearC3 := true
  386. lastC3Bar := bar_index
  387. lastC3Close := close
  388. proj_anchor_is_body := (proj_anchor_body_or_wick == "Body")
  389. proj_anchor_price := proj_anchor_is_body ? (open + close) / 2.0 : low
  390. c2_wait_start_bar := na
  391. if debug_mode
  392. label.new(bar_index, high, "C3↓", style=label.style_label_down, color=color.new(color.red,0), textcolor=color.white)
  393.  
  394. if not na(c2_wait_start_bar)
  395. bars_waited = bar_index - c2_wait_start_bar
  396. if bars_waited >= c2_max_bars_to_c3 and na(lastC3Bar)
  397. xc2 := true
  398. if debug_mode
  399. if lastC2Dir == 1
  400. label.new(lastC2Bar, lastC2Low, "XC2", style=label.style_label_left, color=color.new(color.gray,0), textcolor=color.white)
  401. else
  402. label.new(lastC2Bar, lastC2High, "XC2", style=label.style_label_left, color=color.new(color.gray,0), textcolor=color.white)
  403. c2_wait_start_bar := na
  404. lastC2Bar := na
  405. lastC2High := na
  406. lastC2Low := na
  407. lastC2EQ := na
  408. lastC2Dir := 0
  409.  
  410. if awaiting_c4 and not na(c4_wait_start_bar)
  411. if bar_index - c4_wait_start_bar >= c4_max_bars_to_wait
  412. xc4 := true
  413. awaiting_c4 := false
  414. c4_wait_start_bar := na
  415. if debug_mode
  416. label.new(bar_index, close, "XC4", style=label.style_label_center, color=color.new(color.gray,0), textcolor=color.white)
  417.  
  418. // ======================================================
  419. // Module D: CISD Finalization + History + T-Spot
  420. // ======================================================
  421. var bool smt_bull = false
  422. var bool smt_bear = false
  423.  
  424. show_tspot = input.bool(true, "Show T-Spot on CISD")
  425. tspot_label_size = input.string("small", "T-Spot label size", options=["tiny","small","normal","large"])
  426. history_draw_labels = input.bool(true, "Draw History Markers on Chart")
  427. history_label_color = input.color(color.new(color.gray, 20), "History marker color")
  428.  
  429. var int[] hist_time = array.new_int()
  430. var int[] hist_dir = array.new_int()
  431. var float[] hist_anchor = array.new_float()
  432. var string[] hist_outcome = array.new_string()
  433.  
  434. save_history(dir, anchor_price, outcome_str) =>
  435. array.push(hist_time, bar_index) // store bar_index for exact placement
  436. array.push(hist_dir, dir)
  437. array.push(hist_anchor, anchor_price)
  438. array.push(hist_outcome, outcome_str)
  439. while array.size(hist_time) > history_max_entries
  440. array.shift(hist_time)
  441. array.shift(hist_dir)
  442. array.shift(hist_anchor)
  443. array.shift(hist_outcome)
  444.  
  445. var bool final_cisd_bull = false
  446. var bool final_cisd_bear = false
  447. final_cisd_bull := false
  448. final_cisd_bear := false
  449.  
  450. cisd_require_sweep = input.bool(false, "CISD requires liquidity sweep?")
  451. cisd_require_msb = input.bool(false, "CISD requires BOS/CHoCH shift?")
  452. cisd_min_body_pct = input.float(30, "Min candle body % for displacement", minval=1, maxval=100)
  453.  
  454. is_displacement() =>
  455. body = math.abs(close - open)
  456. rng = high - low
  457. rng > 0 and ((body / rng) * 100.0) >= cisd_min_body_pct
  458.  
  459. // Finalize with SMT gating & history
  460. smt_ok_for_bull() =>
  461. if not smt_master_toggle
  462. true
  463. else
  464. if not smt_require_for_cisd
  465. true
  466. else
  467. smt_bull
  468.  
  469. smt_ok_for_bear() =>
  470. if not smt_master_toggle
  471. true
  472. else
  473. if not smt_require_for_cisd
  474. true
  475. else
  476. smt_bear
  477.  
  478.  
  479. if enable_module_cisd
  480. cisd_bear = false
  481. cisd_bull = false
  482.  
  483. bear_swing_break = not na(ms_last_swing_low) and close < ms_last_swing_low
  484. bear_liq = liq_sweep_bear or (not cisd_require_sweep)
  485. bear_shift = (ms_bos_bear or ms_choch_bear or not cisd_require_msb)
  486.  
  487. if ms_trend == 1 and is_displacement() and bear_swing_break and bear_liq and bear_shift
  488. // tentative cisd flag
  489. cisd_bear := true
  490. else
  491. cisd_bear := false
  492.  
  493. bull_swing_break = not na(ms_last_swing_high) and close > ms_last_swing_high
  494. bull_liq = liq_sweep_bull or (not cisd_require_sweep)
  495. bull_shift = (ms_bos_bull or ms_choch_bull or not cisd_require_msb)
  496.  
  497. if ms_trend == -1 and is_displacement() and bull_swing_break and bull_liq and bull_shift
  498. cisd_bull := true
  499. else
  500. cisd_bull := false
  501.  
  502.  
  503.  
  504. if cisd_bull and tf_ok
  505. if smt_ok_for_bull()
  506. final_cisd_bull := true
  507. c_anchor = not na(proj_anchor_price) ? proj_anchor_price : (not na(ms_last_swing_low) ? ms_last_swing_low : close)
  508. if history_enabled
  509. save_history(1, c_anchor, "valid")
  510. awaiting_c4 := true
  511. c4_wait_start_bar := bar_index
  512. if show_tspot
  513. lbltxt = "T↑"
  514. lblsize = tspot_label_size == "tiny" ? size.tiny : tspot_label_size == "small" ? size.small : tspot_label_size == "normal" ? size.normal : size.large
  515. label.new(bar_index, c_anchor, lbltxt, style=label.style_label_up, color=col_cisd_bull, textcolor=color.white, size=lblsize)
  516.  
  517. if cisd_bear and tf_ok
  518. if smt_ok_for_bear()
  519. final_cisd_bear := true
  520. c_anchor = not na(proj_anchor_price) ? proj_anchor_price : (not na(ms_last_swing_high) ? ms_last_swing_high : close)
  521. if history_enabled
  522. save_history(-1, c_anchor, "valid")
  523. awaiting_c4 := true
  524. c4_wait_start_bar := bar_index
  525. if show_tspot
  526. lbltxt = "T↓"
  527. lblsize = tspot_label_size == "tiny" ? size.tiny : tspot_label_size == "small" ? size.small : tspot_label_size == "normal" ? size.normal : size.large
  528. label.new(bar_index, c_anchor, lbltxt, style=label.style_label_down, color=col_cisd_bear, textcolor=color.white, size=lblsize)
  529.  
  530. if xc4
  531. anchor = not na(proj_anchor_price) ? proj_anchor_price : not na(lastC3Close) ? lastC3Close : close
  532. if history_enabled
  533. save_history(lastC2Dir == 1 ? 1 : -1, anchor, "xc4")
  534. awaiting_c4 := false
  535. c4_wait_start_bar := na
  536. if debug_mode
  537. label.new(bar_index, close, "XC4 Recorded", color=color.gray, textcolor=color.white)
  538.  
  539. if xc2
  540. anchor = not na(lastC2EQ) ? lastC2EQ : not na(lastC2High) ? lastC2High : close
  541. if history_enabled
  542. save_history(lastC2Dir == 1 ? 1 : -1, anchor, "xc2")
  543. if debug_mode
  544. label.new(bar_index, anchor, "XC2 Recorded", color=color.gray, textcolor=color.white)
  545.  
  546. // Draw history markers precisely using stored bar_index
  547. if history_enabled and history_draw_labels and hist_time.size() > 0
  548. draw_count = math.min(array.size(hist_time) - 1, math.min(history_max_entries, 20))
  549. for i = 0 to draw_count
  550. idx = array.size(hist_time) - 1 - i
  551. bi = array.get(hist_time, idx)
  552. dirn = array.get(hist_dir, idx)
  553. anc = array.get(hist_anchor, idx)
  554. out = array.get(hist_outcome, idx)
  555. marktxt = dirn == 1 ? "H↑" : "H↓"
  556. clr = dirn == 1 ? color.new(color.green, 30) : color.new(color.red, 30)
  557. // draw at saved bar index
  558. label.new(bi, anc, marktxt, color=history_label_color, textcolor=color.white, style=label.style_label_left, size=size.tiny)
  559.  
  560. // ======================================================
  561. // Module E: HTF Candle Engine & EQ
  562. // ======================================================
  563. get_auto_htf(string tf) =>
  564. // tf is current chart timeframe string or multiplier; map to HTF
  565. // We'll use simple mapping rules:
  566. // if current <= 5m -> 60, 15 -> 240, 60 -> D, 240 -> W, D -> M
  567. switch
  568. tf == "5" => "60"
  569. tf == "15" => "240"
  570. tf == "60" => "D"
  571. tf == "240" => "W"
  572. tf == "1D" => "M"
  573. => "D"
  574.  
  575. htf_tf = (htf_map == "Manual") ? htf_manual_tf : get_auto_htf(timeframe.period)
  576.  
  577. // Get last N HTF candles using request.security; fetch series of open/high/low/close with history
  578. htf_open_0 = request.security(syminfo.tickerid, htf_tf, open)
  579. htf_high_0 = request.security(syminfo.tickerid, htf_tf, high)
  580. htf_low_0 = request.security(syminfo.tickerid, htf_tf, low)
  581. htf_close_0= request.security(syminfo.tickerid, htf_tf, close)
  582.  
  583. htf_open_1 = request.security(syminfo.tickerid, htf_tf, open[1])
  584. htf_high_1 = request.security(syminfo.tickerid, htf_tf, high[1])
  585. htf_low_1 = request.security(syminfo.tickerid, htf_tf, low[1])
  586. htf_close_1= request.security(syminfo.tickerid, htf_tf, close[1])
  587.  
  588. htf_open_2 = request.security(syminfo.tickerid, htf_tf, open[2])
  589. htf_high_2 = request.security(syminfo.tickerid, htf_tf, high[2])
  590. htf_low_2 = request.security(syminfo.tickerid, htf_tf, low[2])
  591. htf_close_2= request.security(syminfo.tickerid, htf_tf, close[2])
  592.  
  593. draw_htf(offset, o,h,l,c) =>
  594. // draw simple lines representing candle: vertical wick + small body rectangle via two lines
  595. bodyTop = math.max(o, c)
  596. bodyBot = math.min(o, c)
  597. colorEdge = c > o ? color.green : color.red
  598. colorFill = c > o ? col_htf_bull : col_htf_bear
  599. // wick
  600. line.new(bar_index - offset, h, bar_index - offset, l, width=1, color=colorEdge)
  601. // body rectangle using two lines (left & right)
  602. line.new(bar_index - offset - 1, bodyTop, bar_index - offset - 1, bodyBot, width=htf_body_thickness, color=colorFill)
  603. // small horizontal caps
  604. line.new(bar_index - offset - 1, bodyTop, bar_index - offset + 1, bodyTop, color=colorEdge)
  605. line.new(bar_index - offset - 1, bodyBot, bar_index - offset + 1, bodyBot, color=colorEdge)
  606.  
  607. if enable_module_htf and show_htf_overlay and barstate.islast
  608. offset = 20
  609. draw_htf(offset, htf_open_0, htf_high_0, htf_low_0, htf_close_0)
  610. draw_htf(offset+6, htf_open_1, htf_high_1, htf_low_1, htf_close_1)
  611. draw_htf(offset+12, htf_open_2, htf_high_2, htf_low_2, htf_close_2)
  612.  
  613. if show_eq_htf and enable_module_htf and barstate.islast
  614. heq50 = htf_low_0 + (htf_high_0 - htf_low_0) * 0.5
  615. line.new(bar_index, heq50, bar_index + 2, heq50, extend=extend.right, color=color.orange)
  616. label.new(bar_index, heq50, "HTF 50%", style=label.style_label_left, textcolor=color.orange)
  617.  
  618. // ======================================================
  619. // Module F: SMT Engine (pivot-based, single pair)
  620. // ======================================================
  621. smt_bull := false
  622. smt_bear := false
  623.  
  624. if enable_module_smt and smt1_use and enable_module_smt
  625. // fetch HL from comparison symbol
  626. [h2,l2,c2] = request.security(smt1_symA, timeframe.period, [high, low, close])
  627. [h3,l3,c3] = request.security(smt1_symB, timeframe.period, [high, low, close])
  628. // pivots on base chart and symbols
  629. ph_base = ta.pivothigh(high, smt_pivot_len, smt_pivot_len)
  630. pl_base = ta.pivotlow(low, smt_pivot_len, smt_pivot_len)
  631.  
  632. ph_symA = ta.pivothigh(h2, smt_pivot_len, smt_pivot_len)
  633. ph_symB = ta.pivothigh(h3, smt_pivot_len, smt_pivot_len)
  634. pl_symA = ta.pivotlow(l2, smt_pivot_len, smt_pivot_len)
  635. pl_symB = ta.pivotlow(l3, smt_pivot_len, smt_pivot_len)
  636.  
  637. // simple divergence detection on highs (bearish) and lows (bullish)
  638. // when base makes higher-high but sym makes lower-high -> bearish SMT
  639. if not na(ph_base) and not na(ph_symA) and not na(ph_symB)
  640. // compare direction between base and pair (use symA primarily)
  641. delta_base = ph_base - ph_base[1]
  642. delta_sym = ph_symA - ph_symA[1]
  643. if (delta_base > 0) and (delta_sym < 0)
  644. smt_bear := true
  645. if debug_mode
  646. label.new(bar_index, ph_base, "SMT Bear", color=color.purple, style=label.style_label_down, textcolor=color.white)
  647. if not na(pl_base) and not na(pl_symA) and not na(pl_symB)
  648. delta_base_l = pl_base - pl_base[1]
  649. delta_sym_l = pl_symA - pl_symA[1]
  650. if (delta_base_l < 0) and (delta_sym_l > 0)
  651. smt_bull := true
  652. if debug_mode
  653. label.new(bar_index, pl_base, "SMT Bull", color=color.purple, style=label.style_label_up, textcolor=color.white)
  654.  
  655. // ======================================================
  656. // Projections Engine
  657. // ======================================================
  658. plot_proj(price, lvl, name) =>
  659. if not proj_master_toggle
  660. na
  661. else
  662. y = price + lvl
  663. l = line.new(bar_index - 1, y, bar_index, y, extend = proj_extend_right ? extend.right : extend.none, color = col_proj, width = 1)
  664. l
  665.  
  666. // Only draw projections when anchor exists
  667. if proj_master_toggle and not na(proj_anchor_price)
  668. // interpret projection multipliers as price offsets—here we will use percentage of ATR for demonstration
  669. // but per your original design, these are relative levels; we'll implement as price + (proj_multiplier * ATR*mult)
  670. atr_for_proj = ta.atr(14)
  671. if proj_show_plus1
  672. plot_proj(proj_anchor_price, atr_for_proj * 1.0, "+1")
  673. if proj_show_0
  674. line.new(bar_index - 1, proj_anchor_price, bar_index, proj_anchor_price, extend = proj_extend_right ? extend.right : extend.none, color = color.orange, width = 1)
  675. if proj_show_minus1
  676. plot_proj(proj_anchor_price, -atr_for_proj * 1.0, "-1")
  677. if proj_show_minus2
  678. plot_proj(proj_anchor_price, -atr_for_proj * 2.0, "-2")
  679. if proj_show_minus25
  680. plot_proj(proj_anchor_price, -atr_for_proj * 2.5, "-2.5")
  681. if proj_show_minus4
  682. plot_proj(proj_anchor_price, -atr_for_proj * 4.0, "-4")
  683. if proj_show_minus45
  684. plot_proj(proj_anchor_price, -atr_for_proj * 4.5, "-4.5")
  685.  
  686. // ======================================================
  687. // Info Panel
  688. // ======================================================
  689. if enable_info_panel and barstate.islast
  690. // assemble text
  691. bias_text = ndm_auto_bias ? (final_cisd_bull ? "Bull" : final_cisd_bear ? "Bear" : "Neutral") : bias_manual
  692. phase_text = bullC3 ? "C3" : bearC3 ? "C3" : bullC2 ? "C2" : bearC2 ? "C2" : "Idle"
  693. smt_text = smt_bull ? "SMT Bull" : smt_bear ? "SMT Bear" : "None"
  694. cisd_text = final_cisd_bull ? "Bull CISD" : final_cisd_bear ? "Bear CISD" : "None"
  695. fail_text = xc2 ? "XC2" : xc4 ? "XC4" : "None"
  696. proj_text = not na(proj_anchor_price) ? "Anchored" : "Off"
  697. filter_text = inside_time_filter() ? "In" : "Out"
  698. htf_text = str.tostring(htf_tf)
  699.  
  700. info = "MODEL PANEL\nBias: " + bias_text + "\nPhase: " + phase_text + "\nCISD: " + cisd_text + "\nSMT: " + smt_text + "\nFailures: " + fail_text + "\nProj: " + proj_text + "\nFilter: " + filter_text + "\nHTF: " + htf_text
  701. label.new(bar_index, high, info, style=label.style_label_right, textcolor=color.white, color=color.new(color.black, 80), size=size.large, xloc=xloc.bar_index, yloc=yloc.price)
  702.  
  703. // ======================================================
  704. // Final cleanup (throttle debug objects)
  705. // ======================================================
  706. if not debug_mode
  707. // Optionally, remove transient labels created earlier to avoid clutter (keeps T-spots & history)
  708. na
  709.  
Advertisement
Add Comment
Please, Sign In to add comment