Chiến lược dừng lỗ và lấy lợi nhuận động dựa trên ATR hai lần dừng lại

Tác giả:ChaoZhang, Ngày: 2024-03-22 13:52:59
Tags:

img

Tổng quan

Chiến lược này xây dựng hai đường stop-loss theo dõi động bằng cách sử dụng hai chỉ số Average True Range (ATR) với các khoảng thời gian khác nhau, tạo ra tín hiệu giao dịch khi giá vượt qua đường stop-loss. Nó cũng thiết lập mức lợi nhuận dựa trên chiều dài thân nến hiện tại để đạt được stop-loss và take-profit năng động. Chiến lược cũng kết hợp các chỉ số EMA để giúp đánh giá xu hướng.

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

  1. Tính toán các giá trị chỉ số ATR cho hai khoảng thời gian khác nhau (bên mặc định 10 và 20), sau đó nhân chúng với hệ số độ nhạy tương ứng của chúng (bên mặc định 1 và 2) để có được hai chiều rộng dừng lỗ.
  2. Tạo tín hiệu dài hoặc ngắn dựa trên vị trí giá trên hoặc dưới hai đường dừng lỗ và tình huống đột phá.
  3. Mức độ lợi nhuận được tính năng dựa trên 1,65 lần (có thể điều chỉnh) chiều dài thân nến hiện tại.
  4. Sau khi mở một vị trí, nếu giá đạt đến mức lấy lợi nhuận, vị trí được đóng để lấy lợi nhuận.
  5. Sử dụng các chỉ số như EMA để giúp đánh giá xu hướng hiện tại và cung cấp tham chiếu cho nhập cảnh.

Chiến lược này sử dụng các đặc điểm của chỉ số ATR để xây dựng hai stop-loss động, có thể thích nghi tốt với sự biến động thị trường khác nhau và nhanh chóng phản ứng với những thay đổi của thị trường.

Phân tích lợi thế

  1. Các đường dừng lỗ động kép có thể thích nghi với sự biến động thị trường khác nhau và có độ linh hoạt cao.
  2. Mức độ lợi nhuận được tính toán năng động dựa trên chiều dài thân nến hiện tại, cho phép thu được nhiều lợi nhuận hơn trong các thị trường xu hướng.
  3. Việc sử dụng EMA và các chỉ số khác để hỗ trợ đánh giá xu hướng cung cấp một tham chiếu cho nhập cảnh và tăng độ tin cậy của chiến lược.
  4. Logic mã là rõ ràng và dễ đọc, làm cho nó dễ hiểu và tối ưu hóa.

Phân tích rủi ro

  1. Trong các thị trường giới hạn phạm vi, giao dịch thường xuyên có thể dẫn đến chi phí giao dịch cao và ảnh hưởng đến lợi nhuận.
  2. Các thiết lập các tham số đường dừng lỗ và nhân lợi nhuận cần được tối ưu hóa theo các đặc điểm thị trường và sản phẩm khác nhau; các tham số không phù hợp có thể dẫn đến hiệu suất chiến lược kém.
  3. Chiến lược chủ yếu dựa trên sự đột phá giá của các đường dừng lỗ năng động để tạo ra các tín hiệu, có thể tạo ra các tín hiệu sai trong một số sự biến động giả mạo lớn.

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

  1. Đối với các thị trường giới hạn phạm vi, hãy xem xét giới thiệu thêm các chỉ số hoặc điều kiện để lọc các tín hiệu giao dịch, chẳng hạn như RSI và MACD.
  2. Đối với các sản phẩm và thị trường khác nhau, kiểm tra ngược lịch sử và tối ưu hóa tham số có thể được sử dụng để tìm các tham số đường dừng lỗ tối ưu và nhân lợi nhuận.
  3. Xem xét việc đưa ra các mô-đun quản lý vị trí và kiểm soát rủi ro để điều chỉnh kích thước vị trí theo cách năng động dựa trên biến động thị trường và rủi ro tài khoản.
  4. Thêm nhiều chỉ số đánh giá xu hướng để cải thiện độ tin cậy và độ chính xác của tín hiệu.

Tóm lại

Chiến lược này, với thiết kế hai đường dừng lỗ động và lợi nhuận động, có thể thích nghi tốt với các môi trường thị trường khác nhau và hoạt động tốt trong các thị trường xu hướng. Tuy nhiên, trong các thị trường giới hạn phạm vi, nó có thể phải đối mặt với vấn đề giao dịch thường xuyên và bù trừ lợi nhuận và lỗ. Do đó, chiến lược này phù hợp hơn để sử dụng trong các thị trường xu hướng và cần được tối ưu hóa và điều chỉnh dựa trên các đặc điểm của sản phẩm và điều kiện thị trường. Hơn nữa, vẫn còn chỗ cho việc tối ưu hóa hơn nữa, chẳng hạn như giới thiệu nhiều điều kiện lọc hơn, quản lý vị trí và các mô-đun kiểm soát rủi ro để cải thiện độ bền và lợi nhuận của chiến lược. Nhìn chung, chiến lược có ý tưởng rõ ràng, logic đơn giản và dễ hiểu, và có giá trị thực tế nhất định và không gian tối ưu hóa, xứng đáng nghiên cứu và áp dụng thêm.


/*backtest
start: 2024-02-01 00:00:00
end: 2024-02-29 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="UT Bot Strategy", overlay=true)

// Inputs
a1 = input(1, title="Key Value 1 ('This changes the sensitivity')")
c1 = input(10, title="ATR Period 1")
a2 = input(2, title="Key Value 2 ('This changes the sensitivity')")
c2 = input(20, title="ATR Period 2")
h = input(false, title="Signals from Heikin Ashi Candles")

////////////////////////////////////////////////////////////////////////////////
// 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=2019, 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
 
////////////////////////////////////////////////////////////////////////////////

xATR1 = atr(c1)
nLoss1 = a1 * xATR1
xATR2 = atr(c2)
nLoss2 = a2 * xATR2

src = h ? security(heikinashi(syminfo.tickerid), timeframe.period, close, lookahead=false) : close

xATRTrailingStop1 = 0.0
xATRTrailingStop1 := iff(src > nz(xATRTrailingStop1[1], 0) and src[1] > nz(xATRTrailingStop1[1], 0), max(nz(xATRTrailingStop1[1]), src - nLoss1),
   iff(src < nz(xATRTrailingStop1[1], 0) and src[1] < nz(xATRTrailingStop1[1], 0), min(nz(xATRTrailingStop1[1]), src + nLoss1), 
   iff(src > nz(xATRTrailingStop1[1], 0), src - nLoss1, src + nLoss1)))

xATRTrailingStop2 = 0.0
xATRTrailingStop2 := iff(src > nz(xATRTrailingStop2[1], 0) and src[1] > nz(xATRTrailingStop2[1], 0), max(nz(xATRTrailingStop2[1]), src - nLoss2),
   iff(src < nz(xATRTrailingStop2[1], 0) and src[1] < nz(xATRTrailingStop2[1], 0), min(nz(xATRTrailingStop2[1]), src + nLoss2), 
   iff(src > nz(xATRTrailingStop2[1], 0), src - nLoss2, src + nLoss2)))
 
pos = 0   
pos := iff(src[1] < nz(xATRTrailingStop1[1], 0) and src > nz(xATRTrailingStop1[1], 0), 1,
   iff(src[1] > nz(xATRTrailingStop1[1], 0) and src < nz(xATRTrailingStop1[1], 0), -1, nz(pos[1], 0))) 
   
xcolor = pos == -1 ? color.red: pos == 1 ? color.green : color.blue 

ema1 = ema(src, 1)
above1 = crossover(ema1, xATRTrailingStop1)
below1 = crossover(xATRTrailingStop1, ema1)
buy1 = src > xATRTrailingStop1 and above1 
sell1 = src < xATRTrailingStop1 and below1
barbuy1 = src > xATRTrailingStop1 
barsell1 = src < xATRTrailingStop1 

ema2 = ema(src, 1)
above2 = crossover(ema2, xATRTrailingStop2)
below2 = crossover(xATRTrailingStop2, ema2)
buy2 = src > xATRTrailingStop2 and above2 
sell2 = src < xATRTrailingStop2 and below2
barbuy2 = src > xATRTrailingStop2 
barsell2 = src < xATRTrailingStop2 

plotshape(buy1,  title="Buy 1",  text='Buy 1',  style=shape.labelup,   location=location.belowbar, color=color.green, textcolor=color.white, transp=0, size=size.tiny)
plotshape(sell1, title="Sell 1", text='Sell 1', style=shape.labeldown, location=location.abovebar, color=color.red,   textcolor=color.white, transp=0, size=size.tiny)
plotshape(buy2,  title="Buy 2",  text='Buy 2',  style=shape.labelup,   location=location.belowbar, color=color.green, textcolor=color.white, transp=0, size=size.tiny)
plotshape(sell2, title="Sell 2", text='Sell 2', style=shape.labeldown, location=location.abovebar, color=color.red,   textcolor=color.white, transp=0, size=size.tiny)

barcolor(barbuy1  ? color.green : na)
barcolor(barsell1 ? color.red   : na)
barcolor(barbuy2  ? color.green : na)
barcolor(barsell2 ? color.red   : na)

// Calculate SL and TP levels
candle_size = abs(open - close)
tp_level = close + candle_size *65

// Close long positions if TP is hit
strategy.exit("TP Long", "long", limit=tp_level)

// Close short positions if TP is hit
strategy.exit("TP Short", "short", limit=tp_level)

// Enter long position
strategy.entry("long", strategy.long, when=(buy1 or buy2) and time_cond)

// Enter short position
strategy.entry("short", strategy.short, when=(sell1 or sell2) and time_cond)

//adding ema with width
// Calculate EMA and SMA
ema5 = ema(close, 5)
ema200 = ema(close, 200)
ema21 = ema(close, 21)
ema50 = ema(close, 50)
sma50 = sma(close, 50)

// Plot EMA and SMA with width
plot(ema5, color=color.rgb(130, 235, 139), title="EMA 5", linewidth=1)
plot(ema200, color=color.rgb(243, 246, 249), title="EMA 200", linewidth=2)
plot(ema21, color=color.blue, title="21", linewidth=1)
plot(ema50, color=color.rgb(255, 64, 0), title="EMA 50", linewidth=2)
//plot(sma50, color=color.purple, title="SMA 20", linewidth=2)

Thêm nữa