Kênh giá năng động với chiến lược theo dõi dừng lỗ

Tác giả:ChaoZhang, Ngày: 2024-02-01 10:52:33
Tags:

img

Tổng quan

Chiến lược này được phát triển dựa trên chỉ số kênh giá Donchian. Chỉ số tạo thành một kênh giá bằng cách tính toán giá cao nhất và thấp nhất trong một khoảng thời gian nhất định. Chiến lược sử dụng kênh giá để thực hiện giao dịch hai chiều và thiết lập giá dừng lỗ và lấy lợi nhuận. Giá dừng lỗ được cố định ở đường giữa của kênh giá, và giá lấy lợi nhuận được thiết lập ở một tỷ lệ phần trăm nhất định vượt quá giới hạn trên và dưới của kênh giá. Chiến lược cũng thực hiện theo dõi dừng lỗ và lấy lợi nhuận.

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

Đầu tiên, chiến lược tính toán giới hạn trên h và giới hạn dưới l của kênh giá dựa trên tham số pclen. Trung tâm đường giữa là mức trung bình của giới hạn trên và dưới của kênh giá. Sau đó, giá lợi nhuận lấy tpl và tps được tính theo các tham số lấy lợi nhuận tp cho các vị trí dài và ngắn. Giá dừng lỗ được cố định ở trung tâm đường giữa của kênh giá. Khi giá vượt qua kênh giá, các vị trí giao dịch theo các hướng khác nhau được tính toán theo kích thước rủi ro, các vị trí rủi ro dài và ngắn. Chiến lược sẽ đóng khi giá quay lại kênh. Ngoài ra, lọc thời gian được thiết lập để chỉ giao dịch trong phạm vi ngày đã chỉ định.

Logic giao dịch cụ thể là:

Tín hiệu đầu vào dài: mở dài khi giá lớn hơn giới hạn trên kênh h và giảm trở lại kênh

Tín hiệu thoát dài: đóng dài khi giá thấp hơn trung tâm đường giữa kênh (đừng lỗ) hoặc cao hơn giá lấy lợi nhuận tpl (lấy lợi nhuận)

Tín hiệu nhập ngắn: mở ngắn khi giá thấp hơn giới hạn dưới kênh l và rơi trở lại kênh

Tín hiệu thoát ngắn: đóng ngắn khi giá cao hơn trung tâm đường giữa kênh (đừng lỗ) hoặc thấp hơn giá lấy lợi nhuận tps (lấy lợi nhuận)

Phân tích lợi thế

Những lợi thế của chiến lược này là:

  1. Giao dịch hai chiều có thể nắm bắt sự đảo ngược của xu hướng giá
  2. Sử dụng kênh giá để xác định hướng xu hướng và tránh phá vỡ sai
  3. Thiết lập dừng lỗ và lấy lợi nhuận để kiểm soát rủi ro
  4. Tính toán kích thước vị trí liên quan đến kích thước rủi ro để đạt được rủi ro có thể kiểm soát được
  5. Thực hiện theo dõi dừng lỗ và lấy lợi nhuận để khóa thêm lợi nhuận

Phân tích rủi ro

Có một số rủi ro trong chiến lược này:

  1. Cài đặt tham số không chính xác của kênh giá có thể dẫn đến tần suất giao dịch quá cao hoặc bỏ lỡ các cơ hội giao dịch
  2. Giá dừng lỗ được đặt quá rộng có thể làm tăng rủi ro
  3. Theo dõi lợi nhuận có thể được kích hoạt sớm trong các giai đoạn biến động cao

Những rủi ro này có thể được giảm và kiểm soát bằng cách điều chỉnh các thông số và theo dõi bằng tay.

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

Chiến lược này cũng có thể được tối ưu hóa trong các khía cạnh sau:

  1. Thêm thêm các bộ lọc chỉ số để tránh mở và đóng cửa thường xuyên trong các thị trường giới hạn phạm vi
  2. Các thuật toán dừng lỗ và lấy lợi nhuận khác nhau có thể được thử nghiệm, chẳng hạn như ATR dừng lỗ
  3. Mở rộng sang một hệ thống giao dịch xuyên khung thời gian sử dụng khung thời gian cao hơn để xác định hướng xu hướng
  4. Thêm mô-đun định kích thước vị trí để điều chỉnh các vị trí dựa trên tỷ lệ sử dụng vốn
  5. Kết hợp các mô hình học máy để đánh giá tỷ lệ thành công của sự đột phá giá để tránh sự đột phá sai

Kết luận

Kết luận, đây là một chiến lược hiệu quả để thực hiện giao dịch hai chiều bằng cách sử dụng các chỉ số kênh giá. Với các mô-đun kiểm soát stop loss, take profit và kích thước vị trí thích hợp, rủi ro có thể được kiểm soát tốt. Với một số tối ưu hóa và điều chỉnh, nó có thể trở thành một chiến lược giao dịch định lượng mạnh mẽ.


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

//Noro
//2020

//@version=4
strategy(title = "Noro's RiskDonchian Strategy", shorttitle = "RiskDonchian str", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, commission_value = 0.1)

//Settings
needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
tp = input(defval = 20.0, minval = 1, title = "Take-profit, %")
tptype = input(defval = "2. Fix", options = ["1. None", "2. Fix", "3. Trailing"], title = "Take-profit type")
sltype = input(defval = "2. Center", options = ["1. None", "2. Center"], title = "Take-profit type")
risklong  = input(5.0, minval = 0.0, maxval = 99.9, title = "Risk size for long, %")
riskshort = input(5.0, minval = 0.0, maxval = 99.9, title = "Risk size for short, %")
pclen = input(50, minval = 1, title = "Price Channel Length")
showll = input(true, defval = true, title = "Show lines")
showbg = input(false, defval = false, title = "Show Background")
showof = input(true, defval = true, title = "Show Offset")
showlabel = input(true, defval = true, title = "Show label")
fromyear = input(1900, defval = 1900, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")

//Price Channel
h = highest(high, pclen)
l = lowest(low, pclen)
center = (h + l) / 2

//Take-profit
tpl = 0.0
tpl := tptype == "2. Fix" and strategy.position_size > 0 ? tpl[1] : h * (100 + tp) / 100

//Stop-loss
tps = 0.0
tps := tptype == "2. Fix" and strategy.position_size < 0 ? tps[1] : l * (100 - tp) / 100

//Lines
tplcol = showll and needlong and tptype != "1. None" ? color.lime : na
pclcol = showll and needlong ? color.blue : na
sllcol = showll and needlong and sltype != "1. None" ? color.red : na
tpscol = showll and needshort and tptype != "1. None" ? color.lime : na
pcscol = showll and needshort ? color.blue : na
slscol = showll and needshort and sltype != "1. None" ? color.red : na
offset = showof ? 1 : 0
plot(tpl, offset = offset, color = tplcol, title = "TP Long")
plot(h, offset = offset, color = pclcol, title = "Channel High")
plot(center, offset = offset, color = sllcol, title = "SL Long")
plot(center, offset = offset, color = slscol, title = "SL Short")
plot(l, offset = offset, color = pcscol, title = "Channel Low")
plot(tps, offset = offset, color = tpscol, title = "TP Short")

//Background
size = strategy.position_size
bgcol = showbg == false ? na : size > 0 ? color.lime : size < 0 ? color.red : na
bgcolor(bgcol, transp = 70)

//Lot size
risksizelong = -1 * risklong
risklonga = ((center / h) - 1) * 100
coeflong = abs(risksizelong / risklonga)
lotlong = (strategy.equity / close) * coeflong
risksizeshort = -1 * riskshort
riskshorta = ((center / l) - 1) * 100
coefshort = abs(risksizeshort / riskshorta)
lotshort = (strategy.equity / close) * coefshort

//Trading
truetime = time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)
mo = 0
mo := strategy.position_size != 0 ? 0 : high >= center[1] and low <= center[1] ? 1 : mo[1]

if h > 0
    longlimit = tptype == "1. None" ? na : tpl
    longstop = sltype == "1. None" ? na : center
    strategy.entry("Long", strategy.long, lotlong, stop = h, when = strategy.position_size <= 0 and needlong and truetime and mo)
    strategy.exit("TP Long", "Long", limit = longlimit, stop = longstop)
    shortlimit = tptype == "1. None" ? na : tps
    shortstop = sltype == "1. None" ? na : center
    strategy.entry("Short", strategy.short, lotshort, stop = l, when = strategy.position_size >= 0 and needshort and truetime and mo)
    strategy.exit("Exit Short", "Short", limit = shortlimit, stop = shortstop)
if time > timestamp(toyear, tomonth, today, 23, 59)
    strategy.close_all()
    strategy.cancel("Long")
    strategy.cancel("Short")
    
if showlabel

    //Drawdown
    max = 0.0
    max := max(strategy.equity, nz(max[1]))
    dd = (strategy.equity / max - 1) * 100
    min = 100.0
    min := min(dd, nz(min[1]))
    
    //Label
    min := round(min * 100) / 100
    labeltext = "Drawdown: " + tostring(min) + "%"
    var label la = na
    label.delete(la)
    tc = min > -100 ? color.white : color.red
    osx = timenow + round(change(time)*10)
    osy = highest(100)

Thêm nữa