Discusión sobre el artículo "Biblioteca para el desarrollo rápido y sencillo de programas para MetaTrader (Parte I): Concepto, organización de datos y primeros resultados" - página 4
Gracias, está claramente explicado. Pero todavía hay una pregunta - está claro que es más rápido en MT4, pero si estamos hablando de 5 - ¿es más rápido ejecutar todos los métodos por separado que llamar a un CopyRates? Si es así, entonces tiene sentido crear una estructura/clase de barra en lugar de MQLRates, que escribiría no todos los campos, sino sólo los necesarios en nuestro caso, por máscara, por ejemplo.
Gracias, está claramente explicado. Pero todavía hay una pregunta - está claro que es más rápido en MT4, pero si estamos hablando de 5 - ¿es más rápido para ejecutar todos los métodos por separado que llamar a un CopyRates? Si es así, tiene sentido crear tu propia estructura/clase de barra en lugar de MQLRates, que escribiría no todos los campos, sino sólo los necesarios en nuestro caso, por máscara, por ejemplo.
Como se trata de una librería en desarrollo esperaré más artículos antes de hacer cualquier comentario global.
Sin embargo, me di cuenta de 2 posibles situaciones problemáticas en esta primera parte:
En primer lugar
Sometimes, you may want to get the number of decimal places in a symbol lot. Let's enter this function to our file of service functions:
//+------------------------------------------------------------------+
//| Devuelve el número de decimales en un lote de símbolos ||
//+------------------------------------------------------------------+
uint DigitsLots(conststring symbol_name)
{
return (int)ceil(fabs(log(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))/log(10)));
}
1.a La solución propuesta usando log no es universal. En algún símbolo se puede tener perfectamente un paso de volumen de 0.25 por ejemplo y DigitsLots() devolverá una respuesta errónea en tal caso.
1.b ¿Para qué quieres el "número de decimales de un lote de símbolo"? No veo ningún caso de uso real para eso.
1.c Si realmente quieres usar la función log y vas a tratar casos especiales en otro lugar, deberías usar log10, en lugar de logaritmo natural.
1.d Proporcionar dicha función en la interfaz pública podría conducir a resultados ineficientes, utiliza 5 llamadas a funciones y podría ser llamada varias veces en cada tick.
En segundo lugar.
intOnInit()
{
//---
list_all_orders.Sort();
list_all_orders.Clear();
if(!HistorySelect(0,TimeCurrent()))
{
Print(DFUN,TextByLanguage(": Не удалось получить историю сделок и ордеров",": Failed to get history of deals and orders"));
returnINIT_FAILED;
}
...
2.a Esta no es una forma correcta de llamar a HistorySelect(), podría perderse alguna información histórica ya que TimeCurrent() devuelve la última fecha de tick conocida del servidor del broker. Razonamiento desde aquí y desde la experiencia.
2.b Es un mal ejemplo usar TimeCurrent() en la función OnInit() donde no se tiene garantía de tener una conexión con el broker. En general es una mala idea hacer cualquier petición de datos en OnInit().
Gracias por los comentarios, pero esto es sólo una prueba.
Voy a considerar la posibilidad de cambiar la función a otra - completamente universal
el número de decimales para el lote de cada símbolo individual es necesario para el envío inequívoco de órdenes comerciales
Su función con log10 no tiene un problema expresado por usted con un paso de lote de 0,25?
los datos sobre el número de decimales se escriben una vez en el objeto de la clase-símbolo. Esto será más - en artículos posteriores.
Una comprobación de prueba en OnInit () es necesaria sólo para comprobar. Y sólo allí obtengo la historia de las órdenes de esta manera. En colecciones de órdenes, tratos y posiciones - de otra manera.
Todo esto en artículos posteriores.
-------------
Спасибо за комментарии, но это всего лишь тест.
я рассмотрю возможность изменения функции на иную - полностью универсальную
количество знаков после запятой для лота каждого отдельного символа нужно для безошибочной отправки торговых приказов
ваша функция с log10 не имеет озвученной вами проблемы с шагом лота 0.25 ?
данные о количестве знаков после запятой записываются единожды в объект класса-символ. Это будет далее - в последующих статьях
Тестовая проверка в OnInit() нужна всего лишь именно для проверки. И только там историю ордеров получаю таким образом. В коллекциях ордеров, сделок и позиций - иначе.
Gracias por los comentarios, pero esto es sólo una prueba.
Voy a considerar la posibilidad de cambiar la función a otra - completamente universal
el número de decimales para el lote de cada símbolo individual es necesario para el envío inequívoco de órdenes comerciales
Su función con log10 no tiene un problema expresado por usted con un paso de lote de 0,25?
los datos sobre el número de decimales se escriben una vez en el objeto de la clase-símbolo. Esto será más - en artículos posteriores.
Una comprobación de prueba en OnInit () es necesaria sólo para comprobar. Y sólo allí obtengo la historia de las órdenes de esta manera. En colecciones de órdenes, tratos y posiciones - de otra manera.
Todo esto en artículos posteriores.
1. Bien.
2. No es necesario si normaliza su lote correctamente, algo como :
3. log10 tiene el mismo problema, no es universal. Era sólo para evitar la inútil llamada a log(10).
4. Bien.
Sé que es sólo para comprobar, pero incluso con el código de prueba a disposición del público, creo que tenemos la responsabilidad de mostrar y utilizar las buenas prácticas.
2. No es necesario si normaliza su lote correctamente, algo así como :
Usar dígitos de lote sólo puede traer problemas.
3. log10 tiene el mismo problema, no es universal. Era sólo para evitar la inútil llamada a log(10).
4. Bien.
Sé que es sólo para comprobar, pero incluso con el código de prueba a disposición del público, creo que tenemos la responsabilidad de mostrar y utilizar las buenas prácticas.
Puedes considerarme tu entrante o alumno por así decirlo.
Decidí estudiar su biblioteca, pero es difícil para mí, aunque sé algo en MQL, pero me tropecé en el primer paso.
Llegué al punto Implementación del método de comparación de dos órdenes entre sí por una propiedad dada:
//+------------------------------------------------------------------+//|| Compara los objetos COrder entre sí en todas las propiedades posibles||//+------------------------------------------------------------------+int COrder::Compare(const CObject *node,constint mode=0) const
{
const COrder *order_compared=node;
//--- comparación de propiedades enteras de dos órdenesif(mode<ORDER_PROP_INTEGER_TOTAL)
{
long value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
long value_current=this.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
}
//--- comparación de propiedades reales de dos órdeneselseif(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL)
{
double value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
double value_current=this.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
}
//--- comparación de propiedades de cadena de dos órdeneselseif(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL+ORDER_PROP_STRING_TOTAL)
{
string value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_STRING)mode);
string value_current=this.GetProperty((ENUM_ORDER_PROP_STRING)mode);
return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
}
return0;
}
//+------------------------------------------------------------------+
Este es el código en la biblioteca, donde escribirlo
después de
//--- Compara los objetos COrder entre sí en todas las propiedades posiblesvirtualint Compare(const CObject *node,constint mode=0) const;
o en la clase protegida del orden abstracto.
protected:
//--- Constructor paramétrico protegido
COrder(ENUM_ORDER_STATUS order_status,constulong ticket);
//--- Obtiene y devuelve propiedades enteras de la orden seleccionada a partir de sus parámetroslong OrderMagicNumber(void) const;
long OrderTicket(void) const;
long OrderTicketFrom(void) const;
long OrderTicketTo(void) const;
long OrderPositionID(void) const;
long OrderPositionByID(void) const;
long OrderOpenTimeMSC(void) const;
long OrderCloseTimeMSC(void) const;
long OrderType(void) const;
long OrderTypeByDirection(void) const;
long OrderTypeFilling(void) const;
long OrderTypeTime(void) const;
long OrderReason(void) const;
long DealOrder(void) const;
long DealEntry(void) const;
bool OrderCloseByStopLoss(void) const;
bool OrderCloseByTakeProfit(void) const;
datetime OrderOpenTime(void) const;
datetime OrderCloseTime(void) const;
datetime OrderExpiration(void) const;
datetime PositionTimeUpdate(void) const;
datetime PositionTimeUpdateMSC(void) const;
//--- Obtiene y devuelve propiedades reales de la orden seleccionada a partir de sus parámetros: (1) precio de apertura, (2) precio de cierre, (3) beneficio,//--- (4) comisión, (5) swap, (6) volumen, (7) volumen pendiente (8) precio StopLoss, (9) precio TakeProfit (10) precio de ajuste de la orden StopLimitdouble OrderOpenPrice(void) const;
double OrderClosePrice(void) const;
double OrderProfit(void) const;
double OrderCommission(void) const;
double OrderSwap(void) const;
double OrderVolume(void) const;
double OrderVolumeCurrent(void) const;
double OrderStopLoss(void) const;
double OrderTakeProfit(void) const;
double OrderPriceStopLimit(void) const;
//--- Obtiene y devuelve propiedades de cadena de la orden seleccionada a partir de sus parámetros: (1) símbolo, (2) comentario, (3) identificador de bolsastring OrderSymbol(void) const;
string OrderComment(void) const;
string OrderExternalID(void) const;
public:
//--- Devuelve las propiedades (1) integer, (2) real y (3) string de la orden desde el array de propiedadeslong GetProperty(ENUM_ORDER_PROP_INTEGER property) const { return m_long_prop[property]; }
double GetProperty(ENUM_ORDER_PROP_DOUBLE property) const { return m_double_prop[this.IndexProp(property)]; }
string GetProperty(ENUM_ORDER_PROP_STRING property) const { return m_string_prop[this.IndexProp(property)]; }
//--- Devuelve la bandera de que la orden mantiene la propiedad dadavirtualbool SupportProperty(ENUM_ORDER_PROP_INTEGER property) { returntrue; }
virtualbool SupportProperty(ENUM_ORDER_PROP_DOUBLE property) { returntrue; }
virtualbool SupportProperty(ENUM_ORDER_PROP_STRING property) { returntrue; }
Por favor, comprended que ya no soy joven, los jóvenes pueden captar esto al vuelo.
trabajando paso a paso de acuerdo con el artículo . Usted puede estar equivocado y no entiendo.
Hay dos maneras de crear un método de clase - es directamente en el cuerpo de la clase:
class CMyClass
{
bool Flag(void) { returnfalse; }
}
y fuera del cuerpo de la clase:
class CMyClass
{
bool Flag(void);
}
//--- método implementado fuera del cuerpo de la clasebool CMyClass::Flag(void) { returnfalse; }
En el primer caso, el método se define e implementa directamente en el cuerpo de la clase - es conveniente hacerlo para métodos cortos que no ocupan muchas líneas. Pero si el método es grande, es más conveniente declararlo en el cuerpo de la clase, y poner la implementación fuera del cuerpo de la clase - como en el segundo ejemplo.
Está claro que es más conveniente escribir el método dentro del cuerpo de la clase. Pero el método sobre el que preguntas es más conveniente escribirlo separado del cuerpo de la clase.
No obstante, puede descargar todos los archivos adjuntos al artículo - ya contienen todo, están listos para usar - y utilizarlos para estudiar lo que se describe en el artículo.
Gracias, está claramente explicado. Pero todavía hay una pregunta - está claro que es más rápido en MT4, pero si estamos hablando de 5 - ¿es más rápido ejecutar todos los métodos por separado que llamar a un CopyRates? Si es así, entonces tiene sentido crear una estructura/clase de barra en lugar de MQLRates, que escribiría no todos los campos, sino sólo los necesarios en nuestro caso, por máscara, por ejemplo.
Gracias, está claramente explicado. Pero todavía hay una pregunta - está claro que es más rápido en MT4, pero si estamos hablando de 5 - ¿es más rápido para ejecutar todos los métodos por separado que llamar a un CopyRates? Si es así, tiene sentido crear tu propia estructura/clase de barra en lugar de MQLRates, que escribiría no todos los campos, sino sólo los necesarios en nuestro caso, por máscara, por ejemplo.
Pruebe esto.
¿No actualizara?
Не понял вопроса.
I do not understand the question.
Como se trata de una librería en desarrollo esperaré más artículos antes de hacer cualquier comentario global.
Sin embargo, me di cuenta de 2 posibles situaciones problemáticas en esta primera parte:
En primer lugar
Sometimes, you may want to get the number of decimal places in a symbol lot. Let's enter this function to our file of service functions:
En segundo lugar.
Gracias por los comentarios, pero esto es sólo una prueba.
Una comprobación de prueba en OnInit () es necesaria sólo para comprobar. Y sólo allí obtengo la historia de las órdenes de esta manera. En colecciones de órdenes, tratos y posiciones - de otra manera.
Todo esto en artículos posteriores.
-------------
Спасибо за комментарии, но это всего лишь тест.
Тестовая проверка в OnInit() нужна всего лишь именно для проверки. И только там историю ордеров получаю таким образом. В коллекциях ордеров, сделок и позиций - иначе.
Всё это в последующих статьях.Gracias por los comentarios, pero esto es sólo una prueba.
Una comprobación de prueba en OnInit () es necesaria sólo para comprobar. Y sólo allí obtengo la historia de las órdenes de esta manera. En colecciones de órdenes, tratos y posiciones - de otra manera.
Todo esto en artículos posteriores.
1. Bien.
2. No es necesario si normaliza su lote correctamente, algo como :
Usar dígitos de lote sólo puede traer problemas.
3. log10 tiene el mismo problema, no es universal. Era sólo para evitar la inútil llamada a log(10).
4. Bien.
Sé que es sólo para comprobar, pero incluso con el código de prueba a disposición del público, creo que tenemos la responsabilidad de mostrar y utilizar las buenas prácticas.
Leeré otros artículos.
1. Bien.
2. No es necesario si normaliza su lote correctamente, algo así como :
Usar dígitos de lote sólo puede traer problemas.
3. log10 tiene el mismo problema, no es universal. Era sólo para evitar la inútil llamada a log(10).
4. Bien.
Sé que es sólo para comprobar, pero incluso con el código de prueba a disposición del público, creo que tenemos la responsabilidad de mostrar y utilizar las buenas prácticas.
Leeré otros artículos.
Hola
Puedes considerarme tu entrante o alumno por así decirlo.
Decidí estudiar su biblioteca, pero es difícil para mí, aunque sé algo en MQL, pero me tropecé en el primer paso.
Llegué al punto Implementación del método de comparación de dos órdenes entre sí por una propiedad dada:
Este es el código en la biblioteca, donde escribirlo
después de
o en la clase protegida del orden abstracto.
Por favor, comprended que ya no soy joven, los jóvenes pueden captar esto al vuelo.
Y también he abierto un tema en el foro en Artículos y biblioteca técnica en el comercio automatizado (12560) Soy un estudiante allí voy a duplicar este tema me gustaría una respuesta de usted en detalle acerca de la estructura,
trabajando paso a paso de acuerdo con el artículo . Usted puede estar equivocado y no entiendo.
Hola
Puedes considerarme tu aspirante o alumno por así decirlo.
He decidido estudiar su biblioteca, pero es difícil para mí, aunque sé algo en MQL, pero me tropecé en el primer paso.
Llegué al punto Realización del método de comparación de dos órdenes entre sí por una propiedad dada:
Este es el código en la biblioteca, donde escribirlo
después de
o en la clase protegida del orden abstracto
Por favor, comprenda que ya no soy joven, pero los jóvenes pueden entenderlo al vuelo.
Y también he abierto un tema en el foro en Artículos y biblioteca técnica sobre el comercio automatizado (12560) Soy un estudiante allí voy a duplicar este tema me gustaría una respuesta detallada de usted acerca de la estructura,
trabajando paso a paso de acuerdo con el artículo . Usted puede estar equivocado y no entiendo.
Hay dos maneras de crear un método de clase - es directamente en el cuerpo de la clase:
y fuera del cuerpo de la clase:
En el primer caso, el método se define e implementa directamente en el cuerpo de la clase - es conveniente hacerlo para métodos cortos que no ocupan muchas líneas. Pero si el método es grande, es más conveniente declararlo en el cuerpo de la clase, y poner la implementación fuera del cuerpo de la clase - como en el segundo ejemplo.
Está claro que es más conveniente escribir el método dentro del cuerpo de la clase. Pero el método sobre el que preguntas es más conveniente escribirlo separado del cuerpo de la clase.
No obstante, puede descargar todos los archivos adjuntos al artículo - ya contienen todo, están listos para usar - y utilizarlos para estudiar lo que se describe en el artículo.