Estrategia de inversión de tendencia basada en medias móviles múltiples

El autor:¿ Qué pasa?, Fecha: 2023-11-21 14:53:48
Las etiquetas:

img

Resumen general

Esta estrategia genera señales de compra y venta basadas en inversiones de múltiples indicadores de tendencia, incluidos TDI, TCF, TTF y TII. La estrategia permite seleccionar qué señal de indicador utilizar para entradas y salidas.

Estrategia lógica

  • Indicador de la IDT

    El indicador TDI se construye utilizando el impulso del precio con técnicas de sumación y suavización.

  • Indicador de FTC

    El indicador TCF mide los cambios positivos y negativos de precios para medir las fuerzas alcistas y bajistas.

  • Indicador TTF

    El indicador TTF compara la potencia de los precios más altos y más bajos para determinar la tendencia.

  • Indicador TII

    El TII combina el promedio móvil y las bandas de precios para identificar inversiones de tendencia.

La lógica de entrada larga y cercana selecciona las señales adecuadas en función del indicador configurado.

Ventajas

La estrategia incorpora varios indicadores de tendencia de negociación de uso común, lo que permite una flexibilidad para adaptarse a las condiciones cambiantes del mercado.

  1. Captura oportunamente las oportunidades de reversión de tendencia mediante señales de reversión
  2. Optimizable mediante la configuración de diferentes indicadores
  3. Las combinaciones ricas de indicadores se pueden utilizar para confirmar señales

Los riesgos

Los principales riesgos a los que se enfrenta esta estrategia:

  1. Las señales del indicador pueden tener señales falsas que resultan en pérdidas.
  2. Los indicadores individuales no pueden juzgar plenamente las tendencias y son susceptibles al ruido del mercado
  3. Las configuraciones incorrectas de los indicadores y parámetros de negociación pueden interpretar mal el mercado y generar operaciones erróneas

Los riesgos pueden reducirse:

  1. Optimización de los parámetros de los indicadores para encontrar las mejores combinaciones
  2. Requerir confirmaciones de señales múltiples para mejorar la calidad
  3. Ajuste del tamaño de las posiciones para controlar las pérdidas de operaciones únicas

Oportunidades de mejora

La estrategia puede mejorarse en varios ámbitos:

  1. Prueba de indicadores y parámetros óptimos en diferentes ciclos de mercado
  2. Añadir o reducir indicadores para encontrar las mejores combinaciones
  3. Filtra las señales falsas
  4. Optimizar las estrategias de dimensionamiento de posiciones, por ejemplo, tamaño variable, stop loss de seguimiento
  5. Incorporar puntuación de aprendizaje automático para ayudar con la calidad de la señal

Conclusión

Al combinar múltiples indicadores de reversión de tendencia y configuraciones de optimización, esta estrategia es adaptable a diferentes entornos de mercado para operar en puntos de inflexión de tendencia. La clave es encontrar los parámetros e indicadores óptimos mientras se controla el riesgo. Las optimizaciones y validaciones continuas pueden construir una estrategia alfa estable.


/*backtest
start: 2023-11-13 00:00:00
end: 2023-11-15 03:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © kruskakli
//
// Here is a collection of Trend Indicators as defined by M.H Pee and presented
// in various articles of the "STOCKS & COMMODITIES Magazine"
//
// The actual implementation of the indicators here are made by: everget
//
// I have gather them here so that they easily can be tested.
//
// My own test was made using 15 companies from the OMXS30 list
// during the time period of 2016-2018, and I only went LONG.
//
// The result was as follows:
//
//        Average    Std.Dev
//        profit
//  TDI    3.04%      5.97
//  TTF    1.22%.     5.73
//  TII    1.07%      6.2
//  TCF    0.32%      2.68
//
strategy("M.H Pee indicators", overlay=true)


use = input(defval="TDI", title="Use Indicator", type=input.string,
             options=["TDI","TCF","TTF","TII"])

src = close


//
// TDI
//
length = input(title="Length", type=input.integer, defval=20)
mom = change(close, length)
tdi = abs(sum(mom, length)) - sum(abs(mom), length * 2) + sum(abs(mom), length)
// Direction Indicator
tdiDirection = sum(mom, length)
tdiLong = crossover(tdiDirection, tdi)
tdiXLong = crossunder(tdiDirection, tdi)

//
// TCF
//
tcflength = input(title="Length", type=input.integer, defval=35)

plusChange(src) =>
    change_1 = change(src)
    change(src) > 0 ? change_1 : 0.0
minusChange(src) =>
    change_1 = change(src)
    change(src) > 0 ? 0.0 : -change_1

plusCF = 0.0
plusChange__1 = plusChange(src)
plusCF := plusChange(src) == 0 ? 0.0 : plusChange__1 + nz(plusCF[1])

minusCF = 0.0
minusChange__1 = minusChange(src)
minusCF := minusChange(src) == 0 ? 0.0 : minusChange__1 + nz(minusCF[1])

plusTCF = sum(plusChange(src) - minusCF, tcflength)
minusTCF = sum(minusChange(src) - plusCF, tcflength)

tcfLong = plusTCF > 0 
tcfXLong = plusTCF < 0

//
// TTF
//
ttflength = input(title="Lookback Length", type=input.integer, defval=15)

hh = highest(length)
ll = lowest(length)

buyPower = hh - nz(ll[length])
sellPower = nz(hh[length]) - ll

ttf = 200 * (buyPower - sellPower) / (buyPower + sellPower)

ttfLong = crossover(ttf, 100)
ttfXLong = crossunder(ttf, -100)

//
// TII
//
majorLength = input(title="Major Length", type=input.integer, defval=60)
minorLength = input(title="Minor Length", type=input.integer, defval=30)
upperLevel = input(title="Upper Level", type=input.integer, defval=80)
lowerLevel = input(title="Lower Level", type=input.integer, defval=20)

sma = sma(src, majorLength)

positiveSum = 0.0
negativeSum = 0.0

for i = 0 to minorLength - 1 by 1
    price = nz(src[i])
    avg = nz(sma[i])
    positiveSum := positiveSum + (price > avg ? price - avg : 0)
    negativeSum := negativeSum + (price > avg ? 0 : avg - price)
    negativeSum

tii = 100 * positiveSum / (positiveSum + negativeSum)

tiiLong = crossover(tii, 80)
tiiXLong = crossunder(tii,80)

//
// LOGIC 
//
enterLong = (use == "TDI" and tdiLong) or (use == "TCF" and tcfLong) or (use == "TTF" and ttfLong) or (use == "TII" and tiiLong)
exitLong = (use == "TDI" and tdiXLong) or (use == "TCF" and tcfXLong) or (use == "TTF" and ttfXLong) or (use == "TII" and tiiXLong)


// Time range for Back Testing
btStartYear  = input(title="Back Testing Start Year",  type=input.integer, defval=2016)
btStartMonth = input(title="Back Testing Start Month", type=input.integer, defval=1)
btStartDay   = input(title="Back Testing Start Day",   type=input.integer, defval=1)
startTime = timestamp(btStartYear, btStartMonth, btStartDay, 0, 0)

btStopYear  = input(title="Back Testing Stop Year",  type=input.integer, defval=2028)
btStopMonth = input(title="Back Testing Stop Month", type=input.integer, defval=12)
btStopDay   = input(title="Back Testing Stop Day",   type=input.integer, defval=31)
stopTime  = timestamp(btStopYear, btStopMonth, btStopDay, 0, 0)

window() => time >= startTime and time <= stopTime ? true : false


riskPerc     = input(title="Max Position  %", type=input.float, defval=20, step=0.5)
maxLossPerc  = input(title="Max Loss Risk %", type=input.float, defval=5, step=0.25)

// Average True Range (ATR) measures market volatility.
// We use it for calculating position sizes.
atrLen   = input(title="ATR Length", type=input.integer, defval=14)
stopOffset = input(title="Stop Offset", type=input.float, defval=1.5, step=0.25)
limitOffset = input(title="Limit Offset", type=input.float, defval=1.0, step=0.25)
atrValue = atr(atrLen)


// Calculate position size
maxPos = floor((strategy.equity * (riskPerc/100)) / src)
// The position sizing algorithm is based on two parts:
// a certain percentage of the strategy's equity and
// the ATR in currency value.
riskEquity  = (riskPerc / 100) * strategy.equity
// Translate the ATR into the instrument's currency value.
atrCurrency = (atrValue * syminfo.pointvalue)
posSize0    = min(floor(riskEquity / atrCurrency), maxPos)
posSize     = posSize0 < 1 ? 1 : posSize0

if (window())
    strategy.entry("Long", long=true, qty=posSize0, when=enterLong)
    strategy.close_all(when=exitLong)

Más.