Discussion of article "Library for easy and quick development of MetaTrader programs (part I). Concept, data management and first results" - page 4

 
fxsaber:

Thank you, it is clearly explained. But still there is a question - it is clear that it is faster in MT4, but if we are talking about 5 - is it faster to execute all methods separately than to call one CopyRates? If yes, then it makes sense to create a bar structure/class instead of MQLRates, which would write not all fields, but only the necessary ones in our case, by mask, for example.

 
alex_all:

Thank you, it is clearly explained. But still there is a question - it is clear that it is faster in MT4, but if we are talking about 5 - is it faster to execute all methods separately than to call one CopyRates? If yes, it makes sense to create your own bar structure/class instead of MQLRates, which would write not all fields, but only the necessary ones in our case, by mask, for example.

Try this.

 
No update?
 
soldadoraso21:
Won't you update?

Не понял вопроса.

I do not understand the question.

 

As it is a library in development I will wait further articles before doing any global remark.

However I noticed 2 potential problematic situations in this first part :

Firstly.

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:

//+------------------------------------------------------------------+
//| Return the number of decimal places in a symbol lot              |
//+------------------------------------------------------------------+
uint DigitsLots(conststring symbol_name) 
  { 
   return (int)ceil(fabs(log(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))/log(10)));
  }

1.a The proposed solution using log is not universal. On some symbol you can perfectly have a volume step of 0.25 for example and the DigitsLots() will return a wrong answer in such case.

1.b Why would you want the "number of decimal places in a symbol lot" ? I don't see any real use case for that.

1.c If you really want to use log function and you will deal with special cases somewhere else, you should use log10, instead of natural logarithm.

return (int)ceil(fabs(log10(SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_STEP))));

1.d Providing such function on the public interface could lead to inefficient results, it uses 5 function calls and could be called several times on each tick.


Secondly.

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 This is not a correct way to call HistorySelect(), you could miss some history information as TimeCurrent() returns the last know tick date from the broker server. Rationale from here and from experience.

2.b It's a bad example to use TimeCurrent() in OnInit() function where you have no guarantee to have a broker connection. In general it's a bad idea to do any data request in OnInit().

 

Thanks for the comments, but this is just a test.

  1. I will consider the possibility of changing the function to another - completely universal
  2. the number of decimal places for the lot of each individual symbol is necessary for the unmistakable sending of trade orders
  3. Your function with log10 does not have a problem voiced by you with a lot step of 0.25?
  4. data on the number of decimal places is written once to the object of the class-symbol. This will be further - in subsequent articles.

A test check in OnInit () is needed just for checking. And only there I get the history of orders in this way. In collections of orders, deals and positions - otherwise.

All this in subsequent articles.

-------------

Спасибо за комментарии, но это всего лишь тест.

  1. я рассмотрю возможность изменения функции на иную - полностью универсальную
  2. количество знаков после запятой для лота каждого отдельного символа нужно для безошибочной отправки торговых приказов
  3. ваша функция с log10 не имеет озвученной вами проблемы с шагом лота 0.25 ?
  4. данные о количестве знаков после запятой записываются единожды в объект класса-символ. Это будет далее - в последующих статьях

Тестовая проверка в OnInit() нужна всего лишь именно для проверки. И только там историю ордеров получаю таким образом. В коллекциях ордеров, сделок и позиций - иначе.

Всё это в последующих статьях.
 
Artyom Trishkin:

Thanks for the comments, but this is just a test.

  1. I will consider the possibility of changing the function to another - completely universal
  2. the number of decimal places for the lot of each individual symbol is necessary for the unmistakable sending of trade orders
  3. Your function with log10 does not have a problem voiced by you with a lot step of 0.25?
  4. data on the number of decimal places is written once to the object of the class-symbol. This will be further - in subsequent articles.

A test check in OnInit () is needed just for checking. And only there I get the history of orders in this way. In collections of orders, deals and positions - otherwise.

All this in subsequent articles.


1. Good.

2. It's not needed if you normalize your lot correctly, something like :

 double lotStep=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
 lots=MathRound(lots/lotStep)*lotStep;

Using lot digits can only lead to problem.

3. log10 has the same problem, it's not universal. It was just to avoid the useless call to log(10).

4. Good.

I know it's only to check but even with test code publicly available, I think we have a responsibility to show and use good practices.

I will read other articles.

 
Alain Verleyen:

1. Good.

2. It's not needed if you normalize your lot correctly, something like :

Using lot digits can only lead to problem.

3. log10 has the same problem, it's not universal. It was just to avoid the useless call to log(10).

4. Good.

I know it's only to check but even with test code publicly available, I think we have a responsibility to show and use good practices.

I will read other articles.

OK. Thanks
 

Hello

You can consider me your entrant or student so to speak.

I decided to study your library, but it is difficult for me, although I know something in MQL, but I stumbled on the first step.

I came to the point Implementation of the method of comparing two orders with each other by a given property:

//+------------------------------------------------------------------+
//|| Compares COrder objects with each other on all possible properties|
//+------------------------------------------------------------------+
int COrder::Compare(const CObject *node,const int mode=0) const
  {
   const COrder *order_compared=node;
//--- comparison of integer properties of two orders
   if(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);
     }
//--- comparison of real properties of two orders
   else if(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);
     }
//--- comparison of string properties of two orders
   else if(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);
     }
   return 0;
  }
//+------------------------------------------------------------------+

This is the code in the library, where to write it

after

   //--- Compares COrder objects against each other on all possible properties
   virtual int       Compare(const CObject *node,const int mode=0) const;

or in the protected class of the abstract order.

protected:
   //--- Protected parametric constructor
                     COrder(ENUM_ORDER_STATUS order_status,const ulong ticket);
                     
   //--- Gets and returns integer properties of the selected order from its parameters
   long              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;
   
   //--- Gets and returns real properties of the selected order from its parameters: (1) open price, (2) close price, (3) profit,
   //--- (4) commission, (5) swap, (6) volume, (7) outstanding volume (8) StopLoss price, (9) TakeProfit price (10) StopLimit order setting price
   double            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;
   
   //--- Gets and returns string properties of the selected order from its parameters: (1) symbol, (2) comment, (3) exchange identifier
   string            OrderSymbol(void)             const;
   string            OrderComment(void)            const;
   string            OrderExternalID(void)         const;
   
public:
   //--- Returns the (1) integer, (2) real, and (3) string property of the order from the property array
   long              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)];  }
   
   //--- Returns the flag that the order maintains the given property
   virtual bool      SupportProperty(ENUM_ORDER_PROP_INTEGER property)        { return true; }
   virtual bool      SupportProperty(ENUM_ORDER_PROP_DOUBLE property)         { return true; }
   virtual bool      SupportProperty(ENUM_ORDER_PROP_STRING property)         { return true; }

Please understand that I am not young anymore, young people can grasp this on the fly.

And also I have opened a topic on the forum in Articles and technical library on automated trading (12560) I am a student there I will duplicate this topic I would like an answer from you in detail about the structure,

working step by step according to the article . You can be wrong and do not understand.

Форум трейдеров - MQL5.community: Статьи и техническая библиотека по автоматическому трейдингу
Форум трейдеров - MQL5.community: Статьи и техническая библиотека по автоматическому трейдингу
  • www.mql5.com
Обсуждение статей по трейдингу и примеров на языках MQL4/MQL5
 
Vladimir Andreev:

Hello

You can consider me your applicant or student so to speak.

I have decided to study your library, but it is difficult for me, although I know something in MQL, but I stumbled at the first step.

I reached the point Realisation of the method of comparing two orders with each other by a given property:

This is the code in the library, where to write it

after

or in the protected class of the abstract order

Please understand that I am not young anymore, but young people can grasp it on the fly.

And also I opened a topic on the forum in Articles and technical library on automated trading (12560) I am a student there I will duplicate this topic I would like a detailed answer from you about the structure,

working step by step according to the article . You can be wrong and do not understand.

There are two ways to create a class method - it is directly in the class body:

class CMyClass
  {
   bool Flag(void) { return false; }
  }

and outside the class body:

class CMyClass
  {
   bool Flag(void);
  }
//--- method implemented outside the class body
bool CMyClass::Flag(void) { return false; }

In the first case, the method is defined and implemented directly in the class body - it's convenient to do so for short methods that don't take up many lines. But if the method is large, it is more convenient to declare it in the class body, and put the implementation outside the class body - as in the second example.

It is clear that it is more convenient to write the method inside the class body. But the method you are asking about - it is more convenient to write it separately from the class body.

However, you can download all the files attached to the article - they already contain everything, they are ready for use - and use them to study what is described in the article.