xmd79

Market Profile with TPO

Oct 8th, 2021
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.78 KB | None | 0 0
  1. // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
  2. // © drother
  3.  
  4. //@version=5
  5. indicator("Market Profile with TPO", overlay=true, max_labels_count = 500, max_boxes_count = 500, max_lines_count = 500, max_bars_back = 1000)
  6. auto_tick_size_b = input.bool(false, title="Auto Tick Size?", group="Tick Size")
  7. int tick_bars_back = input.int(100 , minval=1, title="Avg Tick Size - Bars Back", group="Tick Size")
  8. avg_session_height = input.float(15, minval=1, title="Average Target Session Height for Tick Size", group="Tick Size")
  9. man_tick_size = input.int(100 , minval=1, title="Manual Tick Size", group="Tick Size")
  10. value_area_pct = input.float(68.26 , minval=0.01, maxval=100, title="Value Area Percent", group="Market Profile Options", tooltip = "Values are typically 68.26 to 70")/100
  11. open_color = input.color(title="Open TPO Text Color", defval=color.orange, group="Market Profile Options")
  12. POC_tpo_color = input.color(title="POC TPO Text Color", defval=color.red, group="Market Profile Options")
  13. POC_box_color = input.color(title="POC Box Color", defval=color.red, group="Market Profile Options")
  14. POC_line_color = input.color(title="POC Line Color", defval=color.red, group="Market Profile Options")
  15. in_value_tpo_color = input.color(title="In Value TPO Text Color", defval=color.blue, group="Market Profile Options")
  16. in_value_box_color = input.color(title="In Value Box Color", defval=color.blue, group="Market Profile Options")
  17. in_value_line_color = input.color(title="In Value Line Color", defval=color.blue, group="Market Profile Options")
  18. in_value_box_transparency = input.int(title="In Value Box Transparency", defval=70,minval=0,maxval=100, group="Market Profile Options")
  19. out_of_value_tpo_color = input.color(title="Out Of Value TPO Text Color", defval=color.green, group="Market Profile Options")
  20. //poc_box_color = input.color(title="POC Box Color", defval=color.red, group="Market Profile Options")
  21. //POC_box_transparency = input.int(title="POC Box Transparency", defval=30,minval=0,maxval=100, group="Market Profile Options")
  22. out_of_value_box_color = input.color(title="Out Of Value Box Color", defval=color.green, group="Market Profile Options")
  23. out_of_value_box_transparency = input.int(title="Out of Value Box Transparency", defval=70,minval=0,maxval=100, group="Market Profile Options")
  24. TPO_txt_size = input.string(title="TPO Letter Size", defval=size.small, options=[size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group="Market Profile Options")
  25. curr_price_text = input.string(" 🔴", title="Current Price Text", group="Market Profile Options")
  26. tpo_offset = input.int(title="Current TPO Session Offset", defval=0,minval=-100,maxval=100, group="Market Profile Options")
  27. tpo_letter_space = input.string(" ", "TPO Spacer to center over Candle", group="Market Profile Options")
  28. show_tpo_info = input.bool(title="Show TPO Info Text?", defval=true, group="Market Profile Options")
  29. plot_TPO_letters = input.bool(group="Market Profile Options",defval=true, title="Plot TPO Letters?")
  30. info_table_txt_size = input.string(title="TPO Info Text Size", defval=size.small, options=[size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group="Market Profile Options")
  31. session_option_24hr = input.bool(group="Market Session", defval=true, title="Use 24hr Session? Overwrites all below settings", tooltip = "Forced to True for CFDs/Stocks")
  32. sessDays = input.string(group="Market Session", defval="1234567", title="Session Days of Week", tooltip = "1 = Sunday, 7 = Saturday")
  33. show_sess1 = input.bool(group="Market Session",defval=true, title="Show Session 1?")
  34. sess1Name = input.string(group="Market Session", defval="Asian", title="Session 1 Name")
  35. sess1Time = input.session(group="Market Session", defval="0000-0759", title="Session 1", tooltip = "Times are GMT")
  36. show_sess2 = input.bool(group="Market Session",defval=true, title="Show Session 2?")
  37. sess2Name = input.string(group="Market Session", defval="London", title="Session 1 Name")
  38. sess2Time = input.session(group="Market Session", defval="0800-1329", title="Session 2", tooltip = "Times are GMT")
  39. show_sess3 = input.bool(group="Market Session",defval=true, title="Show Session 3?")
  40. sess3Name = input.string(group="Market Session", defval="US", title="Session 1 Name")
  41. sess3Time = input.session(group="Market Session", defval="1330-1959", title="Session 3", tooltip = "Times are GMT")
  42. show_sess4 = input.bool(group="Market Session",defval=true, title="Show Session 4?")
  43. sess4Name = input.string(group="Market Session", defval="Pre Market", title="Session 1 Name")
  44. sess4Time = input.session(group="Market Session", defval="2000-0000", title="Session 4", tooltip = "Times are GMT")
  45. show_warning = input.bool(true, title="Show Tick Warning?", group="Debug")
  46. //show_warning = false
  47. //debug_option = input.bool(false, title="Debug?", group="Debug")
  48. //deb_txt_size = input.string(title="Debug Letter Size", defval=size.small, options=[size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group="Debug")
  49. debug_option = false
  50. deb_txt_size = size.small
  51.  
  52. bool is_in_session = false
  53. int sess_start = bar_index
  54. int which_sess = 0
  55. if tick_bars_back > (bar_index + 1)
  56. tick_bars_back := bar_index + 1
  57.  
  58. tz = if syminfo.type == "stock"
  59. session_option_24hr := true
  60. "Etc/UTC"
  61. else if syminfo.type == "futures"
  62. "Etc/UTC"
  63. else if syminfo.type == "index"
  64. "Etc/UTC"
  65. else if syminfo.type == "forex"
  66. "Etc/UTC"
  67. else if syminfo.type == "crypto"
  68. "Etc/UTC"
  69. else if syminfo.type == "fund"
  70. "Etc/UTC"
  71. else if syminfo.type == "dr"
  72. "Etc/UTC"
  73. else if syminfo.type == "economic"
  74. session_option_24hr := true
  75. "Etc/UTC"
  76. else if syminfo.type == "cfd"
  77. session_option_24hr := true
  78. "Etc/UTC"
  79. else
  80. syminfo.timezone
  81.  
  82. //functions
  83. fn_is_session_start(res, sess) =>
  84. t = time(res, sess, tz)
  85. na(t[1]) and not na(t) or t[1] < t
  86.  
  87. fn_is_in_session(session_rollover, session) =>
  88. not na(time(session_rollover, session, tz))
  89.  
  90.  
  91. fn_num_of_tpos_per_tick(price_min, price_max, bars_back) =>
  92. int num_of_tpos = 0
  93. for i=0 to bars_back
  94. if (high[i] >= price_min and low[i] <= price_max)
  95. num_of_tpos := num_of_tpos + 1
  96. num_of_tpos
  97.  
  98. fn_num_of_tpos_per_tick_arr(price_min, price_max, bars_back, array) =>
  99. array.clear(array)
  100. for i=0 to bars_back
  101. if (high[i] >= price_min and low[i] < price_max)
  102. array.push(array, bars_back - i)
  103. array
  104.  
  105.  
  106. fn_build_tpo_letters_row(price_min, price_max, bars_back, array) =>
  107. array.clear(array)
  108. for i=0 to bars_back
  109. if (high[i] >= price_min and low[i] <= price_max)
  110. array.push(array, i)
  111. array
  112.  
  113. //TPOS_remaining = array.new_int(10, na)
  114. //TPO_per_loop = array.new_int(0)
  115. //array.set(TPOS_remaining, 9, 0)
  116. fn_build_VA(POC_index, TPO_array, VA_pct) =>
  117. int TPOs_Left = math.round((array.sum(TPO_array)* VA_pct) - array.get(TPO_array, POC_index))
  118. //int TPOs_used = array.get(TPOS_remaining, 9)
  119. TPO_mid_index = math.round((array.size(TPO_array)-1)/2)
  120. int VAL_index = POC_index
  121. int VAH_index = POC_index
  122. max_index = array.size(TPO_array) - 1
  123. //array.push(TPO_per_loop, TPOs_Left)
  124. //array.push(TPO_per_loop, -1)
  125. for i=0 to max_index
  126. if TPOs_Left > 0
  127. int VAH_2up = 0
  128. int VAH_1up = 0
  129. int VAL_1dn = 0
  130. int VAL_2dn = 0
  131. if VAH_index == max_index
  132. VAH_2up := 0
  133. VAH_1up := 0
  134. else if (VAH_index + 1) == max_index
  135. VAH_2up := 0
  136. VAH_1up := array.get(TPO_array, VAH_index + 1)
  137. else
  138. VAH_2up := array.get(TPO_array, VAH_index + 2)
  139. VAH_1up := array.get(TPO_array, VAH_index + 1)
  140. if VAL_index == 0
  141. VAL_2dn := 0
  142. VAL_1dn := 0
  143. else if (VAL_index -1) == 0
  144. VAL_2dn := 0
  145. VAL_1dn := array.get(TPO_array, VAL_index -1)
  146. else
  147. VAL_2dn := array.get(TPO_array, VAL_index -2)
  148. VAL_1dn := array.get(TPO_array, VAL_index -1)
  149.  
  150. if (VAH_index + 2) <= max_index and (VAL_index - 2) >= 0
  151. ///array.push(TPO_per_loop, 0)
  152. if (VAH_1up + VAH_2up) > (VAL_1dn + VAL_2dn) and (TPOs_Left - (VAH_1up + VAH_2up)) >= 0
  153. TPOs_Left := TPOs_Left - VAH_1up - VAH_2up
  154. //TPOs_used := TPOs_used + VAH_1up + VAH_2up
  155. VAH_index := VAH_index + 2
  156. else if (VAL_1dn + VAL_2dn) > (VAH_1up + VAH_2up) and (TPOs_Left - (VAL_1dn + VAL_2dn)) >= 0
  157. TPOs_Left := TPOs_Left - VAL_1dn - VAL_2dn
  158. //TPOs_used := TPOs_used + VAL_1dn + VAL_2dn
  159. VAL_index := VAL_index - 2
  160. else if (VAH_1up + VAH_2up) > (VAL_1dn + VAL_2dn) and TPOs_Left - VAH_1up >= 0
  161. TPOs_Left := TPOs_Left - VAH_1up - VAH_2up
  162. //TPOs_used := TPOs_used + VAH_1up + VAH_2up
  163. VAH_index := VAH_index + 2
  164. else if (VAL_1dn + VAL_2dn) > (VAH_1up + VAH_2up) and TPOs_Left - VAL_1dn >= 0
  165. TPOs_Left := TPOs_Left - VAH_1up - VAH_2up
  166. //TPOs_used := TPOs_used + VAH_1up + VAH_2up
  167. VAH_index := VAH_index + 2
  168. else if (VAH_1up + VAH_2up) == (VAL_1dn + VAL_2dn)
  169. if math.abs(VAH_index - TPO_mid_index) < math.abs(VAL_index - TPO_mid_index) and (TPOs_Left - (VAH_1up + VAH_2up)) >= 0
  170. TPOs_Left := TPOs_Left - VAH_1up - VAH_2up
  171. //TPOs_used := TPOs_used + VAH_1up + VAH_2up
  172. VAH_index := VAH_index + 2
  173. else if math.abs(VAH_index - TPO_mid_index) > math.abs(VAL_index - TPO_mid_index) and (TPOs_Left - (VAL_1dn + VAL_2dn)) >= 0
  174. TPOs_Left := TPOs_Left - VAL_1dn - VAL_2dn
  175. //TPOs_used := TPOs_used + VAL_1dn + VAL_2dn
  176. VAL_index := VAL_index - 2
  177. else if math.abs(VAH_index - TPO_mid_index) == math.abs(VAL_index - TPO_mid_index) and (TPOs_Left - (VAL_1dn + VAL_2dn)) >= 0
  178. TPOs_Left := TPOs_Left - VAL_1dn - VAL_2dn
  179. //TPOs_used := TPOs_used + VAL_1dn + VAL_2dn
  180. VAL_index := VAL_index - 2
  181. else if math.abs(VAH_index - TPO_mid_index) < math.abs(VAL_index - TPO_mid_index)
  182. TPOs_Left := TPOs_Left - VAH_1up
  183. //TPOs_used := TPOs_used + VAH_1up
  184. VAH_index := VAH_index + 1
  185. else if math.abs(VAH_index - TPO_mid_index) > math.abs(VAL_index - TPO_mid_index)
  186. TPOs_Left := TPOs_Left - VAL_1dn
  187. //TPOs_used := TPOs_used + VAL_1dn
  188. VAL_index := VAL_index - 1
  189. else if math.abs(VAH_index - TPO_mid_index) == math.abs(VAL_index - TPO_mid_index)
  190. TPOs_Left := TPOs_Left - VAL_1dn
  191. //TPOs_used := TPOs_used + VAL_1dn
  192. VAL_index := VAL_index - 1
  193. else if VAH_1up > VAL_1dn
  194. TPOs_Left := TPOs_Left - VAH_1up
  195. //TPOs_used := TPOs_used + VAH_1up
  196. VAH_index := VAH_index + 1
  197. else if VAH_1up < VAL_1dn
  198. TPOs_Left := TPOs_Left - VAL_1dn
  199. //TPOs_used := TPOs_used + VAL_1dn
  200. VAL_index := VAL_index - 1
  201. else if VAH_1up == VAL_1dn
  202. if math.abs(VAH_index - TPO_mid_index) < math.abs(VAL_index - TPO_mid_index)
  203. TPOs_Left := TPOs_Left - VAH_1up
  204. //TPOs_used := TPOs_used + VAH_1up
  205. VAH_index := VAH_index + 1
  206. else if math.abs(VAH_index - TPO_mid_index) > math.abs(VAL_index - TPO_mid_index)
  207. TPOs_Left := TPOs_Left - VAL_1dn
  208. //TPOs_used := TPOs_used + VAL_1dn
  209. VAL_index := VAL_index - 1
  210. else if math.abs(VAH_index - TPO_mid_index) == math.abs(VAL_index - TPO_mid_index)
  211. TPOs_Left := TPOs_Left - VAL_1dn
  212. //TPOs_used := TPOs_used + VAL_1dn
  213. VAL_index := VAL_index - 1
  214.  
  215.  
  216. else if (VAH_index + 1) == max_index or (VAL_index - 1) == 0
  217. //array.push(TPO_per_loop, 1)
  218. if VAH_1up > VAL_1dn
  219. TPOs_Left := TPOs_Left - VAH_1up
  220. //TPOs_used := TPOs_used + VAH_1up
  221. VAH_index := VAH_index + 1
  222. else if VAH_1up < VAL_1dn
  223. TPOs_Left := TPOs_Left - VAL_1dn
  224. //TPOs_used := TPOs_used + VAL_1dn
  225. VAL_index := VAL_index - 1
  226. else if VAH_1up == VAL_1dn
  227. if math.abs(VAH_index - TPO_mid_index) < math.abs(VAL_index - TPO_mid_index)
  228. TPOs_Left := TPOs_Left - VAH_1up
  229. //TPOs_used := TPOs_used + VAH_1up
  230. VAH_index := VAH_index + 1
  231. else if math.abs(VAH_index - TPO_mid_index) > math.abs(VAL_index - TPO_mid_index)
  232. TPOs_Left := TPOs_Left - VAL_1dn
  233. //TPOs_used := TPOs_used + VAL_1dn
  234. VAL_index := VAL_index - 1
  235. else if math.abs(VAH_index - TPO_mid_index) == math.abs(VAL_index - TPO_mid_index)
  236. TPOs_Left := TPOs_Left - VAL_1dn
  237. //TPOs_used := TPOs_used + VAL_1dn
  238. VAL_index := VAL_index - 1
  239.  
  240.  
  241. //array.set(TPOS_remaining, 3, VAH_2up)
  242. //array.set(TPOS_remaining, 4, VAH_1up)
  243. //array.set(TPOS_remaining, 5, VAL_1dn)
  244. //array.set(TPOS_remaining, 6, VAL_2dn)
  245. //array.set(TPOS_remaining, 7, (VAH_1up + VAH_2up) == (VAL_1dn + VAL_2dn) ? 1: 0)
  246. //array.set(TPOS_remaining, 8, (VAH_index + 1) == max_index or (VAL_index - 1) == 0 ? 1: 0)
  247.  
  248. //else
  249. // if (VAH_index + 1) <= max_index and (VAH_1up + VAH_2up) > (VAL_1dn + VAL_2dn
  250. // TPOs_Left := TPOs_Left - VAH_1up - VAH_2up
  251. // VAH_index := VAH_index + 1
  252. //else if (VAL_index - 1) >= 0 and (VAL_1dn + VAL_2dn) > (VAH_1up + VAH_2up)
  253. // TPOs_Left := TPOs_Left - VAL_1dn - VAL_2dn
  254. // VAL_index := VAL_index - 1
  255. //array.push(TPO_per_loop, TPOs_Left)
  256. //array.set(TPOS_remaining, 0, TPOs_Left)
  257. //array.set(TPOS_remaining, 9, TPOs_used)
  258. //array.set(TPOS_remaining, 1, VAH_index)
  259. //array.set(TPOS_remaining, 2, VAL_index)
  260.  
  261. [VAL_index, VAH_index]
  262.  
  263.  
  264. //labelIDs = array.new_label(0)
  265. var labelIds = array.new_label(0)
  266. var boxIDs = array.new_box(0)
  267. var last_boxIDs = array.new_box(0)
  268. var lineIDs = array.new_line(3)
  269. var lastLineIDs = array.new_line(0)
  270. TPO_price = array.new_float(0)
  271. TPO_length = array.new_int(0)
  272.  
  273.  
  274.  
  275.  
  276. sess1 = sess1Time + ":" + sessDays
  277. sess2 = sess2Time + ":" + sessDays
  278. sess3 = sess3Time + ":" + sessDays
  279. sess4 = sess4Time + ":" + sessDays
  280. sess24hr = "0000-0000:" + sessDays
  281.  
  282.  
  283. is_24hr_sess_open = fn_is_in_session("1440", sess24hr)
  284. is_sess1_open = fn_is_in_session("1440", sess1)
  285. is_sess2_open = fn_is_in_session("1440", sess2)
  286. is_sess3_open = fn_is_in_session("1440", sess3)
  287. is_sess4_open = fn_is_in_session("1440", sess4)
  288. sess_clear = false
  289.  
  290. if timeframe.ismonthly
  291. is_in_session := true
  292. sess_start := nz(ta.barssince(ta.change(year)))
  293. which_sess := -4
  294. else if timeframe.isweekly
  295. is_in_session := true
  296. sess_start := nz(ta.barssince(ta.change(year)))
  297. which_sess := -3
  298. else if timeframe.isdaily
  299. is_in_session := true
  300. sess_start := nz(ta.barssince(ta.change(month)))
  301. which_sess := -2
  302. else
  303. if session_option_24hr
  304. is_in_session := fn_is_in_session("1440", sess24hr)
  305. sess_start := nz(ta.barssince(ta.change(dayofweek)))
  306. which_sess := -1
  307. else
  308. if fn_is_in_session("1440", sess1) and show_sess1
  309. is_in_session := fn_is_in_session("1440", sess1)
  310. sess_start := nz(ta.barssince(fn_is_session_start("1440", sess1)))
  311. which_sess := 1
  312. else if fn_is_in_session("1440", sess2) and show_sess2
  313. is_in_session := fn_is_in_session("1440", sess2)
  314. sess_start := nz(ta.barssince(fn_is_session_start("1440", sess2)))
  315. which_sess := 2
  316. else if fn_is_in_session("1440", sess3) and show_sess3
  317. is_in_session := fn_is_in_session("1440", sess3)
  318. sess_start := nz(ta.barssince(fn_is_session_start("1440", sess3)))
  319. which_sess := 3
  320. else if fn_is_in_session("1440", sess4) and show_sess4
  321. is_in_session := fn_is_in_session("1440", sess4)
  322. sess_start := nz(ta.barssince(fn_is_session_start("1440", sess4)))
  323. which_sess := 4
  324. else
  325. is_in_session := false
  326. sess_start := 0
  327. which_sess := 5
  328. if syminfo.type == "economic"
  329. //sess_start := 0
  330. is_in_session := false
  331. sess_start_bar = int(bar_index-sess_start)
  332.  
  333.  
  334.  
  335.  
  336. //float ticks = 0
  337. //native_tick_size = for i = 1 to tick_bars_back-1
  338. // ticks := ticks + (high[i] - low[i])
  339. // avg_bar_range = ticks / tick_bars_back
  340. // tick_size_total = avg_bar_range / syminfo.mintick
  341. native_tick_size = ta.sma(high, tick_bars_back) - ta.sma(low, tick_bars_back)
  342. auto_tick_size = float((native_tick_size / avg_session_height) * syminfo.mintick)
  343. potential_tick_size = auto_tick_size_b? auto_tick_size : man_tick_size * syminfo.mintick
  344. var tick_size = 1.0
  345. if sess_start == 0
  346. tick_size := potential_tick_size > native_tick_size or potential_tick_size == 0? native_tick_size : potential_tick_size
  347. tick_size_ticks = int(tick_size / syminfo.mintick)
  348. tick_size := tick_size_ticks * syminfo.mintick
  349. tick_size := math.round_to_mintick(potential_tick_size)
  350. if tick_size == 0
  351. tick_size := 1
  352. tick_size_ticks = tick_size / syminfo.mintick
  353. half_tick = math.round_to_mintick(tick_size*.5)
  354.  
  355.  
  356.  
  357.  
  358. var TPO_Name_list = array.from("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","!","@","#","$","%","&","*")
  359. var TPO_Names = array.new_string(0)
  360. int required_names = (sess_start) - (array.size(TPO_Names))
  361. name_mult = int(array.size(TPO_Names) / array.size(TPO_Name_list))
  362. if required_names >= 0
  363. for i = 0 to required_names
  364. int tpos_to_add = nz((array.size(TPO_Names))) - array.size(TPO_Name_list)*name_mult
  365. array.push(TPO_Names, array.get(TPO_Name_list, tpos_to_add))
  366.  
  367.  
  368.  
  369.  
  370.  
  371. float highest_high = high
  372. float lowest_low = low
  373. for i = 0 to sess_start
  374. if high[i] > highest_high
  375. highest_high := high[i]
  376. if low[i] < lowest_low
  377. lowest_low := low[i]
  378. TPO_max = float(int(highest_high/tick_size)*tick_size)
  379. TPO_min = float(int(lowest_low/tick_size)*tick_size)
  380. TPO_rows = (TPO_max - TPO_min)/tick_size
  381. open_tick = int((open/tick_size)) * tick_size
  382. int total_tpo_count = 0
  383. TPO_mid = math.round_to_mintick((TPO_min + TPO_max)/2)
  384. TPO_POC = float(0)
  385. TPO_VAL = float(0)
  386. int VAL_index = na
  387. int VAH_index = na
  388. TPO_VAH = float(0)
  389. var label red_pill = na
  390. label.delete(red_pill)
  391.  
  392.  
  393. TPO_low_curr_bar = int((low/tick_size)) * tick_size
  394. TPO_high_curr_bar = int((high/tick_size)) * tick_size
  395. TPO_rows_curr_bar = (TPO_high_curr_bar - TPO_low_curr_bar)/tick_size
  396.  
  397.  
  398. test_array_1 = array.new_float(0)
  399. test_array_2 = array.new_float(0)
  400. test_array_3 = array.new_string(0)
  401. test_array_4 = array.new_float(0)
  402.  
  403. if is_in_session
  404.  
  405. if sess_start == 0
  406. array.concat(last_boxIDs, boxIDs)
  407. if array.size(lastLineIDs) > 497
  408. line.delete(array.shift(lastLineIDs))
  409. line.delete(array.shift(lastLineIDs))
  410. line.delete(array.shift(lastLineIDs))
  411. array.concat(lastLineIDs, lineIDs)
  412. array.set(lineIDs, 0, na)
  413. array.set(lineIDs, 1, na)
  414. array.set(lineIDs, 2, na)
  415. array.clear(boxIDs)
  416. array.clear(test_array_1)
  417. array.clear(test_array_2)
  418. array.clear(test_array_3)
  419. array.clear(test_array_4)
  420.  
  421. if array.size(boxIDs) > 0
  422. for i=0 to array.size(boxIDs)-1
  423. box.delete(array.shift(boxIDs))
  424. array.clear(boxIDs)
  425. if array.size(labelIds) > 0
  426. for i=0 to array.size(labelIds)-1
  427. label.delete(array.shift(labelIds))
  428. array.clear(labelIds)
  429.  
  430. for i = 0 to TPO_rows
  431. // build tpo size array
  432. price_tick_min = TPO_min + i * tick_size
  433. price_tick_max = price_tick_min + tick_size - syminfo.mintick
  434. num_of_tpos = fn_num_of_tpos_per_tick(price_tick_min, price_tick_max, sess_start)
  435. array.push(TPO_length, num_of_tpos)
  436. array.push(TPO_price, price_tick_min)
  437.  
  438. //calculate POC and Value Area
  439. total_tpo_count := array.sum(TPO_length)
  440. max_TPOs = array.max(TPO_length)
  441. TPO_POC := if array.indexof(TPO_length, max_TPOs) == array.lastindexof(TPO_length, max_TPOs)
  442. float poc_price = array.get(TPO_price, array.indexof(TPO_length, max_TPOs))
  443. poc_price
  444. else
  445. float poc_price = na
  446. int poc_index = na
  447. max_TPOs = array.max(TPO_length)
  448. poc_possible_price = array.new_float(0)
  449. poc_possible_dist_to_mid = array.new_float(0)
  450. for i = 0 to array.size(TPO_length)-1
  451. if array.get(TPO_length, i) == max_TPOs
  452. array.push(poc_possible_price, array.get(TPO_price, i))
  453. array.push(poc_possible_dist_to_mid, math.abs(array.get(TPO_price, i) - TPO_mid))
  454.  
  455. int counter = 0
  456. for i = 0 to array.size(poc_possible_price)-1
  457. if array.size(poc_possible_price) > counter
  458.  
  459. if array.min(poc_possible_dist_to_mid) != array.get(poc_possible_dist_to_mid, counter)
  460. array.remove(poc_possible_dist_to_mid, counter)
  461. array.remove(poc_possible_price, counter)
  462. else
  463. counter := counter + 1
  464. if array.indexof(poc_possible_dist_to_mid, array.min(poc_possible_dist_to_mid)) == array.lastindexof(poc_possible_dist_to_mid, array.min(poc_possible_dist_to_mid))
  465. poc_index := array.indexof(poc_possible_dist_to_mid, array.min(poc_possible_dist_to_mid))
  466. else
  467. poc_index := 0
  468. poc_price := array.get(poc_possible_price, poc_index)
  469. poc_price
  470. POC_index = array.indexof(TPO_price, TPO_POC)
  471. [_VAL_index, _VAH_index] = fn_build_VA(POC_index, TPO_length, value_area_pct)
  472. TPO_VAL := array.get(TPO_price, _VAL_index)
  473. TPO_VAH := array.get(TPO_price, _VAH_index)
  474. last_box_color = out_of_value_tpo_color
  475. for i = 0 to TPO_rows
  476. // build tpo and box arrays
  477. price_tick_min = array.get(TPO_price, i)
  478. price_tick_max = price_tick_min + tick_size
  479. tpo_row_index_data = array.new_int()
  480. fn_num_of_tpos_per_tick_arr(price_tick_min, price_tick_max, sess_start, tpo_row_index_data)
  481. array.reverse(tpo_row_index_data)
  482. num_of_tpos = array.size(tpo_row_index_data)
  483. //array.push(TPO_length, num_of_tpos)
  484. // build current TPO boxes and Letters
  485. left_side = sess_start_bar
  486. is_poc = price_tick_min == TPO_POC ? true : false
  487. if is_poc
  488. poc_line_id = array.get(lineIDs, 0)
  489. line.delete(array.get(lineIDs, 0))
  490. POC_line = line.new(left_side, price_tick_min + half_tick, bar_index + 1, price_tick_min + half_tick, color=POC_line_color)
  491. array.set(lineIDs, 0, POC_line)
  492.  
  493. //right_side = is_poc? bar_index + 1 : sess_start_bar + num_of_tpos
  494. right_side = sess_start_bar + num_of_tpos
  495. is_in_value = price_tick_min >= TPO_VAL and price_tick_min <= TPO_VAH
  496. if price_tick_min == TPO_VAH
  497. VAH_line_id = array.get(lineIDs, 1)
  498. line.delete(array.get(lineIDs, 1))
  499. VAH_line = line.new(left_side, price_tick_max, bar_index + 1, price_tick_max, color=in_value_line_color)
  500. array.set(lineIDs, 1, VAH_line)
  501. if price_tick_min == TPO_VAL
  502. VAL_line_id = array.get(lineIDs, 2)
  503. line.delete(array.get(lineIDs, 2))
  504. VAL_line = line.new(left_side, price_tick_min, bar_index + 1, price_tick_min, color=in_value_line_color)
  505. array.set(lineIDs, 2, VAL_line)
  506.  
  507. //POC_tpo_color
  508. box_color = is_poc? POC_box_color : is_in_value? in_value_box_color : out_of_value_box_color
  509. //tpo_color = is_poc? POC_tpo_color : is_in_value? in_value_tpo_color : out_of_value_tpo_color
  510. //box_color = out_of_value_box_color
  511. transparency = is_in_value ? in_value_box_transparency : out_of_value_box_transparency
  512. //transparency = out_of_value_box_transparency
  513. int total_boxes = array.size(boxIDs) + array.size(last_boxIDs)
  514.  
  515. if array.size(boxIDs) > 0
  516. last_box_ID = array.get(boxIDs, array.size(boxIDs)-1)
  517. last_box_right = box.get_right(last_box_ID)
  518. last_box_bot = box.get_bottom(last_box_ID)
  519. if right_side == last_box_right and not is_poc and last_box_bot != TPO_POC and last_box_color == box_color
  520. box.set_top(last_box_ID, price_tick_max)
  521. array.push(test_array_3, str.tostring(price_tick_min))
  522. else
  523. if total_boxes > 499 and array.size(last_boxIDs) > 0
  524. box.delete(array.shift(last_boxIDs))
  525. total_boxes := array.size(boxIDs) + array.size(last_boxIDs)
  526. if total_boxes > 499 and array.size(boxIDs) > 0
  527. box.delete(array.shift(boxIDs))
  528. tpo_box = box.new(left=left_side, top=price_tick_max, right=right_side, bottom=price_tick_min, bgcolor=color.new(box_color, transparency), border_color = na)
  529. array.push(boxIDs, tpo_box)
  530. else
  531. if total_boxes > 499 and array.size(last_boxIDs) > 0
  532. box.delete(array.shift(last_boxIDs))
  533. total_boxes := array.size(boxIDs) + array.size(last_boxIDs)
  534. if total_boxes > 499 and array.size(boxIDs) > 0
  535. box.delete(array.shift(boxIDs))
  536. tpo_box = box.new(left=left_side, top=price_tick_max, right=right_side, bottom=price_tick_min, bgcolor=color.new(box_color, transparency), border_color = na)
  537. array.push(boxIDs, tpo_box)
  538. curr_box_ID = array.get(boxIDs, array.size(boxIDs)-1)
  539.  
  540. if plot_TPO_letters and barstate.isrealtime
  541. //if plot_TPO_letters
  542. //string tpo_row_text = na
  543. for i=0 to array.size(tpo_row_index_data) - 1
  544. if array.size(labelIds) > 499
  545. label.delete(array.shift(labelIds))
  546. letter_index = int(array.get(tpo_row_index_data, i))
  547. tpo_color = is_poc ? POC_tpo_color : price_tick_min == open_tick[sess_start - letter_index]? open_color : is_in_value? in_value_tpo_color : out_of_value_tpo_color
  548. tpo_letter = tpo_letter_space + array.get(TPO_Names, letter_index)
  549. //tpo_row_text := tpo_row_text + tpo_letter
  550. tpo_label = label.new(x=left_side + i, y=price_tick_min, textcolor=tpo_color, text=tpo_letter, style=label.style_none, textalign=text.align_left, size=TPO_txt_size)
  551. array.push(labelIds, tpo_label)
  552. last_box_color := box_color
  553.  
  554.  
  555. curr_price_y = int((close/tick_size)) * tick_size
  556. curr_price_y_index = if array.includes(TPO_price, curr_price_y)
  557. array.indexof(TPO_price, curr_price_y)
  558. else
  559. sess_start_bar
  560. curr_price_x = array.get(TPO_length, curr_price_y_index) + sess_start_bar
  561. red_pill := label.new (x=curr_price_x, y=curr_price_y, text=curr_price_text, style=label.style_none, textalign=text.align_left, size=TPO_txt_size)
  562.  
  563. if not is_in_session or barstate.islastconfirmedhistory
  564. label.delete(red_pill)
  565.  
  566.  
  567.  
  568.  
  569. current_sess = if which_sess == -4
  570. "Monthly"
  571. else if which_sess == -3
  572. "Weekly"
  573. else if which_sess == -2
  574. "Daily"
  575. else if which_sess == -1
  576. "24Hr"
  577. else if which_sess == 1
  578. sess1Name
  579. else if which_sess == 2
  580. sess2Name
  581. else if which_sess == 3
  582. sess3Name
  583. else if which_sess == 4
  584. sess4Name
  585. else
  586. "n/a"
  587.  
  588.  
  589.  
  590. current_bar = is_in_session ? str.tostring(array.get(TPO_Names, sess_start)) : "n/a"
  591. info_text_1 = "Ticks: " + str.tostring(tick_size / syminfo.mintick)
  592. info_text_2 = "Tick Size: $" + str.tostring(tick_size)
  593. info_text_3 = "Total TPOs: " + str.tostring(total_tpo_count)
  594. info_text_4 = "Current Bar: " + current_bar
  595. info_text_5 = "Current Session: " + current_sess
  596.  
  597. warning_display_tick_b = total_tpo_count > 495
  598. warning_display_tick_s = "Please Increase Tick Size"
  599. open_price = int((open/tick_size)) * tick_size
  600. cell_info = str.tostring(array.sum(TPO_length))
  601.  
  602. var table ticktestarray = table.new(position.bottom_right, 1, 20, bgcolor = color.gray, frame_width = 2, frame_color = color.black)
  603. var table ticksizetable = table.new(position.top_right, 1, 5, bgcolor = color.gray, frame_width = 2, frame_color = color.black)
  604. if show_tpo_info
  605. table.cell(ticksizetable, 0, 0, text=info_text_1, text_color = color.white, text_size = info_table_txt_size)
  606. table.cell(ticksizetable, 0, 1, text=info_text_2, text_color = color.white, text_size = info_table_txt_size)
  607. table.cell(ticksizetable, 0, 2, text=info_text_3, text_color = color.white, text_size = info_table_txt_size)
  608. table.cell(ticksizetable, 0, 3, text=info_text_4, text_color = color.white, text_size = info_table_txt_size)
  609. table.cell(ticksizetable, 0, 4, text=info_text_5, text_color = color.white, text_size = info_table_txt_size)
  610. else
  611. table.clear(ticksizetable,0,0,0,2)
  612.  
  613. var table tick_warning = table.new(position.middle_right, 1, 1, bgcolor = color.red, frame_width = 2, frame_color = color.black)
  614. if warning_display_tick_b and show_warning
  615. table.cell(tick_warning, 0, 0, text=warning_display_tick_s, text_color = color.white, text_size = size.large)
  616. else
  617. table.clear(tick_warning,0,0,0,0 )
  618.  
  619. if debug_option
  620.  
  621.  
  622. //table.cell(ticktestarray, 0, 0, text="bar_index " + str.tostring(bar_index), text_color = color.white, text_size = deb_txt_size)
  623. //table.cell(ticktestarray, 0, 1, text="sess_start " + str.tostring(sess_start), text_color = color.white, text_size = deb_txt_size)
  624. //table.cell(ticktestarray, 0, 2, text="is_in_session " + str.tostring(is_in_session), text_color = color.white, text_size = deb_txt_size)
  625. //table.cell(ticktestarray, 0, 3, text="test_array " + str.tostring(test_array), text_color = color.white, text_size = deb_txt_size)
  626. table.cell(ticktestarray, 0, 4, text="TPO_rows " + str.tostring(TPO_rows), text_color = color.white, text_size = deb_txt_size)
  627. table.cell(ticktestarray, 0, 5, text="TPO_price " + str.tostring(array.size(TPO_price)), text_color = color.white, text_size = deb_txt_size)
  628. //table.cell(ticktestarray, 0, 6, text="TPO_price " + str.tostring(TPO_price), text_color = color.white, text_size = deb_txt_size)
  629. table.cell(ticktestarray, 0, 7, text="TPO_length " + str.tostring(array.size(TPO_length)), text_color = color.white, text_size = deb_txt_size)
  630. //table.cell(ticktestarray, 0, 8, text="TPO_length " + str.tostring(TPO_length), text_color = color.white, text_size = deb_txt_size)
  631. table.cell(ticktestarray, 0, 9, text="TPOs_Left, VAH_index, VAL_index, 2up, 1up, 1dn, 2nd", text_color = color.white, text_size = deb_txt_size)
  632. //table.cell(ticktestarray, 0, 10, text="TPOS_remaining " + str.tostring(TPOS_remaining), text_color = color.white, text_size = deb_txt_size)
  633. table.cell(ticktestarray, 0, 11, text="TPO_POC " + str.tostring(TPO_POC), text_color = color.white, text_size = deb_txt_size)
  634. table.cell(ticktestarray, 0, 12, text="TPO_VAL " + str.tostring(TPO_VAL), text_color = color.white, text_size = deb_txt_size)
  635. table.cell(ticktestarray, 0, 13, text="TPO_VAH " + str.tostring(TPO_VAH), text_color = color.white, text_size = deb_txt_size)
  636. //table.cell(ticktestarray, 0, 14, text="TPO_per_loop " + str.tostring(TPO_per_loop), text_color = color.white, text_size = deb_txt_size)
  637.  
  638. //table.cell(ticktestarray, 0, 12, text="poc_possible_price " + str.tostring(poc_possible_price), text_color = color.white, text_size = deb_txt_size)
  639. //tick_size[1] + math.round_to_mintick(tick_size[1]*history_reducer)
  640. else
  641. table.clear(ticktestarray,0,0,0,11)
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
Add Comment
Please, Sign In to add comment