English Русский 中文 Deutsch 日本語 Português
Asesor Experto multiplataforma: Gestión de capital (money management)

Asesor Experto multiplataforma: Gestión de capital (money management)

MetaTrader 5Ejemplos | 28 agosto 2017, 08:00
2 704 0
Enrico Lambino
Enrico Lambino

Índice

  1. Introducción
  2. Objetivos
  3. Clase base
  4. Clases y tipos de la gestión de capital
  5. Contenedor de los objetos de la gestión de capital
  6. Ejemplo
  7. Conclusión

Introducción

La Gestión de capital (money management) es una función común en los Asesores Expertos. Ella permite que el EA determine dinámicamente el tamaño del lote para la siguiente transacción que va a abrir. En este artículo, se presentan varias clases de la gestión de capital (money management) que nos permitirán automatizar todo el proceso del cálculo del volumen comercial en el EA.

Objetivos

  • Comprender y aplicar los métodos más comunes de la gestión del capital que se utilizan en el trading
  • Permitir que el EA seleccione los métodos disponibles de la gestión de capital de la lista
  • Asegurar la compatibilidad con MQL4 y MQL5

Clase base

La clase base para todas las clases de la gestión de capital descritas en este artículo es СMoney, derivada de la clase CMoneyBase. La clase CMoneyBase se muestra en el siguiente fragmento del código:

class CMoneyBase : public CObject
  {
protected:
   bool              m_active;
   double            m_volume;
   double            m_balance;
   double            m_balance_inc;
   int               m_period;
   bool              m_equity;
   string            m_name;
   CSymbolManager   *m_symbol_man;
   CSymbolInfo      *m_symbol;
   CAccountInfo     *m_account;
   CEventAggregator *m_event_man;
   CObject          *m_container;
public:
                     CMoneyBase(void);
                    ~CMoneyBase(void);
   virtual int       Type(void) const {return CLASS_TYPE_MONEY;}
   //--- inicialización
   virtual bool      Init(CSymbolManager*,CAccountInfo*,CEventAggregator*);
   bool              InitAccount(CAccountInfo*);
   bool              InitSymbol(CSymbolManager*);
   CObject          *GetContainer(void);
   void              SetContainer(CObject*);
   virtual bool      Validate(void);
   //--- métodos de obtención y colocación
   bool              Active(void) const;
   void              Active(const bool);
   void              Equity(const bool);
   bool              Equity(void) const;
   void              LastUpdate(const datetime);
   datetime          LastUpdate(void) const;
   void              Name(const string);
   string            Name(void) const;
   double            Volume(const string,const double,const ENUM_ORDER_TYPE,const double);
   void              Volume(const double);
   double            Volume(void) const;
protected:
   virtual void      OnLotSizeUpdated(void);
   virtual bool      UpdateLotSize(const string,const double,const ENUM_ORDER_TYPE,const double);
  };

La mayoría de los métodos de la clase se encargan de la obtención o del establecimiento de diferentes miembros de la clase, y por eso no precisan explicaciones detalladas. En la aplicación práctica, solamente tres métodos tienen la importancia real: UpdateLotSize, OnLotSizeUpdated y Volume.

En el método UpdateLotSize es donde ocurre el cálculo real del volumen de trading. También es el método principal, extendido de la clase base, y por tanto, la mayoría de las diferencias entre las clases de la gestión de capital se encuentra precisamente en él. Para la clase base CMoneyBase, el método puede considerarse como virtual porque su única finalidad aquí es devolver el valor true:

bool CMoneyBase::UpdateLotSize(const string,const double,const ENUM_ORDER_TYPE,const double)
  {
   return true;
  }

A veces, después de calcular el volumen comercial, es necesario actualizar ciertos valores que serán usados para los cálculos posteriores. En estos casos se utiliza el método OnLotSizeUpdated. Se invoca automáticamente dentro del método UpdateLotSize:

void CMoneyBase::OnLotSizeUpdated(void)
  {
   m_symbol=m_symbol_man.Get();
   double maxvol=m_symbol.LotsMax();
   double minvol=m_symbol.LotsMin();
   if(m_volume<minvol)
      m_volume=minvol;
   if(m_volume>maxvol)
      m_volume=maxvol;
  }

Para obtener el valor actual del volumen comercial que ya ha sido calculado mediante la gestión de capital, el EA no necesita llamar a UpdateLotSize ni OnLotSizeUpdated. En vez de eso, se invoca el método Volume de la clase. Este método llamará automáticamente a otros dos métodos dentro de su código.

double CMoneyBase::Volume(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0)
  {
   if(!Active())
      return 0;
   if(UpdateLotSize(symbol,price,type,sl))
      OnLotSizeUpdated();
   return m_volume;
  }

Métodos de la gestión de capital


Lote fijo

Este es el método más común para determinar el volumen del lote con el que está familiarizada la mayoría de los traders. Aquí, todas las transacciones tienen un volumen de trading constante, independientemente de que si el balance o la equidad suba o baje a lo largo de tiempo.

En este tipo de la gestión de capital, necesitamos sólo el volumen fijo. De esta manera, su diferencia principal de CMoney/CMoneyBase se encuentra en el constructor donde determinamos el tamaño fijo del lote:

CMoneyFixedLotBase::CMoneyFixedLotBase(double volume)
  {
   Volume(volume);
  }

Si necesitamos cambiar dinámicamente el resultado del trabajo de este método de la gestión de capital, simplemente cambiamos su miembro de la clase m_volume llamando al método Volume.

Método de fracción fija

El método de fracción fija (o el método del riesgo fijo) supone la asignación de un determinado porcentaje del balance o la equidad como riesgo por cada operación. Este método está implementado en la librería estándar: CmoneyFixedRisk.  Si la transacción se cierra con pérdidas, el valor de esta pérdida no supera el porcentaje establecido del balance de la cuenta, en el momento de la entrada en la transacción. La pérdida aquí es definida como la pérdida máxima que puede sufrir el trader en cada operación en particular, o sea cuando las condiciones de la transacción no alcanzan el Stop Loss. La aplicación de este método exige que el Stop Loss no sea igual a cero.

El cálculo del porcentaje del riesgo está expresado en la siguiente fórmula:

Volume = (balance * account_percentage / ticks) / tick_value

donde:

  • balance — balance o equidad de la cuenta
  • account_percentage — porcentaje del riesgo máximo (rango: 0,0-1,0)
  • ticks — valor del Stop Loss expresado en ticks
  • tick_value — coste del tick en divisa del depósito (para 1 lote completo)

El tick se determina como la variación mínima posible del precio para este instrumento o par de monedas. Por ejemplo, EURUSD del bróker que usa las cotizaciones de cinco dígitos tendrá el coste del tick igual a 0,00001. Pues, es la menor variación posible para este par de divisas. Si el valor del Stop Loss está expresado en puntos o pips, el resultado será la diferencia entre el precio de entrada de la transacción y el Stop Loss en puntos o pips.

Para el mismo par de divisas, el tamaño del tick para el bróker con la cotización de cuatro dígitos va a diferenciarse del bróker con la cotización de cinco dígitos. Eso ocurre porque, en caso de cuatro dígitos, 1 tick equivale a 1 punto (o 1 pips), y en caso de cinco dígitos, 1 tick equivale a 10 puntos.

Como ejemplo de la gestión de capital con el riesgo fijo, supongamos que trabajamos con el bróker que utiliza las cotizaciones de cinco dígitos, tenemos 1 000$ en el balance, y el límite establecido del riesgo asciende a un 5% por una transacción. Supongamos que el coste del tick es de 0,1, mientras que el Stop Loss es de 200 puntos (20 pips):

Volume = (1000 * 0.05 / 200) / 0.1 = 2.5 lote

El volumen del lote calculado se aumenta dependiendo del porcentaje del riesgo y balance disponible, y se disminuye en función del tamaño del Stop Loss y valor del tick. Normalmente, el balance de la cuenta, el riesgo y el coste del tick son constantes, mientras que el Stop Loss a menudo es variable y se calcula dinámicamente. Por eso, el riesgo fijo no vale para las estrategias donde no hay límite superior para la diferencia entre el precio de entrada y el Stop Loss. El tamaño calculado del lote puede llegar a ser demasiado pequeño y el bróker puede rechazarlo. Por otro lado, un Stop Loss demasiado bajo llevará a un tamaño del lote muy grande, lo que también puede causar problemas: algunos brókers establecen el ajuste que limita el lote máximo. Este problema está prácticamente resuelto en MetaTrader 5, donde las órdenes se dividen en varias operaciones si el volumen del lote es demasiado grante. Sin embargo, en MetaTrader 4 no hay esta recurso, porque el volumen de la operación debe preparase de antemano (si hace falta, dividido en transacciones más pequeñas) para que ella pueda tener lugar, incluso si su tamaño supera el nivel máximo permitido.

La fórmula que se utiliza en los cálculos se encuentra dentro del método UpdateLotSize:

bool CMoneyFixedFractionalBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl)
  {
   m_symbol=m_symbol_man.Get(symbol);
   double last_volume=m_volume;
   if(CheckPointer(m_symbol))
     {
      double balance=m_equity==false?m_account.Balance():m_account.Equity();
      double ticks=0;
      if(price==0.0)
        {
         if(type==ORDER_TYPE_BUY)
            ticks=MathAbs(m_symbol.Bid()-sl)/m_symbol.TickSize();
         else if(type==ORDER_TYPE_SELL)
            ticks=MathAbs(m_symbol.Ask()-sl)/m_symbol.TickSize();
        }
      else ticks=MathAbs(price-sl)/m_symbol.TickSize();
      m_volume=((balance*(m_risk/100))/ticks)/m_symbol.TickValue();
     }
   return NormalizeDouble(last_volume-m_volume,2)==0;
  }

Primero, obtenemos el valor del Stop Loss. Después de eso, usamos la fórmula actual para actualizar el miembro de la clase m_volume que más tarde va a utilizarse como resultado final.

Método de proporción fija

El método de proporción fija de la gestión de capital envuelve el cálculo del volumen del lote en proporción al balance actual de la cuenta. Se puede considerarlo como un caso especial del lote fijo, a excepción de que aquí el tamaño del lote se ajusta automáticamente, y no manualmente por el trader. Si la cuenta crece, el tamaño del lote también va a aumentarse después de pasar un determinado límite. Si el balance se disminuye, por consiguiente el tamaño del lote también va a reducirse.

A diferencia de la gestión de capital con riesgo fijo, el método de proporción fija no exige un Stop Loss nulo. Eso lo hace ideal para el uso en las transacciones que no requieren un Stop Loss y cuyas salidas se realizan de manera diferente (cierre según la ganancia/pérdida en moneda del depósito, etc.).

El volumen de la transacción para este método de la gestión de capital se calcula según la siguiente fórmula:

Volume = base_volume + (balance / balance_increase) * volume_increment

donde:

  • base_volume — volumen base del lote que será adicionado al volumen total independientemente de las características de la cuenta
  • balance — balance actual en la cuenta
  • balance_increase — límite de aumento del balance en la cuenta después del cual va a ocurrir el paso del incremento del tamaño del lote
  • volume_increment — volumen de paso que será añadido al lote tras alcanzar el límite (o será restado de él).

Por ejemplo, vamos a usar el lote cero como volumen base. Va a aumentarse en 0,1 por cada 1 000 dólares en la cuenta. En este momento tenemos 2 500$ en la cuenta. El volumen total será calculado de la siguiente manera:

Volume = 0 + (2500 / 1000) * 0.1 = 0.25 lotes

Este método tiene muchas variaciones. Una de ellas es cuando el tamaño del lote se actualiza sólo en unos determinados niveles paso a paso. En el ejemplo de arriba, el volumen del lote calculado es igual a 0,25. Pero en otras ocasiones, puede permanecer algún tiempo en el nivel 0,2 del lote, y luego subir inmediatamente hasta 0,3 (en cuanto el balance alcance 3 000$).

Para este caso el método UpdateLotSize será implementado de la siguiente manera:

bool CMoneyFixedRatioBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0)
  {
   m_symbol=m_symbol_man.Get(symbol);
   double last_volume=m_volume;
   if(CheckPointer(m_symbol))
     {
      double balance=m_equity==false?m_account.Balance():m_account.Equity();      
      m_volume=m_volume_base+((int)(balance/m_balance_inc))*m_volume_inc;
      m_balance=balance;
     }
   return NormalizeDouble(last_volume-m_volume,2)==0;
  }


Riesgo fijo por un punto

El riesgo fijo por un punto trabaja de tal manera que cada punto del Stop Loss vale un determinado importe en la moneda del depósito. El algoritmo del cálculo del tamaño del lote se basa en el coste del tick necesario para el trader. Por ejemplo, si la cuenta es de dólares y el riesgo por punto es de 2.0, cada punto del Stop Loss va a costar 2$. Si el Stop Loss de la transacción es de 200 puntos, el riesgo máximo para esta transacción será de 400$ (es decir, se perderán 400$ si el mercado alcanza el nivel del Stop Loss de la transacción).

Para un trader común, el uso de este tipo de la gestión de capital es muy fácil de comprender, porque el riesgo se expresa en dinero (en la divisa del depósito). El trader simplemente necesita indicar el coste deseado del tick, y así el volumen de trading se calculará automáticamente. El coste del tick, o el cambio en la ganancia/pérdida por el movimiento mínimo del precio, permanecerá el mismo, pero el riesgo total va a depender del tamaño del Stop Loss de la operación.

Usando la fórmula para este tipo de la gestión de capital, el método UpdateLotSize será implementado de la siguiente manera:

bool CMoneyFixedRiskPerPointBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0)
  {
   m_symbol=m_symbol_man.Get(symbol);
   double last_volume=m_volume;
   if(CheckPointer(m_symbol))
     {
      double balance=m_equity==false?m_account.Balance():m_account.Equity();
      m_volume=(m_risk/m_symbol.TickValue());
     }
   return NormalizeDouble(last_volume-m_volume,2)==0;
  }


Riesgo fijo (Margen fijo)

El riesgo fijo por margen es el equivalente a la clase CMoneyFixedMargin de la Librería estándar MQL5. Prácticamente, éste es un caso particular del método de la gestión de capital descrito más arriba, riesgo fijo por punto. Sin embargo, a diferencia del riesgo fijo por punto, este método considera el valor completo del Stop Loss para calcular el volumen de la transacción, de modo que, independientemente del tamaño del Stop Loss, el riesgo permanece el mismo. En el ejemplo anterior, teníamos establecido el Stop Loss en 200 puntos, y 400$ para el riesgo máximo. Si reducimos el Stop Loss a 100 puntos, el riesgo máximo para la transacción también se reducirá en dos en caso de usar el riesgo fijo por punto, mientras que si usamos simplemente el riesgo fijo (margen fijo), el riesgo máximo quedará el mismo, 400$.

Usando esta fórmula, podemos implementar el método UpdateLotSize de la siguiente manera:

bool CMoneyFixedRiskBase::UpdateLotSize(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl)
  {
   m_symbol=m_symbol_man.Get(symbol);
   double last_volume=m_volume;
   if(CheckPointer(m_symbol))
     {
      double balance=m_equity==false?m_account.Balance():m_account.Equity();
      double ticks=0;
      if(price==0.0)
        {
         if(type==ORDER_TYPE_BUY)
            ticks=MathAbs(m_symbol.Bid()-sl)/m_symbol.TickSize();
         else if(type==ORDER_TYPE_SELL)
            ticks=MathAbs(m_symbol.Ask()-sl)/m_symbol.TickSize();
        }
      else ticks=MathAbs(price-sl)/m_symbol.TickSize();
      m_volume=(m_risk/m_symbol.TickValue())/ticks;
     }
   return NormalizeDouble(last_volume-m_volume,2)==0;
  }

La fórmula que se utiliza aquí es prácticamente idéntica a la del riesgo fijo por punto, a diferencia de que necesitamos obtener el valor de tick del Stop Loss, y luego determinar el resultado usando la fórmula anterior con este valor.


Contenedor de los objetos de la gestión de capital

Igual como las clases de la señales descritas en el artículo anterior, nuestros objetos de la gestión de capital también van a tener contenedores. Eso permitirá que el EA seleccione dinámicamente de la lista de los objetos disponibles de la gestión de capital, que han sido cargados en la plataforma. Idealmente, este contenedor va a actuar del intermediario entre las clases de la gestión de capital y el resto del código del EA. La clase base para este objeto es CMoneysBase, cuya definición viene a continuación:

class CMoneysBase : public CArrayObj
  {
protected:
   bool              m_active;
   int               m_selected;
   CEventAggregator *m_event_man;
   CObject          *m_container;
public:
                     CMoneysBase(void);
                    ~CMoneysBase(void);
   virtual int       Type(void) const {return CLASS_TYPE_MONEYS;}
   //--- inicialización
   virtual bool      Init(CSymbolManager*,CAccountInfo*,CEventAggregator*);
   CObject          *GetContainer(void);
   void              SetContainer(CObject*);
   virtual bool      Validate(void) const;
   //--- métodos del establecimiento y obtención
   virtual bool      Active(void) const;
   virtual void      Active(const bool);
   virtual int       Selected(void) const;
   virtual void      Selected(const int);
   virtual bool      Selected(const string);
   //--- cálculo del volumen
   virtual double    Volume(const string,const double,const ENUM_ORDER_TYPE,const double);
  };

Dado que este objeto ha sido diseñado para contener varios objetos de la gestión de capital, se necesitan por lo menos dos métodos para hacerlo disponible para el uso en el EA desarrollado:

  1. Selección o capacidad de cambiar dinámicamente entre los métodos de la gestión de capital
  2. Uso del objeto seleccionado de la gestión de capital y obtención del volumen de la transacción calculado para él
La selección puede implementarse de dos maneras: a través de la asignación del índice al objeto de la gestión de capital en el array de los objetos (CMoneysBase extiende CArrayObj), o encontrando el objeto seleccionado por el nombre (método Name que pertenece a la clase CMoneyBase/CMoney). A continuación, se muestra la sobrecarga del método Selected que recibe el argumento entero (o el índice):
CMoneysBase::Selected(const int value)
  {
   m_selected=value;
  }

Y éste es el método sobrecargado Selected que recibe el argumento string (nombre del objeto de la gestión de capital). Obsérvese que recibe un nombre no vacío del objeto de la gestión de capital que se asigna con el nombre Name.

bool CMoneysBase::Selected(const string select)
  {
   for(int i=0;i<Total();i++)
     {
      CMoney *money=At(i);
      if(!CheckPointer(money))
         continue;
      if(StringCompare(money.Name(),select))
        {
         Selected(i);
         return true;
        }
     }
   return false;
  }

La tercera sobrecarga del método no contiene los argumentos en absoluto. Simplemente devuelve el índice del objeto seleccionado de la gestión de capital cuando es necesario averiguar qué método está seleccionado en este momento.

int CMoneysBase::Selected(void) const
  {
   return m_selected;
  }

El volumen actual se calcula a través de este objeto usando el método Volume. Primero, el método obtiene el puntero al objeto seleccionado de la gestión de capital y luego llama a su propio método Volume. El código del método Volume para la clase CMoneysBase se muestra a continuación:
double CMoneysBase::Volume(const string symbol,const double price,const ENUM_ORDER_TYPE type,const double sl=0)
  {
   CMoney *money=At(m_selected);
   if(CheckPointer(money))
      return money.Volume(symbol,price,type,sl);
   return 0;
  }

Aquí, el método accede al objeto a través del array de objetos y lo guarda en el puntero. Para evitar los errores, hay que asegurarse de que el elemento actual al que se refiere el índice existe realmente dentro del array de objetos.

Ejemplo

Como ejemplo, vamos a usar el último ejemplo del artículo anterior. Vamos a modificarlo de la siguiente manera: incluiremos dentro las clases de la gestión de capital descritas en este artículo, las colocaremos en un contenedor separado y luego las añadiremos al gestor de órdenes. La mayoría de las adiciones van a tratar solamente con la función del EA OnInit que se muestra a continuación:

int OnInit()
  {
//--- 
   order_manager=new COrderManager();
   money_manager = new CMoneys();
   CMoney *money_fixed= new CMoneyFixedLot(0.05);
   //CMoney *money_ff= new CMoneyFixedFractional(5);
   CMoney *money_ratio= new CMoneyFixedRatio(0,0.1,1000);
   //CMoney *money_riskperpoint= new CMoneyFixedRiskPerPoint(0.1);
   //CMoney *money_risk= new CMoneyFixedRisk(100);
   
   money_manager.Add(money_fixed);
   //money_manager.Add(money_ff);
   money_manager.Add(money_ratio);
   //money_manager.Add(money_riskperpoint);
   //money_manager.Add(money_risk);
   order_manager.AddMoneys(money_manager);
   //order_manager.Account(money_manager);
   symbol_manager=new CSymbolManager();
   symbol_info=new CSymbolInfo();
   if(!symbol_info.Name(Symbol()))
      Print("symbol not set");
   symbol_manager.Add(GetPointer(symbol_info));
   order_manager.Init(symbol_manager,new CAccountInfo());

   MqlParam params[1];
   params[0].type=TYPE_STRING;
#ifdef __MQL5__
   params[0].string_value="Examples\\Heiken_Ashi";
#else
   params[0].string_value="Heiken Ashi";
#endif
   SignalHA *signal_ha=new SignalHA(Symbol(),0,1,params,signal_bar);
   SignalMA *signal_ma=new SignalMA(Symbol(),(ENUM_TIMEFRAMES) Period(),maperiod,0,mamethod,maapplied,signal_bar);
   signals=new CSignals();
   signals.Add(GetPointer(signal_ha));
   signals.Add(GetPointer(signal_ma));
   signals.Init(GetPointer(symbol_manager),NULL);
//--- 
   return(INIT_SUCCEEDED);
  }

Aquí, incluimos las líneas del código que se encargan del uso del tipo de fracción fija de la gestión de capital, riesgo fijo y riesgo fijo por punto. No obstante, en este momento nuestro EA entra sólo en las transacciones con los Stop Loss nulos, mientras que todos estos métodos requieren no nulo.  Por eso vamos a abstenernos de usarlos. Vamos a usar sólo los métodos basados en el lote fijo y proporción fija en la gestión de capital. Si estos objetos devuelven un Stop Loss no válido (menos de cero), el gestor de órdenes va a usar el volumen del lote por defecto (0,1, está disponible en el miembro m_lotsize de la clase CorderManager/COrderManagerBase).

COrderManager tiene su propio miembro de la clase que, a su vez, es el puntero al contenedor de la gestión de capital (CMoney). De esta manera, el uso de COrderManager también provocará que los archivos de cabecera de la gestión de capital serán incluidos en el código fuente. Si en el EA no se usa COrderManager, entonces la directiva #include para las clases de la gestión de capital tiene que indicarse en el código fuente.

Para la función OnTick, modificamos el EA de la siguiente manera: para las posiciones largas, el EA va a usar el tamaño fijo del lote, y para las cortas, va a calcular el tamaño del lote usando la proporción fija. Se puede conseguir eso cambiando el tipo de la gestión de capital a través del método Selected (clase CMoneys) antes de que el gestor de órdenes llame al método TradeOpen:

void OnTick()
  {
//--- 
   if(symbol_info.RefreshRates())
     {
      signals.Check();
      if(signals.CheckOpenLong())
        {
         close_last();
         //Print("Entering buy trade..");
         money_manager.Selected(0);
         order_manager.TradeOpen(Symbol(),ORDER_TYPE_BUY,symbol_info.Ask());
        }
      else if(signals.CheckOpenShort())
        {
         close_last();
         //Print("Entering sell trade..");
         money_manager.Selected(1);
         order_manager.TradeOpen(Symbol(),ORDER_TYPE_SELL,symbol_info.Bid());
        }
     }
  }

Puesto que la gestión de capital, en su esencia, es un puro cálculo, esperamos que el lote calculado sea el mismo en ambas versiones del terminal. Abajo se muestra el resultado de las pruebas del EA en MetaTrader 4 (las primeras 10 transacciones):

# Fecha/Hora Tipo Orden Volumen Precio S / L T / P Beneficio Balance
1. 2017.01.02 00:00 venta 1. 1.00 1.05100 0.00000 0.00000
2 2017.01.03 03:00 Cierre 1. 1.00 1.04679 0.00000 0.00000 419.96 10419.96
3 2017.01.03 03:00 Compra 2 0.05 1.04679 0.00000 0.00000
4 2017.01.03 10:00 Cierre 2 0.05 1.04597 0.00000 0.00000 -4.10 10415.86
5 2017.01.03 10:00 venta 3 1.00 1.04597 0.00000 0.00000
6 2017.01.03 20:00 Cierre 3 1.00 1.04285 0.00000 0.00000 312.00 10727.86
7 2017.01.03 20:00 Compra 4 0.05 1.04285 0.00000 0.00000
8 2017.01.03 22:00 Cierre 4 0.05 1.04102 0.00000 0.00000 -9.15 10718.71
9 2017.01.03 22:00 venta 5 1.00 1.04102 0.00000 0.00000
10 2017.01.04 02:00 Cierre 5 1.00 1.04190 0.00000 0.00000 -89.04 10629.67
11 2017.01.04 02:00 Compra 6 0.05 1.04190 0.00000 0.00000
12 2017.01.04 03:00 Cierre 6 0.05 1.03942 0.00000 0.00000 -12.40 10617.27
13 2017.01.04 03:00 venta 7 1.00 1.03942 0.00000 0.00000
14 2017.01.04 06:00 Cierre 7 1.00 1.04069 0.00000 0.00000 -127.00 10490.27
15 2017.01.04 06:00 Compra 8 0.05 1.04069 0.00000 0.00000
16 2017.01.05 11:00 Cierre 8 0.05 1.05149 0.00000 0.00000 54.05 10544.32
17 2017.01.05 11:00 venta 9 1.00 1.05149 0.00000 0.00000
18 2017.01.05 16:00 Cierre 9 1.00 1.05319 0.00000 0.00000 -170.00 10374.32
19 2017.01.05 16:00 Compra 10 0.05 1.05319 0.00000 0.00000
20 2017.01.06 05:00 Cierre 10 0.05 1.05869 0.00000 0.00000 27.52 10401.84

Los siguientes resultados se puede ver en MetaTrader 5 (el modo de cobertura (hedging), las primeras 10 transacciones):














Órdenes
Hora de apertura Orden Símbolo Tipo Volumen Precio S / L T / P Fecha/Hora Estado Comentario
2017.01.02 00:00:00 2 EURUSD venta 1.00 / 1.00 1.05100

2017.01.02 00:00:00 llenando
2017.01.03 03:00:00 3 EURUSD Compra 1.00 / 1.00 1.04669

2017.01.03 03:00:00 llenando
2017.01.03 03:00:00 4 EURUSD Compra 0.05 / 0.05 1.04669

2017.01.03 03:00:00 llenando
2017.01.03 10:00:00 5 EURUSD venta 0.05 / 0.05 1.04597

2017.01.03 10:00:00 llenando
2017.01.03 10:00:00 6 EURUSD venta 1.00 / 1.00 1.04597

2017.01.03 10:00:00 llenando
2017.01.03 20:00:00 7 EURUSD Compra 1.00 / 1.00 1.04273

2017.01.03 20:00:00 llenando
2017.01.03 20:00:00 8 EURUSD Compra 0.05 / 0.05 1.04273

2017.01.03 20:00:00 llenando
2017.01.03 22:00:00 9 EURUSD venta 0.05 / 0.05 1.04102

2017.01.03 22:00:00 llenando
2017.01.03 22:00:00 10 EURUSD venta 1.00 / 1.00 1.04102

2017.01.03 22:00:00 llenando
2017.01.04 02:00:00 11 EURUSD Compra 1.00 / 1.00 1.04180

2017.01.04 02:00:00 llenando
2017.01.04 02:00:00 12 EURUSD Compra 0.05 / 0.05 1.04180

2017.01.04 02:00:00 llenando
2017.01.04 03:00:00 13 EURUSD venta 0.05 / 0.05 1.03942

2017.01.04 03:00:00 llenando
2017.01.04 03:00:00 14 EURUSD venta 1.00 / 1.00 1.03942

2017.01.04 03:00:00 llenando
2017.01.04 06:00:00 15 EURUSD Compra 1.00 / 1.00 1.04058

2017.01.04 06:00:00 llenando
2017.01.04 06:00:00 16 EURUSD Compra 0.05 / 0.05 1.04058

2017.01.04 06:00:00 llenando
2017.01.05 11:00:00 17 EURUSD venta 0.05 / 0.05 1.05149

2017.01.05 11:00:00 llenando
2017.01.05 11:00:00 18 EURUSD venta 1.00 / 1.00 1.05149

2017.01.05 11:00:00 llenando
2017.01.05 16:00:00 19 EURUSD Compra 1.00 / 1.00 1.05307

2017.01.05 16:00:00 llenando
2017.01.05 16:00:00 20 EURUSD Compra 0.05 / 0.05 1.05307

2017.01.05 16:00:00 llenando
2017.01.06 05:00:00 21 EURUSD venta 0.05 / 0.05 1.05869

2017.01.06 05:00:00 llenando

Puesto que el gestor de órdenes ya se ha ocupado de la diferencia entre dos plataformas (y lenguajes), el método y el resultado del cálculo del tamaño del lotes será el mismo.

Conclusión

En este artículo se muestra cómo se puede aplicar la gestión de capital en un Asesor Experto multiplataforma. Han sido presentados cinco diferentes tipos de la gestión de capital. Además, ha sido presentado el objeto contenedor personalizado para los punteros a los objetos que se usa para la selección dinámica del método de la gestión de capital.

Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/3280

Archivos adjuntos |
mm_ha_ma.zip (1038.69 KB)
tester_results.zip (292.36 KB)
Experto comercial universal: Acceso a las propiedades de los instrumentos (parte 8) Experto comercial universal: Acceso a las propiedades de los instrumentos (parte 8)
La octava parte del artículo está dedicada a la descripción de la clase CSymbol, un objeto especial que proporciona acceso a un instrumento comercial aleatorio. Incluida en el experto comercial, esta clase proporciona un rico conjunto de propiedades de cualquier instrumento, haciendo la programación de expertos aún más sencilla y multifuncional.
Patrones disponibles al comerciar con cestas de divisas. Parte III Patrones disponibles al comerciar con cestas de divisas. Parte III
Este es el artículo final dedicado a los patrones que aparecen al comerciar con cestas de parejas de divisas. Se han analizado varios indicadores combinados de tendencia, así como la aplicación de las construcciones gráficas habituales.
El patrón Bandera El patrón Bandera
En el artículo se estudiarán los patrones de Bandera, Banderín, Cuña, Formación en Rectángulo, Triángulo decreciente, Triángulo creciente. Se analizarán sus semejanzas y diferencias, se crearán indicadores para su búsqueda en el gráfico y un indicador-probador para evaluar rápidamente su efectividad.
Optimización Walk-Forward en MetaTrader 5 con sus propias manos Optimización Walk-Forward en MetaTrader 5 con sus propias manos
En este artículo se consideran las técnicas que permiten emular con precisión la optimización walk-forward a través del Probador incorporado y librerías auxiliares implementadas en MQL.