Advertisement
xmd79

Supply and Demand Zones |Moon Dev|

Sep 23rd, 2023
448
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.18 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. // © moondevonyt
  3.  
  4. //@version=5
  5. indicator("Supply and Demand Zones |Moon Dev|", shorttitle="SDZ |Moon Dev|", overlay=true, max_boxes_count= 500, max_bars_back = 500)
  6.  
  7. // settings
  8. thres = input.float(10, 'Threshold %', minval= 0, maxval=100)
  9. div = input.int(50, 'Resolution', minval=2, maxval=500)
  10. custom_timeframe = input.timeframe('', 'Intrabar Timeframe')
  11.  
  12. // picking oour color
  13. supplysh0w = input(true, 'Supply Sh0w', inline='supply', group = 'Style')
  14. c0l0rsupply = input(#FF0000, 'Color', inline='supply', group='Stlye')
  15. supplyar3a = input(true, 'Show area', inline='supply', group = 'Style')
  16. supplyavg = input(true, 'Show avg', inline = 'supply', group = 'Style')
  17. supply_weighted_avg = input(true, 'Show weighted avg', inline = 'supply', group = 'Style')
  18.  
  19. show3qualibr1un = input(true, 'show equalibrium', inline='equi', group='Style')
  20. c0lor3qual = input(color.gray, 'Color', inline= 'equi', group = 'Style')
  21. avg3qualib = input(true, 'equalibrium avg', inline='equi', group='Style')
  22. w3ight3d_avg_3qual = input(true, 'weighted avg equalibrium', inline='equi', group='Style')
  23.  
  24. showd3mand = input(true, 'show demand', inline='demand', group='Style')
  25. c0lor_d3mand = input(#008000, 'Color', inline='demand', group='Style')
  26. d3mandar3a = input(true, 'show area', inline='demand', group='Style')
  27. d3mandavg = input(true, 'show average', inline='demand', group='Style')
  28. d3mand_w3ight3d_avg = input(true, 'show weighted avg', inline='demand', group='Style')
  29.  
  30. // Custom types
  31.  
  32. type DemandSupplyCrate
  33. float quantity
  34. float last_amount
  35. float total
  36. float previous_total
  37. float total_accumulated
  38. float average_quantity
  39. bool fulfilled
  40.  
  41. type DemandSupplyZone
  42. box box_obj
  43. line avg_path
  44. line weighted_avg_line
  45.  
  46. // operations
  47. n = bar_index
  48.  
  49. fetch_data()=> [high, low, volume]
  50.  
  51. method configure_section(DemandSupplyZone id, x1, top, bottom, avg_val, wavg_val, display_section, display_avg, display_wavg)=>
  52. if display_section
  53. id.box_obj.set_lefttop(x1, top)
  54. id.box_obj.set_rightbottom(n, bottom)
  55.  
  56. if display_avg
  57. id.avg_path.set_xy1(x1, avg_val)
  58. id.avg_path.set_xy2(n, avg_val)
  59.  
  60. if display_avg
  61. id.weighted_avg_line.set_xy1(x1, wavg_val)
  62. id.weighted_avg_line.set_xy2(n, wavg_val)
  63.  
  64. // setting up variables
  65. var peak_amount = 0.
  66. var bottom_amount = 0.
  67. var x_init = 0
  68. var total_accumulated = 0.
  69.  
  70. // intrabar info
  71. [high_amount, low_amount, volume_data] = request.security_lower_tf(syminfo.tickerid, custom_timeframe, fetch_data())
  72.  
  73. // initiliazation on intial bar
  74. if time == chart.left_visible_bar_time
  75. peak_amount := high
  76. bottom_amount := low
  77. total_accumulated := volume
  78. x_init := n
  79.  
  80. else // accumulation
  81. peak_amount := math.max(high, peak_amount)
  82. bottom_amount := math.min(low, bottom_amount)
  83. total_accumulated += volume
  84.  
  85. // establish regions
  86.  
  87. var region_A = DemandSupplyZone.new(box.new(na, na, na, na, na, bgcolor = color.new(c0l0rsupply, 80)), line.new(na, na, na, na , color = c0l0rsupply), line.new(na, na, na, na, color=c0l0rsupply, style=line.style_dashed))
  88.  
  89. var region_B = DemandSupplyZone.new(box.new(na, na, na, na, na, bgcolor = color.new(c0lor_d3mand, 80)), line.new(na, na, na, na , color = c0lor_d3mand), line.new(na, na, na, na, color=c0lor_d3mand, style=line.style_dashed))
  90.  
  91. var equalibrium_boundary = line.new(na, na, na, na, color = c0lor3qual)
  92. var weighted_equalibrium_boundary = line.new(na, na, na, na, color = c0lor3qual, style = line.style_dashed)
  93.  
  94. var float A_weighted_avg = na
  95. var float B_weighted_avg = na
  96.  
  97. if time == chart.right_visible_bar_time
  98. partition_size = (peak_amount - bottom_amount) / div
  99. A_section = DemandSupplyCrate.new(peak_amount, peak_amount, 0, 0, 0, 0, false) // A_secont == Supply B = Demand
  100. B_section = DemandSupplyCrate.new(bottom_amount, bottom_amount, 0, 0, 0, 0, false)
  101.  
  102. // iterate through segments
  103. for i = 0 to div -1
  104. A_section.quantity -= partition_size
  105. B_section.quantity += partition_size
  106.  
  107. // cumulative quntity column
  108. if not A_section.fulfilled and supplysh0w and supplyar3a
  109. box_obj = box.new(x_init, A_section.last_amount, x_init + int(A_section.total / total_accumulated * (n - x_init)), A_section.quantity, na, bgcolor=color.new(c0l0rsupply, 50))
  110. avg_path = line.new(na, na, na, na, color = c0l0rsupply)
  111. weighted_avg_line = line.new(na, na, na, na, color=c0l0rsupply, style=line.style_dotted)
  112. region_A := DemandSupplyZone.new(box_obj, avg_path, weighted_avg_line)
  113.  
  114. if not B_section.fulfilled and showd3mand and d3mandar3a
  115. box_obj = box.new(x_init, B_section.quantity, x_init + int(B_section.total / total_accumulated * (n - x_init)), B_section.last_amount, na, bgcolor=color.new(c0lor_d3mand, 50))
  116. avg_path = line.new(na, na, na, na, color = c0lor_d3mand)
  117. weighted_avg_line = line.new(na, na, na, na, color=c0lor_d3mand, style=line.style_dotted)
  118. region_B := DemandSupplyZone.new(box_obj, avg_path, weighted_avg_line)
  119.  
  120. // iterate thought steps
  121. for j = 0 to (n-x_init)-1
  122. // iterate through sub steps
  123. for k = 0 to (volume_data[j]).size()-1
  124. // accumulate if within upper range
  125. A_section.total += (high_amount[j]).get(k) > A_section.quantity and (high_amount[j]).get(k) < A_section.last_amount ? (volume_data[j]).get(k) : 0
  126. A_section.average_quantity += A_section.quantity * (A_section.total - A_section.previous_total)
  127. A_section.total_accumulated += A_section.total - A_section.previous_total
  128. A_section.previous_total := A_section.total
  129.  
  130. // accumulate if within lower range
  131. B_section.total += (low_amount[j]).get(k) < B_section.quantity and (low_amount[j]).get(k) < B_section.last_amount ? (volume_data[j]).get(k) : 0
  132. B_section.average_quantity += B_section.quantity * (B_section.total - B_section.previous_total)
  133. B_section.total_accumulated += B_section.total - B_section.previous_total
  134. B_section.previous_total := B_section.total
  135.  
  136. // check if a section accumualted amount exceed threshold and set
  137. if A_section.total / total_accumulated * 100 > thres and not A_section.fulfilled
  138. avg = math.avg(peak_amount, A_section.quantity)
  139. A_weighted_avg := A_section.average_quantity / A_section.total_accumulated
  140.  
  141. // show box/level cordinates
  142. if supplysh0w
  143. region_A.configure_section(x_init, peak_amount, A_section.quantity, avg, A_weighted_avg, supplyar3a, supplyavg, supply_weighted_avg)
  144.  
  145. A_section.fulfilled := true
  146.  
  147. if B_section.total / total_accumulated * 100 > thres and not B_section.fulfilled
  148. avg = math.avg(bottom_amount, B_section.quantity)
  149. B_weighted_avg := B_section.average_quantity / B_section.total_accumulated
  150.  
  151. // show box/level cordinates
  152. if showd3mand
  153. region_B.configure_section(x_init, B_section.quantity, bottom_amount, avg, B_weighted_avg, d3mandar3a, d3mandavg, d3mand_w3ight3d_avg)
  154.  
  155. B_section.fulfilled := true
  156.  
  157. if A_section.fulfilled and B_section.fulfilled
  158. break
  159.  
  160. if A_section.fulfilled and B_section.fulfilled and show3qualibr1un
  161. // set equalibrium
  162. if avg3qualib
  163. avg = math.avg(peak_amount, bottom_amount)
  164. equalibrium_boundary.set_xy1(x_init, avg)
  165. equalibrium_boundary.set_xy2(n, avg)
  166.  
  167. // weighted
  168. if w3ight3d_avg_3qual
  169. wavg = math.avg(A_weighted_avg, B_weighted_avg)
  170. weighted_equalibrium_boundary.set_xy1(x_init, wavg)
  171. weighted_equalibrium_boundary.set_xy2(n, wavg)
  172.  
  173. break
  174.  
  175. A_section.last_amount := A_section.quantity
  176. B_section.last_amount := B_section.quantity
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement