Significado de resultados de optimización con Backtesting en Metatrader

Cuando hacemos una optimización en Metatrader, cada resultado tiene unos valores que nos indican que tan bueno es la prueba hecha. Acá va una pequeña explicación de cada valor.

Pass: Este valor indica el numero de la prueba. Es como el id.

Profit: Es la ganancia en dolares de la prueba.

Total trades: Es el total de operaciones hechas.

Profit factor: Es la relación entre perdidas y ganancias. Si el valor en 1, quiere decir que las perdidas y las ganancias son iguales. Conviene sobre manera, buscar los resultados que esten mas por encima de 1. Si por ejemplo este valor fuera 2, quiere decir que las ganancias fueron el doble que las perdidas.

Expected Payoff: Es el calculo estadistico de cuanto se puede ganar en efectivo en cada operacion. Osea, cuanto podria esperar ganar en una operacion con esta estrategia.

Drawdown $: Esta y la siguiente no las entiendo muy bien. La mayor reducción en relación con el depósito inicial, el depósito en moneda.

Drawdown %: La mayor reducción en relación con el depósito inicial, en porcentaje.

Ejemplo – Pasar array como parametro en funcion MQL4 – Metatrader

Para pasar un array como parametro en una funcion debemos hacer lo siguiente.

string arrayPrueba[10] = {"Cero", "Uno", "Dos", "Tres", "Cuatro", "Cinco", "Seis", "Siete", "Ocho"};

void ArrayComoParametro(string& array[])
{

array[1] = "Otro Numero";

}

int init()
{
Alert(arrayPrueba[1]);
ArrayComoParametro(arrayPrueba);
Alert(arrayPrueba[1]);
}

Función iCustom() para obtener valores de un indicador personalizado

La funicion  iCustom() se utiliza cuando necesitamos utilizar un indicador personalizado. Su estructura es la siguiente.
double iCustom(
                       string symbol,
                       int timeframe,
                       string name,
                       ...,
                       int mode,
                       int shift
)
Esta función devuelve el valor que nos interesa saber de la línea de un indicador.

symbol: Representa la divisa a utilizar. Si se coloca NULL se tomará como la divisa actual.

timeframe: Representa la temporalidad de la grafica. Si es 0 se tomará el periodo actual.

name: Nombre del indicador.

…: Los parámetros del indicador (si es necesario). Estos parámetros deben corresponder con el de las variables externas del indicador, y también con su orden y su tipo.

mode:  Acá colocamos el índice de la línea que nos interesa utilizar. Como solo se puede tener 8 líneas en un indicador, esta valor solo puede ir de 0 a 7.

shift: Debido a que todos los datos de una línea se almacenan en una array, acá colocamos el índice de la barra o vela en este array, de la cual nos interesa saber el valor de la línea que indicamos en mode.

Un ejemplo de utilizacon seria…
double L_1=iCustom(NULL,0,"rocseparate",H,P,B,A,1,0);

Mas info en ingles

Modificar ordenes con OrderModify();

En las órdenes abiertas podemos modificar el StopLoss y el TakeProfit. En las órdenes pendientes podemos modificar todos sus parámetros. Para esto utilizamos OrderModify();. Veamos  su estructura.

bool OrderModify(
              int ticket,
              double price,
              double stoploss,
              double takeprofit,
              datetime expiration,
              color arrow_color=CLR_NONE
)

La función devuelve true si se hace la modificación con éxito, si no, devuelve false.

ticket: El numero único de la orden.

price: El nuevo precio para una orden pendiente, o (no estoy seguro) un precio para una orden nueva de mercado. Aplica solo para las órdenes pendientes (creo).

stoploss: El nuevo precio para el stoploss.

takeprofit: El nuevo precio para el takeprofit.

expiration: La nueva fecha de clausura de la orden. Aplica solo para las órdenes pendientes. Si uno no quiere modificar la fecha de expiración hay que colocar 0.

arrow_color:
Definir el color de la flecha para la orden. Si se deja en blanco no ha flecha.

Para mas info en ingles http://book.mql4.com/trading/ordermodify

Cerrando órdenes opuestas con OrderCloseBy(); para ahorrar dinero

Si uno tiene dos posiciones abiertas, pero contrarias en la misma gráfica, uno puede hacer que se anulen o cierren mutuamente con OrderCloseBy();. Uno se puede ahorrar la diferencia de ganancias de las dos posiciones opuestas, dinero que no se ahorraría si se utiliza OrderClose() para cerrar una por una. Ejemplo.

Utilizando OrderClose() para cerrar una por una

Utilizando OrderCloseBy(); 

bool OrderCloseBy(
            int ticket,
            int opposite,
            color Color=CLR_NONE
);

ticket: Acá colocamos el número de identificación de la orden que queremos cerrar.

opposite: Colocamos el numero de la orden contraria.

color: El color de la flecha que indica en la grafica donde se cerraron las ordenes. Si no se coloca nada, no se muestra la flecha.

Ver mas info en ingles http://book.mql4.com/trading/orderclose

Cerrar las posiciones con OrderClose(); y OrderSelect ();

OrderClose();

Esta función se utiliza para cerrar posiciones abiertas. Si se cierra con éxito devuelve true. Si se produce algún error devuelve false.
Veamos la estructura de la función.

bool OrderClose (
                 int ticket,
                 double lots,
                 double price,
                 int slippage,
                 color Color=CLR_NONE
);

ticket: Acá debemos colocar el número de identificación de la orden que queremos cerrar. Este lo recibimos cuando crearnos la orden con OrderSend();.

lots:
La cantidad de lotes que se cerraran. Se pueden cerrar una porción de la posición, más no toda.

price:
Esta parte es muy parecida a OrdenSend();. Aca colocamos el precio al que queremos cerrar la posición, y también podemos colocar un rango de pips en los que también se cerrara la posición aunque el precio no sea exacto.  Queda mas claro viendo la explicación de OrderSend();

slippage: es el mismo slippage que el de OrderSend() pero aplicado al cierre de la posición.

Color: Es el color de la flecha que va a indicar cuándo se cerró la posición en la grafica. Si no se coloca nada no se ve ninguna flecha.

La función OrderClose(); no tiene sentido utilizarla si no tenemos la información sobre las posiciones abiertas. Por esta razón, es vital tener la información de las posiciones abiertas o tener alguna forma de conseguir esta información.

En MQL4, hay unas funciones especiales que sirven precisamente para obtener información de las posiciones abiertas o posiciones pendientes. Por ejemplo, la función OrderOpenPrice() devuelve el  precio con el que se abrió una posición o el precio de ejecución de una orden pendiente. La función OrderLots() devuelve la cantidad de lotes. OrderType() devuelve el tipo de la orden, asi etc.

Todas las funciones que nos dan información de las pociones abiertas o las posiciones pendientes, necesitan antes tener una orden seleccionada. Para esto debemos utilizar OrderSelect().

Función OrderSelect ();

Para obtener información, modificar, cerrar o eliminar posiciones abiertas o ordenes pendientes, primero debemos utilizar OrderSelect();. Por lo que he visto de código OrderSelect() literalmente hace eso, seleccionar una orden, y al hacerlo todas las demás funciones que den información, modifiquen o eliminen una orden, van a trabajar con la orden seleccionada por OrderSelect(). El proceso por el que mediante OrderSelect() se termina seleccionando una orden, funciona parecido a un tamiz, en el cual, mediante un ciclo y varias condicionales, se va filtrando un grupo de órdenes, seleccionando varias órdenes en el proceso, hasta dejar solo la orden que se quiere seleccionar. Veamos su estructura.

bool OrderSelect(
                            int index,
                            int select,
                            int pool=MODE_TRADES
);

OrderSelect(); es una función que devuelve true si se ejecuta correctamente y si no, devuelve false.

index: En este parámetro hay dos opciones. Una es colocar el número único de una orden. La segunda opción es colocar la posición o índice de la orden con respecto a una lista. Cuál de estas dos opciones se elija depende del segundo parámetro.

select: En este parámetro elegimos el tipo de índice que queremos utilizar. Solo hay dos opción que son dos constantes. SELECT_BY_POS y SELECT_BY_TICKET.

  • SELECT_BY_POS: Si colocamos SELECT_BY_POS  en select, encontraremos la orden un índice de una lista.
  • SELECT_BY_TICKET: Si elegimos SELECT_BY_POS en select, encontraremos la orden con el numero único de la orden.

pool: Este parámetro solo es útil si en select elegimos la opciones de encontrar por índice, ósea SELECT_BY_POS . Si en el segundo parámetro seleccionamos SELECT_BY_TICKET deberemos dejar en blanco este parámetro. Este parámetro sirve para seleccionar la lista en la que vamos a utilizar el índice. Solo hay dos opciones. MODE_TRADES y MODE_HISTORY

  • MODE_TRADES (por defecto): Elige la lista donde están las posiciones abiertas y posiciones pendientes.
  • MODE_HISTORY (por defecto): Elige la lista donde están las posiciones abiertas y posiciones pendientes.

Las funciónes MarketInfo(); y RefreshRates();

La función MarketInfo(); permite obtener información de las divisas disponibles. 

double MarketInfo(string symbol, int type);

En symbol colocamos el nombre de la divisa de la que queremos tener información. En type colocamos la información que necesitamos tener. MarketInfo() y RefreshRates() son dos funciones muy útiles porque ayudan a tener la información de los precios lo más actualizada posible, evitando que se generen errores por datos desactualizados. Por esta razón es de vital importancia utilizar estas dos funciones antes de utilizar OrderSend(); con el fin de hacer la orden con los datos más recientes.

Para mas info en ingles http://book.mql4.com/trading/ordersend

Gestión de errores en MQL4

Una característica muy importante de MetaTrader es que si un programa hecho en MQL4 da un error, MetaTrader no detiene este programa. Si un programa hecho en MQL4 da un error por un precio invalido o otras causas, este sigue funcionando y nos devuelve la descripción del error por medio de GetLastError().

int  GetLastError ()

La función devuelve el código del error. Si no hay error devuelve  0.  Después de devolver el error la variable last_error que es la que el devuelve se reinicia y queda en valor 0.

Todos los errores se identifican por este código. Varios errores pueden ocurrir durante la ejecución de un programa. La función GetLastError() permite obtener solo un código de error,  el error más reciente. Por esta razón, cuando uno necesita obtener el código de un posible error con GetLastError() se recomienda utilizar la función GetLastError() inmediatamente después en la siguiente línea de código de la operación que puede dar error.

Ejemplo:

int start()
{
OrderSend("GBPUSD",OP_BUY,0.1,Ask,3,Bid-15*Point,Bid+15*Point);
Alert (GetLastError());
return; // Exit start()
}

Para ver todos los códigos de todos los errores posibles ver http://book.mql4.com/appendix/errors

Para mas info en ingles http://book.mql4.com/build/errors

Abriendo posiciones con OrderSend();

Para abrir una posición hay que utilizar la función OrderSend(); La estructura de la función OrderSend() es la siguiente:

int OrderSend (
              string symbol,
              int cmd,
              double volume,
              double price,
              int slippage,
              double stoploss,
              double takeprofit,
              string comment=NULL,
              int magic=0,
              datetime expiration=0,
              color arrow_color=CLR_NONE
)

Vamos a explicar cada parte de la función OrderSend();

int OrderSend: Lo primero que vemos de esta función, es que devuelve un numero entero cuando se ejecuta. Si la orden se ejecuta exitosamente, devuelve el número de la orden. Viene a ser como el identificador único de esa orden con el que más adelante podremos modificar o cerrar esta orden. Si la orden es rechazada, la función devolverá -1. Para saber por qué se dio el error hay que utilizar la función GetLastError();.
Parámetros de OrderSend();

symbol: En este parámetro hay que colocar la divisa en la que queremos operar y tiene que ser un string. Por ejemplo, “EURUSD” “EURJPY” “USDJPY”. Pero es más fácil utilizar la función Symbol() que nos devuelve automáticamente la divisa donde está funcionando el EA.

cmd: Acá colocamos el tipo de operación que queremos efectuar. Hay unas constantes que simplifican eso, aunque también se pueden colocar los números directamente. Lo mejor es ver la tabla siguiente. Ver este link para que los conceptos queden mas claros.

Constante Valor Tipo de operacion
OP_BUY 0 Buy o compra
OP_SELL 1 Sell o venta
OP_BUYLIMIT 2 Orden pendiente BUY LIMIT
OP_SELLLIMIT 3 Orden pendiente SELL LIMIT
OP_BUYSTOP 4 Orden pendiente BUY STOP
OP_SELLSTOP 5 Orden pendiente SELL STOP


volume:
Es la cantidad de lotes con los que queremos operar.

price: Es el precio en el que vamos a comprar o vender o colocar una orden pendiente. Puede darse el caso que el precio cambio desde que se hace la petición hasta que se es aceptada. Si esto pasa la orden se rechaza. Pero para solucionar este problema hay una opción que es dar un rango de desviación del precio permitido.

slippage: slippage o desvió. Siguiendo con el parámetro anterior, “price”, uno tiene la opción de dar un rango de desviación del precio. Por ejemplo si el precio está en 1.561 y cambia un pip a 1.562 o a 1.560, uno puede dar un slippage de 1 pip para que acepte este rango de precios.

stoploss: Acá uno coloca el stop loss, ósea el precio donde uno quiere para la perdida y la posición entra en perdidas.

takeprofit: Acá uno coloca el limite o takeprofit. Ósea el precio donde uno quiere cerrar la posición en ganancia si la posición está dando beneficios.

comment: Esta no la entiendo bien. Creo que uno tiene la opción de colocar un comentario en la orden. Sea como sea, si no se coloca nada en esta opción no pasa nada, pues tiene parámetro predeterminado nulo.

magic: Decíamos que la función OrderSend() si es aceptada por el servidor, devuelve como una especie de numeró de identificación. Con el parámetro magic, pasa algo parecido. Uno puede colocar un número propio para identificar la orden.  La idea es que sea mas fácil encontrar la identificación de una orden.

expiration: Acá uno puede colocar una fecha para que se cierre la posición automáticamente. Algunos broker no permiten esto. Si se coloca 0 o se deja en blanco que es lo mismo, no pasa nada y la posición solo se cierra cuando nosotros le indiquemos.

arrow_color: Acá indicamos el color de la flecha que indica donde se abrió la posición. Si no se coloca nada o se coloca CLR_NONE que es lo mismo, no se muestra la flecha. Eso entiendo de la traducción pero nunca lo he probado.

Veamos un Ejemplo:

int start()
{
              OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Bid-15*Point, Bid+15*Point);
              return; // Exit start()
}

  1. En el primer parámetro nos pide la divisa en la que vamos a operar. Para hacerlo más fácil colocamos la función Symbol() que nos devuelve la divisa donde está funcionando el EA.
  2. Luego nos pide el tipo de operación, y le decimos que queremos comprar.
  3. En el tercer parámetro nos dice los lotes que queremos utilizar. Colocamos 0.1.
  4. En el cuarto parámetro nos pregunta el precio a que queremos comprar. Para esto le colocamos la variable estándar Ask, que nos indica el precio a que se está vendiendo.
  5. En el quinto parámetro nos pregunta el rango de pips en el que es aceptable desviarse para hacer la compra. Le colocamos 3 pips.
  6. Sexto parámetro nos pregunta el StopLoss.  Cuando le decimos Bid-15*Point le estamos diciendo que coloque el StopLoss 15 pips por debajo del precio de venta actual.
  7. Séptimo parámetro nos pide el Takeprofit. Diciendo Bid+15*Point colocamos el TakeProfit o limite 15 pips por arriba del precio de venta actual.

Cómo los últimos 4 parámetros ya tienen valores predefinidos, y son parámetros de menor importancia, podemos omitirlos.
Para ver mas info en ingles http://book.mql4.com/trading/ordersend

Conceptos basicos para crear ordenes

Antes de explicar en detalle,  hay que tener claros algunos términos.
Propiedades de los precios.

  • Precio en doble via: Es un par de precios para vender y comprar una divisa. Estos precios son fijados por el mercado y el broker.
  • Bid o compra: Es el precio en que se está comprado y es el más bajo de los dos precios.
  • Ask o venta: Es el precio en que se esta vendiendo y es el mas algo de los dos precios.
  • Pip: Es la unidad de medida del movimiento de una divisa. Es el menor movimiento que puede tener una divisa.
  • Spread: Es la diferencia entre el precio de compra y venta medida en pips.
  • Lot: Es el numero de lotes o el apalancamiento que uno quiere.
  • StopLoss: Es una orden pendiente para cerrar la posición a un precio, si se está perdiendo dinero.
  • TakeProfit: Es una orden pendiente para cerrar la posición a un precio, si se está ganando dinero.

Tipos de orden de mercado y características

Hay 6 tipos de órdenes de mercado. De esos 6 tipos de operaciones, dos son operaciones directas y cuatro son órdenes pendientes.

  1. Buy o comprar: Es una orden para comprar.
  2. Sell o Vender: Es una orden para vender.
  3. BuyLimit: Es una orden pendiente para comprar a un precio más alto que el actual.
  4. BuyStop: Es una orden pendiente para comprar a un precio más bajo que el actual.
  5. SellLimit: Es una orden pendiente para vender a un precio más alto que el actual.
  6. SellStop: Es una orden pendiente para vender a un precio más bajo que el actual.

Apertura y cierre de posiciones

Para abrir un mercado, use la función OrderSend (); para el cierre, utilice la función OrderClose ();
OrderSend (); también sirve para crear una orden pendiente de mercado, y con OrderDelete() se eliminan las ordenes pendientes.
Para modificar ordenes pendientes, stoploss y takeprofit se utiliza OrderModify ();
Mas info en ingles http://book.mql4.com/trading/orders