Chiến lược xu hướng động lượng ADX


Ngày tạo: 2024-01-16 15:57:17 sửa đổi lần cuối: 2024-01-16 15:57:17
sao chép: 0 Số nhấp chuột: 762
1
tập trung vào
1617
Người theo dõi

Chiến lược xu hướng động lượng ADX

Tổng quan

Chiến lược này dựa trên chỉ số ADX để xác định xu hướng thị trường, kết hợp với chỉ số DMI để xác định hướng đa trống, sử dụng độ lệch ADX để xác định cường độ xu hướng, thiết lập các giá trị quan trọng của ADX để lọc các thị trường không có xu hướng, hỗ trợ các tín hiệu giao dịch lọc đường trung bình di chuyển.

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

  1. Tính ADX, DI+, DI-
  2. ADX lệch > 0, cho thấy xu hướng tăng lên; giá trị quan trọng được đặt là 23, được sử dụng để lọc các thị trường không theo xu hướng.
  3. DI+ cao hơn DI-, cho thấy sức mạnh đa đầu lớn hơn sức mạnh không đầu, để xem nhiều tín hiệu.
  4. Khi kích hoạt bộ lọc trung bình di chuyển, chỉ khi giá đóng cửa cao hơn trung bình di chuyển, tín hiệu đa đầu sẽ được tạo ra.
  5. Khi ADX dốc < 0, nó sẽ giảm xuống.

Phân tích lợi thế

  1. Bộ lọc MA phụ giúp giảm tiếng ồn giao dịch của thị trường không có xu hướng.
  2. ADX có khả năng phán đoán chính xác về sự phát triển của xu hướng.
  3. Định hướng DI được kết hợp với ADX để tạo ra một hệ thống quyết định giao dịch xu hướng hoàn chỉnh hơn.
  4. Tỷ lệ rút và thu lợi nhuận có thể tốt hơn so với chiến lược trung bình di chuyển đơn giản.

Phân tích rủi ro

  1. Chỉ số ADX đặt các tham số khác nhau, kết quả sẽ khác nhau rất nhiều.
  2. DMI vẫn chưa xác định rõ về hướng bay, có thể phát ra tín hiệu sai.
  3. Có một số sự chậm trễ, làm giảm hiệu quả của chiến lược.

Hướng tối ưu hóa

  1. Tối ưu hóa các tham số ADX để tìm các tham số tốt nhất.
  2. Tăng các chiến lược ngăn chặn tổn thất để tránh sự gia tăng tổn thất đơn lẻ.
  3. Thử kết hợp các chỉ số khác để lọc các tín hiệu. Ví dụ: RSI, Bollinger Bands.

Tóm tắt

Chiến lược này tận dụng tối đa lợi thế của ADX để đánh giá xu hướng và cường độ xu hướng, kết hợp với định hướng đánh giá của chỉ số DMI, tạo thành một hệ thống theo dõi xu hướng hoàn chỉnh. Đồng thời hỗ trợ moving average có thể lọc hiệu quả tiếng ồn của thị trường không theo xu hướng.

Mã nguồn chiến lược
/*backtest
start: 2024-01-08 00:00:00
end: 2024-01-15 00:00:00
period: 10m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © millerrh with inspiration from @9e52f12edd034d28bdd5544e7ff92e 
//The intent behind this study is to look at ADX when it has an increasing slope and is above a user-defined key level (23 default). 
//This is to identify when it is trending.
//It then looks at the DMI levels.  If D+ is above D- and the ADX is sloping upwards and above the key level, it triggers a buy condition.  Opposite for short.
//Can use a user-defined moving average to filter long/short if desried.
// NOTE: THIS IS MEANT TO BE USED IN CONJUNCTION WITH MY "ATX TRIGGER" INDICATOR FOR VISUALIZATION. MAKE SURE SETTINGS ARE THE SAME FOR BOTH.

strategy("ADX | DMI Trend", overlay=true, initial_capital=10000, currency='USD', 
   default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.04)

// === BACKTEST RANGE ===
From_Year  = input(defval = 2019, title = "From Year")
From_Month = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
From_Day   = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
To_Year    = input(defval = 9999, title = "To Year")
To_Month   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
To_Day     = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
Start  = timestamp(From_Year, From_Month, From_Day, 00, 00)  // backtest start window
Finish = timestamp(To_Year, To_Month, To_Day, 23, 59)        // backtest finish window

// == INPUTS ==
// ADX Info
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Period")
keyLevel = input(23, title="Keylevel for ADX")
adxLookback = input(3, title="Lookback Period for Slope")

// == FILTERING ==
// Inputs
useMaFilter = input(title = "Use MA for Filtering?", type = input.bool, defval = true)
maType = input(defval="EMA", options=["EMA", "SMA"], title = "MA Type For Filtering")
maLength   = input(defval = 200, title = "MA Period for Filtering", minval = 1)

// Declare function to be able to swap out EMA/SMA
ma(maType, src, length) =>
    maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
maFilter = ma(maType, close, maLength)
plot(maFilter, title = "Trend Filter MA", color = color.green, linewidth = 3, style = plot.style_line, transp = 50)

// Check to see if the useMaFilter check box is checked, this then inputs this conditional "maFilterCheck" variable into the strategy entry 
maFilterCheck = if useMaFilter == true
    maFilter
else
    close

// == USE BUILT-IN DMI FUNCTION TO DETERMINE ADX AND BULL/BEAR STRENGTH
[diplus, diminus, adx] = dmi(dilen, adxlen)

buySignal = (adx[0]-adx[adxLookback] > 0) and adx > keyLevel and diplus > diminus  and close >= maFilterCheck
// buySignalValue = valuewhen(buySignal, close, 0)
shortSignal = (adx[0]-adx[adxLookback] > 0) and adx > keyLevel and diplus < diminus  and close <= maFilterCheck
// shortSignalValue = valuewhen(shortSignal, close, 0)
sellCoverSignal = adx[0]-adx[adxLookback] < 0

// == ENTRY & EXIT CRITERIA
// Triggers to be TRUE for it to fire of the BUY Signal : (opposite for the SELL signal).
// (1): Price is over the 200 EMA line. (EMA level configurable by the user)
// (2): "D+" is OVER the "D-" line
// (3): RSI 7 is under 30 (for SELL, RSI 7 is over 70)
// 1* = The ultimate is to have a combination line of 3 EMA values, EMA 14, EMA 50 and EMA 200 - And if price is over this "combo" line, then it's a strong signal

// == STRATEGY ENTRIES/EXITS == 
strategy.entry("Long", strategy.long, when = buySignal)
strategy.close("Long", when = sellCoverSignal)
strategy.entry("Short", strategy.short, when = shortSignal)
strategy.close("Short", when = sellCoverSignal)
    
// == ALERTS == 
// alertcondition(buySignal, title='ADX Trigger Buy', message='ADX Trigger Buy')
// alertcondition(sellSignal, title='ADX Trigger Sell', message='ADX Trigger Sell')