Sistema de seguimiento de tendencias de reequilibrio dinámico de posición

El autor:¿ Qué pasa?, fecha: 2024-01-26 14:41:08
Las etiquetas:

img

Resumen general

Esta estrategia integra el sistema de cruce de media móvil exponencial y el sistema de negociación de tortuga, dos estrategias comerciales sistemáticas populares.

Estrategia lógica

La estrategia contiene dos subestrategias: estrategia de tendencia y estrategia de ruptura.

La estrategia de tendencia utiliza EMA rápido y cruces de EMA lento como señales de negociación. El período de EMA rápido es definido por el usuario y el período de EMA lento es 5 veces el EMA rápido. La señal se genera dividiendo la diferencia de EMA por la desviación estándar de retorno de 252 períodos, que se ajusta a la volatilidad para producir señales más confiables.

La estrategia de ruptura utiliza el promedio de los precios más altos y más bajos durante un período de retroceso fijo como línea de base.

El tamaño de la posición se basa en la volatilidad de precios reciente y el objetivo de riesgo anual definido por el usuario. Se toma un tamaño más grande cuando la volatilidad es baja, mientras que se toma un tamaño más pequeño cuando la volatilidad es alta. Esto realiza una gestión dinámica de la posición con ajuste de riesgo.

Las paradas duras se establecen como múltiplos del rango verdadero promedio.

Análisis de ventajas

Las principales ventajas de esta estrategia incluyen:

  1. La combinación de las subestrategias de seguimiento de tendencias y de ruptura se adapta a diferentes entornos de mercado con una gran robustez.

  2. La aplicación de técnicas avanzadas de dimensionamiento de posiciones y gestión de riesgos permite gestionar dinámicamente la posición y controlar eficazmente el riesgo.

  3. Las posiciones de ajuste de volatilidad basadas en la volatilidad reciente y el objetivo de riesgo anual mantienen un riesgo de cartera relativamente estable en regímenes de alta/baja volatilidad.

  4. El establecimiento de la parada de pérdida basado en la fluctuación real de precios evita pérdidas innecesarias pequeñas de las carreras de parada.

  5. El ajuste de la parada de trailing en tiempo real sigue de forma flexible las tendencias para registrar ganancias y se detiene a tiempo.

Análisis de riesgos

Los principales riesgos de esta estrategia son:

  1. Dependencia de la optimización de parámetros: los diferentes parámetros afectan considerablemente el rendimiento de la estrategia, por lo que se necesitan pruebas integrales para encontrar parámetros óptimos.

  2. Se podrían relajar los límites de pérdida y optimizar los mecanismos de detención.

  3. Sensibilidad al capital inicial y a los costes de negociación: el capital inicial insuficiente y los altos costes de negociación afectan negativamente a la rentabilidad.

  4. Confianza en estimaciones precisas de volatilidad para el tamaño de las posiciones y los controles de riesgos.

Direcciones de optimización

Las principales direcciones de optimización incluyen:

  1. Búsqueda de conjuntos de parámetros óptimos a través de más backtesting con un conjunto de datos histórico más grande.

  2. Mejorar los mecanismos de parada mediante la prueba de varias paradas como paradas en movimiento, paradas de tiempo, paradas de volatilidad, etc.

  3. Optimizar el tamaño de las posiciones y la gestión del riesgo mediante la prueba de diferentes objetivos de riesgo para encontrar el mejor perfil de riesgo-rendimiento.

  4. Prueba más indicadores auxiliares para mejorar la precisión de la señal y la robustez de la estrategia.

  5. Prueba diferentes períodos de retención ayudando a las decisiones con señales de marcos de tiempo más altos para mejorar la precisión de la asignación de posiciones.

Conclusión

Esta estrategia integra dos categorías principales de estrategias comerciales: seguimiento de tendencias y rupturas. Al aplicar técnicas avanzadas de ajuste de posición dinámica, controla eficazmente el riesgo mientras sigue los movimientos del mercado hacia la ganancia. Demuestra un fuerte potencial de ganancia y vale la pena probar y optimizar aún más.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Crunchster1

//@version=5
strategy(title="Crunchster's Turtle and Trend System", shorttitle="Turtle Trend", overlay=true, slippage=10, pyramiding=1, precision = 4, calc_on_order_fills = false, calc_on_every_tick = false, default_qty_value = 0.1, initial_capital = 1000, commission_value = 0.06, process_orders_on_close = true)

// Inputs and Parameters
src = input(close, 'Source', group='Strategy Settings')
length = input.int(title="Lookback period for fast EMA", defval=10, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the fast exponential moving average. The slow EMA is 5x the fast EMA length')
blength = input.int(title="Lookback period for Breakout", defval=20, minval=5, step=5, group='Strategy Settings')

long = input(true, 'Long', inline='08', group='Strategy toggle')
short = input(true, 'Short', inline='08', group='Strategy toggle', tooltip='Toggle long/short strategy on/off')

EMAwt = input(false, 'Trend', inline='01', group='Strategy toggle')
breakwt = input(true, 'Breakout', inline='01', group='Strategy toggle', tooltip='Toggle trend/breakout strategy on/off')

stopMultiple = input.float(2, 'Stop multiple', step=0.5, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price')
trail = input.int(10, 'Trail lookback', step=5, group='Risk Management Settings', tooltip='Lookback period for the trailing stop')
lev = input.float(1, 'Max Leverage', step=0.5, group='Risk Management Settings', tooltip='Max leverage sets maximum allowable leverage of total capital (initial capital + any net profit), capping maximum volatility adjusted position size')
riskT = input.float(15, maxval=75, title='Annualised Volatility Target %', group='Risk Management Settings', tooltip='Specify annual risk target, used to determine volatility adjusted position size. Annualised daily volatility is referenced to this value and position size adjusted accordingly')
comp = input(true, 'Compounding', inline='09', group='Risk Management Settings')
Comppct = input.float(50, '%', step=5, inline='09', group='Risk Management Settings', tooltip='Toggle compounding of profit, and set % of profit to compound')

// Backtesting period
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, inline='04', group='Backtest range')
FromMonth = input.int(defval=1, title='From Mon', minval=1, maxval=12, inline='04', group='Backtest range')
FromYear = input.int(defval=2018, title='From Yr', minval=1900, inline='04', group='Backtest range', tooltip='Set start of backtesting period')
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31, inline='05', group='Backtest range')
ToMonth = input.int(defval=1, title='To Mon', minval=1, maxval=12, inline='05', group='Backtest range')
ToYear = input.int(defval=9999, title='To Yr', minval=1900, inline='05', group='Backtest range', tooltip='Set end of backtesting period')

start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window = time >= start and time <= finish

// Breakout strategy
lower = ta.lowest(low[1], blength)
upper = ta.highest(high[1], blength)
basis = math.avg(upper, lower)
signal = 20*(close - basis) / (upper - lower)

// Trend strategy
fEMA = ta.ema(close[1], length)
sEMA = ta.ema(close[1], length*5)
emadiff = fEMA - sEMA
nemadiff = 5*emadiff/(ta.stdev(close - close[1], 252))

//Risk Management formulae
strategy.initial_capital = 50000
tr = math.max(high - low, math.abs(high - close), math.abs(low - close)) //True range
stopL = ta.sma(tr, 14) //Average true range
stdev = ta.stdev(close-close[1], 14) //volatility of recent returns
maxcapital = strategy.initial_capital+strategy.netprofit //Maximum capital available to invest - initial capital net of profit
annvol = 100*math.sqrt(365)*stdev/close //converts recent volatility of returns into annualised volatility of returns - assumes daily timeframe

risk = 1.1
if comp
    risk := (strategy.initial_capital+(Comppct*strategy.netprofit/100))//adjust investment capital to include compounding
else
    risk := strategy.initial_capital

shares = (risk * (riskT/annvol)) / close //calculates volatility adjusted position size, dependent on user specified annualised risk target
if ((shares*close) > lev*maxcapital) //ensures position size does not exceed available capital multiplied by user specified maximum leverage
    shares := lev*maxcapital/close

//To set the price at the entry point of trade
Posopen() =>
    math.abs(strategy.position_size[1]) <= 0 and math.abs(strategy.position_size) > 0

var float openN = na
if Posopen()
    openN := stopL

// Trailing stop
tlower = ta.lowest(low[1], trail)
tupper = ta.highest(high[1], trail)
tbasis = math.avg(tupper, tlower)
tsignal = 20*(close - tbasis) / (tupper - tlower)

// Strategy Rules
if EMAwt
    if long
        longCondition2 = (nemadiff >2 and nemadiff[1] <2) and window
        exitlong = tsignal <= -10
        if (longCondition2)
            strategy.entry('Trend Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Trend Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Trend Long!', immediately = true)

    if short
        shortCondition2 = (nemadiff <-1 and nemadiff[1] >-1) and window
        exitshort = tsignal >= 10
        if (shortCondition2)
            strategy.entry('Trend Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Trend Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Trend Short!', immediately = true)

if breakwt
    if long
        longCondition1 = (signal >= 10) and window
        exitlong = tsignal <= -10
        if (longCondition1)
            strategy.entry('Break Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Break Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Break Long!', immediately = true)

    if short
        shortCondition1 = (signal <= -10) and window
        exitshort = tsignal >= 10
        if (shortCondition1)
            strategy.entry('Break Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Break Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Break Short!', immediately = true)

// Visuals of trend and direction
plot(nemadiff, title='EMA Forecast', color=color.black, display=display.none)
plot(ta.sma(ta.median(math.sqrt(math.pow(nemadiff,2)), 700), 350), 'Forecast mean', color=color.rgb(245, 0, 0), display=display.none)

MAColor = fEMA > sEMA ? #00ff00 : #ff0000
MA1 = plot(fEMA, title='Fast EMA', color=MAColor)
MA2 = plot(sEMA, title='Slow EMA', color=MAColor)
fill(MA1, MA2, title='Band Filler', color=MAColor)

Más.