Chiến lược đảo ngược siêu xu hướng hàng ngày

Tác giả:ChaoZhang, Ngày: 2024-02-22 16:22:28
Tags:

img

Tổng quan

Chiến lược đảo ngược hàng ngày siêu xu hướng là một chiến lược giao dịch định lượng sử dụng chỉ số siêu xu hướng để xác định xu hướng thị trường, kết hợp mức đột phá giá và phạm vi trung bình thực sự để tính toán dừng lỗ, và sử dụng chỉ số tỷ lệ thay đổi giá để lọc tín hiệu siêu xu hướng.

Chiến lược logic

Chỉ số cốt lõi của chiến lược này là chỉ số Super Trend. Chỉ số Super Trend dựa trên Average True Range (ATR) và có thể xác định rõ hơn hướng xu hướng thị trường. Một sự cố của đường ray trên của Super Trend là một tín hiệu ngắn, và một sự cố của đường ray dưới là một tín hiệu dài.

Chiến lược này sử dụng chỉ số Tỷ lệ thay đổi giá (ROC) để lọc chỉ số siêu xu hướng để tránh các tín hiệu không hợp lệ. Chỉ tham gia vào các tín hiệu siêu xu hướng khi biến động giá lớn, nếu không thì không tham gia.

Đối với stop loss, chiến lược cung cấp hai phương pháp stop loss: tỷ lệ stop loss cố định và stop loss thích nghi dựa trên ATR. Stop loss cố định đơn giản và trực tiếp.

Các điều kiện vào là đảo ngược chỉ số Super Trend và chỉ số tỷ lệ thay đổi giá vượt qua bộ lọc. Các điều kiện ra là Super Trend đảo ngược lại hoặc phá vỡ đường dừng lỗ. Chiến lược tuân thủ nguyên tắc theo dõi xu hướng và chỉ cho phép một vị trí theo mỗi hướng.

Phân tích lợi thế

Ưu điểm lớn nhất của chiến lược này là chỉ số Super Trend có độ rõ ràng và ổn định cao hơn trong việc đánh giá hướng xu hướng so với các đường trung bình động thông thường, với tiếng ồn ít hơn.

Cơ chế dừng lỗ thích nghi ATR cũng cho phép chiến lược thích nghi với môi trường thị trường rộng hơn.

Từ kết quả thử nghiệm, chiến lược này hoạt động đặc biệt tốt trong một thị trường tăng. Tỷ lệ thắng rất cao trong xu hướng dài hạn có quy mô đáng kể, với các chu kỳ lợi nhuận liên tiếp dài.

Phân tích rủi ro

Nguy cơ chính đối mặt với chiến lược này là đánh giá sai về sự đảo ngược xu hướng, có thể bỏ lỡ các tín hiệu đảo ngược hoặc tạo ra các tín hiệu đảo ngược không cần thiết. Điều này thường xảy ra khi giá dao động và củng cố xung quanh các khu vực hỗ trợ / kháng cự chính.

Ngoài ra, một mức dừng lỗ được đặt quá rộng cũng có thể dẫn đến tổn thất lớn hơn.

Để giải quyết các rủi ro này, thời gian tính toán ATR có thể được rút ngắn thích hợp hoặc điều chỉnh nhân dừng lỗ ATR. Các chỉ số bổ sung cũng có thể được thêm vào để xác định các khu vực hỗ trợ / kháng cự chính để tránh các tín hiệu gây hiểu nhầm từ các khu vực đó.

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. Điều chỉnh các thông số của chỉ số Super Trend để tối ưu hóa thời gian ATR và số nhân ATR để làm cho đường Super Trend mượt mà hơn.

  2. Điều chỉnh các tham số của chỉ số tỷ lệ thay đổi giá để tối ưu hóa thời gian và ngưỡng tỷ lệ thay đổi để giảm tín hiệu sai.

  3. Hãy thử các cơ chế dừng lỗ khác nhau như dừng lại, hoặc tối ưu hóa kích thước dừng lỗ của các điểm dừng cố định.

  4. Thêm các chỉ số đánh giá bổ sung để xác định hỗ trợ / kháng cự chính và tránh đánh giá sai về sự đảo ngược xu hướng.

  5. Kiểm tra các thiết lập tham số và tác dụng đối với các sản phẩm khác nhau để tìm ra sự kết hợp các tham số tối ưu.

  6. Thực hiện tối ưu hóa backtest để tìm các thiết lập tham số tốt nhất.

Kết luận

Nói chung, Chiến lược đảo ngược hàng ngày siêu xu hướng là một chiến lược theo xu hướng tương đối ổn định và đáng tin cậy. Nó kết hợp chỉ số siêu xu hướng và chỉ số tỷ lệ thay đổi giá để lọc, có thể xác định hiệu quả hướng của xu hướng trung và dài hạn. Cơ chế dừng lỗ thích nghi ATR cũng cho phép nó thích nghi với hầu hết các môi trường thị trường. Thông qua việc tối ưu hóa thêm các thiết lập tham số và thêm các chỉ số phán đoán, sự ổn định và lợi nhuận của chiến lược này có thể được cải thiện.


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

//@version=4
strategy("Super Trend Daily BF 🚀", overlay=true, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)

/////////////// Time Frame ///////////////
_1 = input(false,  "════════ Test Period ═══════")
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

///////////// Super Trend /////////////
_2 = input(false,  "══════ Super Trend ══════")
length = input(title="ATR Period", type=input.integer, defval=3)
mult = input(title="ATR Multiplier", type=input.float, step=0.1, defval=1.3)

atr = mult * atr(length)

longStop = hl2 - atr
longStopPrev = nz(longStop[1], longStop)
longStop :=  close[1] > longStopPrev ? max(longStop, longStopPrev) : longStop

shortStop = hl2 + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := close[1] < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and close > shortStopPrev ? 1 : dir == 1 and close < longStopPrev ? -1 : dir

///////////// Rate Of Change ///////////// 
_3 = input(false,  "══════ Rate of Change ══════")
source = close
roclength = input(30, "ROC Length",  minval=1)
pcntChange = input(6, "ROC % Change", minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

///////////////  Strategy  /////////////// 
long = dir == 1 and dir[1] == -1 and isMoving()
short = dir == -1 and dir[1] == 1 and isMoving()

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

/////////////// Dynamic ATR Stop Losses ///////////////
_4 = input(false,  "════════ Stop Loss ═══════")
SL_type = input("Fixed", options=["Fixed", "ATR Derived"], title="Stop Loss Type")
sl_inp = input(6.0, title='Fixed Stop Loss %') / 100
atrLkb = input(20, minval=1, title='ATR Stop Period')
atrMult = input(1.5, step=0.25, title='ATR Stop Multiplier') 
atr1 = atr(atrLkb)

longStop1 = 0.0
longStop1 :=  short_signal ? na : long_signal ? close - (atr1 * atrMult) : longStop1[1]
shortStop1 = 0.0
shortStop1 := long_signal ? na : short_signal ? close + (atr1 * atrMult) : shortStop1[1]

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution ///////////////
if testPeriod()
    strategy.entry("L", strategy.long, when=long)
    strategy.entry("S", strategy.short, when=short)
    strategy.exit("L SL", "L", stop = SL_type == "Fixed" ? long_sl : longStop1, when=since_longEntry > 0)
    strategy.exit("S SL", "S", stop = SL_type == "Fixed" ? short_sl : shortStop1, when=since_shortEntry > 0)

/////////////// Plotting /////////////// 
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
bgcolor(isMoving() ? dir == 1 ? color.lime : color.red : color.white , transp=80)

Thêm nữa