Chiến lược này dựa trên chỉ số ATR thiết lập đường dừng động, theo dõi sự thay đổi giá cổ phiếu, thực hiện bảo vệ dừng lỗ và tối đa hóa lợi nhuận.
Chiến lược này được thực hiện thông qua các bước sau:
Tính ATR, chu kỳ ATR được thiết lập bởi tham số nATRPeriod, mặc định là 5;
Dòng dừng được tính dựa trên giá trị ATR và được thiết lập bằng tham số nATRMultip, mặc định là 3.5 lần ATR;
Khi giá cổ phiếu tăng, nếu cao hơn mức dừng trước đó, mức dừng sẽ được nâng lên giá cổ phiếu trừ mức dừng; khi giá cổ phiếu giảm, nếu thấp hơn mức dừng trước đó, mức dừng sẽ được hạ xuống giá cổ phiếu cộng với mức dừng;
Xác định xem giá cổ phiếu đã vượt qua ngưỡng dừng lỗ hay không, và nếu vượt qua, nó sẽ phát ra tín hiệu mua hoặc bán;
Theo tín hiệu của đường dừng phá vỡ, vào vị trí làm nhiều hoặc trống, và đóng cửa khi chạm vào đường dừng một lần nữa.
Khi giá cổ phiếu tăng, đường dừng sẽ liên tục tăng lên, do đó khóa lợi nhuận; khi giá cổ phiếu giảm, đường dừng sẽ liên tục giảm xuống, do đó dừng. Chỉ số ATR có thể phản ánh chính xác hơn mức độ biến động của giá cổ phiếu, điều chỉnh đường dừng theo động thái ATR, có thể tránh dừng quá mạnh mẽ hoặc bảo thủ.
Các tham số có thể được tối ưu hóa, điều chỉnh tham số chu kỳ ATR và độ rộng của lỗ hổng, tìm ra sự kết hợp tham số tốt nhất để cân bằng lỗ hổng và theo dõi. Nó cũng có thể được kết hợp với các chỉ số kỹ thuật khác để lọc thời gian ra thị trường, giảm lỗ hổng không cần thiết.
Chiến lược này thực hiện việc dừng lỗ và khóa lợi nhuận trong quá trình nắm giữ bằng cách động điều chỉnh đường dừng ATR. So với vị trí dừng lỗ cố định, nó có thể thích ứng tốt hơn với biến động giá cổ phiếu, tránh dừng lỗ quá mạnh hoặc bảo thủ. Chỉ số ATR làm cho điều chỉnh đường dừng lỗ có mục tiêu hơn. Tuy nhiên, thiết lập tham số và chiến lược nhập lại cần được tối ưu hóa hơn nữa để giảm lỗ dừng không cần thiết và mở rộng không gian kiếm lợi nhuận.
/*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)