MTF Order Block Finder

DasanC · study · 182 行 · 点赞 8,669 · TradingView 原页

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

Pine Script

//@version=4
study("MTF Order Block Finder", overlay = true,max_bars_back=100)       
tip1 = "Instituational Order Blocks (OB) often signal the beginning of a strong move. There is a high probability that OB price levels will be revisited in the future. Bullish Order block is the last down candle before a sequence of up candles. Bearish Order Block is the last up candle before a sequence of down candles."
tip2 = "!Experimental!\nFind Order Blocks from different timeframes. Channel prices and positions are accurate, but arrow position is not. Lower timeframes are ignored."
tip3 = "Required number of subsequent candles in the same direction to identify Order Block"
tip4 = "Measured from from potential OB close to close of first candle in sequence"
tip5 = "LIGHT = classic Red + Green scheme\nDARK = clean White + Blue for dark charts"
tip6 = "LINE = 3 lines representing the High, Low, and Average price of the OB\nBOX = a solid bounded area where the Top and Bottom are the High and Low of the OB"
tip7 = "Number of Zones to draw on chart. Higher numbers lead to \"messy\" charts"
//User Inputs
dummy = input(true,"Hover over ( ! ) for documentation", tooltip = tip1)
colors    = input("LIGHT","Color Theme", options=["LIGHT","DARK"],tooltip=tip5)
style = input("BOX","Order Block drawing style",options=["LINE","BOX"],tooltip=tip6)
resolution = input("","Order Block Timeframe",input.resolution,tooltip=tip2)
ob_period = 1 + input(5,"Relevant Periods to identify OB",tooltip=tip3)             // Required number of subsequent candles in the same direction to identify Order Block
threshold = input(0.25,"Min. Percent move for valid OB", step = 0.1, tooltip=tip4)      // Required minimum % move (from potential OB close to last subsequent candle to identify Order Block)
bull_channels = input(2,"Max Bullish Zones to show",tooltip=tip7)                  // Num of channels
bear_channels = input(2,"Max Bearish Zones to show",tooltip=tip7)                   // Num of channels
 
//Convert a given string resolution into seconds
ResolutionToSec(res)=>
    mins = res == "1" ? 1 :
           res == "3" ? 3 :
           res == "5" ? 5 :
           res == "15" ? 15 :
           res == "30" ? 30 :
           res == "45" ? 45 :
           res == "60" ? 60 :
           res == "120" ? 120 :
           res == "180" ? 180 :
           res == "240" ? 240 :
           res == "1D" ? 1440 :
           res == "1W" ? 10080 :
           res == "1M" ? 43200 : 0
    ms = mins * 60
 
//Convert the current chart resolution into seconds
TimeframeToSec()=>
    mins = 0.0
    if(timeframe.isdwm)
        mins := timeframe.isdaily ? 1440 :
                 timeframe.isweekly ? 10080 :
                 timeframe.ismonthly ? 43200 : mins
    if(timeframe.isintraday)
        mins := timeframe.isminutes ? 1 :
                 timeframe.isseconds ? (1/60) : mins
    ms = round(mins * 60 * timeframe.multiplier)
 
//Given a source type, resolution, and warmup period;
//Return 1) an array of prices with gaps removed
//       2) a bool that is True when the given resolution has new data
Rem_Gaps_Security(src,res,warm)=>
    max = security(syminfo.tickerid,res,bar_index,barmerge.gaps_off,barmerge.lookahead_off)
    gap = security(syminfo.tickerid,res,src,barmerge.gaps_on,barmerge.lookahead_off)
    clean = array.new_float()
    if (na(max) or max < warm)
        array.push(clean,na)
        [clean,false]
    else
        for i=0 to warm
            if(not na(gap[i]))
                array.push(clean,gap[i])
        [clean,not na(gap)]
 
//Initialization
bullcolor = colors == "DARK"? color.white : color.green
bearcolor = colors == "DARK"? color.blue : color.red
OB_bull = false
OB_bull_chigh = float(na)
OB_bull_clow  = float(na)
OB_bull_avg  = float(na)
OB_bear = false
OB_bear_chigh = float(na)
OB_bear_clow = float(na)
OB_bear_avg = float(na)
    //MTF Sync vars
var sync = 0
res = TimeframeToSec() > ResolutionToSec(resolution) ? "" : resolution
warmup = ob_period + 1
mtf_warmup = res == "" ? warmup : warmup * ResolutionToSec(res)/TimeframeToSec()
    //Data Curation
[copen,naopen] = Rem_Gaps_Security(open,res,mtf_warmup)
[chigh,nahigh] = Rem_Gaps_Security(high,res,mtf_warmup)
[clow,nalow] = Rem_Gaps_Security(low,res,mtf_warmup)
[cclose,naclose] = Rem_Gaps_Security(close,res,mtf_warmup)
    //Array with least data
MinArraySize = min(array.size(copen),
                   array.size(chigh),
                   array.size(clow),
                   array.size(cclose))
 
if(MinArraySize > warmup)
    //Validity of most recent candle
    relmove   = 100*((abs(array.get(cclose,ob_period) - array.get(cclose,1)))/array.get(cclose,ob_period))>=threshold    
    // Bullish Order Block Identification
    bullishOB = array.get(cclose,ob_period) < array.get(copen,ob_period)            // Determine potential Bullish OB candle (red candle)
    
    int upcandles  = 0
    for i = 1 to ob_period-1
        upcandles := upcandles + (array.get(cclose,i) > array.get(copen,i)? 1 : 0)  // Determine color of subsequent candles (must all be green to identify a valid Bearish OB)
    if(naopen and naclose)
        OB_bull      := bullishOB and (upcandles == (ob_period-1)) and relmove           // Identification logic (red OB candle & subsequent green candles)
        OB_bull_chigh := OB_bull? array.get(chigh,ob_period) : na                        // Determine OB upper limit (Open or High depending on input)
        OB_bull_clow  := OB_bull? array.get(clow,ob_period)  : na                        // Determine OB clower limit (Low)
        OB_bull_avg  := (OB_bull_chigh + OB_bull_clow)/2                                 // Determine OB middle line
    
    // Bearish Order Block Identification
    bearishOB = array.get(cclose,ob_period) > array.get(copen,ob_period)            // Determine potential Bearish OB candle (green candle)
    
    int downcandles  = 0
    for i = 1 to ob_period-1
        downcandles := downcandles + (array.get(cclose,i) < array.get(copen,i)? 1 : 0)                // Determine color of subsequent candles (must all be red to identify a valid Bearish OB)
    if(naopen and naclose)
        OB_bear      := bearishOB and (downcandles == (ob_period-1)) and relmove             // Identification logic (green OB candle & subsequent green candles)
        OB_bear_chigh := OB_bear? array.get(chigh,ob_period) : na                        // Determine OB upper limit (High)
        OB_bear_clow  := OB_bear? array.get(clow,ob_period) : na                         // Determine OB clower limit (Open or Low depending on input)
        OB_bear_avg  := (OB_bear_clow + OB_bear_chigh)/2                                 // Determine OB middle line
    
    sync := time_close(res) 
    if(style=="LINE")
        //Init Line Arrays
        var LineBullAvg = array.new_line()
        var LineBullHigh = array.new_line()
        var LineBullLow = array.new_line()
        var LineBearAvg = array.new_line()
        var LineBearHigh = array.new_line()
        var LineBearLow = array.new_line()
        //Bullish Channel Creation
        if(OB_bull and bull_channels>0)
            if array.size(LineBullAvg) == bull_channels
                line.delete(array.get(LineBullAvg,0))
                array.remove(LineBullAvg,0)
                line.delete(array.get(LineBullHigh,0))
                array.remove(LineBullHigh,0)
                line.delete(array.get(LineBullLow,0))
                array.remove(LineBullLow,0)
            array.push(LineBullAvg,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bull_avg, x2 = time[1], y2 = OB_bull_avg, extend = extend.left, color = bullcolor, style = line.style_solid, width = 1))
            array.push(LineBullHigh,line.new(x1 = sync, xloc=xloc.bar_time,y1 = OB_bull_chigh, x2 = time[1], y2 = OB_bull_chigh, extend = extend.left, color = color.new(bullcolor,50), style = line.style_dashed, width = 1))
            array.push(LineBullLow,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bull_clow, x2 = time[1], y2 = OB_bull_clow, extend = extend.left, color = color.new(bullcolor,50), style = line.style_dashed, width = 1))
        //Bearish Channel Creation
        if(OB_bear and bear_channels>0)
            if array.size(LineBearAvg) == bear_channels
                line.delete(array.get(LineBearAvg,0))
                array.remove(LineBearAvg,0)
                line.delete(array.get(LineBearHigh,0))
                array.remove(LineBearHigh,0)
                line.delete(array.get(LineBearLow,0))
                array.remove(LineBearLow,0)
            array.push(LineBearAvg,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bear_avg, x2 = time[1], y2 = OB_bear_avg, extend = extend.left, color = bearcolor, style = line.style_solid, width = 1))
            array.push(LineBearHigh,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bear_chigh, x2 = time[1], y2 = OB_bear_chigh, extend = extend.left, color = color.new(bearcolor,50), style = line.style_dashed, width = 1))
            array.push(LineBearLow,line.new(x1 = sync, xloc=xloc.bar_time, y1 = OB_bear_clow, x2 = time[1], y2 = OB_bear_clow, extend = extend.left, color = color.new(bearcolor,50), style = line.style_dashed, width = 1))
        
    if(style=="BOX")
        //Init Line Arrays
        var BoxBull = array.new_box()
        var BoxBear = array.new_box()
        //Bullish Channel Creation
        if(OB_bull and bull_channels>0)
            if array.size(BoxBull) == bull_channels
                box.delete(array.get(BoxBull,0))
                array.remove(BoxBull,0)
            array.push(BoxBull,box.new(xloc=xloc.bar_time, left = sync, top = OB_bull_chigh, right = sync, bottom = OB_bull_clow, extend = extend.right, border_width=0, bgcolor = color.new(bullcolor,60)))
        //Bearish Channel Creation
        if(OB_bear and bear_channels>0)
            if array.size(BoxBear) == bear_channels
                box.delete(array.get(BoxBear,0))
                array.remove(BoxBear,0)
            array.push(BoxBear,box.new(xloc=xloc.bar_time, left = sync, top = OB_bear_chigh, right = sync, bottom = OB_bear_clow, extend = extend.right, border_width=0, bgcolor = color.new(bearcolor,60)))
            
os = res=="" ? -ob_period : -ob_period * ResolutionToSec(res)/TimeframeToSec()
// Signal Plotting
plotshape(OB_bull, title="Bullish OB", style = shape.triangleup,   color = bullcolor, textcolor = bullcolor, size = size.tiny, location = location.belowbar, offset = os, text = "Bull")     // Bullish OB Indicator
bull1 = plot(OB_bull_chigh, title="Bullish OB High", style = plot.style_linebr, color = bullcolor, offset = os, linewidth = 2)                                              // Bullish OB Upper Limit
bull2 = plot(OB_bull_clow,  title="Bullish OB Low",  style = plot.style_linebr, color = bullcolor, offset = os, linewidth = 2)                                              // Bullish OB Lower Limit
fill(bull1, bull2, color=color.new(bullcolor,50), title = "Bullish OB fill")                                                                                                        // Fill Bullish OB
plotshape(OB_bull_avg, title="Bullish OB Average", style = shape.cross,   color = bullcolor, size = size.small, location = location.absolute, offset = os)                  // Bullish OB Average
 
plotshape(OB_bear, title="Bearish OB", style = shape.triangledown, color = bearcolor, textcolor = bearcolor,  size = size.tiny, location = location.abovebar, offset = os, text = "Bear")     // Bearish OB Indicator
bear1 = plot(OB_bear_clow,  title="Bearish OB Low",  style = plot.style_linebr, color = bearcolor, offset = os, linewidth = 2)                                              // Bearish OB Lower Limit
bear2 = plot(OB_bear_chigh, title="Bearish OB High", style = plot.style_linebr, color = bearcolor, offset = os, linewidth = 2)                                              // Bearish OB Upper Limit
fill(bear1, bear2, color=color.new(bearcolor,50), title = "Bearish OB fill")                                                                                                        // Fill Bearish OB
plotshape(OB_bear_avg, title="Bearish OB Average", style = shape.cross,   color = bearcolor, size = size.small, location = location.absolute, offset = os)                  // Bullish OB Average

← 返回列表