Discusión sobre el artículo "LifeHack para tráders: cocinamos ForEach usando #define"

 

Artículo publicado LifeHack para tráders: cocinamos ForEach usando #define:

Un escalón intermedio para aquellos que aún escriben en MQL4, pero todavía no han dado el salto a MQL5. Vamos a continuar buscando posibilidades para escribir código en el estilo MQL4. En esta ocasión, analizaremos la macrosustitución del preprocesador - #define.

La creación de asesores o robots comerciales requiere casi siempre de mucho trabajo con los ciclos. Los ciclos nos rodean por todas partes: la iteración de órdenes, de transacciones en la historia, de objetos en el gráfico, de símbolos en la Observación del mercado, de barras en el búfer de indicador. Y para facilitar un poco la vida del programador, al MetaEditor se han añadido los snippets : una característica que permite al usuario introducir los símbolos iniciales y desplegar estos en un pequeño fragmento de código pulsando la tecla Tab. Aquí vemos cómo funciona un snippet para el ciclo for:


No está mal, pero no satisface todas nuestras necesidades. Un ejemplo más sencillo: tenemos que iterar todos los símbolos en la Observación de mercado.

Autor: Vladimir Karputov

 
A la hucha

Foro sobre trading, sistemas automatizados de trading y prueba de estrategias de trading

Bibliotecas: CDouble & CDoubleVector

amrali, 2018.02.12 23:53

#define  forEach(element, array)  for (int __i = 0, __max = ArraySize((array)); __i < __max && ((element) = array[__i]) == (element); __i++)
Hay que embutir todo en los internos de for, para poder llamar a forEach repetidamente. Sino será un coñazo con variables redefinidas.
 
HistorySelect antes que TimeCurrent es un error típico. Como el significado de las afirmaciones para alguien puede depender del autor, he aquí un conjunto de citas

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading

FORTS. Preguntas sobre la ejecución

Renat Fatkhullin, 2015.02.10 08:16

Todavía no he ejecutado el código, pero el código fuente muestra el clásico error de fecha final incorrecta en HistorySelect.

Cada primer programador llama a esta función con fecha incorrecta, constantemente merienda el final de la historia y detecta "comercio de mucho tiempo entrar en la historia".

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading

FORTS. Preguntas sobre la ejecución

Renat Fatkhullin, 2015.02.10 09:15

El error es que la gente no piensa en cuál es el momento actual y sustituye la fecha equivocada tomada de la fuente equivocada.

Basta con especificar una fecha lejana conocida como la fecha final, no el serverTime obsoleto.

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading

FORTS. Preguntas sobre la ejecución

Renat Fatkhullin, 2015.02.10 13:56

Tanto la fecha de inicio como la de finalización deben fijarse con la realización de errores y con un margen obligatorio. Es decir, menos N seg y más N seg como mínimo.

TimeTradeServer() no tiene precisión rltime, sino que se actualiza únicamente con los ticks de precios que llegan a la revisión del mercado.


Si de repente no tiene datos en la muestra del historial, significa en un 99% que el error está en los límites de la consulta.

HistorySelect(0, LONG_MAX);
 

Предопределённые переменные _XXXX переводятся в функции MQL5 при помощи беспараметрической формы #define:

//--- la variable _Digits almacena el número de dígitos después del punto decimal,
#define _Digits         Digits()
¿Por qué? Además, con una macro de este tipo no se puede utilizar _Digits como parámetro de entrada de algunas funciones. Es decir, el código dejará de funcionar.
 
//--- el último precio vendedor conocido (precio ask) para el símbolo actual 
double GetAsk()
  {
   MqlTick tick;
   SymbolInfoTick(Symbol(),tick);
   return(tick.ask);
  }

¡Terriblemente caro! Si realmente quieres hacerlo a través de la estructura, por lo menos deberías haberlo hecho. Y no hay ninguna comprobación por alguna razón.

SymbolInfoDouble es totalmente compatible con MT4.

 
#define IsTradeContextBusy  true

¿Eh?

¿Quizás falso?
 
Para MarketInfo es mejor utilizar el enfoque a través de enumeraciones + sobrecargas

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading.

Asesores Expertos: Quantum 103

fxsaber, 2017.09.26 09:55 pm.

bool RefreshRates( void ) { return(true); }

double MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_DOUBLE Property )  { return(SymbolInfoDouble(Symb, Property)); }
int    MarketInfo( const string Symb, const ENUM_SYMBOL_INFO_INTEGER Property ) { return((int)SymbolInfoInteger(Symb, Property)); }

bool IsTesting(void)            { return(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)); }
bool IsTradeContextBusy( void ) { return(false); }
bool IsTradeAllowed(void)       { return(MQLInfoInteger(MQL_TRADE_ALLOWED)); }
bool IsExpertEnabled(void)      { return(AccountInfoInteger(ACCOUNT_TRADE_EXPERT)); }

int    ObjectFind( const string Name )   { return(ObjectFind(0, Name)); }
int    ObjectsTotal( void )              { return(ObjectsTotal(0)); }
bool   ObjectDelete( const string Name ) { return(ObjectDelete(0, Name)); }
string ObjectName( const int Pos )       { return(ObjectName(0, Pos)); }

double AccountFreeMarginCheck(const string Symb,const int Cmd,const double dVolume)
{
 double Margin;

 return(OrderCalcMargin((ENUM_ORDER_TYPE)Cmd, Symb, dVolume,
        SymbolInfoDouble(Symb, (Cmd == ORDER_TYPE_BUY) ? SYMBOL_ASK : SYMBOL_BID), Margin) ?
        AccountInfoDouble(ACCOUNT_MARGIN_FREE) - Margin : -1);
}

#define False false
#define True  true

#define Digits _Digits
#define Point  _Point

#define MODE_BID       SYMBOL_BID
#define MODE_ASK       SYMBOL_ASK
#define MODE_POINT     SYMBOL_POINT
#define MODE_DIGITS    SYMBOL_DIGITS
#define MODE_STOPLEVEL SYMBOL_TRADE_STOPS_LEVEL
#define MODE_SPREAD    SYMBOL_SPREAD

#define StrToTime    StringToTime
#define StrToInteger StringToInteger
#define TimeToStr    TimeToString
#define DoubleToStr  DoubleToString

#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID)
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
 
Sólo faltan las funciones simplificadas de comercio de MQL4 para la compatibilidad completa. Pero incluso este problema se puede resolver si se desea.
Para ello, es necesario comprender muy bien ambas arquitecturas. No todo sigue siendo obvio.
 

fxsaber:
В копилку

#define  forEach(element, array)  for (int __i = 0, __max = ArraySize((array)); __i < __max && ((element) = array[__i]) == (element); __i++)

Técnica interesante y no obvia )

[Eliminado]  

¿Cuántas cosas retorcidas puedes hacer?

Definir es una estúpida sustitución de un texto por otro. ¡No hay poder en ellos!

Mejor intenta hacer lo mismo con las plantillas.

 
Koldun Zloy:

¿Cuántas veces se puede hacer esto?

Definir es una estúpida sustitución de un texto por otro. ¡No hay poder en ellos!

Escribir menos a veces es conveniente

Mejor intentar hacer lo mismo en las plantillas.

Es sólo una cuestión de viabilidad, usabilidad y rendimiento.