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


Ngày tạo: 2024-03-28 18:08:18 sửa đổi lần cuối: 2024-03-28 18:08:18
sao chép: 0 Số nhấp chuột: 1117
1
tập trung vào
1617
Người theo dõi

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

Tổng quan

Chiến lược Gaussian Channel Adaptive Equilibrium là một chiến lược giao dịch định lượng sử dụng kỹ thuật Gaussian Ripple và thiết lập tham số thích ứng. Chiến lược này dựa trên lý thuyết Gaussian Ripple do John Ehlers đưa ra, tạo ra tín hiệu giao dịch mượt mà và thích ứng bằng cách tính toán trung bình di chuyển chỉ số nhiều lần trên dữ liệu giá.

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

Các nguyên tắc của Gauss’s channel tự thích ứng với chiến lược đường thẳng như sau:

  1. Tính giá trị Gaussian. Các tham số Beta và Alpha được tính dựa trên chu kỳ lấy mẫu và số điểm cực được thiết lập bởi người dùng, sau đó dữ liệu giá được phân loại theo Gaussian và có chuỗi giá được xử lý trơn tru.
  2. Tính toán các giá trị Gaussian của độ dao động thực sự. Xử lý Gaussian tương tự với độ dao động thực sự của giá, để có được một chuỗi độ dao động mịn.
  3. Xây dựng đường Gaussian. Với giá sau sóng Gaussian là đường trung tâm, đường trên được tính bằng đường trung tâm cộng với độ dao động thực tế và nhân số được thiết lập bởi người dùng, đường dưới được tính bằng đường trung tâm trừ đi giá trị này, tạo thành một đường động.
  4. Tạo tín hiệu giao dịch. Khi giá vượt qua kênh lên, tạo tín hiệu mua; Khi giá vượt qua kênh xuống, tạo tín hiệu bán.
  5. Nhập tham số khoảng thời gian. Người dùng có thể đặt thời gian bắt đầu và kết thúc hoạt động của chiến lược, trong khoảng thời gian đó chiến lược sẽ hoạt động theo tín hiệu giao dịch.

Phân tích lợi thế

Chiến lược tự điều chỉnh đường thẳng của Gaussian Channel có những ưu điểm sau:

  1. Khả năng thích ứng mạnh mẽ. Chiến lược sử dụng các tham số được điều chỉnh động, có thể thích ứng với các tình trạng thị trường khác nhau và các loại giao dịch, không cần thiết phải khởi động thủ công thường xuyên.
  2. Theo dõi xu hướng tốt. Bằng cách xây dựng kênh giá, chiến lược có thể nắm bắt và theo dõi xu hướng thị trường tốt hơn, tránh hiệu quả các tín hiệu giả trong thị trường biến động.
  3. Mức độ mượt tốt. Sử dụng công nghệ sóng cao để xử lý dữ liệu giá nhiều lần, loại bỏ phần lớn tiếng ồn thị trường, làm cho tín hiệu giao dịch đáng tin cậy hơn.
  4. Tính linh hoạt cao. Người dùng có thể điều chỉnh các tham số chính sách theo nhu cầu, chẳng hạn như chu kỳ lấy mẫu, số cực, số nhân dao động, v.v., để tối ưu hóa hiệu suất của chính sách.
  5. Tính thực tiễn mạnh mẽ. Các tham số khoảng thời gian được đưa ra để các chiến lược có thể hoạt động trong phạm vi thời gian được chỉ định, thuận tiện cho ứng dụng thực tế và nghiên cứu phản hồi.

Phân tích rủi ro

Mặc dù có nhiều ưu điểm, chiến lược tự điều chỉnh đường thẳng của Gauss vẫn có một số rủi ro:

  1. Rủi ro đặt tham số. Thiết lập tham số không phù hợp có thể dẫn đến thất bại của chiến lược hoặc hoạt động kém, do đó cần phải được thử nghiệm và tối ưu hóa nhiều lần trong ứng dụng thực tế.
  2. Rủi ro của sự kiện bất ngờ. Đối với một số sự kiện bất ngờ quan trọng, chiến lược có thể không phản ứng đúng lúc và gây thiệt hại.
  3. Rủi ro quá phù hợp. Nếu các tham số được đặt quá phù hợp với dữ liệu lịch sử, nó có thể dẫn đến việc chiến lược sẽ không hoạt động tốt trong tương lai, cần phải cân nhắc cả hoạt động trong và ngoài mẫu.
  4. Rủi ro tháo gỡ. Chiến lược này được áp dụng chủ yếu cho thị trường đang có xu hướng, và nếu giao dịch thường xuyên trong thị trường biến động, bạn có thể phải đối mặt với rủi ro tháo gỡ lớn hơn.

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

Các hướng tối ưu hóa cho chiến lược tự điều chỉnh đường thẳng của Gaussian Channel bao gồm:

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

Tóm tắt

Chiến lược tự thích ứng theo đường phẳng của Gauss là một chiến lược giao dịch định lượng dựa trên sóng Gauss và tham số tự thích ứng, tạo ra tín hiệu giao dịch trơn tru và đáng tin cậy bằng cách xây dựng kênh giá động. Chiến lược có các ưu điểm như khả năng thích ứng mạnh, theo dõi xu hướng tốt, tính trơn tru cao, linh hoạt cao, thực tiễn mạnh, nhưng đồng thời phải đối mặt với các rủi ro về thiết lập tham số, sự kiện bất ngờ, quá thích ứng và lợi nhuận.

Mã nguồn chiến lượ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")