Chiến lược Donchian Trend Following được phát triển dựa trên nguyên tắc kênh Donchian được mô tả trong bài viết
Chiến lược này dựa trên chỉ số kênh Donchian để đánh giá hướng xu hướng. Kênh Donchian bao gồm một kênh thời gian dài hơn và một kênh thời gian ngắn hơn. Khi giá vượt qua kênh thời gian dài hơn, nó báo hiệu sự bắt đầu của một xu hướng. Khi giá vượt qua kênh thời gian ngắn hơn, nó báo hiệu sự kết thúc của xu hướng.
Cụ thể, chiều dài kênh thời gian dài là 50 ngày hoặc 20 ngày, và chiều dài kênh thời gian ngắn là 50 ngày, 20 ngày hoặc 10 ngày. Nếu giá bằng giá cao nhất trong 50 ngày, một vị trí dài được mở. Nếu giá bằng giá thấp nhất trong 50 ngày, một vị trí ngắn được mở. Nếu giá bằng giá thấp nhất trong 20 hoặc 10 ngày, các vị trí dài được đóng. Nếu giá bằng giá cao nhất trong 20 hoặc 10 ngày, các vị trí ngắn được đóng.
Bằng cách kết hợp hai kênh Donchian của các giai đoạn khác nhau, nó có thể xác định hướng để thiết lập các vị trí khi xu hướng bắt đầu, và nhận ra dừng lỗ kịp thời khi xu hướng kết thúc.
Những lợi thế chính của chiến lược này là:
Khả năng nắm bắt xu hướng mạnh mẽ. Nó có thể theo dõi xu hướng hiệu quả bằng cách xác định sự khởi đầu và kết thúc của xu hướng bằng cách sử dụng sự đột phá của kênh Donchian.
Kiểm soát rủi ro thích hợp. Nó sử dụng một stop loss di chuyển để kiểm soát lỗ giao dịch duy nhất.
Điều chỉnh tham số linh hoạt. Sự kết hợp các khoảng thời gian kênh có thể được lựa chọn tự do để thích nghi với các sản phẩm và môi trường thị trường khác nhau.
Logic giao dịch đơn giản và rõ ràng. Nó dễ hiểu và thực hiện.
Những rủi ro của chiến lược này bao gồm:
Không thể thích nghi với thị trường giới hạn phạm vi. Nó sẽ bị tổn thất dừng liên tục nhỏ khi xu hướng không rõ ràng.
Nguy cơ thất bại đột phá. Giá có thể giảm sau khi phá vỡ kênh, gây ra dừng lỗ.
Rủi ro lựa chọn thời gian: Cài đặt thời gian kênh không phù hợp có thể dẫn đến giao dịch tiếng ồn.
Rủi ro giảm tỷ lệ Sharpe: Tăng kích thước vị trí mà không điều chỉnh stop loss có thể dẫn đến giảm tỷ lệ Sharpe.
Các giải pháp là:
Các hướng tối ưu hóa cho chiến lược này:
Thêm các điều kiện bộ lọc để tránh chém, ví dụ: kết hợp âm lượng để đánh giá sự đột phá thực sự.
Tối ưu hóa sự kết hợp khoảng thời gian kênh và kích thước vị trí để tăng tỷ lệ lợi nhuận.
Cố gắng tối ưu hóa điểm ngắt để tìm các tập hợp tham số tối ưu.
Tăng các thuật toán học máy để tối ưu hóa và điều chỉnh các thông số năng động.
Chiến lược theo xu hướng Donchian xác định sự bắt đầu và kết thúc của xu hướng giá bằng cách sử dụng hai kênh, và áp dụng phong cách giao dịch theo xu hướng với kiểm soát lỗ giao dịch duy nhất hiệu quả. Chiến lược này có điều chỉnh tham số linh hoạt và dễ thực hiện, làm cho chính nó trở thành một chiến lược theo xu hướng rất thực tế.
/*backtest start: 2023-12-01 00:00:00 end: 2023-12-31 23:59:59 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy(title="Donchian", overlay=true, pyramiding=0, initial_capital=1000, commission_type=strategy.commission.cash_per_order, commission_value=2, slippage=2) // ============================================================================= // VARIABLES // ============================================================================= donch_string = input.string(title="Length", options = ['20/10','50/20', '50/50', '20/20', '100/100'], defval='50/50') permit_long = input.bool(title = 'Permit long', defval = true) permit_short = input.bool(title = 'Permit short', defval = true) risk_percent = input.float(title="Position Risk %", defval=0.5, step=0.25) stopOffset = input.float(title="ATR mult", defval=2.0, step=0.5) atrLen = input.int(title="ATR Length", defval=20) close_in_end = input.bool(title = 'Close in end', defval = true) permit_stop = input.bool(title = 'Permit stop', defval = false) // ============================================================================= // CALCULATIONS // ============================================================================= donch_len_big = donch_string == '50/20' ? 50 : donch_string == '50/50' ? 50 : donch_string == '20/20' ? 20 : donch_string == '20/10' ? 20 : donch_string == '100/100' ? 100 : na donch_len_small = donch_string == '50/20' ? 20 : donch_string == '50/50' ? 50 : donch_string == '20/20' ? 20 : donch_string == '20/10' ? 10 : donch_string == '100/100' ? 100 : na big_maxclose = ta.highest(close, donch_len_big) big_minclose = ta.lowest(close, donch_len_big) small_maxclose = ta.highest(close, donch_len_small) small_minclose = ta.lowest(close, donch_len_small) atrValue = ta.atr(atrLen)[1] tradeWindow = true // ============================================================================= // NOTOPEN QTY // ============================================================================= risk_usd = (risk_percent / 100) * strategy.equity atr_currency = (atrValue * syminfo.pointvalue) notopen_qty = risk_usd / (stopOffset * atr_currency) // ============================================================================= // LONG STOP // ============================================================================= long_stop_price = 0.0 long_stop_price := strategy.position_size > 0 and na(long_stop_price[1]) ? strategy.position_avg_price - stopOffset * atrValue : strategy.position_size > 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price: strategy.position_size > 0 ? long_stop_price[1] : na // ============================================================================= // SHORT STOP // ============================================================================= short_stop_price = 0.0 short_stop_price := strategy.position_size < 0 and na(short_stop_price[1]) ? strategy.position_avg_price + stopOffset * atrValue : strategy.position_size < 0 and strategy.openprofit > risk_usd ? strategy.position_avg_price : strategy.position_size < 0 ? short_stop_price[1] : na // ============================================================================= // PLOT VERTICAL COLOR BAR // ============================================================================= cross_up = strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long cross_dn = strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short bg_color = cross_up ? color.green : cross_dn ? color.red : na bg_color := color.new(bg_color, 70) bgcolor(bg_color) // ============================================================================= // PLOT DONCHIAN LINES // ============================================================================= s1 = cross_up ? na : cross_dn ? na : strategy.position_size != 0 ? strategy.position_avg_price : na s2 = cross_up ? na : cross_dn ? na : strategy.position_size > 0 ? small_minclose : strategy.position_size < 0 ? small_maxclose : na s3 = cross_up ? na : cross_dn ? na : not permit_stop ? na : strategy.position_size > 0 ? long_stop_price : strategy.position_size < 0 ? short_stop_price : na plot(series=big_maxclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Maxclose Black") plot(series=big_minclose, style=plot.style_linebr, color=color.black, linewidth=1, title="Donch Big Minclose Black") plot(series=s1, style=plot.style_linebr, color=color.yellow, linewidth=2, title="Entry Yellow") plot(series=s2, style=plot.style_linebr, color=color.red, linewidth=1, title="Donch Small Red") plot(series=s3, style=plot.style_linebr, color=color.fuchsia, linewidth=2, title="Stop Fuchsia") // ============================================================================= // ENTRY ORDERS // ============================================================================= if strategy.position_size <= 0 and close == big_maxclose and close >= syminfo.mintick and tradeWindow and permit_long strategy.entry("Long", strategy.long, qty=notopen_qty) if strategy.position_size >= 0 and close == big_minclose and close >= syminfo.mintick and tradeWindow and permit_short strategy.entry("Short", strategy.short, qty=notopen_qty) // ============================================================================= // EXIT ORDERS // ============================================================================= if strategy.position_size > 0 and permit_stop strategy.exit(id="Stop", from_entry="Long", stop=long_stop_price) if strategy.position_size < 0 and permit_stop strategy.exit(id="Stop", from_entry="Short", stop=short_stop_price) // ========== if strategy.position_size > 0 and close == small_minclose and not barstate.islast strategy.close(id="Long", comment='Donch') if strategy.position_size < 0 and close == small_maxclose and not barstate.islast strategy.close(id="Short", comment='Donch') // ========== if close_in_end if not tradeWindow strategy.close_all(comment='Close in end') // ============================================================================= // END // =============================================================================