Volume Profile Bar-Magnified Order Blocks [JacobMagleby]

MaglebySystems · study · 213 行 · 点赞 6,264 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © JacobMagleby
 
//@version=5
indicator(title = "Volume Profile Bar-Magnified Order Blocks [JacobMagleby]", shorttitle = "Volume Profile Bar-Magnified Order Blocks [JacobMagleby]", overlay = true, max_boxes_count = 500, max_lines_count = 500)
 
// { START CONSTANTS BUILD
 
OB_BORDER_WIDTH = 2
 
// } END CONSTANTS BUILD
 
 
 
// { START USER INPUT BUILD
 
tuning = input.int(title = "Tuning", defval = 7, group = "Main Settings")
amount_of_boxes = input.int(title = "Amount Of Grids", defval = 10, group = "Main Settings")
ob_high_volume_color = input.color(title = "", defval = color.new(color.yellow, 35), group = "Color Settings", inline = "colors")
ob_low_volume_color = input.color(title = "", defval = color.new(color.orange, 35), group = "Color Settings", inline = "colors")
ob_border_color = input.color(title = "", defval = color.new(color.gray, 85), group = "Color Settings", inline = "colors")
ob_linefill_color = input.color(title = "", defval = color.new(color.gray, 75), group = "Color Settings", inline = "colors")
 
// } END USER INPUT BUILD
 
 
 
// { START FUNCTIONS BUILD
 
check_ob_conditions(set)=>
    bear = false
    for i = tuning - 1 to 0
        start = tuning - 1
        if i == start
            if close[i] <= open[i]
                break
        else
            if close[i] > open[i]
                break
            
            if i == 0
                bear := true
 
    bull = false
    for i = tuning - 1 to 0
        start = tuning - 1
        if i == start
            if close[i] >= open[i]
                break
        else
            if close[i] < open[i]
                break
            
            if i == 0
                bull := true
    
    [bear, bull]
 
// } END FUNCTIONS BUILD
 
 
 
// { START OBJECT BLUEPRINTS BUILD
 
type orderBlock
    line top_line
    line bot_line
    linefill bg_fill
    array<box> box_array = na
    array<float> box_volume = na
    float top_value
    float bot_value
    int left_time
    int right_time
    string direction
 
method generateBorderLines(orderBlock order_block, top_value, bot_value)=>
    new_top_line = line.new(x1 = order_block.left_time, y1 = top_value, x2 = time, y2 = top_value, xloc = xloc.bar_time, extend = extend.none, color = ob_border_color, style = line.style_solid, width = OB_BORDER_WIDTH)
    new_bot_line = line.new(x1 = order_block.left_time, y1 = bot_value, x2 = time, y2 = bot_value, xloc = xloc.bar_time, extend = extend.none, color = ob_border_color, style = line.style_solid, width = OB_BORDER_WIDTH)
    new_linefill = linefill.new(new_top_line, new_bot_line, ob_linefill_color)
    order_block.top_line := new_top_line
    order_block.bot_line := new_bot_line
    order_block.bg_fill := new_linefill
 
method generateVolume(orderBlock order_block, top_value, bot_value, v_array, h_array, l_array)=>
    new_volume_array = order_block.box_volume
    starting_value = top_value
    increment = (top_value - bot_value) / amount_of_boxes
    for i = 0 to amount_of_boxes - 1
        top_of_grid = starting_value - (increment * i)
        bot_of_grid = starting_value - (increment * (i + 1))
        if array.size(v_array) > 0 and array.size(h_array) > 0 and array.size(l_array) > 0
            for j = 0 to array.size(v_array) - 1
                candle_volume = array.get(v_array, j)
                candle_high = array.get(h_array, j)
                candle_low = array.get(l_array, j)
                ltf_diff = candle_high - candle_low
 
                
                if candle_low <= top_of_grid and candle_high >= bot_of_grid
                    top_register = math.min(candle_high, top_of_grid)
                    bot_register = math.max(candle_low, bot_of_grid)
 
                    register_diff = top_register - bot_register
                    register_vol = register_diff / ltf_diff
                    array.set(new_volume_array, i, array.get(new_volume_array, i) + nz(register_vol * candle_volume))
 
    array.sum(new_volume_array)
 
method generateBoxes(orderBlock order_block, top_value, bot_value, left_value, right_value)=>
    new_boxes_array = array.new_box()
 
    highest_volume = array.max(order_block.box_volume)
    lowest_volume = array.min(order_block.box_volume)
    time_length = order_block.right_time - order_block.left_time
    time_ratio = time_length / highest_volume
 
    starting_value = top_value
    increment = (top_value - bot_value) / amount_of_boxes
    for i = 0 to amount_of_boxes - 1
        top_of_grid = starting_value - (increment * i)
        bot_of_grid = starting_value - (increment * (i + 1))
        color_ = color.from_gradient(array.get(order_block.box_volume, i), lowest_volume, highest_volume, ob_low_volume_color, ob_high_volume_color)
        new_box = box.new(left = order_block.left_time, top = top_of_grid, right = order_block.left_time + math.round(array.get(order_block.box_volume, i) * time_ratio), bottom = bot_of_grid, border_color = color_, border_width = 2, xloc = xloc.bar_time, bgcolor = color_, extend = extend.none)
        array.push(new_boxes_array, new_box)
    
    order_block.box_array := new_boxes_array
 
method updateBoxes(orderBlock order_block, current_time)=>
    order_block.right_time := current_time
 
    highest_volume = array.max(order_block.box_volume)
    lowest_volume = array.min(order_block.box_volume)
    time_length = order_block.right_time - order_block.left_time
    time_ratio = time_length / highest_volume
 
    for i = 0 to amount_of_boxes - 1
        box.set_right(array.get(order_block.box_array, i), order_block.left_time + math.round(array.get(order_block.box_volume, i) * time_ratio))
    
    line.set_x2(order_block.top_line, order_block.right_time)
    line.set_x2(order_block.bot_line, order_block.right_time)
 
method wipeBlock(orderBlock order_block)=>
    line.delete(order_block.top_line)
    line.delete(order_block.bot_line)
    linefill.delete(order_block.bg_fill)
    for i = array.size(order_block.box_array) - 1 to 0
        box_ = array.get(order_block.box_array, i)
        box.delete(box_)
 
// } END OBJECT BLUEPRINTS BUILD
 
 
 
// { START LOWER TIMEFRAME SECURITY BUILD
 
tf = timeframe.isdaily ? 1440 : timeframe.isweekly ? 1440 * 7 : timeframe.ismonthly ? 1440 * 30 : str.tonumber(timeframe.period)
req_tf = math.round(tf / 15) < 1 ? "30S" : str.tostring(math.round(tf / 15))
[h, l, v] = request.security_lower_tf(syminfo.tickerid, req_tf, [high, low, volume])
 
// } END LOWER TIMEFRAME SECURITY BUILD
 
 
 
// { START INDICATOR CONSTRUCTION BUILD
 
[bear, bull] = check_ob_conditions(tuning)
 
var array<orderBlock> order_block_array = array.new<orderBlock>(0)
 
if not na(bar_index[tuning]) and barstate.isconfirmed
    if bear
        top_value = high[tuning - 1]
        bot_value = low[tuning - 1]
        left_value = time[tuning - 1]
        right_value = time
 
        new_order_block = orderBlock.new(top_value = top_value, bot_value = bot_value, left_time = left_value, right_time = right_value, box_volume = array.new_float(amount_of_boxes, 0), direction = "Bear")
        new_order_block.generateBorderLines(new_order_block.top_value, new_order_block.bot_value)
        vol = new_order_block.generateVolume(new_order_block.top_value, new_order_block.bot_value, v[tuning - 1], h[tuning - 1], l[tuning - 1])
        new_order_block.generateBoxes(new_order_block.top_value, new_order_block.bot_value, new_order_block.left_time, new_order_block.right_time)
        if vol == 0
            new_order_block.wipeBlock()
        else
            array.push(order_block_array, new_order_block)
 
    if bull
        top_value = high[tuning - 1]
        bot_value = low[tuning - 1]
        left_value = time[tuning - 1]
        right_value = time
 
        new_order_block = orderBlock.new(top_value = top_value, bot_value = bot_value, left_time = left_value, right_time = right_value, box_volume = array.new_float(amount_of_boxes, 0), direction = "Bull")
        new_order_block.generateBorderLines(new_order_block.top_value, new_order_block.bot_value)
        vol = new_order_block.generateVolume(new_order_block.top_value, new_order_block.bot_value, v[tuning - 1], h[tuning - 1], l[tuning - 1])
        new_order_block.generateBoxes(new_order_block.top_value, new_order_block.bot_value, new_order_block.left_time, new_order_block.right_time)
        if vol == 0
            new_order_block.wipeBlock()
        else
            array.push(order_block_array, new_order_block)
 
max_blocks = math.floor(500 / amount_of_boxes)
if array.size(order_block_array) > 0
    for i = array.size(order_block_array) - 1 to 0
        block = array.get(order_block_array, i)
        block.updateBoxes(time)
        bull_break = block.direction == "Bull" and close < block.bot_value
        bear_break = block.direction == "Bear" and close > block.top_value
        if (bull_break or bear_break or i < (array.size(order_block_array) - 1 - max_blocks)) and barstate.isconfirmed
            block.wipeBlock()
            array.remove(order_block_array, i)
 
// } END INDICATOR CONSTRUCTION BUILD

← 返回列表