Order blocks

mickes · study · 158 行 · 点赞 2,784 · 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/
// © mickes
 
//@version=5
indicator("Order blocks", overlay = true, max_boxes_count = 500, max_lines_count = 500, max_labels_count = 500)
 
import mickes/Touched/14
 
_timeframe = input.timeframe("", "Timeframe")
_count = input.int(3, "Count")
_type = input.string("Both", "Type", ["Bullish", "Bearish", "Both"])
_history = input.bool(true, "Keep history", tooltip = "Check this if you want old zones to be keept. They are removed if they are broken (if you have 'Remove broken zones' checked) or if a new zone is created and the count is reached. This means that zones can go 'old' even if thay are not interacted with.")
_removeBroken = input.bool(true, "Remove broken zones")
 
_reactionFactor = input.float(3, "Reaction", inline = "reaction", group = "Requirements")
_reactionShow = input.bool(true, "", tooltip = "A factor (%) of the Average True Range (of length 14) that the total reaction must have. And check the checkbox if you want the limit to be displayed.", inline = "reaction", group = "Requirements")
_takeOut = input.bool(true, "Take out", tooltip = "The bar that start the reaction must take out the previous bar high/low (liquidity sweep).", group = "Requirements")
_consecutiveRisingIrFalling = input.bool(true, "Consecutive rising/falling", tooltip = "The candles in the reaction must consecutivly rise or fall.", group = "Requirements")
_fairValueGap = input.bool(true, "Fair Value Gap", group = "Requirements")
 
_color = input.color(color.fuchsia, "Zones", group = "Display")
_colorReplaced = input.color(color.aqua, "Replaced zones", group = "Display")
_colorBroken = input.color(color.red, "Broken zones", group = "Display")
 
type Visual
    array<box> Boxes
    array<line> Lines
    array<label> Labels
type Zone
    int Time
    int TimeClose
    float High
    float Low
    float ReactionLimit
    Touched.Zone TouchedZone
    Visual Visual
    int Type // -1 = bearish, 1 = bullish
type Zones
    int Index
    int Maximum
    array<Zone> Zones
    Zone Remove
 
CreateUp() =>
    satisfied = true
    for i = 2 to 1
        if _consecutiveRisingIrFalling
            if low[i - 1] < low[i]
                satisfied := false
                break
 
    if _fairValueGap
        if high[2] >= low
            satisfied := false
    satisfied
CreateDown() =>
    satisfied = true
    for i = 3 to 1
        if _consecutiveRisingIrFalling
            if low[i - 1] > low[i]
                satisfied := false
                break
 
    if _fairValueGap
        if low[2] <= high
            satisfied := false
    satisfied
Create() =>
    pivotHigh = ta.pivothigh(_takeOut ? 1 : 0, 2)
    pivotLow = ta.pivotlow(_takeOut ? 1 : 0, 2)
    atr = ta.atr(14)
    reactionLimit = atr * _reactionFactor
    widthUp = high - low[2]
    widthDown = high[2] - low
    zone = Zone.new(time[2], time_close[2], high[2], low[2], reactionLimit, Touched.Zone.new(high[2], low[2], time[2]))
    create = false
    if widthUp >= reactionLimit
        if not na(pivotLow) and barstate.isconfirmed // only create an order block if the HTF bar is closed
            if _type == "Both" or _type == "Bullish"
                if CreateUp()
                    zone.Type := 1
                    create := true
    if widthDown >= reactionLimit
        if not na(pivotHigh) and barstate.isconfirmed // only create an order block if the HTF bar is closed
            if _type == "Both" or _type == "Bearish"
                if CreateDown()
                    zone.Type := -1
                    create := true
    if create
        zone
method Replace(Zones zones, Zone zone) =>
    zones.Remove := zones.Zones.get(zones.Index)
    zones.Zones.set(zones.Index, zone)
    zones.Index := (zones.Index + 1) % _count
    zones
method RemoveVisuals(Zone zone, color newColor) =>
    for [i, b] in zone.Visual.Boxes
        if _history
            if i != 0 // don't change the creation box
                b.set_right(time)
                b.set_extend(extend.none)
                b.set_bgcolor(color.new(newColor, 80))
            else
                b.set_border_color(newColor)
        else
            b.delete()
    for l in zone.Visual.Lines
        if _history
            l.set_color(newColor)
        else
            l.delete()
    for l in zone.Visual.Labels
        l.delete()
    zone.Visual := na
method Remove(Zones zones) =>
    if not na(zones.Remove)
        if not na(zones.Remove.Visual)
            zones.Remove.RemoveVisuals(_colorReplaced)
    zones
method Draw(Zone zone) =>
    reactionLimit = switch zone.Type
        -1 => zone.High - zone.ReactionLimit
        1 => zone.Low + zone.ReactionLimit
    zone.Visual := Visual.new(
      array.from(
          box.new(zone.Time, zone.High, zone.TimeClose, zone.Low, xloc = xloc.bar_time, bgcolor = na, border_color = _color), // the creation zone
          box.new(zone.Time, zone.High, zone.TimeClose, zone.Low, xloc = xloc.bar_time, bgcolor = color.new(_color, 70), border_width = 0, extend = extend.right) // the extended zone
      ),
      array.from(_reactionShow ? line.new(zone.Time, reactionLimit, time, reactionLimit, xloc = xloc.bar_time, color = _color) : line(na)),
      array.new<label>())
    zone
method Interaction(Zone zone, Touched.Touch touch, color c, string lbl) =>
    interacted = false
    if touch.Down
        zone.Visual.Labels.push(label.new(bar_index - touch.ExtremeIndexBack, low[touch.ExtremeIndexBack], lbl, color = c, style = label.style_label_up))
        interacted := true
    if touch.Up
        zone.Visual.Labels.push(label.new(bar_index - touch.ExtremeIndexBack, high[touch.ExtremeIndexBack], lbl, color = c))
        interacted := true
    interacted
method Interactions(Zones zones) =>
    for [i, zone] in zones.Zones
        if na(zone)
            continue
        if na(zone.Visual)
            continue
        zone.Interaction(Touched.Retest(zone.TouchedZone, 30), color.new(color.blue, 30), "R")
        zone.Interaction(Touched.FalseBreakout(zone.TouchedZone, 30), color.new(color.orange, 30), "FB")
        if zone.Interaction(Touched.Breakout(zone.TouchedZone, 50), color.new(color.red, 30), "B") and _removeBroken
            zone.RemoveVisuals(_colorBroken)
 
var zones = Zones.new(0, _count, array.new<Zone>(_count))
zone = request.security(syminfo.tickerid, _timeframe, Create(), lookahead = barmerge.lookahead_off)
if not na(zone) and na(zone[1]) // only draw order block on one bar
    zone.Draw()
    zones.Replace(zone)
      .Remove()
zones.Interactions()

← 返回列表