Desarrollando un algoritmo de autoadaptación (Parte II): Aumentando la efectividad

26 marzo 2021, 14:56
Maxim Romanov
0
379

Introducción

Antes de comenzar a analizar este artículo, le recomendamos que lea el primer artículo "Desarrollando un algoritmo de autoadaptación (Parte I): Encontrando un patrón básico". No es algo imprescindible, ya que la idea principal seguirá estando clara, pero la lectura le resultará más interesante.

En el artículo anterior, detectamos un patrón simple y desarrollamos un algoritmo muy simple que explotaba este. Pero el algoritmo no posee una estructura flexible, por lo que carece de sentido esperar resultados sobresalientes de él.

Así, necesitaremos mejorarlo mucho para que resulte más flexible y ajuste sus parámetros de funcionamiento dependiendo de la situación del mercado para que sea posible lograr estabilidad y mejores resultados.

Analizando los defectos

Vamos a comenzar el desarrollo del nuevo algoritmo analizando los inconvenientes de la versión anterior. Hemos destacado los siguientes inconvenientes:

  • Las señales de apertura de una serie se generan muy rara vez. La mejora en la calidad de la señal reduce en gran medida la cantidad de señales de entrada, así como el beneficio general;
  • Para el análisis, tomaremos una ventana de muestra fija. Vamos a dejar que las muestras se establezcan según un rango; no obstante, analizar una muestra de tamaño fijo no resulta una solución muy eficaz. El mercado no supone una onda sinusoidal y las "colas" afectan la calidad de la señal actual. Los límites de la muestra deben ser difusos e influir en la decisión final. Hablando en general, en la versión anterior tomamos 100 velas y analizamos la preponderancia de las velas descendentes y ascendentes. Si la preponderancia superaba el valor umbral, se generaba una señal de entrada. La muestra no debe ser fija, sino dinámica. Debemos verificar no solo qué situación había en la ventana de análisis, sino también qué se encontraba fuera de la ventana de análisis;
  • El problema de la ventana de análisis fija no es común a todos los métodos conocidos;
  • El porcentaje de umbral tiene un valor fijo para cada muestra, independientemente del número de velas presente en esa muestra. Esta solución resulta ineficaz porque una probabilidad de un 75% de preponderancia en una muestra de 30 velas y en una muestra de 200 velas está lejos de ser la misma, y disminuye de forma no lineal cuando aumenta el número de velas en la muestra;
  • La apertura de posiciones en cada vela resulta demasiado cara y causa mayores reducciones. Con frecuencia, se abren demasiadas posiciones, por lo que debemos reducir el número de posiciones abiertas en la serie. Esto aumentará la eficiencia del uso del capital;
  • El cierre de posiciones con un beneficio fijo por lote reduce la estabilidad o la rentabilidad. Debemos encontrar un compromiso entre estabilidad y rentabilidad en un mercado en cambio constante. Si no ajustamos este parámetro, el robot pronto sufrirá pérdidas simplemente porque dejará pasar el punto de cierre óptimo para una serie de posiciones;
  • La enorme limitación en el número de instrumentos para el comercio simultáneo reduce la rentabilidad general del sistema. Las señales para las series de apertura en diferentes instrumentos están ligeramente correlacionadas entre sí, por consiguiente, las pérdidas sufridas en un instrumento pueden correlacionarse con las pérdidas ocurridas en otro. Por lo tanto, debemos desarrollar medidas para reducir la correlación de las señales de forma que el número de instrumentos comerciados simultáneamente pueda aumentar significativamente sin por ello incrementar de manera sustancial el volumen de la reducción.

Algoritmo de trabajo simplificado

Vamos a recordar cómo funcionaba la primera versión del algoritmo de manera simplificada. En la nueva versión, el sentido del funcionamiento seguirá siendo el mismo, pero cada paso será revisado y mejorado.

  • escaneamos una ventana de N velas; 
  • verificamos de qué tipo de velas hay más, descendentes o ascendentes;
  • si la preponderancia resulta superior al umbral, entonces tendremos la señal para el inicio de una serie de posiciones; 
  • si hay más velas descendentes = señal Buy; si hay más ascendentes = Sell;
  • calculamos el lote;
  • abrimos una nueva posición en cada vela subsiguiente hasta que se active la condición para cerrar la serie; 
  • se activa la condición para cerrar la serie;
  • se cierran todas las posiciones;
  • buscamos una nueva señal.

Modernización

El robot se desarrolló en 2016 para MetaTrader 4, así que adjuntaremos el código para este terminal al final.

Durante el desarrollo, eliminaremos todos los inconvenientes identificados, por lo que dividiremos todo el desarrollo en tareas aparte.

  1. Porcentaje de umbral dinámico de inicio de la serie

El algoritmo de la primera versión se ha vuelto más estable, con un aumento en el número de velas en la ventana de análisis o con un aumento en el porcentaje del umbral del preponderancia de velas descendentes o ascendentes. Hemos tenido que llegar a un compromiso y establecer un tamaño de muestra más grande para el análisis o un porcentaje mayor de preponderancia de la vela predominante. Las pruebas han mostrado que el porcentaje de preponderancia óptimo se puede ajustar a casi cualquier número de velas, pero debería disminuir para un número de velas mayor.

Cuando tenemos un porcentaje de umbral fijo, el aumento en el número de velas en la ventana de análisis disminuye la probabilidad de tal combinación. Por lo tanto, podemos establecer cualquier número máximo de velas en la ventana de análisis, ya que este hecho casi no tendrá ningún efecto en el resultado, simplemente porque la probabilidad de encontrar tal combinación disminuye rápidamente. Para aumentar el número de señales de inicio de la serie, necesitaremos reducir el porcentaje umbral de preponderancia, para que la probabilidad de la combinación se mantenga aproximadamente igual al aumentar el número de velas en la muestra.

Suponemos que la probabilidad de que aparezca un porcentaje de preponderancia dado en un número determinado de velas se puede calcular mediante combinatoria.

CP,

donde

  • С - número de combinaciones
  • n - número de velas en la muestra
  • k - número de velas ascendentes
  • P - probabilidad de que ocurra un evento
  • P2 - probabilidad duplicada de un evento

La probabilidad del evento P debe multiplicarse por 2, porque P se calcula para el caso en el que hay más velas de la misma dirección, sea aumentando o disminuyendo. Estamos interesados ​​en la probabilidad general, sin importar en qué dirección. No deberemos multiplicar la probabilidad por 2 solo si la cantidad de velas descendentes es igual a la cantidad de velas ascendentes.

Por ejemplo, vamos a calcular la probabilidad de que ocurra un evento cuando, de 30 velas, tenemos 24 velas en una dirección y 6 en otra. Para hacerlo, hemos creado un recuadro en la figura 1 a continuación.

probability table

Figura 1. Recuadro de probabilidad

24 velas (en una dirección) de las 30 se corresponden con un 80% de preponderancia. La probabilidad de tal combinación es del 0,11%. Ahora, vamos a realizar comparaciones con el recuadro comprobando qué porcentaje de preponderancia debería haberse dado para 100 velas en la muestra de forma que su probabilidad de aparición fuera del 0.11%. No existe tal probabilidad de que ocurran combinaciones para 100 velas. Existe una probabilidad de aparición del 0.172% y 0.091%. Nos decantaremos por otra opción más rara, que se corresponde con la proporción de un tipo de vela respecto a otro, como 66/34 o el 66% de las velas en una dirección.

Está claro que las combinaciones de 30 velas con un margen del 80% de velas ascendentes o descendentes serán tan comunes como una combinación de 100 velas con un margen del 66%. La dependencia del porcentaje de preponderancia respecto al número de velas no es lineal, por lo tanto, para ajustar el porcentaje al aumentar el número de velas, deberemos aplicar una función no lineal. Hemos desarrollado una función como esta:

Nonliner proc

Donde:

  • Nb — número de velas en la muestra.
  • Koef_NonLiner_proc — coeficiente de ajustes necesario para corregir el porcentaje de umbral.

Veamos en el gráfico de la figura 2 cómo el porcentaje de preponderancia (con una probabilidad estática de ocurrencia de la combinación) disminuye al aumentar el número de velas usando el método combinatorio, y cómo de adecuada es la función desarrollada.

Chart function

Figura 2.

La figura 2 muestra en violeta un gráfico de disminución en el porcentaje de preponderancia con un aumento en el número de velas en la muestra y una probabilidad fija de tal combinación. El gráfico de la función desarrollada para disminuir el porcentaje de preponderancia del número de velas en la muestra se representa en rojo. Ambas funciones son no lineales, pero la función desarrollada decae más lentamente. Lo hemos hecho así deliberadamente, porque cuantas más velas haya en la muestra, más posiciones en la serie se podrán abrir al volver al 50%. Más posiciones conllevan una mayor carga sobre el depósito y una mayor reducción. 

Lo hemos implementado de forma que la señal aparezca con menos frecuencia en un mayor número de velas. Además, tendrá lugar solo si el porcentaje de preponderancia es realmente alto para un número determinado de velas.

2. Incrementando el número de señales

Para mejorar la calidad de la señal, la muestra no debe constar de un número fijo de velas. Podemos ver una preponderancia de velas ascendentes del 65% en 30 velas, pero ¿es mucho o poco? Si existe algún tipo de preponderancia de velas ascendentes sobre 100 velas, este hecho debería hacer la señal más fuerte; no obstante, si no existe preponderancia o, por el contrario, existe una preponderancia de velas descendentes, la señal debería debilitarse. Hemos desarrollado 2 mecanismos para potenciar o atenuar la señal.

a) Usar un porcentaje promedio ponderado es la primera opción para mejorar la calidad de la señal. Encontramos el porcentaje promedio ponderado para todas las muestras del rango especificado en las configuraciones "Min_diap_bar" y "Max_diap_bar". Las muestras deben tomarse con algún paso; nosotros preferimos un paso par = 2. El porcentaje promedio ponderado se determinará para el tipo de velas que sea más grande en la primera muestra. Si hay más velas ascendentes en la primera muestra, en todas las demás muestras deberemos calcular el porcentaje de velas ascendentes. La primera muestra puede ser la muestra más grande o la muestra más pequeña. Para ello, hemos añadido a los ajustes el interruptor "Bigin_pereb_bar". Los pesos se pueden crear utilizando cualquier función, pero nosotros los hemos hecho proporcionales al número de velas en la muestra. 

Si la primera muestra tiene el menor número de velas, entonces su peso será W1; para la segunda muestra, el peso será W2, y así sucesivamente hasta Wn.

weighted average

  • W1 - coeficiente de peso de la primera muestra;
  • W2 - coeficiente de peso de la segunda muestra;
  • Wn - coeficiente de peso n de la muestra;
  • Nb1 - número de velas de la primera muestra;
  • Nbn - número de velas n de la muestra;
  • Pw - porcentaje promedio ponderado de preponderancia de velas;
  • P1 - porcentaje de velas ascendentes/descendentes de la primera muestra;
  • Pn - porcentaje de velas ascendentes/descendentes de la muestra n;
  • Nbm - número de velas en la muestra más grande.

Si la primera muestra tiene la mayor cantidad de velas, los pesos deberán invertirse

 inverted weights
Para obtener una señal al comienzo de la serie, debemos comparar el porcentaje promedio ponderado con un valor aparte especificado en la configuración "Porog_Weighted_proc".

b) El uso de muestras múltiples es la segunda opción para mejorar la calidad de la señal. Debemos recopilar del rango varias muestras en las que la preponderancia de un tipo de velas sea superior al umbral. Aquí asumiremos que cuanto mayor sea el número de muestras para las que el porcentaje de preponderancia es superior al umbral, mayor será la calidad de la señal. Como porcentaje de umbral, usaremos un porcentaje no lineal. Es decir, para cada muestra con su propio número de velas, deberemos usar nuestro propio porcentaje de umbral de preponderancia.
En la configuración "Kol_vibor", estableceremos el número mínimo de muestras en las que la preponderancia deberá ser superior al umbral. El tipo de velas para las que se determinará el porcentaje de preponderancia dependerá del tipo de velas que predomine en la primera muestra. Aquí, para la primera muestra, tomaremos aquella en la que se ha detectado la preponderancia por encima del umbral. Hemos hecho posible iterar por el rango de menor a mayor y viceversa, para así comparar cómo resulta mejor trabajar.
Esta técnica nos permitirá considerar la señal en una ventana más amplia, sin tener que vincular esta a una ventana de análisis fija. Por ejemplo, establecemos un rango para la ventana de análisis de 30 a 300 velas con un paso de 2. Para generar una señal, deberemos recopilar al menos 5 muestras de este rango con una preponderancia superior al umbral. La preponderancia se puede formar en las velas 30, 52, 100, 101, 200. Además, cada muestra se compara con su propio porcentaje de umbral, porque se usa un porcentaje no lineal. Esto consigue que resulte más eficiente valorar lo que ha sucedido en un amplio rango del número de velas, sin que haya vinculación a un valor fijo.

Price Chart

Figura 3.

La figura 3 muestra un ejemplo de forma esquemática. Podemos ver que hay un área en la que predominan las velas ascendentes y hay una señal para abrir posiciones Sell. No se trata de un número claro de velas, sino de un área.  

En el primer artículo, escribimos que la cantidad de velas (y, en consecuencia, la cantidad de posiciones en la serie) en las que teóricamente se compensará la preponderancia resultante, se calcula según la cantidad de velas en las que ha surgido. Gracias a este enfoque, podemos dar los primeros pasos hacia la aparición de la autoadaptación. El algoritmo aún está lejos de autoadaptarse, pero la utilización de las características de mercado actuales para realizar un pequeño ajuste de los parámetros operativos ya lo está acercando al objetivo.
Un algoritmo ideal no debe contener parámetros ajustables: cada parámetro debe calcularse con absoluta precisión según las características actuales del mercado. Necesitamos saber exactamente qué parámetros operativos debemos establecer en cada momento para que el algoritmo siga siendo rentable.
3. Disminución del número de posiciones abiertas en la serie

En la primera versión del algoritmo había un problema: cuando comenzaba una serie, el robot abría posiciones en cada vela. Este enfoque no resulta muy efectivo y provoca grandes reducciones, aumentando la exigencia para el depósito. Con frecuencia había situaciones en las que se abrían posiciones, pero el porcentaje de preponderancia en la muestra seguía creciendo o no disminuía lo suficientemente rápido. Este es un factor que no se considera y provocaba una pérdida de estabilidad. Debemos tener en cuenta este factor y así aumentar la estabilidad del algoritmo.

Hemos desarrollado 2 medidas para reducir el número de posiciones en la serie.

a) Si las posiciones son Sell, entonces necesitaremos abrir nuevas posiciones solo en velas ascendentes. Si las posiciones son Buy, abriremos las posiciones solo en las velas descendentes. Este mecanismo nos permite obtener beneficios de forma más eficiente precisamente gracias al hecho de que hay más velas de un tipo que de otro.

La apertura de posiciones Sell con velas descendentes provoca una disminución en el precio promedio de apertura de la posición y, si el precio aumenta, genera una carga adicional sobre el depósito. Al mismo tiempo, las "posiciones sobrantes" prácticamente no suman beneficio y no aceleran el cierre de la serie en positivo. La lógica resulta similar para las posiciones de compra.

b) Apertura con control del porcentaje de preponderancia. Este es un filtro adicional para abrir posiciones en una serie. Debemos comprobar el porcentaje de preponderancia de toda la muestra con la aparición de cada nueva vela. El tamaño de la muestra aumentará en una unidad con la aparición de una nueva vela. Si, con la aparición de una nueva vela, el porcentaje de preponderancia ha aumentado con respecto a la medición anterior, podremos abrir la posición, de lo contrario, no podremos.

Este artículo funciona casi como el punto (a), pero de una manera ligeramente distinta. Su sentido es muy similar al modo del punto (a): evitar que el precio de apertura promedio de una serie para posiciones Sell disminuya y evitar un aumento en el precio de apertura promedio de una serie para posiciones Buy.

Si el porcentaje medio ponderado se usa como porcentaje de umbral, este método podrá corregir la apertura de posiciones adicionales comparando el valor actual del porcentaje promedio ponderado con el valor de la vela anterior.

Estos dos puntos se pueden usar juntos o por separado. Reducen el nivel de rentabilidad, pero aumentan significativamente la estabilidad, y, en nuestra opinión, esto resulta más importante que el beneficio. Ya tenemos un factor no considerado menos, por lo que hemos aumentado la estabilidad del funcionamiento.

open positions befor

open positions after

Figura 4. Ejemplo de reducción del número de posiciones en una serie

En la figura 4 anterior, las posiciones se abren sin restricciones, en la figura de abajo, se abren usando el algoritmo del punto (b). Podemos ver que se han abierto menos posiciones; los resultados comparativos para esta transacción se enumeran en el recuadro a continuación.


Beneficio Pérdidas máximas Número de posiciones Profit factor
Apertura en cada vela (figura superior) +71.99$ -463.96$ 92 1.56
Apertura con control del porcentaje de preponderancia (figura inferior). +42.26$ -263.86$ 48 1.68

El recuadro muestra que ha disminuido la reducción máxima, pero también ha descendido la rentabilidad. Lo más importante es que el número de posiciones ha disminuido 1,91 veces, lo que finalmente influirá de forma positiva en la estabilidad del algoritmo en los momentos en que los parámetros del mercado se desvían de sus valores típicos.

Hemos desarrollado otros métodos para reducir el número de posiciones en la serie. Estos se describen en la tarea técnica; mostremos los que nos parecen más efectivos. 

4. Modernización del cierre de posiciones en beneficio

En la primera versión del algoritmo, introdujimos el concepto de beneficio por lote. Este valor se establecía en la divisa del depósito para un tamaño de lote igual a uno. A continuación, se calculaba el número de lotes para las posiciones abiertas en la serie y el valor de la configuración se multiplicaba por el lote total actual para las posiciones abiertas en la serie. Por ejemplo, en los ajustes se establece cerrar una serie de posiciones cuando el beneficio supera los 15$ por lote. Ahora hay 11 posiciones abiertas en 0.01 lotes, lo que significa que la posición total es 0.01*11=0.11. Además, el beneficio por lote se multiplica por el número de lotes obtenidos 15$*0.11=1.65$. Si el beneficio total de las posiciones abiertas alcanza los 1.65$, se deberá finalizar la serie de posiciones.

Establecer un beneficio fijo por lote en la divisa del depósito no resulta la solución más eficaz. Cuando desciende la volatilidad de un instrumento, aumenta el riesgo de dejar pasar el punto de cierre adecuado. Por el contrario, cuando aumenta la volatilidad, el robot no obtiene todo el beneficio que podría. Como resultado, durante la optimización, obtenemos un beneficio medio por lote que no funciona con la suficiente eficacia. 

La solución más sencilla sería ajustar el parámetro "beneficio por lote" partiendo de la volatilidad actual. A mayor volatilidad, mayor beneficio por lote y viceversa. Ahora ya podemos decir que la utilización de la volatilidad promedio tampoco es una solución ideal, pero resulta mejor que un valor fijo.

Así conseguimos otra pequeña función de autoadaptación; no establecemos el parámetro de forma estricta, sino que ajustamos la dependencia partiendo del estado actual del mercado. Ya sabemos que el beneficio en una serie depende directamente del tamaño de las velas, y esta dependencia debe utilizarse para aumentar la estabilidad.

Nosotros hemos renunciado a controlar el beneficio en la divisa de depósito, porque el precio del pip no es constante para las parejas de divisas como USD/XXX y cambia partiendo del valor de precio actual. El beneficio se controlará en puntos. Para hacer esto, tomaremos el valor actual del indicador ATR (en puntos) y lo multiplicaremos por el valor de los ajustes de "Koef_multi_ATR". Así, hemos obtenido el número de puntos para cerrar con beneficios. Además, para cada posición, calcularemos cuántos puntos han pasado desde el precio de apertura al valor actual y encontraremos el valor promedio de todas las posiciones. Luego, comparamos el valor promedio resultante con el número de puntos para cerrar en beneficio. Si el número promedio de puntos es superior o igual al número de puntos a cerrar, la serie finaliza, si no, el proceso se repite en la siguiente vela. 

El beneficio actual debe monitorearse en cada tic o mediante un temporizador. Para no saturarnos con cálculos innecesarios, para un sistema de este tipo, resultará normal comprobar el beneficio en el temporizador 1 vez por segundo o incluso 1 vez cada 10 segundos.

  5. Trabajando con instrumentos comerciales múltiples

La anterior versión del robot podía comerciar simultáneamente con 10 instrumentos. Esto no resultaba suficiente, por lo que teníamos que iniciar varias copias del robot simultáneamente. La nueva versión puede operar simultáneamente con 28 instrumentos comerciales; la hemos implementado así para controlar mejor el comercio.

Como escribimos anteriormente, las señales del inicio de la serie están levemente correlacionadas en diferentes instrumentos, y esto conlleva la sincronización de las reducciones para diferentes instrumentos, así como un aumento en los requisitos para el depósito y una disminución en la rentabilidad relativa. 

Si hablamos de una forma ideal, la correlación entre las señales de inicio de una serie en diferentes instrumentos comerciales debería ser negativa. Es decir, una gran reducción actual de un instrumento debería coincidir con pequeñas operaciones rentables en cualquier otro instrumento comercial. Prohibir la apertura simultánea de series para más de un instrumento tampoco resulta la mejor solución, porque la rentabilidad general disminuye.

La correlación de señales al inicio de una nueva serie ocurre debido a que una de las divisas puede comenzar a bajar o subir en relación a otras. Puede aparecer una señal de compra o venta de esta divisa en relación con otras en varias parejas de divisas a la vez; por ello, debemos protegernos ante tal eventualidad.

Para que la correlación entre las señales de apertura de series en diferentes instrumentos sea lo más pequeña posible, deberemos dividir las parejas de divisas en divisas separadas y asumir que las posiciones están abiertas para divisas separadas. Si abrimos una posición de venta para EURUSD, esta posición se dividirá en una posición de venta para EUR y una posición de compra para USD. Antes de comenzar cada nueva serie, deberemos verificar si hay posiciones para las divisas incluidas en la pareja o no. Si hay una posición de venta en EUR, deberemos prohibir el inicio de cualquier serie en la que debamos vender EUR. Pero no es necesario prohibir las señales en las que debemos comprar EUR. 


Figura 5

En la figura 5 vemos un ejemplo sobre cómo dividir divisas en parejas. A continuación, en la figura 6, se muestra esquemáticamente qué posiciones pueden abrirse si una posición de Buy EURUSD está abierta. Para el resto de opciones, todo funciona de la misma manera. 

Currencies 2

Figura 6.

Utilizando este enfoque, ya no será necesario limitar el número máximo de instrumentos para la apertura simultánea de posiciones, pero dejaremos la función en los ajustes.

6. Corrección del lote partiendo de la volatilidad actual.

En la segunda versión del algoritmo, descartamos el refinanciamiento automático, por lo que el lote no cambiará cuando se modifque el tamaño del depósito. Hemos creado este robot para el comercio real y no necesitamos esta función. No obstante, hemos desarrollado una función diferente para la corrección de lotes. Los beneficios y pérdidas de dicho algoritmo dependerán del tamaño de las velas o de la volatilidad. Resulta lógico intentar que el gráfico de rendimiento sea lo más plano posible, sin caídas ni picos. 

Para estabilizar el gráfico de rendimiento, deberemos cambiar el tamaño del lote de la volatilidad actual. Cuanto mayor sea, menos necesitará usar el lote, menor será la volatilidad y más podremos configurar el lote. El lote cambiará en proporción a la volatilidad actual. Para lograr esto, estableceremos en los ajustes el valor del lote normal y la volatilidad normal.

Para calcular el lote actual, deberemos tomar el valor ATR actual y dividirlo por el "Norm_ATR" de la configuración. Luego, deberemos dividir el parámetro "Lot" de la configuración por el coeficiente resultante. El valor obtenido se redondeará hasta al valor correcto. Por consiguiente, el lote disminuirá al aumentar el tamaño de la vela y el gráfico de rendimiento será lo más estable posible.

Después de iniciar la serie, la volatilidad podría cambiar, por lo que hemos previsto 2 opciones para trabajar. En la primera, el lote se determina antes del inicio de la serie y es estable hasta que finaliza esta.

En la segunda opción, el lote cambia dependiendo de la volatilidad actual después del inicio de la serie. Sin embargo, al calcular el beneficio actual, el tamaño de la posición influirá en el beneficio total en la divisa del depósito, y los resultados podrían mejorar y empeorar. La función será experimental; si al lector le gusta cómo funciona, podremos modificarla en la próxima versión.

Pruebas

El artículo no describe la totalidad de las modificaciones y los modos de funcionamiento desarrollados, solo los principales y más interesantes. Hemos implementado mucho más de lo que hemos descrito, y todos los modos se pueden combinar entre sí. Vamos a adjuntar la tarea técnica para el algoritmo al artículo. En esta se describirá todo con detalle. 

Vamos a realizar las pruebas con las mismas parejas de divisas que utilizamos para poner a prueba la primera versión del algoritmo, y comparar así visualmente lo que ha sucedido. Al igual que la primera versión, este algoritmo funciona cerrando velas, por lo que podemos realizar pruebas de forma segura en el modo "puntos de control". Dentro de la vela, el algoritmo solo controla el beneficio actual, asegurándose además de que los fondos actuales no caigan por debajo del valor de umbral establecido en la configuración. Como antes, las pruebas se realizarán con un spread sobreestimado. Estableceremos un spread de 40 para GBPUSD.

Como en la primera versión del algoritmo, podremos comerciar y optimizar cualquier marco temporal. El plazo mínimo está limitado por el tamaño de las velas en relación con los spreads y las comisiones. Cuanto menor sea el marco temporal, mayores serán las exigencias respecto a la calidad de la señal y los beneficios esperados. Si aumentamos el marco temporal, se incrementará el tamaño de las velas y, en consecuencia, aumentará el nivel de las reducciones. Por consiguiente, el plazo máximo se verá limitado por las preferencias respecto al estilo de negociación.

Hemos realizado la optimización en 2017, cuando usamos un robot para comerciar con cuentas reales, así que simplemente hemos tomado la configuración anterior y no hemos realizado la optimización ahora.

GBPUSD 2000 tester chart

GBPUSD 2000 Tester report

Figura 7. GBPUSD H1 2000.01.01 - 2020.12.08 lote estático

La figura 7 muestra una prueba de GBPUSD para el marco temporal H1, por un periodo de casi 21 años desde 2000.01.01 hasta 2020.12.08. Utilizamos una muestra múltiple del rango. El rango de análisis es de 68-200 velas y se usan 15 muestras.

Mientras que la primera versión del algoritmo ha pasado la prueba solo desde 2001, la segunda versión lo ha hecho tranquilamente desde 2000. En comparación con la primera versión del algoritmo, el número de posiciones se ha multiplicado por 3 y el beneficio ha aumentado 1,9 veces. El factor de beneficio ha disminuido de 7,5 a 2,74, pero aún se mantiene en un nivel decente. Las señales para el comienzo de la serie se generan con mayor frecuencia y el número promedio de posiciones en la serie ha disminuido. Probablemente, podríamos elegir mejores configuraciones, pero hemos tomado las que usamos para comerciar.

Antes, desarrollamos una función para ajustar el lote del valor actual de ATR. En la figura 8, hemos realizado la misma prueba que en la figura 7, pero con un lote dinámico dependiente de la volatilidad. Como hemos usado un lote de 0.01 para 3,000$, para que el algoritmo de corrección funcione como debe, hemos aumentado el depósito a 30,000$ y, en consecuencia, hemos incrementado el lote a 0,1.

GBPUSD 2000 tester chart dyn lot

GBPUSD 2000 Tester report dyn lot

Figura 8. GBPUSD H1 2000.01.01 - 2020.12.08 lote dinámico que depende de ATR 

Como podemos ver en la figura 8, el gráfico de rendimiento se ha vuelto significativamente más lineal, como esperábamos durante el desarrollo. Al mismo tiempo, el rendimiento ha disminuido ligeramente, mientras que la reducción máxima ha aumentado ligeramente. El modo ha resultado interesante y útil para obtener la máxima rentabilidad prevista con valores altos del ratio de Sharpe.

Necesitamos comprobar cómo de estables son los parámetros que hemos usado para las pruebas anteriores. Para hacerlo, iniciaremos una prueba en el marco temporal M15 de GBPUSD con la misma configuración que usamos en el H1. Como la volatilidad resulta mucho más desigual en los marcos temporales menores, el coeficiente de beneficio debería reducirse ligeramente. Dado que sabemos por qué hay que hacer esto, podríamos implementar dicho parámetro como autoadaptable, pero este no es el caso en la versión actual del robot, así que lo ajustaremos manualmente. 

GBPUSD M15 tester chart

GBPUSD 2009 m15 Tester report

Figura 9. GBPUSD M15 2009.01.01 - 2020.12.08

La figura 9 muestra la prueba GBPUSD M15 2009.01.01 - 2020.12.08 con los ajustes del marco temporal H1 La prueba se ha superado de forma estable desde 2009. El resultado es bueno porque la configuración del marco temporal no se ha optimizado especialmente para el marco temporal M15. Para encontrar la configuración óptima para el marco temporal M15, bastará con optimizar la sección más difícil, es decir, los 1,5 años que van desde 2008.01.01 hasta 2009.06.01. Si optimizamos los parámetros para esta sección, el robot pasará la prueba durante 21 años sin ningún problema. 

Para la primera versión, ya hemos mostrado las pruebas para EURUSD H1, así que podemos comparar los resultados. La figura 10 muestra el resultado para EURUSD H1 para el periodo que va desde 2000.01.01 hasta 2020.12.08

EURUSD 2000 tester Chart

EURUSD 2000 tester report

Figura 10. EURUSD H1 2000.01.01 - 2020.12.08

La primera versión se ha puesto a prueba desde 2007; la nueva versión se ha puesto a prueba desde 2000, durante 21 años. La estabilidad ha mejorado sustancialmente. Al mismo tiempo, la reducción máxima se ha reducido 1,2 veces y los beneficios han aumentado 3 veces. El número de transacciones ha aumentado 2,3 veces.

Ya que estamos comparando el nivel de mejoría de la segunda versión, podemos ver la prueba de GBPJPY en el marco temporal H1. La primera versión se ha puesto a prueba desde 2009.

GBPJPY 2000 tester chart

GBPJPY 2000 tester report

Figura 11. GBPJPY H1 2000.01.01 - 2020.12.08

Como podemos ver en la figura 11, el algoritmo ha comenzado a superar las pruebas retrospectivas desde 2000, mientras que la reducción ha disminuido 1.8 veces y el factor de beneficio ha aumentado a 3.3.

Hemos optimizado 28 parejas de divisas compuestas por ocho divisas principales USD, GBP, EUR, CHF, CAD, AUD, NZD, JPY. Algunas parejas de divisas muestran mejor resultado, otras peor, pero todas están bien optimizadas y pasan las pruebas, como norma general, desde 2004. Algunas parejas de divisas se han puesto a prueba desde 2007, pero no muchas.

MetaTrader 4 no sabe cómo poner a prueba varios instrumentos al mismo tiempo, así que probamos cada uno de los 28 instrumentos por separado y utilizamos software de terceros para combinar los informes. Como lo hicimos en 2017, el informe combinado será de 2010 a 2017.

Full report

Figura 12. Backtest combinado para 28 parejas de divisas desde 2010 hasta 2017

La figura 12 muestra que el gráfico de rendimiento del backtest para las 28 parejas de divisas resulta bastante plano, con un rendimiento de aproximadamente el 100% anual. El resultado es hermoso, pero en realidad, la rentabilidad resulta menor porque habrá una limitación del comercio simultáneo en varias parejas de divisas. Hemos estado utilizando este robot para comerciar con cuentas reales durante dos años y la rentabilidad real ha sido del 56% anual. 

La rentabilidad real resulta inferior a la calculada porque la prueba se realizó con spreads inflados, y el algoritmo funciona de tal manera que a mayor spread, mayor rentabilidad. La situación no resulta paradójica, ya que, a medida que aumenta el spread, disminuye la estabilidad. Además, en realidad, también se hace sentir el efecto de la disminución en el número de señales debido a la prohibición establecida respecto a las transacciones de divisas unidireccionales.

En el comercio hemos usado la configuración más conservadora, pero podemos configurar el algoritmo de forma mucho más agresiva. 

Funciones adicionales

Hemos añadido la posibilidad adicional de filtrar las señales para el inicio de una serie según otros marcos temporales. Por ejemplo, el comercio se realiza en el marco temporal H1, pero las señales también se verifican en todos los marcos temporales estándar. La señal para el comienzo de una serie se genera solo si hay también una señal para el inicio de una serie en los marcos temporales M1, M5, M15, M30, H1, H4, D1. La señal de confirmación de la serie de marcos temporales adicionales se genera según las mismas reglas y de la misma forma que en el marco temporal principal. Los marcos temporales adicionales se pueden activar o desactivar de forma independiente entre sí.

Desafortunadamente, no hemos podido poner a prueba este modo, porque surgieron problemas con el correcto funcionamiento de esta función.

Existen muchas funciones adicionales en el robot que no hemos tenido en cuenta porque no resultan tan interesantes como la mecánica de trabajo básica. Pero merece la pena enumerarlas:

  • Posibilidad de establecer take profit y stop loss. Los valores se calculan según un algoritmo específico y pueden duplicar puntos de cierre reales o trabajar de forma independiente.
  • Implementada la función de seguimiento de los fondos actuales. Si los fondos descienden por debajo del umbral establecido, el robot cerrará las posiciones y dejará de comerciar
  • Podemos limitar el número máximo de posiciones para un instrumento y para todos los instrumentos.
  • Implementado el control de las pérdidas actuales para cada instrumento comercial; se trata de un stop loss virtual adicional
  • Entre dos series colindantes, podemos establecer una pausa en el número de velas para que la serie no se abra inmediatamente después de que se cierre la anterior. Necesitamos esta función para que puedan iniciarse series de otros instrumentos durante las pausas.
  • Podemos establecer el valor ATR mínimo en el que se podrán iniciar nuevas series para el instrumento. Si la volatilidad es baja, posiblemente no resulte rentable comerciar.
  • El beneficio no lineal se puede usar para cerrar posiciones. Cuantas más posiciones estén abiertas en una serie, más rápido resultará deseable completar esta serie. Por lo tanto, el beneficio umbral desciende en proporción a la raíz cuadrada del número de posiciones abiertas.
  • La pantalla muestra toda la información necesaria para cada instrumento comerciado, para que podamos estar al tanto de lo que sucede en la "cabeza" del robot.
  • El algoritmo procesa los reinicios de la computadora y el terminal, toma sus posiciones abiertas y continúa comerciando según la situación actual; para ello se usan variables globales.

El robot tiene 2337 configuraciones para 28 instrumentos comerciales, por lo que todos podremos encontrar un modo comercial interesante para ellos.

Conclusiones y desarrollo posterior

  • Hemos tomado como base un patrón simple pero comprensible, y durante el proceso de desarrollo ha resultado posible mejorar significativamente las características del algoritmo. Esto es posible precisamente porque el patrón usado resulta muy claro y podemos analizar qué influye exactamente en las pérdidas y los beneficios.
  • El algoritmo está perfectamente optimizado para toda una variedad de instrumentos y resulta bastante estable durante largos periodos de tiempo.
  • Los parámetros de trabajo se han vuelto más flexibles y ya han sido ligeramente ajustados según las características actuales del mercado. Precisamente esta característica es la que ha permitido aumentar significativamente la estabilidad. Este algoritmo se puede mejorar aún más aumentando la calidad de su funcionamiento.
  • Existe un potencial significativo para mejorar el rendimiento del algoritmo. Podemos invertir la lógica tanto para el comercio de tendencia como para el de contratendencia.
  • Cada instrumento requiere de optimización, y esto resulta negativo porque no hemos desarrollado un modelo teórico completo que indique qué parámetros necesitamos en un momento dado para un cierto instrumento comercial y por qué.
  • La necesidad de realizar optimizaciones para cada instrumento de negociación implica que no sabemos en qué se distinguen las características de las series de precios de los diferentes instrumentos comerciales. Cualquier incertidumbre supone un factor que no se tiene en cuenta.
  • Si no sabemos en qué se distinguen los parámetros de la serie de precios de un instrumento respecto a la de otro, no tendremos forma de controlar la presencia de un patrón en el instrumento actual. No podemos decir qué parámetros de la serie de precios influyen en el beneficio y la estabilidad del algoritmo.
  • Tampoco está claro por qué los ajustes optimizados resultan estables en un instrumento e inestables en otro. Podemos seleccionar configuraciones que sean estables en todos los instrumentos comerciales, pero esto provocaría un descenso significativo en la rentabilidad.
  • Al optimizar los parámetros con los datos históricos, no resulta posible deshacerse de los factores no considerados. Precisamente el número de factores no considerados influyen en la estabilidad.
  • Para lograr una estabilidad y fiabilidad reales, es necesario revisar significativamente la teoría y abandonar la optimización en las próximas versiones del algoritmo.
  • Cada parámetro de la configuración debe depender de algo. No debería existir un solo parámetro que se indique solo porque funciona mejor de esa manera. Necesitamos una explicación detallada sobre por qué se está usando este valor de parámetro en este momento y cuándo debería cambiar su valor.

En el próximo artículo, continuaremos desarrollando el algoritmo y revisaremos significativamente el modelo teórico. El nuevo algoritmo se diseñará para MetaTrader 5 porque es una plataforma más potente, flexible y eficiente.

Adjuntamos al artículo el código del robot, la tarea técnica del mismo, la configuración con la que hemos realizado las pruebas, un ejemplo de configuración para 28 parejas de divisas y una tabla de Excel para calcular la probabilidad de un evento.

Autor de la idea y la tarea técnica: Maxim Romanov. Código escrito por: Vyacheslav Ivanov.

Artículos anteriores sobre el tema:

Desarrollando un algoritmo de autoadaptación (Parte I): Encontrando un patrón básico

Traducción del ruso hecha por MetaQuotes Software Corp.
Artículo original: https://www.mql5.com/ru/articles/8767

Archivos adjuntos |
robot.zip (43.21 KB)
Set.zip (152.63 KB)
technical_task.zip (67.45 KB)
Trabajando con los precios en la biblioteca DoEasy (Parte 62): Actualización de las series de tick en tiempo real, preparando para trabajar con la Profundidad del mercado Trabajando con los precios en la biblioteca DoEasy (Parte 62): Actualización de las series de tick en tiempo real, preparando para trabajar con la Profundidad del mercado
En este artículo, vamos a desarrollar la actualización de la colección de datos de tick en tiempo real, y prepararemos una clase del objeto de símbolo para manejar la Profundidad del mercado, con la que empezaremos a trabajar a partir del siguiente artículo.
Trabajando con los precios en la biblioteca DoEasy (Parte 61): Colección de series de tick de los símbolos Trabajando con los precios en la biblioteca DoEasy (Parte 61): Colección de series de tick de los símbolos
Dado que el programa puede utilizar varios símbolos, entonces, es necesario crear su propia lista para cada uno de estos símbolos. En este artículo, vamos a combinar estas listas en una colección de datos de tick. En realidad, se trata de una lista común a base de la clase de la matriz dinámica de punteros a las instancias de la clase CObject y sus herederos de la Biblioteca estándar.
Redes neuronales: así de sencillo (Parte 9): Documentamos el trabajo realizado Redes neuronales: así de sencillo (Parte 9): Documentamos el trabajo realizado
Ya hemos recorrido un largo camino y el código de nuestra biblioteca ha crecido de manera considerable. Resulta difícil monitorear todas las conexiones y dependencias. Y, obviamente, antes de proseguir con el desarrollo del proyecto, necesitaremos documentar el trabajo ya realizado y actualizar la documentación en cada paso posterior. Una documentación debidamente redactada nos ayudará a ver la integridad de nuestro trabajo.
Trabajando con los precios en la biblioteca DoEasy (Parte 60): Lista de serie de datos de tick del símbolo Trabajando con los precios en la biblioteca DoEasy (Parte 60): Lista de serie de datos de tick del símbolo
En este artículo, vamos a crear una lista para almacenar los datos de tick del símbolo único, después, verificaremos su creación y obtención de los datos requeridos en el Asesor Experto. Dichas listas —siendo aplicada cada una de ellas para cada símbolo usado— van a componer luego la colección de datos de tick.