La estrategia combina el filtro de predicción de Voss y el indicador de línea de tendencia instantánea de Ehlers para identificar los puntos de inflexión periódicos del mercado y realizar transacciones cuantitativas. El filtro de Voss emite señales de compra/venta con anticipación, mientras que el indicador de línea de tendencia instantánea se utiliza para determinar la dirección de la tendencia general y reducir la confusión del filtro de Voss en el mercado de tendencia.
El filtro de predicción de Voss proviene del artículo de John F. Ehlers A Peek Into The Future. La fórmula de cálculo del filtro es la siguiente:
_filt = 0.5 * _s3 * _x1 + _f1 * _s2 * _filt[1] - _s1 * _filt[2]
_voss = _x2 * _filt - _sumC
En el mismo,_x1 es la diferencia de un grado en el precio;_x2 es el factor de suavización;_s1、_s2、_s3 es el parámetro de filtración;_f1 es el parámetro de ciclo;_filt es el resultado de la filtración;_voss para la salida final.
Este filtro puede verse como un filtro de suavización, que enfatiza la información de los ciclos actuales y pasados, lo que emite una señal de compra/venta con anticipación. Debido a los retrasos de grupo inherentes, puede emitir una señal predictiva antes de otros indicadores, como si la lente viera hacia el futuro.
El indicador de línea de tendencia instantánea se calcula con la siguiente fórmula:
_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])
El indicador traza en tiempo real una línea de tendencia que coincide mejor con el precio, lo que permite determinar con precisión la dirección y la fuerza de la tendencia.
Se produce una señal de compra cuando Voss se corrige por un giro negativo y pasa el resultado de la filtración.
Cuando Voss pasa de positivo a negativo, y se produce una señal de venta en el resultado de la filtración inferior.
Al mismo tiempo, solo se emite una señal de negociación cuando el indicador de la línea de tendencia instantánea confirma la dirección de la tendencia. Esto puede filtrar las señales erróneas que el filtro Voss puede emitir en un mercado de tendencia.
El riesgo puede reducirse de la siguiente manera:
La estrategia se puede optimizar en los siguientes aspectos:
La estrategia integra el filtro Voss y los indicadores de tendencia, lo que permite identificar con eficacia los puntos de inflexión periódicos del mercado. A través de la optimización de los parámetros, el control del riesgo, la estrategia permite lograr un sistema de negociación cuantitativa estable. Se puede aplicar ampliamente a las variedades con una clara periodicidad, que han demostrado un buen rendimiento comercial en la retroalimentación. En general, la estrategia tiene una capacidad de predicción única y puede optimizarse en muchos aspectos, con un amplio potencial de aplicación.
/*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()