本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © pmk07
//
// Acknowledgements/Reference:
//
// @rumpypumpydumpy - Higher Order Pivots
// https://www.tradingview.com/v/x2LlRvBe/
//
// @MarkMiddleton2020 - Order Blocks
// https://www.tradingview.com/v/GecN34Qq/
//
//@version=5
indicator(title='Order Blocks', overlay=true)
bool bos_sv = input(true, title='Highlight candles that broke structure')
bool msb_sv = input(true, title='Plot market structure broke lines')
bool box_sv = input(true, title='Plot demand boxes')
int box_test_delay = input(3, title='Delay to count test of demand box')
int box_fill_delay = input(3, title='Delay to count fill of demand box')
bool box_test_sv = input(true, title='Dim tested demand boxes')
bool box_stop_sv = input(true, title='Stop plotting filled demand boxes')
var float[] pvh1_price = array.new_float(1000, na) // high
var int[] pvh1_time = array.new_int(1000, na)
var float[] pvl1_price = array.new_float(1000, na) // low
var int[] pvl1_time = array.new_int(1000, na)
var float[] pvh2_price = array.new_float(1000, na) // higher high
var int[] pvh2_time = array.new_int(1000, na)
var float[] pvl2_price = array.new_float(1000, na) // lower low
var int[] pvl2_time = array.new_int(1000, na)
var float htcmrll_price = na // high that created most recent ll
var int htcmrll_time = na
var float ltcmrhh_price = na // low that created most recent hh
var int ltcmrhh_time = na
var box[] long_boxes = array.new_box()
var box[] short_boxes = array.new_box()
var box[] oldlong_boxes = array.new_box()
var box[] oldshort_boxes = array.new_box()
var line[] bull_bos_lines = array.new_line()
var line[] bear_bos_lines = array.new_line()
var float temp_pv_0 = na
var float temp_pv_1 = na
var int temp_pv_time = na
bool pvh = high < high[1] and high[1] > high[2]
bool pvl = low > low[1] and low[1] < low[2]
int pv1_time = bar_index[1]
float pv1_high = high[1]
float pv1_low = low[1]
bool bos_candle = false
if barstate.isconfirmed
if pvh
array.pop(pvh1_price)
array.pop(pvh1_time)
array.unshift(pvh1_price, pv1_high)
array.unshift(pvh1_time, pv1_time)
if array.size(pvh1_price) > 2
temp_pv_0 := array.get(pvh1_price, 0)
temp_pv_1 := array.get(pvh1_price, 1)
temp_pv_time := array.get(pvh1_time, 0)
if temp_pv_0 > temp_pv_1
array.pop(pvh2_price)
array.pop(pvh2_time)
array.unshift(pvh2_price, temp_pv_0)
array.unshift(pvh2_time, temp_pv_time)
for i = 0 to array.size(pvl1_time) - 1 by 1
temp_ltcmrhh_time = array.get(pvl1_time, i)
if temp_ltcmrhh_time < temp_pv_time
ltcmrhh_price := array.get(pvl1_price, i)
ltcmrhh_time := temp_ltcmrhh_time
break
if pvl
array.pop(pvl1_price)
array.pop(pvl1_time)
array.unshift(pvl1_price, pv1_low)
array.unshift(pvl1_time, pv1_time)
if array.size(pvl1_price) > 2
temp_pv_0 := array.get(pvl1_price, 0)
temp_pv_1 := array.get(pvl1_price, 1)
temp_pv_time := array.get(pvl1_time, 0)
if temp_pv_0 < temp_pv_1
array.pop(pvl2_price)
array.pop(pvl2_time)
array.unshift(pvl2_price, temp_pv_0)
array.unshift(pvl2_time, temp_pv_time)
for i = 0 to array.size(pvh1_time) - 1 by 1
temp_htcmrll_time = array.get(pvh1_time, i)
if temp_htcmrll_time < temp_pv_time
htcmrll_price := array.get(pvh1_price, i)
htcmrll_time := temp_htcmrll_time
break
if high > htcmrll_price
if msb_sv
array.push(bull_bos_lines, line.new(x1=htcmrll_time, y1=htcmrll_price, x2=bar_index, y2=htcmrll_price, color=color.red, width=2))
if box_sv
array.push(long_boxes, box.new(left=array.get(pvl1_time, 0), top=math.min(high[bar_index - array.get(pvl1_time, 0)], high[bar_index - array.get(pvl1_time, 0) + 1]), right=bar_index, bottom=array.get(pvl1_price, 0), bgcolor=color.rgb(0, 255, 0, 80), border_color=color.rgb(0, 255, 0, 80), extend=extend.right))
bos_candle := true
htcmrll_price := na
htcmrll_price
if low < ltcmrhh_price
if msb_sv
array.push(bear_bos_lines, line.new(x1=ltcmrhh_time, y1=ltcmrhh_price, x2=bar_index, y2=ltcmrhh_price, color=color.green, width=2))
if box_sv
array.push(short_boxes, box.new(left=array.get(pvh1_time, 0), top=array.get(pvh1_price, 0), right=bar_index, bottom=math.max(low[bar_index - array.get(pvh1_time, 0)], low[bar_index - array.get(pvh1_time, 0) + 1]), bgcolor=color.rgb(255, 0, 0, 80), border_color=color.rgb(255, 0, 0, 80), extend=extend.right))
bos_candle := true
ltcmrhh_price := na
ltcmrhh_price
if array.size(short_boxes) > 0
for i = array.size(short_boxes) - 1 to 0 by 1
tbox = array.get(short_boxes, i)
top = box.get_top(tbox)
bottom = box.get_bottom(tbox)
if high > bottom and box.get_left(tbox) + box_test_delay < bar_index and box_test_sv
box.set_bgcolor(tbox, color.rgb(192, 192, 192, 80))
box.set_border_color(tbox, color.rgb(192, 192, 192, 80))
if high > top and box.get_left(tbox) + box_fill_delay < bar_index
if box_stop_sv
box.set_right(tbox, bar_index)
box.set_extend(tbox, extend.none)
array.unshift(oldshort_boxes, tbox)
array.remove(short_boxes, i)
if array.size(long_boxes) > 0
for i = array.size(long_boxes) - 1 to 0 by 1
lbox = array.get(long_boxes, i)
top = box.get_top(lbox)
bottom = box.get_bottom(lbox)
if low < top and box.get_left(lbox) + box_test_delay < bar_index and box_test_sv
box.set_bgcolor(lbox, color.rgb(192, 192, 192, 80))
box.set_border_color(lbox, color.rgb(192, 192, 192, 80))
if low < bottom and box.get_left(lbox) + box_fill_delay < bar_index
if box_stop_sv
box.set_right(lbox, bar_index)
box.set_extend(lbox, extend.none)
array.unshift(oldlong_boxes, lbox)
array.remove(long_boxes, i)
barcolor(bos_candle and bos_sv ? color.yellow : na)