English Русский 中文 Deutsch 日本語 Português
El modelado de la apuestas como medio para desarrollar la "intuición del mercado"

El modelado de la apuestas como medio para desarrollar la "intuición del mercado"

MetaTrader 4Trading | 30 marzo 2016, 16:14
614 0
Eryomin Sergey
Eryomin Sergey

Introducción

Este artículo aborda el sencillo mecanismo de modelado de apuestas en tiempo real. ¿Qué son las apuestas? Una apuesta financiera es una previsión relativa a los movimientos (hacia arriba o abajo) de los valores y la generación de beneficio si se cumple la previsión. (Traducido a partir de Wikipedia en ruso por MetaQuotes Software Corp.)

En realidad, sólo nos interesa una cosa de las apuestas: es el movimiento de los instrumentos financieros hacia arriba o hacia abajo. El volumen de estos movimientos no nos interesa.

Si usamos las apuestas en forma de un juego en períodos de tiempo cortos, podemos desarrollar nuestra "intuición de mercado". Podemos aprender a "prever" si un par de divisas sube o baja. Es lo que vamos a ver en este artículo.

El concepto

Se dice que para un trader es muy importante conocer el análisis técnico, el análisis fundamental, las reglas de gestión del dinero, etc. Sin lugar a duda, todo aquello es muy importante. Pero también existe lo que se conoce como la "intuición del mercado"; es cuando un trader mira a un gráfico limpio (sin ningún tipo de indicadores) y puede ver más o menos en qué dirección se mueve el par de divisas. Por supuesto, esta previsión no es siempre exacta, pero los errores pueden ocurrir con cualquier método de trading. Sin embrago, la capacidad de "prever" el mercado es muy útil, en particular cuando hay que evaluar rápidamente la situación del mercado.

Por lo general, la "intuición del mercado" es el resultado de una larga experiencia y de numerosos experimentos en el trading. Y el coste de estos "experimentos" puede alcanzar muy a menudo miles de dólares.

Sin embargo, existen métodos para desarrollar este sentimiento con menos tiempo y recursos. Uno de los métodos es la creación de un juego que consiste en adivinar la dirección del movimiento de un par de divisas. El juego sería mucho mejor si se conecta a las condiciones reales del trading. Se puede llevar a cabo en paralelo con el trading real.

Sin lugar a duda, las habilidades humanas son capaces de ejercitarse y desarrollarse. Podemos aprender a dibujar, cantar y tocar distintos instrumentos musicales. Y estoy seguro de que podemos aprender del mismo modo a "ver" el mercado. Podemos jugar a juegos de ordenador. Del mismo modo, podemos jugar a "pronosticar la dirección". No obstante, lo que tenemos que aprender aquí es por dónde empezar y cómo desarrollar esta habilidad. En primer lugar, necesitamos el juego en sí.

Planteamiento de la tarea

¿Qué necesitamos? Necesitamos un juego mediante el cual podemos jugar en un gráfico real y en tiempo real. El juego debe tener unas reglas muy sencillas y una implementación fácil. Tiene que centrarse en el mercado en sí y no en la ejecución de las operaciones. Además, el juego no debe distraernos demasiado del trading real.

Parece que las apuestas cumplen con todos estos requisitos. Pero en la vida real, esto no es tan sencillo. No existen muchas compañías de brokerage que ofrecen esta posibilidad a sus clientes. E incluso si logra encontrar estas compañías, puede enfrentarse a algunos inconvenientes. Por ejemplo, las cuentas de prueba (demo) le pueden distraer del trading real. Además, el juego es muy arriesgado para una cuenta real. Y en general, no puede apostar en períodos inferiores a una hora.

Por lo tanto, queda claro que esta forma no se ajusta del todo a nuestra tarea. Por consiguiente, tenemos que escribir un programa por separado para este juego; un programa sin estas limitaciones. MQL4 es ideal para nuestro propósito.

La implementación

Comencemos con una pregunta sencilla: ¿Cómo será? Obviamente, el usuario tiene que elegir entre dos opciones; hacia arriba o hacia abajo (su previsión sobre la dirección del movimiento del par de divisas). A continuación, el programa añade un punto si se acierta la previsión y resta un punto en caso contrario.

Es mejor llevar a cabo la implementación de la elección mediante los objetos SYMBOL_ARROWDOWN y SYMBOL_ARROWUP (flecha hacia abajo y flecha hacia arriba). El usuario puede colocar la flecha correspondiente en el gráfico. Pero dibujar las flechas y especificar los nombres requiere mucho tiempo y esfuerzo. Por lo tanto, esta opción no nos satisface.

Otra alternativa consiste en colocar dos flechas automáticamente al principio de una nueva vela. El usuario tiene que eliminar una flecha y dejar la que se corresponde con su previsión. Después, al inicio de una nueva vela, el Asesor Experto comprueba si se cumple la previsión o no. Se calcula la puntuación total, el número de previsiones acertadas y el número de previsiones no acertadas. Se usará un archivo externo para almacenarlos.

Parece sencillo. y se puede implementar fácilmente.

//+------------------------------------------------------------------+
//|                                                       trener.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern int gap=5;
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//------------------------------
string solution="none"; 
int point, 
    point_neg, 
    point_pos;
//------------------------------    
//+---------------------------------------------------------------+
//|                      "up" choice searching                    | 
 if(
    ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point
    &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1
    &&ObjectFind("down") != 0
    &&ObjectFind("up") == 0
    )
    {
     solution="up";
    }
//|                      "up" choice searching                    |  
//+---------------------------------------------------------------+
  
//+---------------------------------------------------------------+
//|                      "down" choice searching                  |     
 if(
    ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point
    &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1    
    &&ObjectFind("up") != 0
    &&ObjectFind("down") == 0
    )
    {
     solution="down";
    }
//|                      "down" choice searching                  |       
//+---------------------------------------------------------------+    
 
//+---------------------------------------------------------------+
//|             counting points at a positive answer              |
    if((solution=="up"&&Open[1]<Close[1])
      ||(solution=="down"&&Open[1]>Close[1]))
    {
     point=1;
     point_pos=1;
     point_neg=0;     
    }  
//|             counting points at a positive answer              |   
//+---------------------------------------------------------------+
 
//+---------------------------------------------------------------+
//|             counting points at a negative answer              |    
    if((solution=="up"&&Open[1]>Close[1])
      ||(solution=="down"&&Open[1]<Close[1]))
    {
     point=-1;
     point_pos=0;
     point_neg=1;     
    } 
//|             counting points at a negative answer              |
//+---------------------------------------------------------------+
 
//+----------------------------------------------------------------------------------+
//|                              working with an external file                       |       
      int handle; 
      double points,     //total score
             points_pos, //score of positive answers
             points_neg; //score of negative answers 
       handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                       FILE_CSV|FILE_WRITE|FILE_READ,";");
       if(handle>0) //if there is a file, read it
       { 
        points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits);       
        FileClose(handle);
       } 
       
    if(solution!="none") //if a choice is made 
    {        
      handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                      FILE_CSV|FILE_WRITE|FILE_READ,";");
      FileWrite(handle ,points+point);         //write the total score
      FileWrite(handle ,points_pos+point_pos); //write the score of positive answers
      FileWrite(handle ,points_neg+point_neg); //write the score of negative answers                    
      FileClose(handle); 
    } 
//|                              working with an external file                       | 
//+----------------------------------------------------------------------------------+    
 
//+------------------------------------------------------------------------------------+
//|                                 working with objects                               |   
  if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0
     ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) 
    {
     ObjectDelete("down"); 
    }  
 if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0
    ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point) 
    { 
     ObjectDelete("up"); 
    } 
    
   if(ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no object
   {
     ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow
     ObjectSet("down", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
     ObjectSet("down", OBJPROP_COLOR, Red);
 
     ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow
     ObjectSet("up", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
     ObjectSet("up", OBJPROP_COLOR, Blue);
    }
//|                                 working with objects                               |   
//+------------------------------------------------------------------------------------+
 
Comment("Score: ", points," (",points_pos,"/",points_neg,   //show the score
        ") | Time: ", Hour(),":", Minute(),":", Seconds());//show time (for convenience) 
//----
   return(0);
  }
//+------------------------------------------------------------------+

El código incluye comentarios.


Después de añadirlo al gráfico, obtendremos los siguientes resultados:




Podemos ver dos flechas en la última barra; hacia arriba y hacia abajo. En la esquina superior izquierda podemos ver la puntuación del juego y el tiempo del último tick en el terminal. Se muestra la puntuación en tres cifras: la primera es la puntuación total, la segunda (la primera entre paréntesis) es el número de respuestas positivas (previsiones acertadas) y la tercera (la segunda entre paréntesis) es el número de respuestas negativas (previsiones no acertadas). Se muestra el tiempo en el modo Pantalla completa (F11).


Para "jugar" al juego, hay que escoger la flecha que "sobra" haciendo un doble clic (por defecto) y pulsando "Delete" (para eliminarla). La flecha que queda indica nuestra previsión.




Ahora esperamos el inicio de la siguiente barra. Si la previsión es correcta, la "Puntuación" será de la siguiente forma: "Puntuación: 1(1/0)". Si la previsión es incorrecta, la "Puntuación" será así: "Puntuación: -1(0/1)". Si el precio de cierre es igual al precio de apertura, la puntuación no cambiará. En nuestro ejemplo, la previsión era incorrecta.




Perfeccionamiento

Ya hemos cumplido con la tarea. No obstante, esta implementación tiene un inconveniente: se puede elegir la flecha durante toda la vela, incluyendo los últimos segundos. Esto pone en entredicho todo el concepto. Sería mejor si se pueda elegir durante los primeros 30 segundos. Así que vamos a introducir la variable externa de tipo int; "time_limit". El valor será igual al número de segundos durante los cuales hay que tomar la decisión. Si no le da tiempo al usuario de tomar una decisión dentro del tiempo indicado, se borrarán las flechas y volverán a aparecer en la siguiente vela.

Se introducen los cambios en la parte "working with objects" (la explicación está en los comentarios). Este es el código:

//+------------------------------------------------------------------+
//|                                                       trener.mq4 |
//|                                       Copyright © 2008, FXRaider |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, FXRaider"
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
extern int gap=5;
extern int time_limit=30;
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//------------------------------
string solution="none"; 
int point, 
    point_neg, 
    point_pos;
//------------------------------    
//+---------------------------------------------------------------+
//|                      "up" choice searching                    | 
 if(
    ObjectGet("up", OBJPROP_PRICE1)==Open[1]+gap*Point
    &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==1
    &&ObjectFind("down") != 0
    &&ObjectFind("up") == 0
    )
    {
     solution="up";
    }
//|                      "up" choice searching                    |  
//+---------------------------------------------------------------+
  
//+---------------------------------------------------------------+
//|                      "down" choice searching                  |     
 if(
    ObjectGet("down", OBJPROP_PRICE1)==Open[1]-gap*Point
    &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==1    
    &&ObjectFind("up") != 0
    &&ObjectFind("down") == 0
    )
    {
     solution="down";
    }
//|                      "down" choice searching                  |       
//+---------------------------------------------------------------+    
 
//+---------------------------------------------------------------+
//|             counting points at a positive answer              |
    if((solution=="up"&&Open[1]<Close[1])
      ||(solution=="down"&&Open[1]>Close[1]))
    {
     point=1;
     point_pos=1;
     point_neg=0;     
    }  
//|             counting points at a positive answer              |   
//+---------------------------------------------------------------+
 
//+---------------------------------------------------------------+
//|             counting points at a negative answer              |    
    if((solution=="up"&&Open[1]>Close[1])
      ||(solution=="down"&&Open[1]<Close[1]))
    {
     point=-1;
     point_pos=0;
     point_neg=1;     
    } 
//|             counting points at a negative answer              |
//+---------------------------------------------------------------+
 
//+----------------------------------------------------------------------------------+
//|                              working with an external file                       |       
      int handle; 
      double points,     //total score
             points_pos, //score of positive answers
             points_neg; //score of negative answers 
       handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                       FILE_CSV|FILE_WRITE|FILE_READ,";");
       if(handle>0) //if there is a file, read it
       { 
        points=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_pos=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits); 
        points_neg=NormalizeDouble(StrToDouble(FileReadString(handle)),Digits);       
        FileClose(handle);
       } 
       
    if(solution!="none") //if a choice is made 
    {        
      handle=FileOpen("trener_"+Symbol()+"_"+Period()+".csv",
                      FILE_CSV|FILE_WRITE|FILE_READ,";");
      FileWrite(handle ,points+point);         //write the total score
      FileWrite(handle ,points_pos+point_pos); //write the score of positive answers
      FileWrite(handle ,points_neg+point_neg); //write the score of negative answers                    
      FileClose(handle); 
    } 
//|                              working with an external file                       | 
//+----------------------------------------------------------------------------------+    
 
//+------------------------------------------------------------------------------------+
//|                                 working with objects                               |   
  if(iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))>0
     ||ObjectGet("down",OBJPROP_PRICE1)!=Open[0]-gap*Point) 
    {
     ObjectDelete("down"); 
    }  
 if(iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))>0
    ||ObjectGet("up",OBJPROP_PRICE1)!=Open[0]+gap*Point)            
    { 
     ObjectDelete("up"); 
    } 
   
  int sec_lim;  
  if(!time_limit)
  {
   sec_lim=0; 
  }
  else
  {
   sec_lim=TimeCurrent()-time_limit;
  }
  if(sec_lim>ObjectGet("up",OBJPROP_TIME1)
     &&sec_lim>ObjectGet("down",OBJPROP_TIME1) 
     &&ObjectFind("down") == 0&&ObjectFind("up") == 0
     &&iBarShift(NULL,0,ObjectGet("down",OBJPROP_TIME1))==0
     &&iBarShift(NULL,0,ObjectGet("up",OBJPROP_TIME1))==0)            
    { 
     ObjectDelete("up"); 
     ObjectDelete("down");      
    } 
  
   if((ObjectFind("down") != 0&&ObjectFind("up") != 0) //if no objects
      &&sec_lim<Time[0])
   {
     ObjectCreate("down", OBJ_ARROW, 0, Time[0], Open[0]-gap*Point); //draw a down arrow
     ObjectSet("down", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("down", OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
     ObjectSet("down", OBJPROP_COLOR, Red);
 
     ObjectCreate("up", OBJ_ARROW, 0, Time[0], Open[0]+gap*Point); //draw an up arrow
     ObjectSet("up", OBJPROP_STYLE, STYLE_DOT);
     ObjectSet("up", OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
     ObjectSet("up", OBJPROP_COLOR, Blue);
    }      
//|                                 working with objects                               |   
//+------------------------------------------------------------------------------------+
 
Comment("Score: ", points," (",points_pos,"/",points_neg,   //show the score
        ") | Time: ", Hour(),":", Minute(),":", Seconds());//Show time (for convenience) 
//----
   return(0);
  }
//+------------------------------------------------------------------+

De modo que tenemos dos variables que se pueden modificar en los parámetros de entrada:



El parámetro "gap" indica el número de puntos; la distancia entre las flechas y el precio de apertura de la vela. La variable "time_limit" indica el tiempo en segundos durante el cual el usuario tiene que tomar su decisión. Si su valor es "0", el tiempo será ilimitado, es decir, se puede elegir la flecha durante toda la duración de la vela.

Conclusión

Como resultado, hemos logrado implementar una versión sencilla del modelado de apuestas financieras mediante el lenguaje MQL4. Este juego le puede ayudar muchísimo en el desarrollo de sus habilidades de "previsión" del mercado, además de ayudarle a aprender muchos patrones de movimientos de los instrumentos financieros. Se ha implementado esta versión de modo que el usuario preste toda su atención al gráfico de los precios. Las operaciones que lleva a cabo el trader requieren muy poco tiempo y son muy intuitivas.

Quiero compartir los resultados que he obtenido en el juego. He logrado acertar las previsiones de 5-10 velas sucesivas (en el gráfico de cinco minutos).

Gracias a este juego, el trader aprende a responder a una de las preguntas más importantes: ¿Hacia dónde se mueve el instrumento financiero? Todavía hay muchas otras preguntas importantes, como, por ejemplo, fijar el beneficio, fijar las pérdidas, elegir el volumen de las operaciones a abrir, etc. Sólo la capacidad de responder a estas preguntas puede proporcionar al trader unos resultados fiables.

Otro aspecto muy importante es el tiempo de ocio del trader. Este juego puede resultar mucho más útil que cualquier otro juego.

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

Archivos adjuntos |
trener.mq4 (6.7 KB)
Series temporales de previsión financiera Series temporales de previsión financiera
Las series temporales de previsión financiera son un elemento imprescindible para cualquier actividad de inversión. El concepto de invertir, poner dinero ahora para obtener beneficios en el futuro, está basado en el concepto de predecir el futuro. Por lo tanto, las series temporales de previsión financiera forman la base de las actividades de toda la industria de la inversión; todos los intercambios organizados y otros sistemas de trading de instrumentos financieros.
Una nueva mirada al gráfico Equivolume Una nueva mirada al gráfico Equivolume
El artículo aborda el método de construcción de gráficos en el cual cada barra está compuesta por el mismo número de ticks.
MetaTrader 4 en Linux MetaTrader 4 en Linux
En este artículo, explicaremos cómo instalar fácilmente MetaTrader 4 en las populares versiones de Linux Ubuntu y Debian. Estos sistemas se usan ampliamente no solo en el hardware de los servidores, sino también en los ordenadores habituales de los tráders.
Lenguaje MQL4 para principiantes. Indicadores personalizados (Segunda parte) Lenguaje MQL4 para principiantes. Indicadores personalizados (Segunda parte)
Este es el quinto artículo de la serie "El lenguaje MQL4 para principiantes". Hoy vamos a aprender a utilizar los objetos gráficos; una poderosa herramienta de desarrollo que nos permite ampliar significativamente las posibilidades de uso de los indicadores. Además, se pueden utilizar en los scripts y en los Asesores Expertos. Vamos a aprender a crear objetos, cambiar sus parámetros y comprobar los errores. Obviamente, no puedo describir detalladamente todos los objetos, hay demasiados. Pero le proporcionaré todos los conocimientos necesarios para que pueda entenderlos por sí mismo. Este artículo contiene también un guía paso a paso para crear un indicador de señales compuestas. A su vez, se podrán ajustar muchos parámetros de la configuración, lo que permitiría cambiar fácilmente el aspecto del indicador.