Chiến lược giao dịch theo phần trăm dải Bollinger


Ngày tạo: 2023-12-11 11:14:53 sửa đổi lần cuối: 2023-12-11 11:14:53
sao chép: 0 Số nhấp chuột: 750
1
tập trung vào
1621
Người theo dõi

Chiến lược giao dịch theo phần trăm dải Bollinger

Tổng quan

Chiến lược này dựa trên chỉ số Brin Belt, kết hợp với các chỉ số kỹ thuật di động và ATR, để thực hiện một hệ thống đột phá ngắn. Chiến lược này tính toán tỷ lệ phần trăm vị trí tương đối của giá trong kênh Brin Belt để xác định tình trạng giá quá mua quá bán, kết hợp với đột phá điểm cao thấp mới để tạo ra tín hiệu giao dịch.

Nguyên tắc chiến lược

  1. Tính toán đường dẫn và tỷ lệ phần trăm của giá trong đường dẫn
  2. Đường trung bình di chuyển được tính cho giá mở, giá đóng, giá cao nhất và giá thấp nhất.
  3. Tính toán chỉ số ATR và thiết lập đường dừng cùng với ATR
  4. Xác định giá gần mức cao mới hay thấp mới
  5. Xác định mức giá lớn kết hợp với mức giá cao nhất và thấp nhất hàng năm
  6. Đánh giá liệu có tín hiệu giao dịch thông qua sự thay đổi tỷ lệ phần trăm và mức cao mới

Chiến lược này sử dụng đường băng Brin để xác định tỷ lệ biến động của thị trường, và chiều rộng của đường băng Brin được xác định bằng chênh lệch tiêu chuẩn. Giá là điểm mua khi nó phá vỡ đường băng Brin xuống và giá là điểm bán khi nó phá vỡ đường băng Brin lên.

Lợi thế chiến lược

  1. Phân tích nghiêm ngặt Brin Belt có thể làm giảm tín hiệu giả
  2. Đường trung bình di chuyển làm phẳng giá, nhận ra xu hướng thực sự
  3. Động thái theo dõi ATR dừng lỗ, có thể hạn chế tổn thất đơn lẻ
  4. Đánh giá cao mới, thấp mới và cao thấp hàng năm giúp tín hiệu đáng tin cậy hơn
  5. Kết hợp nhiều chỉ số kỹ thuật để tăng hiệu quả chiến lược

Rủi ro chiến lược và giải pháp

  1. Thiết lập không đúng các tham số đường băng thông Brin có thể dẫn đến quá nhiều đột phá giả, nên thử nghiệm các kết hợp tham số khác nhau để có hiệu quả tốt nhất
  2. Giá đóng cửa có thể trở lại vượt quá mức dừng mà ATR đặt ra để lấy làm đường viền, có thể xem xét tính toán tỷ lệ phần trăm giá cao nhất và thấp nhất bằng cách sử dụng dải sóng lớn hơn
  3. Brin nghiêm ngặt có thể bỏ lỡ các cơ hội xu hướng trên đường dài hơn, thích hợp để nới lỏng các điều kiện lọc và thời gian nắm giữ
  4. Chỉ số ATR chậm hơn theo dõi biến động giá lớn, nên xem xét các chỉ số tỷ lệ dao động tần số cao hơn như real amplitude
  5. Các đợt đột phá mới dễ bị nhiễu bởi tiếng ồn ngắn hạn, cần đánh giá tính thống kê và tính bền vững của xu hướng

Hướng tối ưu hóa chiến lược

  1. Kiểm tra các kết hợp các tham số khác nhau để xác định tham số và chiều dài đường trung bình di chuyển tốt nhất
  2. Sử dụng mô hình kết hợp kết hợp các tham số khác nhau của dải Brin hoặc tín hiệu phán đoán trung bình di chuyển
  3. Kiểm tra sự phù hợp của các tham số trong các khoảng thời gian khác nhau và các giống khác nhau để cải thiện sức khỏe
  4. Kết hợp với các điều kiện cấp độ lớn hơn, chẳng hạn như tín hiệu băng tần Brin cấp độ mặt trời hoặc các yếu tố theo mùa
  5. Đánh giá cơ hội theo xu hướng để mở rộng phạm vi chiến lược và lợi nhuận

Tóm tắt

Chiến lược này kết hợp nhiều công cụ kỹ thuật như tỷ lệ phần trăm của Brin, trung bình di chuyển, chỉ số ATR, mức cao mới và thấp nhất và mức cao nhất hàng năm, để xây dựng một chiến lược giao dịch đột phá tương đối nghiêm ngặt và hiệu quả trong thời gian ngắn. Ưu điểm nổi bật của nó là sử dụng tất cả các loại công cụ để giảm tiếng ồn và nhận ra tín hiệu xu hướng thực sự.

Mã nguồn chiến lược
/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 00:00:00
period: 1d
basePeriod: 1h
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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Bollinger %B Candles Strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

BBLength = input(100, minval=1, step=1)
StdDev = 10
useMovingAverage = input(true)
MAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
lookbackPeriod = input(22, minval=10, step=10)
colorByPreviousClose = input(true)

AtrMAType = input(title="Moving Average Type", defval="hma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(10)
AtrMult = input(4)
wicks = input(false)

considerYearlyHighLow = input(false)
considerNewLongTermHighLows = input(false)
shortHighLowPeriod = 100
longHighLowPeriod = 200
tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])

backtestYears = input(10, minval=1, step=1)


//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
    newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
    newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
    [newHigh,newLow]

//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
    yhigh = security(syminfo.tickerid, '12M', high[1]) 
    ylow = security(syminfo.tickerid, '12M', low[1]) 
    yhighlast = yhigh[365]
    ylowlast = ylow[365]
    yhighllast = yhigh[2 * 365]
    ylowllast = ylow[2 * 365]
    
    yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
    yearlyHighCondition = (  (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
    yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
    yearlyLowCondition = (  (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
    
    label_x = time+(60*60*24*1000*1)
    [yearlyHighCondition,yearlyLowCondition]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

inDateRange = true
[yearlyHighCondition,yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHighS,newLowS] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)
[middleclose, upperclose, lowerclose] = bb(close, BBLength, StdDev)
[middleopen, upperopen, loweropen] = bb(open, BBLength, StdDev)
[middlehigh, upperhigh, lowerhigh] = bb(high, BBLength, StdDev)
[middlelow, upperlow, lowerlow] = bb(low, BBLength, StdDev)

percentBClose = (close - lowerclose)*100/(upperclose-lowerclose)
percentBOpen = (open - loweropen)*100/(upperopen-loweropen)
percentBHigh = (high - lowerhigh)*100/(upperhigh-lowerhigh)
percentBLow = (low - lowerlow)*100/(upperlow-lowerlow)

percentBMAClose = f_getMovingAverage(percentBClose, MAType, lookbackPeriod)
percentBMAOpen = f_getMovingAverage(percentBOpen, MAType, lookbackPeriod)
percentBMAHigh = f_getMovingAverage(percentBHigh, MAType, lookbackPeriod)
percentBMALow = f_getMovingAverage(percentBLow, MAType, lookbackPeriod)

newOpen = useMovingAverage? percentBMAOpen : percentBOpen
newClose = useMovingAverage? percentBMAClose : percentBClose
newHigh = useMovingAverage? percentBMAHigh : percentBHigh
newLow = useMovingAverage? percentBMALow : percentBLow

truerange = max(newHigh, newClose[1]) - min(newLow, newClose[1])

averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
atr = averagetruerange * AtrMult

longStop = newClose - atr
longStopPrev = nz(longStop[1], longStop)
longStop := (wicks ? newLow[1] : newClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop

shortStop = newClose + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := (wicks ? newHigh[1] : newClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and (wicks ? newHigh : newClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? newLow : newClose) < longStopPrev ? -1 : dir

trailingStop = dir == 1? longStop : shortStop

candleColor = colorByPreviousClose ?
                 (newClose[1] < newClose ? color.green : newClose[1] > newClose ? color.red : color.silver) : 
                 (newOpen < newClose ? color.green : newOpen > newClose ? color.red : color.silver)
plotcandle(newOpen, newHigh, newLow, newClose, title='PercentBCandle', color = candleColor, wickcolor=candleColor)
plot(trailingStop, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= dir == 1 ? color.green : color.red)

buyCondition = dir==1 and yearlyHighCondition and newHighS
exitBuyCondition = dir == -1
sellCondition = dir == -1 and yearlyLowCondition and newLowS
exitSellCondition = dir == 1
strategy.risk.allow_entry_in(tradeDirection)

barcolor(buyCondition? color.lime : sellCondition ? color.orange : color.silver)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca_buy")
strategy.close("Buy", when=exitBuyCondition)

strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca_sell")
strategy.close("Sell", when=exitSellCondition)