Stratégie de négociation quantitative basée sur le filtre Voss et l'indicateur de tendance

Auteur:ChaoZhang est là., Date: le 19 septembre 2023 à 16 h 59.
Les étiquettes:

Résumé

Cette stratégie combine le filtre prédictif de Voss et l'indicateur de tendance instantanée d'Ehlers pour identifier les points tournants cycliques sur le marché pour le trading quantitatif.

La logique de la stratégie

Filtre prédictif Voss

Le filtre Voss provient de l'article de John F. Ehlers A Peek Into The Future. Son calcul est le suivant:

_filt = 0.5 * _s3 * _x1 + _f1 * _s2 * _filt[1] - _s1 * _filt[2] 
_voss = _x2 * _filt - _sumC

où _x1 est la différence de prix de 1er ordre; _x2 est un facteur de lissage; _s1, _s2, _s3 sont les paramètres du filtre; _f1 est le paramètre du cycle; _filt est la sortie du filtre; _voss est la sortie finale.

Le filtre peut être considéré comme un filtre lissé qui met l'accent sur les informations du cycle actuel et passé pour générer des signaux précoces.

Indicateur instantané de tendance

L'indicateur de tendance est calculé comme suit:

_it = (_a-((_a*_a)/4.0))*_src+0.5*_a*_a*_src[1]-(_a-0.75*_a*_a)*_src[2]+2*(1-_a)*nz(_it[1])+-(1-_a)*(1-_a)*nz(_it[2]) 

Il trace une ligne de tendance en temps réel qui correspond étroitement à l'action des prix, déterminant avec précision la direction et la force de la tendance.

La logique de la stratégie

Un signal d'achat est généré lorsque le Voss traverse le résultat du filtre.

Un signal de vente est généré lorsque le Voss traverse le résultat du filtre.

Les signaux de négociation ne sont acceptés que s'ils sont confirmés par l'indicateur de tendance, ce qui évite les signaux erronés du filtre Voss sur les marchés en tendance.

Les avantages

  • Le filtre Voss fournit des signaux prédictifs précoces pour attraper les virages cycliques
  • L'indicateur de ligne de tendance détermine avec précision la direction de la tendance, évitant ainsi de mauvais signaux
  • Les paramètres peuvent être optimisés pour différents cycles et environnements de marché
  • Des arrêts peuvent être ajoutés pour contrôler le risque

Risques et atténuation

  • La stratégie repose sur des signaux précoces, qui pourraient manquer certaines tendances
  • Des signaux de contre-trend peuvent apparaître dans des tendances fortes, provoquant des pertes

Les risques peuvent être réduits par:

  • Paramètre de période d'optimisation pour les cycles d'instrumentation
  • Réduction de la bande passante du filtre pour réduire les faux signaux
  • Ajout de filtres de tendance pour éviter les signaux contre les fortes tendances
  • Utilisation des arrêts pour contrôler les pertes par transaction

Des possibilités d'amélioration

La stratégie peut être améliorée par:

  • Essayez différentes sources de prix comme les moyennes mobiles, etc.
  • Période de réglage du filtre pour les cycles spécifiques de l'instrument
  • Optimisation des paramètres des indicateurs de tendance pour une meilleure détection des tendances
  • Essayez différents indicateurs de tendance pour de meilleures combinaisons
  • Ajout d'arrêts, d'arrêts de trail pour un meilleur contrôle des risques
  • Optimisation des paramètres pour les meilleurs ensembles de paramètres

Conclusion

Cette stratégie combine le filtre Voss et l'indicateur de tendance pour identifier efficacement les virages cycliques sur le marché. Avec des paramètres optimisés et des contrôles des risques, elle peut produire un système de trading quantitatif robuste. Elle est largement applicable aux instruments présentant des modèles cycliques, comme en témoignent de bons résultats de backtest.


/*backtest
start: 2023-08-19 00:00:00
end: 2023-09-18 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// A Peek Into the Future
// John F. Ehlers
// TASC Aug 2019

// Created by e2e4mfck for tradingview.com
// Modified by © Bitduke

//@version=4
//strategy("Voss Strategy (Filter + IT)", overlay=false, calc_on_every_tick=false,pyramiding=0, default_qty_type=strategy.cash,default_qty_value=1000, currency=currency.USD, initial_capital=1000,commission_type=strategy.commission.percent, commission_value=0.075)

// voss filter

source = input(close, type = input.source)
period = input(20, type = input.integer)
predict = input(4, type = input.integer)
bandwidth = input(0.25, type = input.float)

// it trendline

src = input(hl2, title="Source IT")
a = input(0.07, title="Alpha", step=0.01) 
fr = input(false, title="Fill Trend Region")
ebc = input(false, title="Enable barcolors")
hr = input(false, title="Hide Ribbon")


voss_filter (_period, _predict, _bandwidth, _source) =>
	float _filt = 0, float _sumC = 0, float _voss = 0
	_PI		= 2 * asin(1)
	_order	= 3 * _predict
	_f1		= cos(2 * _PI / _period)
	_g1		= cos(_bandwidth * 2 * _PI / _period)
	_s1		= 1 / _g1 - sqrt(1 / (_g1 * _g1) - 1)
	_s2		= 1 + _s1
	_s3		= 1 - _s1
	_x1		= _source - _source[2]
	_x2		= (3 + _order) / 2

	for _i = 0 to (_order - 1)
		_sumC := _sumC + ((_i + 1) / _order) * _voss[_order - _i]

	if bar_index <= _order
		_filt := 0		
		_voss := 0		
	else			
		_filt := 0.5 * _s3 * _x1 + _f1 * _s2 * _filt[1] - _s1 * _filt[2]
		_voss := _x2 * _filt - _sumC

	[_voss, _filt]


[Voss, Filt] = voss_filter(period, predict, bandwidth, source)


instantaneous_trendline (_src, _a, _freq, _ebc, _hr) =>
    _it = 0.0
    _it := (_a-((_a*_a)/4.0))*_src+0.5*_a*_a*_src[1]-(_a-0.75*_a*_a)*_src[2]+2*(1-_a )*nz(_it[1], ((_src+2*_src[1]+_src[2])/4.0))-(1-_a)*(1-_a)*nz(_it[2], ((_src+2*_src[1]+_src[2])/4.0))
    _lag = 2.0*_it-nz(_it[2])
    
    [_it, _lag]

[it, lag] = instantaneous_trendline(src, a, fr, ebc, hr)

// - - - - -  - - - - - //

plot(Filt, title = "Filter", style = plot.style_line, color = color.red, linewidth = 2)
plot(Voss, title = "Voss", style = plot.style_line, color = color.blue,	linewidth = 2)
hline(0.0, title = "Zero", linestyle = hline.style_dashed, color = color.black,	linewidth = 1)
plot(hr? na:it, title="IT Trend", color= fr? color.gray : color.red, linewidth=1)
plot(hr? na:lag, title="IT Trigger", color=fr? color.gray : color.blue, linewidth=1)


// Strategy Logic
longCondition =  lag < it  and crossover(Voss,Filt) 
shortCondition = it > lag and crossover(Filt,Voss) 

strategy.entry("Voss_Short", strategy.short, when=shortCondition)
strategy.entry("Voss_Long", strategy.long, when=longCondition)


// === Backtesting Dates === thanks to Trost

testPeriodSwitch = input(true, "Custom Backtesting Dates")
testStartYear = input(2019, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testStartHour = input(0, "Backtest Start Hour")
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, testStartHour, 0)
testStopYear = input(2020, "Backtest Stop Year")
testStopMonth = input(2, "Backtest Stop Month")
testStopDay = input(29, "Backtest Stop Day")
testStopHour = input(0, "Backtest Stop Hour")
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, testStopHour, 0)
testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
testPeriod_1 = testPeriod()
isPeriod = true
// === /END

if not isPeriod
    strategy.cancel_all()
    strategy.close_all()


Plus de