
Chiến lược này tìm kiếm các phân khúc giá có động lực đột phá bằng cách xác định các khối lệnh trong giá và tham gia thị trường khi có tín hiệu mua và bán. Các khối lệnh đánh dấu các khu vực mà các tổ chức tham gia, thể hiện sức mạnh lớn hơn của thị trường. Do đó, khi tín hiệu khối lệnh xuất hiện, có xác suất cao hơn cho sự thay đổi giá theo xu hướng.
Các khối đặt hàng được chia thành các khối đặt hàng đa đầu và khối đặt hàng trống. Các khối đặt hàng đa đầu được định nghĩa là một dòng K xuống (đường K màu đỏ) và sau đó là một dòng K lên (đường K màu xanh lá cây). Các khối đặt hàng trống được định nghĩa là một dòng K lên (đường K màu xanh lá cây) và sau đó là một dòng K xuống (đường K màu đỏ).
Để xác định khối đơn đặt hàng, một số điều kiện sau cùng cần phải được đáp ứng:
Màu sắc của dòng K thay đổi: Từ một dòng K trước đến dòng K hiện tại, màu sắc của dòng K đã chuyển đổi (ví dụ từ đỏ sang xanh, hoặc từ xanh sang đỏ). Điều này cho thấy xu hướng có thể có trước khi cơ quan kết thúc, chuẩn bị để bắt đầu xu hướng mới.
Đường K tiếp theo có màu đồng nhất: Sau khi đạt đến số gốc được chỉ định của tham số period, các đường K tiếp theo giữ cùng một hướng màu ((ví dụ: phía sau khối đặt hàng nhiều đầu là tất cả các đường K màu xanh lá cây). Điều này cho thấy xu hướng mới được tăng cường và xác nhận.
Bước giảm vượt ngưỡng: Bước giảm từ giá mở của khối lệnh đến giá đóng K-line tiếp theo vượt ngưỡng của tham số được thiết lập ((thiết lập là 0). Điều này đảm bảo rằng xu hướng mới có đủ sức mạnh và ảnh hưởng.
Một tín hiệu khối đơn đặt hàng có thể được xác định khi đáp ứng cả ba điều kiện trên cùng lúc.
Khi nhận ra khối đặt hàng nhiều đầu, tạo ra tín hiệu mua; khi nhận ra khối đặt hàng trống, tạo ra tín hiệu bán.
Với sự không chắc chắn của tín hiệu khối lệnh và khả năng kiểm tra lại, chiến lược này không đi vào thị trường trực tiếp khi tín hiệu khối lệnh xuất hiện, mà thông qua các đường vẽ, cảnh báo và các phương thức khác để nhắc nhở các nhà giao dịch. Các nhà giao dịch có thể chọn triển khai giá giới hạn thích hợp gần khu vực giá khối lệnh và chờ đợi giá kích hoạt để đi vào xu hướng.
Các khối đơn đặt hàng đánh dấu sự tham gia của các tổ chức tài chính và khối lượng giao dịch lớn, đại diện cho sự chuyển đổi của sức mạnh thị trường. Do đó, tín hiệu khối đơn đặt hàng có một số khả năng dự đoán và chính xác, có thể bắt đầu hướng đột phá tiềm năng. Điều này cung cấp vị trí thuận lợi và thời gian nắm bắt xu hướng.
Các tham số của chiến lược bao gồm số lượng đường K lịch sử, cường độ động lực đột phá, v.v. có thể được điều chỉnh thông qua các tham số để tối ưu hóa cho các môi trường thị trường khác nhau và phong cách thương nhân, nâng cao khả năng thích ứng của chiến lược.
Chiến lược này không thực sự đi vào thị trường khi tín hiệu khối lệnh xuất hiện, mà là thiết lập báo động và xây dựng vị trí bằng cách đặt lệnh giới hạn ngoài sân. Cách này cho phép các nhà giao dịch kiểm soát điểm vào và rủi ro cụ thể. Ngay cả khi tín hiệu khối lệnh bị đánh giá sai, nó chỉ dẫn đến việc lệnh giới hạn sẽ không được kích hoạt, rủi ro có thể được kiểm soát.
Vì khối lệnh được đánh dấu là một khoảng, có nhiều khả năng giá tiếp theo sẽ quay trở lại trong khoảng đó. Do đó, tín hiệu khối lệnh không được coi là tín hiệu nhập cảnh tiêu chuẩn, mà là thông tin cảnh báo, cần thương nhân tự đánh giá thêm về thời gian nhập cảnh.
Cài đặt tham số của khối lệnh ((số dòng K lịch sử, giá trị giảm tần số, v.v.) Nếu không đúng, nó có thể dễ dàng tạo ra tín hiệu giả trong khoảng Sideways bình thường. Điều này đòi hỏi các nhà giao dịch có một sự nhạy cảm và phán đoán đối với thị trường, tránh tối ưu hóa tham số một cách mù quáng.
Vì tín hiệu khối đơn đặt hàng không phải là 100% đáng tin cậy, người giao dịch cần phân tích thêm khi nhận tín hiệu để đánh giá độ tin cậy của tín hiệu hiện tại, điều này làm tăng một số công việc nhân sự. Phán quyết khác nhau về chất lượng tín hiệu cũng có thể dẫn đến sự khác biệt trong hiệu suất giao dịch.
Có thể kết hợp với các chỉ số khác để đánh giá hướng và cường độ của xu hướng khi có tín hiệu khối đặt hàng, ví dụ kết hợp với MACD, RSI, v.v., lọc các tín hiệu sai do cài đặt tham số, nâng cao độ chính xác của tín hiệu.
Các tham số có thể được thử nghiệm và tối ưu hóa cho các thị trường khác nhau và các loại giao dịch khác nhau để phù hợp hơn với môi trường thị trường hiện tại. Các tham số cũng có thể được thiết lập để tự điều chỉnh theo biến động thị trường và sở thích rủi ro.
Hiện tại, chiến lược chỉ là một công cụ gợi ý tín hiệu, người giao dịch cần tự quyết định thời gian vào. Chúng tôi có thể phát triển cơ chế đặt hàng tự động cho các khối giá của đơn đặt hàng, tự động vào khi đáp ứng các điều kiện nhất định; và kết hợp các phương pháp như dừng lỗ để thiết lập logic thoát ra, giảm yêu cầu phán đoán nhân tạo, nâng cao mức độ tự động hóa chiến lược.
Chiến lược này cung cấp vị trí và thời gian thuận lợi cho việc phá vỡ giá theo xu hướng bằng cách xác định hiệu quả các phân đoạn giá trong các tập trung lưu lượng lệnh, khai thác thông tin động lực ẩn trong thị trường. Chiến lược khối đặt hàng có khả năng nhận diện đầu và chủ động hơn so với các phương pháp theo dõi xu hướng đơn giản.
/*backtest
start: 2024-01-01 00:00:00
end: 2024-01-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © TradingSecrets and wugamlo
// This experimental Indicator helps identifying instituational Order Blocks.
// Often these blocks signal the beginning of a strong move, but there is a significant probability that these price levels will be revisited at a later point in time again.
// Therefore these are interesting levels to place limit orders (Buy Orders for Bullish OB / Sell Orders for Bearish OB).
//
// A Bullish Order block is defined as the last down candle before a sequence of up candles. (Relevant price range "Open" to "Low" is marked) / Optionally full range "High" to "Low"
// A Bearish Order Block is defined as the last up candle before a sequence of down candles. (Relevant price range "Open" to "High" is marked) / Optionally full range "High" to "Low"
//
// In the settings the number of required sequential candles can be adjusted.
// Furthermore a %-threshold can be entered. It defines which %-change the sequential move needs to achieve in order to identify a relevant Order Block.
// Channels for the last Bullish/Bearish Block can be shown/hidden.
//
// In addition to the upper/lower limits of each Order Block, also the equlibrium (average value) is marked as this is an interesting area for price interaction.
//
// Alerts added: Alerts fire when an Order Block is detected. The delay is based on the "Relevant Periods" input. Means with the default setting "5" the alert will trigger after the
// number of consecutive candles is reached.
//@version=4
strategy("[Backtest] Order Block Finder", overlay = true)
colors = input(title = "Color Scheme", defval="DARK", options=["DARK", "BRIGHT"])
periods = input(5, "Relevant Periods to identify OB") // Required number of subsequent candles in the same direction to identify Order Block
threshold = input(0.0, "Min. Percent move to identify OB", step = 0.1) // Required minimum % move (from potential OB close to last subsequent candle to identify Order Block)
usewicks = input(false, "Use whole range [High/Low] for OB marking?" ) // Display High/Low range for each OB instead of Open/Low for Bullish / Open/High for Bearish
showbull = input(false, "Show latest Bullish Channel?") // Show Channel for latest Bullish OB?
showbear = input(false, "Show latest Bearish Channel?") // Show Channel for latest Bearish OB?
showdocu = input(false, "Show Label for documentation tooltip?") // Show Label which shows documentation as tooltip?
info_pan = input(false, "Show Latest OB Panel?") // Show Info Panel with latest OB Stats
//strategy inputs
plot_offset = input( type=input.bool,defval = false, title = 'Plot Offset?')
stoploss_percent = input(type=input.float, defval = 1, title = 'Stop Loss [%]')
takeprofit_percent = input(type=input.float, defval = 2, title = 'Take Profit [%]')
pyramiding = input( type=input.bool,defval = true, title = 'Pyramiding')
ob_period = periods + 1 // Identify location of relevant Order Block candle
absmove = ((abs(close[ob_period] - close[1]))/close[ob_period]) * 100 // Calculate absolute percent move from potential OB to last candle of subsequent candles
relmove = absmove >= threshold // Identify "Relevant move" by comparing the absolute move to the threshold
// Color Scheme
bullcolor = colors == "DARK"? color.white : color.green
bearcolor = colors == "DARK"? color.blue : color.red
// Bullish Order Block Identification
bullishOB = close[ob_period] < open[ob_period] // Determine potential Bullish OB candle (red candle)
int upcandles = 0
for i = 1 to periods
upcandles := upcandles + (close[i] > open[i]? 1 : 0) // Determine color of subsequent candles (must all be green to identify a valid Bearish OB)
OB_bull = bullishOB and (upcandles == (periods)) and relmove // Identification logic (red OB candle & subsequent green candles)
OB_bull_high = OB_bull? usewicks? high[ob_period] : open[ob_period] : na // Determine OB upper limit (Open or High depending on input)
OB_bull_low = OB_bull? low[ob_period] : na // Determine OB lower limit (Low)
OB_bull_avg = (OB_bull_high + OB_bull_low)/2 // Determine OB middle line
// Bearish Order Block Identification
bearishOB = close[ob_period] > open[ob_period] // Determine potential Bearish OB candle (green candle)
int downcandles = 0
for i = 1 to periods
downcandles := downcandles + (close[i] < open[i]? 1 : 0) // Determine color of subsequent candles (must all be red to identify a valid Bearish OB)
OB_bear = bearishOB and (downcandles == (periods)) and relmove // Identification logic (green OB candle & subsequent green candles)
OB_bear_high = OB_bear? high[ob_period] : na // Determine OB upper limit (High)
OB_bear_low = OB_bear? usewicks? low[ob_period] : open[ob_period] : na // Determine OB lower limit (Open or Low depending on input)
OB_bear_avg = (OB_bear_low + OB_bear_high)/2 // Determine OB middle line
//@TradingSecrets: Option to disable the offset in order to allign signals with Backtest
if not plot_offset
ob_period := 0
// Plotting
plotshape(OB_bull, title="Bullish OB", style = shape.triangleup, color = bullcolor, textcolor = bullcolor, size = size.tiny, location = location.belowbar, offset = -ob_period, text = "Bullish OB") // Bullish OB Indicator
bull1 = plot(OB_bull_high, title="Bullish OB High", style = plot.style_linebr, color = bullcolor, offset = -ob_period, linewidth = 3) // Bullish OB Upper Limit
bull2 = plot(OB_bull_low, title="Bullish OB Low", style = plot.style_linebr, color = bullcolor, offset = -ob_period, linewidth = 3) // Bullish OB Lower Limit
fill(bull1, bull2, color=bullcolor, transp = 0, title = "Bullish OB fill") // Fill Bullish OB
plotshape(OB_bull_avg, title="Bullish OB Average", style = shape.cross, color = bullcolor, size = size.normal, location = location.absolute, offset = -ob_period) // Bullish OB Average
plotshape(OB_bear, title="Bearish OB", style = shape.triangledown, color = bearcolor, textcolor = bearcolor, size = size.tiny, location = location.abovebar, offset = -ob_period, text = "Bearish OB") // Bearish OB Indicator
bear1 = plot(OB_bear_low, title="Bearish OB Low", style = plot.style_linebr, color = bearcolor, offset = -ob_period, linewidth = 3) // Bearish OB Lower Limit
bear2 = plot(OB_bear_high, title="Bearish OB High", style = plot.style_linebr, color = bearcolor, offset = -ob_period, linewidth = 3) // Bearish OB Upper Limit
fill(bear1, bear2, color=bearcolor, transp = 0, title = "Bearish OB fill") // Fill Bearish OB
plotshape(OB_bear_avg, title="Bearish OB Average", style = shape.cross, color = bearcolor, size = size.normal, location = location.absolute, offset = -ob_period) // Bullish OB Average
var line linebull1 = na // Bullish OB average
var line linebull2 = na // Bullish OB open
var line linebull3 = na // Bullish OB low
var line linebear1 = na // Bearish OB average
var line linebear2 = na // Bearish OB high
var line linebear3 = na // Bearish OB open
if OB_bull and showbull
line.delete(linebull1)
linebull1 := line.new(x1 = bar_index, y1 = OB_bull_avg, x2 = bar_index - 1, y2 = OB_bull_avg, extend = extend.left, color = bullcolor, style = line.style_solid, width = 1)
line.delete(linebull2)
linebull2 := line.new(x1 = bar_index, y1 = OB_bull_high, x2 = bar_index - 1, y2 = OB_bull_high, extend = extend.left, color = bullcolor, style = line.style_dashed, width = 1)
line.delete(linebull3)
linebull3 := line.new(x1 = bar_index, y1 = OB_bull_low, x2 = bar_index - 1, y2 = OB_bull_low, extend = extend.left, color = bullcolor, style = line.style_dashed, width = 1)
if OB_bear and showbear
line.delete(linebear1)
linebear1 := line.new(x1 = bar_index, y1 = OB_bear_avg, x2 = bar_index - 1, y2 = OB_bear_avg, extend = extend.left, color = bearcolor, style = line.style_solid, width = 1)
line.delete(linebear2)
linebear2 := line.new(x1 = bar_index, y1 = OB_bear_high, x2 = bar_index - 1, y2 = OB_bear_high, extend = extend.left, color = bearcolor, style = line.style_dashed, width = 1)
line.delete(linebear3)
linebear3 := line.new(x1 = bar_index, y1 = OB_bear_low, x2 = bar_index - 1, y2 = OB_bear_low, extend = extend.left, color = bearcolor, style = line.style_dashed, width = 1)
// Alerts for Order Blocks Detection
alertcondition(OB_bull, title='New Bullish OB detected', message='New Bullish OB detected - This is NOT a BUY signal!')
alertcondition(OB_bear, title='New Bearish OB detected', message='New Bearish OB detected - This is NOT a SELL signal!')
// Print latest Order Blocks in Data Window
var latest_bull_high = 0.0 // Variable to keep latest Bull OB high
var latest_bull_avg = 0.0 // Variable to keep latest Bull OB average
var latest_bull_low = 0.0 // Variable to keep latest Bull OB low
var latest_bear_high = 0.0 // Variable to keep latest Bear OB high
var latest_bear_avg = 0.0 // Variable to keep latest Bear OB average
var latest_bear_low = 0.0 // Variable to keep latest Bear OB low
// Assign latest values to variables
if OB_bull_high > 0
latest_bull_high := OB_bull_high
if OB_bull_avg > 0
latest_bull_avg := OB_bull_avg
if OB_bull_low > 0
latest_bull_low := OB_bull_low
if OB_bear_high > 0
latest_bear_high := OB_bear_high
if OB_bear_avg > 0
latest_bear_avg := OB_bear_avg
if OB_bear_low > 0
latest_bear_low := OB_bear_low
// Plot invisible characters to be able to show the values in the Data Window
plotchar(latest_bull_high, char = ' ', location = location.abovebar, color = #777777, transp = 100, size = size.tiny, title = "Latest Bull High")
plotchar(latest_bull_avg, char = ' ', location = location.abovebar, color = #777777, transp = 100, size = size.tiny, title = "Latest Bull Avg")
plotchar(latest_bull_low, char = ' ', location = location.abovebar, color = #777777, transp = 100, size = size.tiny, title = "Latest Bull Low")
plotchar(latest_bear_high, char = ' ', location = location.abovebar, color = #777777, transp = 100, size = size.tiny, title = "Latest Bear High")
plotchar(latest_bear_avg, char = ' ', location = location.abovebar, color = #777777, transp = 100, size = size.tiny, title = "Latest Bear Avg")
plotchar(latest_bear_low, char = ' ', location = location.abovebar, color = #777777, transp = 100, size = size.tiny, title = "Latest Bear Low")
//InfoPanel for latest Order Blocks
draw_InfoPanel(_text, _x, _y, font_size)=>
var label la_panel = na
label.delete(la_panel)
la_panel := label.new(
x=_x, y=_y,
text=_text, xloc=xloc.bar_time, yloc=yloc.price,
color=color.new(#383838, 5), style=label.style_label_left, textcolor=color.white, size=font_size)
info_panel_x = time_close + round(change(time) * 100)
info_panel_y = close
title = "LATEST ORDER BLOCKS"
row0 = "-----------------------------------------------------"
row1 = ' Bullish - High: ' + tostring(latest_bull_high, '#.##')
row2 = ' Bullish - Avg: ' + tostring(latest_bull_avg, '#.##')
row3 = ' Bullish - Low: ' + tostring(latest_bull_low, '#.##')
row4 = "-----------------------------------------------------"
row5 = ' Bearish - High: ' + tostring(latest_bear_high, '#.##')
row6 = ' Bearish - Avg: ' + tostring(latest_bear_avg, '#.##')
row7 = ' Bearish - Low: ' + tostring(latest_bear_low, '#.##')
panel_text = '\n' + title + '\n' + row0 + '\n' + row1 + '\n' + row2 + '\n' + row3 + '\n' + row4 + '\n\n' + row5 + '\n' + row6 + '\n' + row7 + '\n'
if info_pan
draw_InfoPanel(panel_text, info_panel_x, info_panel_y, size.normal)
// === Label for Documentation/Tooltip ===
chper = time - time[1]
chper := change(chper) > 0 ? chper[1] : chper
// === Tooltip text ===
var vartooltip = "Indicator to help identifying instituational Order Blocks. Often these blocks signal the beginning of a strong move, but there is a high probability, that these prices will be revisited at a later point in time again and therefore are interesting levels to place limit orders. \nBullish Order block is the last down candle before a sequence of up candles. \nBearish Order Block is the last up candle before a sequence of down candles. \nIn the settings the number of required sequential candles can be adjusted. \nFurthermore a %-threshold can be entered which the sequential move needs to achieve in order to validate a relevant Order Block. \nChannels for the last Bullish/Bearish Block can be shown/hidden."
// === Print Label ===
var label l_docu = na
label.delete(l_docu)
if showdocu
l_docu := label.new(x = time + chper * 35, y = close, text = "DOCU OB", color=color.gray, textcolor=color.white, style=label.style_label_center, xloc = xloc.bar_time, yloc=yloc.price, size=size.tiny, textalign = text.align_left, tooltip = vartooltip)
// @TradingSecrets: Generate entry and exit orders based on the signals
entryLongSignal = OB_bull
entryShortSignal = OB_bear
if not pyramiding
entryLongSignal := entryLongSignal and not strategy.position_size
entryShortSignal := entryShortSignal and not strategy.position_size
if entryLongSignal
strategy.entry("Long Entry", strategy.long)
//strategy.exit("Long Exit Loss", "Long Entry", stop = close * (1 - stoploss_percent*0.01))
if entryShortSignal
strategy.entry("Short Entry", strategy.short)
//strategy.exit("Short Exit Loss", "Short Entry", stop = close * (1 + stoploss_percent*0.01))
strategy.initial_capital = 50000
//Close Position by market order
if strategy.position_size > 0 and strategy.openprofit/nz(strategy.initial_capital + strategy.netprofit) >= takeprofit_percent*0.01
//If I m in a long position and my take profit got hit close it by market order
strategy.close("Long Entry", comment = "Long Exit Profit")
if strategy.position_size < 0 and strategy.openprofit/nz(strategy.initial_capital + strategy.netprofit) >= takeprofit_percent*0.01
strategy.close("Short Entry", comment = "Short Exit Profit")
if strategy.position_size > 0 and strategy.openprofit/nz(strategy.initial_capital + strategy.netprofit) <= -stoploss_percent*0.01
//If I m in a long position and my take profit got hit close it by market order
strategy.close("Long Entry", comment = "Long Exit Loss")
if strategy.position_size < 0 and strategy.openprofit/nz(strategy.initial_capital + strategy.netprofit) <= -stoploss_percent*0.01
strategy.close("Short Entry", comment = "Short Exit Loss")