Estrategias con órdenes Expert Advisor multiuso

Dmitry Fedoseev | 27 diciembre, 2013

 

Introducción

El elemento principal de cualquier estrategia de trading es el análisis del precio y de los indicadores técnicos que constituyen los principios fundamentales para abrir una posición. Lo llamaremos análisis de mercado, es decir, todo lo que ocurre en el mercado y que está mas allá de nuestro control.

Pero además, las estrategias pueden requerir otro tipo de análisis. A este último lo llamaremos análisis de la situación actual de trading. Comprende el análisis del estado de la posición y de cualquier orden pendiente disponible u omitida (si se usa alguna en una estrategia). Los resultados de este análisis nos plantean la toma de decisiones sobre si es necesario llevar a cabo determinadas acciones relativas a órdenes y posiciones, como por ejemplo órdenes Stop Loss móviles, cursar y eliminar órdenes pendientes, etc. En otras palabras, este análisis incluye el estudio de la actividad del mercado, las acciones relativas a la situación que hemos creado (o a un asesor experto) y las reglas de la estrategia que se está usando.

La orden conocida habitualmente como Trailing Stop puede considerarse, al menos hasta cierto punto, una segunda categoría de elementos presentes en una estrategia de trading. Consideremos el siguiente análisis: si hay una posición abierta con beneficio mayor que el valor establecido, mientras que Stop Loss no está fijada o se aleja del precio actual, Stop Loss será desplazada.

Trainling Stop es una sencilla función especialmente interesante. Además, puede ser clasificada como una categoría completamente distinta de elementos estratégicos de trading, siendo una función para la gestión de posiciones. De esta forma, una estrategia de trading puede comprender tres categorías de elementos:

  1. Análisis del mercado y acciones relacionadas.

  2. Análisis de la situación actual de trading y acciones relacionadas.

  3. Gestión de las posiciones.

Este artículo se centra en las estrategias que usan activamente órdenes pendientes (las llamaremos estrategias de órdenes para abreviar), un metalenguaje que puede utilizarse para describir dichas estrategias y su desarrollo, así como en el uso de una herramienta multiuso (asesor experto) cuya operación se basa en tales descripciones.

 

Ejemplos de estrategias de órdenes

El trading comienza, normalmente, abriendo una posición inicial. Esto puede realizarse de diversas formas:

  1. Abriendo una posición de mercado:

    • En la dirección señalada por los indicadores.

    • En la dirección elegida por el usuario en la ventana de propiedades del asesor experto.

    • En base a los resultados obtenidos al cerrar la última posición. En lugar de ser una posición inicial, tal posición puede ser una operación en una fase intermedia.

  2. Dos órdenes Stop opuestas. Cuando una de las órdenes se inicia, la segunda es borrada.

  3. Dos órdenes Stop Order opuestas. Cuando una de las órdenes se inicia, la segunda es borrada.

  4. Órdenes Limit Order y Stop Order cursadas en la misma dirección. En este caso, es necesario decidir sobre la dirección de las órdenes, al igual que en 1.

Una vez que ha sido abierta la posición inicial puede usar distintas estrategias de órdenes.


Escalado usando órdenes Limit Order (Fig.1)

Se abre una posición inicial y se establecen una o más órdenes Limit Order en la misma dirección incrementando el tamaño del lote. A medida que las órdenes Limit Order se inician, se establecen nuevas órdenes de este tipo hasta que la posición se cierra en Take Profit. Cuando la posición se cierra en Take Profit, las órdenes pendientes restantes se borran.

Fig. 1.  Escalado usando órdenes Limit Order
Fig. 1. Escalado usando órdenes Limit Order


Stop y Reverse (Fig. 2)

Se abre una posición inicial y se establece la orden Stop opuesta con un tamaño de lote incrementado y el nivel de Stop Loss de la posición inicial. Cuando la posición se cierra en Stop Loss, la orden pendiente entra en funcionamiento y una nueva orden Stop de sentido contrario se establece a su nivel Stop Loss, y se mantiene activa hasta que la posición es cerrada en Take Profit. Cuando la posición se cierra en Take Profit, se borran las órdenes pendientes restantes.

Fig. 2. Stop y Reverse
Fig. 2. Stop y Reverse


Efecto en cascada (Fig. 3)

Se abre una posición inicial y si parece una posición ganadora, incrementamos su volumen (escalado) y desplazamos Stop Loss a Breakeven. Si la posición se cierra en Take Profit, se supone que ha alcanzado un gran volumen y, por tanto, beneficio. Sin embargo, si Stop Loss se inicia durante la fase intermedia, simplemente no habrá beneficio.

Fig. 3. Efecto en cascada
Fig. 3. Efecto en cascada


Reapertura (Fig. 4)

Se abre una posición de mercado. El cierre en Stop Loss es seguido por una nueva apertura con un tamaño de lote aumentado y, por tanto, activo hasta que la posición se cierra en Take Profit. Esta estrategia es similar al escalado con órdenes Limit.

Fig. 4. Reapertura
Fig. 4. Reapertura


Es posible combinar todas las estrategias anteriores. Si una posición parece ser ganadora, puede ser útil emplear el efecto en cascada ya que, de otra forma, si se producen pérdidas, puede ser aconsejable utilizar un escalado mediante las órdenes Limit. Dicho esto, el escalado con órdenes Limit no tiene por qué ser continuo. Por ejemplo, puede, en un primer momento, escalar en tres fases y así realizar varias órdenes Stop y Reverse y cambiar al escalado de nuevo usando órdenes Limit, etc.

En la práctica, el desarrollo de estrategias de órdenes puede consumir mucho tiempo, no solo por el código que es necesario desarrollar, sino también por la necesidad de ser creativos en cada caso concreto. Vamos a facilitar la programación de estas estrategias creando un asesor experto multiuso que nos permitirá implementar cualquier estrategia de órdenes.

 

El principio básico

El principio básico del desarrollo de una estrategia de órdenes es la identificación de la fase actual en la que se encuentra la estrategia y llevar a cabo acciones según dicha fase.

Echemos un vistazo al siguiente ejemplo: necesitamos abrir una posición de mercado, digamos, una posición de compra. Una vez que la posición está abierta, se necesitan dos órdenes pendientes: una orden Stop por encima y otra orden Limit por debajo. Al principio no hay ninguna posición u orden en el mercado y, por tanto, identificamos la fase como la de operación inicial, donde necesitamos abrir una posición. La existencia de una posición de mercado sugeriría que esta es la próxima fase de la operación. Por tanto, pueden identificarse las siguientes fases:

  1. No hay posición ni orden. Es necesario abrir una posición.

  2. Hay una posición pero no hay orden. Se necesita una orden Stop.

  3. Hay una posición y una orden Stop. Se necesita una orden Limit.

El trabajo según estas reglas puede realizarse sin mayores problemas, aunque no obstante va a requerir tres ticks: el primero para identificar la falta de la posición y de la apertura de la posición; el siguiente tick será necesario para identificar la posición y la ausencia de órdenes y, finalmente, el tercer tick será necesario para identificar la posición y la orden. La estrategia requiere que las tres acciones se realicen de una sola vez.

Por ello deberíamos intentar realizar todas las acciones al mismo tiempo: si no hay posición u orden, debemos abrir una posición. Si se ha abierto la posición con éxito, debemos enviar una solicitud para cursar una orden Stop y otra para cursar una orden Limit. Puede que ninguna de estas solicitudes para establecer una orden pendiente sea aceptada (por motivos de conectividad, falta de información sobre el precio, etc.), pero la situación de trading ha pasado a otra fase donde tenemos una posición abierta. Esto significa que todas las posibles fases intermedias deben ser cubiertas:

  1. No hay posición. Es necesario abrir una posición. Si la posición ha sido abierta con éxito, deben enviarse solicitudes para las órdenes Stop y Limit.

  2. Hay una posición pero no hay orden pendiente. Deben enviarse solicitudes para las órdenes Stop y Limit.

  3. Hay una posición y una orden Stop pero no hay una orden Limit. Debe enviarse una solicitud para una orden Limit.

  4. Hay una posición y una orden Limit pero no hay una orden Stop. Debe enviarse una solicitud para una orden Stop.

Observe que para identificar la fase en el ejemplo anterior, la situación de la transacción debe coincidir completamente con las reglas de identificación establecidas. Debe haber ciertos requisitos para la orden: solo una posición y ninguna orden o una posición y cualquiera de las órdenes. No hay otra alternativa. La descripción de las fases de operación de una estrategia según este principio puede llevar mucho tiempo y hacer que todo el proceso consuma mucho tiempo debido a la necesidad de tener en cuenta todas las posibles opciones y puede finalmente resultar impracticable. Las reglas de la operación en el ejemplo anterior pueden establecerse de una forma ligeramente distinta:

  1. No hay posición. Es necesario abrir una posición. Si se abre la posición con éxito, deben enviarse solicitudes de órdenes Stop y Limit.

  2. Hay una posición. En este caso, deben haber dos órdenes pendientes en el mercado. Verificar si hay una orden Stop en el mercado y determinar si no la hay. Verificar si hay una orden Limit en el mercado y determinar si no la hay.

En este caso, tenemos un mínimo de reglas para la identificación de la fase de la operación y una completa descripción de una situación de trading en cuya fase debemos estar.

La aplicación de este principio requerirá que la propia posición sea identificada para poder distinguir si es la posición inicial o si se ha iniciado una orden determinada. Es estas circunstancias no será necesario intentar cursar la segunda orden ya que el sistema se encuentran en la nueva fase de operación. También será necesaria la identificación de las órdenes, pero veremos la identificación de posiciones y órdenes un poco más tarde. Vamos ahora a establecer el principio básico para describir las estrategias de órdenes de un modo más claro y breve:

  1. Necesitamos un método para la identificación de la fase de la operación actual con la menor cantidad posible de información.

  2. Cada fase de la operación debe tener una descripción completa de la situación de dicha fase.

  3. Si se requieren acciones de mercado (apertura, cierre, escalado, etc.) u órdenes pendientes en una fase determinada, dicha fase debe dividirse en dos subfases: antes y después de realizar la acción de mercado (para que nos permita realizar todas las acciones a la vez y repetir los intentos fallidos de una orden pendiente).

  4. Si se requieren acciones de mercado (apertura, cierre, escalado, etc.) u órdenes pendientes en una fase determinada, las órdenes pendientes deben negociarse tras la finalización con éxito de la acción de mercado.

  5. Una fase solo puede corresponder a una acción de mercado y a cualquier número de acciones con órdenes pendientes.

 

Identificación de órdenes y posiciones

Las órdenes y posiciones pueden identificarse de varias formas: usando el comentario de la orden, el número mágico o las variables globales. Vamos a usar los comentarios. Los principales problemas que plantea el uso de comentarios son el tamaño limitado del comentario y el hecho de que el broker puede añadir contenido propio al mismo. Si no hay espacio suficiente para la entrada del broker, se eliminará una parte del comentario.

Por tanto, debemos utilizar el menor espacio posible en el comentario e intentar encontrar un modo de separarlo de las posibles entradas del broker. Cada orden tan solo necesita un identificador. En la práctica, pueden ser una o dos cifras o una combinación de una letra con una o dos cifras. Al final del identificador pondremos una marca, digamos "=" (nunca es usada por los brokers en sus entradas). Por tanto, tenemos un máximo de 4 caracteres. Para obtener el identificador de un comentario podemos usar la siguiente función:

//+------------------------------------------------------------------+
//|   Función para obtener el identificador de la cadena aComment |
//+------------------------------------------------------------------+
string GetID(string aComment)
  {
   int    p =StringFind(aComment,"=",0); // Determina la posición del separador
   string id=StringSubstr(aComment,0,p); // Obtiene la subcadena situada antes del separador
   return(id);
  }
//+------------------------------------------------------------------+

Si la posición o la orden requiere ser comparada con algún identificador conocido, puede procederse como sigue:

//+------------------------------------------------------------------+
//|   Comparando el comentario con el identificador                |
//+------------------------------------------------------------------+
bool FitsID(string aID,string aComment)
  {
   return(StringFind(aComment,aID+"=",0)==0);
  }
//+------------------------------------------------------------------+

 

Metalenguaje para la descripción de estrategias de órdenes

Vamos a definir ahora el lenguaje que se va a usar para escribir estrategias de órdenes. Debe ser conciso, claro e intuitivo, mientras que al mismo tiempo debe ajustarse a MQL5 para asegurar la rápida ejecución de sus comandos sin realizar cálculos innecesarios. Se deja a los lectores la decisión sobre si el resultado ha sido o no un éxito.

La descripción de la estrategia se realiza en un archivo de texto que se conecta al asesor experto, especificando su nombre en la ventana de propiedades del asesor experto.

Cada línea del archivo se corresponde con una fase de la operación del sistema. La línea se divide en dos campos. El primer campo contiene las reglas de identificación de la fase. El segundo cubre la lista de acciones. Los espacios se separan por una línea vertical "|". Se establecen las reglas de identificación y los elementos de la lista de acciones, separadas por un punto y coma ";".

Además de los comandos, la parte derecha de cada línea puede contener un comentario separado del resto del texto por "#", por ejemplo:

Nothing | Buy(M1,1,0,0) # Si no hay posición ni orden en el mercado abre una posición Buy, la marca como "М1", lote 1, no Stop Loss, no Take Profit.

 

Identificación de la fase

La identificación de la fase puede requerir información sobre la posición del mercado actual, órdenes pendientes o la última transacción. Además del estado de la posición, pueden ser necesarios algunos detalles sobre la posición como el precio, beneficio, valor de Stop Loss, si se establece alguno, etc. La información requerida sobre la última transacción puede incluir los resultados de esta. Para órdenes pendientes puede ser necesario especificar su precio de apertura, Stop Loss o Take Profit (que probablemente sea necesaria en la fase de ejecución).

Esta información puede obtenerse usando comandos de acceso a datos de transacciones. La mayoría de estos comandos tendrán dos parámetros: identificador de posición u orden e identificador de parámetro. Si no se especifica el identificador de parámetro, solo se comprobará la existencia del objeto especificado por el comando y el identificador.

Por ejemplo, el comando Buy(M1) sugiere que debe haber una posición de mercado con el identificador "M1". El comando Buy() solo (o simplemente Buy sin paréntesis) significa que debe haber una posición Buy con algún identificador. Si especificamos el identificador del parámetro, este indicará el valor del parámetro, por ejemplo Buy(M1,StopLossInPoints) - valor de Stop Loss en los puntos establecidos por una posición Buy con el identificador "M1". Si no se especifica ningún identificador - Buy(,StopLossInPoints), lo consideramos como un valor de Stop Loss de una posición Buy con cualquier identificador (siempre y cuando haya una posición Buy).

El valor obtenido puede utilizarse en la expresión para verificar las condiciones, por ejemplo Buy(M1,StopLossInPoints)>=0 - la posición es un punto de equilibrio. Si no hay ninguna posición o hay una posición con un identificador distinto, la fase expresada de esa forma en las reglas de identificación no será identificada, es decir, no es necesario tener en cuenta dos condiciones -para verificar el estado de la posición y el valor de Stop Loss. Sin embargo, en este caso será necesario verificar con anterioridad la existencia de Stop Loss - Buy(M1,StopLossExists); Buy(M1,StopLossInPoints)>=0.

Cuando se verifican los valores puede usarse cualquier expresión de comparación: ">=", "<=", "==", "!=", ">", "<". El valor en el lado derecho de la comparación puede expresarse como un número o con variables especiales: Var1, Var2 ... Var20. Añadir "p" a un número o una variable sugerirá que el valor será multiplicado adicionalmente por el valor del punto (la variable _Point).

Alternativamente, puede haber una expresión aritmética más compleja en la parte derecha de la expresión de comparación. Puede ser de esta forma: X1*X2+X3*X4 ("+" puede reemplazarse con "-"), donde X1, X2, X3 y X4 pueden ser números, variables o comandos de acceso a datos. El ejemplo siguiente puede considerarse correcto en teoría (si obviamos su valor práctico):

-BuyStop(BS1,StopLossInPoints)*-SellLimit(SL1,StopLossInPoints)+-SellStop(SS1,StopLossInPoints)*-BuyLimit(SL1,StopLossInPoints)

La Tabla 1 muestra la lista de todos los comandos de acceso.

Tabla 1. Comandos de acceso a datos

Índice Comando Parámetros posibles Propósito
0 Nada Sin parámetros No hay posición u orden pendiente en el mercado
1 NoPos No parámetros No hay posición en el mercado
2 Pendiente Identificador de objeto, identificador del parámetro de la orden Cualquier orden pendiente con el identificador de objeto especificado. Si no se especifica el identificador de objeto, entonces cualquier orden pendiente con independencia del valor del identificador de objeto.
3 Buy Identificador de objeto, identificador del parámetro de la posición Una posición Buy con el identificador de objeto especificado. Si el identificador de objeto no se especifica, entonces una posición Buy
4 Sell Identificador de objeto, identificador del parámetro de la posición Una posición Sell con el identificador de objeto especificado. Si el identificador de objeto no se especifica, entonces una posición Sell
5 BuyStop Identificador de objeto, identificador del parámetro de la orden Una orden BuyStop con el identificador de objeto especificado. Si el identificador de objeto no se especifica, entonces una orden BuyStop
6 SellStop Identificador de objeto, identificador del parámetro de la orden Una orden SellStop con el identificador de objeto especificado. Si el identificador de objeto no se especifica entonces una orden SellStop
7 BuyLimit Identificador de objeto, identificador del parámetro de la orden Una orden BuyLimit con el identificador de objeto especificado. Si el identificador de objeto no se especifica, entonces una orden BuyLimit
8 SelLimit Identificador de objeto, identificador del parámetro de la orden Una orden SellLimit con el identificador de objeto especificado. Si el identificador de objeto no se especifica, entonces una orden SellLimit
9 BuyStopLimit Identificador de objeto, identificador del parámetro de la orden Una orden BuyStopLimit con el identificador de objeto especificado. Si el identificador de objeto no se especifica, entonces una orden BuyStopLimit
10 SellStopLimit Identificador de objeto, identificador del parámetro de la orden Una orden SellStopLimit con el identificador de objeto especificado. Si el identificador de objeto no se especifica, entonces una orden SellStopLimit
11 LastDeal Vacío, identificador del parámetro de la transacción La última transacción
12 LastDealBuy Vacío, identificador del parámetro de la transacción La última transacción es la transacción Buy
13 LastDealSell Vacío, identificador del parámetro de la transacción La última transacción es la transacción Sell
14 NoLastDeal Sin parámetros No hay datos sobre la transacción en el historial. Esto es necesario en caso de que el Expert Advisor haya empezado a operar en la cuenta.
15 SignalOpenBuy Sin parámetros Señal del indicador para abrir una posición Buy
16 SignalOpenSell Sin parámetros Señal del indicador para abrir una posición Sell
17 SignalCloseBuy Sin parámetros Señal del indicador para cerrar una posición Buy
18 SignalCloseSell Sin parámetros Señal del indicador para cerrar una posición Sell
19 UserBuy Sin parámetros Comando del usuario para comprar
20 UserSell Sin parámetros Comando del usuario para vender
21 Compra Sin parámetros Precio de compra
22 Venta Sin parámetros Precio de venta
23 ThisOpenPrice Sin parámetros Precio de apertura de la orden cuyo parámetro es calculado. Se usa en comandos de acción para órdenes pendientes, excepto para órdenes de tipo Stop Limit
24 ThisOpenPrice1 Sin parámetros Precio de apertura-1 de la orden cuyo cuyo parámetro es calculado. Se usa en comandos de acción para órdenes pendientes del tipo Stop Limit
25 ThisOpenPrice2 Sin parámetros Precio de apertura-2 de la orden cuyo parámetro es calculado. Se usa en comandos de acción para órdenes pendientes del tipo Stop Limit
26 LastEADeal Identificador de objeto, identificador del parámetro de la transacción La última transacción ejecutada por el Expert Advisor. Se busca en el historial la última transacción que tiene "=" en su comentario y se compara con el identificador de objeto
27 LastEADealBuy Identificador de objeto, identificador del parámetro de la transacción La última transacción ejecutada por el Expert Advisor es la operación Buy. Se busca en el historial la última transacción que tiene "=" en su comentario y se compara con el identificador de objeto y la dirección de la transacción
28 LastEADealSell Identificador de objeto, identificador del parámetro de la transacción La última transacción ejecutada por el Expert Advisor es la operación Sell. Se busca en el historial la última transacción que tiene "=" en su comentario y se compara con el identificador de objeto y la dirección de la transacción
29 NoTradeOnBar Sin parámetros No hay transacciones en la última barra

 

Los comandos de la Tabla 1 le permiten acceder a los siguientes tipos de objetos de transacción: posiciones, órdenes, transacciones y órdenes a realizar. Diferentes objetos tienen diferentes conjuntos de parámetros.

La Tabla 2 muestra todos los identificadores del parámetro junto con los tipos de objeto a los que pueden aplicarse.

Tabla 2. Identificadores de acceso a datos.

Índice Identificador Propósito Tipo de objeto Trade
0 ProfitInPoints Beneficio en puntos Posición
1 ProfitInValute Beneficio en la moneda del depósito Posiciones, transacciones
2 OpenPrice Precio de apertura Posiciones, órdenes pendientes (excepto para órdenes Stop Limit)
3 LastPrice Price Trades
4 OpenPrice1 Precio de transición de Stop Limit a Limit Ódenes pendientes del tipo Stop Limit. El identificador OpenPrice se usa cuando la orden cambia a Limit
5 OpenPrice2 Precio de transición de Stop Limit a posición Órdenes pendientes del tipo Stop Limit. El identificador OpenPrice se usa cuando la orden cambia a Limit
6 StopLossValue StopLoss value Posiciones, órdenes pendientes
7 TakeProfitValue Valor de Take Profit Posiciones, órdenes pendientes
8 StopLossInPoints Stop Loss en puntos Posiciones, órdenes pendientes
9 TakeProfitInPoints Take Profit en puntos Posiciones, órdenes pendientes
10 StopLossExists Existencia de Stop Loss Posiciones, órdenes pendientes
11 TakeProfitExists Existencia de Take Profit Posiciones, órdenes pendientes
12 Dirección Dirección 1 - Buy, -1 -Sell Posiciones, órdenes pendientes, transacciones

 

Descripción de las acciones

Las acciones incluyen la apertura y cierre de las posiciones de mercado, el establecimiento, la modificación y eliminación de órdenes pendientes y la ejecución de funciones de gestión: Trailing Stop, Breakeven y Trailing Stop para una orden pendiente (cualesquiera otras funciones para la gestión de posiciones).

Las acciones de apertura de una posición y cursado de una orden implican el uso de los parámetros requeridos para ejecutar dichas acciones. Estos parámetros serán especificados tras el comando entre paréntesis, de la forma en que se suele llamar a las funciones. El identificador es el primer parámetro para todos los comandos. Al especificar los parámetros puede usar valores numéricos, variables, así como parámetros de la posición u orden existente. Puede usar también expresiones aritméticas como X1*X2+X3*X4, a la que se hace referencia en la sección de identificación de la fase para todos los parámetros de los comandos de acción.

La Tabla 3 muestra todos los comandos de acción.

Tabla 3. Comandos de acción

Índice Comando Propósito
0 Buy(ID,Lot,StopLoss,TakeProfit) Abrir una posición Buy
1 Sell(ID,Lot,StopLoss,TakeProfit) Abrir una posición Sell
2 Close(ID) Cerrar una posición de mercado
3 BuyStop(ID,Lot,Price,StopLoss,TakeProfit) Establecer una orden Buy Stop
4 SellStop(ID,Lot,Price,StopLoss,TakeProfit) Establecer una orden Sell Stop
5 BuyLimit(ID,Lot,Price,StopLoss,TakeProfit) Establecer una orden Buy Limit
6 SellLimit(ID,Lot,Price,StopLoss,TakeProfit) Establecer una orden Sell Limit
7 BuyStopLimit(ID,Lot,Price1,Price2,StopLoss,TakeProfit) Establecer una orden Buy Stop Limit
8 SellStopLimit(ID,Lot,Price1,Price2,StopLoss,TakeProfit) Establecer una orden Sell Stop Limit
9 Delete(ID) Borrar una orden pendiente
10 DeleteAll(ID,BuyStop,SellStop,BuyLimit,SellLimit,BuyStopLimit,SellStopLimit) Borrar los tipos especificados de órdenes pendientes
11 Modify(ID,Price1,Price2,StopLoss,TakeProfit) Modificación de la posición o la orden
12 TrailingStop Operación de la función Trailing Stop. Los parámetros de la función se definen en la ventana de propiedades del Expert Advisor
13 BreakEven Operación de la función Breakeven Los parámetros de la función se definen en la ventana de propiedades del Expert Advisor

 

Las descripciones del parámetro del comando de la acción se muestran en la Tabla 4.

Tabla 4. Parámetros del comando de acción

Parámetro Propósito
ID Identificador del objeto de la transacción (posición, orden)
Lot Tamaño del lote en unidades. La variable Lot que define el valor de la unidad se encuentra disponible en la ventana de propiedades del Expert Advisor
StopLoss Valor de Stop Loss
TakeProfit Valor de Take Profit
Price Valor de la orden pendiente (excepto para órdenes del tipo Stop Limit)
Price1 Precio de transición de Stop Limit a Limit
Price2 Precio de transición de Stop Limit a posición

 

Vamos ahora a escribir las estrategias de órdenes que hemos visto antes en nuestro nuevo metalenguaje.

 

Ejemplos de estrategias de órdenes en metalenguaje

Los programas se muestran en tablas donde todos los comandos de identificación de fase y acción se disponen en columnas para una mejor comprensión y se anotan con comentarios. Junto al artículo se encuentran todos los programas en archivos de texto en forma adecuada para su uso en el asesor experto.

Nota importante: No se permite el uso de "+", "-" y "*" en los identificadores. Es mejor usar simplemente números.

 

Escalado usando órdenes Limit Order

La posición inicial se abrirá según la dirección especificada por el usuario en la ventana de propiedades. Se permite el escalado hasta 5 veces (órdenes Limit). Solo puede haber tres órdenes en el mercado al mismo tiempo.

Tabla 5. Metaprograma para el escalado usando órdenes Limit

Número de fase Identificación de la fase Acciones Comentarios
1 Nothing;
UserBuy
Buy(1,1,0,Ask+Var1p);
BuyLimit(2,2,Buy(1,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(3,4,BuyLimit(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
Si no hay posición u orden en el mercado, la dirección de Buy se establece en las propiedades del asesor experto y abrimos una posición con un lote inicial. Si la posición ha sido abierta con éxito, intentaremos establecer tres órdenes Limit. Dicho lo cual, cada orden posterior solo será establecida con éxito si la anterior ha sido establecida, ya que el precio se calcula en base al precio de la orden anterior.
2 Buy(1) BuyLimit(2,2,Buy(1,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(3,4,BuyLimit(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
Si la posición ha sido abierta con éxito en la fase 1 pero no se han establecido todas las órdenes pendientes, se seguirá intentando establecer todas las órdenes pendientes.
3 Buy(2) BuyLimit(3,4,Buy(2,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(4,8,BuyLimit(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(5,16,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
Si la primera orden pendiente (con el identificador 2) ha entrado en funcionamiento, se continua con los intentos para establecer las otras dos órdenes que debían haberse establecido (pero no fue posible establecer) en fases previas, y se establece una nueva orden de forma que siempre hay tres órdenes Limit en el mercado.
4 Buy(3) BuyLimit(4,8,Buy(3,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(5,16,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(6,32,BuyLimit(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
Se ha iniciado otra orden Limit y debemos asegurarnos de la presencia de tres órdenes Limit en el mercado, al igual que en la fase anterior.
5 Buy(4) BuyLimit(5,16,Buy(4,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p);
BuyLimit(6,32,BuyLimit(5,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p)
Esta fase garantiza la presencia de dos órdenes pendientes solo cuando el total de órdenes se aproxima al número máximo de órdenes.
6 Buy(5) BuyLimit(6,32,Buy(5,OpenPrice)-Var2p,0,ThisOpenPrice+Var3p) Esta fase solo tiene una última orden.
7 Buy(6) Modify(6,,,Buy(6,OpenPrice)-Var4p,) Si la última orden ha entrado en funcionamiento, se establece una orden Stop Loss.
8 Nothing;
UserSell
Sell(1,1,0,Var1p); SellLimit(2,2,Sell(1,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(3,4,SellLimit(2,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
Similar a la fase 1 pero para la dirección de Sell.
9 Sell(1) SellLimit(2,2,Sell(1,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(3,4,SellLimit(2,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
Similar a la fase 2 pero para la dirección de Sell.
10 Sell(2) SellLimit(3,4,Sell(2,OpenPrice)+Var2p,0,Var3);
SellLimit(4,8,SellLimit(3,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(5,16,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
Similar a la fase 3 pero para la dirección de Sell.
11 Sell(3) SellLimit(4,8,Sell(3,OpenPrice)+Var2p,0,Var3);
SellLimit(5,16,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p);
SellLimit(6,32,SellLimit(4,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
Similar a la fase 4 pero para la dirección de Sell.
12 Sell(4) SellLimit(5,16,Sell(4,OpenPrice)+Var2p,0,Var3);
SellLimit(6,32,SellLimit(5,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p)
Similar a la fase 5 pero para la dirección de Sell.
13 Sell(5) SellLimit(6,32,Sell(5,OpenPrice)+Var2p,0,ThisOpenPrice-Var3p) Similar a la fase 6 pero para la dirección de Sell.
14 Sell(6) Modify(6,,,Sell(6,OpenPrice)+Var4p,) Similar a la fase 7 pero para la dirección de Sell.
15 NoPos;
Pending
DeleteAll(,0,0,1,1,0,0) Hay órdenes pendientes pero ninguna posición. Esto ocurre cuando la orden Take Profit de la posición se inicia. En este caso deben borrarse las órdenes. Después de borrar las órdenes el sistema cambia a la fase 1 o 9. Si el usuario ha deshabilitado la dirección inicial durante la operación del sistema, no habrá ninguna acción.

 

Uso de variables: Var1 - Take Profit de la orden inicial, Var2 - nivel al que se establece la orden Limit con relación al precio de apertura de la orden previa, Var3 - Stop Loss de la última orden.

La Fig. 5 es el gráfico que muestra el funcionamiento de este metaprograma.

Fig. 5. Funcionamiento del metaprograma para escalado usando órdenes Limit
Fig. 5. Funcionamiento del metaprograma para escalado usando órdenes Limit

Por favor, tenga en cuenta que las reglas para las direcciones de Sell y Buy se establecen por separado. Cada nivel de orden pendiente siguiente se calcula según el nivel de orden previo. Si falla un intento de establecer cualquier orden, la próxima orden no se usará por la falta del parámetro requerido. No será correcto calcular el nivel en función del precio de mercado para la posición. En tales casos pueden perderse algunas órdenes.

 

Stop y Reverse

El trabajo comienza con dos órdenes Stop pendientes. Se permite tener hasta cinco inversas.

Tabla 6. Metaprograma para Stop y Reverse

Número de fase Identificación de la fase Acciones Comentarios
1 Nada BuyStop(1,1,Ask+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellStop(1,1,Bid-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
No hay posición ni orden en el mercado. Intentamos establecer dos órdenes Stop con identificador 1.
2 NoPos;
BuyStop(1)
SellStop(1,1,Bid-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) No hay posición pero hay orden Buy Stop con identificador 1, lo que significa que debe haber una orden Sell Stop con identificador 1.
3 NoPos;
SellStop(1)
BuyStop(1,1,Ask+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) No hay posición pero hay orden Sell Stop con identificador 1 lo que significa que debe haber una orden Buy Stop con identificador 1.
4 Buy(1) Delete(1);
SellStop(2,2,Buy(1,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
Hay una posición Buy con identificador 1 en el mercado. En este caso no debe haber otras órdenes con identificador 1 pero debe haber una orden Sell Stop con identificador 2.
5 Sell(1) Delete(1);
BuyStop(2,2,Sell(1,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p)
Similar a la fase 4 pero la primera orden Sell Stop se ha iniciado.
6 Buy(2) SellStop(3,4,Buy(2,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) La segunda orden Buy Stop ha entrado en funcionamiento por lo que debe establecerse la tercera orden Sell Stop.
7 Sell(2) BuyStop(3,4,Sell(2,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) La segunda orden Sell Stop ha entrado en funcionamiento por lo que debe establecerse la tercera orden Buy Stop.
8 Buy(3) SellStop(4,8,Buy(3,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) La tercera orden Buy Stop ha entrado en funcionamiento por lo que debe establecerse la cuarta orden Sell Stop.
9 Sell(3) BuyStop(4,8,Sell(3,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) La tercera orden Sell Stop ha entrado en funcionamiento por lo que debe establecerse la cuarta orden Buy Stop.
10 Buy(4) SellStop(5,16,Buy(4,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) La cuarta orden Buy Stop ha entrado en funcionamiento por lo que debe establecerse la quinta orden Sell Stop.
11 Sell(4) BuyStop(5,16,Sell(4,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) La cuarta orden Sell Stop ha entrado en funcionamiento por lo que debe establecerse la quinta orden Buy Stop.
12 Buy(5) SellStop(6,32,Buy(5,StopLossValue),ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) La quinta orden Buy Stop ha entrado en funcionamiento por lo que debe establecerse la sexta orden Sell Stop.
13 Sell(5) BuyStop(6,32,Sell(5,StopLossValue),ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) La quinta orden Sell Stop ha entrado en funcionamiento por lo que debe establecerse la sexta orden Buy Stop.
14 NoPos;
BuyStop(2)
Delete(2) No hay posición pero todavía tenemos Buy Stop. Esto puede ocurrir cuando la posición se ha cerrado en Take Profit. En este caso las restantes órdenes se borran y el sistema pasa a la fase 1.
15 NoPos;
SellStop(2)
Delete(2) Similar a la fase 14.
16 NoPos;
BuyStop(3)
Delete(3) Similar a la fase 14.
17 NoPos;
SellStop(3)
Delete(3) Similar a la fase 14.
18 NoPos;
BuyStop(4)
Delete(4) Similar a la fase 14.
19 NoPos;
SellStop(4)
Delete(4) Similar a la fase 14.
20 NoPos;
BuyStop(5)
Delete(5) Similar a la fase 14.
21 NoPos;
SellStop(5)
Delete(5) Similar a la fase 14.
22 NoPos;
BuyStop(6)
Delete(6) Similar a la fase 14.
23 NoPos;
SellStop(6) |
Delete(6) Similar a la fase 14.

 

Uso de variables: Var1 - nivel al que se establecen las órdenes iniciales a partir del precio de mercado actual, Var2 - Stop Loss, Var3 - Take Profit.

La Fig. 6 es el gráfico que muestra el funcionamiento de este metaprograma.

Fig. 6. Funcionamiento del metaprograma para Stop y Reverse
Fig. 6. Funcionamiento del metaprograma para Stop y Reverse

 

Efecto en cascada

Se abre una posición inicial en función de la señal del indicador. Se permite el escalado hasta en cinco ocasiones.

Tabla 7. Metaprograma para el "efecto en cascada"

Número de fase Identificación de la fase Acciones Comentarios
1 Nothing;
SignalOpenBuy
Buy(1,1,Ask-Var1p,Ask+Var2p*6) No hay posición u orden en el mercado. Obtenemos una señal de los indicadores para abrir una posición Buy siguiendo la posición abierta. Primero se establece Take Profit a una distancia igual a Var2p*6 y en el siguiente paso se establecerá en Var2p*5 para asegurar que Take Profit se encuentra al mismo nivel de precio aproximadamente.
2 Buy(1);
Buy(1,ProfitInPoints)>=Var3
Buy(2,1,Ask-Var1p,Ask+Var2p*5) Hay una posición Buy que muestra un buen beneficio y por tanto escalamos.
3 Buy(2) Modify(2,,,Buy(2,OpenPrice),) La posición en el mercado tiene índice 2 sugiriendo que esta posición no es inicial y debería haber sido escalada. Stop Loss debería estar en Breakeven.
4 Buy(2);
Buy(2,ProfitInPoints)>=Var3
Buy(3,1,Ask-Var1p,Ask+Var2p*4) La posición está ganando otra vez, por tanto escalamos.
5 Buy(3) Modify(3,,,Buy(3,OpenPrice),) Stop Loss se mueve a Breakeven cada vez que escalamos.
6 Buy(3);
Buy(3,ProfitInPoints)>=Var3
Buy(4,1,Ask-Var1p,Ask+Var2p*3) Similar a la fase 4.
7 Buy(4) Modify(4,,,Buy(4,OpenPrice),) Similar a la fase 5.
8 Buy(4);
Buy(4,ProfitInPoints)>=Var3
Buy(5,1,Ask-Var1p,Ask+Var2p*2) Similar a la fase 4.
9 Buy(5) Modify(5,,,Buy(5,OpenPrice),) Similar a la fase 5.
10 Buy(5);
Buy(5,ProfitInPoints)>=Var3
Buy(6,1,Ask-Var1p,Ask+Var2p) Similar a la fase 4.
11 Buy(6) Modify(6,,,Buy(6,OpenPrice),) Similar a la fase 5.
12 Nothing;
SignalOpenSell
Sell(1,1,Bid+Var1p,Bid-Var2p*6) Similar a fase 1 pero con respecto a una posición Sell.
13 Sell(1);
Sell(1,ProfitInPoints)>=Var3
Sell(2,1,Bid+Var1p,Bid-Var2p*5) Similar a fase 2 pero con respecto a una posición Sell.
14 Sell(2) Modify(2,,,Sell(2,OpenPrice),) Similar a fase 3 pero con respecto a una posición Sell.
15 Sell(2);
Sell(2,ProfitInPoints)>=Var3
Sell(3,1,Bid+Var1p,Bid-Var2p*4) Similar a fase 4 pero con respecto a una posición Sell.
16 Sell(3); Modify(3,,,Sell(3,OpenPrice),) Similar a fase 5 pero con respecto a una posición Sell.
17 Sell(3);
Sell(3,ProfitInPoints)>=Var3
Sell(4,1,Bid+Var1p,Bid-Var2p*3) Similar a fase 6 pero con respecto a una posición Sell.
18 Sell(4); Modify(4,,,Sell(4,OpenPrice),) Similar a fase 7 pero con respecto a una posición Sell.
19 Sell(4);
Sell(4,ProfitInPoints)>=Var3
Sell(5,1,Bid+Var1p,Bid-Var2p*2) Similar a fase 8 pero con respecto a una posición Sell.
20 Sell(5); Modify(5,,,Sell(5,OpenPrice),) Similar a fase 9 pero con respecto a una posición Sell.
21 Sell(5);
Sell(5,ProfitInPoints)>=Var3
Sell(6,1,Bid+Var1p,Bid-Var2p) Similar a fase 10 pero con respecto a una posición Sell.
22 Sell(6); Modify(6,,,Sell(6,OpenPrice),) Similar a fase 11 pero con respecto a una posición Sell.

 

Uso de variables: Var1 - Stop Loss inicial, Var2 - Take Profit de la última orden, Var3 - beneficio en puntos en los que escalamos y movemos Stop Loss a Breakeven.

La Fig. 7 es el gráfico que muestra el funcionamiento de este metaprograma.

Fig. 7. Funcionamiento del metaprograma para el efecto en cascada
Fig. 7. Funcionamiento del metaprograma para el efecto en cascada

 

Reapertura

Primero establecemos dos órdenes Limit. Tan pronto como una de ellas se inicia, se borra la otra. A continuación, cuando entra en funcionamiento Stop Loss, se abre una nueva posición hasta que se cierra en Take Profit o se agota el número de posiciones (5).

Tabla 8. Metaprograma para reapertura

Número de fase Identificación de la fase Acciones Comentarios
1 Nothing;
NoLastDeal
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
No hay posición ni orden en el mercado y el historial de la cuenta no muestra transacciones en el símbolo. Significa que este es el inicio de la operación del sistema. Se establecen dos órdenes Limit como acción inicial.
2 Nothing;
LastDeal(,ProfitInValute)>0
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
No hay ni posición ni orden en el mercado pero el historial muestra una transacción que se cerró con beneficio. Esto sugiere que la fase previa se ha completado y necesitamos comenzar desde el principio y establecer dos órdenes Limit como en la fase 1.
3 Nothing;
LastEADeal(5)
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p);
SellLimit(1,1,Bid+Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p)
No hay ni posición ni orden en el mercado pero el historial contiene una transacción con el último identificador. En este caso, el beneficio obtenido en la transacción no es de importancia ya que la fase se considera completa de todas formas. Empezamos desde el principio y establecemos dos órdenes Limit como en la fase 1.
4 NoPos;
BuyLimit(1)
SellLimit(1,1,Bid+Var1p,ThisOpenPrice-Var2p,ThisOpenPrice+Var3p) No hay posición en el mercado pero sabemos que hay una orden Limit, lo que significa que debe haber también una segunda orden.
5 NoPos;
SellLimit(1)
BuyLimit(1,1,Ask-Var1p,ThisOpenPrice+Var2p,ThisOpenPrice-Var3p) Similar a la fase 4.
6 Buy(1);
SellLimit(1)
Delete(1) Hay una posición con identificador 1. Esto significa que las órdenes Limit se han iniciado y que la segunda orden debe borrarse.
7 Sell(1);
BuyLimit(1)
Delete(1) Similar a la fase 6.
8 Nothing;
LastDeal(1,ProfitInValute)<=0;
LastEADeal(1,Direction)==1
Buy(2,2,Ask-Var2p,Ask+Var3p) No hay posición y la última transacción no obtuvo beneficio. Se verifica la dirección de la última transacción ejecutada por el asesor experto. Si fue una transacción Buy, la siguiente posición que necesitamos abrir es una posición Buy.
9 Nothing;
LastDeal(1,ProfitInValute)<=0;
LastEADeal(1,Direction)==-1
Sell(2,2,Bid+Var2p,Bid-Var3p) No hay posición y la última transacción no obtuvo beneficio. Se verifica la dirección de la última transacción ejecutada por el asesor experto. Si fue una transacción Sell, la siguiente posición que necesitamos abrir es una posición Sell.
10 Nothing;
LastDeal(2,ProfitInValute)<=0;
LastEADeal(2,Direction)==1
Buy(3,4,Ask-Var2p,Ask+Var3p) Similar a la fase 8.
11 Nothing;
LastDeal(2,ProfitInValute)<=0;
LastEADeal(2,Direction)==-1
Sell(3,4,Bid+Var2p,Bid-Var3p) Similar a la fase 9.
12 Nothing;
LastDeal(3,ProfitInValute)<=0;
LastEADeal(3,Direction)==1
Buy(4,8,Ask-Var2p,Ask+Var3p) Similar a la fase 8.
13 Nothing;
LastDeal(3,ProfitInValute)<=0;
LastEADeal(3,Direction)==-1
Sell(4,8,Bid+Var2p,Bid-Var3p) Similar a la fase 9.
14 Nothing;
LastDeal(4,ProfitInValute)<=0;
LastEADeal(4,Direction)==1
Buy(5,16,Ask-Var2p,Ask+Var3p) Similar a la fase 8.
15 Nothing;
LastDeal(4,ProfitInValute)<=0;
LastEADeal(4,Direction)==-1
Sell(5,16,Bid+Var2p,Bid-Var3p) Similar a la fase 9.

 

Uso de variables: Var1 - nivel del precio de mercado al que deben establecerse las órdenes Limit, Var2 - Stop Loss, Var3 - Take Profit.

La Fig. 8 es el gráfico que muestra el funcionamiento de este metaprograma.

Fig. 8. Funcionamiento del metaprograma para reapertura
Fig. 8. Funcionamiento del metaprograma para reapertura

A continuación se muestran algunos programas sencillos para ver cómo operan estas funciones como señales de trading y órdenes Trailing Stop y Breakeven.

 

Señales de trading

La entrada y la salida se basan en señales de trading.

Tabla 9. Metaprograma para señales de trading

Número de fase Identificación de la fase Acciones Comentarios
1 Nothing;
SignalOpenBuy;
NoTradeOnBar
Buy(1,1,0,0) No hay posición ni orden en el mercado pero podemos ver una señal para abrir una posición Buy. No hay transacciones en la barra actual y abrimos una posición Buy.
2 Nothing;
SignalOpenSell;
NoTradeOnBar
Sell(1,1,0,0) No hay posición ni orden en el mercado pero podemos ver una señal para abrir una posición Sell. No hay transacciones en la barra actual y abrimos una posición Sell.
3 SignalCloseBuy;
Buy(1)
Close(1); Hay una posición Buy y una señal para cerrarla. La posición Buy está siendo cerrada.
4 SignalCloseSell;
Sell(1)
Close(1); Hay una posición Sell y una señal para cerrarla. La posición Sell está siendo cerrada.

 

La Fig. 9 es el gráfico que muestra el funcionamiento de este metaprograma.

Fig. 9. Funcionamiento del metaprograma para señales de trading
Fig. 9. Funcionamiento del metaprograma para señales de trading

 

Señales de trading con una orden Trailing Stop

Tabla 10. Metaprograma para señales de trading con una orden Trailing Stop

Número de fase Identificación de la fase Acciones Comentarios
1 Nothing;
SignalOpenBuy;
NoTradeOnBar
Buy(1,1,0,0) No hay posición ni orden en el mercado pero podemos ver una señal para abrir una posición Buy. No hay transacciones en la barra actual y abrimos una posición Buy.
2 Nothing;
SignalOpenSell;
NoTradeOnBar
Sell(1,1,0,0) No hay posición ni orden en el mercado pero podemos ver una señal para abrir una posición Sell. No hay transacciones en la barra actual y abrimos una posición Sell.
3 SignalCloseBuy;
Buy(1)
Close(1); Hay una posición Buy y una señal para cerrarla. La posición Buy está siendo cerrada.
4 SignalCloseSell;
Sell(1)
Close(1); Hay una posición Sell y una señal para cerrarla. La posición Sell está siendo cerrada.
5 Buy(1) TrailingStop Hay una posición Buy en el mercado. La función Trailing Stop debe ser activada.
6 Sell(1) TrailingStop Hay una posición Sell en el mercado. La función Trailing Stop debe ser activada.

 

La Fig. 10 es el gráfico que muestra el funcionamiento de este metaprograma.

Fig. 10. Funcionamiento del metaprograma para señales de trading con una Trailing Stop
Fig. 10. Funcionamiento del metaprograma para señales de trading con una Trailing Stop

 

Señales de trading con la función Breakeven

Tabla 11. Metaprograma para señales de trading con la función Breakeven

Número de fase Identificación de la fase Acciones Comentarios
1 Nothing;
SignalOpenBuy;
NoTradeOnBar
Buy(1,1,0,0) No hay posición ni orden en el mercado pero podemos ver una señal para abrir una posición Buy. Como no hay transacciones en la barra actual, la posición Buy está siendo abierta.
2 Nothing;
SignalOpenSell;
NoTradeOnBar
Sell(1,1,0,0) No hay posición ni orden en el mercado pero podemos ver una señal para abrir una posición Sell. Como no hay transacciones en la barra actual, la posición Sell está siendo abierta.
3 SignalCloseBuy;
Buy(1)
Close(1); Hay una posición Buy y una señal para cerrarla. La posición Buy está siendo cerrada.
4 SignalCloseSell;
Sell(1)
Close(1); Hay una posición Sell y una señal para cerrarla. La posición Sell está siendo cerrada.
5 Buy(1) BreakEven Hay una posición Buy en el mercado. La función Breakeven debe ser activada.
6 Sell(1) BreakEven Hay una posición Sell en el mercado. La función Breakeven debe ser activada.

 

La Fig. 11 es el gráfico que muestra el funcionamiento de este metaprograma.

Fig. 11. Funcionamiento del metaprograma para señales de trading con la función Breakeven

Fig. 11. Funcionamiento del metaprograma para señales de trading con la función Breakeven

 

Intérprete de comandos

El enfoque anterior para formalizar estrategias de órdenes nos permite entenderlas mejor y resolver un algoritmo para su posterior implementación en un asesor experto, así como para interpretar directamente y seguir las reglas creadas. Se ha creado el asesor experto eInterpretator con este propósito en mente (ver archivos adjuntos). Los parámetros del asesor experto y sus descripciones se muestran en la Tabla 12.

Tabla 12. Parámetros del Expert Advisor eInterpretator

Parámetros Propósito
Lotes Volumen de la orden cuando el coeficiente de lote es igual a 1.
UserTradeDir Dirección de la transacción especificada por el usuario (se verifica en la identificación de la fase cuando se ejecutan los comandos UserBuy y UserSell).
ProgramFileName Nombre de archivo del metaprograma (cuando trabaja sobre la cuenta). Cuando se prueba u optimiza debe reemplazarse el metaprograma en el archivo TesterMetaProgram.txt
DeInterpritate Interpretación inversa de comandos. Una vez finalizado, en la carpeta de archivos aparece un archivo con el prefijo "De_", y podremos ver cómo el asesor experto ha "entendido" el metaprograma a partir del archivo ProgramFileName.
Variables de usuario
Var1 - Var20 Variables de usuario.
Trailing Stop
TR_ON Activación de la función Trailing Stop.
TR_Start Beneficio de la posición en puntos al que Trailing Stop comienza a funcionar.
TR_Level Nivel de Trailing Stop Distancia en puntos del precio actual de mercado a Stop Loss.
TR_Step Distancia en puntos para la modificación de Stop Loss.
Break Even
BE_ON Activación de la función Breakeven.
BE_Start Beneficio de la posición en puntos que inicia la función Breakeven.
BE_Level Nivel al que se desplaza Stop Loss cuando Breakeven se inicia. El BE_Start-BE_Level de puntos de beneficio es fijo.
Señales de apertura
OS_ON Activación de señales para apertura.
OS_Shift Barra en la que el indicador es verificado: 0 - nuevo, 1 - completado.
OS_TimeFrame Período del indicador.
OS_MA2FastPeriod Período MA rápido.
OS_MA2FastShift Cambio MA rápido.
OS_MA2FastMethod Método MA rápido.
OS_MA2FastPrice Precio MA rápido.
OS_MA2SlowPeriod Período MA lento.
OS_MA2SlowShift Cambio MA lento.
OS_MA2SlowMethod Método MA lento.
OS_MA2SlowPrice Precio MA lento.
Señales de cierre
CS_ON Activación de señales para el cierre.
CS_Shift Barra en la que el indicador es verificado: 0 - nuevo, 1 - completado.
CS_TimeFrame Período del indicador.
CS_CCIPeriod Período CCI.
CS_CCIPrice Precio CCI.
CS_CCILevel Nivel CCI superior (para cerrar una posición Buy). Aparece una señal para cerrar una posición Buy en el cruce descendiente del nivel. Es exactamente lo opuesto a cerrar una posición Sell.

 

Cómo funciona un asesor experto

Al principio, el asesor experto carga el metaprograma a partir del archivo para revisarlo y analizarlo. Si se encuentra algún error grave en el metaprograma aparecerá un mensaje de error. Mientras analiza el metapograma, el asesor experto rellena las estructuras de datos con valores numéricos que se corresponden con los comandos de texto para asegurar el máximo rendimiento. El análisis con éxito del metaprograma genera el siguiente mensaje en el registro: "Se ha completado la inicialización del intérprete".

Si se incluye la variable DeInterpritate, el asesor experto ejecutará una interpretación inversa de comandos de prueba (por la que se desconectará del gráfico y se abortará cualquier prueba en el probador de estrategia que se lleve a cabo en ese momento). En la interpretación inversa, el asesor experto transforma los valores numéricos encontrados en las estructuras en comandos de texto. Y aunque las entradas de comando en el archivo serán diferentes, el metaprograma interpretado inverso nos permitirá tener una mejor idea de cómo analiza los comandos el asesor experto.

Veámoslo usando la siguiente cadena de texto del archivo del metaprograma:

Buy(6) | Modify(6,,,ThisOpenPrice-Var4p,)

Siguiendo la interpretación inversa, esta cadena es como sigue:

Buy(6)==1*1+0*0; | Modify(6,,,ThisOpenPrice()*1-0.0025*1,)

Como podemos ver, un simple comando Buy(6) se transforma en una expresión de comparación donde la parte derecha contiene la expresión aritmética X1*X2+X3*X4, que da 1 como resultado de los cálculos. En el campo de acción, la variable de usuario se reemplaza con el valor numérico.

 

Consejos sobre la personalización del asesor experto

Algunos de vosotros querréis probablemente personalizar este asesor experto añadiendo vuestros propios comandos a la fase de análisis y a la ejecución del comando, e incluir otras funciones de gestión de posición. Debido a la estructura del asesor experto, esta personalización puede realizarse directamente, ya que de otro modo todo el trabajo realizado sobre el asesor experto habría sido de escaso valor práctico.


Añadiendo comandos de datos

En la matriz InfoCommand se encuentra disponible una lista de comandos para obtener datos. Los comandos se disponen en columnas con cinco comandos en una fila que nos permiten contar fácilmente su número y encontrar el valor del índice para el comando a añadir.

Después de añadir el comando a la matriz InfoCommand, añadimos una nueva instancia correspondiente al nuevo índice de comando a la estructura de conmutación en la función SetValue(). Para obtener el valor, necesitamos primero seleccionar el objeto a partir del cual se obtendrá el valor y solo entonces podremos obtener dicho valor. Dependiendo del tipo de objeto del que se obtiene el valor se usan diferentes funciones para seleccionar el objeto. Estas funciones se muestran en la Tabla 13.

Tabla 13. Funciones del Expert Advisor para seleccionar objetos de transacciones

Función Propósito y parámetros
Pos.Select(_Symbol) Selección de la posición. Método de clase estándar similar a la función PositionSelect().
SelectOrder(long aType,string aID,bool & aSelected) Función para seleccionar una orden por el símbolo del asesor experto, tipo (aType) y valor del identificador (aID). Si se encuentra el objeto y se selecciona, la variable aSelected por referencia devuelve verdadero.
bool SelectLastDeal(int aType,bool & aSelected) Función para seleccionar la última transacción por el símbolo del asesor experto y el tipo (aType). Si se encuentra el objeto y se selecciona, la variable aSelected por referencia devuelve un valor verdadero.
SelectLastEADeal(int aType,string aID,bool & aSelected) Función para seleccionar la última transacción ejecutada por el asesor experto por el símbolo del asesor experto y el tipo (aType). Si se encuentra el objeto y se selecciona, la variable aSelected por referencia devuelve un valor verdadero.

 

La diferencia entre la última transacción y la última transacción ejecutada por el asesor experto está en que la última transacción cubre las transacciones Stop Loss y Take Profit. Los datos de la última transacción pueden requerir la determinación del resultado de cerrar la última posición, mientras que la información sobre la última transacción ejecutada por el asesor experto puede ser necesaria para identificar la última dirección de la transacción o la fase de operación del asesor experto.

Además de los datos del objeto trade, puede accederse a datos de mercado tales como el precio, etc. Es importante asegurarse de que los datos pueden obtenerse. Siguiendo un intento de seleccionar un objeto, debemos asegurarnos de que el objeto ha sido realmente seleccionado (verificando el valor de aSelected), obtener el parámetro requerido, asignar su valor a la variable Val.Value y devolver un valor verdadero.

La Tabla 14 muestra las funciones que se usan para obtener parámetros de varios objetos trade.

Tabla 14. Funciones del Expert Advisor para obtener parámetros del objeto trade seleccionado.

Función Propósito y parámetros
double SelPosParam(int aIndex) Obteniendo el parámetro de la posición por el índice establecido aIndex.
double SelOrdParam(int aIndex) Obteniendo el parámetro de la orden por el índice establecido aIndex.
double SelDealParam(int aIndex) Obteniendo el parámetro de la transacción por el índice establecido aIndex.

 

El índice de identificador del dato a obtener se pasa en la función. El valor del índice se encuentra en la variable Val.InfoIdentifierIndex.

Al añadir un nuevo comando de acceso, puede ser necesario añadir también el identificador del dato a obtener o solo añadir el identificador del dato tomado.

 

Añadiendo identificadores de datos

En la matriz InfoIdentifier se encuentra disponible una lista de identificadores. Necesitamos añadir el nuevo identificador a la matriz, encontrar su índice y actualizar las funciones SelPosParam(), SelOrdParam() y SelDealParam(). Las actualizaciones pueden afectar a algunas o a todas las funciones, dependiendo de si el nuevo identificador puede aplicarse a todos los objetos trade. La actualización de funciones consiste en añadir a la estructura de conmutación una nueva instancia correspondiente al nuevo índice de identificador.

 

Añadiendo comandos de acción

Los comandos de acción se añaden a la matriz ActCommand. Los comandos en la matriz se disponen en una cadena (string), haciendo que la búsqueda del índice sea más difícil. Los elementos representan una cadena, ya que además de añadir un comando necesitamos especificar el número y tipo de parámetros. El número de parámetros se especifica en la matriz ActCmndPrmCnt y el tipo se indica en la matriz ActCmndType. Los tipos posibles pueden ser: 0 - acción de mercado, 1 - acción con una orden pendiente y 2 - gestión de la posición.

Después de añadir el comando a la matriz, encontramos la función DoAction() y añadimos otra instancia para la nueva llamada de la función a su conmutador. La nueva función debe ser del tipo booleana y devolver un valor verdadero si se ejecuta con éxito o falso en caso de error. Si no es necesario verificar el funcionamiento de la función, como ocurre con la función Trailing Stop, puede simplemente devolver verdadero.

Recuerde que aquellas funciones que trabajan con órdenes pendientes, tales como las funciones para establecer las del mismo tipo, requieren comprobaciones preliminares de la existencia de la orden.

 

Cambios en las funciones de señales de trading

Todo el trabajo relativo a la obtención de señales de trading en el asesor experto se realiza en dos funciones (dos funciones para las señales de cierre y dos funciones para las señales de apertura).

La función CloseSignalsInit() (inicialización de señales para cierre) y la función OpenSignalsInit() (inicialización de señales para apertura) son llamadas desde la función OnInit() del asesor experto. Estas funciones son las responsables de cargar los indicadores. Las principales funciones -CloseSignalsMain() (identificación de las señales de trading para cierre) y OpenSignalsMain() (identificación de las señales de trading para apertura) son llamadas desde la función OnTick() en cada tick.

Al principio de la ejecución de la función se debe asignar el valor falso a GlobalCloseBuySignal, GlobalCloseSellSignal (señales para cierre) y GlobalOpenBuySignal, GlobalOpenSellSignal (señales para apertura) y verdadero con la lectura del indicador correspondiente.

Además, en la función OnDeinit() del asesor experto, necesitamos ejecutar IndicatorRelease().

 

Adjuntos

Nota. Al usar programas con señales de trading, Trailing Stop y Breakeven, debe siempre recordar habilitar las funciones correspondientes en la ventana de propiedades del asesor experto. Al probar estrategias en el probador de estrategia, copie los archivos del metaprograma en el archivo TesterMetaProgram.txt (esto es necesario para permitir el uso de los agentes de prueba remota). El archivo debe situarse en MQL5/Files del directorio de datos del terminal (puede abrirlo desde el terminal: Archivo -> Abrir carpeta de datos).

El funcionamiento de los programas mostrado en los gráficos de los ejemplos de las estrategias de ordenes en la sección Metalenguaje se basa en los parámetros especificados en los archivos de parámetro. Se ha realizado una prueba sobre los últimos meses (a 29.08.2012), para EURUSD H1, modelo OHLC en M1.

 

Conclusión

Muy a menudo, la primera sensación al empezar con el desarrollo de la estrategia de órdenes es la confusión -¿con qué empezar, qué debemos tener en cuenta, como conseguir la estabilidad del asesor experto en un entorno real, cómo combinar la ejecución de un algoritmo de estrategia de trading con la fiabilidad de su operación?

Este artículo pretende, en definitiva, ayudar tanto a los programadores como a los operadores que cursan órdenes en el desarrollo de asesores expertos con la formalización inicial de sus estrategias y ayudarles a comprender las etapas del desarrollo de la estrategia, lo que cada etapa conlleva y qué debe ser tenido en cuenta. El asesor experto del eInterpretator abre grandes posibilidades para experimentar con estrategias de órdenes con el mínimo esfuerzo y tiempo.

Ademas, me gustaría decir que no puedo dejar de comentar mi admiración por el terminal de MetaTrader 5. La velocidad de operación del asesor experto del eInterpretator en el probador de estrategia ¡ha superado mis expectativas!