
Đây là một chiến lược giao dịch định lượng hiệu quả dựa trên phạm vi giá và phá vỡ. Chiến lược này chủ yếu bằng cách xác định các khu vực thu hẹp trong thị trường và giao dịch khi giá vượt qua các khu vực này. Chiến lược sử dụng chỉ số ZigZag để xác định các điểm giá quan trọng, kết hợp các điểm cao và thấp để xác định khu vực thu hẹp và phát tín hiệu giao dịch khi giá vượt qua các khu vực này.
Lập luận cốt lõi của chiến lược bao gồm các bước quan trọng sau:
Đây là một chiến lược giao dịch định lượng được thiết kế hợp lý, logic rõ ràng. Nó cung cấp cho các nhà giao dịch một hệ thống giao dịch đáng tin cậy bằng cách nhận diện và thu thập các tín hiệu đột phá trong khoảng cân bằng. Hiệu quả trực quan của chiến lược và tính linh hoạt của tham số làm cho nó có tính thực tế tốt.
/*backtest
start: 2024-09-01 00:00:00
end: 2025-02-18 08:00:00
period: 5d
basePeriod: 5d
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
// This code is released under the Mozilla Public License 2.0
// More details at: https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
//@version=5
strategy("Consolidation Zones - Live [Strategy]", overlay=true, max_bars_back=1100)
//-----------------------------------------------------------------------//
// Input Variables
//-----------------------------------------------------------------------//
prd = input.int(defval=10, title="Loopback Period", minval=2, maxval=50)
conslen = input.int(defval=5, title="Min. Consolidation Length", minval=2, maxval=20)
paintcons = input.bool(defval=true, title="Color Consolidation Zone?")
zonecol = input.color(defval=color.new(color.blue, 70), title="Zone Color")
//-----------------------------------------------------------------------//
// Variables and Calculations for ZZ (ZigZag) Detection
//-----------------------------------------------------------------------//
// Check if the bar has the highest High or lowest Low in the last prd bars
float hb_ = ta.highestbars(prd) == 0 ? high : na
float lb_ = ta.lowestbars(prd) == 0 ? low : na
// Convert to bool to check if hb_ and lb_ are valid (not na)
bool hasHb = not na(hb_)
bool hasLb = not na(lb_)
// Direction variable to determine the trend, based on the last high or low pivot
var int dir = 0
// ZigZag value and last pivot
float zz = na
float pp = na
// 1) Determine direction based on whether a high or low pivot occurred
dir := if hasHb and not hasLb
1
else if hasLb and not hasHb
-1
else
dir // unchanged direction
// 2) If both a high and low pivot occurred in the same bar
bool sameBar = hasHb and hasLb
if sameBar
if dir == 1
zz := hb_
else
zz := lb_
else
zz := hasHb ? hb_ : (hasLb ? lb_ : na)
// 3) Storing last pivots (pp) - iterate over older bars
for x = 0 to 1000
if na(close) or dir != dir[x]
break
if not na(zz[x]) // if zz[x] is a valid value
if na(pp)
pp := zz[x]
else
if dir[x] == 1 and zz[x] > pp
pp := zz[x]
if dir[x] == -1 and zz[x] < pp
pp := zz[x]
//-----------------------------------------------------------------------//
// Logic for Consolidation Zone Detection
//-----------------------------------------------------------------------//
var int conscnt = 0
var float condhigh = na
var float condlow = na
float H_ = ta.highest(conslen)
float L_ = ta.lowest(conslen)
var line upline = na
var line dnline = na
bool breakoutup = false
bool breakoutdown = false
// Check if pp has changed
bool changedPP = ta.change(pp) != 0
if changedPP
// If enough candles are in consolidation, check for breakout
if conscnt > conslen and not na(condhigh) and not na(condlow) and not na(pp)
if pp > condhigh
breakoutup := true
if pp < condlow
breakoutdown := true
// Check if we are still "in the zone"
bool inZone = conscnt > 0 and not na(pp) and not na(condhigh) and not na(condlow) and (pp <= condhigh) and (pp >= condlow)
if inZone
conscnt += 1
else
conscnt := 0
else
// No change in pivot -> continue consolidation
conscnt += 1
if conscnt >= conslen
// At the first "touch" of the required number of candles
if conscnt == conslen
condhigh := H_
condlow := L_
else
condhigh := math.max(condhigh, high)
condlow := math.min(condlow, low)
//-----------------------------------------------------------------------//
// Drawing Fill
//-----------------------------------------------------------------------//
// Declare two plot variables (just ordinary assignment)
condHighPlot = plot(condhigh, color=na, style=plot.style_stepline)
condLowPlot = plot(condlow, color=na, style=plot.style_stepline)
// bool to check if we want to color the zone
bool doFill = paintcons and (conscnt > conslen)
// Calling fill
fill(condHighPlot, condLowPlot, color= doFill ? zonecol : color.new(color.white, 100))
//-----------------------------------------------------------------------//
// Alerts & STRATEGY
//-----------------------------------------------------------------------//
alertcondition(breakoutup, title="Breakout Up", message="Breakout Up")
alertcondition(breakoutdown, title="Breakout Down", message="Breakout Down")
if breakoutup
// Close short first
if strategy.position_size < 0
strategy.close("Breakout Short")
// Open LONG
strategy.entry("Breakout Long", strategy.long)
if breakoutdown
// Close long first
if strategy.position_size > 0
strategy.close("Breakout Long")
// Open SHORT
strategy.entry("Breakout Short", strategy.short)