
Esta estrategia es una variante de otra estrategia de seguidor de tendencias de ruptura que hice anteriormente. En otra estrategia, puedes usar el promedio móvil como un filtro para las transacciones (es decir, si el precio está por debajo del promedio móvil, no hará mucho).
Por lo tanto, la estrategia le permite ver las tendencias en los marcos de tiempo más altos (es decir, si hay altos más altos y bajos más bajos? Si es así, es una tendencia alcista). Usted solo hace una posición en la dirección de la tendencia. Puede elegir hasta dos tendencias como filtro.
He encontrado que esta estrategia en general no funciona muy bien en comparación con otras estrategias, pero sí parece ser más exigente en el comercio. Muestra una mayor tasa de ganancias y un mejor factor de ganancia.
La lógica central de esta estrategia es identificar tendencias utilizando soportes y resistencias que rompan con los marcos de tiempo más altos y negociar en función de la dirección de la tendencia.
En concreto, se realiza a través de los siguientes pasos:
Calcular los puntos de soporte y resistencia en el marco de tiempo actual (como la línea de 1 hora). Esto se logra mediante la búsqueda de los precios más altos y más bajos en un período determinado.
Calcula el punto de soporte y el punto de resistencia de uno o más marcos de tiempo superiores (como la línea de 4 horas y la línea de sol). Esto se realiza utilizando la misma lógica que el marco de tiempo actual.
Trazar en el gráfico las líneas horizontales de estos puntos de soporte y resistencia. Cuando los precios superan estos niveles, la tendencia de los marcos de tiempo más altos cambia.
La dirección de la tendencia se determina en función de si el precio ha roto estos niveles clave. Si el precio ha roto un punto alto, se considera una tendencia alcista. Si ha roto un punto bajo, se considera una tendencia bajista.
Permitir a los usuarios elegir una o más tendencias de un marco de tiempo superior como condición de filtro. Es decir, solo se considerará una operación si la dirección de la tendencia del marco de tiempo actual coincide con la dirección de la tendencia del marco de tiempo superior.
Cuando se cumplen las condiciones de filtración de tendencia y el precio actual supera el nivel crítico, se compra o se vende. El nivel de parada de pérdida se establece como el soporte o resistencia clave anterior.
A medida que los precios se mueven, cuando se forman nuevos picos o bajos, el stop loss se mueve a nuevos bajos para bloquear las ganancias y seguir la tendencia.
Cuando el stop loss se activa o se rompe un soporte/resistencia clave, la posición se retira a la par.
A través de este análisis de tendencias de múltiples marcos de tiempo, la estrategia trata de operar solo en la dirección de la tendencia más fuerte para aumentar la probabilidad de ganar. Al mismo tiempo, los niveles clave ofrecen señales claras de entrada y parada.
El uso de varios marcos de tiempo para juzgar las tendencias permite identificar con mayor precisión las direcciones de las tendencias más fuertes y evitar ser engañados por el ruido del mercado.
Solo operando en la dirección de la tendencia principal, se puede aumentar considerablemente la tasa de ganancias. Según los resultados de las pruebas, la estrategia muestra una mayor tasa de ganancias y un mejor índice de ganancias-riesgo en comparación con el filtro de las medias móviles simples.
Las posiciones de soporte y resistencia ofrecen niveles claros de entrada y parada. No es necesario complicar la selección de puntos de entrada específicos.
La posición de parada se ajusta a medida que la tendencia avanza, para maximizar el bloqueo de ganancias.
La lógica de la estrategia es simple y clara, fácil de entender y ajustar.
El juicio de tendencias que depende de tramos más largos de la línea es fácil de corregir cuando la tendencia se invierte. Se debe reducir adecuadamente el período de tiempo para juzgar la tendencia, o usar otros indicadores para auxiliar el juicio.
Sin tener en cuenta los efectos fundamentales, puede haber desviaciones en el precio de las acciones cuando ocurren eventos importantes. Se pueden agregar condiciones de filtrado como eventos de ATM o fechas de resultados.
No hay control del tamaño de la posición. El tamaño de la posición se puede ajustar según el tamaño de los fondos de la cuenta, la volatilidad y otros factores.
El tiempo de respuesta es limitado. Se debe ampliar el período de respuesta para probar la estabilidad en diferentes entornos de mercado.
No se tiene en cuenta el impacto de los costos de transacción. En el disco real, los parámetros de la estrategia se deben ajustar en función de los costos de las transacciones específicas.
Considere solo el comercio de líneas largas. Se puede combinar con otras estrategias para desarrollar señales de comercio de líneas cortas y lograr un arbitraje multi-ciclo.
Añadir condiciones de filtro:
Datos básicos, como noticias de negocios y eventos de noticias
Indicadores como el volumen de transacciones, el ATR y el stop loss.
Parámetros de optimización:
Ajuste el ciclo de cálculo de los bits de soporte/resistencia
El marco de tiempo para ajustar las tendencias
Ampliar el alcance de las estrategias:
Desarrollo de estrategias de corto plazo
Considere la posibilidad de una venta por descuento
Arbitraje de varias variedades
Mejorar la gestión de riesgos:
Optimización del tamaño de la posición en función de la volatilidad y el tamaño del capital
Optimización de las estrategias de detención de pérdidas, como el movimiento de la detención, la suspensión de la detención, etc.
La introducción de un mecanismo de castigo por riesgo
Optimización de la lógica de ejecución:
Cambios en la hora de entrada
Consideraciones para la entrada de algunas posiciones
Optimización de las estrategias de movilidad para detener el daño
La estrategia diseña un sistema de ruptura más robusto mediante el análisis de tendencias en marcos temporales múltiples. En comparación con el filtro de indicadores como las medias móviles simples, muestra una mayor proporción de ganancias y riesgos de ganancias. Pero también hay aspectos que se pueden optimizar, como la imperfección del mecanismo de gestión de riesgos, sin considerar los factores fundamentales, etc. Si se optimiza aún más, puede ser una estrategia de seguimiento de tendencias muy práctica.
/*backtest
start: 2023-10-24 00:00:00
end: 2023-10-26 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=4
// Revision: 1
// Author: @millerrh
// Strategy: Enter long when recent swing high breaks out, using recent swing low as stop level. Move stops up as higher lows print to act
// as trailing stops. Ride trend as long as it is there and the higher lows aren't breached.
// The difference between this one and the previous Breakout Trend Follower is that this one uses higher timeframe higher highs/higher lows as a filter instead
// of an arbitrary Moving Average. I wanted to test out whether waiting for longer term actual trend changes produced better stats than just the moving average.
// Conditions/Variables
// 1. Manually configure which dates to back test
// 2. Can add a filter to only take setups that are above (or below for shorts) user-defined larger timeframe trends (helps avoid trading counter trend)
// === CALL STRATEGY/STUDY, PROGRAMATICALLY ENTER STRATEGY PARAMETERS HERE SO YOU DON'T HAVE TO CHANGE THEM EVERY TIME YOU RUN A TEST ===
// (STRATEGY ONLY) - Comment out srategy() when in a study()
strategy("Breakout Trend Follower V2", overlay=true, initial_capital=10000, currency='USD',
default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)
// (STUDY ONLY) - Comment out study() when in a strategy()
//study("Breakout Trend Follower V2", overlay=true)
// === BACKTEST RANGE ===
Start = input(defval = timestamp("01 Jan 2019 06:00 +0000"), title = "Backtest Start Date", type = input.time, group = "Backtest Range")
Finish = input(defval = timestamp("01 Jan 2100 00:00 +0000"), title = "Backtest End Date", type = input.time, group = "Backtest Range")
// == USER INPUTS ==
tableLocation = input(defval="Top", options=["Top", "Bottom"], title = "Info Table Location", group = "Display",
tooltip = "Place information table on the top of the pane or the bottom of the pane.")
lookback = input(defval = 3, title = "Pivot Lookback Period", group = "Pivot Points",
tooltip = "Looks for pivot points within this number of bars both left and right.")
showPivotPoints = input(title = "Show Historical Pivot Points?", type = input.bool, defval = false, group = "Pivot Points",
tooltip = "Toggle this on to see the historical pivot points that were used. Change the Lookback Period to adjust the frequency of these points.
The pivot points are only shown for the current chart timeframe - to see the Daily pivot pionts, use the Daily timeframe, etc.")
trendFilter = input(defval="1st Timeframe", options=["1st Timeframe", "Both Timeframes", "None"], title = "Use HTF Trend for Filtering?", group = "Higher Timeframe Levels",
tooltip = "Signals will be ignored when price is not aligned with the higher timeframe trend(s). The intent is to keep you out of bear periods and only buying when
price is showing strength and you are trading with the trend.")
twoSet = input(defval="D", title="1st High Timeframe", type=input.resolution, group = "Higher Timeframe Levels",
tooltip = "Allows you to set two different time frames for looking at the trend.")
threeSet = input(defval="W", title="2nd High Timeframe", type=input.resolution, group = "Higher Timeframe Levels")
showMTFLevels = input(title = "Show Multiple Timeframe S/R Levels?", type = input.bool, defval = true, group = "Higher Timeframe Levels",
tooltip = "Displays the pivot highs and lows of higher timeframes to use as support/resistance levels. When these levels break, the trend
will change on these higher timeframes.")
currentColorS = input(color.new(color.orange,50), title = "Current Timeframe Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF1")
currentColorR = input(color.new(color.blue,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF1")
oneColorS = input(color.new(color.yellow,50), title = "1st High Timeframe Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF2")
oneColorR = input(color.new(color.yellow,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF2")
twoColorS = input(color.new(color.white,50), title = "2nd High Timeframe Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF3")
twoColorR = input(color.new(color.white,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF3")
// == DEFINE FUNCTIONS FOR USE IN MULTIPLE TIMEFRAMES (USING A TUPLE TO AVOID SO MANY SECURITY CALLS) ==
f_getHTF() =>
ph = pivothigh(high, lookback, lookback)
pl = pivotlow(low, lookback, lookback)
highLevel = valuewhen(ph, high[lookback], 0)
lowLevel = valuewhen(pl, low[lookback], 0)
barsSinceHigh = barssince(ph) + lookback
barsSinceLow = barssince(pl) + lookback
timeSinceHigh = time[barsSinceHigh]
timeSinceLow = time[barsSinceLow]
[ph, pl, highLevel, lowLevel, barsSinceHigh, barsSinceLow, timeSinceHigh, timeSinceLow]
[ph_01, pl_01, hL_01, lL_01, bsSH_01, bsSL_01, tSH_01, tSL_01] = security(syminfo.tickerid, "", f_getHTF())
[ph_02, pl_02, hL_02, lL_02, bsSH_02, bsSL_02, tSH_02, tSL_02] = security(syminfo.tickerid, twoSet, f_getHTF())
[ph_03, pl_03, hL_03, lL_03, bsSH_03, bsSL_03, tSH_03, tSL_03] = security(syminfo.tickerid, threeSet, f_getHTF())
// Plot historical pivot points for debugging and configuring the lookback period.
plot(showPivotPoints ? ph_01 : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow,50), offset=-lookback)
plot(showPivotPoints ? pl_01 : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow,50), offset=-lookback)
// == PLOT SUPPORT/RESISTANCE LINES ON THE HIGHER TIMEFRAMES ==
// Use a function to define the lines
f_line(x1, y1, y2, _color) =>
var line id = na
// line.delete(id)
// id := line.new(x1, y1, time, y2, xloc.bar_time, extend.right, _color)
// 1st Timeframe
highLine1 = showMTFLevels ? f_line(tSH_01, hL_01, hL_01, currentColorR) : na
lowLine1 = showMTFLevels ? f_line(tSL_01, lL_01, lL_01, currentColorS) : na
// 2nd Timeframe
highLine2 = showMTFLevels ? f_line(tSH_02, hL_02, hL_02, oneColorR) : na
lowLine2 = showMTFLevels ? f_line(tSL_02, lL_02, lL_02, oneColorS) : na
// 3rd Timeframe
highLine3 = showMTFLevels ? f_line(tSH_03, hL_03, hL_03, twoColorR) : na
lowLine3 = showMTFLevels ? f_line(tSL_03, lL_03, lL_03, twoColorS) : na
// == TREND CALCULATIONS (USING A TUPLE TO CONSOLIDATE REPETATIVE CODE AND GENERATE MULTIPE VARIABLES WITH ONE FUNCTION ==
f_signal(highLevel, lowLevel) =>
uptrendSignal = high > highLevel
downtrendSignal = low < lowLevel
inUptrend = bool(na)
inDowntrend = bool(na)
inUptrend := uptrendSignal[1] ? true : downtrendSignal[1] ? false : inUptrend[1]
inDowntrend := not inUptrend
[uptrendSignal, downtrendSignal, inUptrend, inDowntrend]
[uptrendSignal1, downtrendSignal1, inUptrend1, inDowntrend1] = f_signal(hL_01, lL_01) // 1st Timeframe
[uptrendSignal2, downtrendSignal2, inUptrend2, inDowntrend2] = f_signal(hL_02, lL_02) // 2nd Timeframe
[uptrendSignal3, downtrendSignal3, inUptrend3, inDowntrend3] = f_signal(hL_03, lL_03) // 3rd Timeframe
// == TREND TABLE PLOTTING ==
tablePos = tableLocation == "Top" ? position.top_right : position.bottom_right
var table trendTable = table.new(tablePos, 3, 1, border_width = 3)
upColor = color.rgb(38, 166, 154)
downColor = color.rgb(240, 83, 80)
f_fillCell(_column, _row, _cellText, _c_color) =>
table.cell(trendTable, _column, _row, _cellText, bgcolor = color.new(_c_color, 70), text_color = _c_color, width = 6)
if barstate.islast or barstate.islastconfirmedhistory
f_fillCell(0, 0, inUptrend1 ? "▲" : "▼", inUptrend1 ? upColor : downColor)
f_fillCell(1, 0, inUptrend2 ? "▲ " + twoSet : "▼ " + twoSet, inUptrend2 ? upColor : downColor)
f_fillCell(2, 0, inUptrend3 ? "▲ " + threeSet : "▼ " + threeSet, inUptrend3 ? upColor : downColor)
// Conditions for entry and exit
buyConditions = true
buySignal = high > hL_01 and buyConditions // Code to act like a stop-buy for the Study
sellSignal = low < lL_01 // Code to act like a stop-loss for the Study
// (STRATEGY ONLY) Comment out for Study
strategy.entry("Long", strategy.long, stop = hL_01, when = buyConditions)
// strategy.entry("Long", strategy.long, stop = buyLevel2, when = time > Start and time < Finish and high > maFilterCheck)
strategy.exit("Exit Long", from_entry = "Long", stop=lL_01)