
Indicador de fuerza y dirección de la tendencia en barras 3D
Introducción
A primera vista, poco podemos añadir nuevo al tema de las velas: todo ya ha sido descubierto, contado, digitalizado. Pero, si observamos el mercado desde un ángulo distinto, se nos revela un lado completamente inesperado.
Imagine que mira el gráfico no como una imagen plana, sino como un organismo vivo que respira, donde cada barra no es solo un rectángulo con sombras, sino una estructura volumétrica que late al compás del mercado. Así nació la idea de las barras 3D. Al principio era solo un experimento de visualización: quería ver los datos conocidos de otra manera. Pero cuanto más profundizaba en la investigación, más patrones sorprendentes se manifestaban.
Recuerdo el momento en que vi por primera vez un clúster "amarillo". Literalmente brillaba en el gráfico 3D, presagiando un cambio de tendencia. Al principio pensé que se trataba de un accidente. Pero el patrón se repetía una y otra vez, indicando los futuros movimientos de los precios con notable precisión. Seis meses de investigación ininterrumpida, cientos de noches sin dormir, miles de líneas de código... todo ello se fue plasmando en un elegante modelo matemático.
Ahora, al ver los resultados de las pruebas, me doy cuenta de que hemos encontrado algo realmente importante. Algo que reside en la propia estructura del mercado, en su naturaleza subyacente. El análisis técnico clásico resulta inútil aquí: estos patrones solo pueden verse a través del prisma del análisis tensorial, solo elevándose por encima del plano del gráfico hasta la tercera dimensión.
En este artículo quiero compartir mi descubrimiento y mostrar cómo los datos ordinarios del mercado, vistos desde un nuevo ángulo, pueden darnos señales sorprendentemente precisas sobre la fuerza y la dirección de una tendencia. Además, no a posteriori, sino con antelación, cuando aún tenemos tiempo de tomar una posición y esperar el movimiento. Abróchense los cinturones: nos vamos de viaje por el mercado tridimensional.
Estructura del tensor básico del estado del mercado
¿Recuerda cuando éramos niños y montábamos un cubo de Rubik? De entrada parece un caos total, pero en cuanto pillamos el punto inicial necesario, todas las facetas empiezan a unirse en una imagen coherente. Aquí pasa lo mismo. Empecé a ensamblar los datos en una estructura tridimensional: un tensor. Parece complicado, pero en esencia supone solo una forma de ver cómo el precio, el volumen y el tiempo se influyen mutuamente.
Los primeros experimentos fueron... bueno, digamos que no fueron muy impresionantes. Las matemáticas se empeñaban en no querer sumar una bella fórmula, y este interminable torrente de números resultaba exasperante. Y entonces... entonces dejé de pensar en los números como tales.
Imagine que cada vela no es solo un conjunto de valores open-high-low-close, sino un organismo vivo. Tiene volumen, como la masa corporal. Y un impulso, como el movimiento. Y una estructura interna, como el ADN. Cuando empecé a mirar los datos desde este ángulo, todo encajó.
El resultado final es un "cubo" como éste:
- Una faceta son los datos clásicos sobre los precios
- La segunda son los volúmenes, pero no solo el número de transacciones, sino su estructura interna
- La tercera son los ciclos de tiempo, que no pude captar durante mucho tiempo
Lo más sorprendente empezó cuando hice la primera prueba de este modelo. El gráfico... literalmente cobró vida. Donde antes solo había visto líneas, ahora existía una clara estructura volumétrica. ¡Y se movía! Era como si latiera al compás de algún ritmo interno del mercado.
Pero lo más importante es que dicha estructura empezó a mostrar patrones extraños. Al principio los confundí con artefactos de visualización, pero cuantos más datos pasaba por el modelo, más claro aparecía el patrón. Y estos patrones aparecían poco antes de fuertes movimientos del precio. Como si el mercado... ¿me advirtiera de sus intenciones?
Veamos ahora cómo llevar estos datos a un denominador común. Esa es una historia aparte, y comenzó con un hallazgo casual en los viejos trabajos de Gunn.....
Normalización de los datos usando el método de Gunn
Conocí la obra de Gunn por pura casualidad. Estaba hojeando PDFs archivados en busca de materiales diferentes, y de repente eché un vistazo a sus extraños gráficos. Cuadrados, ángulos, algo semejante a espirales..... Lo primero que pensé fue en otro místico del mercado, pero algo me hizo indagar más. Escribí un artículo sobre los métodos de Gunn.
¿Y sabe qué? Bajo todo este oropel geométrico se ocultaba la idea asombrosamente elegante de la normalización de los datos. Gunn comprendió de manera intuitiva lo que yo intentaba explicar matemáticamente: el principio de invariancia del mercado a gran escala.
Pasé tres semanas estudiando sus notas. Y aunque tuve que descartar la mitad por esoterismo, el resto... ¡maldita sea, allí había algo real! Sobre todo me enganchó su enfoque de los ciclos temporales. Recuerdo saltar de la cama en mitad de la noche y correr hacia mi ordenador para comprobar una corazonada repentina.
Resultó que si escalamos los intervalos temporales correctamente, el mercado empieza a mostrar una estructura casi cristalina. Es como mirar un copo de nieve al microscopio: cada nueva escala muestra los mismos patrones, solo que a distinto tamaño.
Tomé sus principios básicos y los reelaboré para adaptarlos a mi propio modelo. En lugar de los números "mágicos" de Gann, utilicé coeficientes dinámicos basados en la volatilidad. Ahora, cada parámetro del tensor se normalizaba no a una escala fija, sino a un rango "flotante", que a su vez se ajustaba al estado actual del mercado.
Era como afinar un instrumento musical. ¿Conoce esa sensación cuando las cuerdas por fin empiezan a sonar al unísono? Fue más o menos lo mismo que sentí cuando vi los primeros resultados. El gráfico ya no se fragmentaba en elementos separados, sino que empezaba a vivir como un todo.
Lo más difícil fue hallar el equilibrio adecuado entre la sensibilidad de la normalización y la estabilidad del modelo. Si el ajuste era demasiado sutil, el sistema empezaba a reaccionar al ruido del mercado. Si era demasiado brusco, se perdían señales importantes. Me pasé dos semanas jugando con estos parámetros hasta que encontré el dorado término medio.
Pero el verdadero avance se produjo cuando apliqué esta normalización al componente de volumen de la tendencia. Entonces empezó la parte divertida...
Cálculo del componente de volumen de la tendencia
Aquí es donde la cosa se pone interesante. Tras normalizar los datos, topé con un problema inesperado: los indicadores volumétricos clásicos sencillamente no "veían" los momentos clave del cambio de tendencia. Recuerdo pasarme una semana intentando modificar el OBV y el MFI. El resultado fue... no del todo bueno.
Y entonces, escarbando en las fuentes de un antiguo indicador (ya no es posible hallar al autor), me encontré con un enfoque interesante para el cálculo del perfil de volumen. La idea era genialmente simple: no fijarse en los valores absolutos del volumen, sino en su relación con la media móvil. Aquí está mi código:
def _calculate_components(self, df: pd.DataFrame) -> pd.DataFrame: # Базовые компоненты df['volatility'] = df['close'].pct_change().rolling(20).std() df['momentum'] = df['close'].pct_change(5) # Вот оно, ключевое место - объемный профиль df['volume_ma'] = df['tick_volume'].rolling(20).mean() df['volume_trend'] = df['tick_volume'] / df['volume_ma'] # Сила тренда как производная трех компонент df['trend_force'] = df['volatility'] * df['volume_trend'] * abs(df['momentum'])
Mire lo que ocurre aquí. En lugar de limitarnos a resumir los volúmenes, creamos una especie de "aceleración de volúmenes". Cuando el volumen aumenta drásticamente en relación con su media, esta es la primera señal de alarma. Pero lo divertido empieza cuando superponemos la volatilidad y el impulso.
Probé muchos periodos para las medias móviles. 10, 15, 25... Al final, fue el periodo de 20 barras el que ofreció el mejor equilibrio entre sensibilidad y estabilidad de las señales.
Pero el verdadero efecto sorpresa se produjo cuando añadí el coeficiente de sesión comercial:
# Коэффициенты активности разных сессий df['session_coef'] = 1.0 hour = df.index.hour df.loc[(hour >= 0) & (hour < 8), 'session_coef'] = 0.7 # Азиатская df.loc[(hour >= 8) & (hour < 16), 'session_coef'] = 1.0 # Европейская df.loc[(hour >= 16) & (hour < 24), 'session_coef'] = 0.9 # Американская
El gráfico cobró, literalmente, vida. Ahora, cada pico de volumen se consideraba en el contexto de la sesión comercial en curso. ¿Sabe que en la naturaleza existen las mareas? Lo mismo ocurre aquí: cada sesión tiene su propio carácter, su propio "poder de atracción".
Pero lo más importante es que esta fórmula empezó a mostrar lo que yo denominaba "precursores". Unas pocas barras antes de un movimiento fuerte, el perfil de volumen comenzaba a formar un patrón característico. Es como si el mercado estuviera "cogiendo aliento" antes de lanzarse.
Y luego surgió la cuestión de cómo visualizarlo todo correctamente....
La dinámica de precios en el espacio tridimensional
Me llevó bastante tiempo encontrar la forma adecuada de visualizar toda esta locura. Mis primeros intentos de construir gráficos 3D en MatPlotLib se parecían más a un árbol de Navidad que a algo útil para el trading. Plotly no se prestaba inmediatamente a ninguna de las dos cosas: los gráficos estaban demasiado recargados o carecían de detalles importantes.
Y ahí es donde entró en juego el azar. Estaba jugando con mi hija a construir algo semejante a un puente y, de repente, me di cuenta de que no necesitábamos tanta fantasía gráfica en 3D. ¡Bastaba con ubicar las proyecciones correctamente! Esto es lo que obtuve:
def create_visualization(self, df: pd.DataFrame = None): if df is None: df = self.analyze_market() df = df.reset_index() # Три проекции нашего "моста" fig = make_subplots(rows=3, cols=1, shared_xaxes=True, subplot_titles=('Price', 'Trend Force', 'Trend Direction'), row_heights=[0.5, 0.25, 0.25], vertical_spacing=0.05) # Основной график - классические свечи fig.add_trace( go.Candlestick( x=df['time'], open=df['open'], high=df['high'], low=df['low'], close=df['close'], name='OHLC' ), row=1, col=1 )
Veamos qué ocurre: vamos a tomar tres proyecciones del mismo espacio. La de arriba muestra las conocidas velas, pero eso es solo la punta del iceberg. La parte más interesante empieza en la segunda ventana:
# Сила тренда - наша основная фишка fig.add_trace( go.Scatter( x=df['time'], y=df['trend_force_adjusted'], mode='lines', line=dict(color='blue', width=2), name='Trend Force' ), row=2, col=1 ) # Опорные уровни fig.add_hline(y=3, line_dash="dash", line_color="yellow", row=2, col=1) fig.add_hline(y=6, line_dash="dash", line_color="green", row=2, col=1)
Estos niveles (3 y 6) los he tanteado de forma empírica. Cuando la fuerza de la tendencia rompe el nivel 6, casi siempre implica un movimiento fuerte. El nivel 3 es una especie de zona de turbulencias, donde la tendencia puede fortalecerse o revertirse.
Pero la verdadera magia tiene lugar en la ventana inferior:
# Направление тренда как производная силы fig.add_trace( go.Bar( x=df['time'], y=df['trend_direction'] * df['trend_force_adjusted'], name='Trend Direction', marker_color=np.where(df['trend_direction'] > 0, 'green', 'red') ), row=3, col=1 )
Aquí vemos no solo la dirección de la tendencia, sino su fuerza en la dinámica. Cuando las barras verdes aumentan frente a un valor alto de Trend Force, se tratará de una fuerte señal de compra. Por el contrario, el aumento de las barras rojas contra la fuerza por encima de 6 supondrá una señal segura de venta.
Pero regresemos a tierra firme. Tras la visualización, me surgió la cuestión de los ciclos temporales.....
El componente temporal y las sesiones comerciales
¿Sabe lo que siempre me ha sorprendido del análisis técnico clásico? La facilidad con la que todo el mundo se olvida del tiempo. ¡Sí, sí, el tiempo, simple y llanamente! Miran los gráficos, calculan los indicadores, pero pasan por alto un simple hecho: el mercado vive en zonas horarias distintas.
El primer toque de atención sonó cuando noté un patrón extraño: mis señales funcionaban mucho mejor en la sesión europea. Al principio lo atribuí a la casualidad. Pero entonces indagué más, y esto es lo que encontré:
# Смотрите, как просто оказалось учесть влияние сессий hour = df.index.hour # Азиатская сессия - самая спокойная asian_mask = (hour >= 0) & (hour < 8) df.loc[asian_mask, 'session_coef'] = 0.7 # Европа - пик активности european_mask = (hour >= 8) & (hour < 16) df.loc[european_mask, 'session_coef'] = 1.0 # Америка - всё ещё активно, но уже не так сильно american_mask = (hour >= 16) & (hour < 24) df.loc[american_mask, 'session_coef'] = 0.9
Estos coeficientes los elegí literalmente sobre la marcha, probando distintas variantes. Recuerdo pasarme la noche en vela haciendo backtests con distintos valores. Mi mujer me llamaba para que me fuera a dormir, pero yo seguía sin poder despegarme del monitor: los resultados eran muy emocionantes.
Pero lo más interesante empezó cuando apliqué estos coeficientes al perfil de volumen. De repente, todo encajó en su sitio. Resulta que el mismo volumen en sesiones distintas tiene un "peso" completamente diferente:
- En la sesión asiática, incluso un pequeño repunte del volumen puede resultar significativo
- La europea necesita desviaciones mucho más significativas
- Y en la unión entre ambas sesiones, sucede algo muy interesante....
Pero el verdadero avance se produjo al añadir otro componente: las "transiciones entre sesiones". Me di cuenta de que 30-40 minutos antes de la apertura de una nueva sesión el indicador empezaba a comportarse.... de forma extraña. Es como si el mercado se preparase para la llegada de nuevos jugadores. Y entonces...
Indicador integral de la fuerza de la tendencia
A veces, los descubrimientos más importantes surgen de errores frustrantes. En mi caso, todo empezó con un error en el código. Accidentalmente multipliqué las variables equivocadas y el gráfico mostró una anomalía salvaje. Mi primer impulso fue reescribirlo todo, pero algo me hizo estudiarlo más de cerca.....
Resulta que accidentalmente creé lo que más tarde llamé un "indicador integral". Mire:
def _calculate_components(self, df: pd.DataFrame) -> pd.DataFrame: # Вот она, та самая "ошибка" - перемножение трех компонент df['trend_force'] = df['volatility'] * df['volume_trend'] * abs(df['momentum']) # Нормализация результата в диапазон от 3 до 9 df['trend_force_norm'] = self.scaler.fit_transform( df['trend_force'].values.reshape(-1, 1) ).flatten() # Финальная корректировка с учетом сессий df['trend_force_adjusted'] = df['trend_force_norm'] * df['session_coef']
¿Sabe lo que ocurre aquí? La volatilidad se multiplica por una tendencia de volumen y el valor absoluto del impulso. En teoría, esto debería haber producido un caos total. Y en la práctica... En la práctica, resultó un indicador sorprendentemente claro de la fuerza de la tendencia.
Recuerdo mi sorpresa cuando empecé a probar esta fórmula con los datos históricos. El gráfico mostraba picos claros exactamente donde comenzaban los movimientos fuertes. Y no a posteriori, ¡sino varias barras antes del movimiento!
La parte más interesante comenzó cuando añadí la normalización con MinMaxScaler. Elegí un intervalo de 3 a 9 casi al azar; me pareció que así el gráfico resultaría más fácil de leer. Y de repente descubrí que estos números crean niveles casi perfectos para la toma de decisiones:
- Por debajo de 3: el mercado está dormido
- De 3 a 6, empieza el movimiento
- Por encima de 6: la tendencia está en su apogeo
Y cuando le añadí factores de sesión.... ¡Ahí empezó la fiesta de verdad! Las señales eran tan claras que hasta mi tráder vecino, siempre escéptico, silbaba de admiración al ver los backtests.
Pero me esperaba un gran descubrimiento. Resulta que este indicador no solo mide la fuerza de la tendencia, sino que puede predecir los retrocesos...
Determinación de la dirección del movimiento futuro
Tras descubrir el indicador integral, me volví literalmente loco buscando patrones de inversión. Durante semanas estuve sentado frente al monitor, pasando gráficos de un lado a otro. Mi mujer ya empezaba a preocuparse: incluso me olvidaba de comer cuando encontraba algo interesante.
Entonces, una noche (¿por qué todos los descubrimientos importantes ocurren de noche?) percibí un extraño patrón. Antes de los cambios de tendencia fuertes, el indicador de fuerza... no, no caía, como se podría pensar. Comenzaba a oscilar de una manera peculiar:
# Определение направления тренда df['trend_direction'] = np.sign(df['momentum']) # Тут магия и начинается df['direction_strength'] = df['trend_direction'] * df['trend_force_adjusted'] # Ищем паттерны разворота df['reversal_pattern'] = np.where( (df['trend_force_adjusted'] > 6) & # Сильный тренд (df['direction_strength'].diff().rolling(3).std() > 1.5), # Нестабильность направления 1, 0 )
Vea lo que ocurre: cuando la fuerza de la tendencia supera el nivel 6 (¿recuerda nuestra normalización?), pero la dirección se vuelve inestable, ¡esto casi siempre anuncia una reversión!
Pasé dos semanas comprobando esta observación en diferentes marcos temporales e instrumentos. Funcionó en todas partes, pero de forma especialmente clara en H1 y H4. Como si fuera en estos marcos temporales cuando el mercado "piensa" de forma más racional.
Pero la verdadera revelación llegó cuando le apliqué un perfil volumétrico:
df['volume_confirmation'] = np.where( (df['reversal_pattern'] == 1) & (df['volume_trend'] > df['volume_trend'].rolling(20).mean() * 1.5), 'Strong', 'Weak' )
¡Y entonces todo encajó! Resulta que no todas las reversiones son iguales. Cuando el patrón coincide con un fuerte volumen que supera la media, esto casi supone una reversión garantizada. Y si el volumen no la respalda, probablemente sea solo una corrección.
Recuerdo haber enseñado estos resultados a mi antiguo profesor de estadística. Se quedó mirando las fórmulas durante un buen rato, luego me miró y me preguntó: "¿Y has comprobado esto con datos de hasta 2020?". Asentí con la cabeza. "¿Y después?". De nuevo asentí. "Hmmm... Sabe, hay algo en esto. Contradice el paseo aleatorio, pero... ¡se parece mucho a la verdad!".
Obviamente, también se dieron falsas activaciones. Pero para eso, ya tenía listo un sistema de filtrado...
Visualización de la señales en el gráfico
Cuando todos los componentes del indicador estuvieron listos, me surgió la pregunta: ¿cómo mostrárselo a los tráders? No todo el mundo podrá entender las fórmulas y las hojas de cálculo. Tuve muchos problemas hasta que se me ocurrió la idea de la visualización en tres niveles.
Mis primeros intentos en MatPlotLib puro fueron, digamos, no muy buenos. Puedes hacerte los ojos trizas antes de ver dónde está la señal. Probé una docena de bibliotecas hasta que me decidí por Plotly. Esto es lo que ocurrió finalmente:
def create_visualization(self, df: pd.DataFrame = None): if df is None: df = self.analyze_market() fig = make_subplots(rows=3, cols=1, shared_xaxes=True, subplot_titles=('Price', 'Trend Force', 'Trend Direction'), row_heights=[0.5, 0.25, 0.25], vertical_spacing=0.05) # Основной график - свечи с подсветкой сигналов fig.add_trace( go.Candlestick( x=df['time'], open=df['open'], high=df['high'], low=df['low'], close=df['close'], name='OHLC', hoverlabel=dict( bgcolor='white', font=dict(size=12) ) ), row=1, col=1 )
Pero el principal atractivo reside en la interactividad. Si situamos el cursor sobre una vela, podremos ver todos los parámetros a la vez: la fuerza de la tendencia, los volúmenes y la dirección. Y el esquema de colores... Aquí me pasé una semana eligiendo tonos para que no se cansaran los ojos:
fig.add_trace( go.Scatter( x=df['time'], y=df['trend_force_adjusted'], mode='lines', line=dict(color='blue', width=2), name='Trend Force', hovertemplate="<br>".join([ "Time: %{x}", "Force: %{y:.2f}", "<extra></extra>" ]) ), row=2, col=1 )
La visualización de la dirección de la tendencia es harina de otro costal. La implementé en forma de barras, donde la altura muestra la fuerza y el color la dirección:
fig.add_trace( go.Bar( x=df['time'], y=df['trend_direction'] * df['trend_force_adjusted'], name='Trend Direction', marker_color=np.where(df['trend_direction'] > 0, 'green', 'red'), ), row=3, col=1 )
Recuerdo la reacción de mi amigo tráder cuando le enseñé la versión final. Hizo clic por el gráfico en silencio durante unos cinco minutos, y luego me dijo: "Oye, ¡ahora hasta un principiante puede averiguar hacia dónde se mueve el mercado!".
Pero lo mejor fue cuando empezaron a llegar las opiniones de usuarios reales. Alguien escribió que por fin dejó de confundirse con las señales. Algunos se mostraron agradecidos por poder negociar sin tener que estar sentados frente a un monitor durante horas: ......
Intentamos implementar el indicador de fuerza de tendencia en MetaTrader 5
Tras el éxito con la versión Python del indicador, me surgió una pregunta lógica: ¿cómo transfiero esto a MetaTrader 5?
La tarea resultó ser... interesante. Obviamente, MQL5 es un lenguaje potente, pero sin pandas ni numpy tuve que trastear mucho. Esto es lo que obtuve:
//+------------------------------------------------------------------+ //| TrendForceIndicator.mq5 | //+------------------------------------------------------------------+ #property copyright "Your Name" #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 3 #property indicator_plots 3 // Буферы для отрисовки double TrendForceBuffer[]; double DirectionBuffer[]; double SignalBuffer[]; // Входные параметры input int InpMAPeriod = 20; // Период сглаживания input int InpMomentumPeriod = 5; // Период для моментума input double InpSignalLevel = 6.0; // Уровень сигнала //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { // Настройка индикатора SetIndexBuffer(0, TrendForceBuffer, INDICATOR_DATA); SetIndexBuffer(1, DirectionBuffer, INDICATOR_DATA); SetIndexBuffer(2, SignalBuffer, INDICATOR_DATA); // Стили отрисовки PlotIndexSetString(0, PLOT_LABEL, "Trend Force"); PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE); PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrBlue); PlotIndexSetString(1, PLOT_LABEL, "Direction"); PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_HISTOGRAM); PlotIndexSetString(2, PLOT_LABEL, "Signal"); PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_LINE); PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrRed); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { // Проверка на достаточность данных if(rates_total < InpMAPeriod) return(0); // Расчет компонентов int start = (prev_calculated > 0) ? prev_calculated - 1 : 0; for(int i = start; i < rates_total; i++) { // Волатильность double volatility = 0.0; if(i >= InpMAPeriod) { double sum = 0.0; for(int j = 0; j < InpMAPeriod; j++) { double change = (close[i-j] - close[i-j-1]) / close[i-j-1]; sum += change * change; } volatility = MathSqrt(sum / InpMAPeriod); } // Моментум double momentum = 0.0; if(i >= InpMomentumPeriod) { momentum = (close[i] - close[i-InpMomentumPeriod]) / close[i-InpMomentumPeriod]; } // Объемный тренд double volume_ma = 0.0; if(i >= InpMAPeriod) { for(int j = 0; j < InpMAPeriod; j++) { volume_ma += tick_volume[i-j]; } volume_ma /= InpMAPeriod; } double volume_trend = volume_ma != 0 ? (double)tick_volume[i] / volume_ma : 0; // Сессионный коэффициент MqlDateTime dt; TimeToStruct(time[i], dt); double session_coef = GetSessionCoefficient(dt.hour); // Расчет силы тренда TrendForceBuffer[i] = NormalizeTrendForce(volatility * MathAbs(momentum) * volume_trend) * session_coef; DirectionBuffer[i] = momentum > 0 ? TrendForceBuffer[i] : -TrendForceBuffer[i]; // Сигнальная линия SignalBuffer[i] = InpSignalLevel; } return(rates_total); } //+------------------------------------------------------------------+ //| Получение коэффициента сессии | //+------------------------------------------------------------------+ double GetSessionCoefficient(int hour) { if(hour >= 0 && hour < 8) return 0.7; // Азиатская сессия if(hour >= 8 && hour < 16) return 1.0; // Европейская сессия if(hour >= 16 && hour < 24) return 0.9; // Американская сессия return 1.0; } //+------------------------------------------------------------------+ //| Нормализация показателя силы тренда | //+------------------------------------------------------------------+ double NormalizeTrendForce(double force) { // Простая нормализация в диапазон [3, 9] double max_force = 0.01; // Подобрано эмпирически return 3.0 + 6.0 * (MathMin(force, max_force) / max_force); }
Lo más difícil fue reproducir el comportamiento de pandas rolling windows. En MQL5, todo tiene que ser calculado en ciclos, pero el rendimiento es mayor: el indicador funciona mucho más rápido que la versión Python.
Conclusión
Al final de esta larga investigación, me gustaría compartir algunas observaciones importantes. La transferencia del algoritmo de Python a MQL5 me descubrió oportunidades inesperadas de optimización. Lo que al principio parecía una desventaja (falta de bibliotecas conocidas) se convirtió en una ventaja: el código se hizo más rápido y eficiente.
Lo más difícil fue encontrar un equilibrio entre la precisión de las señales y la velocidad del indicador. Cada parámetro adicional, cada nueva comprobación supone una carga adicional para el sistema. Pero al final logré alcanzar la relación óptima: el indicador procesa los datos de los ticks casi en tiempo real, manteniendo al mismo tiempo una gran precisión de las señales.
Por otra parte, cabe destacar la reacción de los tráders activos. Cuando empecé este proyecto, el objetivo principal era crear algo nuevo e interesante para mí. Pero cuando otros tráders empezaron a utilizar el indicador, notamos que habíamos encontrado algo realmente importante. Me ha complacido especialmente recibir comentarios de tráders experimentados que afirman que el indicador les ayuda a ver el mercado de una forma nueva.
Obviamente, no es el Santo Grial. Como cualquier otra herramienta de análisis técnico, nuestro indicador requiere comprensión y una aplicación adecuada. Pero su principal ventaja consiste en permitir ver aspectos de la dinámica del mercado que suelen permanecer invisibles en los análisis clásicos.
Aún queda mucho trabajo por delante. Me gustaría añadir un ajuste adaptativo de los parámetros, mejorar el sistema de filtrado de señales e incluso incorporar elementos de aprendizaje automático. Pero ahora, al ver los resultados, me doy cuenta de que este viaje ha valido la pena.
Y lo que es más importante, me he convencido de que incluso en un conjunto de herramientas que aparentemente se ha estudiado con tanto detalle como el análisis técnico, siempre hay lugar para la innovación. Lo esencial es no tener miedo a mirar las cosas conocidas desde un ángulo nuevo y estar preparado para descubrimientos inesperados.
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/16719
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.





- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Pero te ayuda mucho a ti, y a todos los demás gurús del trading.
Aquí entramos, y aquí salimos y ganamos 100500pp de cada operación, y así durante todo el periodo pasado.
¿Sabes cuál es el problema de todos los codificadores? Han olvidado cómo buscar patrones.
Todos siguen el mismo patrón - ¡ahora pondremos una idea en el código y la máquina encontrará el Grial! Y así 100500 veces en círculo. ))
Pero cogerlo y comprobarlo a mano, calcularlo en una calculadora.... No, lo honorable no es elegir un agujero.... ))
Por eso no entiendes que el mercado sigue las leyes habituales de la física: el ángulo de incidencia es igual al ángulo de reflexión. El sistema gráfico se describió hace 100 años. Funciona como funciona. Pero para entenderlo, hay que dedicar una buena cantidad de tiempo a trabajar con la historia para encontrar todas las conexiones matemáticas. Y sobre todo reordenando tu pensamiento.
Incluso el primer impulso conlleva información sobre futuros niveles de reversión. El error en la libra no suele ser superior a 2-5 pips.
¿Sabes cuál es el problema con todos los codificadores? Han olvidado cómo buscar patrones.
Todos siguen el mismo patrón - ¡ahora pondremos alguna idea en el código y la máquina encontrará el Grial por nosotros! Y así 100500 veces en círculo. ))
Pero cogerlo y comprobarlo a mano, calcularlo en una calculadora.... No, lo honorable no es elegir un agujero.... ))
Por eso no entiendes que el mercado sigue las leyes habituales de la física: el ángulo de incidencia es igual al ángulo de reflexión. El sistema gráfico se describió hace 100 años. Funciona como funciona. Pero para entenderlo, hay que dedicar una buena cantidad de tiempo a trabajar con la historia para encontrar todas las conexiones matemáticas. Y sobre todo reordenando tu pensamiento.
Incluso el primer impulso conlleva información sobre futuros niveles de reversión. El error en la libra no suele ser superior a 2-5 pips.
Varios cientos de sistemas diferentes de diferentes usuarios pasan por la codificación, los pruebas y ves todas las desventajas y ventajas.
No es elegir manualmente y fallar algunos patrones. Una máquina nunca se perderá nada, esa es su ventaja.
Y lo que funcionaba hace 100 años dejó de funcionar a medida que mejoraba la tecnología.
¿Te imaginas cómo habrían funcionado los pips antes, cuando las operaciones se hacían por teléfono o por telegrama al broker?
Y lo que funcionaba hace 100 años dejó de funcionar al mejorar la tecnología.
¿Puede explicar por qué dejó de funcionar? ¡¿Algún corredor o creador de mercado canceló las leyes de la física y las matemáticas?!
Tío, cómo me he perdido semejante primicia. ¿Puedo saber cuándo ocurrió este hecho y quién fue el autor de la anulación?
Varios cientos de sistemas diferentes de distintos usuarios pasan por codificación, los pruebas y ves todos los defectos y ventajas.
No es elegir a mano, se pierden algunos patrones. A una máquina nunca se le escapará nada, esa es su ventaja.
Para codificar algo correctamente, primero hay que encontrar TODOS los patrones a mano. Puede que la máquina no se equivoque, pero sólo buscará lo que tú le pongas, es decir, ¡lo que hayas encontrado por tu cuenta sin la máquina! ¡¡¡¡A veces me asombra la creencia fanática en las capacidades de AI!!!! )))
Has codificado para buscar en el texto las letras A, B y C. Porque o bien las has encontrado por accidente, o bien alguien te las ha indicado. PERO hay otras letras en el alfabeto y no las conoces .... ¿Qué te dará la máquina?
Es lo mismo en el mercado, hay reglas generales, hay modelos mat., pero cada día tienen proporciones diferentes (aunque todos encajan en un modelo general). Incluso en el precio habrá un retroceso, +-3 puntos del valor calculado, pero funcionará exactamente de acuerdo con el tiempo. O funcionará exactamente al precio, pero con un deslizamiento de un par de barras.
Para codificar algo correctamente, primero hay que encontrar todos los patrones con las manos. Puede que la máquina no se equivoque, pero sólo buscará lo que tú le pongas, es decir, ¡lo que hayas encontrado por ti mismo sin la máquina! ¡¡¡¡A veces me asombra la creencia fanática en las capacidades de AI!!!! )))
Has codificado para buscar en el texto las letras A, B y C. Porque o bien las has encontrado por accidente, o bien alguien te las ha indicado. PERO hay otras letras en el alfabeto y no las conoces .... ¿Qué te dará la máquina?
Es lo mismo en el mercado, hay reglas generales, hay modelos mat., pero cada día tienen proporciones diferentes (aunque todos encajan en un modelo general). Incluso en el precio habrá un retroceso, +-3 puntos del valor calculado, pero funcionará exactamente de acuerdo con el tiempo. O funcionará exactamente al precio, pero con un deslizamiento de un par de barras.
La serie numérica no cambia, cambian las comas en ella.