Chiến lược lọc kênh Gaussian: Cách xây dựng hệ thống giao dịch định lượng mạnh mẽ

GAUSSIAN Kijun-Sen VAPI ATR TRAILING
Ngày tạo: 2025-09-02 18:22:32 sửa đổi lần cuối: 2025-09-09 09:39:46
sao chép: 0 Số nhấp chuột: 333
2
tập trung vào
319
Người theo dõi

Chiến lược lọc kênh Gaussian: Cách xây dựng hệ thống giao dịch định lượng mạnh mẽ Chiến lược lọc kênh Gaussian: Cách xây dựng hệ thống giao dịch định lượng mạnh mẽ

Tại sao các chỉ số công nghệ truyền thống không hiệu quả trong một thị trường phức tạp?

Trong lĩnh vực giao dịch định lượng, chúng ta thường phải đối mặt với một vấn đề cốt lõi: chỉ số kỹ thuật đơn lẻ dễ tạo ra tín hiệu sai trong tiếng ồn thị trường, dẫn đến việc dừng lỗ và rút vốn thường xuyên. Vậy làm thế nào để xây dựng một hệ thống giao dịch có thể nắm bắt xu hướng và lọc tiếng ồn hiệu quả?

Chiến lược lọc nhiều Gaussian Channel mà chúng ta đang phân tích hôm nay, cung cấp cho chúng ta một giải pháp đáng để nghiên cứu sâu hơn bằng cách kết hợp một cách khéo léo bốn chiều khác nhau của các chỉ số kỹ thuật.

Cấu trúc công nghệ cốt lõi: Làm thế nào mà 4 bộ lọc có thể làm việc cùng nhau?

1. Gaussian Channel - Nhận diện xu hướng

Cơ sở của chiến lược là một bộ lọc Gaussian 4 cấp với cửa sổ lấy mẫu 144 chu kỳ. Không giống như trung bình di chuyển truyền thống, bộ lọc Gaussian loại bỏ phần lớn tiếng ồn thị trường thông qua mô hình toán học, trong khi vẫn giữ được sự nhạy cảm với sự thay đổi giá.

Cài đặt tham số chính:

  • Số cực Gaussian: 4 (cân bằng giữa độ trễ và độ trơn)
  • Chu kỳ lấy mẫu: 144 (chụp xu hướng trung hạn)
  • Tỷ lệ nhân của phấn sóng: 1.414 ((tỷ lệ nhân chênh lệch tiêu chuẩn, kiểm soát chiều rộng của kênh)

2. Kijun-Sen đường ((130 chu kỳ) - xác nhận xu hướng trung và dài hạn

Dòng Kijun-Sen 130 chu kỳ được sử dụng như một bộ lọc xu hướng thay vì chu kỳ 26 truyền thống.

Cài đặt chu kỳ dài hơn cho phép:

  • Giảm tín hiệu đột phá giả
  • Đảm bảo hướng giao dịch phù hợp với xu hướng chính
  • Tăng chất lượng tín hiệu, giảm tần suất giao dịch

Chỉ số VAPI - Phân tích giá trị giao dịch

VAPI ((Volume Adjusted Price Indicator) phân tích mối quan hệ giữa khối lượng giao dịch và thay đổi giá để đánh giá ý định thực sự của người tham gia thị trường. Khi VAPI > 0 hỗ trợ nhiều hơn, khi < 0 hỗ trợ ít hơn.

ATR Dynamic Stop Loss - Cơ chế kiểm soát rủi ro

Sử dụng 4,5 lần ATR 11 chu kỳ làm khoảng cách dừng, thiết lập này xem xét sự biến động của thị trường và tránh dừng quá chặt chẽ do tiếng ồn thị trường gây ra.

Sự sáng tạo trong quản lý tài chính: Sự khôn ngoan của chiến lược phân chia 7525

Điều đáng học hỏi nhất về chiến lược này là cách quản lý tài chính độc đáo của nó:

Logic phân tích:

  • 75% vị thế: cố định 3,5 lần rủi ro lợi nhuận so với dừng
  • 25% vị thế: Động lực theo dõi dừng lỗ

Tại sao lại thiết kế như vậy?

  1. Bảo đảm thu nhập cơ bảnTrong khi đó, các nhà đầu tư khác cũng có thể sử dụng các giao dịch này để tăng lợi nhuận của mình.
  2. Bắt thêm lợi nhuận: 25% lệnh dừng theo dõi có thể mang lại lợi nhuận lớn hơn khi xu hướng tiếp tục
  3. Rủi ro phân tánCác cơ chế rút lui khác nhau làm giảm nguy cơ thất bại của một chiến lược duy nhất.

Hệ thống kiểm soát rủi ro: cơ chế bảo vệ đa cấp

Kiểm soát rủi ro

  • Rủi ro mỗi giao dịch được giới hạn ở mức 3% số tiền trong tài khoản
  • Tính toán vị thế động dựa trên ATR

2. Quản lý rủi ro

  • Giảm lỗ chính: 4,5 lần ATR
  • Tracking Stop Loss: Dynamic Adjustment, Locking Float
  • Chế độ bảo vệ lợi nhuận cố định: 10%

3. Cơ chế lọc tín hiệu Bốn chỉ số kỹ thuật được xác nhận đồng thời làm giảm đáng kể khả năng tín hiệu giả.

Phân tích lợi thế và hạn chế của chiến lược

Điểm mạnh:

  1. Chất lượng tín hiệu caoCác nhà phân tích cho biết: “Sự phân tích đa dạng đã làm tăng đáng kể độ tin cậy của tín hiệu giao dịch”.
  2. Những rủi ro có thể kiểm soát được- Hệ thống quản lý lỗ hổng và vị trí tốt
  3. Khả năng thích nghi caoATR có khả năng điều chỉnh để thích ứng với các biến động thị trường khác nhau
  4. Tối ưu hóa lợi nhuậnChiến lược phân chia cổ phần cân bằng lợi nhuận ổn định với lợi nhuận dư thừa

Hạn chế tiềm năng:

  1. Xu hướng phụ thuộcTrong khi đó, các nhà đầu tư ở Việt Nam đang có xu hướng tăng trưởng mạnh.
  2. Nhận định tham sốMột số tham số cần được tối ưu hóa cho các giống khác nhau:
  3. Sự chậm trễLần đầu tiên, người dân ở Việt Nam có thể nhận được thông tin về sự cố này.

Hướng dẫn ứng dụng thực tế

1. Lựa chọn giống Ưu tiên chọn các loại có xu hướng mạnh, chẳng hạn như các cặp tiền tệ chính, tương lai chỉ số cổ phiếu.

Tối ưu hóa tham số Các nhà nghiên cứu đã đề xuất các phương pháp tối ưu hóa dựa trên dữ liệu lịch sử của các loại giao dịch cụ thể, đặc biệt chú ý đến:

  • Chu kỳ lấy mẫu của kênh Gauss
  • Kijun-Sen có chu kỳ
  • ATR Stop Loss Multiple

3. Thị trường thích ứng Trong một thị trường rõ rệt biến động, bạn có thể xem xét tạm dừng chiến lược hoặc điều chỉnh các thiết lập tham số.

Tóm lại: Suy nghĩ hệ thống về giao dịch định lượng

Giá trị của chiến lược này không chỉ nằm ở khả năng kỹ thuật mà còn nằm ở khả năng suy nghĩ hệ thống:

  1. Xác thực đa chiều: Xác nhận tín hiệu giao dịch từ nhiều góc độ như xu hướng, khối lượng giao dịch và biến động
  2. Ưu tiên rủi roMột hệ thống kiểm soát rủi ro tốt là nền tảng của chiến lược
  3. Tối ưu hóa lợi nhuậnMột chiến lược phân chia cổ phần để cân bằng các mục tiêu thu nhập khác nhau

Đối với các nhà giao dịch định lượng, chiến lược này cung cấp một khung tham khảo tốt. Điều quan trọng không phải là chuyển các tham số, mà là hiểu ý tưởng thiết kế của nó và điều chỉnh phù hợp theo các loại giao dịch và sở thích rủi ro của riêng bạn.

Hãy nhớ rằng chiến lược tốt nhất không phải là những chiến lược phức tạp nhất, mà là những chiến lược phù hợp nhất với phong cách giao dịch và môi trường thị trường của bạn.

Mã nguồn chiến lược
/*backtest
start: 2025-01-01 00:00:00
end: 2025-04-01 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","balance":500000}]
*/

// @version=6
strategy("Gaussian Channel Strategy – GC + Kijun (120) + VAPI Gate + ATR(4.5x) + 75/25 TP-TRAIL + Extra %TP",
     overlay=true)

// =============================
// ======= INPUTS ==============
// =============================
N_poles   = input.int(4,   "Gaussian Poles", minval=1, maxval=9)
per       = input.int(144, "Sampling Period", minval=2)
mult      = input.float(1.414, "Filtered TR Multiplier", step=0.001)
src       = input.source(hlc3, "Source")
modeLag   = input.bool(false, "Reduced Lag Mode")
modeFast  = input.bool(false, "Fast Response Mode")

kijunLen  = input.int(130, "Kijun-Sen Period")

vapiLen   = input.int(10, "VAPI Length")
vapiThresh= input.float(0.0, "VAPI Threshold (0 = zero line)")

atrLen    = input.int(11, "ATR Length (RMA)")
slATRmul  = input.float(4.5, "SL = ATR ×", step=0.1)
rr_fixed  = input.float(3.5, "Fixed TP RR (Leg A)", step=0.1)
allocA    = input.float(75,  "Allocation %: Fixed TP Leg", minval=1, maxval=99)
riskPct   = input.float(3.0, "Risk % of Equity per Trade", step=0.1, minval=0.1, maxval=10)

tpEnable    = input.bool(true,  "Enable Extra % Take Profit")
tpPctLong   = input.float(10.0, "Extra Long TP % of Entry",  step=0.1, minval=0)
tpPctShort  = input.float(10.0, "Extra Short TP % of Entry", step=0.1, minval=0)

// =============================
// ===== CORE COMPONENTS =======
// =============================
atr = ta.rma(ta.tr(true), atrLen)

donchian_avg(len) => (ta.highest(high, len) + ta.lowest(low, len)) / 2.0
kijun = donchian_avg(kijunLen)

// --- VAPI_LB (LazyBear) ---
rs(x, len) => ta.cum(x) - nz(ta.cum(x)[len])
v_x   = (2*close - high - low) / math.max(high - low, syminfo.mintick)
v_tva = rs(volume * v_x, vapiLen)
v_tv  = rs(volume, vapiLen)
v_va  = 100 * (v_tva / v_tv)

// =============================
// ===== Gaussian Channel ======
// =============================
f_filt9x(_a, _s, _i) =>
    int _m2 = 0, int _m3 = 0, int _m4 = 0, int _m5 = 0, int _m6 = 0,
    int _m7 = 0, int _m8 = 0, int _m9 = 0, float _f = 0.0, _x = (1 - _a)
    _m2 := _i == 9 ? 36  : _i == 8 ? 28 : _i == 7 ? 21 : _i == 6 ? 15 : _i == 5 ? 10 : _i == 4 ? 6 : _i == 3 ? 3 : _i == 2 ? 1 : 0
    _m3 := _i == 9 ? 84  : _i == 8 ? 56 : _i == 7 ? 35 : _i == 6 ? 20 : _i == 5 ? 10 : _i == 4 ? 4 : _i == 3 ? 1 : 0
    _m4 := _i == 9 ? 126 : _i == 8 ? 70 : _i == 7 ? 35 : _i == 6 ? 15 : _i == 5 ? 5  : _i == 4 ? 1 : 0
    _m5 := _i == 9 ? 126 : _i == 8 ? 56 : _i == 7 ? 21 : _i == 6 ? 6  : _i == 5 ? 1  : 0 
    _m6 := _i == 9 ? 84  : _i == 8 ? 28 : _i == 7 ? 7  : _i == 6 ? 1  : 0 
    _m7 := _i == 9 ? 36  : _i == 8 ? 8  : _i == 7 ? 1  : 0 
    _m8 := _i == 9 ? 9   : _i == 8 ? 1  : 0 
    _m9 := _i == 9 ? 1   : 0
    _f := math.pow(_a, _i) * nz(_s) +
         _i  *     _x      * nz(_f[1])      - (_i >= 2 ?
         _m2 * math.pow(_x, 2)  * nz(_f[2]) : 0) + (_i >= 3 ?
         _m3 * math.pow(_x, 3)  * nz(_f[3]) : 0) - (_i >= 4 ?
         _m4 * math.pow(_x, 4)  * nz(_f[4]) : 0) + (_i >= 5 ?
         _m5 * math.pow(_x, 5)  * nz(_f[5]) : 0) - (_i >= 6 ?
         _m6 * math.pow(_x, 6)  * nz(_f[6]) : 0) + (_i >= 7 ?
         _m7 * math.pow(_x, 7)  * nz(_f[7]) : 0) - (_i >= 8 ?
         _m8 * math.pow(_x, 8)  * nz(_f[8]) : 0) + (_i == 9 ?
         _m9 * math.pow(_x, 9)  * nz(_f[9]) : 0)

f_pole(_a, _s, _i) =>
    _f1 =            f_filt9x(_a, _s, 1),      _f2 = (_i >= 2 ? f_filt9x(_a, _s, 2) : 0), _f3 = (_i >= 3 ? f_filt9x(_a, _s, 3) : 0)
    _f4 = (_i >= 4 ? f_filt9x(_a, _s, 4) : 0), _f5 = (_i >= 5 ? f_filt9x(_a, _s, 5) : 0), _f6 = (_i >= 6 ? f_filt9x(_a, _s, 6) : 0)
    _f7 = (_i >= 7 ? f_filt9x(_a, _s, 7) : 0), _f8 = (_i >= 8 ? f_filt9x(_a, _s, 8) : 0), _f9 = (_i == 9 ? f_filt9x(_a, _s, 9) : 0)
    _fn = _i == 1 ? _f1 : _i == 2 ? _f2 : _i == 3 ? _f3 : _i == 4 ? _f4 : _i == 5 ? _f5 : _i == 6 ? _f6 : _i == 7 ? _f7 : _i == 8 ? _f8 : _i == 9 ? _f9 : na
    [_fn, _f1]

beta  = (1 - math.cos(4*math.asin(1)/per)) / (math.pow(1.414, 2/N_poles) - 1)
alpha = - beta + math.sqrt(math.pow(beta, 2) + 2*beta)

lag = (per - 1) / (2.0 * N_poles)

srcdata = modeLag ? src + (src - nz(src[lag])) : src
tr_raw  = ta.tr(true)
trdata  = modeLag ? tr_raw + (tr_raw - nz(tr_raw[lag])) : tr_raw

[filt_n, filt_1]       = f_pole(alpha, srcdata, N_poles)
[filt_n_tr, filt_1_tr] = f_pole(alpha, trdata,  N_poles)

filt   = modeFast ? (filt_n + filt_1)/2.0 : filt_n
filttr = modeFast ? (filt_n_tr + filt_1_tr)/2.0 : filt_n_tr

hband = filt + filttr * mult
lband = filt - filttr * mult

// =============================
// ===== Signals & Filters =====
// =============================
doLong  = close > filt and close > kijun and v_va > vapiThresh
doShort = close < filt and close < kijun and v_va < -vapiThresh

// =============================
// ===== Position Sizing =======
// =============================
riskValue   = strategy.equity * (riskPct/100.0)
slDist      = atr * slATRmul
qtyTotal    = slDist > 0 ? riskValue / slDist : 0.0
qtyA        = qtyTotal * (allocA/100.0)
qtyB        = qtyTotal * ((100 - allocA)/100.0)

// =============================
// ===== Order Execution =======
// =============================
var float trailStopL = na
var float trailStopS = na

inLong  = strategy.position_size > 0
inShort = strategy.position_size < 0
entryPx = strategy.position_avg_price

// Entries
if doLong and not inLong and strategy.position_size <= 0
    strategy.order("L-A", strategy.long, qty=qtyA)
    strategy.order("L-B", strategy.long, qty=qtyB)
    trailStopL := na
if doShort and not inShort and strategy.position_size >= 0
    strategy.order("S-A", strategy.short, qty=qtyA)
    strategy.order("S-B", strategy.short, qty=qtyB)
    trailStopS := na

// LONG management
if inLong
    slL = entryPx - slDist
    tpA = entryPx + rr_fixed * slDist

    // Leg A: 固定RR止盈 + 止损
    strategy.exit("TP/SL-LA", from_entry="L-A", limit=tpA, stop=slL)

    // Leg B: 追踪止损
    trailStopL := na(trailStopL[1]) or strategy.position_size[1] <= 0 ? slL : math.max(trailStopL[1], close - slDist)
    strategy.exit("Trail-LB", from_entry="L-B", stop=trailStopL)

    // 额外百分比止盈
    if tpEnable and high >= entryPx * (1 + tpPctLong/100.0)
        strategy.close("L-A", comment="ExtraTP")
        strategy.close("L-B", comment="ExtraTP")

// SHORT management
if inShort
    slS = entryPx + slDist
    tpA = entryPx - rr_fixed * slDist

    // Leg A: 固定RR止盈 + 止损
    strategy.exit("TP/SL-SA", from_entry="S-A", limit=tpA, stop=slS)

    // Leg B: 追踪止损
    trailStopS := na(trailStopS[1]) or strategy.position_size[1] >= 0 ? slS : math.min(trailStopS[1], close + slDist)
    strategy.exit("Trail-SB", from_entry="S-B", stop=trailStopS)

    // 额外百分比止盈
    if tpEnable and low <= entryPx * (1 - tpPctShort/100.0)
        strategy.close("S-A", comment="ExtraTP")
        strategy.close("S-B", comment="ExtraTP")

// =============================
// ===== 图表绘制 ==============
// =============================
fcolor = filt > nz(filt[1]) ? color.new(color.lime, 0) : filt < nz(filt[1]) ? color.new(color.red, 0) : color.new(color.gray, 0)
plotFilter = plot(filt,  title="GC Filter",    color=fcolor, linewidth=2)
plotH      = plot(hband, title="GC High Band", color=fcolor)
plotL      = plot(lband, title="GC Low Band",  color=fcolor)
fill(plotH, plotL, color=color.new(fcolor, 80))

plot(kijun, "Kijun-Sen", color=color.new(color.maroon, 0))

// 信号标记
plotshape(doLong,  title="Long Setup",  style=shape.triangleup,   location=location.belowbar, color=color.new(color.lime, 0), size=size.tiny, text="ENTRY L")
plotshape(doShort, title="Short Setup", style=shape.triangledown, location=location.abovebar, color=color.new(color.fuchsia, 0), size=size.tiny, text="ENTRY S")