Experto comercial universal: Los modos comerciales de las estrategias (Parte 1)

Vasiliy Sokolov | 8 febrero, 2016

Contenido

 

Introducción

Las tareas que surgen durante la implementación de un algoritmo de comercio automático, son diversas. Se trata tanto del análisis del entorno y la obtención de señales en la entrada en el mercado, como del cierre de una posición ya existente. Comprende igualmente el control de la corrección de las acciones realizadas por el experto y el procesamiento adecuado de los errores comerciales. Y al fin, se trata también del acceso cómodo y sencillo a los datos del mercado y a las posiciones comerciales del propio experto. Todas estas tareas se implementan directamente en el código fuente del asesor.

Por otra parte, es conveniente separar la realización técnica del proceso comercial, y la propia idea implementada en el asesor de usuario. Gracias el enfoque orientado a objetos, se pueden separar estas dos tareas, distintas en esencia, y delegar la cobertura del proceso comercial en una clase especial común para todas las estrategias, a veces conocida también como motor comercial.

Este artículo inaugura una serie dedicada a la descripción del funcionamiento de uno de esos motores, que podemos llamar de manera convencional "Experto universal". Este nombre une un conjunto de clases que permiten escribir algoritmos comerciales con un sencillo método: una enumeración normal de las condiciones de entrada y salida de la posición. Además, no resulta imprescindible proporcionar a su experto los datos necesarios y una lógica comercial parecida a la iteración de posiciones, todo esto lo hará por usted el motor comercial.

El material que proponemos es amplio, por eso lo hemos dividido en cuatro partes. Describiremos estas partes con más detalle.

Parte 1. Modos comerciales de la estrategia. Se describen en este artículo. La primera parte está dedicada a un concepto original de gestión de posiciones, basado en los modos comerciales. Gracias a estos modos comerciales, se puede formular la lógica comercial del experto de forma fácil y sencilla. Un experto escrito en este estilo se puede ajustar de forma sencilla. La lógica de semejantes expertos se convierte en algo universal, lo que facilita la gestión de este tipo de estrategias. Las ideas explicadas en este material son universales y no exigen de escritura de código orientado a objetos. Esto significa que este material puede resultarle de utilidad, independientemente de si va usted a utilizar o no el conjunto propuesto de bibliotecas.

Parte 2. Modelo de eventos y prototipo de estrategia comercial.. En este apartado se describe un modelo de eventos original, basado en el procesamiento centralizado de eventos. Esto significa que los eventos se "reúnen" en un lugar de la lógica comercial del experto, que procesa dichos eventos. Además, los eventos son multiinstrumentales, por ejemplo, si el experto ha sido iniciado en la pareja de divisas EURUSD, se puede obtener un evento sobre la llegada de un nuevo tick en el instrumento GBPUSD. Este modelo de eventos puede ser muy útil a la hora de escribir expertos que comercien con varios instrumentos. En esta parte también se describe la clase básica del motor comercial MetaTrader 5: CPositionMT5.

Parte 3. Estrategias de usuario y clases comerciales auxiliares. El material está dedicado precisamente a la escritura de expertos de usuario. Tras la lectura del material, usted podrá aprender cómo crear un asesor experto con la ayuda de una enumeración simple de condiciones de entrada y salida de la posición. En esta parte, asimismo, se describen los diversos algoritmos auxiliares con la ayuda de los cuales se simplifica notablemente el acceso a la información comercial.

Parte 4. Comerciar en grupo y gestionar la cartera de estrategias. En esta parte se describen los algoritmos especiales con ayuda de los cuales se pueden integrar varias lógicas comerciales en un módulo ejecutor ex5. Asimismo, se describen los mecanismos que ayudan a la hora de formar un conjunto de estrategias de usuario con el uso de XML.

 

Métodos de apertura de una posición y de acompañamiento de una posición existente

Para comprender el enfoque propuesto en el artículo, vamos a intentar describir un sistema comercial clásico, basado en dos medias móviles: una de ellas tiene un periodo de promediación corto, y la otra, largo. De esta forma, la media móvil con mayor periodo de promediación resulta de mayor inercia o más lenta con respecto a la media móvil con el periodo de promediación menor. Las normas de comercio son simples: si la media móvil rápida está por encima de la lenta, entonces nuestro experto se encuentra en la zona de compra, y al contrario, si la media móvil rápida está por debajo de la lenta, el experto debe encontrarse en la de venta. Como ejemplo ilustrativo de lo anteriormente dicho, recurriremos a un gráfico que muestra nuestra estrategia de forma esquemática.

Fig. 1. Gráfico del sistema comercial con dos medias móviles

Con la línea roja se muestra una media móvil rápida simple con un periodo de 50. Con la línea azul se muestra una media móvil lenta con un periodo de 120. En el momento del cruce (se muestran con líneas punteadas azules) la dirección de la posición del experto cambia a la opuesta. Desde un punto de vista no algorítmico, esta descripción es suficiente para que cada tráder pueda comprender cómo comerciar según esta estrategia. Sin embargo, si queremos crear un experto basado en esta estrategia, esta descripción resultará claramente insuficiente.

Veamos las acciones comerciales que deberá realizar el experto en el momento en que la media rápida cruce la lenta de abajo hacia arriba:

  1. Si en el momento del cruce de las medias el experto tiene abierta una posición corta, será necesario cerrarla.
  2. Deberá asegurarse de la ausencia de una posición larga abierta con anterioridad. Si no hay una posición larga, deberá abrirla, y si la hay, no hacer nada.

Las acciones que se realizarán en el momento que la media móvil rápida cruce la lenta, serán opuestas en lo que respecta a su dirección:

  1. Si en el momento del cruce de las medias el experto tiene abierta una posición larga, será necesario cerrarla.
  2. Deberá asegurarse de la ausencia de una posición corta abierta con anterioridad. Si no hay una posición corta, deberá abrirla, y si la hay, no hacer nada.

En total, tenemos cuatro acciones comerciales para describir todo el proceso comercial. Para las acciones comerciales se describen las reglas de apertura y seguimiento de la posición larga. Las otras dos acciones describen las reglas de apertura y seguimiento de la posición corta. Puede parecer que cuatro acciones son demasiadas para describir un proceso comercial tan sencillo. En realidad, en nuestra estrategia, los momentos de entrada en una posición larga coinciden con los momentos de salida de la posición corta, entonces, ¿no será más sencillo unirlos en una acción comercial, o al menos en una acción lógica? No, no es más sencillo. Para comprobarlo, basta con cambiar un poco las condiciones en nuestra estrategia inicial.

Lo haremos de tal forma que para la compra se usarán diferentes conjuntos de medias. Por ejemplo, entraremos en la posición larga cuando la media móvil rápida con periodo 50 cruce la media móvil lenta con el periodo 120. Y empezaremos a vender cuando la media móvil rápida con periodo 20 cruce la media móvil lenta con el periodo 70. De acuerdo con las nuevas reglas, las señales de compra dejarán de coincidir con las señales de venta: comenzarán a aparecer en momentos y situaciones de mercado diferentes.

Las reglas propuestas no son inventadas. En realidad, en las estrategias se usan con frecuencia condiciones "inversas" para entrar y salir en el mercado: la entrada en una posición larga significa la salida de una corta, y al contrario. Sin embargo, no siempre sucede así, ni mucho menos, y si queremos crear el "esqueleto" universal de un asesor experto, necesitaremos tener en cuenta esto, por eso nuestras reglas serán cuatro.

Estudiemos nuestras acciones desde otro ángulo. Ahora mostraremos un recuadro, en la horizontal se indica el tipo de operación comercial (Buy o Sell), y en la vertical, el tipo de acción comercial (abrir o cerrar). En las propias celdas del recuadro, se indicará el conjunto concreto de acciones.

Buy Sell
Abrir 1. Si no hay posiciones largas y la media móvil rápida con periodo 50 está por encima de la media móvil lenta con periodo 120, abrir una posición larga 2. Si no hay posiciones cortas y la media móvil rápida con periodo 20 está por debajo de la media móvil lenta con periodo 70, abrir la posición corta
Cerrar 3. Si la media móvil rápida con periodo 50 está por debajo de la media móvil lenta con periodo 120, cerrar la posición larga 4. Si la media móvil rápida con periodo 20 está por encima de la media móvil lenta con periodo 70, cerrar la posición corta

 Recuadro 1. Conjunto de acciones comerciales

Desde el punto de vista de la programación, nuestros "conjuntos de reglas" o bloques del recuadro presentado, son funciones o métodos normales, que se encuentran dentro de la futura clase de estrategias universales. Vamos a darles nombre a estos cuatro métodos:

¿Qué es lo que aporta este enfoque? En primer lugar, hemos clasificado las acciones comerciales que deberá realizar el asesor experto para ejecutar correctamente la tarea comercial. Todas las acciones se han trasladado a bloques independientes: métodos de clase normales. Esto significa que no tendremos que pensar qué parte de la lógica comercial deberemos procesar en qué sitio. Toda la programación en este caso se reduce solo a la escritura de estos cuatro métodos.

En suegundo lugar, si en el futuro necesitamos cambiar la lógica comercial del experto, hacerlo será algo muy sencillo, para ello, bastará con completar los métodos correspondientes con condiciones adicionales. En tercer lugar, la organización de la lógica comercial que proponemos dará soporte a modos comerciales sencillos y naturales para cada experto escrito en este estilo.

 

Modos comerciales de la estrategia

Con mucha frecuencia, debemos limitar al experto en sus acciones comerciales. El ejemplo más claro de ello es prohibir al experto realizar operaciones cortas, o al revés, largas. En MetaTrader 4 se dispone de un interruptor estándar para tales modos. Se encuentra directamente en la pestaña de la ventana de propiedades del experto que aparece al iniciarse:

Fig. 2. Modos de comercio en MetaTrader 4

Fig. 2. Modos de comercio en MetaTrader 4

Sin embargo, la cantidad de modos puede ser mayor. Además, pueden usarse instrumentos más flexibles para configurar estos modos. Por ejemplo, en ciertos expertos, es necesario detener temporalmente el comercio en determinados momentos. Supongamos que durante la sesión del Pacífico en el mercado Forex, un asesor experto debe ignorar la llegada de nuevas señales a la entrada en la posición. Este enfoque es un método clásico de limitación del asesor experto en los momentos de poca volatilidad en el mercado Forex. ¿Cómo organizar mejor este modo de comercio y hacerlo a la vez opcional? De nuevo la organización de cuatro bloques de la lógica comercial nos ayudará mucho.

Si en el proceso del comercio, durante cierto tiempo es necesario prohibir la venta, entonces para ello bastará con dejar de llamar al método SellInit, que contiene las reglas de apertura de las posiciones cortas. Y es que precisamente dentro de este método tendrán lugar las acciones comerciales que iniciarán una nueva venta. Lo mismo sucede para la compra: si no se llama al método BuyInit, las posiciones largas no se abrirán. De esta forma, determinadas combinaciones de estos métodos se corresponderán con determinados modos comerciales del asesor. Describimos estos modos en el recuadro 2:

Modo comercial Descripción Métodos a los que se llama Métodos cuyas llamadas se omiten
Compras y ventas Se permiten las operaciones tanto de compra, como de venta. No hay limitaciones en el comercio. BuyInit
SellInit
BuySupport
SellSupport
Solo compras Solo se permiten las compras. No se realizan ventas. Las posiciones cortas abiertas con anterioridad se siguen de forma estándar hasta el momento de su cierre. BuyInit
BuySupport
SellSupport
SellInit
Solo venta Se permite solo la venta. No se realizan compras. Las posiciones largas abiertas con anterioridad se siguen de forma estándar hasta el momento de su cierre. SellInit
BuySupport
SellSupport
BuyInit
Ausencia de entradas nuevas Está prohibido abrir nuevas operaciones de venta y compra. Las posiciones largas y cortas abiertas con anterioridad se siguen de forma estándar hasta el momento de su cierre según las señales de salida. BuySupport
SellSupport
BuyInit
SellInit
Espera El control sobre el seguimiento de las posiciones abiertas anteriormente se detiene. La inicialización de nuevas operaciones de venta y compra se detiene. Este modo, normalmente, se usa en los momentos en los que el mercado está cerrado y no se pueden realizar acciones comerciales. BuyInit
SellInit
BuySupport
SellSupport
Stop Todas las posiciones abiertas con anterioridad se cierran forzosamente. Las nuevas posiciones, tanto de compra, como de venta, no se inicializan. Cierre de todas las posiciones abiertas con ayuda del método especial BuyInit
SellInit
BuySupport
SellSupport

 Recuadro 2. Modos comerciales del experto

Todos los modos comerciales se establecen al realizar la implementación práctica en MQL con la ayuda de la siguiente estructura ENUM_TRADE_STATE. Aquí tenemos su descripción:

//+------------------------------------------------------------------+
//| Define el estado comercial del experto.                          |
//+------------------------------------------------------------------+
enum ENUM_TRADE_STATE
{
   TRADE_BUY_AND_SELL,              // Se permite comprar y vender.
   TRADE_BUY_ONLY,                  // Se permite solo la compra. La venta está prohibida.
   TRADE_SELL_ONLY,                 // Se permite solo la venta. La compra está prohibida.
   TRADE_STOP,                      // El trading está prohibido. Cerrar de inmediato todas las posiciones. No admitir nuevas señales a la entrada.
   TRADE_WAIT,                      // El control sobre las posiciones abiertas se pierde. Las nuevas señales son ignoradas. Es útil en los momentos en los que salen noticias.
   TRADE_NO_NEW_ENTRY               // Las señales a la entrada se ignoran. Sin embargo, las posiciones ya abiertas se siguen según la lógica comercial. 
};

Estos modos permiten a cualquier experto escrito en el marco del enfoque propuesto activar y desactivar módulos comerciales lo más flexiblemente posible, pasándolo "sobre la marcha" a este u otro modo comercial.

 

Interruptor de modos comerciales CTradeState

Usando los modos comerciales, el experto siempre puede comprender en qué momento ejecutar esta u otra acción. Sin embargo, este momento, propiamente, debe ser establecido de forma individual para cada experto por separado. La gestión de modos es especialmente necesaria al comerciar en la sección FORTS de la Bolsa de Moscú. El comercio bursátil en esta sección tiene varias peculiaridades, la más importante de ellas es la realización del clearing dos veces al día, desde las 14:00 hasta las 14:03 (clearing intermedio) y desde las 18:45 hasta las 19:00 (clearing principal). No es en absoluto recomendable dar al experto la posibilidad de realizar acciones comerciales en esos momentos.

Por supuesto, si el experto funciona solo en los momentos de llegada de nuevos ticks o de formación de nuevas barras, entonces durante el cierre del mercado el experto no funcionará, dado que tampoco llegarán nuevas cotizaciones. Pero muchos expertos funcionan con una periodicidad establecida (según el temporizador), y para ellos es imprescindible el modo de control de acciones comerciales. Además, a veces las transacciones se pueden realizar los fines de semana y los días festivos, y algunos brókers Fórex proporcionan acceso a ellas incluso los fines de semana. Aunque debido a la baja volatilidad de esos días, así como su baja significación estadística, es mejor omitirlos.

De una forma u otra, la gestión de modos comerciales es un procedimiento imprescindible para cualquier tráder algorítmico profesional. Esta tarea se puede delegar en el módulo especial CTradeState. Este módulo está implementado en forma de clase MQL5, y entre sus tareas se incluye retornar el modo comercial que corresponde a la hora actual. Por ejemplo, si la hora actual corresponde al momento de realización del clearing de los cálculos, entonces el módulo retorna el estado TRADE_WAIT, si ha llegado el momento de cerrar todas las posiciones, el módulo retornará el estado TRADE_STOP. Vamos a describir su funcionamiento y los métodos de configuración de forma más detallada, para ello mostraremos los encabezamientos de esta clase:

//+------------------------------------------------------------------+
//|                                                  TimeControl.mqh |
//|                                 Copyright 2015, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Vasiliy Sokolov."
#property link      "http://www.mql5.com"
#include "Strategy.mqh"
#define ALL_DAYS_OF_WEEK 7
//+------------------------------------------------------------------+
//| Módulo de estados comerciales TradeState                         |
//+------------------------------------------------------------------+
class CTradeState
{
private:
   ENUM_TRADE_STATE  m_state[60*24*7];  // Máscara de estados comerciales
public:
                     CTradeState(void);
                     CTradeState(ENUM_TRADE_STATE default_state);
   ENUM_TRADE_STATE  GetTradeState(void);
   ENUM_TRADE_STATE  GetTradeState(datetime time_current);
   void              SetTradeState(datetime time_begin, datetime time_end, int day_of_week, ENUM_TRADE_STATE state);
};

La tarea principal de esta clase solo es una: retornar el modo de la estrategia actual, para ello es necesario llamar a su método GetTradeState. Pero antes de que el módulo pueda retornar el estado, dicho estado deberá ser añadido usando el método SetTradeState.

El algoritmo de funcionamiento del módulo recuerda a la pestaña "Horario" del agente de pruebas de MetaTrader 5:

Fig. 3. Pestaña "Horario" en el agente de pruebas de MetaTrader 5

Fig. 3. Pestaña "Horario" en el agente de pruebas de MetaTrader 5

Esta ventana permite establecer los diapasones de funcionamiento según los días de la semana durante los cuales se pueden ejecutar tareas de MQL5 Cloud Network. La clase CTradeState funciona de una forma semejante, pero permite establecer para cada diapasón uno de los cinco valores de la enumeración ENUM_TRADE_STATE.

Para comprender mejor cómo usar CTradeState, vamos a configurar un módulo de estados comerciales. Durante el trabajo diario en el mercado FORTS, el autor del presente artículo usa la siguiente configuración, presentada en forma de recuadro:

Hora Modo Descripción
10:00-10:01 TRADE_WAIT Hora de apertura del mercado. El momento de apertura se caracteriza por la volatilidad y los saltos bruscos del precio. Las acciones comerciales en estos momentos conllevan un gran riesgo, por eso durante el primer minuto es mejor abstenerse de comerciar, para lo cual debemos poner el experto en el modo espera.
14:00 - 14:03 TRADE_WAIT Hora de ejecución del clearing intermedio. En este intervalo de tiempo el mercado no funciona, por eso el asesor experto se debe poner en el modo TRADE_WAIT.
18:45 - 18:49 TRADE_WAIT Hora de ejecución del clearing principal. En este momento el mercado también está cerrado y el comercio está prohibido. Está en funcionamiento el modo TRADE_WAIT.
23:50 - 9:59 TRADE_WAIT El mercado está cerrado, el comercio está prohibido. Modo del asesor TRADE_WAIT.
Viernes, desde las 15:00 TRADE_NO_NEW_ENTRY Viernes, último día comercial de la semana. Para no dejar posiciones abiertas en los días festivos, se las deberá cerrar el último día de comercio. Por eso, abrir nuevas posiciones el último día comercial, para luego cerrarlas, no tiene mucho sentido. Para estos menesteres se usa el modo NO_NEW_ENTRY. Cada viernes, a partir de las 15:00, se ignoran todas las nuevas señales a la entrada. Las posiciones existentes solo pueden cerrarse.
Viernes, 23:40-23:50 TRADE_STOP Hora precedente al cierre del mercado. A esta hora, todas las órdenes deberán estar cerradas. El asesor experto, pasando al modo TRADE_STOP a las 23:40, cerrará su posición abierta y pasará al modo espera.
Sábado, domingo. TRADE_WAIT Los fines de semana no se comercia. Debido al traslado de las fiestas, algunos sábados pueden ser laborables. Esos días la bolsa funciona. Se trata de un fenómeno muy poco frecuente, y semejantes días "laborables" deben ser evitados, debido a su baja volatilidad y su vaguedad estadística. El comercio en estos días se deberá prohibir, independientemente de que se trate o no de un día laborable.

 Recuadro 3. Modos comerciales dependiendo de la hora

Como podemos ver por el recuadro, la configuración necesaria es una tarea en absoluto trivial, pero la clase CTradeState permite crear una combinación de modos parecida. Como ejemplo, mostraremos un script que establece los modos del recuadro, y acto seguido requiere el modo que corresponde a esta u otra hora:

//+------------------------------------------------------------------+
//|                                               TestTradeState.mq5 |
//|                                 Copyright 2015, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Vasiliy Sokolov."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <Strategy\TradeState.mqh>

CTradeState TradeState(TRADE_BUY_AND_SELL);  // Establecemos el modo por defecto Buy And Sell
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   TradeState.SetTradeState(D'15:00', D'23:39', FRIDAY, TRADE_NO_NEW_ENTRY);
   TradeState.SetTradeState(D'10:00', D'10:01', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'14:00', D'14:03', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'18:45', D'18:59', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'23:50', D'23:59', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'0:00',  D'9:59',  ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'23:40', D'23:49', FRIDAY, TRADE_STOP);
   TradeState.SetTradeState(D'00:00', D'23:59', SATURDAY, TRADE_WAIT);
   TradeState.SetTradeState(D'00:00', D'23:59', SUNDAY, TRADE_WAIT);
   
   printf("10:00 - " + EnumToString(TradeState.GetTradeState(D'10:00')));
   printf("14:01 - " + EnumToString(TradeState.GetTradeState(D'14:01')));
   printf("18:50 - " + EnumToString(TradeState.GetTradeState(D'18:50')));
   printf("23:50 - " + EnumToString(TradeState.GetTradeState(D'23:51')));
   printf("Friday, > 15:00 - " + EnumToString(TradeState.GetTradeState(D'2015.11.27 15:00')));
   printf("Saturday - " + EnumToString(TradeState.GetTradeState(D'2015.11.28')));
   printf("Sunday - " + EnumToString(TradeState.GetTradeState(D'2015.11.29')));
   printf("Default State - " + EnumToString(TradeState.GetTradeState(D'11:40')));
}
//+------------------------------------------------------------------+

El aspecto del script será el siguiente:

Default State - TRADE_BUY_AND_SELL
Sunday - TRADE_WAIT
Saturday - TRADE_WAIT
Friday, > 15:00 - TRADE_NO_NEW_ENTRY
23:50 - TRADE_STOP
18:50 - TRADE_WAIT
14:01 - TRADE_WAIT
10:00 - TRADE_WAIT

Preste atención al formato en el que se establecen los modos de comercio. En ellos no se usa el componente de la fecha, sino solo las horas y los minutos (D'15:00' o D'18:40'), Si al método se le transmite la fecha completa, por ejemplo así:

TradeState.SetTradeState(D'2015.11.27 15:00', D'2015.11.27 23:39', FRIDAY, TRADE_NO_NEW_ENTRY);

El componente de la fecha se ignorará de todas formas.

El segundo momento importante al que hay que prestar atención es la secuencia de llamadas a SetTradeState. ¡La secuencia es importante! El asunto es que el módulo CTradeState guarda una máscara de estados comerciales en forma de matriz ENUM_TRADE_STATE, cuya cantidad de elementos es igual a la cantidad de minutos en una semana (10 080 elementos). El método SetTradeState, basándose en las fechas transmitidas, calcula el diapasón de elementos de esta matriz, después de lo cual las rellena con el estado correspondiente. Esto significa que el estado anterior es sustituido por uno nuevo. De esta forma el último cambio se convierte en el definitivo. El código completo de este método se muestra más abajo:

//+-------------------------------------------------------------------------+
//| Establece el estado comercial TradeState                                |
//| INPUT:                                                                  |
//| time_begin  - Hora a partir de la cual se vuelve activo                 |
//|               el estado comercial.                                      |
//| time_end    - Hora hasta la cual funciona el estado comercial           |
//| day_of_week - Día de la semana al que se hace extensivo                 |
//|               el estado comercial. Se corresponde con los modificadores |
//|               ENUM_DAY_OF_WEEK o el modificador ALL_DAYS_OF_WEEK        |
//| state       - Estado comercial.                                         |
//| Atención, el componente de la fecha en time_begin y time_end se ignora. |
//+-------------------------------------------------------------------------+
void CTradeState::SetTradeState(datetime time_begin,datetime time_end, int day_of_week, ENUM_TRADE_STATE state)
{
   if(time_begin > time_end)
   {
      string sb = TimeToString(time_begin, TIME_MINUTES);
      string se = TimeToString(time_end, TIME_MINUTES);
      printf("Time " + sb + " must be more time " + se);
      return;
   }
   MqlDateTime btime, etime;
   TimeToStruct(time_begin, btime);
   TimeToStruct(time_end,  etime);
   for(int day = 0; day < ALL_DAYS_OF_WEEK; day++)
   {
      if(day != day_of_week && day_of_week != ALL_DAYS_OF_WEEK)
         continue;
      int i_day = day*60*24;
      int i_begin = i_day + (btime.hour*60) + btime.min;
      int i_end = i_day + (etime.hour*60) + etime.min;
      for(int i = i_begin; i <= i_end; i++)
         m_state[i] = state;
   }
}

El método GetTradeState funciona de forma más encilla. Calcula el índice del elemento de la matriz que corresponde a la hora requerida, después de lo cual retorna el valor de este elemento:

//+--------------------------------------------------------------------+
//| Retorna el estado comercial establecido anteriormente para la hora |
//| transmitida.                                                       |
//+--------------------------------------------------------------------+
ENUM_TRADE_STATE CTradeState::GetTradeState(datetime time_current)
{
   MqlDateTime dt;
   TimeToStruct(time_current, dt);
   int i_day = dt.day_of_week*60*24;
   int index = i_day + (dt.hour*60) + dt.min;
   return m_state[index];
}

El código fuente completo de la clase CTradeState se adjunta al archivo TradeState.mqh y está disponible dentro de los códigos fuente del motor comercial descrito. En las siguientes partes del artículo se escribirá sobre el funcionamiento de esta clase dentro de sus componentes.

 

Conclusión

Hemos descrito las cuatro reglas principales con la ayuda de las cuales podemos formular la lógica de prácticamente cualquier experto de forma bastante rápida y simple. Cada regla comercial supone una función o un método de clase independiente. Las diferentes combinaciones de llamadas de estos métodos determinan este o aquel modo de la estrategia. De esta forma, con la ayuda de unos recursos mínimos, se implementa un sistema bastante flexible de gestión del experto.

En la siguiente parte de esta serie de artículos, describiremos un modelo de eventos centralizado, con la ayuda del cual los métodos de la lógica comercial entienden qué evento comercial ha tenido lugar. Asimismo, hablaremos sobre los algoritmos comerciales auxiliares que reducen significativamente la complejidad de la recepción de la información comercial.

Puede descargar e instalar los códigos completos de la biblioteca "Experto universal" en su computadora. El código fuente de la biblioteca se incluye como aplicación a este material. La descripción de la mayor parte de las clases de esta biblioteca se dará en los siguientes artículos.