Chiến lược giao dịch nhịp độ nến dao động

Tác giả:ChaoZhang, Ngày: 2023-09-26 20:05:55
Tags:

Tổng quan

Đây là một chiến lược dựa trên động lực sử dụng các chỉ số dao động như RSI, Stoch, MACD để tạo ra các tín hiệu giao dịch. Ý tưởng chính là xác định hướng xu hướng khi giá dao động bằng cách sử dụng các chỉ số và tham gia giao dịch dựa trên các tín hiệu chỉ số. Chiến lược cũng sử dụng siêu xu hướng trì hoãn để dừng lỗ.

Chiến lược logic

Chiến lược đầu tiên gọi hàm tùy chỉnh f_getOscilatorValues để có được giá trị của các chỉ số dao động khác nhau bao gồm RSI, Stoch, MACD v.v. Sau đó nó tính toán các giá trị siêu xu hướng bị trì hoãn với f_getSupertrend để theo dõi dừng lỗ.

Sau khi tính toán các chỉ số, chiến lược gọi f_getBuySellStops để tính toán các điểm dừng nhập và mục tiêu lợi nhuận dựa trên các giá trị chỉ số. Cụ thể, nó tính toán ATR và sử dụng ATR nhân với hệ số dừng lỗ như điểm dừng nhập, và ATR nhân với hệ số lấy lợi nhuận như mục tiêu lợi nhuận. Các điểm dừng và mục tiêu sẽ điều chỉnh khi xu hướng đảo ngược.

Sau đó, chiến lược xác định hướng nến. Nến xu hướng tăng có màu xanh lá cây và nến xu hướng giảm có màu đỏ. Sau khi vẽ các nến và chỉ số, chiến lược kiểm tra xem các điều kiện nhập cảnh có được đáp ứng không. Các điều kiện nhập cảnh là mua khi chỉ số hiển thị quá mua và giá phá vỡ trên dải trên, và bán khi chỉ số hiển thị quá bán và giá phá vỡ dưới dải dưới.

Sau khi vào, stop loss được theo dõi bởi dải trên / dưới, bất cứ điều nào gần hơn. Khi stop loss được kích hoạt, vị trí được đóng. Khi giá đạt mục tiêu lợi nhuận, lợi nhuận một phần được lấy.

Phân tích lợi thế

Những lợi thế của chiến lược này là:

  1. Sử dụng dao động để xác định hướng xu hướng có thể nắm bắt các cơ hội đảo ngược ngắn hạn kịp thời.

  2. Ứng dụng quá trình dừng lỗ siêu xu hướng trì hoãn có thể dừng lại trước khi lỗ tăng, hạn chế lỗ giao dịch duy nhất.

  3. Việc tính toán mục tiêu dừng lỗ và lợi nhuận dựa trên ATR năng động giúp điều chỉnh kích thước vị trí.

  4. Việc lọc với đường trung bình động theo khung thời gian cao hơn tránh bị mắc kẹt trong việc hợp nhất.

  5. Lấy lợi nhuận một phần cho phép lợi nhuận chạy trong khi khóa một số lợi nhuận.

  6. Lý thuyết đơn giản và dễ hiểu cho những người mới bắt đầu giao dịch lượng tử.

Phân tích rủi ro

Một số rủi ro của chiến lược này bao gồm:

  1. Các dao động có thể có các vấn đề chậm trễ, gây ra tín hiệu bước vào và bước ra sớm. Điều này có thể được cải thiện bằng cách tối ưu hóa các thông số hoặc thêm các chỉ số theo xu hướng.

  2. Phạm vi dừng lỗ có thể được mở rộng hoặc dừng động như Chandelier có thể được sử dụng.

  3. Các vị trí còn lại sau khi lấy lợi nhuận một phần có thể được dừng lại.

  4. Phương pháp nên được xác nhận trên các thị trường khác nhau.

  5. Trục trặc của bộ lọc trung bình động khung thời gian cao hơn.

Hướng dẫn cải thiện

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

  1. Kiểm tra các kết hợp khác nhau của các thông số dao động và tìm những người cung cấp tín hiệu chất lượng.

  2. Cố gắng thay thế phần lợi nhuận bằng việc dừng lợi nhuận dựa trên ATR hoặc trung bình động.

  3. Thêm các thuật toán học máy để thay thế trung bình động cho phân tích xu hướng và cải thiện độ chính xác.

  4. Thêm các chỉ số âm lượng như điều kiện lọc để tránh đảo ngược không cần thiết.

  5. Tập hợp và cân nhắc các chỉ số tối ưu để tìm ra sự kết hợp tối ưu cho tài sản.

  6. Thêm các mô-đun kiểm soát rủi ro học máy để tối ưu hóa năng động các điểm dừng, mục tiêu và kích thước vị trí.

  7. Tích hợp các tín hiệu giao dịch ngang hình tam giác hoặc cơ sở bằng cách sử dụng chênh lệch giá giữa tương lai và giao dịch tại chỗ.

Kết luận

Nhìn chung, đây là một chiến lược tuyệt vời cho những người mới bắt đầu giao dịch lượng với logic rõ ràng tập trung vào các chỉ số và quản lý rủi ro. Nhưng tối ưu hóa tham số và giảm rủi ro vẫn cần thiết cho giao dịch trực tiếp. Nó cũng có thể được tăng cường trong các khía cạnh như phân tích xu hướng, tối ưu hóa dừng lỗ, mô hình tập hợp vv để cải thiện độ bền. Là một mẫu chiến lược giao dịch, nó cung cấp tài liệu tham khảo có giá trị.


/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 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("Oscilator 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)

oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"])
length = input(3)
shortlength = input(3)
longlength = input(9)

showSupertrend = input(true)
AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(30, step=10)
stopMultiplier  = input(4)
targetMultiplier  = input(3)
wicks = input(true)
considerWicksForDelayByStep = input(false)
colorByPreviousClose = input(true)

useHTFPivot = input(false)
resolution = input("12M", type=input.resolution)
HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1)
PivotLength = input(2, step=1)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time)
i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time)
inDateRange = true

f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=>
    oOpen = rsi(open, length)
    oClose = rsi(close, length)
    oHigh = rsi(high, length)
    oLow = rsi(low, length)
    if(oscilatorType == "tsi")
        oOpen := tsi(open, shortlength, longlength)
        oClose := tsi(close, shortlength, longlength)
        oHigh := tsi(high, shortlength, longlength)
        oLow := tsi(low, shortlength, longlength)
    if(oscilatorType == "stoch")
        oOpen := stoch(open, longlength, shortlength, length)
        oClose := stoch(close, longlength, shortlength, length)
        oHigh := stoch(high, longlength, shortlength, length)
        oLow := stoch(low, longlength, shortlength, length)
    if(oscilatorType == "cci")
        oOpen := cci(open, length)
        oClose := cci(close, length)
        oHigh := cci(high, length)
        oLow := cci(low, length)
    if(oscilatorType == "cog")
        oOpen := cog(open, length)
        oClose := cog(close, length)
        oHigh := cog(high, length)
        oLow := cog(low, length)
    if(oscilatorType == "cmo")
        oOpen := cmo(open, length)
        oClose := cmo(close, length)
        oHigh := cmo(high, length)
        oLow := cmo(low, length)
    if(oscilatorType == "mfi")
        oOpen := mfi(open, length)
        oClose := mfi(close, length)
        oHigh := mfi(high, length)
        oLow := mfi(low, length)
    if(oscilatorType == "macd")
        [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length)
        [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length)
        [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length)
        [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length)
        oOpen := macdLineOpen
        oClose := macdLineClose
        oHigh := macdLineHigh
        oLow := macdLineLow
    [oOpen, oClose, oHigh, oLow]

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_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=>
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
    atr = averagetruerange * stopMultiplier

    longStop = oClose - atr
    longStopPrev = nz(longStop[1], longStop)
    longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop
    
    shortStop = oClose + atr
    shortStopPrev = nz(shortStop[1], shortStop)
    shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
    
    dir = 1
    dir := nz(dir[1], dir)
    dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir
    
    trailingStop = dir == 1? longStop : shortStop
    
    [dir, trailingStop]


f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=>
    barState = 0
    source = oClose
    
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    atr = f_getMovingAverage(truerange, AtrMAType, AtrLength)

    buyStop = source - atr * stopMultiplier
    sellStop = source + atr * stopMultiplier
    buyStopDerived = buyStop
    sellStopDerived = sellStop
    highTarget = considerWicks ? oHigh : source
    lowTarget = considerWicks ? oLow : source
    
    highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source
    lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source
    
    barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0)
    
    buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier
    sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier
    buyStop := source - atr * buyMultiplier
    sellStop := source + atr * sellMultiplier
    buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop
    sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop
    
    buyStopDerived := buyStop
    sellStopDerived := sellStop
    
    buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived
    sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived

    [buyStopDerived, sellStopDerived, barState]


f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off)

f_multiple_resolution(HTFMultiplier) => 
    target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
      timeframe.isseconds   ? 1. / 60. :
      timeframe.isminutes   ? 1. :
      timeframe.isdaily     ? 1440. :
      timeframe.isweekly    ? 7. * 24. * 60. :
      timeframe.ismonthly   ? 30.417 * 24. * 60. : na)

    target_Res_In_Min     <= 0.0417       ? "1S"  :
      target_Res_In_Min   <= 0.167        ? "5S"  :
      target_Res_In_Min   <= 0.376        ? "15S" :
      target_Res_In_Min   <= 0.751        ? "30S" :
      target_Res_In_Min   <= 1440         ? tostring(round(target_Res_In_Min)) :
      tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"
    
f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=>
    derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution
    HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh)
    HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow)
    CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose)
    pivothi = pivothigh(HTFHigh, PivotLength, PivotLength)
    pivotlo = pivotlow(HTFLow, PivotLength, PivotLength)
    pivothi := na(pivothi)? nz(pivothi[1]) : pivothi
    pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo
    [pivothi, pivotlo]
    
[oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength)
[dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)

candleColor = colorByPreviousClose ?
                 (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : 
                 (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver)
plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor)

[buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)

trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived

plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red)

[pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength)

buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot)
exitBuyConditin = (barState == -1)
sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot)
exitSellCondition = (barState == 1)

// strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca")
strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca")
strategy.close("Buy", when = exitBuyConditin)
strategy.close( "Sell", when = exitSellCondition)

Thêm nữa