Chiến lược trung bình động thích nghi kênh Gauss

Tác giả:ChaoZhang, Ngày: 2024-03-28 18:08:18
Tags:

img

Tổng quan

Chiến lược trung bình chuyển động thích nghi kênh Gaussian là một chiến lược giao dịch định lượng sử dụng kỹ thuật lọc Gaussian và cài đặt tham số thích nghi. Dựa trên lý thuyết lọc Gaussian được đề xuất bởi John Ehlers, chiến lược này tạo ra các tín hiệu giao dịch trơn tru và thích nghi bằng cách áp dụng nhiều tính toán trung bình chuyển động theo cấp số nhân vào dữ liệu giá.

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

Các nguyên tắc của chiến lược trung bình động thích nghi kênh Gaussian là như sau:

  1. Tính toán giá trị bộ lọc Gaussian của giá. Dựa trên thời gian lấy mẫu được xác định bởi người dùng và số cột, các thông số Beta và Alpha được tính toán, và sau đó dữ liệu giá trải qua lọc Gaussian đa cấp để có được một chuỗi giá mịn.
  2. Tính toán giá trị bộ lọc Gaussian của phạm vi thực.
  3. Xây dựng kênh Gaussian. Giá được lọc theo Gaussian phục vụ như một dải giữa, dải trên được hình thành bằng cách thêm phần tử của phạm vi thực được lọc và nhân được xác định bởi người dùng vào dải giữa, và dải dưới được hình thành bằng cách trừ giá trị này khỏi dải giữa, tạo ra một kênh năng động.
  4. Tạo tín hiệu giao dịch: Khi giá vượt qua dải trên của kênh, tín hiệu mua được tạo ra; khi giá vượt qua dải dưới, tín hiệu bán được tạo ra.
  5. giới thiệu các thông số khoảng thời gian. Người dùng có thể đặt thời gian bắt đầu và kết thúc cho việc thực hiện chiến lược, và chiến lược sẽ chỉ hoạt động dựa trên tín hiệu giao dịch trong khoảng thời gian được chỉ định này.

Phân tích lợi thế

Chiến lược trung bình động thích nghi kênh Gaussian có những lợi thế sau:

  1. Khả năng thích nghi mạnh: Chiến lược sử dụng các tham số điều chỉnh động có thể thích nghi với các điều kiện thị trường và các công cụ giao dịch khác nhau mà không cần điều chỉnh thủ công thường xuyên.
  2. Khả năng theo dõi xu hướng tốt. Bằng cách xây dựng các kênh giá, chiến lược có thể nắm bắt và theo dõi các xu hướng thị trường hiệu quả, tránh các tín hiệu sai trong thị trường hỗn loạn.
  3. Kỹ thuật lọc Gaussian được sử dụng để làm mịn dữ liệu giá nhiều lần, loại bỏ hầu hết tiếng ồn thị trường và làm cho tín hiệu giao dịch đáng tin cậy hơn.
  4. Độ linh hoạt cao. Người dùng có thể điều chỉnh các tham số chiến lược theo nhu cầu của họ, chẳng hạn như thời gian lấy mẫu, số cột, nhân phạm vi, v.v., để tối ưu hóa hiệu suất của chiến lược.
  5. Khả năng thực tế mạnh mẽ: Việc giới thiệu các tham số thời gian cho phép chiến lược chạy trong một khoảng thời gian cụ thể, tạo điều kiện cho ứng dụng thực tế và nghiên cứu backtesting.

Phân tích rủi ro

Mặc dù có nhiều lợi thế, Chiến lược Đường trung bình động thích nghi kênh Gaussian vẫn mang lại một số rủi ro:

  1. Các thiết lập tham số không phù hợp có thể dẫn đến chiến lược không hiệu quả hoặc hiệu suất kém, đòi hỏi phải thử nghiệm và tối ưu hóa nhiều lần trong các ứng dụng thực tế.
  2. Rủi ro sự kiện đột ngột: Khi đối mặt với một số sự kiện đột ngột lớn, chiến lược có thể không phản ứng đúng cách và kịp thời, dẫn đến tổn thất.
  3. Nguy cơ quá phù hợp: Nếu các thiết lập tham số quá phù hợp với dữ liệu lịch sử, chiến lược có thể hoạt động kém trong tương lai, cần phải xem xét cả hiệu suất trong và ngoài mẫu.
  4. Rủi ro trọng tài: Chiến lược này chủ yếu phù hợp với các thị trường xu hướng, và giao dịch thường xuyên trong các thị trường hỗn loạn có thể phải đối mặt với rủi ro trọng tài đáng kể.

Hướng dẫn tối ưu hóa

Các hướng tối ưu hóa cho chiến lược trung bình động thích nghi kênh Gaussian bao gồm:

  1. Tối ưu hóa tham số động. Bằng cách giới thiệu máy học và các kỹ thuật khác, đạt được tối ưu hóa tự động và điều chỉnh động các tham số chiến lược để cải thiện khả năng thích nghi.
  2. Kết hợp nhiều yếu tố. Kết hợp các chỉ số hoặc yếu tố kỹ thuật hiệu quả khác với kênh Gaussian để tạo ra các tín hiệu giao dịch mạnh mẽ hơn.
  3. Tối ưu hóa quản lý vị trí: Kết hợp các quy tắc quản lý vị trí và quản lý tiền hợp lý vào chiến lược để kiểm soát rút tiền và rủi ro.
  4. Điều phối đa công cụ: mở rộng chiến lược đến nhiều công cụ giao dịch khác nhau và đa dạng hóa rủi ro thông qua phân bổ tài sản và phân tích tương quan.

Tóm lại

Chiến lược trung bình chuyển động thích nghi kênh Gaussian là một chiến lược giao dịch định lượng dựa trên lọc Gaussian và các tham số thích nghi, tạo ra các tín hiệu giao dịch trơn tru và đáng tin cậy bằng cách xây dựng các kênh giá năng động. Chiến lược có những lợi thế như khả năng thích nghi mạnh mẽ, khả năng theo dõi xu hướng tốt, độ mượt mà cao, tính linh hoạt cao và tính thực tế mạnh mẽ. Tuy nhiên, nó cũng phải đối mặt với các rủi ro như thiết lập tham số, sự kiện đột ngột, quá phù hợp và điều chỉnh. Trong tương lai, chiến lược có thể được tinh chỉnh và nâng cao hơn thông qua tối ưu hóa tham số động, sáp nhập đa yếu tố, tối ưu hóa quản lý vị trí và phối hợp đa công cụ.


/*backtest
start: 2023-03-22 00:00:00
end: 2024-03-27 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="Gaussian Channel Strategy v1.0", overlay=true, calc_on_every_tick=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)

// Date condition inputs
startDate = input(title="Date Start", type=input.time, defval=timestamp("1 Jan 2018 00:00 +0000"), group="Dates")
endDate = input(title="Date End", type=input.time, defval=timestamp("31 Dec 2060 23:59 +0000"), group="Dates")
timeCondition = true

// This study is an experiment utilizing the Ehlers Gaussian Filter technique combined with lag reduction techniques and true range to analyze trend activity.
// Gaussian filters, as Ehlers explains it, are simply exponential moving averages applied multiple times.
// First, beta and alpha are calculated based on the sampling period and number of poles specified. The maximum number of poles available in this script is 9.
// Next, the data being analyzed is given a truncation option for reduced lag, which can be enabled with "Reduced Lag Mode".
// Then the alpha and source values are used to calculate the filter and filtered true range of the dataset.
// Filtered true range with a specified multiplier is then added to and subtracted from the filter, generating a channel.
// Lastly, a one pole filter with a N pole alpha is averaged with the filter to generate a faster filter, which can be enabled with "Fast Response Mode". 

//Custom bar colors are included.

//Note: Both the sampling period and number of poles directly affect how much lag the indicator has, and how smooth the output is.
//      Larger inputs will result in smoother outputs with increased lag, and smaller inputs will have noisier outputs with reduced lag.
//      For the best results, I recommend not setting the sampling period any lower than the number of poles + 1. Going lower truncates the equation.

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
// Huge shoutout to @e2e4mfck for taking the time to improve the calculation method!
// -> migrated to v4
// -> pi is now calculated using trig identities rather than being explicitly defined.
// -> The filter calculations are now organized into functions rather than being individually defined.
// -> Revamped color scheme.

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Functions - courtesy of @e2e4mfck
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
 
//Filter function 
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, _x = (1 - _a)
    // Weights. 
    // Initial weight _m1 is a pole number and equal to _i
    _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
    // filter
    _f :=   pow(_a, _i) * nz(_s) + 
      _i  *     _x      * nz(_f[1])      - (_i >= 2 ? 
      _m2 * pow(_x, 2)  * nz(_f[2]) : 0) + (_i >= 3 ? 
      _m3 * pow(_x, 3)  * nz(_f[3]) : 0) - (_i >= 4 ? 
      _m4 * pow(_x, 4)  * nz(_f[4]) : 0) + (_i >= 5 ? 
      _m5 * pow(_x, 5)  * nz(_f[5]) : 0) - (_i >= 6 ? 
      _m6 * pow(_x, 6)  * nz(_f[6]) : 0) + (_i >= 7 ? 
      _m7 * pow(_x, 7)  * nz(_f[7]) : 0) - (_i >= 8 ? 
      _m8 * pow(_x, 8)  * nz(_f[8]) : 0) + (_i == 9 ? 
      _m9 * pow(_x, 9)  * nz(_f[9]) : 0)

//9 var declaration fun
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 >= 2 ? 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]

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Inputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Source
src = input(defval=hlc3, title="Source")

//Poles
int N = input(defval=4, title="Poles", minval=1, maxval=9)

//Period
int per = input(defval=144, title="Sampling Period", minval=2)

//True Range Multiplier
float mult = input(defval=1.414, title="Filtered True Range Multiplier", minval=0)

//Lag Reduction
bool modeLag  = input(defval=false, title="Reduced Lag Mode")
bool modeFast = input(defval=false, title="Fast Response Mode")

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Definitions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Beta and Alpha Components
beta  = (1 - cos(4*asin(1)/per)) / (pow(1.414, 2/N) - 1)
alpha = - beta + sqrt(pow(beta, 2) + 2*beta)

//Lag
lag = (per - 1)/(2*N)

//Data
srcdata = modeLag ? src + (src - src[lag]) : src
trdata  = modeLag ? tr(true) + (tr(true) - tr(true)[lag]) : tr(true)

//Filtered Values
[filtn, filt1]     = f_pole(alpha, srcdata, N)
[filtntr, filt1tr] = f_pole(alpha, trdata,  N)

//Lag Reduction
filt   = modeFast ? (filtn + filt1)/2 : filtn
filttr = modeFast ? (filtntr + filt1tr)/2 : filtntr

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

// Colors
color1   = #0aff68
color2   = #00752d
color3   = #ff0a5a
color4   = #990032
fcolor   = filt > filt[1] ? #0aff68 : filt < filt[1] ? #ff0a5a : #cccccc
barcolor = (src > src[1]) and (src > filt) and (src < hband) ? #0aff68 : (src > src[1]) and (src >= hband) ? #0aff1b : (src <= src[1]) and (src > filt) ? #00752d : 
           (src < src[1]) and (src < filt) and (src > lband) ? #ff0a5a : (src < src[1]) and (src <= lband) ? #ff0a11 : (src >= src[1]) and (src < filt) ? #990032 : #cccccc

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Outputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Filter Plot
filtplot = plot(filt, title="Filter", color=fcolor, linewidth=3)

//Band Plots
hbandplot = plot(hband, title="Filtered True Range High Band", color=fcolor)
lbandplot = plot(lband, title="Filtered True Range Low Band", color=fcolor)

//Channel Fill
fill(hbandplot, lbandplot, title="Channel Fill", color=fcolor, transp=80)

//Bar Color
barcolor(barcolor)


longCondition = crossover(close, hband) and timeCondition
closeAllCondition = crossunder(close, hband) and timeCondition

if longCondition
    strategy.entry("long", strategy.long)

if closeAllCondition
    strategy.close("long")

Thêm nữa