Chiến lược đột phá dựa trên động lượng


Ngày tạo: 2024-02-23 14:27:21 sửa đổi lần cuối: 2024-02-23 14:27:21
sao chép: 0 Số nhấp chuột: 646
1
tập trung vào
1621
Người theo dõi

Chiến lược đột phá dựa trên động lượng

Tổng quan

Chiến lược phá vỡ động lực là một chiến lược theo dõi xu hướng về động lực của thị trường. Nó kết hợp nhiều chỉ số để xác định liệu thị trường hiện đang trong xu hướng tăng hay giảm, và đặt nhiều vị trí khi phá vỡ ngưỡng kháng cự quan trọng, và đặt vị trí trống khi phá vỡ ngưỡng hỗ trợ quan trọng.

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

Chiến lược này chủ yếu đánh giá xu hướng thị trường và mức giá quan trọng bằng cách tính toán các kênh Donchian dài hơn. Cụ thể, nó đánh giá xu hướng tăng khi giá phá vỡ chu kỳ dài hơn như đường kênh Donchian 40 ngày, và trên cơ sở đó phát ra nhiều tín hiệu kết hợp các điều kiện lọc như cao mới trong năm, sắp xếp theo hướng trung bình di chuyển; và khi giá phá vỡ chu kỳ Donchian dài hơn, để xác định xu hướng giảm, kết hợp các điều kiện lọc như thấp mới trong năm.

Đối với việc thoát khỏi vị trí, chiến lược này cung cấp hai lựa chọn: đường hủy cố định và theo dõi dừng. Đường hủy cố định là đặt điểm dừng dựa trên chu kỳ ngắn hơn như kênh Donchian 20 ngày; theo dõi dừng là tính toán hàng ngày dựa trên giá trị ATR.

Phân tích lợi thế

Chiến lược này kết hợp sự phán đoán xu hướng và hoạt động phá vỡ, có thể nắm bắt hiệu quả các cơ hội định hướng của đường ngắn trong thị trường. So với chỉ số đơn lẻ, nó sử dụng nhiều điều kiện lọc tổng hợp, có thể lọc một số phá vỡ giả để cải thiện chất lượng tín hiệu nhập. Ngoài ra, việc sử dụng chiến lược dừng lỗ cũng làm cho khả năng chịu đựng của nó mạnh mẽ hơn, thậm chí có thể kiểm soát thiệt hại một cách hiệu quả ngay cả khi điều kiện ngắn hạn.

Phân tích rủi ro

Rủi ro chính của chiến lược này là có thể xảy ra biến động mạnh mẽ trong thị trường, dẫn đến việc dừng lỗ được kích hoạt để thoát khỏi vị trí. Nếu thị trường thay đổi nhanh chóng, cơ hội có thể bị bỏ lỡ. Ngoài ra, việc sử dụng nhiều điều kiện lọc cũng sẽ lọc ra một số cơ hội, làm giảm tần suất giữ vị trí của chiến lược.

Để giảm nguy cơ, bạn có thể điều chỉnh giá trị ATR thích hợp hoặc mở rộng khoảng cách đường ray Donchian, điều này có thể làm giảm khả năng bị phá vỡ. Bạn cũng có thể giảm hoặc loại bỏ một phần các điều kiện lọc, tăng tần số truy cập, nhưng nguy cơ cũng sẽ tăng.

Hướng tối ưu hóa

Chiến lược này có thể được tối ưu hóa theo các khía cạnh sau:

  1. Tối ưu hóa chiều dài của kênh Donchian, tìm kiếm sự kết hợp tham số tốt nhất
  2. Thử các loại trung bình di chuyển khác nhau như là một chỉ số đợt sóng
  3. Điều chỉnh ATR nhân hoặc thay đổi số điểm cố định
  4. Thêm thêm các chỉ số định hướng như MACD
  5. Tối ưu hóa thời kỳ cửa sổ phán quyết cao và thấp trong năm

Bằng cách thử nghiệm các tham số khác nhau, bạn có thể tìm ra sự kết hợp tốt nhất của các tham số để cân bằng giữa rủi ro và lợi ích.

Tóm tắt

Chiến lược này kết hợp nhiều chỉ số để xác định xu hướng, phát tín hiệu giao dịch khi điểm mấu chốt bị phá vỡ. Cơ chế dừng lỗ của nó cũng làm cho chiến lược có khả năng kiểm soát rủi ro mạnh mẽ. Bằng cách thiết lập tham số tối ưu, chiến lược có thể đạt được lợi nhuận vượt trội ổn định. Nó phù hợp cho các nhà đầu tư không có phán đoán rõ ràng về thị trường nhưng muốn theo dõi xu hướng.

Mã nguồn chiến lược
/*backtest
start: 2024-01-23 00:00:00
end: 2024-02-22 00:00:00
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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("BuyHigh-SellLow Strategy", overlay=true, initial_capital = 10000, 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)
donchianEntryLength = input(40, step=10)
donchianExitLength = input(20, step=10)

considerNewLongTermHighLows = input(true)
shortHighLowPeriod = input(120, step=10)
longHighLowPeriod = input(180, step=10)

considerMAAlignment = input(true)
MAType = input(title="Moving Average Type", defval="ema", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
LookbackPeriod = input(40, minval=10,step=10)

atrLength = input(22)
atrMult = input(4)

exitStrategy = input(title="Exit Strategy", defval="tsl", options=["dc", "tsl"])

considerYearlyHighLow = input(true)
backtestYears = input(10, minval=1, step=1)
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

f_getTrailingStop(atr, atrMult)=>
    stop = close - atrMult*atr
    stop := strategy.position_size > 0 ? max(stop, stop[1]) : stop
    stop

f_getMaAlignment(MAType, includePartiallyAligned)=>
    ma5 = f_getMovingAverage(close,MAType,5)
    ma10 = f_getMovingAverage(close,MAType,10)
    ma20 = f_getMovingAverage(close,MAType,20)
    ma30 = f_getMovingAverage(close,MAType,30)
    ma50 = f_getMovingAverage(close,MAType,50)
    ma100 = f_getMovingAverage(close,MAType,100)
    ma200 = f_getMovingAverage(close,MAType,200)

    upwardScore = 0
    upwardScore := close > ma5? upwardScore+1:upwardScore
    upwardScore := ma5 > ma10? upwardScore+1:upwardScore
    upwardScore := ma10 > ma20? upwardScore+1:upwardScore
    upwardScore := ma20 > ma30? upwardScore+1:upwardScore
    upwardScore := ma30 > ma50? upwardScore+1:upwardScore
    upwardScore := ma50 > ma100? upwardScore+1:upwardScore
    upwardScore := ma100 > ma200? upwardScore+1:upwardScore
    
    upwards = close > ma5 and ma5 > ma10 and ma10 > ma20 and ma20 > ma30 and ma30 > ma50 and ma50 > ma100 and ma100 > ma200
    downwards = close < ma5 and ma5 < ma10 and ma10 < ma20 and ma20 < ma30 and ma30 < ma50 and ma50 < ma100 and ma100 < ma200
    upwards?1:downwards?-1:includePartiallyAligned ? (upwardScore > 5? 0.5: upwardScore < 2?-0.5:upwardScore>3?0.25:-0.25) : 0

//////////////////////////////////// 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]

donchian(rangeLength)=>
    upper = highest(rangeLength)
    lower = lowest(rangeLength)
    middle = (upper+lower)/2
    [middle, upper, lower]

inDateRange = true
[eMiddle, eUpper, eLower] = donchian(donchianEntryLength)
[exMiddle, exUpper, exLower] = donchian(donchianExitLength)
maAlignment = f_getMaAlignment(MAType, false)
[yearlyHighCondition, yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHigh,newLow] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)

maAlignmentLongCondition = highest(maAlignment, LookbackPeriod) == 1 or not considerMAAlignment 

atr = atr(atrLength)
tsl = f_getTrailingStop(atr, atrMult)

//U = plot(eUpper, title="Up", color=color.green, linewidth=2, style=plot.style_linebr)
//D = plot(exLower, title="Ex Low", color=color.red, linewidth=2, style=plot.style_linebr)
longCondition = crossover(close, eUpper[1]) and yearlyHighCondition and newHigh and maAlignmentLongCondition
exitLongCondition = crossunder(close, exLower[1])

shortCondition = crossunder(close, eLower[1]) and yearlyLowCondition and newLow
exitShortCondition = crossover(close, exUpper[1])
strategy.entry("Buy", strategy.long, when=longCondition and inDateRange, oca_name="oca_buy")
strategy.exit("ExitBuyDC", "Buy", when=exitStrategy=='dc', stop=exLower)
strategy.exit("ExitBuyTSL", "Buy", when=exitStrategy=='tsl', stop=tsl)
plot(strategy.position_size > 0 ? (exitStrategy=='dc'?exLower:tsl) : na, title="Trailing Stop", color=color.red, linewidth=2, style=plot.style_linebr)
//strategy.close("Buy", when=exitLongCondition)