Chiến lược theo dõi xu hướng Doniphan là chiến lược theo dõi xu hướng được phát triển dựa trên nguyên tắc kênh Doniphan được mô tả trong bài viết Black Box Trend Following Lifting the Veil . Chiến lược này sử dụng kênh Doniphan để xác định xu hướng giá, để tạo thêm hoặc làm trống vị trí tùy thuộc vào giá sáng tạo cao hoặc sáng tạo thấp.
Chiến lược dựa trên chỉ số kênh Doniphan để đánh giá xu hướng. Các kênh Doniphan bao gồm một kênh có chu kỳ dài hơn và một kênh có chu kỳ ngắn hơn.
Cụ thể, độ dài của các kênh chu kỳ dài hơn là 50 ngày hoặc 20 ngày, và độ dài của các kênh chu kỳ ngắn hơ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, hãy mở đơn; Nếu giá bằng giá thấp nhất trong 50 ngày, hãy mở đơn trống. Nếu giá bằng giá thấp nhất trong 20 ngày hoặc 10 ngày, hãy xóa nhiều đơn; Nếu giá bằng giá cao nhất trong 20 ngày hoặc 10 ngày, hãy xóa đơn trống.
Bằng cách này, thông qua sự kết hợp của hai kênh Dony khác nhau, bạn có thể xác định hướng đặt hàng khi xu hướng bắt đầu và dừng lỗ khi xu hướng kết thúc.
Chiến lược này có những lợi thế chính như sau:
Khả năng nắm bắt xu hướng mạnh mẽ. Bằng cách phá vỡ các kênh Donya để xác định xu hướng bắt đầu và kết thúc, có thể theo dõi xu hướng hiệu quả.
Kiểm soát rủi ro. Sử dụng dừng di chuyển để kiểm soát tổn thất đơn lẻ.
Các tham số được điều chỉnh linh hoạt. Có thể tự do lựa chọn kết hợp chu kỳ của kênh, phù hợp với các giống khác nhau và môi trường thị trường.
Logic giao dịch đơn giản và rõ ràng. Dễ hiểu và dễ thực hiện.
Chiến lược này cũng có những rủi ro sau:
Không thể thích nghi với thị trường chấn động. Khi xu hướng không rõ ràng, sẽ có nhiều lần điều chỉnh nhỏ, dẫn đến tổn thất dừng.
Rủi ro phá vỡ thất bại. Giá có thể quay trở lại sau khi phá vỡ kênh, gây ra lỗ dừng.
Rủi ro chọn chu kỳ. Nếu chu kỳ kênh được thiết lập không đúng cách, sẽ dẫn đến trading in noise.
Rủi ro giảm tỷ lệ Sharpe. Nếu tăng vị trí mà không điều chỉnh mức dừng lỗ, sẽ có nguy cơ giảm tỷ lệ Sharpe.
Giải pháp tương ứng:
Chiến lược này có thể được tối ưu hóa theo các hướng sau:
Thêm các điều kiện lọc, tránh các whipsaws. Các chỉ số kết hợp, ví dụ, để xác định sự đột phá thực sự.
Tối ưu hóa kết hợp và kiểm soát vị trí của chu kỳ kênh, cải thiện tỷ lệ thua lỗ. Có thể giới thiệu cơ chế dừng lỗ thích ứng.
Cố gắng tối ưu hóa điểm dừng để tìm ra sự kết hợp tốt nhất.
Thêm các thuật toán học máy để tối ưu hóa và điều chỉnh động của tham số.
Chiến lược theo dõi xu hướng Doniphan là một chiến lược theo dõi xu hướng rất thực tế. Tuy nhiên, cũng cần lưu ý đến khả năng lợi nhuận kém trong điều kiện xung đột và rủi ro do lựa chọn tham số. Bằng cách tối ưu hóa hơn nữa, có thể có hiệu quả chiến lược tốt hơn.
/*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
// =============================================================================