Estratégia de negociação quantitativa baseada no filtro Voss e no indicador de tendência

Autora:ChaoZhang, Data: 2023-09-19 16:59:10
Tags:

Resumo

Esta estratégia combina o Filtro Preditivo Voss e o indicador de linha de tendência instantânea de Ehlers para identificar pontos de virada cíclicos no mercado para negociação quantitativa. O filtro Voss fornece sinais de compra / venda iniciais, enquanto o indicador de linha de tendência determina a direção geral da tendência para evitar enganos do filtro Voss em mercados de tendência. Esta estratégia funciona bem em instrumentos como o Bitcoin que exibem padrões cíclicos, como evidenciado por bons resultados de backtest.

Estratégia lógica

Filtro Preditivo Voss

O filtro Voss vem do artigo de John F. Ehlers A Peek Into The Future.

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

Onde _x1 é a diferença de preço da primeira ordem; _x2 é um fator de suavização; _s1, _s2, _s3 são parâmetros do filtro; _f1 é o parâmetro do ciclo; _filt é a saída do filtro; _voss é a saída final.

O filtro pode ser visto como um filtro suavizado que enfatiza as informações do ciclo atual e passado para gerar sinais iniciais.

Indicador de linha de tendência instantânea

O indicador da linha de tendência é calculado como:

_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]) 

Ele traça uma linha de tendência em tempo real que se encaixa intimamente na ação do preço, determinando com precisão a direção e a força da tendência.

Estratégia lógica

Um sinal de compra é gerado quando o Voss atravessa o resultado do filtro.

Um sinal de venda é gerado quando o Voss atravessa o resultado do filtro.

Os sinais de negociação só são aceites se forem confirmados pelo indicador de linha de tendência, evitando assim sinais errados do filtro Voss nos mercados de tendência.

Vantagens

  • O filtro Voss fornece sinais preditivos precoces para capturar curvas cíclicas
  • Indicador de linha de tendência determina com precisão a direção da tendência, evitando sinais errados
  • Os parâmetros podem ser otimizados para diferentes ciclos e ambientes de mercado
  • As paradas podem ser adicionadas para controlar o risco

Riscos e mitigação

  • A estratégia baseia-se em sinais iniciais, potencialmente perdendo algumas tendências
  • Os sinais de contra-tendência podem ocorrer em tendências fortes, causando perdas

Os riscos podem ser reduzidos:

  • Parâmetro de período de otimização para ciclos de instrumentos
  • Reduzir a largura de banda do filtro para diminuir os sinais falsos
  • Adicionar filtros de tendência para evitar sinais contra tendências fortes
  • Utilização de paradas para controlar perdas por transação

Oportunidades de melhoria

A estratégia pode ser melhorada:

  • Experimentando diferentes fontes de preços como fechamento, médias móveis, etc.
  • Período de ajuste do filtro para ciclos específicos do instrumento
  • Optimização dos parâmetros do indicador de tendência para uma melhor detecção da tendência
  • Tentar diferentes indicadores de tendência para melhores combinações
  • Adição de paradas, paradas de atraso para melhor controlo do risco
  • Optimização de parâmetros para os melhores conjuntos de parâmetros

Conclusão

Esta estratégia combina o filtro Voss e o indicador de tendência para identificar efetivamente as voltas cíclicas no mercado. Com parâmetros e controles de risco otimizados, pode produzir um sistema de negociação quantitativo robusto. É amplamente aplicável a instrumentos que exibem padrões cíclicos, como evidenciado por bons resultados 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()


Mais.