리소스 로딩... 로딩...

가우스 채널 적응 이동 평균 전략

저자:차오장, 날짜: 2024-03-28 18:08:18
태그:

img

전반적인 설명

가우스 채널 적응 이동 평균 전략 (Gaussian Channel Adaptive Moving Average Strategy) 은 가우스 필터링 기법과 적응 매개 변수 설정을 활용한 양적 거래 전략이다. 존 에일러스가 제안한 가우스 필터 이론을 기반으로, 이 전략은 여러 기하급수적 이동 평균 계산을 가격 데이터에 적용하여 원활하고 적응적인 거래 신호를 생성한다. 전략의 핵심은 가우스 필터링 가격에서 필터링 된 진정한 범위를 더하고 빼면서 얻는 상부 및 하부 대역으로 동적으로 조정된 가격 채널을 구축하는 것이다. 가격이 상부 대역을 넘으면 긴 포지션을 입력하고, 하부 대역을 넘으면 짧은 포지션을 입력한다. 또한, 전략은 시간 기간 설정을 도입하여 전략 실행의 시작 및 종료 시간을 유연하게 설정하여 실용성을 향상시킨다.

전략 원칙

가우스 채널 적응 이동 평균 전략의 원칙은 다음과 같습니다.

  1. 가격의 가우스 필터 값을 계산한다. 사용자 정의 샘플링 기간과 극의 수를 기반으로, 베타와 알파 매개 변수를 계산하고, 그 다음 가격 데이터는 매끄러운 가격 시리즈를 얻기 위해 다단계 가우스 필터링을 받는다.
  2. 실제 범위의 가우스 필터 값을 계산한다. 동일한 가우스 필터링 프로세스는 가격의 실제 범위에 적용되어 평형 범위 시리즈가 생성된다.
  3. 가우스 채널을 구성합니다. 가우스 필터링 가격은 중간 대역으로 작용하며, 상단 대역은 필터링 된 진정한 범위의 곱과 사용자 정의 곱자를 중간 대역에 추가하여 형성되며, 하단 대역은 이 값을 중간 대역에서 빼어 동적 채널을 생성하여 형성됩니다.
  4. 거래 신호를 생성합니다. 가격이 채널의 상단 범위를 넘으면 구매 신호가 생성됩니다. 가격이 하단 범위를 넘으면 판매 신호가 생성됩니다.
  5. 시간 기간 매개 변수를 소개합니다. 사용자는 전략 실행의 시작 및 종료 시간을 설정할 수 있으며 전략은 이 지정된 시간 내에 거래 신호를 기반으로만 작동합니다.

이점 분석

가우스 채널 적응 이동 평균 전략은 다음과 같은 장점을 가지고 있습니다.

  1. 강력한 적응력: 전략은 동적으로 조정되는 매개 변수를 사용하여 자주 수동 조정이 필요하지 않고 다른 시장 조건과 거래 도구에 적응 할 수 있습니다.
  2. 좋은 트렌드 추적 능력. 가격 채널을 구축함으로써 전략은 시장 트렌드를 효과적으로 포착하고 추적 할 수 있으며 불안정한 시장에서 잘못된 신호를 피할 수 있습니다.
  3. 탁월한 평형화. 가우스 필터링 기술은 가격 데이터를 여러 번 평형화하여 대부분의 시장 소음을 제거하고 거래 신호를 더 신뢰할 수 있도록합니다.
  4. 높은 유연성: 사용자는 샘플링 기간, 폴 수, 범위 곱기 등과 같은 전략 매개 변수를 자신의 필요에 따라 조정하여 전략의 성능을 최적화 할 수 있습니다.
  5. 강력한 실용성. 시간 기간 매개 변수 도입은 전략이 지정된 시간 범위 내에서 실행되도록 허용하며 실제 세계 응용 및 백테스팅 연구를 촉진합니다.

위험 분석

많은 장점에도 불구하고 가우스 채널 적응 이동 평균 전략은 여전히 특정 위험을 초래합니다.

  1. 매개 변수 설정 위험: 부적절한 매개 변수 설정은 전략의 비효율성 또는 낮은 성능을 초래할 수 있으며, 실제 응용 프로그램에서 반복 테스트 및 최적화를 요구합니다.
  2. 갑작스러운 이벤트 위험: 갑작스러운 주요 이벤트에 직면하면 전략은 적시에 올바르게 반응하지 않을 수 있으며 손실이 발생할 수 있습니다.
  3. 과도한 적합성 위험: 매개 변수 설정이 역사 데이터에 너무 밀접하게 맞추어지면 전략은 미래에 성능이 좋지 않을 수 있으며 표본 내 및 표본 외 성능이 모두 고려되어야합니다.
  4. 중재 위험: 이 전략은 주로 트렌딩 시장에 적합하며 불안정한 시장에서 자주 거래하면 상당한 중재 위험이 발생할 수 있습니다.

최적화 방향

가우스 채널 적응 이동 평균 전략의 최적화 방향은 다음과 같습니다.

  1. 동적 매개 변수 최적화 기계 학습 및 다른 기술을 도입하여 적응력을 향상시키기 위해 전략 매개 변수 자동 최적화 및 동적 조정.
  2. 다중 요인 융합: 다른 효과적인 기술 지표 또는 요인을 가우스 채널과 결합하여 더 강력한 거래 신호를 형성합니다.
  3. 포지션 관리 최적화. 적당한 포지션 관리 및 자금 관리 규칙을 전략에 포함하여 마감 및 위험을 제어하십시오.
  4. 다중 도구 조정: 여러 가지 다른 거래 도구에 전략을 확장하고 자산 할당 및 상관 분석을 통해 위험을 다양화하십시오.

요약

가우스 채널 적응 이동 평균 전략 (Gaussian Channel Adaptive Moving Average Strategy) 은 가우스 필터링과 적응 매개 변수에 기반을 둔 양적 거래 전략으로, 동적으로 가격 채널을 구성하여 원활하고 신뢰할 수있는 거래 신호를 생성합니다. 이 전략은 강력한 적응력, 좋은 트렌드 추적 능력, 높은 매끄럽기, 큰 유연성 및 강력한 실용성 등의 장점이 있습니다. 그러나 매개 변수 설정, 갑작스러운 이벤트, 과잉 적합성 및 중재 등 위험도 있습니다. 미래에 이 전략은 동적 매개 변수 최적화, 멀티 팩터 융합, 위치 관리 최적화 및 멀티 인스트루먼트 조정을 통해 더욱 정밀화 및 향상 될 수 있습니다.


/*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")

더 많은