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