Chiến lược theo dõi xu hướng dựa trên đường trung bình động định lượng


Ngày tạo: 2023-09-18 13:23:52 sửa đổi lần cuối: 2023-09-18 13:23:52
sao chép: 0 Số nhấp chuột: 398
1
tập trung vào
1166
Người theo dõi

Tổng quan

Chiến lược này được thực hiện bằng cách tính hai trung bình di chuyển dựa trên khối lượng giao dịch và đánh giá hướng xu hướng hiện tại dựa trên hướng chênh lệch của chúng, sau đó thực hiện lệnh dài hoặc ngắn. Chiến lược này đơn giản và dễ sử dụng, có thể theo dõi xu hướng thị trường một cách hiệu quả.

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

  1. Tính toán đường nhanh và đường chậm. Đường nhanh là trung bình di chuyển định lượng dựa trên chu kỳ đường nhanh được xác định bởi người dùng, đường chậm là trung bình di chuyển định lượng dựa trên chu kỳ đường chậm.

  2. Tính độ chênh lệch của hai đường. Đường nhanh trừ đường chậm để có đường cong chênh lệch.

  3. Xác định hướng xu hướng. Khi đường nhanh đi qua đường chậm, làm nhiều; khi đường nhanh đi qua đường chậm, làm trống.

  4. Gửi tín hiệu giao dịch. Gửi tín hiệu nhiều khi thấy giá tăng; Gửi tín hiệu trống khi thấy giá giảm.

  5. Cài đặt dừng chân. Cài đặt vị trí dừng chân bằng phần trăm dừng cố định do người dùng định nghĩa hoặc dừng động dựa trên ATR.

  6. Điều kiện thoát khỏi cuộc chơi. Nếu kích hoạt dừng lỗ hoặc có tín hiệu đảo ngược khi nắm giữ vị trí, vị trí sẽ bị xóa.

Phân tích lợi thế

  1. Sử dụng các chỉ số định lượng để xác định xu hướng, không dễ bị lừa bởi các đột phá giả.

  2. Các dòng nhanh và chậm kết hợp để lọc tiếng ồn thị trường và tránh giao dịch thường xuyên.

  3. Cài đặt dừng lỗ có hiệu quả trong việc kiểm soát rủi ro mất mát.

  4. Lập luận của chiến lược đơn giản, rõ ràng và dễ hiểu.

  5. Các tham số có thể được tùy chỉnh để đáp ứng nhu cầu của các giống và thời gian khác nhau.

Phân tích rủi ro

  1. Thiết lập tham số không đúng cách có thể dẫn đến tần suất giao dịch quá cao hoặc bỏ lỡ xu hướng.

  2. Lệnh dừng cố định có thể quá cơ học và không thích nghi với sự thay đổi của thị trường.

  3. Sự thay đổi của quan hệ giá trị-số lượng có thể ảnh hưởng đến hiệu quả của chỉ số định lượng.

  • Rủi ro 1 có thể tìm ra sự kết hợp tốt nhất thông qua các tham số tối ưu hóa.

  • Rủi ro 2 có thể sử dụng dừng động ATR thay cho dừng cố định.

  • Rủi ro 3 cần chú ý đến tác động của sự thay đổi khối lượng giao dịch đối với chiến lược.

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

  1. Kiểm tra các kết hợp tham số khác nhau của đường nhanh và đường chậm.

  2. Thử các chỉ số khác như OBV, William.

  3. Tăng lỗ dừng dựa trên tỷ lệ biến động

  4. Đánh giá hiệu quả khi kết hợp với các chỉ số khác.

  5. Đánh giá hiệu quả của các loại giao dịch khác nhau.

Tóm tắt

Chiến lược này theo dõi xu hướng bằng cách sử dụng các kết hợp đường chậm nhanh của đường trung bình định lượng, logic giao dịch đơn giản và rõ ràng, có thể điều chỉnh các tham số một cách tối ưu. Cài đặt dừng lỗ giúp kiểm soát rủi ro.

Mã nguồn chiến lược
/*backtest
start: 2023-08-18 00:00:00
end: 2023-09-17 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("EVWMA 6HR", overlay=false, 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)
// Credit to QuantNomad for the main idea behind this code
/////////////// 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

///////////// EVWMA /////////////
_2 = input(false,  "════════ EVMA ═══════")

fast_sum_length = input(5, title = "Fast Sum Length",  type = input.integer)
slow_sum_length = input(11, title = "Slow Sum Length",  type = input.integer)

fast_vol_period = sum(volume, fast_sum_length)
slow_vol_period = sum(volume, slow_sum_length)

fast_evwma = 0.0
fast_evwma := ((fast_vol_period - volume) * nz(fast_evwma[1], close) + volume * close) / (fast_vol_period)
slow_evwma = 0.0
slow_evwma := ((slow_vol_period - volume) * nz(slow_evwma[1], close) + volume * close) / (slow_vol_period)

diff = fast_evwma - slow_evwma

///////////////  Strategy  /////////////// 
long = fast_evwma > slow_evwma 
short = fast_evwma < slow_evwma 

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(9.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

_5 = input(false,  "══════ Longs or Shorts ═════")
useLongs = input(true, title="Use Longs")
useShorts = input(true, title="Use Shorts")

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

/////////////// Plotting /////////////// 
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
p1 = plot(diff, title = "Delta", color = long ? color.lime : short ? color.red : na, transp=0)
p2 = plot(0, color = color.white)
fill(p1, p2, color = long ? color.lime : short ? color.red : na, transp=60)