Guest

Phidias Master Engine

Mar 2nd, 2026
42
0
Never
Not a member of gistpad yet? Sign Up, it unlocks many cool features!
None 48.28 KB | None | 0 0
  1. //@version=5
  2. indicator("Phidias Master Engine [v9.5 TITAN]", shorttitle="Phidias_v9.5", overlay=true, max_labels_count=500)
  3.  
  4. // ═══════════════════════════════════════════════════════════════════════════════
  5. // 1. GLOBAL INPUTS
  6. // ═══════════════════════════════════════════════════════════════════════════════
  7. nq_sym = input.symbol("NQ1!", "NQ Symbol", group="Institutional Sync")
  8. pl_input = input.float(0, "Current P&L ($)", step=50, group="Preservation Gate")
  9. stop_pts = input.float(4.0, "Stop Loss (Pts)", group="Risk Audit")
  10. target_pts = input.float(8.0, "Target (Pts)", group="Risk Audit")
  11. rr_floor = 1.5
  12.  
  13. // Silent Sweep Detection
  14. grp_sweep = "Sweep Detection (Silent)"
  15. z_threshold = input.float(2.5, "Z-Score Volume Threshold", minval=0.5, step=0.1, group=grp_sweep)
  16. touch_zone_ticks = input.int(2, "Touch Zone (ticks from boundary)", minval=0, maxval=10, group=grp_sweep)
  17. tick_size_input = input.float(0.25, "Tick Size", step=0.25, group=grp_sweep)
  18. max_tracked = input.int(10, "Max Tracked Boxes", minval=5, maxval=20, group=grp_sweep)
  19. sweep_stale_bars = input.int(15, "Sweep Stale After (bars)", minval=5, maxval=60, group=grp_sweep)
  20. sweep_expire_bars = input.int(30, "Sweep Expires After (bars)", minval=10, maxval=120, group=grp_sweep)
  21.  
  22. // RSI Settings
  23. grp_rsi = "RSI Divergence"
  24. rsi_len = input.int(14, "RSI Length", minval=5, maxval=30, group=grp_rsi)
  25. rsi_ob = input.float(70.0, "Overbought", minval=60, maxval=90, group=grp_rsi)
  26. rsi_os = input.float(30.0, "Oversold", minval=10, maxval=40, group=grp_rsi)
  27. div_lookback = input.int(20, "Divergence Lookback (bars)", minval=5, maxval=30, group=grp_rsi)
  28. div_confirm = input.int(2, "Divergence Confirm (bars)", minval=1, maxval=5, group=grp_rsi)
  29.  
  30. // ═══════════════════════════════════════════════════════════════════════════════
  31. // 2. CURRENT PRICE DATA
  32. // ═══════════════════════════════════════════════════════════════════════════════
  33. mes_c = close
  34. mes_v = volume
  35. nq_c = request.security(nq_sym, timeframe.period, close)
  36.  
  37. // ═══════════════════════════════════════════════════════════════════════════════
  38. // 3. LONDON MIDPOINT (08:00 UTC)
  39. // ═══════════════════════════════════════════════════════════════════════════════
  40. var float lon_mid = na
  41. var bool lon_tested = false
  42. is_lon_start = not na(time(timeframe.period, "0800-0805", "UTC"))
  43. if is_lon_start
  44. lon_mid := (high + low) / 2
  45. lon_tested := false
  46. if not na(lon_mid) and not lon_tested
  47. if low <= lon_mid and high >= lon_mid
  48. lon_tested := true
  49.  
  50. // ═══════════════════════════════════════════════════════════════════════════════
  51. // 4. ZONE MEMORY
  52. // ═══════════════════════════════════════════════════════════════════════════════
  53. vol_ma = ta.sma(mes_v, 20)
  54. atr_val = ta.atr(14)
  55. atr_ma = ta.sma(atr_val, 20)
  56. is_climax = mes_v > vol_ma * 1.8 or atr_val > atr_ma * 1.5
  57. var red_highs = array.new_float(3, na)
  58. var red_lows = array.new_float(3, na)
  59. var grn_highs = array.new_float(3, na)
  60. var grn_lows = array.new_float(3, na)
  61. var int r_ghosts = 0
  62. var int g_ghosts = 0
  63. if is_lon_start
  64. r_ghosts := 0
  65. g_ghosts := 0
  66. if is_climax
  67. if close < open
  68. array.unshift(red_highs, high)
  69. array.unshift(red_lows, low)
  70. array.pop(red_highs)
  71. array.pop(red_lows)
  72. else
  73. array.unshift(grn_highs, high)
  74. array.unshift(grn_lows, low)
  75. array.pop(grn_highs)
  76. array.pop(grn_lows)
  77.  
  78. // ═══════════════════════════════════════════════════════════════════════════════
  79. // 5. REFINED ZONE ANALYSIS — nearest = immediate structural threat
  80. // ═══════════════════════════════════════════════════════════════════════════════
  81. bool in_red = false
  82. bool in_grn = false
  83. bool box_broken = false
  84. string break_type = ""
  85.  
  86. float nearest_resistance = na // closest red zone top above price (immediate threat for longs)
  87. float nearest_support = na // closest green zone bottom below price (immediate threat for shorts)
  88.  
  89. for i = 0 to 2
  90. rh = array.get(red_highs, i)
  91. rl = array.get(red_lows, i)
  92. gh = array.get(grn_highs, i)
  93. gl = array.get(grn_lows, i)
  94.  
  95. if not na(rh)
  96. if mes_c >= rl and mes_c <= rh
  97. in_red := true
  98. float red_edge = rh
  99. if red_edge > mes_c
  100. if na(nearest_resistance) or (red_edge - mes_c) < (nearest_resistance - mes_c)
  101. nearest_resistance := red_edge
  102.  
  103. if not na(gh)
  104. if mes_c >= gl and mes_c <= gh
  105. in_grn := true
  106. float grn_edge = gl
  107. if grn_edge < mes_c
  108. if na(nearest_support) or (mes_c - grn_edge) < (mes_c - nearest_support)
  109. nearest_support := grn_edge
  110.  
  111. if not na(rh) and close < rl
  112. box_broken := true
  113. break_type := "SUPPLY"
  114. if not na(gh) and close > gh
  115. box_broken := true
  116. break_type := "DEMAND"
  117.  
  118. if not na(rh) and close > rh
  119. array.set(red_highs, i, na)
  120. array.set(red_lows, i, na)
  121. r_ghosts += 1
  122. if not na(gh) and close < gl
  123. array.set(grn_highs, i, na)
  124. array.set(grn_lows, i, na)
  125. g_ghosts += 1
  126.  
  127. // ═══════════════════════════════════════════════════════════════════════════════
  128. // 6. SILENT SWEEP DETECTION ENGINE
  129. // ═══════════════════════════════════════════════════════════════════════════════
  130. float vol_sma_z = ta.sma(volume, 20)
  131. float vol_std_z = ta.stdev(volume, 20)
  132. float z_vol = vol_std_z != 0 ? (volume - vol_sma_z) / vol_std_z : 0
  133. bool high_vol = z_vol >= z_threshold
  134. bool bullish_candle = close > open
  135. var float[] s_box_tops = array.new_float(0)
  136. var float[] s_box_bottoms = array.new_float(0)
  137. var int[] s_box_dirs = array.new_int(0)
  138. var int[] s_box_births = array.new_int(0)
  139. var int[] s_box_touches = array.new_int(0)
  140. var bool[] s_box_swept = array.new_bool(0)
  141. if high_vol
  142. array.push(s_box_tops, high)
  143. array.push(s_box_bottoms, low)
  144. array.push(s_box_dirs, bullish_candle ? 1 : -1)
  145. array.push(s_box_births, bar_index)
  146. array.push(s_box_touches, 0)
  147. array.push(s_box_swept, false)
  148.  
  149. if array.size(s_box_tops) > max_tracked
  150. array.shift(s_box_tops)
  151. array.shift(s_box_bottoms)
  152. array.shift(s_box_dirs)
  153. array.shift(s_box_births)
  154. array.shift(s_box_touches)
  155. array.shift(s_box_swept)
  156. var int last_sweep_bar = 0
  157. var int last_sweep_dir = 0
  158. var int last_sweep_touches = 0
  159. var float last_sweep_level = na
  160. float touch_zone = touch_zone_ticks * tick_size_input
  161. int n_sboxes = array.size(s_box_tops)
  162. if n_sboxes > 0
  163. for i = n_sboxes - 1 to 0
  164. float b_top = array.get(s_box_tops, i)
  165. float b_bottom = array.get(s_box_bottoms, i)
  166. int b_dir = array.get(s_box_dirs, i)
  167. int b_birth = array.get(s_box_births, i)
  168. bool b_swept = array.get(s_box_swept, i)
  169. int b_touch = array.get(s_box_touches, i)
  170.  
  171. if bar_index - b_birth > 200 or b_swept
  172. continue
  173.  
  174. if b_dir == 1
  175. bool near_bottom = low <= (b_bottom + touch_zone) and low >= (b_bottom - touch_zone)
  176. bool closed_above = close > b_bottom
  177. bool swept_below = low < (b_bottom - touch_zone)
  178.  
  179. if near_bottom and closed_above and not swept_below
  180. array.set(s_box_touches, i, b_touch + 1)
  181.  
  182. if swept_below
  183. array.set(s_box_swept, i, true)
  184. last_sweep_bar := bar_index
  185. last_sweep_dir := 1
  186. last_sweep_touches := b_touch
  187. last_sweep_level := b_bottom
  188.  
  189. if b_dir == -1
  190. bool near_top = high >= (b_top - touch_zone) and high <= (b_top + touch_zone)
  191. bool closed_below = close < b_top
  192. bool swept_above = high > (b_top + touch_zone)
  193.  
  194. if near_top and closed_below and not swept_above
  195. array.set(s_box_touches, i, b_touch + 1)
  196.  
  197. if swept_above
  198. array.set(s_box_swept, i, true)
  199. last_sweep_bar := bar_index
  200. last_sweep_dir := -1
  201. last_sweep_touches := b_touch
  202. last_sweep_level := b_top
  203. int sweep_age = bar_index - last_sweep_bar
  204. bool sweep_active = last_sweep_bar > 0 and sweep_age <= sweep_expire_bars
  205. bool sweep_fresh = sweep_active and sweep_age <= sweep_stale_bars
  206. bool sweep_stale = sweep_active and sweep_age > sweep_stale_bars
  207. int pending_touches = 0
  208. int active_boxes = 0
  209. if array.size(s_box_tops) > 0
  210. for i = 0 to array.size(s_box_tops) - 1
  211. if bar_index - array.get(s_box_births, i) <= 200 and not array.get(s_box_swept, i)
  212. active_boxes += 1
  213. pending_touches += array.get(s_box_touches, i)
  214.  
  215. // ═══════════════════════════════════════════════════════════════════════════════
  216. // 7. RSI DIVERGENCE ENGINE
  217. // ═══════════════════════════════════════════════════════════════════════════════
  218. float rsi_val = ta.rsi(close, rsi_len)
  219. float price_low_1 = ta.lowest(low, div_lookback)
  220. float price_low_2 = ta.lowest(low, div_lookback)[div_lookback]
  221. float price_high_1 = ta.highest(high, div_lookback)
  222. float price_high_2 = ta.highest(high, div_lookback)[div_lookback]
  223. float rsi_low_1 = ta.lowest(rsi_val, div_lookback)
  224. float rsi_low_2 = ta.lowest(rsi_val, div_lookback)[div_lookback]
  225. float rsi_high_1 = ta.highest(rsi_val, div_lookback)
  226. float rsi_high_2 = ta.highest(rsi_val, div_lookback)[div_lookback]
  227. bool raw_bull_div = price_low_1 < price_low_2 and rsi_low_1 > rsi_low_2
  228. bool raw_bear_div = price_high_1 > price_high_2 and rsi_high_1 < rsi_high_2
  229. var int bull_div_count = 0
  230. var int bear_div_count = 0
  231. if raw_bull_div
  232. bull_div_count += 1
  233. else
  234. bull_div_count := 0
  235. if raw_bear_div
  236. bear_div_count += 1
  237. else
  238. bear_div_count := 0
  239. bool bull_div_confirmed = bull_div_count >= div_confirm
  240. bool bear_div_confirmed = bear_div_count >= div_confirm
  241. string rsi_state = ""
  242. color rsi_bg = color.new(#000000, 40)
  243. color rsi_tc = color.gray
  244. if bull_div_confirmed and rsi_val < rsi_os
  245. rsi_state := "OS + BULL DIV"
  246. rsi_bg := color.new(color.green, 10)
  247. rsi_tc := color.white
  248. else if bear_div_confirmed and rsi_val > rsi_ob
  249. rsi_state := "OB + BEAR DIV"
  250. rsi_bg := color.new(color.red, 10)
  251. rsi_tc := color.white
  252. else if bull_div_confirmed
  253. rsi_state := "BULL DIV"
  254. rsi_bg := color.new(color.green, 40)
  255. rsi_tc := color.green
  256. else if bear_div_confirmed
  257. rsi_state := "BEAR DIV"
  258. rsi_bg := color.new(color.red, 40)
  259. rsi_tc := color.red
  260. else if rsi_val > rsi_ob
  261. rsi_state := "OB " + str.tostring(rsi_val, "#.#")
  262. rsi_bg := color.new(color.red, 60)
  263. rsi_tc := color.red
  264. else if rsi_val < rsi_os
  265. rsi_state := "OS " + str.tostring(rsi_val, "#.#")
  266. rsi_bg := color.new(color.green, 60)
  267. rsi_tc := color.green
  268. else
  269. rsi_state := str.tostring(rsi_val, "#.#")
  270. rsi_bg := color.new(#000000, 40)
  271. rsi_tc := color.gray
  272.  
  273. // ═══════════════════════════════════════════════════════════════════════════════
  274. // 8. TARGET CALCULATIONS
  275. // ═══════════════════════════════════════════════════════════════════════════════
  276. float long_target = mes_c + target_pts
  277. float short_target = mes_c - target_pts
  278. float dyn_rr = target_pts / stop_pts
  279.  
  280. // ═══════════════════════════════════════════════════════════════════════════════
  281. // 9. DUAL GATE AUDIT ENGINE — refined proximity
  282. // ═══════════════════════════════════════════════════════════════════════════════
  283. bool is_rsw = not na(time(timeframe.period, "1430-1445", "UTC"))
  284. bool rr_fail = dyn_rr < rr_floor
  285. bool loss_limit = pl_input <= -500
  286.  
  287. bool long_trap = in_red
  288. bool long_nq_fail = nq_c < nq_c[1] and not box_broken
  289. bool long_target_blocked = not na(nearest_resistance) and nearest_resistance < long_target
  290.  
  291. string long_veto = ""
  292. if loss_limit
  293. long_veto := "LOSS"
  294. else if is_rsw
  295. long_veto := "RSW"
  296. else if rr_fail
  297. long_veto := "R:R"
  298. else if long_trap
  299. long_veto := "ZONE"
  300. else if long_nq_fail
  301. long_veto := "NQ"
  302. else if long_target_blocked
  303. long_veto := "BLOCKED"
  304. bool long_pass = long_veto == ""
  305.  
  306. bool short_trap = in_grn
  307. bool short_nq_fail = nq_c > nq_c[1] and not box_broken
  308. bool short_target_blocked = not na(nearest_support) and nearest_support > short_target
  309.  
  310. string short_veto = ""
  311. if loss_limit
  312. short_veto := "LOSS"
  313. else if is_rsw
  314. short_veto := "RSW"
  315. else if rr_fail
  316. short_veto := "R:R"
  317. else if short_trap
  318. short_veto := "ZONE"
  319. else if short_nq_fail
  320. short_veto := "NQ"
  321. else if short_target_blocked
  322. short_veto := "BLOCKED"
  323. bool short_pass = short_veto == ""
  324.  
  325. // ═══════════════════════════════════════════════════════════════════════════════
  326. // 10. SETUP GRADING ENGINE
  327. // ═══════════════════════════════════════════════════════════════════════════════
  328. bool sweep_long_aligned = sweep_fresh and last_sweep_dir == 1
  329. bool sweep_short_aligned = sweep_fresh and last_sweep_dir == -1
  330. bool rsi_supports_long = bull_div_confirmed or rsi_val < rsi_os
  331. bool rsi_supports_short = bear_div_confirmed or rsi_val > rsi_ob
  332. bool rsi_warns_long = bear_div_confirmed
  333. bool rsi_warns_short = bull_div_confirmed
  334. bool rsi_neutral = not rsi_supports_long and not rsi_supports_short and not rsi_warns_long and not rsi_warns_short
  335.  
  336. string long_grade = "X"
  337. if not long_pass
  338. long_grade := "X"
  339. else if sweep_long_aligned and (rsi_supports_long or (rsi_neutral and not rsi_warns_long))
  340. long_grade := "A+"
  341. else if rsi_warns_long
  342. long_grade := "C"
  343. else if sweep_long_aligned or rsi_supports_long
  344. long_grade := "B+"
  345. else
  346. long_grade := "B+"
  347.  
  348. string short_grade = "X"
  349. if not short_pass
  350. short_grade := "X"
  351. else if sweep_short_aligned and (rsi_supports_short or (rsi_neutral and not rsi_warns_short))
  352. short_grade := "A+"
  353. else if rsi_warns_short
  354. short_grade := "C"
  355. else if sweep_short_aligned or rsi_supports_short
  356. short_grade := "B+"
  357. else
  358. short_grade := "B+"
  359.  
  360. f_grade_bg(string grade) => grade == "A+" ? color.new(#00e676, 15) : grade == "B+" ? color.new(#448aff, 25) : grade == "C" ? color.new(#ffd600, 25) : color.new(#444455, 50)
  361. f_grade_tc(string grade) => grade == "A+" ? color.white : grade == "B+" ? color.white : grade == "C" ? color.black : color.gray
  362.  
  363. // ═══════════════════════════════════════════════════════════════════════════════
  364. // 11. CANDLE COLOURING
  365. // ═══════════════════════════════════════════════════════════════════════════════
  366. color candle_col = na
  367. if long_pass and not short_pass
  368. candle_col := color.new(color.green, 60)
  369. else if short_pass and not long_pass
  370. candle_col := color.new(color.red, 60)
  371. else if long_pass and short_pass
  372. candle_col := color.new(color.yellow, 60)
  373. else
  374. candle_col := color.new(color.gray, 80)
  375. barcolor(candle_col)
  376.  
  377. // ═══════════════════════════════════════════════════════════════════════════════
  378. // 12. VISUALS
  379. // ═══════════════════════════════════════════════════════════════════════════════
  380. plot(lon_mid, "London Mid", color=lon_tested ? color.gray : color.aqua, linewidth=2)
  381. plotshape(box_broken, "Box Break", shape.diamond, location.belowbar, color=break_type == "DEMAND" ? color.green : color.red, size=size.small)
  382. plot(long_target, "Long Target", color=color.new(color.green, 70), style=plot.style_linebr, linewidth=1)
  383. plot(short_target, "Short Target", color=color.new(color.red, 70), style=plot.style_linebr, linewidth=1)
  384.  
  385. // ═══════════════════════════════════════════════════════════════════════════════
  386. // 13. GRADED ALERTS
  387. // ═══════════════════════════════════════════════════════════════════════════════
  388. var string prev_long_grade = "X"
  389. var string prev_short_grade = "X"
  390. bool long_a_plus_new = long_grade == "A+" and prev_long_grade != "A+"
  391. bool long_b_plus_new = long_grade == "B+" and prev_long_grade == "X"
  392. bool long_c_new = long_grade == "C" and prev_long_grade == "X"
  393. bool short_a_plus_new = short_grade == "A+" and prev_short_grade != "A+"
  394. bool short_b_plus_new = short_grade == "B+" and prev_short_grade == "X"
  395. bool short_c_new = short_grade == "C" and prev_short_grade == "X"
  396. bool long_gate_closed = long_grade == "X" and prev_long_grade != "X"
  397. bool short_gate_closed = short_grade == "X" and prev_short_grade != "X"
  398.  
  399. prev_long_grade := long_grade
  400. prev_short_grade := short_grade
  401.  
  402. alertcondition(long_a_plus_new, title="⚡ A+ LONG", message="A+ LONG SETUP — Gate open, sweep aligned, RSI supports.")
  403. alertcondition(short_a_plus_new, title="⚡ A+ SHORT", message="A+ SHORT SETUP — Gate open, sweep aligned, RSI supports.")
  404. alertcondition(long_b_plus_new, title="📈 B+ LONG", message="B+ LONG SETUP — Gate open.")
  405. alertcondition(short_b_plus_new, title="📉 B+ SHORT", message="B+ SHORT SETUP — Gate open.")
  406. alertcondition(long_c_new, title="⚠️ C LONG", message="C LONG SETUP — RSI divergence warning.")
  407. alertcondition(short_c_new, title="⚠️ C SHORT", message="C SHORT SETUP — RSI divergence warning.")
  408.  
  409. // ═══════════════════════════════════════════════════════════════════════════════
  410. // 14. UI TABLE
  411. // ═══════════════════════════════════════════════════════════════════════════════
  412. var table t = table.new(position.bottom_left, 9, 3, bgcolor=color.new(#000000, 80), border_width=1)
  413.  
  414. if barstate.islast
  415. // Row 0: Headers
  416. table.cell(t, 0, 0, "SYM", text_color=#888888, text_size=size.tiny)
  417. table.cell(t, 1, 0, "R:R", text_color=#888888, text_size=size.tiny)
  418. table.cell(t, 2, 0, "LONG", text_color=#888888, text_size=size.tiny)
  419. table.cell(t, 3, 0, "SHORT", text_color=#888888, text_size=size.tiny)
  420. table.cell(t, 4, 0, "ZONE", text_color=#888888, text_size=size.tiny)
  421. table.cell(t, 5, 0, "GATE", text_color=#888888, text_size=size.tiny)
  422. table.cell(t, 6, 0, "CANDLE", text_color=#888888, text_size=size.tiny)
  423. table.cell(t, 7, 0, "SWEEP", text_color=#888888, text_size=size.tiny)
  424. table.cell(t, 8, 0, "RSI", text_color=#888888, text_size=size.tiny)
  425.  
  426. // Row 1: Data
  427. string candle_status = long_pass and short_pass ? "BOTH" : long_pass ? "GREEN" : short_pass ? "RED" : "DEAD"
  428. color candle_bg = long_pass and short_pass ? color.yellow : long_pass ? color.green : short_pass ? color.red : color.gray
  429.  
  430. // Create GATE status text
  431. string gate_status = ""
  432. color gate_bg = color.new(#000000, 40)
  433.  
  434. if long_pass and short_pass
  435. gate_status := "BOTH OPEN"
  436. gate_bg := color.new(color.yellow, 30)
  437. else if long_pass
  438. gate_status := "LONG OPEN"
  439. gate_bg := color.new(color.green, 30)
  440. else if short_pass
  441. gate_status := "SHORT OPEN"
  442. gate_bg := color.new(color.red, 30)
  443. else
  444. // Gate is closed - show the primary veto reason
  445. if loss_limit
  446. gate_status := "LOSS LIMIT"
  447. else if is_rsw
  448. gate_status := "RSW"
  449. else if rr_fail
  450. gate_status := "R:R FAIL"
  451. else if long_trap or short_trap
  452. gate_status := "ZONE TRAP"
  453. else if long_nq_fail or short_nq_fail
  454. gate_status := "NQ FAIL"
  455. else if long_target_blocked or short_target_blocked
  456. gate_status := "BLOCKED"
  457. else
  458. gate_status := "CLOSED"
  459. gate_bg := color.new(color.gray, 30)
  460.  
  461. table.cell(t, 0, 1, "MES", text_color=#FF9800, text_size=size.tiny)
  462. table.cell(t, 1, 1, str.tostring(dyn_rr, "#.#") + "R", bgcolor=dyn_rr < rr_floor ? color.red : color.green, text_color=color.black, text_size=size.tiny)
  463. table.cell(t, 2, 1, str.tostring(long_target, "#.##"), text_color=color.green, bgcolor=color.new(#000000, 40), text_size=size.tiny)
  464. table.cell(t, 3, 1, str.tostring(short_target, "#.##"), text_color=color.red, bgcolor=color.new(#000000, 40), text_size=size.tiny)
  465.  
  466. string zone_text = in_red ? "RED" : in_grn ? "GREEN" : "CLEAN"
  467. zone_text += " | G:" + str.tostring(r_ghosts) + "/" + str.tostring(g_ghosts)
  468. table.cell(t, 4, 1, zone_text, bgcolor=(in_red or in_grn) ? color.new(color.red, 40) : color.new(color.green, 40), text_color=color.white, text_size=size.tiny)
  469.  
  470. // GATE cell - PROPERLY POPULATED
  471. table.cell(t, 5, 1, gate_status, bgcolor=gate_bg, text_color=color.white, text_size=size.tiny)
  472.  
  473. // CANDLE cell
  474. table.cell(t, 6, 1, candle_status, bgcolor=candle_bg, text_color=color.black, text_size=size.tiny)
  475.  
  476. // Sweep cell
  477. string sweep_text = sweep_fresh ? "SWEEP " + (last_sweep_dir == 1 ? "↓ DEMAND" : "↑ SUPPLY") : sweep_stale ? "STALE" : "NO SWEEP"
  478. color sweep_bg = sweep_fresh ? color.new(color.green, 20) : color.new(#000000, 40)
  479. table.cell(t, 7, 1, sweep_text, bgcolor=sweep_bg, text_color=color.white, text_size=size.tiny)
  480.  
  481. // RSI cell
  482. table.cell(t, 8, 1, rsi_state, bgcolor=rsi_bg, text_color=rsi_tc, text_size=size.tiny)
  483.  
  484. // Row 2: Grades
  485. table.cell(t, 2, 2, long_grade + " LONG", bgcolor=f_grade_bg(long_grade), text_color=f_grade_tc(long_grade), text_size=size.tiny)
  486. table.cell(t, 3, 2, short_grade + " SHORT", bgcolor=f_grade_bg(short_grade), text_color=f_grade_tc(short_grade), text_size=size.tiny)
RAW Gist Data Copied