戦略をフォローするガウス運河の傾向

作者: リン・ハーンチャオチャン開催日:2024年3月29日 16:26:26
タグ:

img

概要

ガウスチャンネルのトレンドフォロー戦略 (Gaussian Channel Trend Following Strategy) は,ガウスチャンネルの指標に基づいたトレンドフォロー戦略である.この戦略は,市場における主要なトレンドを把握し,上向きのトレンド中に買い出し,保持し,下向きのトレンド中にポジションを閉じることを目的としている.これは,ガウスチャンネルの指標を使用して,価格とチャネルの上下帯の関係を分析してトレンドの方向性と強さを特定する.この戦略の主な目標は,持続的なトレンドの間に利益を最大化し,レンジ・バインド・トレード市場での取引頻度を最小化することである.

戦略原則

ガウスチャネルトレンドフォロー戦略の核心は,エラーズによって提案されたガウスチャネル指標である.これはトレンド活動を分析するために,ガウスチャネルフィルタリング技術とトゥールレンジを組み合わせている.指標は,まずサンプリング期間とポール数に基づいてベータとアルファ値を計算し,次にスムーズカーブ (ミッドライン) を取得するためにデータにフィルターを適用する.次に,戦略は,スムーズなトゥールレンジを倍数で倍数で上下チャネルを生成する.価格が上下チャネルを超えると,購入/売却信号を生成する.さらに,戦略は,遅延を減らす機能と迅速な応答モードを提供しています.

戦略 の 利点

  1. トレンドフォロー: この戦略は,市場の主要なトレンドを把握し,トレンドの方向に投資し,長期的に安定したリターンを達成するのに役立ちます.
  2. 低取引頻度: 戦略は,トレンドが確認されたときにのみポジションを入力し,トレンド中にポジションを維持し,不必要な取引と取引コストを削減します.
  3. 遅延削減: 遅延を減らすモードと迅速な応答モードによって,戦略は市場の変化により迅速に反応することができます.
  4. 柔軟なパラメータ: 戦略のパフォーマンスを最適化するために,サンプリング期間,ポール数,真の範囲倍数など,ユーザーが必要に応じて戦略パラメータを調整できます.

戦略リスク

  1. パラメータ最適化リスク: パラメータの設定が正しくない場合,戦略のパフォーマンスが低下する可能性があります.最適なパラメータ組み合わせを見つけるために,異なる市場環境でパラメータ最適化とバックテストを実行することが推奨されます.
  2. トレンド逆転リスク:市場のトレンドが突然逆転すると,戦略は重大な引き下げを経験する可能性があります.これはストップロスを設定したり,リスクを制御するための他の指標を導入することによって軽減することができます.
  3. 範囲限定市場リスク:範囲限定市場では,戦略が頻繁な取引信号を生成し,収益が低下する可能性があります. これはパラメータを最適化したり,他の技術指標と組み合わせてシグナルをフィルタリングすることによって対処できます.

戦略の最適化方向

  1. 他の技術指標を組み込む:他のトレンドフォローまたはオシレーター指標,MACD,RSIなどと組み合わせ,信号の正確性と信頼性を向上させる.
  2. ダイナミックパラメータ最適化: 市場の状況の変化に基づいて戦略パラメータをダイナミックに調整し,異なる市場環境に適応します.
  3. リスク管理モジュールを追加する: 個々の取引リスクと総引き上げレベルを制御するために,合理的なストップ・ロースとテイク・プロフィートルールを設定する.
  4. 複数のタイムフレーム分析:日用チャートや4時間チャートなどの異なるタイムフレームからの信号を組み合わせて,より包括的な市場情報を得ます.

概要

ガウスチャンネルのトレンドフォロー戦略 (Gaussian Channel Trend Following Strategy) は,ガウスフィルタリング技術に基づいたトレンドフォロー戦略で,長期にわたる安定したリターンのための主要市場トレンドを把握することを目的としている.この戦略は,ギャウスチャンネルの指標を使用してトレンド方向と強さを特定し,遅れを軽減し迅速な応答を提供するための機能を提供している.この戦略の利点は,強いトレンドフォロー能力と低取引頻度にある.しかし,パラメータ最適化,トレンド逆転,レンジバインド市場などのリスクにも直面している.将来の最適化には,他の技術指標,ダイナミックパラメータ最適化,リスク制御モジュールを追加し,マルチタイムフレーム分析を含む.


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

//@version=5
strategy(title="Gaussian Channel Strategy v2.0", overlay=true, calc_on_every_tick=false, initial_capital=1000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1, slippage=3)

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
// Gaussian Channel Indicaor - courtesy of @DonovanWall
//----------------------------------------------------------------------------------------------------------------------------------------------------------------- 

// Date condition inputs
startDate = input(timestamp("1 January 2018 00:00 +0000"), "Date Start", group="Main Algo Settings")
endDate = input(timestamp("1 January 2060 00:00 +0000"), "Date Start", group="Main Algo Settings")
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 :=   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)

// 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.int(defval=4, title="Poles", minval=1, maxval=9)

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

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

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

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

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

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

// Data
srcdata = modeLag ? src + (src - src[lag]) : src
trdata  = modeLag ? ta.tr(true) + (ta.tr(true) - ta.tr(true)[lag]) : ta.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=color.new(fcolor, 80))

// Bar Color
barcolor(barcolor)

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

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

if closeAllCondition
    strategy.close("long")

もっと