Chiến lược này thiết lập một đường dừng lỗ năng động dựa trên chỉ số Average True Range (ATR) để theo dõi sự thay đổi giá cổ phiếu, để bảo vệ dừng lỗ trong khi tối đa hóa lợi nhuận.
Chiến lược được thực hiện chủ yếu thông qua các bước sau:
Tính toán chỉ số ATR, thời gian ATR được đặt bởi tham số nATRPeriod, mặc định là 5;
Tính toán đường stop loss dựa trên giá trị ATR, kích thước stop loss được thiết lập bởi tham số nATRMultip, mặc định là 3,5 lần ATR;
Khi giá tăng, nếu cao hơn đường dừng lỗ trước đó, điều chỉnh đường dừng lỗ lên đến giá trừ số lượng dừng lỗ; khi giá giảm, nếu thấp hơn đường dừng lỗ trước đó, điều chỉnh đường dừng lỗ xuống đến giá cộng với số lượng dừng lỗ;
Xác định giá có vượt qua đường dừng lỗ, nếu vượt qua, gửi tín hiệu mua hoặc bán;
Nhập các vị trí dài hoặc ngắn dựa trên tín hiệu đột phá đường dừng lỗ, và đóng các vị trí khi giá chạm vào đường dừng lỗ một lần nữa.
Khi giá tăng, đường dừng lỗ sẽ di chuyển lên liên tục để khóa lợi nhuận. Khi giá giảm, đường dừng lỗ sẽ di chuyển xuống liên tục để dừng lỗ. Chỉ số ATR có thể phản ánh biến động giá chính xác hơn. Điều chỉnh năng động đường dừng lỗ dựa trên ATR có thể tránh dừng lỗ quá hung hăng hoặc quá bảo thủ.
Các thông số có thể được tối ưu hóa bằng cách điều chỉnh thời gian ATR và kích thước stop loss để tìm sự cân bằng tối ưu giữa stop loss và trailing.
Chiến lược này nhận ra dừng lỗ và lợi nhuận trong khi giữ thông qua đường dừng lỗ kéo theo động ATR. So với các điểm dừng lỗ cố định, nó thích nghi tốt hơn với biến động giá, tránh dừng lỗ quá hung hăng hoặc quá bảo thủ. Chỉ số ATR làm cho việc điều chỉnh đường dừng lỗ được nhắm mục tiêu hơn. Nhưng các thông số và chiến lược tái nhập cần tối ưu hóa hơn nữa để giảm dừng không cần thiết và mở rộng biên lợi nhuận. Nhìn chung đây là một ý tưởng dừng lỗ kéo theo động tốt đáng nghiên cứu và áp dụng thêm.
/*backtest start: 2023-09-08 00:00:00 end: 2023-10-08 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 //@okadoke //////////////////////////////////////////////////////////// // Based on Average True Range Trailing Stops Strategy by HPotter // Average True Range Trailing Stops Strategy, by Sylvain Vervoort // The related article is copyrighted material from Stocks & Commodities Jun 2009 //////////////////////////////////////////////////////////// strategy(title="ATR Trailing Stops Strategy", shorttitle="ATRTSS", overlay = true, initial_capital=100000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type="percent", commission_value=0.0) nATRPeriod = input(5, "ATR Period") nATRMultip = input(3.5, "ATR Multiplier") useShorts = input(false, "Test w/Shorts?") daysBackMax = input(defval = 360, title = "Max Days Back to Test", minval = 0) daysBackMin = input(defval = 0, title = "Min Days Back to Test", minval = 0) msBackMax = 1000 * 60 * 60 * 24 * daysBackMax msBackMin = 1000 * 60 * 60 * 24 * daysBackMin xATR = atr(nATRPeriod) nLoss = nATRMultip * xATR xATRTrailingStop = na xATRTrailingStop := iff(close > nz(xATRTrailingStop[1], 0) and close[1] > nz(xATRTrailingStop[1], 0), max(nz(xATRTrailingStop[1]), close - nLoss), iff(close < nz(xATRTrailingStop[1], 0) and close[1] < nz(xATRTrailingStop[1], 0), min(nz(xATRTrailingStop[1]), close + nLoss), iff(close > nz(xATRTrailingStop[1], 0), close - nLoss, close + nLoss))) pos = na pos := iff(close[1] < nz(xATRTrailingStop[1], 0) and close > nz(xATRTrailingStop[1], 0), 1, iff(close[1] > nz(xATRTrailingStop[1], 0) and close < nz(xATRTrailingStop[1], 0), -1, nz(pos[1], 0))) color = pos == -1 ? red: pos == 1 ? green : blue plot(xATRTrailingStop, color=color, title="ATR Trailing Stop") isWithinTimeBounds = (msBackMax == 0 or (time > (timenow - msBackMax))) and (msBackMin == 0 or (time < (timenow - msBackMin))) buy = crossover(close, xATRTrailingStop) sell = crossunder(close, xATRTrailingStop) strategy.entry("LONG", long=true, when=buy and isWithinTimeBounds) strategy.close("LONG", when=sell and isWithinTimeBounds) strategy.entry("SHORT", long=false, when=useShorts and sell and isWithinTimeBounds) strategy.close("SHORT", when=useShorts and buy and isWithinTimeBounds)