Chiến lược dừng lỗ kéo dài nhiều khung thời gian

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

img

Tổng quan

Chiến lược này là một phiên bản nhiều khung thời gian của chiến lược dừng lỗ kéo dài đơn giản trước đây của tôi. Chiến lược trước đây chỉ sử dụng lỗ dừng kéo dài cơ bản để nhập các vị trí. Nó hoạt động khá tốt vì vậy tôi đã cố gắng cải thiện nó. Tôi nghĩ điều gì sẽ xảy ra nếu tôi sử dụng cùng một ATR dừng lỗ kéo dài trên các khung thời gian khác nhau và kết hợp chúng thành một tín hiệu.

Trong chiến lược này, bạn chỉ có thể sử dụng các điểm dừng ATR và chọn 3 khung thời gian cao hơn khác ngoài khung thời gian hiện tại của bạn. Mức dừng lỗ cuối cùng từ tất cả các khung thời gian này sẽ được vẽ trên biểu đồ. Nhập vị trí dài nếu tất cả 4 khung thời gian đồng ý về tín hiệu dài. Đóng vị trí dài khi ít nhất 2 khung thời gian không đồng ý về tín hiệu dài. Lý thuyết cho các vị trí ngắn là như nhau.

Chiến lược logic

Trọng tâm của chiến lược này nằm trong việc dừng lỗ và theo xu hướng. Lỗ lỗ dừng lại được sử dụng để thiết lập mức dừng lỗ dựa trên giá trị ATR, có thể ngăn chặn hiệu quả việc dừng lỗ bị tấn công.

Đặc biệt, chiến lược đầu tiên tính toán giá trị ATR trên các khung thời gian khác nhau và thiết lập khoảng cách dừng lỗ. Sau đó nó tạo ra các tín hiệu dài / ngắn khi giá vượt qua mức dừng lỗ. Nếu tín hiệu từ nhiều khung thời gian đồng ý, vị trí sẽ được nắm giữ. Sau đó, tiếp tục theo dõi mức dừng lỗ theo hướng xu hướng. Nếu tín hiệu từ một tỷ lệ phần trăm nhất định của khung thời gian đảo ngược, đóng vị trí.

Bằng cách kết hợp đánh giá xu hướng trong các giai đoạn khác nhau, các vụ phá vỡ giả có thể được lọc ra một cách hiệu quả.

Ưu điểm

  1. Sử dụng nhiều khung thời gian giúp lọc tiếng ồn và xác định hướng xu hướng
  2. ATR trailing stop điều chỉnh khoảng cách dừng lại một cách năng động, làm giảm khả năng bị dừng lại
  3. Kết hợp theo xu hướng và quản lý dừng lỗ, bạn có thể theo xu hướng và dừng lại trong thời gian
  4. Một số tham số, dễ hiểu và tối ưu hóa

Phân tích rủi ro

  1. ATR dừng có thể quá gần hoặc quá xa nếu các thông số không được thiết lập đúng cách, dễ bị va chạm hoặc dừng khoảng cách quá lớn
  2. Kết hợp nhiều khung thời gian có thể không hoạt động hiệu quả hoặc đánh giá sai nếu các thông số không được thiết lập đúng cách
  3. Cần phải cấu hình cả hai parameter stop loss và khung thời gian đúng cách, nếu không có thể không đạt được kết quả tốt nhất

Giải pháp:

  1. Kiểm tra các bộ tham số và sản phẩm khác nhau để tìm ra tối ưu
  2. Tối ưu hóa tỷ lệ và số khung thời gian để đảm bảo đánh giá xu hướng đáng tin cậy
  3. Điều chỉnh nhân ATR để cân bằng giữa không bị trúng và khoảng cách thích hợp

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

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

  1. Thêm / giảm số khung thời gian để tìm kết hợp tốt nhất để đánh giá xu hướng
  2. Kiểm tra các nhân ATR khác nhau để xác định khoảng cách dừng tối ưu
  3. Thêm cơ chế tái nhập để xây dựng thêm các vị trí khi xu hướng tiếp tục
  4. Tích hợp các bộ lọc khác trên tín hiệu đầu vào ví dụ như chỉ số âm lượng vv
  5. Điều chỉnh tham số cho các sản phẩm khác nhau

Kết luận

Chiến lược này kết hợp theo dõi xu hướng và kiểm soát rủi ro thông qua các điểm dừng ATR theo dõi nhiều khung thời gian. So với điểm dừng duy nhất, nó xác định hướng xu hướng rõ ràng hơn; so với khung thời gian duy nhất, nó lọc ra rất nhiều tiếng ồn. Cấu hình đúng trên các thông số dừng và khung thời gian là chìa khóa để đạt được kết quả tốt nhất. Nó phù hợp với các nhà đầu tư có thể dung nạp một số drawdowns nhất định và cung cấp lợi nhuận ổn định.


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

//@version=4
strategy(title="MTF Trailing SL Strategy [QuantNomad]", shorttitle = "MTF TrailingSL [QN]", overlay = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 100)

////////////
// Inputs //

atr_length = input(14,    title = "ATR Length")
atr_mult   = input(2,     title = "ATR Mult",    type = input.float)

tf2 = input('120', title = "TF2", type = input.string)
tf3 = input('180', title = "TF3", type = input.string)
tf4 = input('240', title = "TF4", type = input.string)

// BACKTESTING RANGE
// From Date Inputs
fromDay   = input(defval = 1,    title = "From Day",   minval = 1, maxval = 31)
fromMonth = input(defval = 1,    title = "From Month", minval = 1, maxval = 12)
fromYear  = input(defval = 2016, title = "From Year",  minval = 1970)
 
// To Date Inputs
toDay   = input(defval = 1,    title = "To Day",   minval = 1, maxval = 31)
toMonth = input(defval = 1,    title = "To Month", minval = 1, maxval = 12)
toYear  = input(defval = 2100, title = "To Year",  minval = 1970)
 
// Calculate start/end date and time condition
startDate  = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear,   toMonth,   toDay,   00, 00)

time_cond = time >= startDate and time <= finishDate

//////////////////
// CALCULATIONS //


tsl() => 
    // SL values
    sl_val = atr_mult * atr(atr_length)
     
    // Init Variables
    pos         = 0
    trailing_sl = 0.0
    
    // Signals
    long_signal  = nz(pos[1]) !=  1 and high > nz(trailing_sl[1])
    short_signal = nz(pos[1]) != -1 and low  < nz(trailing_sl[1]) 
    
    // Calculate SL
    trailing_sl := short_signal     ? high + sl_val : 
                   long_signal      ? low  - sl_val : 
                   nz(pos[1]) ==  1 ? max(low  - sl_val, nz(trailing_sl[1])) :  
                   nz(pos[1]) == -1 ? min(high + sl_val, nz(trailing_sl[1])) : 
                   nz(trailing_sl[1])
                   
    // Position var               
    pos := long_signal  ? 1 : short_signal ? -1 : nz(pos[1]) 
    trailing_sl
    
    
trailing_sl1 = tsl()
trailing_sl2 = security(syminfo.tickerid, tf2, tsl())
trailing_sl3 = security(syminfo.tickerid, tf3, tsl())
trailing_sl4 = security(syminfo.tickerid, tf4, tsl())

pos1 = 0
pos1 := low <= trailing_sl1 ? -1 : high >= trailing_sl1 ? 1 : nz(pos1[1])

pos2 = 0
pos2 := low <= trailing_sl2 ? -1 : high >= trailing_sl2 ? 1 : nz(pos2[1])

pos3 = 0
pos3 := low <= trailing_sl3 ? -1 : high >= trailing_sl3 ? 1 : nz(pos3[1])

pos4 = 0
pos4 := low <= trailing_sl4 ? -1 : high >= trailing_sl4 ? 1 : nz(pos4[1])

total_pos = pos1 + pos2 + pos3 + pos4

//////////////
// PLOTINGS //

plot(trailing_sl1, linewidth = 2 , color = pos1 == 1 ? color.green : color.red, title = "TSL TF1")
plot(trailing_sl2, linewidth = 2 , color = pos2 == 1 ? color.green : color.red, title = "TSL TF2", transp = 25)
plot(trailing_sl3, linewidth = 2 , color = pos3 == 1 ? color.green : color.red, title = "TSL TF3", transp = 50)
plot(trailing_sl4, linewidth = 2 , color = pos4 == 1 ? color.green : color.red, title = "TSL TF4", transp = 75)

//////////////
// STRATEGY //

//strategy.entry("long",  true,  stop = trailing_sl1)
//strategy.entry("short", false, stop = trailing_sl1)

strategy.entry("long",    true, when = total_pos ==  4)
strategy.entry("short",  false, when = total_pos == -4)

strategy.close("long",  when = total_pos <= 0)
strategy.close("short", when = total_pos >= 0)


Thêm nữa