Discusión sobre el artículo "El prototipo del Robot de trading" - página 2

 

Recomiendo evitar este diseño

//------------------------------------------------------------------ CheckNewBar
bool CExpertAdvisor::CheckNewBar()          // función de comprobar si aparece una nueva barra
  {
   MqlRates rt[2];
   if(CopyRates(m_smb,m_tf,0,2,rt)!=2)      // copiar las barras
     { Print("CopyRates of ",m_smb," failed, no history"); return(false); }
   if(rt[1].tick_volume>1) return(false);   // comprobar el volumen 
   return(true);
  }

ya que el procesamiento del tick anterior puede tardar lo suficiente como para perderse la llegada del primer tick de la nueva barra.

respectivamente, es posible que se pierda la apertura.

Es mejor vincularse a la hora de apertura de la barra, pero para ello es necesario guardar la hora anterior de la barra cero por ejemplo, para compararla con la hora actual de la barra cero.

Si es la misma, no hay nueva barra.

Si es diferente, entonces se abre al menos una nueva (siguiente) barra, tras lo cual inicializamos el tiempo guardado de la barra cero con el tiempo actual de la barra cero.

Esta construcción es más fiable.

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций - Документация по MQL5
 

Abordaremos este tema en un futuro artículo:

  • órdenes de stop-loss y take-profit *robustas* (del lado del servidor) por operación y de distinto nivel; son *necesarias* para evitar problemas asociados a las interrupciones de la red y del programa cliente (desconexiones prolongadas de la red, deslizamientos (y recotizaciones) inducidos por el retardo de la red, cierres del programa cliente o del sistema operativo, reinicios, bloqueos (ausencia prolongada de software del lado del cliente), etc.); las llamadas órdenes "virtuales" no sirven y tampoco los sustitutos que no son OCO (no, no es *negociable*, si la robustez es un requisito, las órdenes stop-loss y take-profit *deben* estar en el servidor, y si una es golpeada la otra *debe* ser eliminada *por el servidor* al mismo tiempo)
  • *recuperación robusta del estado de cada operación en caso de caída; en otras palabras, si el cliente/OS se cae (y se reinicia automáticamente) quiero que el EA sepa exactamente qué ha pasado con las operaciones y órdenes individuales pendientes mientras tanto: completadas, cerradas, aún activas, qué órdenes s/l y t/p asociadas pertenecen a qué operación/orden, etc. (no, escribir el estado en disco *no* es suficiente porque hay una condición de carrera entre la apertura de una operación y la escritura del estado en disco y el programa cliente puede bloquearse exactamente en el momento inapropiado; los comentarios de órdenes del lado del servidor podrían hacerlo, *si* fueran modificables).

Por lo que sé, MT5 sólo admite *1* (una) orden s/l y t/p del lado del servidor *por instrumento* (no por operación) y no órdenes OCO (las órdenes OCO pueden utilizarse para simular órdenes s/l y t/p por operación, pero también existe una condición de carrera en este caso). A menos que se solucione lo anterior, yo no me comprometería a invertir más de 100 $ en operaciones a través de MT5 (EAs simplistas de una sola orden, un solo marco temporal y una sola dirección de cruce de MA). Y ni siquiera estoy seguro acerca de los $ 100.

 
olyakish:

Recomiendo evitar este diseño

ya que el procesamiento del tick anterior puede tardar lo suficiente como para perderse la llegada del primer tick de la nueva barra.

respectivamente, es posible que se pierda la apertura.

Es mejor vincularse a la hora de apertura de la barra, pero para ello es necesario guardar la hora anterior de la barra cero, por ejemplo, para compararla con la hora actual de la barra cero.

Si es la misma, no hay nueva barra.

Si es diferente, entonces se abre al menos una nueva (siguiente) barra, tras lo cual inicializamos el tiempo guardado de la barra cero con el tiempo actual de la barra cero.

Este diseño es más fiable.

Yo lo he hecho así:

bool CUniexp::checkNewBar(void)
{
   static datetime prevTime[1];
   datetime currentTime[0];
   CopyTime(_Symbol,_Period,0,1,currentTime);
   if (currentTime[0]==prevTime[0])
   {return (false);}
   else
   {
      prevTime[0] = currentTime[0];
      return (true);
   }
}
 
isNewBar
isNewBar
  • votos: 7
  • 2010.05.07
  • Prival
  • www.mql5.com
Функция анализа появления нового бара на заданном таймфрейме.
 

Compila pero el depurador falla.

La carga de C:³ de programa³MetaTrader 5³MQL5³Experts³Examples³eMyEA.ex5 falló.

 
Rosh:

Se publica el nuevo artículo El prototipo de robot de comercio:

Autor: Алексей Сергеев


¡Gracias por el gran artículo! Soy un novato pero tengo una pregunta sobre el código.


En la función void CExpertAdvisor::TrailingPosition(long dir,int TS), hay una línea:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // calcular Stop Loss


¿Deberíamos usar apr tanto para el segundo como para el tercer argumento cuando llamamos a NormalSL? Yo pensaba que debería ser

sl=NormalSL(dir,op,apr,TS,StopLvl);

ya que el segundo argumento debería ser el precio de compra/venta para la dirección "especificada" (es decir, la variable op) en lugar de la dirección "inversa" (es decir, la variable apr).


Gracias.

 
echostate:


En la función void CExpertAdvisor::TrailingPosition(long dir,int TS), hay una línea:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // calcular Stop Loss


¿Deberíamos usar apr tanto para el segundo como para el tercer argumento cuando llamamos a NormalSL? Yo pensaba que debería ser

sl=NormalSL(dir,op,apr,TS,StopLvl);

no.
el segundo y tercer argumento deben ser apr.

porque el cálculo de tral se deriva del precio al que se cerrará la posición. Bid para la compra y Ask para la venta. la función es correcta.

ya que el segundo argumento debe ser el precio de compra/venta para la dirección "especificada" (es decir, la variable op) en lugar de la dirección "inversa" (es decir, la variable apr).

debería calcularse a partir de la dirección "inversa". En este caso, apr.
 
sergeev:

no.
el segundo y tercer argumento deben ser apr.

porque el cálculo de tral se deriva del precio al que se cerrará la posición. Bid para la compra y Ask para la venta. función es correcta.

debe calcularse a partir de la dirección "inversa". En este caso, apr.


Gracias por la rápida respuesta. Pensé que debía estar equivocado.


¿Puedo preguntar también en la función

double CExpertAdvisor::CountLotByRisk(int dist,double risk,double lot) // calcular lote por tamaño de riesgo
  {
   if(dist==0 || risk==0) return(lot);
   m_smbinf.Refresh();
   return(NormalLot(AccountInfoDouble(ACCOUNT_BALANCE)*risk/(dist*10*m_smbinf.TickValue())));
  }

¿por qué tenemos un "10" entre "dist" y "m_smbinf.TickValue()" en el valor de retorno? Supongo que "dist" es el stop loss (en términos de pips), y "m_smbinf.TickValue()" es el valor en dólares por pip por lote para el par de divisas. Así que no estoy seguro de por qué multiplicamos otro "10" entre ellos.

Gracias.

 
Un millón de gracias.
 

Artículo muy útil. Muchas gracias.