- Obtener símbolos disponibles y listas de Observación de Mercado
- Editar la lista de Observación de Mercado
- Comprobar la existencia de un símbolo
- Comprobar la pertinencia de los datos de los símbolos
- Obtener el último tick de un símbolo
- Horarios de sesiones de trading y cotización
- Coeficientes de margen de los símbolos
- Visión general de las funciones para obtener las propiedades de los símbolos
- Comprobar el estado de los símbolos
- Tipo de precio para construir gráficos de símbolos
- Divisas base, de cotización y de margen del instrumento
- Precisión de la representación de precios y pasos de cambio
- Volúmenes permitidos de operaciones de trading
- Permiso de trading
- Condiciones de trading de símbolos y modos de ejecución de órdenes
- Requisitos de margen
- Reglas de vencimiento de órdenes pendientes
- Diferenciales y distancia de orden del precio actual
- Obtener tamaños de swap
- Información actual sobre el mercado (tick)
- Propiedades descriptivas de los símbolos
- Profundidad de Mercado
- Propiedades personalizadas de símbolos
- Propiedades específicas (bolsa, derivados, bonos)
Requisitos de margen
Una de las informaciones más importantes sobre un instrumento financiero para un operador es la cantidad de fondos necesarios para abrir una posición. Sin saber cuánto dinero se necesita para comprar o vender un número determinado de lotes, es imposible implementar un sistema de gestión de dinero dentro de un Asesor Experto y controlar el saldo de la cuenta.
Dado que MetaTrader 5 se utiliza para operar diversos instrumentos (divisas, materias primas, acciones, bonos, opciones y futuros), los principios de cálculo del margen difieren significativamente. La documentación proporciona detalles, en particular para el mercado de divisas y futuros, así como mercados bursátiles.
Varias propiedades de la API de MQL5 permiten definir el tipo de mercado y el método de cálculo del margen para un instrumento concreto.
Supongamos que, para una determinada combinación de parámetros, como el tipo de operación de trading, el instrumento, el volumen y el precio, MQL5 le permite calcular el margen utilizando la función OrderCalcMargin. Este es el método más sencillo, pero tiene una limitación importante: la función no tiene en cuenta las posiciones abiertas actuales ni las órdenes pendientes. Esto, en particular, ignora los posibles ajustes por solapamiento de volúmenes cuando se permiten posiciones opuestas en la cuenta.
Así, para obtener un desglose de los fondos de la cuenta utilizados actualmente como margen para las órdenes y posiciones abiertas, un programa MQL puede necesitar analizar las siguientes propiedades y cálculos mediante fórmulas. Además, está prohibido utilizar la función OrderCalcMargin en los indicadores. Puede estimar el margen libre por adelantado después de que se complete la transacción propuesta utilizando OrderCheck.
Identificador |
Descripción |
---|---|
SYMBOL_TRADE_CALC_MODE |
El método para calcular el margen y el beneficio (véase ENUM_SYMBOL_CALC_MODE) |
SYMBOL_MARGIN_HEDGED_USE_LEG |
Bandera booleana para activar (true) o desactivar (false) el modo de cálculo del margen de cobertura para la mayor de las posiciones solapadas (compra y venta). |
SYMBOL_MARGIN_INITIAL |
Margen inicial de un instrumento bursátil |
SYMBOL_MARGIN_MAINTENANCE |
Margen de mantenimiento de un instrumento bursátil |
SYMBOL_MARGIN_HEDGED |
Tamaño del contrato o margen para un lote de posiciones cubiertas (posiciones opuestas para un símbolo) |
Las dos primeras propiedades están incluidas en la enumeración ENUM_SYMBOL_INFO_INTEGER, y las tres últimas en ENUM_SYMBOL_INFO_DOUBLE, y pueden ser leídas, respectivamente, por las funciones SymbolInfoInteger y SymbolInfoDouble.
Las fórmulas específicas de cálculo de márgenes dependen de la propiedad SYMBOL_TRADE_CALC_MODE y se muestran en la tabla que aparece más abajo. Encontrará información más completa en Documentación MQL5.
Tenga en cuenta que los márgenes inicial y de mantenimiento no se utilizan para los instrumentos Forex, y estas propiedades son siempre 0 para ellos.
El margen inicial indica el importe del depósito de garantía exigido en la divisa de margen para abrir una posición con un volumen de un lote. Se utiliza cuando se comprueba la suficiencia de los fondos del cliente antes de entrar en el mercado. Para obtener el importe final del margen cobrado en función del tipo y la dirección de la orden, compruebe los coeficientes de margen utilizando la función SymbolInfoMarginRate. Así, el bróker puede establecer un apalancamiento o descuento individual para cada instrumento.
El margen de mantenimiento indica el valor mínimo de fondos en la divisa del margen del instrumento para mantener una posición abierta de un lote. Se utiliza al comprobar la suficiencia de fondos del cliente cuando cambia el estado de la cuenta (condiciones de trading). Si el nivel de fondos cae por debajo del importe del margen de mantenimiento de todas las posiciones, el bróker comenzará a cerrarlas a la fuerza.
Si la propiedad de margen de mantenimiento es 0, se utiliza el margen inicial. Al igual que en el caso del margen inicial, para obtener el importe final del margen cobrado en función del tipo y la dirección, deberá comprobar los coeficientes de margen utilizando la función SymbolInfoMarginRate.
Las posiciones de cobertura, es decir, las posiciones multidireccionales para un mismo símbolo, sólo pueden existir en cuentas de cobertura en trading. Obviamente, el cálculo del margen de cobertura junto con las propiedades SYMBOL_MARGIN_HEDGED_USE_LEG, SYMBOL_MARGIN_HEDGED sólo tiene sentido en dichas cuentas. El margen de cobertura se aplica al volumen cubierto.
El bróker puede elegir para cada instrumento uno de los dos métodos existentes para calcular el margen de las posiciones cubiertas:
- El cálculo base se aplica cuando el modo de cálculo del lado más largo está desactivado, es decir, la propiedad SYMBOL_MARGIN_HEDGED_USE_LEG es igual a false. En este caso, el margen consta de tres componentes: el margen para el volumen descubierto de la posición existente, el margen para el volumen cubierto (si hay posiciones opuestas y la propiedad SYMBOL_MARGIN_HEDGED es distinta de cero), el margen para órdenes pendientes. Si se establece el margen inicial para el instrumento (la propiedad SYMBOL_MARGIN_INITIAL es distinta de cero), entonces el margen de cobertura se especifica como un valor absoluto (en dinero). Si no se fija el margen inicial (igual a 0), entonces SYMBOL_MARGIN_HEDGED especifica el tamaño del contrato que se utilizará al calcular el margen según la fórmula correspondiente al tipo de instrumento de trading (SYMBOL_TRADE_CALC_MODE).
- El cálculo de la posición más alta se aplica cuando la propiedad SYMBOL_MARGIN_HEDGED_USE_LEG es igual a true. El valor de SYMBOL_MARGIN_HEDGED se ignora en este caso. En lugar de ello se calcula el volumen de todas las posiciones cortas y largas en el instrumento, y se calcula el precio medio ponderado de apertura para cada lado. Además, utilizando las fórmulas correspondientes al tipo de instrumento (SYMBOL_TRADE_CALC_MODE), se calcula el margen para el lado corto y el lado largo. El valor mayor se utiliza como valor final.
En la siguiente tabla se enumeran los elementos ENUM_SYMBOL_CALC_MODE y sus respectivos métodos de cálculo de márgenes. La misma propiedad (SYMBOL_TRADE_CALC_MODE) es también responsable de calcular el beneficio/pérdida de una posición, pero consideraremos este aspecto más adelante, en el capítulo sobre las funciones de trading de MQL5.
Identificador |
Fórmula |
---|---|
SYMBOL_CALC_MODE_FOREX Forex |
Lots * ContractSize * MarginRate / Leverage |
SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE Forex without leverage |
Lots * ContractSize * MarginRate |
SYMBOL_CALC_MODE_CFD CFD |
Lots * ContractSize * MarketPrice * MarginRate |
SYMBOL_CALC_MODE_CFDLEVERAGE CFD with leverage |
Lots * ContractSize * MarketPrice * MarginRate / Leverage |
SYMBOL_CALC_MODE_CFDINDEX CFDs on indices |
Lots * ContractSize * MarketPrice * TickPrice / TickSize * MarginRate |
SYMBOL_CALC_MODE_EXCH_STOCKS Securities on the stock exchange |
Lots * ContractSize * LastPrice * MarginRate |
SYMBOL_CALC_MODE_EXCH_STOCKS_MOEX Securities on MOEX |
Lots * ContractSize * LastPrice * MarginRate |
SYMBOL_CALC_MODE_FUTURES Futures |
Lots * InitialMargin * MarginRate |
SYMBOL_CALC_MODE_EXCH_FUTURES Futures on the stock exchange |
Lots * InitialMargin * MarginRate or |
SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS Futures on FORTS |
Lots * InitialMargin * MarginRate or |
SYMBOL_CALC_MODE_EXCH_BONDS Bonds on the stock exchange |
Lots * ContractSize * FaceValue * OpenPrice / 100 |
SYMBOL_CALC_MODE_EXCH_BONDS_MOEX Bonds on MOEX |
Lots * ContractSize * FaceValue * OpenPrice / 100 |
SYMBOL_CALC_MODE_SERV_COLLATERAL |
Activo no negociable (margen no aplicable) |
En las fórmulas se utiliza la siguiente notación:
- Lots: posición o volumen de la orden en lotes (acciones del contrato).
- ContractSize: tamaño del contrato (un lote, SYMBOL_TRADE_CONTRACT_SIZE)
- Leverage: apalancamiento de la cuenta de trading (ACCOUNT_LEVERAGE)
- InitialMargin: margen inicial (SYMBOL_MARGIN_INITIAL)
- MaintenanceMargin: margen de mantenimiento (SYMBOL_MARGIN_MAINTENANCE)
- TickPrice: precio del tick (SYMBOL_TRADE_TICK_VALUE)
- TickSize: tamaño del tick (SYMBOL_TRADE_TICK_SIZE)
- MarketPrice: el último precio Bid/Ask conocido en función del tipo de transacción
- LastPrice: el último precio Last conocido
- OpenPrice: precio medio ponderado de apertura de una posición u orden
- FaceValue: valor nominal del bono
- MarginRate: coeficiente de margen según la función SymbolInfoMarginRate; puede tener también dos valores diferentes: para el margen inicial y para el margen de mantenimiento.
Encontrará una implementación alternativa de los cálculos de la fórmula para la mayoría de los tipos de símbolos en el archivo MarginProfitMeter.mqh (véase la sección Estimación del beneficio de una operación de trading) que también puede utilizarse en indicadores.
Formulemos un par de comentarios sobre algunos modos.
En la tabla anterior, sólo tres de las fórmulas de futuros utilizan el margen inicial (SYMBOL_MARGIN_INITIAL). Sin embargo, si esta propiedad tiene un valor distinto de cero en la especificación de cualquier otro símbolo, entonces determina el margen.
Algunas bolsas pueden imponer sus propias especificidades en el ajuste de márgenes, como el sistema de descuento para FORTS (SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS). Consulte la documentación de MQL5 y a su bróker para obtener más detalles.
En el modo SYMBOL_CALC_MODE_SERV_COLLATERAL, el valor de un instrumento se tiene en cuenta en los Activos, que se suman al Capital (Equity). Por lo tanto, las posiciones abiertas en dicho instrumento aumentan el importe del Margen Libre y sirven como garantía adicional para las posiciones abiertas en instrumentos negociados. El valor de mercado de una posición abierta se calcula en función del volumen, el tamaño del contrato, el precio actual de mercado y el coeficiente de liquidez: Lots * ContractSize * MarketPrice * LiquidityRate (este último valor puede obtenerse como la propiedad SYMBOL_TRADE_LIQUIDITY_RATE).
Como ejemplo de trabajo con propiedades relacionadas con los márgenes, vea el script SymbolFilterMarginStats.mq5. Su objetivo será calcular estadísticas sobre los métodos de cálculo de márgenes en la lista de símbolos seleccionados, así como, opcionalmente, registrar estas propiedades para cada símbolo. Seleccionaremos los símbolos para el análisis utilizando la clase de filtro ya conocida SymbolFilter y las condiciones para ello suministradas a partir de las variables de entrada.
#include <MQL5Book/SymbolFilter.mqh>
|
Por defecto, se solicita información para todos los símbolos disponibles. Para limitar el contexto únicamente a la visión general del mercado, debemos fijar UseMarketWatch en true.
El parámetro ShowPerSymbolDetails permite activar la salida de información detallada sobre cada símbolo (por defecto, el parámetro es false, y sólo se muestran estadísticas).
Los tres últimos parámetros sirven para filtrar los símbolos según las condiciones de los valores de margen cero (inicial, de mantenimiento y de cobertura, respectivamente).
Para recoger y mostrar convenientemente en el registro un conjunto completo de propiedades para cada símbolo (cuando ShowPerSymbolDetails está activada), se define en el código la estructura MarginSettings.
struct MarginSettings
|
Dado que algunas de las propiedades son de enteros (SYMBOL_TRADE_CALC_MODE, SYMBOL_MARGIN_HEDGED_USE_LEG), y algunas de reales (SYMBOL_MARGIN_INITIAL, SYMBOL_MARGIN_MAINTENANCE, SYMBOL_MARGIN_HEDGED), el objeto de filtro tendrá que solicitarlas por separado.
Ahora vamos directamente al código de trabajo en OnStart. Aquí, como de costumbre, definimos el objeto de filtro (f), los arrays de salida para los nombres de los caracteres (symbols) y los valores de las propiedades solicitadas (flags,values). Además de ellas, añadimos un array de estructuras MarginSettings.
void OnStart()
|
Se ha introducido el mapa del array stats para calcular estadísticas con una clave como ENUM_SYMBOL_CALC_MODE y el valor entero int para el número de veces que se ha encontrado cada método. Además, todos los casos de margen cero y el modo de cálculo habilitado en el tramo más largo deben registrarse en las variables del contador correspondientes.
MapArray<ENUM_SYMBOL_CALC_MODE,int> stats; // counters for each method/mode
|
A continuación, especificamos las propiedades que nos interesan relacionadas con el margen, que se leerán de la configuración del símbolo. Primero, los enteros del array ints y luego, los reales del array doubles.
ENUM_SYMBOL_INFO_INTEGER ints[] =
|
En función de los parámetros de entrada, estableceremos las condiciones de filtrado.
if(ExcludeZeroInitMargin) f.let(SYMBOL_MARGIN_INITIAL, 0, SymbolFilter::IS::GREATER);
|
Ahora todo está listo para seleccionar símbolos por condiciones y obtener sus propiedades en arrays. Lo hacemos dos veces, por un lado para las propiedades de enteros y por otro, para las de reales.
f.select(UseMarketWatch, ints, symbols, flags);
|
Un array con símbolos debe ponerse a cero después de la primera aplicación del filtro para que los nombres no se dupliquen. A pesar de tratarse de dos consultas distintas, el orden de los elementos en todos los arrays de salida (ints y doubles) es el mismo, ya que las condiciones de filtrado no cambian.
Si el usuario activa un registro detallado, asignamos memoria para el array de estructuras margins.
if(ShowPerSymbolDetails) ArrayResize(margins, n); |
Por último, calculamos las estadísticas iterando sobre todos los elementos de los arrays resultantes y, opcionalmente, rellenamos el array de estructuras.
for(int i = 0; i < n; ++i)
|
Ahora mostramos las estadísticas en el registro.
PrintFormat("===== Margin calculation modes for %s symbols %s=====",
|
Dado que los miembros de la enumeración ENUM_SYMBOL_CALC_MODE se muestran como números enteros (lo cual no es muy informativo), mostramos también un texto en el que cada valor tiene un nombre (de EnumToString).
Print("Legend: key=calculation mode, value=count");
|
Si se necesita información detallada sobre los caracteres seleccionados, se emite el array de estructuras margins.
if(ShowPerSymbolDetails)
|
Vamos a ejecutar el script un par de veces con diferentes configuraciones. Empecemos con la configuración por defecto.
===== Margin calculation modes for all available symbols =====
|
Para la segunda ejecución, establezcamos ShowPerSymbolDetails y ExcludeZeroInitMargin en true. Así se solicita información detallada sobre todos los símbolos que tienen un valor distinto de cero del margen inicial.
===== Margin calculation modes for all available symbols (with conditions) =====
|