本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。
// This work is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
// https://creativecommons.org/licenses/by-nc-sa/4.0/
// © BigBeluga
//@version=5
indicator("FVG Order Blocks [BigBeluga]", overlay=true, max_boxes_count=500, max_lines_count=500, max_bars_back=2000)
// INPUTS ========================================================================================================{
//@variable: Lookback period for detecting imbalances
int loockback = 2000
//@variable: Filter to determine significant imbalances as a percentage
float filter = input.float(0.5, "Filter Gaps by %", minval=0, maxval=100, step=0.1)
//@variable: Toggle to show/hide Order Blocks
bool show_imb = input.bool(true, "Fair Value Gaps", inline="1")
//@variable: Maximum number of levels to display
int box_amount = input.int(6, "Blocks Amount")
//@variable: Toggle to show/hide broken Order Blocks
bool show_broken = input.bool(false, "Broken Blocks")
bool show_signal = input.bool(false, "Order Blocks Signals")
//@variable: Color for bullish Order Blocks
color col_bull = input.color(#14be94, "Color +/-", inline="2")
//@variable: Color for bearish Order Blocks
color col_bear = input.color(color.rgb(194, 25, 25), "", inline="2")
// Arrays to store boxes
var boxes1 = array.new<box>(10, box(na)) // Bullish boxes
var boxes2 = array.new<box>(10, box(na)) // Bearish boxes
// Boolean variables to identify bullish and bearish gaps
var bool isBull_gap = na
var bool isBear_gap = na
// Box variables for the current bullish and bearish levels
var box1 = box(na)
var box2 = box(na)
// }
// CALCULATIONS ============================================================================================={
// Normalized ATR (Average True Range)
series float atr = ta.atr(200)
// Imbalance Filters
float filt_up = (low-high[2])/low*100 // Filter for bullish Imbalance
float filt_dn = (low[2]-high) / low[2] *100 // Filter for bearish Imbalance
max_up = ta.highest(filt_up, 200)
max_dn = ta.highest(filt_dn, 200)
// Detect gaps and create boxes for bullish and bearish imbalances
if barstate.isconfirmed and last_bar_index - bar_index < loockback
isBull_gap := high[2] < low and high[2] < high[1] and low[2] < low and filt_up > filter
isBear_gap := low[2] > high and low[2] > low[1] and high[2] > high and filt_dn > filter
// Logic for Bullish Imbalance
if isBull_gap
if show_imb
// Create a temporary box representing the gap
box.new(bar_index-1, low, bar_index + 5, high[2], na, 0,
bgcolor = color.from_gradient(filt_up, 0, max_up, color.new(chart.fg_color, 90), color.new(chart.fg_color, 70)),
text = str.tostring(filt_up, format.percent),
text_color = chart.fg_color
)
box1 := box.new(bar_index-1, high[2], last_bar_index, high[2] - atr, col_bull, 1,
bgcolor = color.from_gradient(filt_up, 0, max_up, na, color.new(col_bull, 70)),
text = str.tostring(filt_up, format.percent),
text_size = size.small,
text_color = chart.fg_color,
text_halign = text.align_right)
boxes1.push(box1)
// Logic for Bearish Imbalance
if isBear_gap
if show_imb
// Create a temporary box representing the gap
box.new(bar_index-1, low[2], bar_index + 5, high, na, 0,
bgcolor = color.from_gradient(filt_dn, 0, max_dn, color.new(chart.fg_color, 90), color.new(chart.fg_color, 70)),
text = "-"+str.tostring(filt_dn, format.percent),
text_color = chart.fg_color
)
box2 := box.new(bar_index-1, low[2] + atr, last_bar_index, low[2], col_bear, 1,
bgcolor = color.from_gradient(filt_dn, 0, max_dn, na, color.new(col_bear, 70)),
text =str.tostring(filt_dn, format.percent),
text_size =size.small,
text_color = chart.fg_color,
text_halign = text.align_right)
boxes2.push(box2)
// Adjust the position of the boxes as new bars are added
if barstate.islast
for box_id in boxes1
box.set_right(box_id, bar_index + 15)
for box_id in boxes2
box.set_right(box_id, bar_index + 15)
// Logic to handle broken levels
for box_id in boxes1
if high < box.get_bottom(box_id)
box.set_border_width(box_id, 0)
box.set_bgcolor(box_id, color.new(chart.fg_color, 85))
if not show_broken
box.delete(box_id)
boxes1.remove(boxes1.indexof(box_id))
if low > box.get_top(box_id) and low[1] <= box.get_top(box_id) and not isBull_gap and show_signal
label.new(bar_index-1, low[1], "︽", color = color(na), textcolor = col_bull, style = label.style_label_up)
for box_id1 in boxes1
top1 = box_id1.get_top()
top = box_id.get_top()
bottom1 = box_id1.get_bottom()
bottom = box_id.get_bottom()
if top1 < top and top1 > bottom
box.delete(box_id)
boxes1.remove(boxes1.indexof(box_id))
for box_id in boxes2
if low > box.get_top(box_id)
box.set_border_width(box_id, 0)
box.set_bgcolor(box_id, color.new(chart.fg_color, 85))
if not show_broken
box.delete(box_id)
boxes2.remove(boxes2.indexof(box_id))
if high < box.get_bottom(box_id) and high[1] >= box.get_bottom(box_id) and not isBear_gap and show_signal
label.new(bar_index-1, high[1], "﹀", color = color(na), textcolor = col_bear, style = label.style_label_down)
for box_id1 in boxes2
top1 = box_id1.get_top()
top = box_id.get_top()
bottom1 = box_id1.get_bottom()
bottom = box_id.get_bottom()
if top1 < top and top1 > bottom
box.delete(box_id)
boxes2.remove(boxes2.indexof(box_id))
// Limit the number of displayed boxes to the specified amount
if boxes1.size() >= box_amount
box.delete(boxes1.shift())
if boxes2.size() >= box_amount
box.delete(boxes2.shift())
// }