Bi-Directional Options Trade
MetaTrader 5 - Trading Systems Negociación bidireccional y cobertura de posiciones en MetaTrader 5 Uso de la API de HedgeTerminal, parte 2 Introducción Este artículo es una continuación de la primera parte Negociación bidireccional y cobertura de posiciones en MetaTrader 5 Uso del panel HedgeTerminal, parte 1. En la segunda parte, discutiremos la integración de Expert Advisors y otros programas MQL5 con la biblioteca HedgeTerminalAPI. Lea este artículo para aprender a trabajar con la biblioteca. Le ayudará a crear asesores expertos de comercio bidireccional mientras sigue trabajando en un entorno comercial cómodo y simple. Además de la descripción de la biblioteca, el artículo aborda los fundamentos de la negociación asíncrona y la programación de múltiples hilos. Estas descripciones se dan en la tercera y cuarta secciones de este artículo. Por lo tanto, este material será útil para los comerciantes que no están interesados en el comercio bidireccional, pero que les gustaría descubrir algo nuevo acerca de la programación asíncrona y multihilo. El material que se presenta a continuación está destinado a comerciantes algorítmicos experimentados que conocen el lenguaje de programación MQL5. Si no conoce MQL5, lea la primera parte del artículo, que contiene diagramas y dibujos sencillos que explican el principio general de la biblioteca y el panel HedgeTerminal. Capítulo 1. Interacción de los asesores expertos con HedgeTerminal y su panel 1.1. Instalación de HedgeTermianlAPI. El primer inicio de la biblioteca El proceso de instalación de HedgeTerminalAPI difiere de la instalación del panel visual HT, ya que la biblioteca no puede ejecutarse sola en MetaTrader 5. En su lugar, necesitará desarrollar un Asesor experto especial para llamar a la función HedgeTerminalInstall () desde la biblioteca. Esta función establecerá un archivo de encabezado especial Prototypes. mqh que describe las funciones disponibles en HedgeTerminalAPI. Una biblioteca se instala en un equipo en tres pasos: Paso 1. Descargue la biblioteca HedgeTerminalAPI en su computadora. Ubicación de la biblioteca en relación con su terminal: MQL5ExpertsMarketHedgeTerminalApi. ex5. Paso 2. Cree un nuevo Asesor experto en el Asistente MQL5 utilizando una plantilla estándar. El asistente MQL5 genera el código fuente siguiente: Paso 3. Sólo necesitará una función del consejero experto resultante - OnInit (). Y la directiva de exportación que describe la función de instalador especial HedgeTerminalInstall () exportada por la biblioteca HedgeTerminalApi. Ejecute esta función a la derecha en la función OnInit (). El código fuente marcado en amarillo realiza estas operaciones: Paso 4. Sus acciones adicionales dependen de si ha comprado la biblioteca. Si lo ha comprado, puede ejecutar el asesor experto en tiempo real directamente en el gráfico. Esto iniciará el instalador estándar de toda la línea de productos de HedgeTerminal. Puede completar este paso fácilmente siguiendo las instrucciones descritas en las secciones 2.1 y 2.2 del artículo Negociación bidireccional y cobertura de posiciones en MetaTrader 5 Uso del panel HedgeTerminal, Parte 1. El asistente de instalación instala todos los archivos necesarios, incluido el archivo de encabezado y el Asesor experto de prueba en el equipo. Si no ha comprado la biblioteca y sólo desea probarla, entonces la operación de EA en tiempo real no estará disponible para usted, pero puede probar la API ejecutando la EA en el probador de estrategia. El instalador no se ejecutará en este caso. En el modo de prueba, HedgeTermianalAPI funciona en un modo de usuario único, por lo que no necesita los archivos instalados en el modo normal. Esto significa que no necesita configurar nada más. Tan pronto como se realiza la prueba EA, la carpeta HedgeTerminal se crea en la carpeta común del terminal. La ruta normal al directorio común de los terminales de MetaTrader es c: UsersltUsernamegtAppDataRoamingMetaQuotesTerminalCommonFilesHedgeTerminal. Donde ltUsernamegt es el nombre de su cuenta de equipo actual. La carpeta HedgeTerminal ya contiene los archivos MQL5IncludePrototypes. mqh y MQL5ExpertsChaos2.mq5. Copie estos archivos en los mismos directorios de su terminal: file Prototypes. mqh to MetaTrader5MQL5Include. Y el archivo Chaos2.mq5 a MetaTrader5MQL5Experts. Archivo Prototypes. mqh es un archivo de encabezado que contiene la descripción de las funciones exportadas desde la biblioteca HedgeTerminalAPI. Su propósito y descripciones están contenidos en los comentarios a ellos. File Chaos2.mq5 contiene un ejemplo de EA descrito en la sección La función SendTradeRequest y la estructura HedgeTradeRequest a través del ejemplo de Chaos II EA. De esta forma, podrá comprender visualmente cómo funciona HedgeTerminalAPI y cómo desarrollar un asesor experto utilizando la tecnología de virtualización de HedgeTerminal. Los archivos copiados están disponibles para sus EAs. Por lo tanto, sólo necesita incluir el archivo de encabezado en el código fuente del Asesor experto para comenzar a utilizar la biblioteca. He aquí un ejemplo: Por ejemplo, el código anterior obtiene el número total de posiciones activas y muestra el número en la pestaña Expertos del terminal MetaTrader 5. Es importante entender que HedgeTerminal realmente se inicializa en la primera llamada de una de sus funciones. Esta inicialización se llama perezoso. Por lo tanto, la primera llamada de una de sus funciones puede tomar mucho tiempo. Si desea una respuesta rápida durante la primera ejecución, debe inicializar HT de antemano, por ejemplo, puede llamar a la función TransactionTotal () en el bloque de OnInit (). Con la inicialización perezosa puede omitir la inicialización explícita del Asesor experto. Esto simplifica enormemente el trabajo con HedgeTerminal y hace innecesario preconfigurarlo. 1.2. Integración de expertos asesores con el panel HedgeTerminal Si tiene el panel visual de HedgeTerminal y la versión completa de la biblioteca, que se puede ejecutar en tiempo real, puede integrar a sus asesores expertos con el panel para que todas las operaciones comerciales realizadas por ellos También aparecerá en el panel. En general, la integración no es visible. Si utiliza las funciones HedgeTermianalAPI, las acciones realizadas por los robots se muestran automáticamente en el panel. Sin embargo, puede ampliar la visualización indicando el nombre de EA en cada transacción comprometida. Puede hacerlo descomentando la siguiente línea en el archivo Settings. xml: Esta etiqueta está en las secciones ltActive-Positiongt y ltHistory-Positiongt. Ahora, los comentarios se eliminan y las etiquetas se incluyen en el procesamiento. Después del reinicio del panel, aparecerá una nueva columna de Magic en las tablas de posiciones activas e históricas. La columna contiene el número mágico del Asesor Experto, al que pertenece la posición. Si desea mostrar el nombre de EA en lugar de su número mágico, agregue el nombre al archivo de alias ExpertAliases. xml. Por ejemplo, un número mágico de EA es 123847. Y desea mostrar su nombre, como ExPro 1.1. Agregue la siguiente etiqueta al archivo: Si se hace correctamente, el nombre EA se mostrará en lugar de su magia en la columna apropiada: Fig. 1. Mostrando el nombre de EA en lugar de Magic Note que el panel y los Expert Advisors se comunican en tiempo real. Esto significa que si cierra una posición de EA directamente en el panel, la EA lo sabrá con la siguiente llamada de la función TransactionsTotal (). Y viceversa: después de que el Asesor experto cierra su posición, desaparece inmediatamente de la pestaña de posiciones activas. 1.3. Principios Generales de HedgeTerminalAPI Operación Además de las posiciones bidireccionales, HedgeTerminal también trabaja con otros tipos de operaciones, tales como órdenes pendientes, transacciones y operaciones de corredores. HedgeTerminal trata a todos estos tipos como un solo grupo de transacciones. Un acuerdo, una orden pendiente, una posición direccional - todos ellos son transacciones. Sin embargo, una transacción no puede existir por sí sola. En términos de programación orientada a objetos, una transacción puede ser introducida como una clase base abstracta, de la cual se heredan todas las entidades comerciales posibles, tales como ofertas y posiciones direccionales. A este respecto, todas las funciones de HedgeTerminalAPI se pueden dividir en varios grupos: Funciones de búsqueda y selección de transacciones. La firma común de las funciones y la forma en que funcionan casi completamente coinciden con las funciones OrderSend () y OrderSelect () en MetaTrader 4 Funciones para obtener propiedades de una transacción seleccionada. Cada transacción tiene un conjunto específico de propiedades y funciones específicas para la selección de propiedades. La firma común de las funciones y la forma en que funcionan se asemejan a las funciones del sistema MetaTrader 5 en la forma de acceder a posiciones, ofertas y pedidos (como OrderGetDouble () o HistoryDealGetInteger ()) HedgeTerminalAPI utiliza sólo una función de negociación: SendTradeRequest (). Esta función permite cerrar una posición bidireccional o parte de ella. La misma función se utiliza para modificar la pérdida de parada, tomar ganancias o el comentario saliente. Trabajar con la función es similar a OrderSend () en MetaTrader 5 La función para obtener errores comunes GetHedgeError (). Funciones para el análisis detallado de las acciones de negociación de HedgeTerminal: TotalActionsTask () y GetActionResult (). También se utiliza para la detección de errores. No hay análogos en MetaTrader 4 o MetaTrader 5. Trabajar con casi todas las funciones es similar a usar MetaTrader 4 y MetaTrader 5 funciones del sistema. Como regla, la entrada de función es algún identificador (valor de enumeración), y la función devuelve un valor que le corresponde. Hay enumeraciones específicas disponibles para cada función. La firma de llamada común es la siguiente: Consideremos un ejemplo de cómo obtener un identificador de posición único. Así es como se ve la línea en MetaTrader 5: En HedgeTerminal, la recepción de un identificador único de una posición bidireccional es la siguiente: Los principios generales de las funciones son los mismos. Sólo los tipos de enumeraciones difieren. 1.4. Selección de transacciones La selección de una transacción se realiza a través de la lista de transacciones, que es similar a la búsqueda de órdenes en MetaTrader 4. Sin embargo, en MetaTrader 4 sólo se buscan pedidos, mientras que en HedgeTerminal se puede encontrar cualquier cosa como una transacción O una posición de cobertura. Por lo tanto, cada transacción primero debe seleccionarse utilizando la función TransactionSelect () y, a continuación, su tipo debe identificarse a través de TransactionType (). Dos listas de transacciones están disponibles hasta la fecha: transacciones activas e históricas. La lista a aplicar se define en función del modificador ENUMMODETRADES. Es similar al modificador de MODETRADES en MetaTrader 4. El algoritmo de búsqueda y selección de transacciones es el siguiente: El código recorre la lista de transacciones activas en el ciclo para (línea 1). Antes de continuar con la transacción, selecciónela mediante TransactionSelect () (línea 3). Sólo se seleccionan posiciones bidireccionales de estas transacciones (línea 4). Si el número mágico de la posición y su símbolo no coinciden con el número mágico de la EA actual y el símbolo en el que se está ejecutando, HT pasa a la siguiente posición (líneas 5 y 6). Luego define el identificador de posición único (línea 8). Se debe prestar especial atención a la línea 7. Las posiciones seleccionadas deben ser verificadas en términos de posibilidad de modificación. Si la posición ya está en proceso de modificación, no se puede cambiar en el subproceso actual, aunque puede obtener una de sus propiedades. Si la posición está bloqueada, mejor espere hasta que se suelte para acceder a sus propiedades o vuelva a intentar modificarla. La propiedad HEDGEPOSITIONSTATE se utiliza para averiguar si es posible modificar la posición. El modificador POSITIONSTATEFROZEN indica que la posición está congelada y no se puede cambiar. El modificador POSITIONSTATEACTIVE muestra que una posición está activa y se puede cambiar. Estos modificadores se enumeran en la ENUMHEDGEPOSITIONSTATE enumeración, que se documenta en la sección correspondiente. Si se necesita una búsqueda a través de transacciones históricas, el modificador MODETRADES en las funciones TransactionTotal () y TransactionSelect () debe ser reemplazado por MODEHISTORY. Una transacción en HedgeTerminal puede anidarse en otra. Esto es muy diferente del concepto de MetaTrader 5 donde no hay anidamiento. Por ejemplo, la posición bidireccional histórica en HedgeTerminal consiste en dos órdenes, cada una de las cuales incluye un conjunto arbitrario de tratos. El anidamiento se puede representar de la siguiente manera: Fig. 2. Transacciones anidadas El anidamiento de transacciones se ve claramente en el panel visual de HedgeTerminal. La siguiente captura de pantalla muestra los detalles de una posición de MagicEx 1.3: Fig. 3. Transacciones anidadas en el panel HedgeTerminal Puede acceder a las propiedades de un pedido particular o de un contrato en la posición bidireccional. Seleccione una transacción histórica y asegúrese de que es una posición bidireccional Seleccione una de las órdenes de esta posición usando HedgeOrderSelect () Obtenga una de las propiedades de la orden seleccionada: el número de ofertas que contiene Seleccione una de las ofertas que pertenecen A la orden mediante la búsqueda a través de todas las ofertas Obtener la propiedad de oferta requerida. Tenga en cuenta que después de que la transacción ha sido seleccionada, sus propiedades específicas están disponibles para él. Por ejemplo, si la transacción es una orden, después de la selección a través de HedgeOrderSelect (). Usted puede encontrar el número de ofertas para él (HedgeOrderGetInter (HEDGEORDERDEALSTOTAL)) o el precio de entrada medio ponderado (HedgeDealGetDouble (HEDGEDEALPRICEEXECUTED)). Permite averiguar el precio del acuerdo 1197610. Que está marcado en rojo en la captura de pantalla. Este acuerdo forma parte de la posición bidireccional de MagicEx 1.3 EA. A través del siguiente código, el EA puede acceder a su posición y este trato: Después de la ejecución del código, se creará la siguiente entrada en la pestaña Expertos del terminal MetaTrader 5: El EA selecciona primero la posición 5917888 y luego selecciona el orden 6389111 dentro de la posición . Una vez que se selecciona el pedido, EA comienza a buscar el número de oferta 1197610. Cuando se encuentra el acuerdo, la EA obtiene su precio de ejecución y agrega el precio en la revista. 1.5. Cómo obtener códigos de error con GetHedgeError () Pueden producirse errores y situaciones imprevistas mientras se trabaja con el entorno HedgeTerminal. En estos casos se utilizan errores para obtener y analizar funciones. El caso más simple cuando se obtiene un error es cuando se olvida de seleccionar una transacción mediante la función TransactionSelect (). La función TransactionType () devolverá el modificador TRANSNOTDEFINED en este caso. Para entender dónde se encuentra el problema, necesitamos obtener el modificador del último error. El modificador nos dirá que ahora se ha seleccionado la transacción. El siguiente código lo hace: Este es el mensaje resultante: El ID de error sugiere que hemos olvidado seleccionar una transacción antes de intentar obtener su tipo. Todos los posibles errores se enumeran en la estructura ENUMHEDGEERR. 1.6. Análisis detallado de comercio e identificación de errores con TotalActionsTask () y GetActionResult () Además de los errores que se producen en el proceso de trabajar con el entorno HedgeTerminal, pueden producirse errores comerciales como resultado de la llamada a SendTradeRequest (). Estos tipos de errores son más difíciles de tratar. Una tarea realizada por SendTradeRequest () puede contener múltiples actividades comerciales (subtareas). Por ejemplo, para cambiar el comentario saliente en una posición activa protegida por un nivel de pérdida de stop, debe realizar dos acciones comerciales: Cancelar la orden de detención pendiente que representa el nivel de detención Coloque una nueva orden de detención pendiente con un nuevo comentario en lugar de orden anterior. Si la nueva orden de stop se activa, entonces su comentario se mostrará como un comentario cerrando la posición, que es una manera correcta. Sin embargo, la tarea se puede ejecutar en parte. Supongamos que la orden pendiente se cancela satisfactoriamente, pero la colocación de un nuevo pedido fracasa por cualquier razón. En este caso, la posición quedará sin el nivel de stop loss. Para poder manejar este error, el EA tendrá que llamar a un registro de tarea especial y buscar en él para encontrar la subtarea que falló. Esto se hace utilizando dos funciones: TotalActionsTask () devuelve el número total de acciones de negociación (subtareas) dentro de esta tarea y GetActionResult () acepta el índice de subtareas y devuelve su tipo y su resultado de ejecución. Dado que todas las operaciones comerciales se realizan utilizando herramientas estándar de MetaTrader 5, el resultado de su rendimiento corresponde al código de retorno del servidor comercial. En general, el algoritmo de búsqueda del motivo de fallo es el siguiente: Obtención del número total de subtareas en la tarea mediante TotalActionsTask () Búsqueda en todas las subtareas del bucle for. Determinar el tipo de cada subtarea y su resultado. Supongamos que no se pudo colocar la orden de finalización con un nuevo comentario porque el precio de ejecución del pedido estaba demasiado cerca del nivel de precios actual. El siguiente código de ejemplo muestra cómo el EA podría encontrar la razón de este error: El siguiente mensaje aparecerá después de la ejecución del código: Al comparar los números con los modificadores estándar de los códigos de retorno del servidor comercial, descubrimos que el pedido pendiente se eliminó correctamente, Pero la colocación de un nuevo pedido falló. El servidor de comercio devolvió un error 10015 (precio incorrecto), lo que puede significar que el precio actual está demasiado cerca del nivel de stop. Sabiendo esto, la EA puede tomar el control sobre los niveles de parada. Para ello, la EA sólo tendrá que cerrar esta posición utilizando la misma función SendTradeRequest (). 1.7. Seguimiento del Estatus de la Ejecución de la Tarea Comercial Cada tarea de negociación puede consistir en cualquier número de subtareas que se deben realizar secuencialmente. En el modo asíncrono, se puede realizar una tarea en varias pasadas del código. También puede haber casos en los que la tarea puede congelarse. Por lo tanto, se requiere el control de EA sobre la ejecución de la tarea. Al llamar a la función HedgePositionGetInteger () con el modificador HEDGEPOSITIONTASKSTATUS, devuelve la enumeración de tipo ENUMTASKSTATUS que contiene el estado de la tarea de posición actual. Por ejemplo, si algo sale mal después de enviar una orden para cerrar una posición, debido a que la posición no está cerrada, entonces necesita obtener el estado de la tarea. El siguiente ejemplo muestra el código que un Asesor experto asincrónico puede ejecutar para analizar el estado de la tarea para la posición: Tenga en cuenta que la ejecución de algunas tareas complejas requiere múltiples iteraciones. En el modo asíncrono, los sucesos próximos que señalan cambios en el entorno de negociación inician una nueva iteración. Por lo tanto, todas las iteraciones se realizan sin demora, una tras otra, siguiendo las respuestas recibidas del servidor comercial. La ejecución de tareas difiere en el modo síncrono. El método síncrono utiliza el emulador de la operación síncrona. Debido a que los usuarios pueden realizar incluso tareas compuestas en un solo paso. El emulador usa retrasos de tiempo. Por ejemplo, una vez iniciada la ejecución de una subtarea, el emulador no devuelve el subproceso de ejecución al EA. En su lugar, espera un tiempo esperando que el entorno comercial cambie. Después de eso, vuelve a leer el entorno comercial nuevamente. Si entiende que la subtarea se ha completado correctamente, inicia las siguientes subtareas. Este proceso reduce un tanto el rendimiento general, ya que toma algún tiempo esperar. Pero convierte la ejecución de tareas incluso complejas en una simple operación secuencial realizada en una sola llamada de función. Por lo tanto, casi nunca tendrá que analizar el registro de ejecución de tareas en el método síncrono. 1.8. Cómo modificar y cerrar posiciones bidireccionales Las posiciones bidireccionales se modifican y se cierran usando la función SendTradeRequest (). Sólo se pueden aplicar tres posiciones a una posición activa: Una posición puede ser total o parcialmente cerrada Posición de pérdida de parada y toma de ganancia se puede modificar El comentario saliente de una posición se puede cambiar. La posición histórica no puede ser el cambio. Similar a la función OrderSend () en MetaTrader 5, SendTradeRequest () utiliza una consulta pre-compilada en forma de una estructura de negociación HedgeTraderRequest. Lea la documentación para más detalles sobre la función SendTradeRequest () y la estructura HedgeTraderRequest. El ejemplo que muestra la modificación de posición y el cierre está disponible en la sección sobre Chaos II EA. 1.9. Cómo configurar las propiedades de HedgeTerminal desde un Asesor experto HedgeTerminal posee un conjunto de propiedades, como la frecuencia de actualización, el número de segundos que debe esperar una respuesta del servidor y otros. Todas estas propiedades se definen en Settings. xml. Cuando un EA se ejecuta en tiempo real, la biblioteca lee las propiedades del archivo y establece los parámetros internos apropiados. Cuando se evalúa la EA en un gráfico, no se utiliza el archivo Settings. xml. Sin embargo, en algunas situaciones puede que necesite modificar las propiedades de EA de forma individual, independientemente de si se está ejecutando en un gráfico o en el probador de estrategias. Esto se hace a través del conjunto especial de funciones HedgePropertySet La versión actual sólo cuenta con un prototipo de este conjunto: Por ejemplo, para establecer el tiempo de espera de la biblioteca para esperar una respuesta del servidor, escriba lo siguiente: Si la respuesta del servidor no se recibe dentro de 30 segundos después de enviar una solicitud asincrónica, se liberará la posición bloqueada. 1.10. Modos de operación síncronos y asíncronos HedgeTerminal y su API realizan actividades comerciales de forma totalmente asíncrona. Sin embargo, este modo requiere una lógica más compleja de EAs. Para ocultar esta complejidad, HedgeTerminalAPI incluye un emulador especial de operación síncrono, permitiendo que los EA desarrollados en un método síncrono convencional se comuniquen con algoritmos asíncronos de HedgeTerminalAPI. Esta interacción se revela en el momento de la modificación de la posición bidireccional y el cierre a través de SendTradeRequest (). Esta función permite ejecutar una tarea comercial en modo síncrono o asíncrono. De forma predeterminada, todas las acciones comerciales se ejecutan de forma síncrona a través del emulador de operaciones síncronas. Sin embargo, si una solicitud de comercio (HedgeTradeRequest estructura) contiene un indicador especificado explícitamente asynchmode true. La tarea comercial se realizará en un modo asíncrono. En el modo asíncrono, las tareas se realizan independientemente del subproceso principal. La implementación de la interacción entre un EA asincrónico y algoritmos asincrónicos de HedgeTerminal no está completa todavía. El emulador síncrono es muy simple. Comienza las subtareas de forma secuencial y luego espera un tiempo hasta que cambie el entorno de comercio en MetaTrader 5. El emulador analiza estos cambios y determina el estado de la tarea actual. Si la ejecución de la tarea tiene éxito, el emulador pasa a la siguiente. El emulador síncrono provoca retrasos menores en la ejecución de órdenes comerciales. Esto se debe al hecho de que el entorno de comercio en el MetaTrader 5 toma algo de tiempo para reflejar las actividades comerciales ejecutadas. La necesidad de acceso al entorno está relacionada principalmente con el hecho de que HedgeTermianlAPI no puede acceder a los eventos que llegan al controlador OnTradeTransaction () en el modo de emulación de subprocesos síncronos. Los problemas de interacción entre hilos asíncronos, así como entre los hilos asíncronos y síncronos a través de la emulación son demasiado complicados y no tienen soluciones obvias. 1.11. Gestión de propiedades de posición bidireccional a través del ejemplo de una secuencia de comandos En la secuencia siguiente, la función TransactionSelect () busca todas las transacciones disponibles en la lista de transacciones activas. Cada transacción se selecciona de la lista. Si la transacción es una posición, se accede a algunas de sus propiedades y se imprimen. Además de las propiedades de las posiciones, también se imprimen propiedades de órdenes y ofertas dentro de la posición. Una orden y un trato se seleccionan primero usando HedgeOrderSelect () y HedgeDealSelect (), respectivamente. Todas las propiedades de la posición, sus órdenes y ofertas se combinan e imprimen como una sola línea utilizando la función de sistema printf. 1.12. La función SendTradeRequest () y la estructura HedgeTradeRequest a través del ejemplo de Chaos II EA Como ejemplo, permite desarrollar un robot comercial basado en las tácticas comerciales propuestas por Bill Williams en su libro Trading Chaos. Segunda edicion . No seguiremos todas sus recomendaciones, pero simplificaremos el esquema omitiendo el indicador de Alligator y algunas otras condiciones. La elección de esta estrategia se deriva de varias consideraciones. La principal es que esta estrategia incluye tácticas compuestas de mantenimiento de posiciones. A veces es necesario cerrar una parte de una posición y mover la pérdida de stop a punto de equilibrio. Cuando se traslada al punto de equilibrio, el nivel de parada debe ser arrastrado siguiendo el precio. La segunda consideración es que esta táctica es bastante conocida y los indicadores desarrollados para ello están incluidos en el paquete de entrega estándar de MetaTrader 5. Permite modificar y simplificar ligeramente las reglas, para evitar que la lógica compleja del Asesor experto obstaculice sus objetivos principales: mostrar un ejemplo de interacción EA con la biblioteca HedgeTerminalAPI. La lógica EA utiliza la mayoría de las funciones comerciales de HedgeTerminalAPI. Esta es una buena prueba para la biblioteca. Comencemos en la barra de inversión. Una barra de reversión alcista es una barra con el precio de cierre en su tercio superior, cuyo Bajo es el más bajo para las últimas barras N. Una barra de reversión bajista es una barra con el precio de cierre en su tercio inferior, cuyo alto es el más alto para los últimos bares de N. N es un parámetro elegido al azar, que se puede configurar durante el inicio del Asesor Experto. Esto difiere de la estrategia clásica Chaos 2. Después de la barra de reversión se define, dos órdenes pendientes se colocan. Para una barra alcista, las órdenes se colocan por encima de su alto, una barra bajista - justo debajo de su punto bajo. Si estas dos órdenes no se activan durante las barras OldPending, la señal se considera obsoleta y los pedidos se cancelan. Los valores de OldPending y N son establecidos por el usuario antes de lanzar el EA en el gráfico. Las órdenes se activan y se convierten en dos posiciones bidireccionales. La EA distingue entre ellos por números en los comentarios, 1 y 2, respectivamente. Esta no es una solución muy elegante, pero su multa para fines de demostración. Una vez que las órdenes de activación, una pérdida de parada se coloca en la alta (para una barra bajista) o la baja (si la barra alcista) de la barra de inversión. La primera posición tiene objetivos apretados. Su beneficio de toma se establece de modo que en caso de activación, el beneficio de posición sería igual a la pérdida absoluta de una pérdida de parada activada. Por ejemplo, si una posición larga se abre a un precio de 1.0000, y su pérdida de stop está en el nivel de 0.9000, el nivel de beneficio de toma sería 1.0000 (1.0000 - 0.9000) 1.1000. El EA sale de la posición en stop loss o tomar ganancias. La segunda posición es de largo plazo. Su pérdida de parada se arrastra siguiendo el precio. La parada se mueve después del recién formado fractal de Bill Williams. Para una posición larga, el tope se mueve según los fractales inferiores, y los fractales superiores se usan para una posición corta. La EA sale de la posición sólo en stop loss. El siguiente gráfico ilustra esta estrategia: Fig. 4. La representación de las posiciones bidireccionales del Chaos 2 EA en el cuadro de precios Las barras de reversión están marcadas con un marco rojo. El período N en esta tabla es igual a 2. El momento más oportuno es elegido para esta estrategia. Las posiciones cortas se muestran como una línea punteada azul, las posiciones largas se representan en verde. Como puede verse, las posiciones largas y cortas pueden existir simultáneamente incluso en una estrategia relativamente simple. Preste atención al período del 5 al 8 de enero de 2014. Este es un punto de inflexión para la tendencia bajista AUDCAD. El 4 de enero se recibió una señal de la barra de inversión alcista y el 5 de enero se abrieron dos posiciones largas. Al mismo tiempo, todavía había tres posiciones cortas cuyas paradas fueron arrastradas siguiendo la tendencia (línea roja discontinua). A continuación, el 7 de enero, dejar de activado para las posiciones cortas, por lo que sólo las posiciones largas se quedaron en el mercado. Los cambios serían difíciles de controlar en una posición neta, ya que el volumen neto no tendría en cuenta el número de posiciones realmente mantenidas por la EA. HedgeTerminal permite a los EAs monitorear sus posiciones individuales independientemente de la posición neta actual, lo que hace posible obtener estos gráficos y desarrollar estrategias similares. A continuación se muestra el código que implementa esta estrategia. He intencionalmente no utilizar la programación orientada a objetos, la adaptación del código para los principiantes: A continuación se muestra una breve descripción de cómo funciona este código. El EA se llama en cada tick. Analiza la barra anterior mediante la función BarIsExtremum (): si es bajista o alcista, coloca dos órdenes pendientes (función SetNewPendingOrder ()). Una vez activadas, las órdenes pendientes se convierten en posiciones. El EA establece la pérdida de parada y tomar ganancias para las posiciones entonces. Desafortunadamente, estos niveles no pueden ser colocados junto con órdenes pendientes, porque todavía no hay una posición real. Los niveles se establecen a través de la función SupportPositions (). Para funcionar correctamente, necesitamos saber la posición para la cual tomaremos ganancia debe colocarse, y la posición que debemos seguir detrás de los fractales. Esta definición de posiciones se realiza mediante la función IdentifySelectPosition (). Analiza el comentario de la posición iniciadora, y si contiene la cadena 1, se establece un objetivo apretado si contiene 2, se aplica el tope final. Para modificar una posición bidireccional abierta, o para cerrarla, se crea una petición de comercio especial, la cual se envía a la función SendTradeRequest () para su ejecución: Preste atención al manejo de errores. Si el envío falla y la función devuelve false. Necesitamos obtener el último código de error utilizando la función GetHedgeError (). En algunos casos, la ejecución de una orden de negociación ni siquiera se iniciará. Si la posición no ha sido preseleccionada, entonces la consulta se realiza incorrectamente y su ejecución es imposible. Si un pedido no se ejecuta, no tiene sentido analizar el log de su implementación, obtener un código de error es suficiente. Sin embargo, si la consulta es correcta, pero el pedido no se ha ejecutado por alguna razón, se devolverá el error HEDGEERRTASKFAILED. En este caso, es necesario analizar el registro de ejecución de órdenes buscando en el registro. Esto se hace a través de la función especial PrintTaskLog (): Estos mensajes permiten identificar el motivo del fallo y arreglarlo. Ahora vamos a ilustrar la visualización de la Chaos2 EA y sus posiciones en HedgeTerminal en tiempo real. El EA se está ejecutando en el gráfico M1: Fig. 5. La representación de las posiciones bidireccionales del EA Caos 2 en el panel HedgeTerminal Como puede verse, incluso las posiciones bidireccionales de una EA pueden coexistir perfectamente. 1.13. Sobre los símbolos duplicados y la virtualización por Broker Cuando MetaTrader 5 fue lanzado, algunos corredores empezaron a proporcionar los llamados símbolos duplicados. Sus cotizaciones son iguales a los instrumentos originales, pero tienen un postfix como regla, como m o 1. Se introdujeron para permitir a los comerciantes tener posiciones bidireccionales en prácticamente el mismo símbolo. Sin embargo, estos símbolos son casi inútiles para los comerciantes algorítmicos que utilizan robots. Y heres por qué. Supongamos que necesitaríamos escribir el EA Caos II sin la biblioteca HedgeTerminalAPI. En su lugar, tendríamos algunos símbolos duplicados. ¿Cómo haríamos? Asumir que todas las operaciones de venta se abrieron en un solo instrumento, como EURUSD, y todas las operaciones de compra en el otro, por ejemplo EURUSDm1. But what would happen if, at the moment of position opening one of the symbols were already traded by another robot or by the trader Even if such symbols were always free, the problem would not be solved for this robot, which could simultaneously have multiple positions in the same direction. The screenshot above shows three sell positions, and there can be even more of them. The positions have different protective stop levels, that is why they cannot be combined into a single net position. The solution is to open a new position for a new duplicate symbol. But there can be not enough such symbols, because one robot needs six duplicate instruments (three in each trade direction). If two robots run on different timeframes, 12 symbols are required. None of the brokers provide so many duplicate symbols. But even if there were an unlimited amount of such symbols, and they were always free, a complex decomposition of the algorithm would be required. The robot would have to go through all the available symbols searching for duplicates and its own positions. This would create more problems than it could solve. There are even more difficulties with the duplicate symbols. Here is a brief list of additional problems arising from their use: You pay for each duplicate symbol in the form of negative swaps, because swaps for locking or partial locking are always negative, and this is the case when you keep two bi-directional positions on two different instruments. Not all brokers provide duplicate symbols. A strategy developed for a broker who provides duplicate symbols will not work with a broker providing only one instrument. The difference in the symbol names is another potential source of problems. Creating a duplicate symbol is not always possible. On transparent markets subject to strict regulations, any transaction is a financial document. The net position is the de facto standard in such markets and therefore creation of individual symbols is far from possible there. For example, no broker providing duplicate symbols can ever appear on Moscow Exchange MOEX. In less strict regulated markets brokers can create any symbols for their clients. Duplicate instruments are ineffective when trading using robots. The reasons for their ineffectiveness have been disclosed in the above example of the Chaos 2 EA. A duplicate symbol is essentially a virtualization on the broker side. HedgeTerminal uses virtualization on the client side. In both cases we use virtualization as such. It changes the actual representation of traders obligations. With virtualization, one position can turn into two positions. There is no problem when it occurs on the client side, because clients can represent whatever they want. But if virtualization is done by the broker, regulatory and licensing organizations may have questions about how the information provided relates to the actual information. The second difficulty is that this requires having two APIs in one: a set of functions and modifiers for use in the net mode, and another one for the bi-directional mode. Many algorithmic traders have found their own way to bind trades into a single position. Many of these methods work well, and there are articles describing these methods. However, virtualization of positions is a more complicated procedure than it might seem. In HedgeTerminal, the algorithms associated with virtualization of positions take about 20,000 lines of the source code. Moreover, HedgeTerminal implements only basic functions. Creating a similar amount of code in your EA only to accompany bi-directional positions would be too much resource consuming. Chapter 2. HedgeTerminal API Manual 2.1. Transaction Selection Functions The function returns the total number of transactions in the list of transactions. This is the basic function for searching though available transactions (see the example in section 1.4 and 1.11 of this article). in poolMODETRADES Specifies the identifier of the data source for selection. It can be one of the values of the ENUMMODETRADES enumeration. The function returns the total number of transactions in the list of transactions. The function returns the type of a selected transaction. Return type. The value can be one of the ENUMTRANSTYPE values. This function selects a transaction for further manipulations. The function selects a transaction by its index or unique identifier in the list of transactions. in index The index of the order in the list of orders or a unique identifier of the transaction depending on the select parameter. in selectSELECTBYPOS Identifier of the index type of the parameter. The value can be one of the ENUMMODESELECT values. in poolMODETRADES Specifies the identifier of the data source for selection. It can be one of the values of the ENUMMODETRADES enumeration. Returns true if a transaction has been successfully selected or false otherwise. To get error details, call GetHedgeError() . If a transaction is selected based on its index, the complexity of the operation corresponds to O(1) . If a transaction is selected based on its unique identifier, the complexity of the operation asymptotically tends to O(log2(n)) . The function selects one of the orders included in the bi-directional position. The bi-directional position, which includes the required order, must be pre-selected using TransactionSelect () . in type the identifier of the order to be selected. The value can be one of the ENUMHEDGEORDERSELECTEDTYPE enumeration values. Returns true if an order has been successfully selected or false otherwise. To get error details, call GetHedgeError() . The function selects one of the deals that have executed the order. The order the part of which is the selected deal must be pre-selected using the HedgeOrderSelect() function. in index The index of the deal to be selected from the list of deals that executed the order. To find out the total number of deals inside one order, call the appropriate order property using the HedgeOrderGetInteger() function. For the parameter, use the ENUMHEDGEORDERPROPINTEGER modifier equal to the HEDGEORDERDEALSTOTAL value. Returns true if a deal has been successfully selected or false otherwise. To get error details, call GetHedgeError() . 2.2. Functions for Getting Properties of a Selected Transaction The function returns the property of a selected bi-directional position. The property can be of type int. largo. datetime or bool depending on the type of the requested property. The bi-directional position must be pre-selected using the TransactionSelect() function. in property Identifier of the property of the bi-directional position. The value can be one of the ENUMHEDGEDEALPROPINTEGER enumeration values. Value of the ulong type. For further use of the value, its type should be explicitly cast to the type of the requested property. The function returns the property of a selected bi-directional position. The type of the return property is double. Property type is specified through the ENUMHEDGEPOSITIONPROPDOUBLE enumeration. The bi-directional position must be pre-selected using the TransactionSelect() . in property Identifier of the property of the bi-directional position. The value can be one of the ENUMHEDGEDEALPROPDOUBLE enumeration values. The function returns the property of a selected bi-directional position. The property is of the string type. Property type is specified through the ENUMHEDGEPOSITIONPROPSTRING enumeration. The bi-directional position must be pre-selected using the TransactionSelect() . in property Identifier of the property of the bi-directional position. The value can be one of the ENUMHEDGEPOSITIONPROPSTRING enumeration values. A value of the string type. The function returns the property of the selected order, which is part of the bi-directional position. The property can be of type int. largo. datetime or bool. Property type is specified through the ENUMHEDGEORDERPROPINTEGER enumeration. The order must be pre-selected using the HedgeOrderSelect() function. in property Identifier of the property of the order, which is part of the bi-directional position. The value can be one of the ENUMHEDGEORDERPROPINTEGER enumeration values. Value of the ulong type. For further use of the value, its type must be explicitly cast to the type of the requested property. The function returns the property of the selected order, which is part of the bi-directional position. The requested property is of the double type. Property type is specified through the ENUMHEDGEORDERPROPDOUBLE enumeration. The order must be pre-selected using the HedgeOrderSelect() function. in property Identifier of the property of the order, which is part of the bi-directional position. The value can be any of the ENUMHEDGEORDERPROPDOUBLE enumeration values. The function returns the property of the selected deal, which is part of the executed order. The property can be of type int. largo. datetime or bool. Property type is specified through the ENUMHEDGEDEALPROPINTEGER enumeration. The deal must be pre-selected using the HedgeDealSelect() function. in property Identifier of the property of the selected deal included in the executed order. The value can be one of the ENUMHEDGEDEALPROPINTEGER enumeration values. Value of the ulong type. For further use of the value, its type should be explicitly cast to the type of the requested property. The function returns the property of the selected deal, which is part of the executed order. The property can be of type double. Property type is specified through the ENUMHEDGEDEALPROPDOUBLE enumeration. The deal must be pre-selected using the HedgeDealSelect() function. in property Identifier of the property of the selected deal included in the executed order. The value can be one of the ENUMHEDGEDEALPROPDOUBLE enumeration values. 2.3. Functions for Setting and Getting HedgeTerminal Properties from Expert Advisors The function sets one of the HedgeTerminal properties. The property can be of type int. largo. datetime or bool. Property type is specified through the ENUMHEDGEPROPINTEGER enumeration. in property Identifier of the property that should be set for HedgeTerminal. The value can be one of the ENUMHEDGEPROPINTEGER enumeration values. A value of type bool. If the property has been successfully set, the function returns true, otherwise it returns false. In the example, the function is used to set the position locking time while sending an asynchronous request. If the server response is not received within 30 seconds after you send an asynchronous request, the blocked position will be unblocked. The function gets one of the HedgeTerminal properties. The property can be of type int. largo. datetime or bool. Property type is specified through the ENUMHEDGEPROPINTEGER enumeration. in property Identifier of the property that should be received from HedgeTerminal. The value can be one of the ENUMHEDGEPROPINTEGER enumeration values. A value of type long . The function receives the position blocking time while sending an asynchronous request and shows it in the terminal. 2.4. Functions for Getting and Handling Error Codes The function returns the identifier of the error, which was obtained from the last action. The error identifier corresponds to the ENUMHEDGEERR enumeration. Position ID. The value can be any of the ENUMHEDGEERR enumeration type. After the call, the GetHedgeError() function does not reset the error ID. To reset the error ID use the ResetHedgeError() function. The function resets the identifier of the last received error. After its call, the ENUMHEDGEERR identifier returned by GetHedgeError() will be equal to HEDGEERRNOTERROR . Once the position is selected using the HedgePositionSelect() function, it can be modified using the SendTradeRequest() function. For example, it can be closed, or its outgoing comment can be changed. This modification is performed by a special trading task . Each task can consist of several trading activities (subtasks). A task may fail. In this case you may need to analyze the result of all the subtasks included in the task to see what kind of the subtasks failed. The TotalActionTask() function returns the number of subtasks contained in the last trading task being executed for the selected position. Knowing the total number of subtasks, you can search though all the subtasks by their index, and analyze their execution results using the GetActionResult() function and thereby find out the circumstances of the failure. Returns the total number of subtasks within the task. The function takes the index of the subtask within the task (see TotalActionTask() ). Returns the type of the subtask and its execution results through reference parameters. The type of the subtask is defined by the ENUMTARGETTYPE enumeration. The subtask execution result corresponds to the MetaTrader 5 trade server return codes . in index The index of the subtask in the list of subtasks. out targettype Type of the subtask. The value can be one of the ENUMTARGETTYPE enumeration values. out retcode Trade server return code received upon the subtask execution. The function sends a request to change the selected bi-directional position in HedgeTerminalAPI. The function execution result is one of the three actions: Closing a position or a part of its volume Modification of stop loss and take profit levels Modification of the outgoing comment. The action type and its parameters are specified in the HedgeTradeRequest structure, which is passed by reference as a parameter. Before the function call, the bi-directional position must be pre-selected using the TransactionSelect() function. in request The structure of the request to modify the bi-directional position. Please see the structure description and the explanation of its fields in the description of the HedgeTradeRequest structure. Returns true, if the request for position modification has been successfully executed. Returns false otherwise. In case of request execution failure, use functions TotalActionsTask() and GetActionResult() to find the failure and its reasons. In the asynchronous mode of request sending, the return flag contains true if a task has been successfully placed and started. However, we must remember that even in the case of the successful start of a task, its execution cannot be guaranteed. Therefore this flag cannot be used to control task completion in the asynchronous mode. In the synchronous mode, a task is started and executed in a single thread, so in the synchronous mode, you can control the trade request execution result using this flag. Trade Request Structure HedgeTradeRequest() Bi-directional positions in HedgeTerminal are closed and modified through a call of the SendTradeRequest() function, in which the trade request is used as an argument. The request is represented by a special predefined structure HedgeTradeRequest, which contains all the fields necessary to close or modify the selected position: The enumeration defines a special marker for the order closing the bi-directional position. The marker indicates the reason for position closing. It can be one of the following reasons: The position has reached the maximum loss level or stop loss The position has reached a certain profit level or take profit Position closed by market. The stop loss and take profit levels were not placed or reached. Indicates that the position is closed by market. The stop loss and take profit levels were not placed or reached. Indicates that the position is closed due to reaching the stop loss level. Indicates that the position is closed due to reaching the take profit level. Chapter 3. The Fundamentals of Asynchronous Trading The subject of asynchronous operations is complex and requires a separate detailed article. However, due to the fact that HedgeTerminal actively uses asynchronous operations, it is appropriate to briefly describe the principles of organization of Expert Advisors using this type of request submission. In addition, there are almost no materials about the subject. 3.1. Organization and Scheme of Sending a Synchronous Trading Order MetaTrader 5 provides two functions for sending trade requests to the server: The OrderSend() function accepts a request as a filled MqlTradeRequest structure and performs basic verification of the structure correctness. If the basic verification is successful, it sends the request to a server, waits for its result, and then returns the result to the custom thread through the MqlTradeResult structure and the return flag. If the basic verification fails, the function returns a negative value. The reason why the request could not be verified is also included in MqlTradeResult. The below scheme features the execution of the thread of a custom MQL5 program with the OrderSend() function: Fig. 6. The scheme of organization and sending of a synchronous trade request. As seen from the scheme, the thread of the MQL5 program cannot be separated from the common system thread sending a request to the server and executing trade operations on the exchange. That is why, after completion of OrderSend(). we can analyze the actual result of the trade request. The custom thread is marked by red arrows. It is executed almost instantly. Most of the time is taken to perform trading operations on the exchange. Since the two threads are connected, considerable amount of time passes between the beginning and end of the OrderSend() function. Due to the fact that the trading operations are executed in a single thread, the logic of MQL5-programs can be sequential. 3.2. Organization and Scheme of Sending an Asynchronous Trading Order The OrderSendAsync() function is different. Like OrderSend(). it accepts the trade request MqlTradeRequest and returns a flag indicating its result. However, unlike the first example, it does not wait for the trade request to be executed by the server, but returns the values obtained only from the module of basic verification of trade request values (Basic verification inside the terminal). The below scheme shows the procedure of custom thread execution when using the OrderSendAsync() function: Fig. 7. The scheme of organization and sending of an asynchronous trade request. Once a trade request is successfully verified, it is sent to the trading server parallel to the main thread. Passing of a trade request over the network as well as its execution on the exchange takes some time, like in the first case. But the custom thread will get almost an instant result from the OrderSendAsync() function. The above scheme shows that OrderSendAsync() actually forms a new parallel thread which is executed by a trade server, and its execution result gets into the OnTradeTransaction() or OnTrade() function. These functions begin a new custom thread. The result of sending a trade request should be processed in this new thread. This greatly complicates the logic of the Expert Advisor, because with asynchronous order sending, it is impossible to organize sending of the request and its checking in a single thread. For example, you cannot sequentially place the code for sending and checking a request in OnTick() . Lets write a simple test EA to illustrate the above: Lets make sure that the EA works by starting it with UsingAsynchMode false. The EA opens a long 0.1-lot position. The trade request is performed synchronously using the OrderSend() function. Here is its sample log: The trade request was completed within 94 milliseconds. This time tells us that the request passed the basic verification, was sent to the server, and then was filled. Now we modify the EA code by changing the transaction volume to the maximum possible value DBLMAX : Obviously, this value is outside the actual range. Lets try to execute this request in the synchronous mode: Sending a request failed. The reason for the failure is error 10014 (Invalid requested volume). The request failed during the basic verification and was not even sent to the server, as clear from the request execution time of 0 milliseconds. Again, lets change the request. This time we specified a large enough volume, but not an extreme value 15 lots. For the account of 1,000 where the EA is tested, it is too much. Such a position cannot be opened on this account. Lets see what OrderSend() returns: The error is different this time: 10019 (Insufficient funds for request execution, which is true). Note that the request execution time is now 79 milliseconds . It indicates that the request was sent to the server, and that the server returned an error. Lets now send the same request with the 15-lot volume using the OrderSendAsync() function. Like with OrderSend(). no position is opened. But lets analyze the log: The log tells there is no error Since the error 10019 is detected by the trading server, it is not available for the current thread in the asynchronous order sending mode. The return value only indicates that the request passed the basic verification. In order to get the actual error 10019, we need to analyze the results in a new custom thread, in the OnTradeTransaction() system function, which should be added to our EA: Lets run the EA again and see logs: Error 10019 was received, but not immediately after sending. It was received in the new custom thread running in OnTradeTransaction() . 3.3. Asynchronous Order Execution Speed Traders mistakenly believe that the execution speed of an asynchronous request is close to zero. It stems from the observation of OrderSendAsync(). which is completed as a rule in less than one millisecond. In reality, as has been shown above, the actual time of execution of the trade transaction should be measured when a response from the serve is received inside the functions OnTradeTransaction() or OnTrade(). This measurement shows the real speed, which is equal to the speed of a synchronous execution for a single order. Real advantages in execution time are perceptible when sending a group of transactions. There are at least three situations where you need to send multiple requests: The required time between two successive requests is so small that there is no possibility to check the request result before sending the next one. When the next request is sent, it is hoped that the previous one has been executed. Similar tactics are used in high frequency trading You need to open multiple positions for multiple symbols at a time. For example, arbitrage strategies and composite synthetic positions require the simultaneous opening of positions for various instruments at current prices. The gradual formation of positions is undesirable in such tactics It is required to complete the thread as soon as possible and wait for further events and user commands. This requirement is important for multi-threaded and infrastructure solutions. This is the main reason why HedgeTerminal uses asynchronous requests. If HT used synchronous sending of requests, it would constantly freeze for 1-2 seconds each time the user closes or modifies the position, which it unacceptable. Remember to take into account the limit for sending requests when placing multiple orders. In MetaTrader 5 build 1010 and higher, the limit is 64 transactions, 4 of which are reserved for users, and others are available to Expert Advisors. The limit is aimed at protecting novice traders from serious errors in their programs, as well as reducing the spam load on a trading server. This means that at the same time, for example in the loop for, you can send up to 60 trade orders by calling SendOrderAsync() with an appropriate trade request. After all the 60 transactions are sent, the transaction buffer will be full. We need to wait for confirmation from the server that one of the transactions has been processed by the server. After being handled, the place of a transaction in the buffer of transactions is released, and a new trade request can take it. Once the buffer is full, the space for new transactions is released slowly, because a trade server needs time to process each transaction, and the TradeTransaction() event notifying of the start of processing is passed over the network, which causes additional delays. Thus, the time required to send requests will grow nonlinearly compared to the growth of the number of requests. The table below features the estimated rates of order sending in the asynchronous mode. Tests were carried out several times, and the shown rate is the mean value: Number of requests In the case where the number of requests is less than 60, the script does not wait for the server response, thats why the time is so small. It is approximately equal to the time it takes to send a single request. In fact, to get an approximate real execution time, add the average request execution time to the request placing time specified in the table. Chapter 4. The Fundamentals of Multi-Threaded Programming in the MetaTrader 5 IDE MQL5 programmers know that threads cannot be controlled directly from MQL-programs. This restriction is for the good of novice programmers, because the use of threads greatly complicates the program algorithms. However, in some situations, two or more EAs must communicate with each other, for example, they must create and read global data. HedgeTerminal is one of such EAs. To inform every EA using the HedgeTerminalAPI library about the actions of other Expert Advisors, the HT organizes data exchange through multi-threaded reading and writing of the ActivePositions. xml file. This solution is non-trivial and is rarely used by MQL programmers. Therefore, we will create a multi-threaded EA with the algorithm similar to HedgeTerminal. This will help to better understand the multi-threaded programming, and thus better understand how HedgeTerminal works. 4.1. Multithreaded Programming through the Example of Quote Collector UnitedExchangeQuotes We will learn the basics of multi-threaded programming through a specific example: well write a collector of quotes from different providers (brokers). The idea is this: suppose we have 6-7 brokers that provide quotes for the same instrument. Naturally, quotes from different brokers may vary slightly. The analysis of these differences opens the way to arbitrage strategies. In addition, comparison of quotes dynamics will help identify the best and worst provider. For example, if a broker is providing better prices, wed rather select this broker to trade with. We are not hunting for the practical value of the results, instead we only describe the mechanism by which these results can be achieved. Heres a screenshot of the EA that we will have to write by the end of this chapter: Fig. 8. The appearance of the quote collector UnitedExhangesQuotes. The Expert Advisor displays the results in a simple table consisting of four columns and an unlimited number of rows. Each row represents a broker providing symbol quotes (in this case, EURUSD). Ask and Bid are the best offer and demand of the broker. The screenshot shows that prices slightly differ. The difference between the offer of the current broker and another one appears in the D-ASK (Delta Ask) column. Similarly, the difference between the demand values is displayed in D-BID (Delta Bid). For example, at the time the screenshot was taken, the best Ask was provided by Alpari Limited, and the most expensive was that of Bank VTB 24. MQL programs cannot access the environment of other MetaTrader terminals. In other words, if a program is running on one terminal, it cannot receive data from another one. However, all MQL programs can communicate through the files in the shared directory of the MetaTrader terminals. If any program writes information, e. g. the current quote, to a file, the MQL program from another terminal can read it. MQL does not have any other means without external DLLs. Therefore, we will use this method. The greatest difficulty is to organize such access. On the one hand, the EA has to read quotes from other providers, and on the other - to write the quote of its provider to the same file. Another problem is the fact that at the time of reading quotes, another EA can be writing a new quote to this file. The result of such parallel work is unpredictable. At best, this will be followed by a crash and program interruption, and at worst this will lead to occasional emergence of strange subtle errors associated with the display of quotes. To eliminate these errors, or at least minimize the probability of their occurrence, we will develop a clear plan. Firstly, all the information will be stored in the XML format. This format has replaced the clumsy ini file. XML allows flexible deployment of its nodes into complex data structures, such as classes. Next, lets determine the general algorithm of reading and writing. There are two basic operations: reading data and writing data. When any MQL program is reading or writing, no other program can access this file. Thus we eliminate a situation where one program reads the data, and the second one changes them. Due to this, access to data will not always be possible. Lets create a special class CQuoteList that will contain the XML access algorithms, as well as data of all quotes from this file. One of the functions of this class is TryGetHandle(), it tries to access the file and returns its handle in case of success. Here is the implementation of the function: It makes several attempts to open the file in a combined read/write mode. The default number of attempts is ten. If an attempt is not successful, the function freezes for 15 milliseconds and retries to open the file, thus making up to 10 attempts. Once the file is opened, its handle is passed to the LoadQuotes() function. A complete listing of this function, and the CQuoteList class are available as an attachment to the article. So here we describe only the sequence of the actions in the function: TryGetHandle() opens the file to read and write The XML document is uploaded to the EA memory using the XML Parser library Based on the uploaded XML document, a new array of quotes is formed storing the required information The created array contains a quote belonging to the current EA. Its values are updated The array of quotes is converted back into an XML document. The contents of the open XML file are replaced with this XML document The XML file of quotes is closed. The LoadQuotes() function does a great job, but in most cases it takes less than 1 millisecond. Data reading and data updating with their further saving are combined into one block. This is done on purpose, so as not to lose control of access to the file between the operations of reading and writing. Once quotes are loaded and are inside a class, they can be accessed just like any other data in MetaTrader 5. This is done through a special MetaTrader 5 - style program interface implemented in the CQuotesList class. Function call and data rendering are performed inside the OnTick() block. Here are the contents: It is noteworthy that the sample code works both in MetaTrader 4 and in MetaTrader 5 without any additional modifications There are only minor cosmetic differences in the way the panels are displayed in different versions of the terminal. Undoubtedly, this is a remarkable fact that facilitates code porting between platforms. The operation of the EA is best observed in dynamics. The below video shows the EA operation on different accounts: Reading and writing to a file have significant advantages, but there are also some disadvantages. The main advantages are: Flexibility. You can store and load any data, even whole classes Relatively high speed. The entire cycle of reading and rewriting almost always takes mo more than 1 millisecond, which is a good time as compared to relatively slow trading operations that take 80 - 150 milliseconds or sometimes even more Based on the standard tools of the MQL5 language without calling DLL. The main drawback of such a solution is a serious load on the storage system. When there is one quote and two brokers, the number of rewrite operations is relatively small, but with a heavy stream of quotes and a large number of brokers/symbols, the number of rewrite operations becomes very large. In less than one hour, the demo EA produced over 90,000 Quotes. xml file rewriting operations. These statistics is shown at the top of the EA panel: I/O Rewrite shows the total number of file rewrites, fps indicates the rate between the last two rewrite operations, and Avrg displays the average speed of rewrites per second. If you store files on SSD or HDD, these operation will have a negative impact on the disk lifetime. Therefore it is better to use a virtual RAM disk for such a data exchange. Unlike the above example, HedgeTerminal sparingly uses ActivePositions. xml. writing only significant position changes that are inaccessible through the global context. So it produces much fewer read/write operations than the above example, and therefore does not require any special conditions, such as RAM disks. 4.2. Use of Multi-Threaded Interaction between Expert Advisors Real time interaction between independent MQL programs is a complicated but interesting subject. The article contains only a very brief description of it, but it is worthy of a separate article. In most cases the multi-threaded interaction between Expert Advisors is not required. However, here is a list of tasks and the variety of programs, for which the organization of such interaction is required: Trade copier. Any trade copier involves simultaneous launch of at least two EAs, one of which provides trades, the other one copies them. In this case, it is necessary to organize multi-threaded reading/writing of a common data file for providing and copying trades Organization of global data exchange between EAs, global variables. Standard global variables in MetaTrader 5 are available to Expert Advisors only at the level of one terminal. A global variable declared in one terminal is not available in the other. However, through the use of common data, you can organize complex global variables that might be available for all terminals even of different versions Arbitrage strategies. Analyzers of quotes from different liquidity providers. If the difference between prices provided by different brokers is significant, traders can benefit from this by creating arbitrage strategies. Analyzers also allow gathering statistics of the best prices and objectively identify the best liquidity provider. Description of Attachments Here is a brief description of files attached to the article, as well as of the compilation procedure. Prototypes. mqh is a file with the description of the HedgeTerminalAPI library functions. This file contains the description and prototypes of the functions from the HedgeTerminalAPI library. It lets your EA know what functions and modifiers are available in the library, how to call the functions, and what values they return. Save this file to C:Program FilesMetaTrader 5MQL5Include. where C:Program FilesMetaTrader 5 is the name of the directory where your MetaTrader 5 terminal is installed. Once the file is copied to the correct directory, you can refer to it in your MQL program. This should be done whenever you need to use the HedgeTerminalAPI library. To refer to the Prototypes. mqh file, add the special file include directory into your code: In the above example, this directive is marked in yellow and is called include ltPtototypes. mqhgt . Now the script above can refer to the library functions and use their functionality. Please note that in the process of development of the HedgeTerminalAPI library, the file of the prototypes may undergo minor changes. Often, with the update of the library version, you will need to update the prototype file, which will describe the changes. Please take this uncomfortable factor with understanding. In any case, the latest version of the prototype file can always be installed manually from the library (the installation procedure is described in section 1.1 ) or downloaded from the attachment to this article (regular updates for the attachments are expected). Chaos2.mqh is a source code of the Chaos2 EA. Its operation is described in section 1.12: The example of the SendTradeRequest function and the HedgeTradeRequest function through the example of Chaos II EA. To successfully compile the code, save the file of function prototypes to the corresponding directory Include and save the HedgeTerminalAPI library to: C:Program FilesMetaTrader 5MQL5Markethedgeterminalapi. ex5. Where C: Program Files MetaTrader 5 is the name of the directory (terminal data folder) where your MetaTrader 5 terminal is installed. The UnitedExchangeQuotes source code is the special zip archive ( unitedexchangequotes. zip ) that contains the project described in detail in chapter 4: The fundamentals of multi-threaded programming in the MetaTrader 5 IDE . This zip contains the following files: UnitedExchangeQuotes. mq5 - the central file of the EA. Save it to the experts folder: MetaTrader 5MQL5Experts. Compile this file in MetaEditor. MultiThreadXML. mqh is the main file containing algorithms of multi-threaded access to the XML file. It organizes the information exchange between independent threads. Save to MetaTrader 5MQL5Include. The algorithms in this file are based on the special library developed by ya-sha. available in CodeBase. However, it has been slightly modified for multi-threaded operation. The attachment contains this modified version. It consists of the following files: XmlBase. mqh XmlDocument. mqh XmlAttribute. mqh XmlElement. mqh. Save these files to the Include folder. Panel. mqh contains the panel class described in the example. Save this file into the same directory where you save UnitedEchangesQuotes. mqh. i. e. to the Experts folder. All files in the archive contain relative paths. For example, file UnitedExchangeQuotes. mq5 is located in folder MQL5Experts. This means that it should be placed in the same subdirectory of the MetaTrader 5 terminal data folder, such as C:Program FilesMetaTrader 5MQL5ExpertsUnitedExchangeQuotes. mq5 . Conclusion We have considered the details of working with the HedgeTerminal program interface. It has been shown that the principles of this library are very much similar to MetaTrader 4 API. Like in MetaTrader 4 API, before you start working with a transaction (an analogue of the order concept in MetaTrader 4), you should first select it using the TransactionSelect(). A transaction in Hedge Terminal is a bi-directional position as a rule. Once a position is selected, you can get its properties or apply a trading action to it, for example, set a stop loss level or close it. This sequence of actions is almost identical to the algorithm of working with orders in MetaTrader 4. In addition to basic information about the number of bi-directional positions and their properties, HedgeTerminal provides access to the values that are not available directly in MetaTrader 5 and require complex analytical calculations. For example, you can see the amount of slippage of each bi-directional position by requesting only one of its properties. You can check the number of deals inside a selected position. All such calculations and the required matching of deals are performed behind the scenes during start of HedgeTerminal. It is convenient because the trading Expert Advisor does not need to calculate anything. All the necessary information has been already calculated and is available through a simple and intuitive API. The use of the common algorithms by the HedgeTerminal API and the panel enables unified data presentation. Therefore, you can control EAs from the HedgeTerminal panel, while changes made by the EA will be displayed straight on the panel. MetaTrader 5 - Trading Bi-Directional Trading and Hedging of Positions in MetaTrader 5 Using the HedgeTerminal Panel, Part 1 Table of Contents Introduction Within the last 18 months MetaQuotes have conducted extensive work on consolidating the MetaTrader 4 and MetaTrader 5 platforms into a unified trading ecosystem. Now both platforms share a common market of program solutions - Market. offering different products from external developers. The compilers for both platforms were united as well. As a result both platforms have a common compiler based on MQL5 and one programming language - MQL with a different function set depending on the platform in use. All publicly available source codes located in the Code Base were also revised and some of them were adjusted to be compatible with the new compiler. This major unification of the platforms left aside the unification of their trading parts. The trading models of MetaTrader 4 and MetaTrader 5 are still fundamentally incompatible despite the fact that the major part of the trading environment is shared. MetaTrader 4 facilitates individual management of trading positions through the system of orders - special program entities making the bi-directional trading in this terminal simple and easy. MetaTrader 5 is intended for the exchange trade where the main representation of a traders obligations is their aggregate net position. Orders in MetaTrader 5 are simply instructions to buy or sell a financial instrument. The difference between the trading performance of these two platforms caused a lot of heated discussions and debates. However, discussions remained discussions. Unfortunately, since the release of MetaTrader 5, not a single working solution was published that could enable presenting a traders obligations as bi-directed positions like in MetaTrader 4. Although numerous published articles suggest various solutions, they are not flexible enough to be conveniently used on a large scale. In addition, none of those decisions are suitable for the exchange trading, which involves a lot of nuances that have to be taken into consideration. This article should settle the controversies between the fans of the fourth and the fifth versions of the MetaTrader platform. This is going to provide a universal solution in the form of thorough program specification and the exact program solution implemented by this specification. This article discusses a visual panel and the virtualization library HedgeTerminal . which enable presenting a traders obligation as bi-directional positions like in MetaTrader 4. At the same time, the model underlying HedgeTerminal takes into account the character of the trading orders execution. That means that it can be successfully implemented both at the over-the-counter market FOREX and centralized exchanges like, for example, trading derivative securities in the derivatives section of Moscow Exchange . HedgeTerminal is a fully featured trading terminal inside the MetaTrader 5 terminal. Through the mechanism of virtualization it changes the representation of the current positions so a trader or a trading robot can manage their individual trading positions. Neither the number of positions, nor their direction have any importance. I would like to place emphasis on the fact that we are talking about virtualization - a specific mechanism transforming the presentation of a traders obligations but not their qualitative characteristics. This is not about distorting the results of the traders financial activity but about transforming representation of this activity. HedgeTerminal is based on the MetaTrader 5 trading environment and the MQL5 programming language. It does not bring new trading information to the terminal, it simply makes the current trading environment seen from a different angle. That means that HedgeTerminal is essentially MetaTrader 5 and is its native application. Even though, we could put an identity sign between them, an inclusion sign is more appropriate as HedgeTerminal is just a small and one of many MetaTrader 5 applications. The virtualization possibility and the HedgeTerminal existence are based on three paradigms: Conceptually, a complete and guaranteed convertibility of the position net representation into individual bi-directional trading transactions is possible . This statement proves the fact that in some external trading platforms including the ones designed for exchange trading, there is a means to manage bi-directional positions The trading model of MetaTrader 5 at the users level allows creating one way links of orders to each other . Calculations have shown that links designed in a certain way will be resistant to collisions. Moreover, even in the case of a corrupted history or any force majeure situations, bi-directional transactions could be retrospectively corrected and brought down to a financial result calculated at net representation Advanced API in MQL5 allows to put the identity sign between MQL5 and the MetaTrader 5 terminal . In other words, nearly everything in MetaTrader 5 is accessible through the program interface and the MQL5 programming language. For instance, your own version of the terminal can be written inside the MetaTrader 5 terminal like HedgeTerminal. This article discusses the underlying algorithms and how HedgeTerminal works. The specifications and algorithms ensuring consistent bi-directional trading are discussed in this article in detail. Irrespective of whether you decide to use HedgeTerminal or to create your own library to manage your own trading algorithms, you will find useful information in this article and its continuation. This article is not targeting programmers specifically. If you do not have any experience in programming, you are still going to understand it. The MQL source code is not included in this article deliberately. All source code was replaced with more illustrative diagrams, tables and pictures schematically representing the operational principle and the data organization. I can tell from experience that even having a good grasp of programming principles, it is a lot easier to see a common pattern of the code than to analyze it. In the second part of this article, we are going to talk about the integration of Expert Advisors with the HedgeTerminalAPI visualization library and then programming will be involved. However, even in that case, everything was done to simplify the perception of the code especially for novice programmers. For instance, object-oriented constructions like classes are not used though HedgeTerminal is an object oriented application. How to Read this Article This article is rather lengthy. On the one hand, this is good as the answer to virtually any question regarding this topic can be found here. On the other hand, many users would prefer to read only the most important information returning to the relevant section whenever necessity arises. This article covers in full a consistent presentation of the material. Similar to books, we are going to give a short summary of every chapter so you can see whether you need to read it or not. Part 1, Chapter 1. Theory of the bi-directional trading organization. This chapter contains the main ideas of HedgeTerminal. If you do not want in-depth information about organization of bi-directional trading, this chapter is sufficient to get an idea of the general principles of HedgeTerminal operation. This chapter is recommended for all readers. Part 1, Chapter 2. Installation of HedgeTerminal, first launch. This chapter describes the launch and setting up the visual panel of HedgeTerminal. If you are not going to use a visual panel of HedgeTerminal, then you can skip this chapter. If you, however, are going to use the HedgeTerminalAPI library, you will need to go through sections 2.1 and 2.2 of this chapter. They are dedicated to the HedgeTerminal installer. The installer is the common component for all the HedgeTerminal products. Part 1, Chapter 3. Under the bonnet of HedgeTerminal. Specification and principle of operations. This chapter highlights the internal arrangement of HedgeTerminal, its algorithm and internal data organization. Those who are interested in bi-directional trading may find this chapter informative. Professional algorithmic traders developing their own virtualization libraries and using a lot of robots simultaneously can find this chapter useful too. Part 2, Chapter 1. Communication of Expert Advisors with HedgeTerminal and its panel . This chapter will be appreciated by those who are just exploring this aspect and those who are in algorithmic trading professionally. It describes common principles of work with the HedgeTerminal library and the architecture of the trading robot. Part 2, Chapter 2. Documentation to the API HedgeTerminal. Contains documentation on using the functions of the HedgeTerminalAPI library. The chapter is written as a list of documentation that could be referred to from time to time. There are no unnecessary discussions and excessive text in it. This chapter contains only prototypes of function, structures and enumerations as well as brief examples of their usage. Part 2, Chapter 3. Basics of asynchronous trading operations. HedgeTerminal uses asynchronous operations in its work. This chapter comprises the experience of using them. This chapter was included in this article so any reader could find some useful information irrespective of their plans to use the HedgeTerminal in their work. Part 2, Chapter 4. Basics of multi-threaded programming in the MetaTrader environment. This chapter explains what multi-threading is, how to arrange it and what patterns of data organization can be used. Like Chapter 3 it shares the experience of multi-threaded application development with all MetaTrader users. I hope that this article is interesting enough so you read it up to the end. Chapter 1. Organization theory of bi-directional trading 1.1. MetaTrader 5 Opportunities in Organizing Bi-Directional Trading The article Principles of Exchange Pricing through the Example of Moscow Exchanges Derivatives Market carefully describes the nuances of the exchange price formation and methods of financial result calculation of the market players. It outlines that pricing and calculation on the Moscow Exchange significantly differ from concepts and calculation methods accepted in the FOREX trading. On the whole, formation of the exchange price is more complex and contains a lot of significant details hidden when trading Forex and in the MetaTrader 4 terminal. For example, in MetaTrader 4 the deals that executed the traders order are hidden whereas in MetaTrader 5 such information is available. On the other hand, detailed trade information in MetaTrader 5 is not always required. It may make work difficult for an inexperienced user or a novice programmer and cause misunderstanding. For example, in MetaTrader 4, to find out the price of the executed order, you simple need to look up the correspondent value in the Price column. In the MQL4 programming language it is enough to call the OrderOpenPrice() function. In MetaTrader 5 it is required to find all the deals that executed the order and then go over them and calculate their weighted average price. This very price is the price of the order execution. There are other situations when extended representation of the trading environment in MetaTrader 5 requires additional efforts to analyze this information. That prompts logical questions: Is there a way of making the trading process in MetaTrader 5 as simple and clear as in MetaTrader 4 and keep a convenient access to all required trade details If there is a way to arrange bi-directional exchange trading using MetaTrader 5 the same simple way as MetaTrader 4 - The answer to those questions is: Yes, there is Let us refer to the diagram of capabilities of the MetaTrader 4 and MetaTrader 5 terminals to understand how this is possible: Fig. 1 Capabilities of MetaTrader 4 and MetaTrader 5 As we can see, the MetaTrader 5 set includes the MetaTrader 4 subset. It means that everything possible in MetaTrader 4 can be done in MetaTrader 5 though the converse is false. New capabilities of MetaTrader 5 inevitably increase the amount and the complexity of the trade information presentation. This difficulty can be delegated to special assistant programs working in the MetaTrader 5 environment. These programs can process the complexity, leaving the terminal capabilities at the same level. One of such programs HedgeTerminal is the focus of this chapter. HedgeTerminal is a full-fledged trading terminal inside the MetaTrader 5 terminal. It uses the MetaTrader 5 trading environment, transforms it with the MQL5 language and represents it as a convenient graphical interface - panel HedgeTerminalUltimate and special interface HedgeTerminalAPI for interaction with independent algorithms (Expert Advisors, scripts and indicators). MetaTrader 4 features a possibility to use bi-directional positions or locking orders . In MetaTrader 5 there is such capability too but it is not explicit. This can be enabled using a specific add-on program, which HedgeTerminal essentially is. HedgeTerminal is built in MetaTrader 5 and uses its environment, gathering information by deals and orders into integrated positions looking very similar to orders in MetaTrader 4 and having all the capabilities of MetaTrader 5. Such positions can be in a complete or partial locking order (when active long and short positions exist at the same time). The opportunity of maintaining such positions is not a goal in itself for HedgeTerminal. Its main objective is to unite trade information in unified groups (positions) that would be easy to analyze, manage and get access to. Bi-directional positions can exist in HedgeTerminal only because this is very convenient. In the case several traders are trading on one account, or more than one strategy is used, splitting trading actions must be arranged. In addition, a number of nuances have to be taken into consideration at exchange trading such as partial order execution, position rollover, variation margin calculation, statistics and many others. HedgeTerminal was developed for meeting those challenges. It provides the user or an Expert Advisor a regular high level interface resembling MetaTrader 4 and at the same time working correctly in the exchange environment. 1.2. Pairing orders - Basis of Hedging and Statistics To be able to manage trading techniques and algorithms consistently, it is required to know with certainty what trading action belongs to what algorithm. I highlighted the words with certainty because if there is even the smallest probability of failure, crash of position management is inevitable sooner or later. In its turn, it will result in damage of statistics and undermining the idea of managing different algorithms on one account. A reliable separation of trade activities is based on two fundamental possibilities: The possibility of uniting or pairing two trading orders together so it can always be defined which of the two orders is opening the individual (virtual) position and which of them is closing this position The algorithm, analyzing orders for their pairing must be completely deterministic and unified for all program modules. The second requirement for the algorithm determinism will be considered in detail below. Now we are going to focus on the first one. An order is an instruction to sell or buy. An order is a defined entity, which includes many more information fields in addition to the main information like magic number and order number, required price and opening conditions. One of such fields in MetaTrader 5 is called Order Magic . This is a specified field used for a trading robot or an Expert Advisor to be able to mark this order with its individual unique number also called the magic number. This field is not used in manual trade though it is very important for trading algorithms because when a trading algorithm analyses the values of this field, it can always see if the order in question was placed by it or any other algorithm. Let us take a look at an example. Let us assume that we need to open a classical long position and then, in some time, close it. For that we have to place two orders. The first order will open this position and the second order will close it: Fig. 2. Orders forming a historical net position What if we write the magic number of the first order in the field Order Magic of the second order at the moment of sending it to the market Later, this orders field can be read and if the value is equal to the number of the first order, then we can definitely say that the second order is related to the first one and is opposite to it, i. e. a closing order. On a diagram this pairing would look like: Fig. 3. Pairing orders Nominally such orders can be called paired as the second order contains a link to the first one. The first order opening a new position can be called an initiating or opening order. The second order can be called closing . A pair of such orders can be called position . To avoid confusion with the concept of position in MetaTrader 5, we are going to call such paired positions bi-directional, hedging or the HedgeTerminal positions. Positions in MetaTrader 5 will be called net positions or the MetaTrader 5 classical positions. Apparently, the number of HedgeTerminal positions and their directions, unlike the classical ones, can be any. What if there is an executed order that is not referred to by any other order Such an order can be presented as an active bi-directional position. In fact, if an opposite order that contains a link to this order is placed, it will become an order that closes the first order. Such orders will become paired and make a closed bi-directional position as the volume of two orders is going to be equal and their direction is opposite. So, let us define what is meant in HedgeTerminal by position: If an executed order is not referred to by any other order, then HedgeTerminal treats such an order as an active bi-directional position . If one executed order is referred to by another executed order, then two such orders make a pair and are treated by HedgeTerminal as one unified historical or closed bi-directional position. In reality, pairing orders in HedgeTerminal is more complicated, as every order generates a minimum one deal and in exchange trade there can be many such deals. In general, the trade process can be presented as follows: a trader places an order to open a new position through the MetaTrader 5 terminal. The exchange executes this order through one or several deals. Deals, similar to orders, contain fields for additional information. One of such fields contains the order id, on the basis of which the deal was executed. This field contains information about the order a certain deal belongs to. The converse is false. The order itself does not know what deals belong to it. It happens because at the time of placing the order it is not clear what deals will execute the order and if the order is going to be executed at all. This way, causality or determinism of actions is observed. Deals are referring to orders and orders are referring to each other. Such a structure can be presented as a singly linked list. Executed deals of the opening order generate a classical position in MetaTrader 5 and deals that belong to a closing order, on the contrary, close this position. These pairs are presented in the figure below: Fig. 4. Diagram of a relationship between orders, deals and exchange We are going to get back to the detailed analysis of this diagram as the direction of the relationships is very important for building a strictly determined system of the traders actions recording, which is HedgeTerminal. 1.3. Relationship of the MetaTrader 5 Net Positions and the HedgeTerminal Positions From the point of view of HedgeTerminal, two opposite orders with the same volumes can be two different positions. In this case their net position will be zero. That is why HedgeTerminal does not use information about the factual net positions opened in MetaTrader 5. Therefore, positions in HedgeTerminal are not connected with positions in MetaTrader 5 . The only time when the current net positions get verified is the moment of the HedgeTerminal launch. The total volumes of the opposite active positions must be identical to the values of the factual net positions. If this is not the case, then a warning exclamation mark in a frame will appear on the HedgeTerminal, indicating that positions in HedgeTerminal and positions in MetaTrader 5 are not equal. This asymmetry does not affect the efficiency of HedgeTerminal, though for further correct work it has to be eliminated. In the majority of cases, it can appear when users make errors editing the files of excluded orders ExcludeOrders. xml . though corruption of the order and deal history on the server can also cause this sign to emerge. In any case, these discrepancies can be removed by the exclusion mechanism implemented through the ExcludeOrders. xml file. 1.4. Requirements of the Algorithms Implementing Bi-Directional Trading Rather strict requirements are imposed on the algorithms implementing bi-directional trading. They must be met when developing HedgeTerminal. Otherwise, HedgeTerminal would quickly turn into a program working stochastically. The program would be yet another solution that could operate or fail to do so with the same probability Below are some requirements specified for its development: The representation of traders bi-directional positions must be reliable. Any idea implemented in HedgeTerminal must not lead to ambiguity or potential errors in the business logic. If some property or opportunity does not meet these requirements, then this idea wont be used in spite of its convenience and the demand for it All algorithms must be based on the MetaTrader 5 trading environment as much as possible. Storing additional information in the files is permitted in the cases when this is strictly necessary. The virtualization algorithms must receive the major part of information from the trading environment. This property enhances the total level of reliability as the majority of changes are conveyed through the server and therefore are accessible from any point in the world All actions on the trading environment transformation must be performed behind the scenes. Complex configuration and initialization of the API HedgeTerminal library should not be required. A user should be able to launch the application out of the box and receive the expected result The HedgeTerminal visual panel must fit the general MetaTrader 5 interface as seamlessly as possible, giving simple and understandable visual tools for work with bi-directional positions familiar to all the users of MetaTrader 4 and 5. In other words, the visual panel must be intuitively clear and simple for all users The visual panel of HedgeTerminal must be designed taking into consideration algorithmic traders high requirements. For instance, the panel must be configurable, the user must be able to change its appearance and even add custom modules It must provide the Intuitive and simple program interface (API) of interactions with external Experts. The program part of interactions between external Experts and the HedgeTerminal algorithms must fit seamlessly the existing standard of the program interaction of the custom Experts with the MetaTrader 4/5 system functions. Actually, the HedgeTerminal API appears to be a hybrid of the MetaTrader 4 and MetaTrader 5 APIs HedgeTerminal must ensure reliable work in the exchange environment, taking into account all the nuances of the exchange orders execution. HedgeTerminal is written based on the canonical article Principles of Exchange Pricing through the Example of Moscow Exchanges Derivatives Market . Initially, this article was a part of a long article about HedgeTerminal, which later was divided into several independent articles because of the volume. One can say that HedgeTerminal is a program implementation of the ideas discussed in this article. Many of these ideas are not quite connected with each other. For instance, the abundance of the exchange information that is to be reflected in the exchange trading is difficult to connect with the simplicity of this information representation. Another difficulty was to create a panel that could be easy to use for novice traders and at the same time provide extensive opportunities for professional algorithmic traders. Nevertheless, assessing the result, it is clear that these mutually exclusive properties were successfully implemented in HedgeTerminal. Chapter 2. Installation of HedgeTerminal, First Launch 2.1. Installation of HedgeTerminal We know that all executed orders in HedgeTerminal are considered as positions. Positions can consist either of two paired orders, which make a closed historical position or an unbound order, which makes an open or active position. If before HedgeTerminal was installed, there were some actions on the trading account and the trading history contains a lot of executed orders, then from the point of view of HedgeTerminal all these orders will be open positions as the links between them were not created. It does not matter if the account history contains 2-3 executed orders. If there are thousands of them, HedgeTerminal will generate thousands of open positions. What can one do with them These orders can be closed by placing opposite orders containing links to the initiating orders through HedgeTerminal. There is a down side though. If by the time of installing HedgeTerminal there are too many of them, it can ruin the trader as the brokerage fee and slippage expenses are to be paid. To avoid this, HedgeTerminal launches a dedicated installation wizard at the beginning of its installation, where different solutions of this problem are suggested. Let us launch HedgeTerminal, call this wizard and describe its work in detail. For that download and install HedgeTerminalDemo from the MetaTrader 5 Market. Similar to HedgeTerminalUltimate. it has a form of an Expert Advisor and all it takes to launch it is dragging its icon available in the Navigator folder to a free chart. Dragging this icon will bring up a standard window suggesting to launch the Expert Advisor on the chart: Fig. 5. The HedgeTerminal window before the launch At this stage it is enough to set the flag Allow AutoTrading, allowing the EA to perform trade actions. HedgeTerminal will follow your orders as it does not have its own trading logic but for executing trades it will still need your permission. For any Expert Advisor to start trading, the general permission for trading through Expert Advisors must be enabled on the panel in addition to the personal permission to trade in MetaTrader 5. Fig. 6. Enabling automated trading HedgeTerminal was designed so the user could avoid long and complex configuration. That is why all available settings are included in a special XML text file. The only explicit parameter for HedgeTerminal is the actual name of these settings file: Fig. 7. Settings window of the HedgeTerminal panel The nature of these settings and the way to change them will be discussed later. After pressing OK, the HedgeTerminal installation wizard launches suggesting to start the installation process. The process of installation goes down to creating a few files in the shared directory for the terminals MetaTrader 4 and MetaTrader 5. HedgeTerminal requests permission to install such files: Fig. 8. Dialog of the installation start If you do not want some files to be installed on your computer, press Cancel. In this case HedgeTerminal will finish work. To continue installation press OK. The appearance of the following dialog will depend on the account you launch HedgeTerminal with. If no trades were executed on the trading account, then HedgeTerminal will complete its work. If some trades have already been executed, HedgeTerminal will display the following dialog: Fig. 9. Dialog detecting the first launch of HedgeTerminal On the figure above, HedgeTerminal identified 5 active orders. In your case their number will be different (it is likely to be big and equal to the total number of executed orders of the account lifetime). These orders do not make a pair with a closing order as from the point of view of HedgeTerminal, they are active positions. HedgeTerminal suggests several options. Exclude these orders from HedgeTerminal: You can hide them in HedgeTerminal. To hide these orders, click YES and go into the next step . If you choose this option and press YES . HedgeTerminal will put them into a specified list and from then will stop accounting their contribution to the aggregate net position as well as their financial result. These orders can be placed in the list only if there is no currently open net position. If you have an open position on one or several symbols, HedgeTerminal will call an additional dialog suggesting to close existing positions. Leave orders as they are and close them later if required: You can close manually later. Click No if you want close these orders manually later. In this case, you have to perform 5 trades of opposite direction . In this case, if you press No . HedgeTerminal will reflect after launch all these orders in the Active tab (i. e. as active positions). Later these orders can be closed with other orders through the HedgeTerminal panel. After that they will turn into closed positions and will be transferred to the History tab (historical positions). If these orders are great in number, then it is better to hide them than to close all executed orders again and pay brokerage fees. You can stop the installation: If you are not ready continue press Cancel. In this case HedgeTerminal complete its work . If you choose this option and press Cancel, HedgeTerminal will stop its work. If there are no active positions by the time HedgeTerminal is installed, installation will be stopped at this stage. If you have selected the second option and you currently have one or several opened positions, HedgeTerminal will call an additional dialog suggesting to close them: Fig. 10. Dialog suggesting to close net positions automatically HedgeTerminal requires closing all existing positions as all executed orders are to be put into the list of excluded orders. If there are no net positions, then any following order initializes a new net position. The direction and volume in this case are the same as in HedgeTerminal and that ensures avoiding unsynchronization of net positions with the total positions in HedgeTerminal. HedgeTerminal can automatically close all net positions for you: The HedgeTerminal can automatically close all active positions . If this is acceptable to you, press OK . In this case it will try to close positions and if successful will finish work. If positions cannot be closed for some reason, it will move on to the dialog of manual position closing. If you select the manual position closing, Click Cancel if you want to close a position manually . press Cancel . The dialog of manual position closing is called either when manual closure type was chosen in the previous dialog window or when automatic position closure is impossible. Higo. 11. Dialog suggesting to close net positions manually At this point all active positions have to be closed manually through MetaTrader 5 or installation should be cancelled by pressing Cancel . After all positions are closed, press Retry . 2.2. Three Step Installation. Installation Diagram and Solution to Possible Problems If we simplify the installation process as much as possible, it can be narrowed down to three steps: Before installing HedgeTerminal, close all currently active net positions in the MetaTrader 5 terminal Launch HedgeTerminal on the chart and press Yes in the appeared window of the installation wizard to start installation. HedgeTerminal in this case will install all the files required for its operation In the next window if this appears, select the second option and press Yes . In this case active positions wont appear when HedgeTerminal is launched and the information about previously executed orders will be transferred to the ExcludeOrders. xml file automatically as there are no active positions requiring closure. The simplest way to describe it is as follows: close all positions before launching Hedge Terminal and then press Yes two times in the HedgeTerminal installation wizard. Complete pattern of the installation wizard is represented on the diagram below. It will help to answer the questions and perform installation correctly: Fig. 12. Installation wizard What is the course of action if installation was not performed correctly or HedgeTerminal is required to be deleted from the computer In the case installation was incorrect, simply delete all installed files. For that, go to the folder where programs for MetaTrader store shared information (as a rule this is located at: c:UsersltyourusernamegtAppDataRoamingMetaQuotesTerminalCommonFiles ). If you want to delete information about the HedgeTerminal installation from all accounts, find the HedgeTerminal folder in this directory and delete it. If you want to delete information about the HedgeTerminal installation only for a certain account, go to the HedgeTerminalBrokers directory and select the folder, containing the name of your broker and the account number that looking like Brokers name - account number . Delete this folder. Next time the installation wizard will launch again when HedgeTerminal is started on this account. Installation on the terminal connected to the account already working with HedgeTerminal. It may happen that that HedgeTerminal is required to be installed on the terminal connected to the account where HedgeTerminal is already working. As you already know, the installation process consists of creating and configuring system files. If all these files are already created on another computer and properly configured, then there is no need to install HedgeTerminal. As a rule, these files are stored at c:UsersltyourusernamegtAppDataRoamingMetaQuotesTerminalCommonFilesHedgeTerminal. Simply carry over this folder to the same place on your computer. After copying the directory, launch HedgeTerminal again. The installation wizard will not get called as all files are present and configured. In this case active positions will be similar to the display on other terminals and computers. Installation of HedgeTerminalAPI and using the library in test mode. HedgeTerminal is implemented both as a visual panel and a library of program functions - HedgeTerminalAPI. The library contains a similar installation wizard called at the first launch of HedgeTerminalAPI in real time. Installing files when using the library is similar. At the first call of any function, the Expert will bring up a relevant MessageBox suggesting to start installation. In that case the user has to do the same thing - close all positions before calling HedgeTerminalAPI and perform installation in three steps. It is not required to install HedgeTerminal when launching the library in test mode. As in test mode the Expert starts every time working with a new virtual account, there is no need to hide previously executed order and install files. The settings stored in the file Settings. xml , in the library can be defined grammatically through calling relevant functions. 2.3. Getting Started with HedgeTerminal, First Launch After HedgeTerminal has installed all the files required for its work, it will launch on the chart and display its panel: Fig. 13. First launch of HedgeTerminal, appearance As all existing orders are hidden, there are no displayed active positions. The upper panel contains a button of the HedgeTerminal menu on the left hand side and dedicated icons displaying the state of the panel. The buttons have the following functions: - Indicates that the panel demo version has been launched. This does not support the trade on real accounts and displays positions only on the AUDCAD and VTBR symbols. In this mode, the history of positions is also limited by the last 10 closed positions. - Indicates that positions in HedgeTerminal are not equal to the total net position in MetaTrader 5. This is not a critical error but it is required to be eliminated. If the HedgeTerminal installation is correct, refer to the section of this article describing how to eliminate the mistake. - The icon signifies that trade is impossible. Hover the mouse over this icon and find out from the pop-up tip what the matter is. Possible reasons: no connection with the server the Expert Advisor is prohibited to trade trading with Expert Advisors is not allowed in MetaTrader 5. - An icon indicating that the trade is permitted HedgeTerminal can perform any trade action. Now, when HedgeTerminal is launched and ready for work, carry out several trades and see how they are displayed. If HedgeTerminal is launched on Forex, trading actions are to be executed on the AUDCAD symbol. There should not be any open net positions as installation of HedgeTerminal could be successful only in that case. If this is not the case for some reason, close all active positions. If HedgeTerminal is launched on an account connected to the Moscow Exchange, trading should be executed on one of the futures of the VTBR group, for example VTBR-13.15 or VTBR-06.15. As an illustration, buy 0.4 lot of AUDCAD by the current price through the standard window NewOrder. In a few moments, the order and the deal that executed it will appear in the order history of the terminal: Fig. 14. Historical order and its deal in MetaTrader 5 The active positions tab will contain a correspondent long position of 0.4 lot: Fig. 15. Active net position in MetaTrader 5 At the same time, HedgeTerminal will display the historical order as an active position: Fig. 16. Active bi-directional position in HedgeTerminal and its deal As we can see, the results are the same, as one position in HedgeTerminal is correspondent to 1 net position in MetaTrader 5. Please pay attention that in addition to the order, the position in HedgeTerminal contains a deal that executed this position (to see it, maximize the position string by pressing ) A part of an active position can be hidden. For that simply enter a new volume value in the field Vol. (Volume). The new volume should be less than the current one. The difference between the current and the new volumes will be covered by the new order that forms a historical position and is displayed in the correspondent tab of historical positions. Enter the value of 0.2 in this field and then press Enter. In some time the volume of the active position is going to be 0.2 and the historical positions tab will feature the first historical transaction with the volume of 0.2 lot ( 0.4 - 0.2 0.2 ): Fig. 17. Historical bi-directional position in HedgeTerminal In other words, we closed half of our active position. Common financial result of the historical and active position will be identical to the result in the terminal. Now we are going to close the rest of the active position. For that press the button of closing a position in HedgeTerminal: Fig. 18. Close button of a bi-directional position in HedgeTerminal After this button has been pressed, the remaining position must be closed by the opposite order and transferred to the historical position tab. This way active positions (both in MetaTrader 5 and in HedgeTerminal) will be closed. 2.4. Hedging and Calculation of Financial Operations In this section we are going to describe methods of work with HedgeTerminal using several bi-directional positions as an example. So currently we do not have any active positions. Open a new long position with the volume of 0.2 lot on AUDCAD. For that it is enough to open the new order dialog window and place a correspondent order. After the position has been opened, lock it by the opposite position - sell 0.2 lot through the MetaTrader 5 terminal. This time the trade result in HedgeTerminal and in the MetaTrader 5 terminal window are different. HedgeTerminal displays two positions: Fig. 19. Opposite bi-directional positions in HedgeTerminal (lock) In MetaTrader 5 they are not present at all: Fig. 20. Absence of an active net position in MetaTrader 5 Let us assess the result. 4 deals have been executed. They are in the red frame on the screenshot below: Fig. 21. Result of executed deals in MetaTrader 5 Put these deals in a table: Table 2. Displaying positions in HedgeTerminal The difference between them is 0.34 (21,28 - 20,92) . which is exactly the same as the result obtained in net trading. 2.5. One Click Trading HedgeTerminal employs a peculiar management system. This is based on the direct entry of the required values to the active position field. There is no alternative management. For instance, to place StopLoss for an active position, simply enter the required value in the StopLoss field and then press Enter: Fig. 23. Entry of the StopLoss level directly to the table Similarly, this way a trader can modify the volume, place TakeProfit or modify its level, change the initial comment . In general, the position line in HedgeTerminal is similar to the position display in MetaTrader 4/5. The columns of the table with positions have identical names and values used in the MetaTrader terminals. There are differences too. So, a position in HedgeTerminal has two comments whereas in MetaTrader a position has only one comment. This means that a position in HedgeTerminal is formed by two orders and each of them has its own comment field. As HedgeTerminal does not use these comments for storing technical information, it is possible to create a position with an opening and closing comment. HedgeTerminal features an opportunity to add columns that are not displayed by default. For example, a column reflecting the name of the Expert Advisor that opened the position. The section dedicated to configuring the Settings. xml file describes the way to do it. 2.6. Placing StopLoss and TakeProfit, Trailing Stop HedgeTerminal allows to close positions by the StopLoss or TakeProfit levels. To see how it happens, introduce the StopLoss and TakeProfit levels in the active position and then wait till one of those levels triggers. In our case TakeProfit triggered. It closed the position and moved it to the list of historical transactions: Fig. 24. Historical bi-directional position and its StopLoss and TakeProfit levels The green mark in the TakeProfit level indicates that TakeProfit triggered and the position was closed by that level. In addition to TakeProfit, a position contains information about the StopLoss level which was also used when the position was active. Similarly, if the StopLoss level triggered, then the StopLoss cell would be highlighted pink and TakeProfit would not be colored. HedgeTerminal supports TrailingStop and future versions will allow to write a specific custom module containing the logic of carrying over the StopLoss. Currently the work with Trailing Stop in HedgeTerminal is different from the same Trailing Stop in the MetaTrader terminal. To enable it, it is required to enter the StopLoss level in the StopLoss cell of the correspondent position. When StopLoss is placed, following the price option can be flagged in the cell marked with a sign : Fig. 25. Placing Trailing Stop in HedgeTerminal After flagging, HedgeTerminal fixes the distance between the current price and the StopLoss level. If it increases, StopLoss will follow the price so the distance stays the same. Trailing Stop works only when HedgeTerminal is working and gets cleared upon the exit. In HedgeTerminal, StopLoss is implemented with the BuyStop and SellStop orders. Every time a StopLoss is placed, a correspondent order with a magic number connected with the active position is placed too. If this pending order gets deleted in the MetaTrader terminal, then the StopLoss level in HedgeTerminal will disappear. Changing the price of the pending order will trigger the change of the StopLoss in HedgeTerminal. TakeProfit works a little differently. This is virtual and it hides its trigger level from the broker. It means that HedgeTerminal closes a position by TakeProfit autonomously. Therefore, if you want your TakeProfit to trigger, you need to keep your HedgeTerminal in a working order. 2.7. Report Generation HedgeTerminal allows to save the information about its bi-directional positions to designated files, which can be loaded to third party statistical programs of analysis, for instance to Microsoft Excel. Since HedgeTerminal currently does not have a system of analysis and statistics gathering, this feature is especially important. At the moment, only one format of report saving is supported - CSV (Comma-Separated Values). Let us see how this works. To save the bi-directional positions in the CSV file, select the Save CSV Report option in the menu after launching HedgeTerminal: Fig. 26. Saving a report through the Save CSV Report menu After selecting those points in the menu, HedgeTerminal will generate two files in the CSV format. One of them will comprise the information about active positions and another one about historical, completed ones. The reason why two different files are generated is because each of them has a different set of columns. Besides, the number of active positions can constantly vary, therefore it is more convenient to analyze them separately. The generated files are available by the relative path . HedgeTerminal Brokers ltBrokers name - account numbergt . There must be two files at the end: History. csv and Active. csv. The first one contains information about historical positions and the second one about active positions. The files can be loaded into the statistical programs for analysis. Let us look at this procedure using Microsoft Excel as an example. Launch this program and select Data --gt From the text . In the appeared data export wizard select the mode with separators. In the following window, select semicolon as the separator. Press Next . In the following window change the general format of floating point number representation. To do that press Details . In the appeared window select the period character as a separator of the integer and fractional parts: Fig. 27. Export the CSV report to Microsoft Excel Press , and then Finish. The appeared table will contain information about active positions: Fig. 28. Information about active positions exported to Excel Data on historical positions can be loaded in the next sheet the same way. The number of columns will be correspondent to the factual number of columns in HedgeTerminal. If one of the columns gets deleted from the HedgeTerminal panel, it will not be included into the report. This is a convenient way to form a report based only on the required data. Later versions of the program will allow to save a report in the XML and HTML formats. Added to that, a report saved in HTML will be similar to a standard HTML report in MetaTrader 5, though it will consist of completed bi-directional positions. 2.8. Currency Swap Presentation Currency swap is a combination of two bi-directional conversion deals for the same sum with different valuation dates. In simple words, swap is a derivative operation on accruing the difference of the interest rates paid for holding two currencies forming a net position . There is no history of net positions in MetaTrader 5. There are historical orders and deals that formed and closed historical net positions instead. As there are no historical positions, the swap is assigned to the order that closes a historical position: Fig. 29. Currency swap as an independent transaction It would be more accurate to present the swap as an independent derivative operation appearing as a result of a net position prolongation. The current version of HedgeTerminal does not support swap representation though the later versions will feature such an option. There a swap will be shown as a separate historical position in the historical position tab. The swap identifier will be correspondent to the identifier of the net position that it was accrued on. The swap will include the name of the currency pair and its financial result. Similar to MetaTrader, HedgeTerminal displays the final row with common characteristics for the whole account in the table of deals. For the table of active and historical positions these characteristics and their values are listed below: Balance Total balance. Equal to the similar value Profit in the window of active positions in MetaTrader. This does not take into account the floating profit or loss from open positions. Floating P/L Floating profit/loss. This is equal to the sum of the profit of all currently active positions. Margin Contains a share of pledge funds from the account balance in percent. Can vary from 0 to 100. Indicates a degree of the load on deposit. Total P/L Contains a sum of all profits and losses for closed positions. Pos.: - Displays the number of historical positions. For correct display of the bottom row, it is required to add the Arial Rounded MT Bold font to the system. 2.10. Changing the Appearance of HedgeTerminal Tables As mentioned before, HedgeTerminal has only one explicit parameter in the window of the Expert launch. This is the name if the settings file. This is so because the HedgeTerminal settings cannot be placed in the window of the Expert settings. There are many of them and they are too specific for such a window. That is why all settings are placed to the designated configuration file Settings. xml. For every launched version of HedgeTerminal, there can be its own settings file. That gives an opportunity to configure every launched version of HedgeTerminal individually. HedgeTerminal currently does not allow editing this file through the visual windows of settings. Therefore, the only way to change the behavior of HedgeTerminal is to edit the file manually. The settings file is configured in the optimal way by default and therefore most of the time there is no need to edit the content. There may be situations when such editing may be required. Such editing is necessary for fine tuning and customizing the panel appearance. For instance, when a file has been edited, unnecessary columns can be deleted or, on the contrary, the columns not displayed by default can be added. Let us see the content of this file and see how to customize it. To do that, find this file in the directory where HedgeTerminal has installed its files. This directory, as was mentioned before, can be located at the address c:Usersltyour user namegtAppDataRoamingMetaQuotesTerminalCommonFilesHedgeTerminal. The Settings. xml file should be located inside. Open it with the help of any text editor: This file contains a special document written in the xml markup language. describing the behavior and the appearance of HedgeTerminal. The main thing to do before the start of editing is to create a backup copy in case the file gets accidentally corrupted. The file has a hierarchical structure and consists of several sections enclosed into each other. The main section is called ltHedge-Terminal-Settingsgt and it contains two main subsections: ltShow-Columnsgt and ltOther-Settingsgt. As follows from their names, the first section adjusts the displayed columns and their conditional width and the second section has the settings for the panel itself and the HedgeTerminalAPI library. Changing the size and the name of columns . Let us refer to the ltShow-Columnsgt section and consider its structure. Essentially, this section contains two sets of columns: one for the table of active positions in the Active tab and the other one for the table of historical positions in the History tab. Every column in one of the sets looks like: The column must contain an identifier ( IDSymbol ), name of the column ( NameSymbol ) and conditional width ( Width70 ). The identifier contains a unique internal name of the column. It prompts HedgeTerminal how to display this column and what value to place in it. The identifier cannot be changed and it should be supported by HedgeTerminal. The name of the column defines what name the column will be displayed with in the table. If the name is changed for another one, like: Name Currency Pair . then at the next launch of HedgeTerminal, the name of the column displaying the symbol will change: Fig. 30. Change of the column names in the HedgeTerminal panel This very property allows creating a localized version of the panel where the name of every column will be displayed in preferred language, for example in Russian: Fig. 31. The HedgeTerminal panel localization The next tag contains the conditional width of the column. The thing is that a graphics engine automatically aligns the table size with the width of the window where the panel is launched. The wider the window is the wider each column. It is impossible to set up the width of the column precisely but the proportions can be specified by setting up the basic width of the column. The basic width is the width of the column in pixels when the width of the window is 1280 pixels. If your display is wider, then the factual size of the column is greater. To see how uniform scaling works, set up the width of the Symbol column as 240 conditional pixels: Width240. Then save the file and reset the panel: Fig. 32. The width of the Symbol column is set up for 240 pixels. The width of the column with symbols has increased significantly. However, it should be noted that its width was gained at the expense of the width of other columns ( Entry ID and Entry Date ). Other columns are now looking worse, last values do not fit in the allowed width. The size of the columns should be changed carefully, finding the best size for each of them. The standard settings have precise values for majority of displays and changing their size is normally not required. Deleting columns. In addition to changing column sizes and their headers, the columns can be added or deleted too. For example, let us try and delete the Symbol column from the list. To do that, simply comment out the tag of the column in the Settings. xml file (highlighted in yellow): In xml a specified tag lt-- content of the comment --gt has a role of the comment. The commented out column must be located in the tag. After changes in the file have been saved and HedgeTerminal was relaunched, its set of columns for historical positions will change. It wont contain a column displaying the symbol: Fig. 33. Deleting the Symbol column from the table of active positions Several columns can be deleted at once. Let us comment out all columns except the symbol name and the profit size and then relaunch HedgeTerminal on the chart: Fig. 34. Deleting main columns from the HedgeTerminal panel As we can see, the HedgeTerminal table has significantly reduced. One should be careful with deleting columns as in some cases they contain elements of position management. In our case, the column that allows reversing positions and view their deals got deleted. Even the Profit column from the table of active positions can be deleted. This column, however, contains a button of closing position. In this case a position wont get closed as the close button is missing. Adding columns and displaying the aliases of Experts. Columns can be deleted by editing and added, if HedgeTerminal was programmed to work with them. In the future, a user can create their own columns and calculate their own parameters. Such columns can be connected via the interface of the external indicator iCustom and the manifest of interaction with extension modules, written in xml. Currently there is no such a functionality and only the columns supported by HedgeTerminal are available. The only column supported by the panel but not displayed in the settings by default is the column that contains the Experts magic number. Position can be open not only manually but also using a robot. In this case, the identifier of the robot, which opened a position can be displayed for every position. The commented out column tag including the Expert Advisors number is already present in the settings file. Let us uncomment it: Save the changes and relaunch the panel: Fig. 35. Adding the Magic column to the HedgeTerminal table As we can see on the picture above, a column called Magic appeared. This is the identifier of the Expert Advisor that opened a position. The position was opened manually and therefore the identifier is equal to zero. A position opened by a robot as a rule contains an identifier different from zero. In that case a correspondent magic number of the Expert will be displayed in the column. It is more convenient though to see the names of the Expert Advisors instead of their numbers. HedgeTerminal has this option. It takes the aliases (names) of the EAs taken from the ExpertAliases. xml file and displays them instead of the correspondent magic numbers. For instance, if you have an Expert called ExPro 1.1 and trading under the magic number 123847 . it is enough to place the following tag in the ExpertsAliases. xml file in the ltExpert-Aliasesgt section: From now on, when your robot opens a new position, it will have its name: Fig. 36. Displaying the name of the Expert in the column Magic The number of robots and their names is not limited. The only condition here is for their numbers to differ. Other settings of HedgeTerminal . We have described all the settings of the visual panel the currently available. The next section ltOther-Settingsgt contains the settings defining internal work of the terminal. Please note, that the program call library HedgeTerminalAPI uses these settings as default values. The Expert Advisor, however, can change the current values of these settings using the special Set. Funciones. To get the values of those settings, the Expert only needs to call special Get. Funciones. We are going to describe tags with settings in more detail. Contains the value of extreme deviation from the required price in units of minimal price change. So, for the pair EURUSD quoted to the fifth decimal place, it will be 0,0003 point. For the RTS index future this value will be 300 points as the minimum step of the price changing is 10 points. If the price deviation is greater, then the order to close or change the price will not be executed. This is in place for protection from unfavorable slippage. This tag contains the value of the maximum permissible response from the server. HedgeTerminal works in the asynchronous mode. That means that HedgeTerminal sends a trading signal to the server without waiting to receive a response from the latter. Instead, HedgeTerminal controls the sequence of events pointing at the fact that the order was placed successfully. The event may not take place at all. This is the reason why it is so important to set the wait timeout period, during which HedgeTerminal will be waiting for the server response. If there is no response during that time, the task will be cancelled, HedgeTerminal will unblock the position and carry on its work. The wait timeout period can be shortened or extended. By default this is 180 seconds. It is important to understand that in real trading, this limitation is never reached. Responses to trading signals come back quickly, the majority of them are executed within 150 200 milliseconds. More details about the work of HedgeTerminal and about the peculiarities of work in the asynchronous mode can be found in the third section of this article: Under the Bonnet of HedgeTerminal . This tag sets up the frequency of the panel updates. It contains the time in milliseconds between two consequent panel updates. The less this value is, the higher the panel update frequency is and the more CP resources are used. If your processor is not very powerful and it cannot cope with the update frequency of 200 milliseconds (default value), you can increase it up to 500 or even to 1000 milliseconds by editing the tag. In this case the CP load will drop significantly. Values less than 100 milliseconds are not recommended. Increasing the update frequency, the CP load will increase nonlinearly. It is important to understand that the update frequency defines discreteness of the terminal. Some of its actions are defined by this timer and happen with a certain speed. 2.11. Planned Yet Unimplemented Features HedgeTerminal has a flexible and nontrivial architecture due to which new nontrivial capabilities of this program become feasible. Today these capabilities have not been implemented, though they may appear in the future if there is demand. Below are the main ones: Using color schemes and skins. HedgeTerminal uses its own graphics engine. This is based on the graphic primitives like a rectangular label or a usual text. Graphics based on pictures is not used at all. This gives an opportunity to change the color, size and font of all the elements displayed in HedgeTerminal. This way it is easy to create a description of fonts and the color scheme in the form of skin and load it at the launch of HedgeTerminal, changing its appearance. Connecting custom Trailing Stop modules. Every Expert, and HedgeTerminal is essentially an Expert, can initiate a calculation of an arbitrary indicator through a specific program interface (function iCustom() ). It allows to call the indicator calculation, which depends on the set of arbitrary parameters. Trailing Stop is an algorithm that places a new or keeps the old price level depending on the current price. This algorithm and its price levels can be implemented as an indicator. If the passed parameters are agreed on, HedgeTerminal can call such an indicator and calculate the required price level. HedgeTerminal can take care of the mechanics of transferring the Trailing Stop. This way, any HedgeTerminal user can write their own (even the most unusual one) module of managing Trailing Stop. Adding new columns for the table of positions. That includes the custom columns. The HedgeTerminal tables are designed the way that they allow adding new columns. Support of new columns can be programmed inside HedgeTerminal and implemented in a familiar way through the iCustom() interface. Every cell in the line of a position represents a parameter (for example, opening price or Take Profit level). This parameter can be calculated by an indicator and that means that an unlimited number of indicators can be written so each of them calculates some parameter for a position. If passing parameters is coordinated for such indicators, it will become possible to add an unlimited number of custom columns to a table in HedgeTerminal. Connecting extension modules. Other calculation algorithms can be calculated through the mechanism of the custom indicator call. For example, the report system includes a lot of calculation parameters such as expected payoff and Sharpe ratio. Many of those parameters can be received by moving their calculation block to the custom indicator. Copying deals, receiving and transmission of deals from other accounts. HedgeTerminal is essentially a position manager. This can easily be a base for a deal copier as the main functionality have already been implemented. Such a copier will have nontrivial capabilities to copy bi-directional MetaTrader 4 positions to the MetaTrader 5 terminal. The copier will display those positions as bi-directional like in MetaTrader 4 with a possibility to manage every position individually. Reports and statistics. The Equity chart and the Summary tab. The counting of bi-directional positions allows analyzing the contribution to the result of every strategy or trader. Alongside with statistics, a portfolio analysis can be carried out. This report can notably differ from the report in MetaTrader 5 and add to it. In the Summary tab report, in addition to the generally accepted parameters like expected payoff, maximum drawdown, profit factor, etc, other parameters will be included too. The names and the values of the latter can be obtained from the custom extension modules. Instead of the familiar balance chart on a picture, the Equity chart in the form of a custom candlestick exchange chart can be used. Sorting columns. Usually, when pressing on the table header, the rows get sorted in the ascending or descending order (second pressing). Current version of HedgeTerminal does not support this option as sorting is connected with the deal filter and the custom set of columns, which are not available at the moment. Later versions will feature this option. Sending a trade report via email, ftp. Push notifications. HedgeTerminal can use the system functions to send emails, ftp files and even push notifications. For instance it can form an html report once a day and send it to the list of users. Since HedgeTerminal is a manager of Expert Advisors and it knows all trading actions of other EAs, it can notify users about trading actions of other Expert Advisors. For instance, if one of the EAs opens a new position, HedgeTerminal can send a push notification informing users that a certain Expert entered a new position. HedgeTerminal will also specify the direction of the entry, its date, time and volume. The EA itself wont need to be configured, it will be enough to add its name into the alias file. Filtering positions with the regular expressions console. This is the most powerful of the planned developments. It will bring up the work of HedgeTerminal to a completely new level. Regular expressions can be used for filtering historical and active positions so only those meeting the requirements of this filter are displayed. Regular expressions can be combined and entered in a dedicated console above the table of active and historical positions. This is how this console may look like in the future versions of HedgeTerminal: Fig. 37. Request console in the future version of HedgeTerminal Regular expressions can form very flexible conditions for filtering positions followed by statistic calculation on them. For example, to display historical positions only by the AUDCAD symbol, it is enough to enter the AUDCAD symbol in the cell Symbol. Conditions can be combined. For example, positions by AUDCAD executed by a particular robot can be displayed for the period from 01.09.2014 till 01.10.2014. All you need to do for that is to enter conditions to the correspondent cells. After the filter displays the results, the report from the Summary tab will change in accordance with the new filter conditions. Regular expressions will consist of a small number of simple operators. However, used together, they will allow to create very flexible filters. The presence of the below operators is necessary and sufficient in console: Operator - Strict equality. If the word AUDAD gets entered in the Symbol field, then all the symbols containing this substring, for example AUDCADm1 or AUDCAD1, will be found. That means that an implicit insertion operator will be used. Strict equality requires a complete match of the expression and therefore all symbols except AUDCAD will be excluded. AUDCADm1 or EURUSD will be excluded. Operator gt - Displays only the values greater than the specified one. Operator lt - Displays only the values less than the specified one. Operator Logical negation. Reflects only the values that are not equal to the specified one. Operator - Logical OR . Allows specifying two or more conditions in one row at the same time. At the same time, to meet the criterion, it is enough to fulfill at least one stipulation. For instance, the expression gt 10106825 10106833 entered in the cell Entry Order of the expression console will show all positions with the incoming order identifier greater than 10106825 or equal to 10106833. Operator amp - Logical AND. Allows to specify two or more conditions in one row at the same time and each of them has to be fulfilled. The expression gt10106825 amp lt10105939 entered in the cell Entry Order shows all positions with the incoming identifier greater than 10106825 or less than 10105939. Positions with identifiers between these two numbers, for example 10106320, will be filtered. Correcting and managing positions using special commands. Additional symbols can be entered into the cells reflecting the volume or StopLoss and TakeProfit levels. This makes a more complex position management possible. For instance, to close a half of the current position volume, enter the value 50 correspondent to the active position in the Volume field. Instead of placing StopLoss and TakeProfit levels, a value, for example 1, can be entered into those cells. HedgeTerminal will automatically calculate the StopLoss and TakeProfit level so they will be placed at a distance of 1 from the entry price. Numbers with the postfix p can be entered in these cells. For instance, 200p will mean the order: place the StopLoss and TakeProfit levels 200 points away from the position entry price . In the future, if a minus is put before the volume in the column Volume, the volume will close by the value specified after that sign. For instance, if you have a position with the volume 1.0 and we want to close a part of the volume (for example 0.3), then it is enough to enter -0.3 in the volume cell. Chapter 3. Under the Bonnet of HedgeTerminal. Specification and Principle of Operations 3.1. Global and Local Contours. Context, Transfer and Storage of Information The appearance of HedgeTerminal and trading process resemble the familiar MetaTrader 4. This is possible due to the virtualization and the transformation of data display, when trading information available through MetaTrader 5 gets displayed by the panel in a more convenient way. This chapter describes the mechanisms that allow to create such virtualization and the mechanisms of group data processing. As you know, HedgeTerminal is represented in several different products. The main of them are the visual panel and the library with program interface. The latter allows implementing management of bi-directional positions in any external Expert Advisor and it also integrates it into the HedgeTerminal visual panel. For example, an active position of an EA can be closed straight from the panel. The Expert Advisor will get the information and process it accordingly. Apparently, such a structure requires a group interaction between the Expert Advisors. The panel, which is essentially an Expert Advisor, must know about all trading actions that take place. Conversely, every Expert Advisor using the HedgeTerminal library must know about trading actions executed manually (by third party programs or using the HedgeTerminal panel). In general, the information about trading actions can be received from the trading environment. For instance, when the user opens a new position, the number of orders changes. The last order can tell what symbol the position was opened for and what volume it had. The information about orders and deals is stored on the server. That is why it is available for any terminal connected to the trading account. This information can be called global as this is available for everyone and is distributed through the global channel of communication. Communication with the trading server has the Request - response format. Therefore such communication can be presented as a global contour . Contour is a concept from the graph theory. In simple words, a contour is a closed line with a few nodes interacting with each other. This definition may not be sufficient but we will leave the precision for mathematicians. The important thing for us is to present the trading process as some closed sequence of actions. Not all the required information can be passed through the global contour. A part of information cannot be passed as MetaTrader 5 does not support such passing besides this information does not exist explicitly. The sequence of trading actions is: A trader places an order to buy. The order gets executed in some time. Trading environment changes. The executed order gets into the list of historical orders. The aggregate position of the symbol changes. The trader or an Expert Advisor detects the change in the trading environment and makes next decision. Some time passes between the first and the fourth actions. It can be significant. If only one trader trades on the account, they know what actions are taken and wait for the appropriate response from the server. If there are a few traders or Expert Advisors trading on the account at the same time, there can be management errors. For example, the second trader can place an order to close an existing position in the time between the first and the fourth step. Can you see a potential problem The second order is placed when the first one is being executed. In other words, an order to close a position will be sent twice. This example seems to be far fetched and unlikely if the trader is trading on the account alone and manually and uses synchronous methods of placing orders. When there are several robots trading on the account and executing independent trading operations, there is a high probability of such errors. As HedgeTerminal is a position manager, working in the asynchronous mode and ensuring simultaneous parallel work of a number of Experts, it can be very close to those mistakes. To avoid this, HedgeTerminal synchronizes actions between all its launched copies (no matter if this is the HedgeTerminalAPI library or the visual panel) through the mechanism of the local contour implemented as a multi-threaded reading and changing of the ActivePositions. xml file. Interaction with the ActivePositions. xml file is the core of the local contour, the most important part of HedgeTerminal. This mechanism is described below. In a simplistic way, the work of HedgeTerminal goes down to the cooperation with a local and global contour like on the figure below: Fig. 38. A simplified scheme of information exchange between the global and local contour Any trading action (the label start on the diagram) in HedgeTerminal starts with writing of a special tag in ActivePositions. xml. which blocks further changes of the position being modified. After the position block has been set and the local contour has been successfully passed, HedgeTerminal sends a trading order to the server. For instance, a counter order to close the position. In some time, the order gets executed and the trading environment gets changed. HedgeTerminal processes this change and detects that the global contour is passed successfully and the order is executed. It unblocks the position and returns to the initial state (label finish on the diagram). There can be a situation when an order cannot be executed. In this case HedgeTerminal also unblocks the position and makes a record about the reason of the failure in the log of the MetaTrader 5 terminal. In reality the pattern of the communication of information is more complex. As we already mentioned, in one MetaTrader 5 terminal several HedgeTerminal copies can be running. They can be the library or the visual panel. Every copy can act as a listener and a writer . When HedgeTerminal performs a trading action, this is a writer because it blocks the position for changes using the records of the designated xml tag. All other copies of HedgeTerminal are listeners as they are reading the file ActivePositions. xml with a certain periodicity and block a position for changes having come across the blocking tag. This mechanism ensures spreading information between independent threads. It facilitates parallel work between several panels and Experts using the HedgeTerminalAPI library. A realistic diagram, showing the work of HedgeTerminal in the conditions of multi-threaded cooperation: Fig. 39. Near-natural pattern of the information exchange between copies of HedgeTerminal The efficiency of such data organization is very high. Operations on the reading and writing the ActivePositions. xml file normally take less than 1 millisecond, whereas passing the global contour with sending and executing the order can take up to 150-200 milliseconds. To see the difference between the scale of these values, take a look at the diagram. The width of the green rectangle shows the time of passing the local contour and the width of the blue one is the time of the trading order execution: Fig. 40. Time scale of making a record to the file and the time required for the order execution As you can see, the green rectangle looks more like a vertical line. In reality the difference between scales is even greater. Quick operations of reading and recording can facilitate a complex data exchange between Experts and creating of distributed high frequency trading systems. 3.2. Storing Global and Local Information Conventionally, all trading information used by HedgeTerminal can be divided into two parts: Local information. This is stored in the computer files and is passed exclusively through the local contour Global information. This information is stored on the trading server. It is passed through the global contour and is available from any terminal connected to the account. Orders, deals and the information about the account belong to global information. This information is available through specific functions of MetaTrader 5, like HistoryOrderGetInteger() or AccountInfoInteger(). HedgeTerminal mainly uses this information. Due to that, HedgeTerminal displays the following data: Active and historical positions of HedgeTerminal StopLoss of active and historical orders Triggered TakeProfit levels of historical positions Incoming comment of an active position, incoming and outgoing comments of historical positions All other properties of active and historical positions not included into the list of local information. As all these properties are global, their display is unique for all copies of HedgeTerminal, running on different computers. For example, if one bi-directional position gets closed in one of the terminals, this position will get closed in the other HedgeTerminal even if this is launched on another computer. In addition to the global data, HedgeTerminal uses local information in its work. Local information is available only within one computer. This information is the basis of the following properties: TakeProfit levels of active positions TakeProfit levels of historical positions that did not trigger Outgoing comment of an active position Service flag, blocking a change of a bi-directional position. Take profit levels that did not trigger are stored in the HistoryPositions. xml file. The rest of the local information is stored in the ActivePositions. xml file. Local data storage means that if you place a TakeProfit, it will be visible only in the HedgeTerminal copies running on your computer. No one except you will know this level. 3.3. Stop Loss and Take Profit Levels. Order System Issues and OCO Orders In MetaTrader 5 as well as in MetaTrader 4, there is a concept of StopLoss and TakeProfit levels. These are protective stops. Similar to MetaTrader 4, they close a position in the case when it reaches the certain level of loss (StopLoss) or profit (TakeProfit). In MetaTrader 4, though, such stops are active for each open order individually. In MetaTrader 5 these stops work for the whole aggregate net position. The issue here is that a net position is not connected with bi-directional positions of Experts and particularly HedgeTerminal. That means that regular StopLoss and TakeProfit levels cannot be used for bi-directional positions, however, these levels can be presented as separate pending orders. If you have a long position open, then two pending orders will emulate the work of TakeProfit and StopLoss respectively. One of them is SellLimit placed above the opening price of this position and another one is SellStop placed below this price. In fact, if the price after opening reaches SellLimit of the order, this order will close the position with profit and if the price reaches the SellStop order, it will close the position with a loss. The only drawback is that after one order triggers, the second order will not stop existing and if the price then changes direction, the second order can trigger after the first one. As there is no position at that point, triggering of the second order will open a new net position instead of closing the previous one. The figure below illustrates this problem on the example of using protective stops in a long position: Fig. 41. Emulating StopLoss and TakeProfit using the orders SellStop and SellLimit To avoid such inconsistency, in exchange trading the OCO orders ( One Cancels the Other ) are used. These are two pending orders connected with each other so triggering of one order cancels the other. In our example, after one order triggered, the second order is cancelled by the trading server and therefore new positions wont be opened and that is exactly what we are looking for. The work of this type of orders is presented on the diagram below: Fig. 42. OCO orders as StopLoss and TakeProfit MetaTrader 5 does not support OCO orders. As a bundle of three orders cannot be used, orders simultaneously acting as StopLoss and TakeProfit are not suitable. A pair of two orders can be used So, it can be either StopLoss or TakeProfit. In fact, if a pending order connected with the executed order initializing a new bi-directional position was placed (for example StopLoss), then such a construction is safe. There wont be a second pending order and it wont be able to open a new bi-directional position. Factually, there will be only three scenarios: A pending order will be cancelled for some reason by a broker or a user A pending order will trigger A pending order wont trigger. There are no other scenarios. If a pending order is cancelled, it will be equal to canceling StopLoss or TakeProfit. If a pending order triggers, it will close the position. If the order does not trigger, then a bi-directional position will stay active with a placed StopLoss. Even if HedgeTerminal is disabled when the pending order triggers, then later, when it launches, it will be able to process its triggering and understand that the position was closed by this order. It is possible to work out if the position was closed by StopLoss or TakeProfit if the field with the magic number contains special service information indicating whether the closing order is a regular order, TakeProfit or StopLoss. The way the link and the service information are stored in the field with the magic number is explained in detail in the next section. Since two real protective stops cannot be used at the same time, a compromise was made when HedgeTerminal was designed: Bi-directional positions in HedgeTerminal are protected by the real orders of BuyStop and SellStop playing a role of StopLoss. TakeProfit levels are virtual and supported at the level of HedgeTerminal copies run on one computer and unavailable at the global level. The StopLoss levels are chosen, as these levels are the ones required to have a high level of triggering reliability. If TakeProfit does not work, it wont be catastrophic and the account wont be closed by margin call, whereas StopLoss that did not trigger can lead to the account bankruptcy. Nevertheless, there is an algorithmic opportunity to choose a way of trailing a position. You can choose between a real StopLoss and virtual TakeProfit or a virtual StopLoss and a real TakeProfit. The StopLoss and TakeProfit levels can also be virtual. At the moment this feature has not been implemented but if it is in demand, it may appear. The virtualization of the TakeProfit level lowers its general reliability, though not significantly. The TakeProfit levels are distributed locally and are available to every copy of HedgeTerminal. It is sufficient to have at least one running copy of HedgeTerminal as an Expert Advisor that uses the library or the HedgeTerminal panel, for TakeProfit to be executed. When there are several copies of HedgeTerminal running, only one of them will execute TakeProfit. It will be the first one putting a blocking tag on the bi-directional position. In this sense, instances of HedgeTerminal are competing against each other in the multi-thread mode of writing and reading of the data. For a user, trading manually through the HedgeTerminal panel or using the virtualization library in the EAs, work with TakeProfit does not differ from work with StopLoss. All factual differences between these levels are hidden behind the scene of HedgeTerminal. It is sufficient for the trader to enter TakeProfit and StopLoss. These levels will be present simultaneously and have the same color indication warning about triggering of one of the levels. 3.4. Can OCO Orders Resolve Issues with Protection of Bi-Directional Positions OCO orders make it possible to use real StopLoss and TakeProfit levels simultaneously. Are they really that versatile in organizing bi-directional trade Below are their characteristics. We already know that OCO orders allow canceling one order when the other triggers. It seems that it will protect our bi-directional position from both sides as in that case Stop-Loss and Take-Profit can be real orders not requiring HedgeTerminal be running on the computer. The thing is that in the exchange order execution it is necessary to take into account partial order execution . This property can destroy the business logic of the application. Let us consider a simple example: A long position with the volume of 10 contracts gets open. Two linked OCO orders implementing StopLoss and TakeProfit levels are placed The SellLimit order gets partially executed when TakeProfit level gets reached. 7 out of 10 contracts were closed by it and the remaining 3 stayed open as a long position SellStop order, implementing StopLoss level, will be cancelled as the SellLimit order connected with it was executed though only partially. Position in three contracts does not have a protective stop any more. This scenario is presented on the figure below: Fig. 43. Partial execution of protective stops There may be an objection that OCO orders can be designed so they account for a partial execution and that will allow to avoid such clearing of protective stops. Volumes of two OCO orders can be interconnected. In this case partial execution will definitely be foreseen. However, this will complicate complex enough logics of the order system used in net trading. The main issue here is that OCO orders cannot provide the same opportunities as MetaTrader 4, even accounting for partial execution. For instance, placing a pending order with TakeProfit and StopLoss levels will be difficult. The reason is that two interconnected orders cannot take into account triggering of the initiating order. To write a truly versatile algorithm allowing to manage positions similar to MetaTrader 4, OCO orders must have the following characteristics: Every linked order must adjust its volume depending on the execution degree of the order linked to it. For instance, if TakeProfit executed 7 out of 10 contacts, the StopLoss linked to it must change its volume from 10 to 3 (10 - 7 3) Each of the linked orders must take into account the volume of the initializing order execution. In the case a trader places a pending order of the BuyLimit type and protects it with StopLoss and TakeProfit in the form of orders, it does not necessarily mean that BuyLimit is guaranteed to execute the whole volume. These cases must also be catered for by the paired orders. In addition to the condition for cancellation, a paired order must have an additional condition for triggering. It can trigger only when an additional order connected with it triggers. That means that an OCO order must have links to two orders. The first link is to the order which triggering will activate the current order. The second link is the order which triggering will cancel the current order. Such a mechanism will allow to create a position with a pending initializing order Such mechanisms, even if they appear, will be very complex for a user with limited experience. Their suitability is doubtful. Virtualization on the clients side, like the one currently used in HedgeTerminal, is easier to use. As an alternative to OCO orders, MetaQuotes could consider a possibility of introducing specific algorithmic TakeProfit and StopLoss levels ensuring protection of a certain trading order. Surely, this is only a theory though it has rational kernel. Such algorithmic levels can hide the major part of the implementation and configuration on the trading server side offering to the end users a simple ready-to-use protection mechanism. Summing up, our little discourse about the perspectives of integrating OCO orders in the MetaTrader 5 platform: OCO orders are not effective when orders are executed partially, they are not reliable enough and too complex for a regular user of the platform. 3.5. Storing Links to Initializing Orders This section considers a detailed description of the internal storage of the links to other orders and mechanism of binding between them. As was mentioned before, the field Order Magic contains the identifier of the Expert Advisor that placed an order. This means that any trader can enter any integer value in this field using the MQL5 programming language. In such cases a collision is possible, when the order initializing a new position will contain the identifier of an Expert Advisor matching the identifier of an existing order. In this case a wrong link to the order will appear. If a trader uses identifier for the EAs close to zeros, like 1 . 7 or 100 . and the order numbers are significantly greater than those numbers, like 10002384732 . these collisions can be avoided. It would be rather naive to believe that traders will keep that in mind. That is why HedgeTerminal stores links to orders in a special way so the probability of collisions is very low and its algorithms do not allow ambiguousness and eliminate collisions automatically if they appear. The Order Magic field storing the link takes 64 bit. Due to its width, this field can take a very long number. In reality, the working range of order identifiers is a lot smaller. That allows Hedge Terminal to use higher digits of this field for its needs safely, forming a link to the order in a special way. Let us refer to the scheme showing how HedgeTerminal stores a link to the initiating order: Fig. 44. A pattern of storing a link to the initializing order in HedgeTerminal The top digit of the field (63) is always marked as 1. This enables a very quick iteration over all orders. Clearly, if the next digit is not equal to 1, then the order cannot contain a link to another order and it can be skipped. Besides, assigning the value of 1 to the highest digit makes the magic number very large and that increases the distance between the working range of the order identifiers and the working range of the links in HedgeTerminal, which minimizes a probability of a collision. HedgeTerminal can fill the following three bits with service information. Unlike the order identifier, HedgeTerminal stores order identifiers in this field inside out. At first it fills higher digits and then smaller ones, which is pointed at by a blue arrow direction SI (service information) at Fig. 44. This way of storage makes the ranges of service information and order identifiers to meet half way. If necessity arises, their composition can be changed. The size of service information can be increased through the digits for storing the order identifier. This information allows to identify the type of the closing order . The point is that active orders in MetaTrader 4 can be closed by TakeProfit or StopLoss. These are certain price levels at which orders get closed with fixed profit or loss. In MetaTrader 5, TakeProfit and StopLoss can be applied only to net positions and they are not suitable for paired orders. Only ordinary pending orders can play a role of TakeProfit and StopLoss orders. In HedgeTerminal such orders are assigned special identifiers specifying whether this is a TakeProfit or StopLoss order. As magic number is stored on the trading server, the service information becomes available for all the traders who have access to the trading account. This way, even several HedgeTerminal copies running on different computers will have the information about the type of the triggered orders and will display the information on closed positions correctly. The referenced information about the order identifier is stored in the range from 0 to 59 digit. This is stored in the standard direction, using digits from right to left, which is indicated by a blue arrow direction order id. To evaluate the allocated storage size, let us calculate the amount required for storing the range of all orders sent to Moscow Exchange during a year. My brokers report dated 13.06.2013 contains an order with the 10 789 965 471 identifier. This number uses 33.3297 bits ( log2(10 789 965 471) ) or 34 out of 64 digits. The identifier of one of the orders placed by 25.09.2014 is 13 400 775 716 . This number uses 33.6416 bits. Although 2.6 billion orders were placed in one year and four months, the size of the identifier increased by only 0.31263 bit, which is less than even one order. I do not claim that the Sun will die before the size of the order identifier will come to the 59th digit, but I am pretty confident that this will happen no earlier than in a couple of million years. HedgeTerminal does not store a link openly. For that it encrypts the field OrderMagic, leaving the senior digit untouched. The code of HedgeTerminal is based on the reversible rearrangement of digits implemented by the special encrypting function working on the variable length key. After such an encryption, the service information and order identifier get mixed with each other and hidden under a special mask so that on the exit they represent an even distribution of ones and zeros. The encryption takes place for two reasons. First of all, the digit rearrangement decreases the probability of links and order identifiers overlapping and then it protects the internal algorithms of HedgeTerminal from the external deliberate or random impact. This procedure is absolutely safe, reversible and is not prone to collisions. That warrants that irrespective to the actions a trader performs using the Expert Advisors, they do not affect the reliability of the internal HedgeTerminal algorithms. This is very important as in a real situation managing these links is impossible without complex dedicated algorithms. At the same time, if we confine ourselves with only controlling the links, the failure of the business logic is inevitable. The following sections will explain why as they are dedicated to the detailed description of these algorithms. Encryption is also used to avoid this failure. The reverse of the coin of this restriction is that there is no other way to manage the HedgeTerminal positions but to use this. 3.6. Limitations at Work with HedgeTerminal The peculiarity of the structure of link storage prompts that HedgeTerminal stores links to the orders evenly using numbers from 9223372036854775808 to 18446744073709551615 . If a 64-digit field is represented as a number with the sign of the long type, then these will be negative values. Here arise three limitations for work with HedgeTerminal. The first limitation concerns the trading robot, working with HedgeTerminal. This is not strict and it can be treated as a recommendation: A trading robot or an Expert Advisor working with HedgeTerminal must have an identifier (Experts magic number) not exceeding the value 9223372036854775808 . In reality, usual Expert Advisors will never come across this restriction as identifiers exceeding 5-6 digits are used very seldom. The most common identifier for an Expert is 12345 or something of the kind). This restriction may be applicable for the robots storing service information like links to other orders in their magic numbers. HedgeTerminal is not compatible with such Experts and cannot work in conjunction with them. If for some reason mentioned limit is exceeded, then appears a zero probability of collision. The latter is very small as coincidence in such a range is very unlikely. Even in this case HedgeTerminal will solve this collision using its algorithms. This will slow its work down as deciphering a link, comparing this link with the existing orders and analyzing this order for suitability for pairing with another order will take extra time. So, to avoid this, it is better not to use long numbers with a negative sign. The second limitation is hard but it concerns only the broker and the exchange HedgeTerminal is going to be connected to: Order identifiers must use numbers from 0 to 259 or 576 460 752 303 423 488. This is obvious as only 59 digits are used for storing order identifiers instead of 64. If your broker uses order identifiers greater than this value, you cannot use Hedge Terminal in your work. The third limitation follows from the way of position representation: HedgeTerminal is not compatible with any other position management system. This is not compatible with external trading panels featuring the function of closing positions and cannot be used together with them. 3.7. Mechanism of Pairing Orders and Determinism of Actions We have considered in detail position representation in HedgeTerminal and the structure of its links. Not we are going to discuss the algorithm description that manage bound orders. For instance, we have two orders chosen from a number of other orders and we have to link them. If we do not rely on the rule that a link to the order must be unique and be possessed only by one order, all possible situations can be divided into three groups: The order is not referenced by any other orders The order is referenced by one order The order is referenced by two or more orders. The first group does not cause difficulties and such an order is considered an open position. Things are very straight forward with the third group too as a pair of orders makes a closed position. What can we do with the cases from the third group What if an order is referenced to by two other orders Which of them is supposed to be linked with the first one and what will happen to the second order It is easy to answer this question if we present the process of pairing as a sequential one: We come across an order that does not contain a link to another order. It gets transferred into the section of active orders (positions) and after that the iteration over orders continues Then we come across another order that has a reference to the first order. Then the referenced order is being searched in the section of the active orders. If the referenced order is in this section, then it gets paired with the current order and they both get transferred to the section of complete transactions in the form of historical positions During further iteration, we come across one more order that contains a link to the order described in point 1. Then the referenced order is being searched in the section of the active orders. This time the search will be unsuccessful as the sought orders was carried over from this section to the section of completed transactions. Since the order referenced to by the current order was not found, then the current order despite its link is an active order and is carried to the section with the active positions. Since the order identifiers are filled in a consistent manner and their list is sorted by time, then their sequential iteration can be performed. So, the initializing order will be paired with the very first order containing a link to it irrespective to the number of other orders containing the same links. All other orders containing links to the initializing order will be included in the list of active initiating positions. As we already mentioned, the algorithm executing such an iteration must be completely deterministic and consistent. HedgeTerminal uses such an iteration algorithm in its work. Factually, this is not simply an iteration but a repetition of all trading actions that have been performed from the moment of the first deal. Effectively, at every launch HedgeTerminal consistently builds a chain of trading actions from the very beginning to the current moment. Thanks to that, its current position representation is the result of its retrospective trading at the moment of launch. Since the iteration over all orders in history is carried out sequentially, it is required to perform trading actions sequentially too. That determines the way of the order execution in HedgeTerminal. For instance, an active bi-directional HedgeTerminal position protected by StopLoss is required to be closed. We know that such a bi-directional position essentially consists of two orders: executed order initiating an active position and a pending order buy-stop or sell-stop, acting as a stop-loss order. To close such a position, it is required to delete the pending order and close an active bi-directional position by a counter order with the same volume. So, two trading actions have to be performed. HedgeTerminal executes all trading orders in an asynchronously. This way orders can be executed simultaneously i. e. the first order can be placed to cancel the pending order and the second order to execute the counter order, which will close your position. This however will upset the determinism of actions and HedgeTerminal cannot perform that. If for some reason, the pending order is not cancelled and the position does not get closed by the counter order, there will be ambiguity as position will be closed and its StopLoss will still exist. In the end, the order that implements StopLoss can trigger and generate a new bi-directional position. That should not happen. That is why HedgeTerminal will cancel StopLoss and after successful cancellation will place a counter order. There is a possibility that the counter order will not be executed or executed partially at the second step. In that case though, ambiguity will be eliminated as even a partially executed counter order will close a part of the active position. This is an ordinary situation. There is a more complex sequence of actions implemented by HedgeTerminal. Let us use an example similar to the previous one but this time we shall close a part of the position. That means that HedgeTerminal will have to carry out three actions: Delete the pending order that acted as the StopLoss order Execute the counter order closing a part of the volume of a bi-directional position Place a new StopLoss with a new volume protecting the remaining part of the active position. All these actions will be executed consistently to avoid disrupting the determinism of actions. The natural thing to expect is the increase of the order execution speed due to the simultaneous order placement though in that case a sequential execution of trading operations cannot be guaranteed and ambiguities are possible. A sequential order processing does not imply any ambiguity. 3.8. Splitting and Connecting Deals - the Basis of the Order Arithmetics A sequential order handling is not sufficient. Here two things should be noted: One order can include several deals. The number of those deals can be random It is also important to take into account a partial order execution and a more common case when a volume of a closing order may be not equal to the volume of the initiating order The order can be executed by several deals at the same time and it can be executed partially. If you do not know why it can happen, please refer to the article dedicated to the description of the exchange pricing Principles of Exchange Pricing through the Example of Moscow Exchanges Derivatives Market . The question Why can the volume of the closing order be not equal to the volume of the opening one requires an answer. What can we do in this case In fact, their volumes can be not equal if we presume an opportunity of a partial closure of an active position. If we open an active position with the volume of 50 contracts and close a part of positions by the counter order with the volume of 20 contracts, then the active position will be split into two parts. The first part will make a new historical position with the volume of 20 orders with the counter order and the second part will still open though its volume will decrease and will be 30 contracts. This algorithm of a partial position closure is implemented in HedgeTerminal. If a new volume value is entered in the Volume field of HedgeTerminal panel, then a partial closure will take place. In the History folder a new position will appear and the volume of the current position will be equal to the new value. HedgeTerminal can process the situation even when the volume of the closing order is greater than the volume of the initiating one Such a situation can take place if HedgeTerminal for some reason places an incorrect volume of the closing order or the broker backhandedly cancels a several deals included into the initiating order, and that will change the executed volume for a smaller one. To take into account a potential difference in volumes, it is required to use a universal algorithm based on the calculation of the total volume of all deals related to the order. In this case, it is deals, not orders that determine everything. The volume of an order is the volume of its deals. The price of an executed order is the average price of its deals. HedgeTerminal uses the algorithm that links orders with each other or divides them. It is based on the addition and subtraction of the deals. Its work is based on uniting the deals between the initializing and the closing order with the following formation of a historical position. To understand how this algorithm works, let us assume that there are two orders required to be paired to make a historical position. Both orders have the same number of deals and their executed volume is the same. Numbers of deals will be three digit for simplicity: Order 1 (in order) Table 4. Order 2 and its deals Let us put their deals with volumes together: Table 5. Putting orders together Select two last orders from each column: 294 and 921. In general they cannot be at the same level with each other (like in this example). Select a deal with the least volume. This is deal 294 with the volume 5. Divide the opposite deal 921 into two. The first deal is equal to the volume of deal 294 (5 contracts) and the second deal contains the remaining volume of 1 contract (6 contracts 5 contracts 1 contract). Unite deal 294 with the volume 5 with the first part of the volume 921 with the similar volume: Table 6. Subtraction of volumes Transfer the united part to a new column containing the deals of the historic position. This is highlighted in green . Leave the remaining part of the deal 921 with volume 1 in the initial column of active position. This is highlighted in gray : Table 7. Split and carrying over deals We have made the first step in uniting deals of two orders and carrying them over to historical position. Let us reflect the sequence of actions in a brief form: Table 8. Split and carrying over deals. Step 1 The volume of the deal 294 was carried over in full to the section of historical positions. The deal was annihilated completely. So the deal was split and carried over to the section of historical orders. That is why at the following step we can proceed to the following deal 288 with volume 2. Deal 921 is still present and its volume is equal to the remaining second part of the deal. At the following step this volume will interact with the volume of deal 288. At the second step repeat the procedure with deals 288 and 921. This time the remaining volume of deal 921 (1 contract) is united with the volume of deal 288 after getting to the column of historical orders. The remaining volume of deal 288 is equal to 1 contract and will remain in the column of the active position: Table 9. Split and carrying over deals. Steps 1-2 Repeat the same actions with deals 288 and 882: Table 10. Split and carrying over deals. Steps 1-3 Execute steps IV and V the same way: Table 11. Split and carrying over deals. Steps 1-5 After step V, the volume of the closing order will be absolutely the same as the volume of the opening order deals. Deals carried over to the column of historical positions make a complete historical transaction. The remaining deals of the active position make an active position. In this case there are no deals left in the column of the active position. This means that after such a unity, the active position will cease to exist. A new historical position will appear and will include all the deals of the active position. After deals were carried over, many of them will be split into parts and will occupy several lines. To avoid that, an option on collecting deals can be added to the algorithm of uniting/splitting of the deals. Simply unite the volume of the deals with the same identifiers into : Table 12. Uniting deals in one level After uniting, the number of deals and their volume completely match the initial deals and volumes. This happens only because their volumes initially matched. If their volumes were different, then after the procedure of uniting, the deals would have different volumes. This algorithm is universal as it does not require the same number of deals for the initiating and closing order. There is another example based on this property we are going to look at: Table 13. Uniting orders with different number of deals As we can see, uniting orders into one historical position was successful. In spite of a different number of deals, their volume matched again. Now, imagine that the aggregate volume of the closing order (12 contracts) is less than the volume of the deals of the initiating order (22 contracts). How will uniting go in this case Table 14. Uniting orders with different volumes As we can see, at the second step, the volume of the deals of the closing order is equal to zero whereas the initiating order contains two more deals 321 with volume 4 and 344 with volume 6. There is an excess of the active order deals. This excess will exist as an active bi-directional position. There is, however, a new historical position with the deals carried over to the green column. Its initial and exit volumes of 12 contracts matched again. In the case when the volume of the closing order is greater than the initiating, there is also an excess though this time it is on the side of the closing order: Table 15. Uniting orders with different volumes As we can see, the initial order with volume 4 and closing order with volume 6 make two positions. The first one is a historical position with volume 4 and deals 625 of the initial order and 719, 720 of the closing order. The second position is an excess of pairing deals of these orders. It contains deal 719 with volume 2. This deal and the order make an active position in the Active tab of the HedgeTerminal panel. Deals and orders can be divided by the algorithm into historical and active positions. Volumes can be different. The main thing is that the algorithm allows to bring together the volumes of the initiating and closing orders by forming a historical position with equal volumes of entry and exit. It insures the impossibility of the situation when these volumes are not equal and therefore of the errors of position representation causing an asymmetry of the position. Let us assume that in the first example the broker cancelled a deal included into the closing order: Table 16. Simulating of deleting a deal from the history A new net position with volume of 6 contracts. It will be equal to the volume of cancelled deals. Let us see how the algorithm of Hedge Terminal will work in this case: Table 17. Restoring the representation integrity As we can see, on step two there is an excess of 6 contracts (321). This excess will turn into an active position and thus the volume and direction of the bi-directional position is equal to that of the net position. Summing up, we can say that the algorithm of uniting deals guarantees the equality of the volumes of the initiating and closing orders in the historical positions due to excessive unbound deals. This excess of deals makes an active bi-directional position, which makes the net position in MetaTrader 5 equal to the net position of all active positions in HedgeTerminal. This mechanism works both retrospectively and in the real time mode and that means that it will make the net positions in Hedge Terminal even with the net position in MetaTrader 5 irrespective to the brokers action on canceling trading actions. The combinations on the change of a net position and deal cancellation can be as they do not cause an asymmetry between the net position of the terminal and the net position of HedgeTerminal. The mechanism of partial position closure is based on the capability of this algorithm to bring together different volumes. This algorithm is one of the most important parts of HedgeTerminal ensuring its stable work as a self-adapting system with no setting required. 3.9. Order and Deal Virtualization Every order and deal in HedgeTerminal have a real prototype with a correspondent identifier. Nevertheless, from the point of view of HedgeTerminal one order can make an active position and at the same time be a part of a historical one. Deals and orders in MetaTrader 5 are indivisible entities. An order in the platform can be either pending or executed. A deal also has a constant volume and is always an executed transaction. In HedgeTerminal same orders and deals can be present in different bi-directional positions. The same deal or order in it can make an active and a historical position. In other words, orders and deals in HedgeTerminal are divided into several virtual ones. This data representation greatly differs from data representation in MetaTrader 5. However, this representation allows to be flexible and adapt to the retrospective changes of trading information and bring orders and deals together. 3.10. Mechanism of Hiding Orders We mentioned the mechanism of hiding orders in the section describing the installation of HedgeTerminal. HedgeTerminal can ignore some orders. For an order or a deal to stop existing for HedgeTerminal, it is enough to enter its identifier to the designated file ExcludeOrders. xml . Let us assume that we have several executed sell or buy orders on one symbol. The aggregate volume of sell orders is equal to the aggregate volume of buy orders. This way, no matter how many orders we have, their total position is equal to zero. If identifiers of these orders are not in the ExcludeOrders. xml file, HedgeTerminal will display each of them as a bi-directional position. Their total position though will be zero. Therefore, if a net position in MetaTrader 5 is zero, then the contribution of this order set to the net position can be simply ignored. Now, let us assume that at the moment t we have a zero net position on the S symbol and a set of orders N executed on this symbol by this time. As there is no position on this symbol, the total volume of the set of orders N is insignificant. In fact, the number of orders and their volume are irrelevant as since there is no position, these orders do not contribute to the total net position . This means that such orders can simply be ignored and there is no need to represent them as bi-directional positions. This is the very mechanism that HedgeTerminal uses at the moment of its installation. At the moment of installation t if there is no a net position, HedgeTerminal includes the set of orders N to the list of exception. Their total volume and number are irrelevant as there is no net position. If there is a net position at the moment of the HedgeTerminal installation, then it simply wont be installed until the net position is closed. After the installation, new orders will change the state of the net position. This state though will be synchronized with the net volume of the bi-directional positions in HedgeTerminal. Seemingly, we could get away without putting orders executed by the time of HedgeTerminal to the list of exceptions. At the same time, it may happen that there are a lot of orders by the time of installation and from the point of view of HedgeTerminal all of them will become bi-directional positions and their total volume cab differ from the net volume in MetaTrader 5. The mechanism of hiding orders can be effective against corruption of the account history. Así es como funciona. Let us assume that there is some order history. When HedgeTerminal is launched on this account, it will iterate all orders and will build bi-directional position based on them. If all orders are available from the time of the opening and data about these orders are not corrupted, the net position of these orders will be correspondent to the net position in MetaTrader 5. Apparently, net position in HedgeTerminal will be equal to the sum of these orders. This is illustrated on the diagram below: Fig. 45. Diagram of integral history A part of history can be missing or the information about orders be incorrect. It is not important if only one order is missing or several orders and it is irrelevant if information is missing in the beginning of the account history or in the middle. Net position in HedgeTerminal running on such an account is equal to the net position of all available orders. The net position of orders will not be equal to the factual net position of the terminal because of the missing part of the history. This situation is presented on the diagram B : Fig. 46. Partially corrupted history To synchronize a net position in HedgeTerminal with the factual net position in MetaTrader 5, we do not need to know what orders disappeared or corrupted. All we need is to calculate the difference between these net positions. In the above example, a position to buy with the volume of 5 contracts is open in the MetaTrader 5 terminal. In HedgeTerminal this will be correspondent to a long total position for 8 contracts. The difference between these two positions will be 3 contracts to buy because 8 BUY 5 BUY 3 BUY . After the contract difference has been calculated, it is required to place a correspondent buy or sell order with the volume equal to the difference. In our example it is required to place an order of buying 3 contracts. When the order is executed, HedgeTerminal will display it in the tab of active positions and its total net position will increase by 3 contracts and will become equal to 11 contracts to buy. The position in MetaTrader 5 will also increase and will make 8 contracts. The identifier of this order has to be entered in the list of ExcludeOrders. xml. and then the terminal has to be restarted. So, if the identifier of our order is equal to 101162513, then the following tag is supposed to be written in the file: After restarting HedgeTerminal, this bi-directional position will disappear. This way a net position in MetaTrader 5 will match a net position in HedgeTerminal and will make 5 contracts to buy. The described sequence of actions is presented on the diagram below: Fig. 47. Diagram of restoring data integrity Financial result of the disappeared position will not be recorder in the HedgeTerminal statistics. Unfortunately, hidden bi-directional positions do not take part in the trading statistics. In reality, a situation when a part of history is unavailable or corrupted is highly unlikely. Such a mechanism must be in place though the majority of MetaTrader 5 users will never come across a situation when they need to use it. After all a possibility of program errors of HedgeTerminal are not excluded. Even in this case there should be a reliable instrument of resolving these errors. 3.11. Adaptation Mechanisms We have considered mechanisms allowing HedgeTerminal to represent bi-directional positions in the net environment of MetaTrader 5. There are three of these mechanisms: Sequential iteration of deals Mechanism of splitting and bringing together deals Mechanism of hiding orders. Each of these mechanisms is addressing their issues and allows to avoid ambiguities and errors at their levels. Let us bring these problems and their solutions to the table. The first column contains the problems and possible errors of binding and the second column the mechanisms that solve them: Problems, errors, ambiguities arising at the bi-directional trading organization Mechanisms of error correction Errors in the links to the opening orders Link collision Long magic numbers in Experts deleting orders from the history Errors of trading operation execution. Sequential iteration over orders. Determinism of actions. Volume errors Matching orders with different volumes partial order execution deleting deals from history Covering a smaller volume with a greater one. Mechanism of splitting and matching deals. Installing HedgeTerminal on the account with a great number of executed orders Corrupted history Bugs of HedgeTerminal in the work with orders. Mechanism of hiding orders. Table 18. Possible errors and mechanisms of their elimination All three mechanisms together with the system of storing links ensure stable data representation. Essentially, these mechanisms cover all possible cases of unforeseen failures and guarantee matching of the net position in HedgeTerminal with the net position in MetaTrader 5. 3.12. Performance and Memory Usage HedgeTerminal is essentially an object oriented application. Due to the OOP principles underlying its architecture, the terminal has high efficiency and low requirements to the storage. The only resource consuming task is extracting the history of orders and deals in the computer memory at the moment of launching the terminal on a chart. After all required transactions were extracted in the memory, the terminal will print a message informing about the time spent on this operation and also memory usage. Launching the HedgeTerminal panel on the account containing more than 20,000 deals on the computer with the processor Intel i7 took less than 30 seconds and it required 118 Mb of RAM: The HedgeTerminalAPI library works even faster and takes a lot less memory as graphical representation of transactions is not required. Below is the result of the launch on the same account: A simple calculation shows that extracting one position takes from 1 to 1.26 milliseconds depending on the program type. Storing one transaction takes: (22 156 deals 22237 orders) / 44 Mb 1 Kb of RAM. Storing additional graphic representation of one transaction takes approximately: (118 Mb 44 Mb) 1024 / (22 156 deals 22237 orders) 1.71 Kb of memory. The code profiling shows that the major part of the time is taken by the only block of the order analysis. The major part of the latter is the system function call. In the future versions this block is going to be optimized and that will allow to boost efficiency at the launch by 10-15. Conclusion We have considered the key points in working with the visual panel HedgeTerminal. It was an example of creating a new class of panels with a possibility of flexible configuration. Schemes and specifications gave an in-depth idea of the organization principles of bi-directional trading. If you are creating your own virtualization libraries, the second chapter of this article will help you to design such a library. The character of the exchange execution requires to take into account the key points in the process of deal and order representation as bi-directional positions. This article showed that such a representation was impossible without the virtualization of deals and orders. Virtualization is a mechanism of breaking the volume of executed deals and cloning real orders so one order can be a part of several transactions. These manipulations with the trading environment are rather brave however the major part of the information required at the virtualization is stored on the trading server, such representation can be treated as reliable. Warning: All rights to these materials are reserved by MQL5 Ltd. Copying or reprinting of these materials in whole or in part is prohibited.
Comments
Post a Comment