Chiến lược giao dịch tối ưu hóa kép MACD

Tác giả:ChaoZhang, Ngày: 2024-01-22 11:10:10
Tags:

img

II. Tổng quan chiến lược

Chiến lược này sử dụng chỉ số MACD và các nguyên tắc chéo trung bình động để xây dựng các tín hiệu giao dịch. Ưu điểm của nó là nó có thể tối ưu hóa các thông số của MACD riêng biệt cho các hướng dài và ngắn, để các thông số có thể được cấu hình tối ưu cho các hướng thị trường khác nhau.

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

  1. Tính toán chỉ số MACD riêng biệt cho các hướng dài và ngắn. Một bộ tham số được sử dụng cho dài, và một bộ tham số khác được sử dụng cho ngắn, có thể được cấu hình tự do.

  2. Đánh giá các tín hiệu giao dịch được tạo ra bởi sự chéo chéo của đường MACD và đường tín hiệu. Tìm kiếm chéo chéo tăng cho dài và chéo chéo giảm cho ngắn.

  3. Bạn có thể cấu hình xem đường tín hiệu cũng cần phải vượt qua để kích hoạt tín hiệu, để tránh tín hiệu sai.

  4. Sau khi nhập vào vị trí dài hoặc ngắn, đóng vị trí khi xảy ra giao thoa ngược.

IV. Ưu điểm của Chiến lược

  1. Tối ưu hóa tham số hai chiều: các tham số cho dài và ngắn có thể được tối ưu hóa tự do để được cấu hình tối ưu cho các hướng thị trường riêng biệt.

  2. Đơn giản hóa tín hiệu có thể cấu hình: Các thông số tín hiệu có thể kiểm soát sự trơn tru của đường tín hiệu để lọc ra các tín hiệu giả.

  3. Bộ lọc tín hiệu có thể cấu hình: Có thể được cấu hình cho dù đường truyền tín hiệu cần phải kích hoạt để tránh tín hiệu sai.

  4. Điều khiển vị trí tinh chỉnh: Chỉ có thể kích hoạt dài hoặc ngắn riêng biệt, hoặc dài và ngắn có thể được thực hiện cùng một lúc.

V. Rủi ro của chiến lược

  1. MACD lag: Bản thân MACD có một số sự chậm trễ có thể bỏ lỡ sự đảo ngược nhanh chóng.

  2. Nguy cơ chuyển đổi giữa dài và ngắn: Thay đổi vị trí thường xuyên có thể xảy ra khi thị trường thay đổi nhanh chóng.

  3. Rủi ro tham số: Các cấu hình tham số không chính xác có thể không thể nắm bắt các đặc điểm của thị trường.

  4. Thiếu bảo vệ dừng lỗ: Đặt lỗ dừng hợp lý để kiểm soát lỗ duy nhất.

Phương pháp quản lý rủi ro:

  1. Kết hợp với các chỉ số khác để đánh giá bức tranh lớn và tránh theo đuổi mức cao và bán thấp.

  2. Đặt các thông số chậm tín hiệu và làm mịn để giảm tín hiệu lỗi.

  3. Thử nghiệm và tối ưu hóa các thông số nhiều lần để phù hợp với nhịp điệu của thị trường trong các chu kỳ khác nhau.

  4. Thiết lập cơ chế dừng lỗ và lấy lợi nhuận để kiểm soát lỗ đơn.

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

Một số cách chiến lược này có thể được tối ưu hóa thêm:

  1. Kiểm tra các kết hợp khác nhau của các thông số chiều dài đường dây nhanh và đường dây chậm để tìm các thông số tối ưu cho điều kiện thị trường trong các chu kỳ khác nhau.

  2. Kiểm tra các thông số đường tín hiệu khác nhau, đường tín hiệu mượt mà hơn có thể lọc ra nhiều tiếng ồn hơn.

  3. Kiểm tra sự khác biệt giữa bật và tắt bộ lọc chéo đường tín hiệu để tìm sự cân bằng tối ưu.

  4. Đặt tỷ lệ dừng lỗ tối ưu và lấy lợi nhuận dựa trên kết quả backtest.

  5. Hãy thử chỉ dài hoặc chỉ ngắn để xem liệu hiệu ứng chiến lược có thể được tối đa hóa hay không.

VII. Tóm tắt

Bằng cách cấu hình các tham số dài và ngắn riêng biệt, Chiến lược giao dịch tối ưu hóa hai lần MACD này nhận ra tối ưu hóa phù hợp với các hướng thị trường khác nhau và cho phép điều chỉnh tự do hướng tham gia. Đồng thời, các cơ chế lọc tín hiệu được giới thiệu để tránh các tín hiệu sai. Thông qua tối ưu hóa tham số và các biện pháp quản lý rủi ro, hiệu ứng chiến lược có thể được cải thiện hơn nữa.


/*backtest
start: 2023-01-15 00:00:00
end: 2024-01-21 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Gentleman-Goat & TradingTools.Software/Optimizer
strategy(title="MACD Short/Long Strategy for TradingView Input Optimizer", shorttitle="MACD Short/Long TVIO", initial_capital=1000, default_qty_value=100, default_qty_type=strategy.percent_of_equity)

// Get Inputs Long
allow_long                  = input.bool(title="Allow Long", defval=true, group="inputs long")
fast_length_long            = input.int(title="Fast Length Long", defval=13, group="inputs long")
slow_length_long            = input.int(title="Slow Length Long", defval=19, group="inputs long")
src_long                    = input.source(title="Source Long", defval=close, group="inputs long")
signal_length_long          = input.int(title="Signal Smoothing Long", minval = 1, maxval = 50, defval = 9, group="inputs long")
sma_source_long             = input.string(title="Oscillator MA Type Long", defval="EMA", options=["SMA", "EMA"], group="inputs long")
sma_signal_long             = input.string(title="Signal Line MA Type Long", defval="EMA", options=["SMA", "EMA"], group="inputs long")
cross_point_long            = input.int(title="Cross Point Long", defval=0, group="inputs long")
cross_delay_macd_long       = input.int(title="MacD Cross Delay Long", defval=0, group="inputs long")
signal_must_cross_long      = input.bool(title="Signal Must Also Cross Long", defval=false, group="inputs long")
cross_delay_signal_long     = input.int(title="Signal Cross Delay Long", defval=0, group="inputs long")

//Get Inputs Short
allow_short                 = input.bool(title="Allow Short", defval=true, group="inputs short")
fast_length_short           = input.int(title="Fast Length Short", defval=11, group="inputs short")
slow_length_short           = input.int(title="Slow Length Short", defval=20, group="inputs short")
src_short                   = input.source(title="Source Short", defval=close, group="inputs short")
signal_length_short         = input.int(title="Signal Smoothing Short", minval = 1, maxval = 50, defval = 9, group="inputs short")
sma_source_short            = input.string(title="Oscillator MA Type Short", defval="EMA", options=["SMA", "EMA"], group="inputs short")
sma_signal_short            = input.string(title="Signal Line MA Type Short", defval="EMA", options=["SMA", "EMA"], group="inputs short")
cross_point_short           = input.int(title="Cross Point Short", defval=0, group="inputs short")
cross_delay_macd_short      = input.int(title="MacD Cross Delay Short", defval=1, group="inputs short")
signal_must_cross_short     = input.bool(title="Signal Must Also Cross Short", defval=false, group="inputs short")
cross_delay_signal_short    = input.int(title="Signal Cross Delay Short", defval=0, group="inputs short")

use_stop_loss_long          = input.bool(defval=false,title="Use Stop Loss Long", group="Stop/Profit Long")
stop_loss_long_percentage   = input.float(defval=1,title="Stop Loss % Long",minval=0.0,step=0.1, group="Stop/Profit Long") * .01
use_take_profit_long        = input.bool(defval=false,title="Use Take Profit Long", group="Stop/Profit Long")
take_profit_long_percentage = input.float(defval=1,title="Take Profit % Long",minval=0.0,step=0.1, group="Stop/Profit Long") * .01
use_stop_loss_short         = input.bool(defval=true,title="Use Stop Loss Short", group="Stop/Profit Short")
stop_loss_short_percentage  = input.float(defval=21,title="Stop Loss % Short",minval=0.0,step=0.1, group="Stop/Profit Short") * .01
use_take_profit_short       = input.bool(defval=true,title="Use Take Profit Short", group="Stop/Profit Short")
take_profit_short_percentage= input.float(defval=20,title="Take Profit % Short",minval=0.0,step=0.1, group="Stop/Profit Short") * .01
//------------------------------------------------------------------------------

// Plot colors Long
col_macd_long        = input.color(#2962FF, "MACD Line Long", group="Color Settings", inline="MACD")
col_signal_long      = input.color(#FF6D00, "Signal Line Long", group="Color Settings", inline="Signal")
col_grow_above_long  = input.color(#26A69A, "Grow Above Long", group="Histogram Color Settings", inline="Above Long")
col_fall_above_long  = input.color(#B2DFDB, "Fall Above Long", group="Histogram Color Settings", inline="Above Long")
col_grow_below_long  = input.color(#FFCDD2, "Grow Below Long", group="Histogram Color Settings", inline="Below Long")
col_fall_below_long  = input.color(#FF5252, "Fall Below Long", group="Histogram Color Settings", inline="Below Long")

// Plot colors Short
col_macd_short        = input.color(#B03DFF, "MACD Line Short", group="Color Settings", inline="MACD")
col_signal_short      = input.color(#00FFE8, "Signal Line Short", group="Color Settings", inline="Signal")
col_grow_above_short  = input.color(#D95965, "Grow Above Short", group="Histogram Color Settings", inline="Above Short")
col_fall_above_short  = input.color(#4D2024, "Fall Above Short", group="Histogram Color Settings", inline="Above Short")
col_grow_below_short  = input.color(#00322D, "Grow Below Short", group="Histogram Color Settings", inline="Below Short")
col_fall_below_short  = input.color(#00ADAD, "Fall Below Short", group="Histogram Color Settings", inline="Below Short")

// Calculate Long
fast_ma_long = sma_source_long == "SMA" ? ta.sma(src_long, fast_length_long) : ta.ema(src_long, fast_length_long)
slow_ma_long = sma_source_long == "SMA" ? ta.sma(src_long, slow_length_long) : ta.ema(src_long, slow_length_long)
macd_long    = fast_ma_long - slow_ma_long
signal_long  = sma_signal_long == "SMA" ? ta.sma(macd_long, signal_length_long) : ta.ema(macd_long, signal_length_long)
hist_long    = macd_long - signal_long

// Calculate Short
fast_ma_short = sma_source_short == "SMA" ? ta.sma(src_short, fast_length_short) : ta.ema(src_short, fast_length_short)
slow_ma_short = sma_source_short == "SMA" ? ta.sma(src_short, slow_length_short) : ta.ema(src_short, slow_length_short)
macd_short    = fast_ma_short - slow_ma_short
signal_short  = sma_signal_short == "SMA" ? ta.sma(macd_short, signal_length_short) : ta.ema(macd_short, signal_length_short)
hist_short    = macd_short - signal_short

//Plot Long
plot(hist_long, title="Histogram Long", style=plot.style_columns, color=(hist_long>=0 ? (hist_long[1] < hist_long ? col_grow_above_long : col_fall_above_long) : (hist_long[1] < hist_long ? col_grow_below_long : col_fall_below_long)))
plot(macd_long, title="MACD Long", color=col_macd_long)
plot(signal_long, title="Signal Long", color=col_signal_long)

//Plot Short
plot(hist_short, title="Histogram Short", style=plot.style_columns, color=(hist_short>=0 ? (hist_short[1] < hist_short ? col_grow_above_short : col_fall_above_short) : (hist_short[1] < hist_short ? col_grow_below_short : col_fall_below_short)))
plot(macd_short, title="MACD Short", color=col_macd_short)
plot(signal_short, title="Signal Short", color=col_signal_short)

var detectedLongCrossOver = false
var detectedShortCrossUnder = false

if(ta.crossunder(macd_short,cross_point_short))
    detectedShortCrossUnder := true
if(ta.crossover(macd_short,cross_point_short))
    detectedShortCrossUnder := false
                
if(ta.crossover(macd_long,cross_point_long))
    detectedLongCrossOver := true
if(ta.crossunder(macd_long,cross_point_long))
    detectedLongCrossOver := false

crossover_signal_long = ta.crossover(signal_long,cross_point_long)
crossunder_signal_long = ta.crossunder(signal_long,cross_point_long)

crossunder_signal_short = ta.crossunder(signal_short,cross_point_short)
crossover_signal_short = ta.crossover(signal_short,cross_point_short)

crossover_macd_long = ta.crossover(macd_long,cross_point_long)
crossunder_macd_long = ta.crossunder(macd_long,cross_point_long)

crossunder_macd_short = ta.crossunder(macd_short,cross_point_short)
crossover_macd_short = ta.crossover(macd_short,cross_point_short)

inEntry = false
//Strategy Entries
if (strategy.equity > 0) //This is required for the input optimizer to work since it will fail if the strategy fails to succeed by not having enough equity.
    
    if (strategy.position_size <= 0 and allow_long==true and inEntry==false)
        if(signal_must_cross_long==true)
            longSignalCondition = detectedLongCrossOver==true and crossover_signal_long[cross_delay_signal_long]
            strategy.entry(id="long", direction=strategy.long, when=longSignalCondition)
            if(longSignalCondition)
                inEntry:=true
        else
            longMacDCondition = crossover_macd_long[cross_delay_macd_long]
            strategy.entry(id="long", direction=strategy.long, when=longMacDCondition)
            if(longMacDCondition)
                inEntry:=true
    if (strategy.position_size >= 0 and allow_short==true and inEntry==false)
        if(signal_must_cross_short==true)
            shortSignalCondition = detectedShortCrossUnder and crossunder_signal_short[cross_delay_signal_short]
            strategy.entry(id="short", direction=strategy.short, when=shortSignalCondition)
            if(shortSignalCondition)
                inEntry:=true
        else
            shortMacDCondition = crossunder_macd_short[cross_delay_macd_short]
            strategy.entry(id="short", direction=strategy.short, when=shortMacDCondition)
            if(shortMacDCondition)
                inEntry:=true
    if(strategy.position_size > 0 and allow_long==true and allow_short==false)
        if(signal_must_cross_long==true)
            strategy.close(id="long", when=detectedLongCrossOver==false and crossunder_signal_long)
        else
            strategy.close(id="long", when=crossunder_macd_long)
    if(strategy.position_size < 0 and allow_short==true and allow_long==false)
        if(signal_must_cross_short==true)
            strategy.close(id="short", when=detectedShortCrossUnder==false and crossover_signal_short)
        else
            strategy.close(id="short", when=crossover_macd_short)

stop_loss_value_long    = strategy.position_avg_price*(1 - stop_loss_long_percentage)
take_profit_value_long  = strategy.position_avg_price*(1 + take_profit_long_percentage)
stop_loss_value_short   = strategy.position_avg_price*(1 + stop_loss_short_percentage)
take_profit_value_short = strategy.position_avg_price*(1 - take_profit_short_percentage)

if(strategy.position_size>0) //Long positions only
    strategy.exit(id="TP/SL Long",from_entry="long", limit=use_take_profit_long ? take_profit_value_long : na, stop=use_stop_loss_long ? stop_loss_value_long : na)
if(strategy.position_size<0) //Short positions only
    strategy.exit(id="TP/SL Short",from_entry="short", limit=use_take_profit_short ? take_profit_value_short : na, stop=use_stop_loss_short ? stop_loss_value_short : na)

Thêm nữa