Chiến lược lai của MACD Turtle

Tác giả:ChaoZhang, Ngày: 2023-10-30 12:16:20
Tags:

img

Tổng quan

Chiến lược này kết hợp các tín hiệu đường chéo vàng và đường chéo chết của chỉ số MACD, mối quan hệ giá đóng với đường trung bình và các đặc điểm biến động giá để xác định các điểm nhập và thoát. Nó cũng thiết lập các cơ chế nhập lại và điều chỉnh để có được nhiều cơ hội giao dịch hơn trong khi kiểm soát rủi ro và nhận được lợi nhuận ổn định.

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

Chiến lược này chủ yếu dựa trên các nguyên tắc sau:

  1. Sử dụng đường MACD nhanh và đường chậm, đường chéo vàng và đường chéo chết để xác định thị trường tăng và giảm và các điểm vào cụ thể.

  2. Sử dụng mối quan hệ giá đóng với đường trung bình để xác định kết thúc xu hướng và điểm thoát.

  3. Thiết lập cơ chế tái tham gia để tái tham gia thị trường theo cùng một hướng sau khi kết thúc xu hướng MACD hiện tại để tăng lợi nhuận.

  4. Thiết lập cơ chế nhập chỉnh sửa để thêm các vị trí trong khi điều chỉnh giá một phần trong một xu hướng.

  5. Điều chỉnh động các vị trí dựa trên những điều trên để tối đa hóa lợi nhuận trong xu hướng trong khi thoát nhanh khi xu hướng kết thúc.

Cụ thể, chiến lược đầu tiên kiểm tra xem có một đường chéo vàng hoặc đường chéo chết xảy ra giữa đường MACD nhanh và chậm để đi dài hoặc ngắn. Sau đó nó kiểm tra xem giá đóng chạm vào đường trung bình để xác định kết thúc xu hướng và đóng các vị trí.

Ngoài ra, chiến lược có một cơ chế nhập lại để mở lại các vị trí theo hướng ban đầu nếu MACD tiếp tục hiển thị tín hiệu theo cùng một hướng sau khi xu hướng ban đầu kết thúc.

Thông qua các thiết lập này, chiến lược có thể điều chỉnh vị trí một cách năng động, tăng tần suất nhập và xuất, và tối đa hóa lợi nhuận trong khi kiểm soát rủi ro trong xu hướng.

Ưu điểm

Những lợi thế chính của chiến lược đa chỉ số này là:

  1. MACD xác định xu hướng và điểm đảo ngược cho bước vào.

  2. Giá đóng cửa và mối quan hệ đường trung bình xác định chính xác kết thúc xu hướng.

  3. Thêm vào tăng hiệu quả sử dụng vốn.

  4. Đăng nhập điều chỉnh kịp thời thêm các vị trí để nắm bắt xu hướng.

  5. Tần suất giao dịch cao với rủi ro có thể kiểm soát mang lại các yếu tố lợi nhuận cao.

  6. Các thông số tùy chỉnh để tối ưu hóa trên các sản phẩm và thị trường.

  7. Logic rõ ràng và mã ngắn gọn cho giao dịch trực tiếp dễ dàng.

  8. Dữ liệu backtest đủ đảm bảo độ tin cậy.

Rủi ro

Những rủi ro chính là:

  1. Khả năng tín hiệu MACD sai cần được xác minh với các chỉ số khác.

  2. Các điểm dừng quá chặt có thể bị dừng lại bởi các động thái biến động.

  3. Tăng tần suất giao dịch đòi hỏi phải kiểm soát việc sử dụng vốn.

  4. Các mục sửa lỗi có thể gây ra tổn thất trong quá trình rút lại.

  5. Tối ưu hóa cần thiết cho các sản phẩm và thị trường khác nhau.

  6. Yêu cầu kiểm tra và tối ưu hóa liên tục.

  7. Chi phí trượt cần được xem xét cho giao dịch trực tiếp.

Các biện pháp quản lý rủi ro bao gồm sử dụng dừng để hạn chế tổn thất, đánh giá việc sử dụng vốn, tối ưu hóa các thông số cho mỗi sản phẩm thông qua backtesting, theo dõi động lực thị trường để tinh chỉnh các thông số và tính toán sự trượt trong các thử nghiệm.

Cơ hội gia tăng

Cơ hội cải thiện:

  1. Thêm các chỉ số khác để xác minh tín hiệu, ví dụ: KDJ.

  2. Thực hiện dừng động thích nghi.

  3. Tối ưu hóa logic nhập lại và sửa lỗi.

  4. Tối ưu hóa tham số cho mỗi sản phẩm.

  5. Tối ưu hóa việc sử dụng vốn cho các mục nhập.

  6. Bao gồm các chỉ số khối lượng để tránh tổn thất từ các mục rút lại.

  7. Thêm các cơ chế thoát như dừng di chuyển.

  8. Xây dựng robot giao dịch tự động.

  9. Hãy tính đến các yếu tố thực tế như trượt.

Chúng có thể cải thiện hơn nữa tính ổn định, khả năng thích nghi, tự động hóa và hiệu suất trực tiếp.

Kết luận

Chiến lược này tích hợp các tín hiệu MACD, phân tích giá đóng cửa và nhiều cơ chế nhập để tối đa hóa xu hướng trong khi kiểm soát rủi ro. Nó có hiệu quả vốn cao và dễ thực hiện nhưng đòi hỏi kiểm soát rủi ro và tối ưu hóa. Tự động hóa có thể làm cho nó trở thành một hệ thống giao dịch định lượng mạnh mẽ.


/*backtest
start: 2023-09-29 00:00:00
end: 2023-10-29 00:00:00
period: 2h
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/
// © Puckapao

//@version=4
// strategy(title="MACD", shorttitle="MACD", overlay=true, initial_capital=10000.00, currency="USD", default_qty_type=strategy.cash, default_qty_value=10000.00)
// Getting inputs
reenter_delay = input(title="Re-enter Delay", type=input.integer, defval=2)
sculp_delay = input(title="Sculp Delay", type=input.integer, defval=4)
fast_length = input(title="Fast Length", type=input.integer, defval=12)
slow_length = input(title="Slow Length", type=input.integer, defval=26)
src = input(title="Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9)
sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=true)
ema_period = input(title="EMA Period", type=input.integer, defval=21)

// Get date
startDate = input(title="Start Date", type=input.integer,
     defval=19, minval=1, maxval=31)
startMonth = input(title="Start Month", type=input.integer,
     defval=09, minval=1, maxval=12)
startYear = input(title="Start Year", type=input.integer,
     defval=2017, minval=1800, maxval=2100)

endDate = input(title="End Date", type=input.integer,
     defval=31, minval=1, maxval=31)
endMonth = input(title="End Month", type=input.integer,
     defval=3, minval=1, maxval=12)
endYear = input(title="End Year", type=input.integer,
     defval=2021, minval=1800, maxval=2100)
     
// STEP 2:
// Look if the close time of the current bar
// falls inside the date range
inDateRange =  true

reenter_cnt = 0
reenter_cnt := nz(reenter_cnt[1])

sculp_cnt = 0
sculp_cnt := nz(sculp_cnt[1])

close_cnt = 0
close_cnt := nz(close_cnt[1])

on_long = false
on_long := nz(on_long[1])

on_short = false
on_short := nz(on_short[1])

sculp = false
reenter = false
slowdown = false

ema = ema(close, ema_period)

// Plot colors
col_grow_above = #26A69A
col_grow_below = #FFCDD2
col_fall_above = #B2DFDB
col_fall_below = #EF5350
col_macd = #0094ff
col_signal = #ff6a00
// Calculating
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
hist = macd - signal
// plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below) ), transp=0 )
// plot(macd, title="MACD", color=col_macd, transp=0)
// plot(signal, title="Signal", color=col_signal, transp=0)

cross_up = crossover(macd, signal)
cross_down = crossunder(macd, signal)

if (inDateRange)

    over_macd = macd > 0 and signal > 0 ? true : false
    under_macd = macd < 0 and signal < 0 ? true : false
    over_water = close > ema ? true : false
    under_water = close < ema ? true : false
    slowdown := hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] > hist ? false : true)
    reenter := hist >= 0 ? (hist[1] < hist ? true : false) : (hist[1] > hist ? true : false)
    sculp := (hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] < hist ? true : false))
    
    if(reenter == true)
        if(reenter_cnt < reenter_delay)
            reenter_cnt := reenter_cnt + 1
    else
        if(reenter_cnt > 0)
            reenter_cnt := reenter_cnt - 1
                    
    if(sculp == true)
        if(sculp_cnt < sculp_delay)
            sculp_cnt := sculp_cnt + 1
    else
        if(sculp_cnt > 0)
            sculp_cnt := sculp_cnt - 1
        
    if(slowdown == false)
        if(close_cnt < 2)
            close_cnt := close_cnt + 1
        else
            close_cnt := 0
    
    // plotchar(fork_cnt, "fork count", "")
    // plotchar(spoon_cnt, "spoon count", "")

    // Entry
    if (cross_up == true)
        strategy.entry("long", strategy.long, comment = "long", alert_message = "long")
        on_long := true
        on_short := false
    if (cross_down == true)
        strategy.entry("short", strategy.short, comment = "short", alert_message = "short")
        on_short := true
        on_long := false
        
    // Sculp bottom / top
    if (sculp == true and sculp_cnt >= sculp_delay)
        if (hist >= 0)
            strategy.entry("sculp-short", strategy.short, comment = "sculp-short", alert_message = "sculp-short")
        else
            strategy.entry("sculp-long", strategy.long, comment = "sculp-long", alert_message = "sculp-long")
        
        sculp_cnt := 0
        sculp := false
            
    // Re-Entry
    if (reenter == true and reenter_cnt >= reenter_delay)
        if (hist >= 0)
            strategy.entry("re-long", strategy.long, comment = "re-long", alert_message = "re-long")
        else
            strategy.entry("re-short", strategy.short, comment = "re-short", alert_message = "re-short")
            
        reenter_cnt := 0
        reenter := false
            
    // Close
    strategy.close("long", when = slowdown, comment = "close long", alert_message = "close long")
    strategy.close("short", when = slowdown, comment = "close short", alert_message = "close short")
    strategy.close("re-long", when = slowdown, comment = "close re-long", alert_message = "close re-long")
    strategy.close("re-short", when = slowdown, comment = "close re-short", alert_message = "close re-short")
    strategy.close("sculp-long", when = slowdown, comment = "close sculp-long", alert_message = "close sculp-long")
    strategy.close("sculp-short", when = slowdown, comment = "close sculp-short", alert_message = "close sculp-short")
    
    if (slowdown)
        if (hist >= 0)
            on_long := false
        else
            on_short := false


plotchar(slowdown, "close", "")
plotchar(reenter, "reenter", "")
plotchar(reenter_cnt, "reenter count", "")
plotchar(sculp, "sculp", "")
plotchar(sculp_cnt, "sculp count", "")

Thêm nữa