Triple Moving Average Crossover và chiến lược chỉ số Williams

Tác giả:ChaoZhang, Ngày: 2023-09-28 10:58:16
Tags:

Tổng quan

Chiến lược này xác định hướng xu hướng giá bằng cách kết hợp ba đường trung bình di chuyển trơn tru, chỉ số sức mạnh tương đối (RSI) và chỉ số Williams, và tìm kiếm các cơ hội giao dịch khi xu hướng đảo ngược. Nó đi dài (ngắn) khi các đường trung bình di chuyển nhanh, trung bình và chậm liên kết lên (dưới), RSI trên (dưới) 50 và tín hiệu Williams giảm (lên) xuất hiện. Đặt dừng lỗ ở một tỷ lệ phần trăm nhất định của giá nhập cảnh và lấy lợi nhuận ở một tỷ lệ phần trăm nhất định di chuyển theo hướng thuận lợi từ giá nhập cảnh.

Chiến lược logic

Chiến lược này sử dụng ba đường trung bình động với các giai đoạn khác nhau, bao gồm MA nhanh, trung bình và chậm. Khi MA nhanh vượt qua MA trung bình, nó báo hiệu xu hướng tăng giá. Khi MA nhanh vượt dưới MA trung bình, nó báo hiệu xu hướng giảm giá. Sau khi xác định xu hướng tăng hoặc giảm, chiến lược chờ cơ hội giao dịch đầu tiên.

Cụ thể, sau khi giá bước vào xu hướng tăng, chiến lược chờ cho đến khi năm điều kiện sau được đáp ứng trước khi mua dài:

  1. Các MAs nhanh, trung bình và chậm đều hướng lên;

  2. RSI trên 50;

  3. Một mô hình Williams giảm dần xuất hiện;

  4. Giá vượt qua MA chậm;

  5. Không có vị trí hiện tại.

Sau khi giá bước vào xu hướng giảm, chiến lược chờ cho đến khi năm điều kiện sau được đáp ứng trước khi đi ngắn:

  1. Các MA nhanh, trung bình và chậm đều hướng xuống;

  2. RSI dưới 50;

  3. Một mô hình Williams tăng lên xuất hiện;

  4. Giá vượt qua dưới mức MA chậm;

  5. Không có vị trí hiện tại.

Sau khi mua dài hoặc ngắn, chiến lược đặt một mức dừng lỗ ở một tỷ lệ phần trăm nhất định dưới giá nhập cảnh và mục tiêu lợi nhuận ở một tỷ lệ phần trăm nhất định trên giá nhập cảnh.

Ưu điểm

  1. Kết hợp nhiều chỉ số để xác nhận các mục nhập có thể tránh hiệu quả các đột phá sai. Các MAs ba xác định hướng xu hướng, Williams bắt tín hiệu đảo ngược và RSI lọc hành động giá giới hạn trong phạm vi, cùng nhau cải thiện độ chính xác của các mục nhập.

  2. Thiết lập dừng lỗ và lấy lợi nhuận có thể kiểm soát rủi ro / phần thưởng của mỗi giao dịch, đảm bảo các giao dịch chiến thắng vượt quá các giao dịch thua lỗ.

  3. Chiến lược logic là rõ ràng và dễ hiểu. các thông số được thiết lập hợp lý. nó phù hợp với các nhà giao dịch ở các cấp độ khác nhau.

Rủi ro

  1. Các chỉ số có thể tạo ra các tín hiệu không chính xác trong các thị trường giới hạn phạm vi, gây ra các mục nhập không cần thiết.

  2. Việc chéo MA nhanh và trung bình có thể có sự đột phá sai.

  3. Nếu stop loss quá gần với giá nhập cảnh, nó có thể bị dừng sớm.

  4. Nếu lợi nhuận được lấy quá xa so với giá nhập cảnh, nó có thể không bị tấn công.

Hướng dẫn tối ưu hóa

  1. Kiểm tra các kết hợp tham số khác nhau cho ba MA và RSI.

  2. Thêm các chỉ số khác, chẳng hạn như khối lượng, để kiểm tra xem khối lượng tăng lên khi phá vỡ.

  3. Các thông số thử nghiệm dựa trên các sản phẩm khác nhau.

  4. Kéo đường cong lợi nhuận dựa trên kết quả backtest để tối ưu hóa dừng lỗ và lấy lợi nhuận.

  5. Hãy thử giao dịch giấy trước khi cho phép nó tối ưu hóa các thông số.

Kết luận

Chiến lược có logic rõ ràng nói chung, nhập và ra khỏi các vị trí với sự kết hợp của các chỉ số, điều này kiểm soát rủi ro một cách hiệu quả. Có nhiều chỗ cho tối ưu hóa tham số. Bằng cách kiểm tra các thiết lập tham số khác nhau, chiến lược này có thể trở thành một chiến lược giao dịch định lượng có lợi nhuận ổn định. Tuy nhiên, không có chiến lược nào có thể tránh hoàn toàn thua lỗ. Các nhà giao dịch cần tuân theo kỷ luật giao dịch - lấy lợi nhuận khi thắng và cắt giảm lỗ khi thua.


/*backtest
start: 2023-08-28 00:00:00
end: 2023-09-27 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//This script is a combination of 3 smoothed moving averages, and RSI. When moving averages are aligned upward (downward) and RSI is above (below) 50 and a down (up) William fractal appears, it enters long (short) position. Exiting from long and short entries are defined by StopLoss and TargetProfit.

//@version=5

strategy(title="3SmmaCrossUp + Fractal + RSI", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, currency=currency.USD, commission_type=strategy.commission.percent, commission_value=0.03)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// inputs

// Global
src = input(close, title="Source")
stopLoss = input.float(defval = 0.1, title = "Stop Loss %", minval = 0, maxval=100, step = 0.1)
targetProfit = input.float(defval = 0.4, title = "Target Profit %", minval = 0, maxval=100, step = 0.1)

// Smooth Moving Average
fastSmmaLen = input.int(21, minval=1, title="Fast Length", group = "Smooth Moving Average")
midSmmaLen = input.int(50, minval=1, title="Mid Length",group = "Smooth Moving Average")
slowSmmaLen = input.int(200, minval=1, title="Slow Length",group = "Smooth Moving Average")

// RSI
rsiLen = input.int(defval=14, title="length", minval=1, maxval=1000, step=1, group="RSI")

// Fractals
n = input.int(title="Periods", defval=2, minval=2, group = "Fractals")

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// initialization

var waitingFirstTradeInUpwardTrend = false
var waitingFirstTradeInDownwardTrend = false

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// functions

smma(ma, src, len) => 
    smma = 0.0
    smma := na(smma[1]) ? ma : (smma[1] * (len - 1) + src) / len
    smma
    
fractals(n, highs, lows) =>
    // UpFractal
    bool upflagDownFrontier = true
    bool upflagUpFrontier0 = true
    bool upflagUpFrontier1 = true
    bool upflagUpFrontier2 = true
    bool upflagUpFrontier3 = true
    bool upflagUpFrontier4 = true
    for i = 1 to n
        upflagDownFrontier := upflagDownFrontier and (highs[n-i] < highs[n])
        upflagUpFrontier0 := upflagUpFrontier0 and (highs[n+i] < highs[n])
        upflagUpFrontier1 := upflagUpFrontier1 and (highs[n+1] <= highs[n] and highs[n+i + 1] < highs[n])
        upflagUpFrontier2 := upflagUpFrontier2 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+i + 2] < highs[n])
        upflagUpFrontier3 := upflagUpFrontier3 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+i + 3] < highs[n])
        upflagUpFrontier4 := upflagUpFrontier4 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+4] <= highs[n] and highs[n+i + 4] < highs[n])
    flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4
    
    upFractal = (upflagDownFrontier and flagUpFrontier)
    
    // downFractal
    bool downflagDownFrontier = true
    bool downflagUpFrontier0 = true
    bool downflagUpFrontier1 = true
    bool downflagUpFrontier2 = true
    bool downflagUpFrontier3 = true
    bool downflagUpFrontier4 = true
    
    for i = 1 to n
        downflagDownFrontier := downflagDownFrontier and (lows[n-i] > lows[n])
        downflagUpFrontier0 := downflagUpFrontier0 and (lows[n+i] > lows[n])
        downflagUpFrontier1 := downflagUpFrontier1 and (lows[n+1] >= lows[n] and lows[n+i + 1] > lows[n])
        downflagUpFrontier2 := downflagUpFrontier2 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+i + 2] > lows[n])
        downflagUpFrontier3 := downflagUpFrontier3 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+i + 3] > lows[n])
        downflagUpFrontier4 := downflagUpFrontier4 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+4] >= lows[n] and lows[n+i + 4] > lows[n])
    flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4
    
    downFractal = (downflagDownFrontier and flagDownFrontier)
    [upFractal, downFractal]

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// calcs

[upFractal, downFractal] = fractals(n, high, low)


rsiIsHigh = ta.rsi(src, rsiLen) >= 50 


slowMa = ta.sma(src, slowSmmaLen)
midMa = ta.sma(src, midSmmaLen)
fastMa = ta.sma(src, fastSmmaLen)

slowSmma = smma(slowMa ,src, slowSmmaLen)
midSmma = smma(midMa, src, midSmmaLen)
fastSmma = smma(fastMa, src, fastSmmaLen)

isFastSmmaUpward = ta.rising(fastSmma, 1)
isMidSmmaUpward = ta.rising(midSmma, 1)
isSlowSmmaUpward = ta.rising(slowSmma, 1)

isFastSmmaDownward = ta.falling(fastSmma, 1)
isMidSmmaDownward = ta.falling(midSmma, 1)
isSlowSmmaDownward = ta.falling(slowSmma, 1)

slowMovingAveragesAreUpward = isMidSmmaUpward and isSlowSmmaUpward
slowMovingAveragesAreDownward = isMidSmmaDownward and isSlowSmmaDownward

justEnteredUpwardTrend = ta.crossover(fastSmma, midSmma) ? true : false
justEnteredDownwardTrend = ta.crossunder(fastSmma, midSmma) ? true : false

waitingFirstTradeInUpwardTrend := justEnteredUpwardTrend == true ? true : (isFastSmmaDownward or isMidSmmaDownward or isSlowSmmaDownward ? false : waitingFirstTradeInUpwardTrend)
waitingFirstTradeInDownwardTrend := justEnteredDownwardTrend == true ? true : (isFastSmmaUpward or isMidSmmaUpward or isSlowSmmaUpward ? false : waitingFirstTradeInDownwardTrend)

priceCrossedOverSlowMa = ta.crossover(close, slowSmma)
priceCrossedUnderSlowMa = ta.crossunder(close, slowSmma)

enterLongCondition = barstate.isconfirmed and low > fastSmma and rsiIsHigh and (downFractal or priceCrossedOverSlowMa) and waitingFirstTradeInUpwardTrend and strategy.position_size == 0

enterShortCondition = barstate.isconfirmed and high < fastSmma and (not rsiIsHigh) and (upFractal or priceCrossedUnderSlowMa) and waitingFirstTradeInDownwardTrend and strategy.position_size == 0

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// strategy

if(enterLongCondition)
    strategy.entry(id="L", direction=strategy.long)
    waitingFirstTradeInUpwardTrend := false

if(enterShortCondition)
    strategy.entry(id="S", direction=strategy.short)
    waitingFirstTradeInDownwardTrend := false
    
if(strategy.position_size > 0)
    strategy.exit(id="EL", stop=strategy.position_avg_price * (1 - stopLoss/100), limit=strategy.position_avg_price * (1+targetProfit/100)) 
if(strategy.position_size < 0)
    strategy.exit(id="ES", stop=strategy.position_avg_price * (1 + stopLoss/100), limit=strategy.position_avg_price * (1-targetProfit/100)) 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// plots

plot(series = slowSmma, title="Slow SMMA", linewidth=3)
plot(series = midSmma, title="Mid SMMA", linewidth=2)
plot(series = fastSmma, title="Fast SMMA", linewidth=1)
plotchar(series=rsiIsHigh, title='rsiIsHigh', char='')
plotchar(series=justEnteredUpwardTrend, title='justEnteredUpwardTrend', char='')
plotchar(series=justEnteredDownwardTrend, title='justEnteredDownwardTrend', char='')
plotchar(series=waitingFirstTradeInUpwardTrend, title='waitingFirstTradeInUpwardTrend', char='')
plotchar(series=waitingFirstTradeInDownwardTrend, title='waitingFirstTradeInDownwardTrend', char='')
plotchar(series=enterLongCondition, title='enterLongCondition' , char='')
plotchar(series=enterShortCondition, title='enterShortCondition' , char='')
plotshape(series=upFractal, title='upFractal', style=shape.triangleup, location=location.abovebar, color=#009688, size = size.tiny)
plotshape(series=downFractal, title='downFractal', style=shape.triangledown, location=location.belowbar, color=color.red, size = size.tiny)













Thêm nữa