Inversion Fair Value Gap Signals [AlgoAlpha]

AlgoAlpha · study · 317 行 · 点赞 3,818 · TradingView 原页

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

Pine Script

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © AlgoAlpha
//@version=6
//────────────────────────────────────────────────────────────────────── Inputs
indicator("Inversion Fair Value Gap Signals [AlgoAlpha]",shorttitle = "AlgoAlpha – IFVG Signals",overlay    = true,max_boxes_count = 500, max_lines_count = 500, max_labels_count = 50)
import TradingView/ta/10
//────────────────────────────────────────────────────────────────────── FVG Detection Inputs
maxBoxAge      = input.int(defval=1000, title="Zone Expiration Bars", tooltip="Upper limit (in bars) for how long an unfinished gap will keep stretching to the right before being deleted", group="FVG  Detection")
preventOverlap = input.bool(defval=true, title="Prevent Overlap", tooltip="When enabled, gaps whose price range overlaps an existing unfinished gap or inversion zone (blue/orange) are discarded", group="FVG  Detection")
showBull       = input.bool(defval=true, title="Show Bullish FVGs", tooltip="Enable detection and rendering of bullish (price-up) fair-value gaps", group="FVG  Detection")
showBear       = input.bool(defval=true, title="Show Bearish FVGs", tooltip="Enable detection and rendering of bearish (price-down) fair-value gaps", group="FVG  Detection")
showGapZone    = input.bool(defval=true, title="Show Main Gap Zone", tooltip="Render the main coloured rectangle that represents the full price gap", group="Appearance")
ltf_ = input.timeframe("5", "Lower Timeframe Value", tooltip = "Determines the lower timeframe used to calculate buying and selling volume")
text_size    = input.string("Tiny", "Volume Text Size", options=["Auto","Tiny","Small","Medium","Large"], group="Appearance", tooltip="Size of the volume text at the corner of the channels.")
bullColor = input.color(#00ffbb, "Bullish Color", tooltip="Color used for bullish trends and indicators. This color appears when price action or indicators suggest upward momentum", group="Appearance")
bearColor = input.color(#ff1100, "Bearish Color", tooltip="Color used for bearish trends and indicators. This color appears when price action or indicators suggest downward momentum", group="Appearance")
invis = color.rgb(0,0,0,100)
//────────────────────────────────────────────────────────────────────── FVG Detection Logic
atr150 = ta.atr(150)*0.3
bullFVG = showBull and low > high[2] and (low - high[2]) > atr150
bearFVG = showBear and high < low[2] and (low[2] - high) > atr150
 
[upv, downv, deltav] = ta.requestUpAndDownVolume(ltf_)
 
//────────────────────────────────────────────────────────────────────── Data Structures
var box[]   gapBoxes = array.new<box>()
var int[]   gapTypes = array.new<int>()
var box[]   gapBoxes_ = array.new<box>()
var int[]   gapTypes_ = array.new<int>()
var box[]   gapBoxes_0 = array.new<box>()
var line[]  gapLines = array.new<line>()
var line[]  gapLines_ = array.new<line>()
var line[]  gapLines_0 = array.new<line>()
var float[] bullVolData = array.new<float>()
var float[] bearVolData = array.new<float>()
var box[]   bullvol = array.new<box>()
var box[]   bearvol = array.new<box>()
var float[] bullVolData_ = array.new<float>()
var float[] bearVolData_ = array.new<float>()
var box[]   bullvol_ = array.new<box>()
var box[]   bearvol_ = array.new<box>()
 
bool bullMit = false
bool bearMit = false
// Track when price has closed inside a given active FVG (per-gap flag)
var bool[]  gapInsideFlags = array.new<bool>()
// Per-bar signal flags for arrows when price exits the FVG without mitigation
bool bullExitNoMit = false
bool bearExitNoMit = false
// Track when price has closed inside a given active inversion zone (orange/blue)
var bool[]  gapInsideFlagsInv = array.new<bool>()
// Per-bar signal flags for inversion zones
bool invBullExitNoMit = false
bool invBearExitNoMit = false
 
// IFVG creation alert flags
bool ifvgBullCreated = false
bool ifvgBearCreated = false
 
// IFVG mitigation alert flags
bool ifvgBullMit = false
bool ifvgBearMit = false
 
 
textSize(text_size) =>
    switch text_size
        "Auto"  => size.auto
        "Tiny"  => size.tiny
        "Small" => size.small
        "Medium"=> size.normal
        "Large" => size.large
 
//────────────────────────────────────────────────────────────────────── Overlap Check Function
f_can_create(float tNew, float bNew) =>
    bool ok = true
    if array.size(gapBoxes) > 0
        for j = 0 to array.size(gapBoxes) - 1
            bx = array.get(gapBoxes, j)
            existingBottom = box.get_bottom(bx)
            existingTop    = box.get_top(bx)
            if (tNew > existingBottom) and (bNew < existingTop)
                ok := false
                break
    if ok and array.size(gapBoxes_) > 0
        for j = 0 to array.size(gapBoxes_) - 1
            bx = array.get(gapBoxes_, j)
            existingBottom = box.get_bottom(bx)
            existingTop    = box.get_top(bx)
            if (tNew > existingBottom) and (bNew < existingTop)
                ok := false
                break
    ok
//────────────────────────────────────────────────────────────────────── New Gap Creation Function
f_new(bool isBull) =>
    l  = bar_index - 1
    r  = bar_index
    t  = isBull ? low     : low[2]
    b  = isBull ? high[2] : high
    c  = chart.fg_color
    bgTransp = showGapZone ? 90 : 100
    brdTransp = showGapZone ? 95 : 100
    big = box.new(l, t, r, b,
         bgcolor      = color.new(c, bgTransp), 
         border_color = color.new(c, brdTransp),
         extend       = extend.none, text = "▲: " + str.tostring(upv[1], format.volume) + " | " + "▼: " + str.tostring(downv[1], format.volume), text_size = textSize(text_size), text_color = chart.fg_color, text_halign = text.align_right, text_valign = text.align_bottom)
    array.unshift(gapBoxes , big)
    array.unshift(gapTypes , isBull ? 1 : -1)
    midY = (t + b) / 2.0
    mid = line.new(l, midY, r, midY)
    mid.set_extend(extend.none)
    mid.set_color(color.new(c, 0))
    mid.set_width(1)
    mid.set_style(line.style_dashed)
    array.unshift(gapLines, mid)
    array.unshift(gapInsideFlags, false)
    array.unshift(bullVolData, upv[1])
    array.unshift(bearVolData, math.abs(downv[2]))
    array.unshift(bullvol, box.new(bar_index-1, t, bar_index, midY, color.new(bullColor, 90), bgcolor = color.new(bullColor, 70)))
    array.unshift(bearvol, box.new(bar_index-1, midY, bar_index, b, color.new(bearColor, 90), bgcolor = color.new(bearColor, 70)))
 
//────────────────────────────────────────────────────────────────────── Gap Management and Rendering
if array.size(gapBoxes) > 0
    for i = array.size(gapBoxes) - 1 to 0
        bx  = array.get(gapBoxes, i)
        l   = box.get_left(bx)
        t   = box.get_top(bx)
        b   = box.get_bottom(bx)
        typ = array.get(gapTypes , i)
        age = bar_index - l
        done = typ == 1 ? (close <= b) : (close >= t)
        insideNow = (close <= t) and (close >= b)
        wasInside = array.get(gapInsideFlags, i)
        if not done
            if insideNow and not wasInside
                array.set(gapInsideFlags, i, true)
            else if wasInside and not insideNow
                if typ == 1 and close > t
                    bullExitNoMit := true
                    array.set(gapInsideFlags, i, false)
                if typ == -1 and close < b
                    bearExitNoMit := true
                    array.set(gapInsideFlags, i, false)
        if done
            array.get(gapBoxes, i).set_right(bar_index)
            array.get(gapBoxes, i).set_text("")
            if typ == 1
                bullMit := true
            else
                bearMit := true
            array.unshift(gapBoxes_, box.new(bar_index, t, bar_index+1, b, color.new(typ == 1 ? bearColor : bullColor, 95), bgcolor = color.new(typ == 1 ? bearColor : bullColor, 90), text = "▲: " + str.tostring(upv[1], format.volume) + " | " + "▼: " + str.tostring(downv[1], format.volume), text_size = textSize(text_size), text_color = chart.fg_color, text_halign = text.align_right, text_valign = text.align_bottom))
            invMidY = (t + b) / 2.0
            invMid = line.new(bar_index, invMidY, bar_index + 1, invMidY)
            invMid.set_extend(extend.none)
            invMid.set_color(typ == 1 ? bearColor : bullColor)
            invMid.set_width(1)
            invMid.set_style(line.style_dashed)
            array.unshift(gapLines_, invMid)
            array.unshift(gapBoxes_0, array.get(gapBoxes, i))
            array.unshift(gapLines_0, array.get(gapLines, i))
            array.unshift(gapTypes_, -typ)
            if (-typ) == 1
                ifvgBullCreated := true
            else
                ifvgBearCreated := true
            array.unshift(bullVolData_, upv[1])
            array.unshift(bearVolData_, math.abs(downv[2]))
            array.unshift(bullvol_, box.new(bar_index-1, t, bar_index, invMidY, color.new(bullColor, 90), bgcolor = color.new(bullColor, 70)))
            array.unshift(bearvol_, box.new(bar_index-1, invMidY, bar_index, b, color.new(bearColor, 90), bgcolor = color.new(bearColor, 70)))
            array.unshift(gapInsideFlagsInv, false)
            array.remove(gapBoxes, i)
            array.remove(gapLines, i)
            array.remove(gapTypes, i)
            array.remove(gapInsideFlags, i)
            array.remove(bullVolData, i)
            array.remove(bearVolData, i)
            bv = array.get(bullvol, i)
            sv = array.get(bearvol, i)
            bv.delete()
            sv.delete()
            array.remove(bullvol, i)
            array.remove(bearvol, i)
            continue
        if age > maxBoxAge
            array.remove(gapBoxes, i).delete()
            array.remove(gapLines, i).delete()
            array.remove(gapTypes, i)
            array.remove(gapInsideFlags, i)
            array.remove(bullVolData, i)
            array.remove(bearVolData, i)
            bv2 = array.get(bullvol, i)
            sv2 = array.get(bearvol, i)
            bv2.delete()
            sv2.delete()
            array.remove(bullvol, i)
            array.remove(bearvol, i)
            continue
        array.get(gapBoxes, i).set_right(bar_index)
        array.get(gapLines, i).set_x2(bar_index)
        midX = int(math.avg(l, bar_index))
        ratio = array.get(bullVolData, i) / math.max(array.get(bearVolData, i), 0.0000001)
        if ratio > 1
            array.get(bullvol, i).set_right(midX)
            array.get(bearvol, i).set_right(int(l + (midX-l) / ratio))     
        else
            array.get(bullvol, i).set_right(int(l + (midX-l) * ratio))     
            array.get(bearvol, i).set_right(midX)
 
if array.size(gapBoxes_) > 0
    for i = array.size(gapBoxes_) - 1 to 0
        bx  = array.get(gapBoxes_, i)
        l   = box.get_left(bx)
        t   = box.get_top(bx)
        b   = box.get_bottom(bx)
        typ = array.get(gapTypes_, i)
        age = bar_index - l
        done = typ == 1 ? (close <= b) : (close >= t)
        insideNowInv = (close <= t) and (close >= b)
        wasInsideInv = array.size(gapInsideFlagsInv) > i ? array.get(gapInsideFlagsInv, i) : false
        if not done
            if insideNowInv and not wasInsideInv
                array.set(gapInsideFlagsInv, i, true)
            else if wasInsideInv and not insideNowInv
                if typ == 1 and close > t
                    invBullExitNoMit := true
                    array.set(gapInsideFlagsInv, i, false)
                if typ == -1 and close < b
                    invBearExitNoMit := true
                    array.set(gapInsideFlagsInv, i, false)
        if done
            if typ == 1
                ifvgBullMit := true
            else
                ifvgBearMit := true
            array.remove(gapBoxes_0, i).delete()
            array.remove(gapLines_0, i).delete()
            array.remove(gapBoxes_, i).delete()
            array.remove(gapLines_, i).delete()
            array.remove(gapTypes_, i)
            array.remove(bullVolData_, i)
            array.remove(bearVolData_, i)
            bv3 = array.get(bullvol_, i)
            sv3 = array.get(bearvol_, i)
            bv3.delete()
            sv3.delete()
            array.remove(bullvol_, i)
            array.remove(bearvol_, i)
            if array.size(gapInsideFlagsInv) > i
                array.remove(gapInsideFlagsInv, i)
            continue
        if age > maxBoxAge
            array.remove(gapBoxes_0, i).delete()
            array.remove(gapLines_0, i).delete()
            array.remove(gapBoxes_, i).delete()
            array.remove(gapLines_, i).delete()
            array.remove(gapTypes_, i)
            array.remove(bullVolData_, i)
            array.remove(bearVolData_, i)
            bv4 = array.get(bullvol_, i)
            sv4 = array.get(bearvol_, i)
            bv4.delete()
            sv4.delete()
            array.remove(bullvol_, i)
            array.remove(bearvol_, i)
            if array.size(gapInsideFlagsInv) > i
                array.remove(gapInsideFlagsInv, i)
            continue
        array.get(gapBoxes_, i).set_right(bar_index)
        array.get(gapLines_, i).set_x2(bar_index)
        midX = int(math.avg(l, bar_index))
        ratio_ = array.get(bullVolData_, i) / math.max(array.get(bearVolData_, i), 0.0000001)
        if ratio_ > 1
            array.get(bullvol_, i).set_right(midX)
            array.get(bearvol_, i).set_right(int(l + (midX-l) / ratio_))     
        else
            array.get(bullvol_, i).set_right(int(l + (midX-l) * ratio_))     
            array.get(bearvol_, i).set_right(midX)
 
 
 
 
//────────────────────────────────────────────────────────────────────── New Gap Detection
if bullFVG
    tProp = low
    bProp = high[2]
    if not preventOverlap or f_can_create(tProp, bProp)
        f_new(true)
if bearFVG
    tProp = low[2]
    bProp = high
    if not preventOverlap or f_can_create(tProp, bProp)
        f_new(false)
//────────────────────────────────────────────────────────────────────── Signals: exit FVG without mitigation
if bullExitNoMit
    label.new(bar_index, low - atr150, "△", style = label.style_text_outline, color = invis, textcolor = color.new(chart.fg_color, 50), size = size.small, xloc = xloc.bar_index)
if bearExitNoMit
    label.new(bar_index, high + atr150, "▽", style = label.style_text_outline, color = invis, textcolor = color.new(chart.fg_color, 50), size = size.small, xloc = xloc.bar_index)
//────────────────────────────────────────────────────────────────────── Signals: exit inversion (orange/blue) without mitigation
if invBullExitNoMit
    label.new(bar_index, low - atr150, "▲", style = label.style_text_outline, color = invis, textcolor = color.new(bullColor, 30), size = size.small, xloc = xloc.bar_index)
if invBearExitNoMit
    label.new(bar_index, high + atr150, "▼", style = label.style_text_outline, color = invis, textcolor = color.new(bearColor, 30), size = size.small, xloc = xloc.bar_index)
//────────────────────────────────────────────────────────────────────── Alerts
alertcondition(bullFVG, "Bullish FVG", "Bullish fair-value gap detected")
alertcondition(bearFVG, "Bearish FVG", "Bearish fair-value gap detected")
alertcondition(bullMit, "Bullish FVG Mitigated", "Bullish fair-value gap mitigated")
alertcondition(bearMit, "Bearish FVG Mitigated", "Bearish fair-value gap mitigated")
// IFVG creation alerts
alertcondition(ifvgBullCreated, "Bullish IFVG Created", "Bullish inversion fair-value gap created")
alertcondition(ifvgBearCreated, "Bearish IFVG Created", "Bearish inversion fair-value gap created")
// IFVG mitigation alerts
alertcondition(ifvgBullMit, "Bullish IFVG Mitigated", "Bullish inversion fair-value gap mitigated")
alertcondition(ifvgBearMit, "Bearish IFVG Mitigated", "Bearish inversion fair-value gap mitigated")
// Rejection alerts (exit without mitigation)
alertcondition(bullExitNoMit, "Bullish FVG Rejection", "Price rejected bullish FVG without mitigation")
alertcondition(bearExitNoMit, "Bearish FVG Rejection", "Price rejected bearish FVG without mitigation")
alertcondition(invBullExitNoMit, "Bullish IFVG Rejection", "Price rejected bullish IFVG without mitigation")
alertcondition(invBearExitNoMit, "Bearish IFVG Rejection", "Price rejected bearish IFVG without mitigation")

← 返回列表