Chiến lược MACD - Giao dịch thoát đường hai chiều

Tác giả:ChaoZhang, Ngày: 2023-12-12 12:44:50
Tags:

img

Tổng quan

Chiến lược này sử dụng chỉ số Divergence Convergence Moving Average (MACD) để tạo ra các tín hiệu dài và ngắn và thực hiện các giao dịch đảo ngược trong điều kiện xu hướng tốt bằng cách thiết lập các điểm thoát động để nắm bắt lợi nhuận.

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

Cốt lõi của chiến lược này dựa trên đường chéo vàng MACD cho các tín hiệu dài và đường chéo chết cho các tín hiệu ngắn. Cụ thể, khi đường MACD vượt qua trên đường tín hiệu từ dưới, một đường chéo vàng được tạo thành một tín hiệu dài; khi đường MACD vượt qua dưới đường tín hiệu từ trên, một đường chéo chết được tạo thành một tín hiệu ngắn.

Trên các tín hiệu chéo vàng, hãy đi dài nếu giá đóng trên EMA; trên các tín hiệu chéo chết, hãy đi ngắn nếu giá đóng dưới EMA. Điều này đảm bảo các giao dịch đảo ngược dưới xu hướng tăng.

Sau khi nhập các vị trí, chiến lược sử dụng stop loss và take profit để điều khiển năng động các lối ra. Cụ thể, stop loss cho các vị trí dài được đặt ở mức giá nhập * (1 - max drawdown); take profit được đặt ở mức giá nhập * (1 + TARGET_STOP_RATIO * max drawdown). ngược lại cho các vị trí ngắn. Ở đây, max drawdown được tính năng động như tỷ lệ phần trăm giảm giá từ swing low đến close; TARGET_STOP_RATIO là mặc định là 2, có nghĩa là tỷ lệ rủi ro / phần thưởng là 2.

Ưu điểm của chiến lược dừng động này là nó có thể điều chỉnh mức dừng lỗ và tỷ lệ rủi ro / phần thưởng dựa trên biến động thị trường. Nó thoát nhanh với mức dừng lỗ chặt chẽ trong thời gian biến động cao trong khi theo dõi lợi nhuận với mức dừng lỏng trong môi trường biến động thấp.

Ưu điểm

  1. MACD là một chỉ số hiệu quả để xác định các cơ hội đảo ngược.

  2. Bộ lọc EMA đảm bảo giao dịch dài chỉ xảy ra trong một thị trường xu hướng tăng.

  3. Hệ thống kiểm soát thoát động tối đa hóa lợi nhuận trong khi quản lý rủi ro hiệu quả.

  4. Tốc độ tồn tại nhanh giảm thời gian giám sát cần thiết, làm cho nó phù hợp với các nhà đầu tư bận rộn.

Rủi ro và giải pháp

  1. MACD dao động thường xuyên trong các thị trường ngang, tạo ra các tín hiệu giả. Điều này được giải quyết bằng cách thêm bộ lọc EMA để tránh giao dịch ngược xu hướng.

  2. Sự biến động cực kỳ có thể khiến DYNAMIC STOP quá lỏng lẻo.

  3. Tỷ lệ lợi nhuận hạn chế cho mỗi giao dịch đòi hỏi giao dịch thường xuyên. Các nhà đầu tư cần một sự kiên trì tâm lý và cam kết thời gian nhất định. Có thể chuyển sang khung thời gian cao hơn nếu quá bận rộn.

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

  1. Điều chỉnh các thông số MACD dựa trên các đặc điểm của biểu tượng để tối ưu hóa chất lượng tín hiệu.

  2. Kiểm tra các đường trung bình động khác nhau như bộ lọc xu hướng để tìm ra đường tối ưu.

  3. Kiểm tra tính toán TARGET_STOP_RATIO và định nghĩa rút tiền tối đa để tối ưu hóa chiến lược thoát.

  4. Thêm các yếu tố khác như khối lượng, biến động vv để cải thiện chất lượng tín hiệu.

  5. Khám phá các mô hình học máy để chiết xuất nhiều tính năng hơn và xây dựng các mô hình đa yếu tố thích nghi cho lối ra thông minh hơn.

Kết luận

Chiến lược này có giá trị thực tế mạnh mẽ nói chung. Với MACD là tín hiệu giao dịch cốt lõi, các mô-đun bổ sung của bộ lọc xu hướng và điều khiển thoát động có thể cải thiện đáng kể hiệu suất của MACD. Kiểm soát thoát là điều cần thiết cho tối ưu hóa chiến lược và chiến lược này đổi mới đáng kể trong lĩnh vực này.


/*backtest
start: 2022-12-05 00:00:00
end: 2023-12-11 00:00:00
period: 1d
basePeriod: 1h
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/
// © maxencetajet

//@version=5
strategy("MACD Strategy", overlay=true, initial_capital=1000, slippage=25)

src = input(title="Source", defval=close)
target_stop_ratio = input.float(title='Risk/Reward', defval=2, minval=0.5, maxval=100)
risk = input.float(2, title="Risk per Trade %")

riskt = risk / 100 + 1

useDateFilter = input.bool(true, title="Filter Date Range of Backtest",
     group="Backtest Time Period")
backtestStartDate = input(timestamp("5 June 2022"), 
     title="Start Date", group="Backtest Time Period",
     tooltip="This start date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")
backtestEndDate = input(timestamp("5 July 2022"),
     title="End Date", group="Backtest Time Period",
     tooltip="This end date is in the time zone of the exchange " + 
     "where the chart's instrument trades. It doesn't use the time " + 
     "zone of the chart or of your computer.")

inTradeWindow =  true
emaV = input.int(200, title="Length", group="EMA")
swingHighV = input.int(7, title="Swing High", group="number of past candles")
swingLowV = input.int(7, title="Swing Low", group="number of past candles")

ema = ta.ema(src, emaV)

fast_length = input(title="Fast Length", defval=12, group="MACD")
slow_length = input(title="Slow Length", defval=26, group="MACD")
signal_length = input.int(title="Signal Smoothing",  minval = 1, maxval = 50, defval = 9, group="MACD")
sma_source = input.string(title="Oscillator MA Type",  defval="EMA", options=["SMA", "EMA"], group="MACD")
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group="MACD")

fast_ma = sma_source == "SMA" ? ta.sma(src, fast_length) : ta.ema(src, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src, slow_length) : ta.ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
hist = macd - signal

longcondition = close > ema and ta.crossover(macd, signal) and macd < 0
shortcondition = close < ema and ta.crossunder(macd, signal) and macd > 0

float risk_long = na
float risk_short = na
float stopLoss = na
float takeProfit = na
float entry_price = na

risk_long := risk_long[1]
risk_short := risk_short[1]

swingHigh = ta.highest(high, swingHighV)
swingLow = ta.lowest(low, swingLowV)

lotB = (strategy.equity*riskt-strategy.equity)/(close - swingLow)
lotS = (strategy.equity*riskt-strategy.equity)/(swingHigh - close)

if strategy.position_size == 0 and longcondition and inTradeWindow
    risk_long := (close - swingLow) / close
    strategy.entry("long", strategy.long, qty=lotB)
    
if strategy.position_size == 0 and shortcondition and inTradeWindow
    risk_short := (swingHigh - close) / close  
    strategy.entry("short", strategy.short, qty=lotS)

if strategy.position_size > 0

    stopLoss := strategy.position_avg_price * (1 - risk_long)
    takeProfit := strategy.position_avg_price * (1 + target_stop_ratio * risk_long)
    entry_price := strategy.position_avg_price
    strategy.exit("long exit", "long", stop = stopLoss, limit = takeProfit)
    
if strategy.position_size < 0

    stopLoss := strategy.position_avg_price * (1 + risk_short)
    takeProfit := strategy.position_avg_price * (1 - target_stop_ratio * risk_short)
    entry_price := strategy.position_avg_price
    strategy.exit("short exit", "short", stop = stopLoss, limit = takeProfit)
    
plot(ema, color=color.white, linewidth=2, title="EMA")
p_ep = plot(entry_price, color=color.new(color.white, 0), linewidth=2, style=plot.style_linebr, title='entry price')
p_sl = plot(stopLoss, color=color.new(color.red, 0), linewidth=2, style=plot.style_linebr, title='stopLoss')
p_tp = plot(takeProfit, color=color.new(color.green, 0), linewidth=2, style=plot.style_linebr, title='takeProfit')
fill(p_sl, p_ep, color.new(color.red, transp=85))
fill(p_tp, p_ep, color.new(color.green, transp=85))



Thêm nữa