Stratégie des moyennes mobiles adaptatives du canal de Gauss

Auteur:ChaoZhang est là., Date: 2024-03-28 18h08 et 18h18
Les étiquettes:

img

Résumé

La stratégie des moyennes mobiles adaptatives du canal de Gauss est une stratégie de trading quantitative qui utilise des techniques de filtrage de Gauss et des paramètres adaptatifs. Basée sur la théorie du filtre de Gauss proposée par John Ehlers, cette stratégie génère des signaux de trading fluides et adaptatifs en appliquant plusieurs calculs de moyennes mobiles exponentielles aux données des prix.

Principes de stratégie

Les principes de la stratégie des moyennes mobiles adaptatives du canal de Gauss sont les suivants:

  1. Calculer la valeur du filtre gaussien du prix. Sur la base de la période d'échantillonnage définie par l'utilisateur et du nombre de pôles, les paramètres bêta et alpha sont calculés, puis les données de prix subissent un filtrage gaussien à plusieurs niveaux pour obtenir une série de prix lissée.
  2. Calculer la valeur du filtre gaussien de la plage réelle. Le même processus de filtrage gaussien est appliqué à la plage réelle du prix, ce qui donne une série de plage lissée.
  3. Construisez le canal de Gauss. Le prix filtré par Gauss sert de bande moyenne, la bande supérieure est formée en ajoutant le produit de la plage réelle filtrée et un multiplicateur défini par l'utilisateur à la bande moyenne, et la bande inférieure est formée en soustrayant cette valeur de la bande moyenne, créant un canal dynamique.
  4. Générer des signaux de trading. Lorsque le prix dépasse la bande supérieure du canal, un signal d'achat est généré; lorsque le prix dépasse la bande inférieure, un signal de vente est généré.
  5. Les utilisateurs peuvent définir les heures de début et de fin pour l'exécution de la stratégie, et la stratégie ne fonctionnera que sur la base des signaux de trading dans cette période de temps spécifiée.

Analyse des avantages

La stratégie des moyennes mobiles adaptatives du canal de Gauss présente les avantages suivants:

  1. La stratégie utilise des paramètres dynamiquement ajustés qui peuvent s'adapter aux différentes conditions du marché et aux différents instruments de négociation sans nécessiter de réglage manuel fréquent.
  2. Une bonne capacité de suivi des tendances. En construisant des canaux de prix, la stratégie peut capturer et suivre efficacement les tendances du marché, en évitant de faux signaux sur les marchés instables.
  3. La technique de filtrage gaussienne est utilisée pour lisser les données de prix plusieurs fois, éliminant la plupart des bruits du marché et rendant les signaux de trading plus fiables.
  4. Les utilisateurs peuvent ajuster les paramètres de la stratégie en fonction de leurs besoins, tels que la période d'échantillonnage, le nombre de pôles, le multiplicateur de gamme, etc., afin d'optimiser les performances de la stratégie.
  5. L'introduction de paramètres de période de temps permet à la stratégie de fonctionner dans une plage de temps spécifiée, facilitant l'application dans le monde réel et la recherche de backtesting.

Analyse des risques

Malgré ses nombreux avantages, la stratégie des moyennes mobiles adaptatives du canal de Gauss comporte encore certains risques:

  1. Les paramètres inappropriés peuvent entraîner l'inefficacité de la stratégie ou de mauvaises performances, nécessitant des tests et une optimisation répétés dans les applications pratiques.
  2. Risque d'événement soudain: face à certains événements soudains majeurs, la stratégie peut ne pas être en mesure de réagir correctement et en temps opportun, ce qui entraîne des pertes.
  3. Si les paramètres sont trop adaptés aux données historiques, la stratégie peut mal fonctionner à l'avenir, ce qui nécessite de prendre en considération les performances à la fois dans l'échantillon et en dehors de l'échantillon.
  4. Le risque d'arbitrage: la stratégie est principalement adaptée aux marchés en tendance, et les transactions fréquentes sur des marchés instables peuvent présenter des risques d'arbitrage importants.

Directions d'optimisation

Les directions d'optimisation de la stratégie de moyenne mobile adaptative du canal de Gauss comprennent:

  1. Optimisation dynamique des paramètres. En introduisant l'apprentissage automatique et d'autres techniques, obtenir une optimisation automatique et un ajustement dynamique des paramètres de stratégie pour améliorer l'adaptabilité.
  2. Combinez d'autres indicateurs ou facteurs techniques efficaces avec le canal de Gauss pour former des signaux commerciaux plus robustes.
  3. Optimisation de la gestion des positions: intégrer des règles raisonnables de gestion des positions et de gestion de l'argent dans la stratégie pour contrôler les retraits et les risques.
  4. Coordination multi-instruments: étendre la stratégie à plusieurs instruments de négociation différents et diversifier les risques par l'allocation des actifs et l'analyse des corrélations.

Résumé

La stratégie des moyennes mobiles adaptatives de canal de Gauss est une stratégie de trading quantitative basée sur le filtrage et les paramètres adaptatifs de Gauss, qui génère des signaux de trading fluides et fiables en construisant dynamiquement des canaux de prix. La stratégie présente des avantages tels qu'une forte adaptabilité, une bonne capacité de suivi des tendances, une grande fluidité, une grande souplesse et une grande praticité.


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

Plus de