Hitchhike22

Untitled

Jun 29th, 2026 (edited)
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.79 KB | None | 0 0
  1. //@version=6
  2. // =====================================================================
  3. // Strong Start — RVOL table
  4. // A glanceable, live-updating table of Relative Volume for up to 30
  5. // symbols, sorted highest RVOL first. Built for spotting "strong starts":
  6. // unusually heavy volume early in the day + an up move.
  7. //
  8. // RVOL = (today's volume so far) / (average daily volume over N days)
  9. // shown as % by default — 100% = a full average day's volume already
  10. // traded; ~8% in the first few minutes is a strong start. Same number
  11. // your "Simple Volume" indicator and the screener use.
  12. //
  13. // Pulls DAILY data internally, so it works on ANY chart timeframe
  14. // (daily or intraday) and ANY market (US, NSE, …).
  15. //
  16. // NOTE: Pine cannot read your watchlist — type your symbols in Settings
  17. // as EXCHANGE:TICKER (e.g. NASDAQ:NVDA, NSE:RELIANCE). Blank = skip.
  18. // Max 40 symbols (Pine's cross-symbol limit); 40 slots provided.
  19. // =====================================================================
  20. indicator("Strong Start — RVOL table", overlay = true, max_bars_back = 500)
  21.  
  22. // ---- settings ----
  23. int lookback = input.int(20, "Avg volume lookback (days)", minval = 1, maxval = 100, tooltip = "20 is a steadier baseline than 10 (less skewed by a recent volume spike). Set 10 to match the screener exactly.", group = "Settings")
  24. string showAs = input.string("Percent", "Show RVOL as", options = ["Percent", "Ratio"], group = "Settings")
  25. float rvolFlag = input.float(8.0, "Flag when RVOL% ≥", step = 0.5, group = "Settings")
  26. float chgFlag = input.float(1.5, "Move threshold (Chg% for green)", step = 0.1, tooltip = "A high-volume row colors green when up at least this, red when down by it, amber in between (volume but no move).", group = "Settings")
  27. int gatePct = input.int(50, "Light up top % by RVOL", minval = 10, maxval = 100, step = 5, tooltip = "Only the heaviest-volume X% of the list gets a colored row (a rank, so it self-calibrates through the day and catches mid-day RVOL risers). Lower = stricter / fewer, hotter names.", group = "Settings")
  28. string posStr = input.string("Top Right", "Table position", options = ["Top Right", "Top Left", "Center Right", "Center Left", "Bottom Right", "Bottom Left"], group = "Display")
  29. int szStr = input.int(1, "Text size (1 tiny … 4 large)", minval = 1, maxval = 4, tooltip = "Tiny fits the most rows on screen.", group = "Display")
  30. string theme = input.string("Dark", "Theme", options = ["Dark", "Light"], tooltip = "Switch to Light if your chart background is light — it darkens the table text so it stays readable. Dark is the default.", group = "Display")
  31.  
  32. // ---- symbols (EXCHANGE:TICKER; blank = skip) ----
  33. string g = "Symbols"
  34. string s01 = input.string("NSE:JASH", "01", group = g)
  35. string s02 = input.string("NSE:MOTILALOFS", "02", group = g)
  36. string s03 = input.string("NSE:DIACABS", "03", group = g)
  37. string s04 = input.string("NSE:FIVESTAR", "04", group = g)
  38. string s05 = input.string("NSE:TARSONS", "05", group = g)
  39. string s06 = input.string("NSE:GOLDIAM", "06", group = g)
  40. string s07 = input.string("NSE:AVALON", "07", group = g)
  41. string s08 = input.string("NSE:OLECTRA", "08", group = g)
  42. string s09 = input.string("NSE:TEJASNET", "09", group = g)
  43. string s10 = input.string("NSE:NELCO", "10", group = g)
  44. string s11 = input.string("NSE:ADANIPOWER", "11", group = g)
  45. string s12 = input.string("NSE:EMMVEE", "12", group = g)
  46. string s13 = input.string("NSE:SKYGOLD", "13", group = g)
  47. string s14 = input.string("NSE:BDL", "14", group = g)
  48. string s15 = input.string("NSE:TARIL", "15", group = g)
  49. string s16 = input.string("NSE:RAYMOND", "16", group = g)
  50. string s17 = input.string("NSE:DATAPATTNS", "17", group = g)
  51. string s18 = input.string("NSE:SUPRIYA", "18", group = g)
  52. string s19 = input.string("NSE:BHARATCOAL", "19", group = g)
  53. string s20 = input.string("NSE:IFCI", "20", group = g)
  54. string s21 = input.string("NSE:CMPDI", "21", group = g)
  55. string s22 = input.string("NSE:STALLION", "22", group = g)
  56. string s23 = input.string("NSE:RAIN", "23", group = g)
  57. string s24 = input.string("NSE:BALAMINES", "24", group = g)
  58. string s25 = input.string("NSE:EXICOM", "25", group = g)
  59. string s26 = input.string("NSE:EPACKPEB", "26", group = g)
  60. string s27 = input.string("", "27", group = g)
  61. string s28 = input.string("", "28", group = g)
  62. string s29 = input.string("", "29", group = g)
  63. string s30 = input.string("", "30", group = g)
  64. string s31 = input.string("", "31", group = g)
  65. string s32 = input.string("", "32", group = g)
  66. string s33 = input.string("", "33", group = g)
  67. string s34 = input.string("", "34", group = g)
  68. string s35 = input.string("", "35", group = g)
  69. string s36 = input.string("", "36", group = g)
  70. string s37 = input.string("", "37", group = g)
  71. string s38 = input.string("", "38", group = g)
  72. string s39 = input.string("", "39", group = g)
  73. string s40 = input.string("", "40", group = g)
  74.  
  75. // ---- per-symbol daily RVOL + change% (vs previous close) ----
  76. // Computed on DAILY resolution in each symbol's own context. On the live
  77. // (incomplete) day, `volume` is the running cumulative volume so far today;
  78. // `volume[1]` back are completed days. So this updates in real time.
  79. calcDaily(simple int N) =>
  80. float avgv = ta.sma(volume[1], N) // avg of last N completed days
  81. float rv = avgv > 0 ? volume / avgv : na // today-so-far / avg day (ratio)
  82. float cg = close[1] != 0 ? (close - close[1]) / close[1] * 100 : na // % vs prev close
  83. [rv, cg]
  84.  
  85. req(string sym) =>
  86. string s = sym == "" ? syminfo.tickerid : sym // placeholder for blanks
  87. request.security(s, "1D", calcDaily(lookback))
  88.  
  89. [rv01, cg01] = req(s01)
  90. [rv02, cg02] = req(s02)
  91. [rv03, cg03] = req(s03)
  92. [rv04, cg04] = req(s04)
  93. [rv05, cg05] = req(s05)
  94. [rv06, cg06] = req(s06)
  95. [rv07, cg07] = req(s07)
  96. [rv08, cg08] = req(s08)
  97. [rv09, cg09] = req(s09)
  98. [rv10, cg10] = req(s10)
  99. [rv11, cg11] = req(s11)
  100. [rv12, cg12] = req(s12)
  101. [rv13, cg13] = req(s13)
  102. [rv14, cg14] = req(s14)
  103. [rv15, cg15] = req(s15)
  104. [rv16, cg16] = req(s16)
  105. [rv17, cg17] = req(s17)
  106. [rv18, cg18] = req(s18)
  107. [rv19, cg19] = req(s19)
  108. [rv20, cg20] = req(s20)
  109. [rv21, cg21] = req(s21)
  110. [rv22, cg22] = req(s22)
  111. [rv23, cg23] = req(s23)
  112. [rv24, cg24] = req(s24)
  113. [rv25, cg25] = req(s25)
  114. [rv26, cg26] = req(s26)
  115. [rv27, cg27] = req(s27)
  116. [rv28, cg28] = req(s28)
  117. [rv29, cg29] = req(s29)
  118. [rv30, cg30] = req(s30)
  119. [rv31, cg31] = req(s31)
  120. [rv32, cg32] = req(s32)
  121. [rv33, cg33] = req(s33)
  122. [rv34, cg34] = req(s34)
  123. [rv35, cg35] = req(s35)
  124. [rv36, cg36] = req(s36)
  125. [rv37, cg37] = req(s37)
  126. [rv38, cg38] = req(s38)
  127. [rv39, cg39] = req(s39)
  128. [rv40, cg40] = req(s40)
  129.  
  130. // ---- display ----
  131. var table t = table.new(
  132. posStr == "Top Right" ? position.top_right : posStr == "Top Left" ? position.top_left : posStr == "Center Right" ? position.middle_right : posStr == "Center Left" ? position.middle_left : posStr == "Bottom Right" ? position.bottom_right : position.bottom_left,
  133. 3, 41, border_width = 1, frame_width = 1, frame_color = color.new(color.gray, 40))
  134.  
  135. sz = szStr == 1 ? size.tiny : szStr == 2 ? size.small : szStr == 3 ? size.normal : size.large
  136.  
  137. // Theme palette. Dark (default) keeps the original look exactly; Light swaps the
  138. // text/header to dark shades so nothing washes out on a light chart background.
  139. bool light = theme == "Light"
  140. color cText = light ? color.black : color.white // symbol text
  141. color cUp = light ? #0b8043 : color.lime // up / high RVOL
  142. color cDown = light ? #cc2222 : color.red // down
  143. color cFlat = light ? #c77800 : color.orange // mid RVOL / flat
  144. color cMuted = light ? #5b616b : color.silver // low RVOL
  145. color cNa = light ? #9aa0aa : color.gray // no value
  146. color cHdrBg = light ? color.new(#d1d4dc, 0) : color.new(color.gray, 15)
  147. color cHdrTx = light ? color.black : color.white
  148.  
  149. fmtRvol(float rv) =>
  150. na(rv) ? "–" : showAs == "Percent" ? str.tostring(rv * 100, "#") + "%" : str.tostring(rv, "#.00")
  151.  
  152. if barstate.islast
  153. names = array.from(s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30, s31, s32, s33, s34, s35, s36, s37, s38, s39, s40)
  154. rvs = array.from(rv01, rv02, rv03, rv04, rv05, rv06, rv07, rv08, rv09, rv10, rv11, rv12, rv13, rv14, rv15, rv16, rv17, rv18, rv19, rv20, rv21, rv22, rv23, rv24, rv25, rv26, rv27, rv28, rv29, rv30, rv31, rv32, rv33, rv34, rv35, rv36, rv37, rv38, rv39, rv40)
  155. cgs = array.from(cg01, cg02, cg03, cg04, cg05, cg06, cg07, cg08, cg09, cg10, cg11, cg12, cg13, cg14, cg15, cg16, cg17, cg18, cg19, cg20, cg21, cg22, cg23, cg24, cg25, cg26, cg27, cg28, cg29, cg30, cg31, cg32, cg33, cg34, cg35, cg36, cg37, cg38, cg39, cg40)
  156.  
  157. // header
  158. table.cell(t, 0, 0, "Symbol", text_color = cHdrTx, bgcolor = cHdrBg, text_size = sz)
  159. table.cell(t, 1, 0, "RVOL", text_color = cHdrTx, bgcolor = cHdrBg, text_size = sz)
  160. table.cell(t, 2, 0, "Chg%", text_color = cHdrTx, bgcolor = cHdrBg, text_size = sz)
  161.  
  162. // valid (non-blank, has a value) indices
  163. idx = array.new<int>()
  164. for i = 0 to array.size(names) - 1
  165. if array.get(names, i) != "" and not na(array.get(rvs, i))
  166. array.push(idx, i)
  167. cnt = array.size(idx)
  168.  
  169. // sort indices by RVOL descending (simple selection sort)
  170. for a = 0 to cnt - 2
  171. for b = a + 1 to cnt - 1
  172. ia = array.get(idx, a)
  173. ib = array.get(idx, b)
  174. if array.get(rvs, ib) > array.get(rvs, ia)
  175. array.set(idx, a, ib)
  176. array.set(idx, b, ia)
  177.  
  178. // clear all data rows first — use table.clear (not empty cells) so unused
  179. // rows collapse to zero height instead of padding the table off-screen.
  180. table.clear(t, 0, 1, 2, 40)
  181.  
  182. // VOLUME LEADS: only the heaviest-volume slice of the list (top `gatePct`%)
  183. // is eligible for a colored row. A rank, not an absolute %, so it
  184. // self-calibrates through the day and catches names whose RVOL climbs mid-
  185. // session. Movers on low relative volume are deliberately left plain.
  186. int hiCount = math.max(1, int(math.round(cnt * gatePct / 100.0)))
  187.  
  188. // fill sorted rows
  189. for r = 0 to cnt - 1
  190. i = array.get(idx, r)
  191. nm = array.get(names, i)
  192. parts = str.split(nm, ":")
  193. disp = array.size(parts) > 1 ? array.get(parts, 1) : nm
  194. rv = array.get(rvs, i)
  195. cg = array.get(cgs, i)
  196. float rvPct = na(rv) ? na : rv * 100
  197. bool isHigh = r < hiCount // among the heaviest-volume names right now
  198. // Brightness scales with RVOL rank — heaviest volume = most opaque, so the
  199. // explosive names pop hardest and ZEEL-type moderate-RVOL movers show as a
  200. // softer shade. transp 0 = solid, 100 = invisible.
  201. int tp = 45 + int(35.0 * r / math.max(1, hiCount - 1))
  202. color rvCol = na(rvPct) ? cNa : rvPct >= rvolFlag ? cUp : rvPct >= rvolFlag * 0.6 ? cFlat : cMuted
  203. // Among the high-volume names, color by the move:
  204. // green = up by chgFlag+ → big guys buying and price following (target)
  205. // amber = flat → volume but no move yet (early / churn)
  206. // red = down by chgFlag+ → volume but being sold (skip)
  207. color rowBg = na
  208. if isHigh and not na(cg)
  209. rowBg := cg >= chgFlag ? color.new(color.green, tp) : cg <= -chgFlag ? color.new(color.red, tp) : color.new(color.orange, tp)
  210. color cgCol = na(cg) ? cNa : cg >= 0 ? cUp : cDown
  211. table.cell(t, 0, r + 1, disp, text_color = cText, bgcolor = rowBg, text_size = sz)
  212. table.cell(t, 1, r + 1, fmtRvol(rv), text_color = rvCol, bgcolor = rowBg, text_size = sz)
  213. table.cell(t, 2, r + 1, na(cg) ? "–" : str.tostring(cg, "#.0") + "%", text_color = cgCol, bgcolor = rowBg, text_size = sz)
  214.  
Add Comment
Please, Sign In to add comment