Ошибки, баги, вопросы - страница 3379

 
Aleksandr Slavskii #:

Почему линии начинаются не с 1 и выходят за пределы рисунка???

Количество необходимых вычислений можно оценить по исходнику этой функции.

//+------------------------------------------------------------------+
//| Calculate boundaries for workspace                               |
//+------------------------------------------------------------------+
void  CGraphic::CalculateBoundaries(void)
 
A100 #:
В последнем build 3902 появилась какая то трудноуловимая ошибка при компиляции - если параметрический макрос расположен много раньше применения то выдается какая то несуществующая абсурдная ошибка, а если его продублировать непосредственно перед применением, то все нормально - не смог с ходу разобраться

Проверил - эта ошибка и раньше была, а в build 3902 проявилась по совпадению - удалил пару неиспользуемых макросов и порядковый номер макроса, на котором возникает ошибка сместился с неиспользуемого на используемый макрос

 
fxsaber #:

Количество необходимых вычислений можно оценить по исходнику этой функции.

Не понял, я не нашёл CGraphic в родителях LineChart.mqh.

А при чём тут количество вычислений?

Ваш ответ слишком краткий, для моего понимания. Сделайте его пожалуйста чуть чуть более развёрнутым.

 
Aleksandr Slavskii #:

Не понял, я не нашёл CGraphic в родителях LineChart.mqh.

А при чём тут количество вычислений?

Ваш ответ слишком краткий, для моего понимания. Сделайте его пожалуйста чуть чуть более развёрнутым.

Сравнил исходники обеих библиотек. Такое ощущение, что в самой LineChart слишком мало вычислений. Будто не дописана до рабочего состояния.

 
A100 #:

Проверил - эта ошибка и раньше была, а в build 3902 проявилась по совпадению - удалил пару неиспользуемых макросов и порядковый номер макроса, на котором возникает ошибка сместился с неиспользуемого на используемый макрос

Без воспроизведения поправить не смогут, наверное.

 
fxsaber #:

Сравнил исходники обеих библиотек. Такое ощущение, что в самой LineChart слишком мало вычислений. Будто не дописана до рабочего состояния.

Понятно. Спасибо. Я то думал это я делаю, что то не так.

Читал статью "Статистические распределения вероятностей в MQL5", код там немного устарел, чуть чуть поправил-заработало,

а вот выбранный способ визуализации у меня не захотел работать, вот и решил по быстренькому сделать визуализацию с помощью  LineChart.mqh,

но если ошибки вылазят даже при минимальном наборе данных, то лучше и не пытаться ничего делать на этой библе.

 
fxsaber #:

Без воспроизведения поправить не смогут, наверное.

Простого кода не смог вычленить

Еще особенность: перед проблемным макро должно быть макро с вычислением и обязательно в скобках, например так:

/*
. . . 
*/
#define MACRO665        (1+1)
#define MACRO666(X) int X;
MACRO666(j) //Error: 'j' - unexpected token, probably type is missing?
            //       'X' - semicolon expected
 
Тестер стратегий версия 1.39 Некоторые ошибки при тестировании истории с использованием лимитных ордеров.
Тестер стратегий версия 1.39 Некоторые ошибки при тестировании истории с использованием лимитных ордеров.
  • 2023.09.02
  • www.mql5.com
1. Происходит сделка полным объемом при объеме на свече меньше, чем в запрашиваемом ордере при установленном ключе ORDER_FILLING_FOK 2...
 

Извините, это мой машинный перевод на русский, за которым следует английский оригинал:

Функция OnTradeTransaction () вызывается от 1 до 4 раз для одной и той же сделки, в зависимости от сделки. Согласно образцу советника (из MQ) с OnTradeTransaction() из https://www.mql5.com/en/docs/event_handlers/ontradetransaction , отдельные шаги бронирования в пределах торгового ордера суммируются советником (или ручной заказ), если они происходят в течение одной секунды:


 void OnTradeTransaction ( const MqlTradeTransaction &trans,
                         const MqlTradeRequest &request,
                         const MqlTradeResult &result)
  {
 //--- 
   static int counter= 0 ;   // counter of OnTradeTransaction() calls 
   static uint lasttime= 0 ; // time of the OnTradeTransaction() last call
 //--- 
   uint time= GetTickCount ();
 //--- if the last transaction was performed more than 1 second ago, 
   if (time-lasttime> 1000 )
     {
      counter= 0 ; // then this is a new trade operation, an the counter can be reset 
       if ( IS_DEBUG_MODE )
         Print ( " New trade operation" );
     }
   lasttime=time;
   counter++;
   Print (counter, ". " , __FUNCTION__ );
....


Это сложно, очень сложно и фактически невозможно использовать в советнике, которому требуется только OnTradeTransaction() для подтверждения торговых приказов на сервер и реализованных значений:

  • Как узнать, сколько еще звонков поступит?
  • Как можно узнать в OnTradeTransaction(), каким будет ключевой вызов или последний вызов, на который будет реагировать?
  • Как OnTradeTransaction() может узнать, принадлежит ли вызов советнику или другому в терминале, работающем на другом графике?
  • Какому ключевому призыву следует следовать?
  • Кроме того, передаваемые переменные структур (trans, request и result) иногда заполняются, иногда пусты или все равно нулю.
  • Зачем советнику знать о способе бронирования своих ордеров? Важен только результат!
  • Наконец, в режиме отладки я вижу, что после асинхронной отправки отложенного ордера сначала немедленно выполняется вызов OnTradeTransaction с trans.Ord_State = STATE_PLACED с order=#2.
    за которым следует вызов с trans.Ord_State = STATE_STARTED, снова order=#2. Кто и как должен в этом разобраться?
  • Первый звонок - единственный, который происходит наверняка.

Все это заставило меня искать более простое решение, вместо того, чтобы ждать, пока пройдут различные шаги и этапы, когда они могут произойти. Чтобы упростить работу советника (и написать об этом статью), я просто хочу использовать билеты ордера и/или позиции через PositionSelectByTicket(ulong Ticket) или OrderSelect(ulong Ticket) для запроса значений открывать позиции или отложенные ордера и обновлять их для дальнейших целей. Кроме того, время и билет сохраняются как статические переменные, поэтому дальнейшая обработка не происходит при повторном вызове OnTradeTransaction() в течение 1 секунды с тем же билетом.

Вот макет OnTradeTransaction() всего из 12 строк и пример других функций моей идеи:

 void OnTradeTransaction ( const MqlTradeTransaction & trans,
                         const MqlTradeRequest & rquest,
                         const MqlTradeResult & result) {

   string sym  = fmax (trans.symbol,rquest.symbol);                 // symbol 
   if ( sym != _Symbol ) return ;                                   // not mine ... 

   ulong     p  = fmax (trans.position,rquest.position),             // ticket number of a position 
            o  = fmax3(trans.order,rquest.order,result.order),     // ticket number of an order 
            d  = fmax (trans.deal,result.deal),                     // ticket number of a deal 
            pB = fmax (trans.position_by,rquest.position_by),       // ticket number of a conjugated position 
            m  = rquest.magic;                                     // magic numbers now and later 
   iCallsOnTrTrans++;
   ResetLastError ();

   if (p> 0 ) updtPos(p,o);
   if (o> 0 ) updtOrd(o);
   return ;
} 

...

 bool updtPos( const ulong p, const ulong o) {
   static ulong       delPos= 0 ;
   static datetime    tmePos= 0 ;
   int i,k;

   if ( p==delPos && tmePos> TimeCurrent () ) {
       return ( false );
   } else {
      delPos=p;
      tmePos=TimeCurrent()+2;
   }

   if (! PositionSelectByTicket (p)) { 
       if ( _LastError == 4753 ) ResetLastError (); // Err[4753] = ERR_TRADE_POSITION_NOT_FOUND: 
       if ( _LastError > 1 ) { Print ( "e:" ,err()); DebugBreak (); }
....


Как уже было сказано, это будет работать ТОЛЬКО в том случае, если значения соответствующей открытой позиции или отложенного ордера больше НЕ изменяются между последующими вызовами OnTradeTransaction() в терминале. Другими словами: поступает ли измененная позиция/ордер до или с первым вызовом (после ORDER_STATE_STARTED – но даже это не первый вызов!) OnTradeTransaction() в терминале, или они все еще изменяются/обновляются после первого вызова OnTradeTransactio() относительно этого заказа ?

Sorry this is my Russian machine translation followed by the English original:

The OnTradeTransaction() function is called between 1 and 4 times for the same trade, depending on the trade. According to the Sample EA (from MQ) with OnTradeTransaction() from https://www.mql5.com/en/docs/event_handlers/ontradetransaction , the individual up to 4 booking steps within a trade order are summarized by an EA (or a manual order) if they occur within one second:

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   static int counter=0;   // counter of OnTradeTransaction() calls
   static uint lasttime=0; // time of the OnTradeTransaction() last call
//---
   uint time=GetTickCount();
//--- if the last transaction was performed more than 1 second ago,
   if(time-lasttime>1000)
     {
      counter=0; // then this is a new trade operation, an the counter can be reset
      if(IS_DEBUG_MODE)
         Print(" New trade operation");
     }
   lasttime=time;
   counter++;
   Print(counter,". ",__FUNCTION__);
....


This is hard, very complicated and actually impossible to use in an EA that only needs OnTradeTransaction() to confirm its trade orders to the server and the values realized:

  • How can it be known how many more calls are coming?
  • How can it be know within OnTradeTransaction() what will be the key-call or the last call to react?
  • How can OnTradeTransaction() know whether the call belongs to the EA or to another in the terminal running on a different chart?
  • Which is the key-call that should be followed?
  • Beside this the passed variables of the structures (trans, request & result) are sometimes filled sometimes empty or everything is null.
  • Why should an EA get knowledge about the way of booking its orders? Only the outcomming is important!
  • Finally in debug mode I see that after async submitting a pending order, first a call to OnTradeTransaction with trans.Ord_State = STATE_PLACED is made with order=#2 immediately
    followed by a call with trans.Ord_State = STATE_STARTED, again order=#2. Who is supposed to get their head around this and how?
  • The first call is the only one that happens for sure.

All this led me to look for a simpler solution instead of waiting for the various steps and stages to work through when they might occur. To simplify the whole thing for an EA (and to write an article about it), I just want to use the tickets of the order and/or position via PositionSelectByTicket(ulong ticket) or OrderSelect(ulong ticket) to query the values of the open positions or pending orders and update them for further purposes. Additionally, the time and the ticket are stored as a static variables, so that no further processing happens when OnTradeTransaction() is called again within 1 second with the same ticket.

Here is the layout of OnTradeTransaction() with only 12 lines and the sample the other functions of my idea:

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& rquest,
                        const MqlTradeResult& result) {

   string sym  = fmax(trans.symbol,rquest.symbol);                // symbol
   if ( sym != _Symbol ) return;                                  // not mine ...

   ulong    p  = fmax(trans.position,rquest.position),            // ticket number of a position
            o  = fmax3(trans.order,rquest.order,result.order),    // ticket number of an order
            d  = fmax(trans.deal,result.deal),                    // ticket number of a deal
            pB = fmax(trans.position_by,rquest.position_by),      // ticket number of a conjugated position
            m  = rquest.magic;                                    // magic numbers now and later
   iCallsOnTrTrans++;
   ResetLastError();

   if (p>0) updtPos(p,o);
   if (o>0) updtOrd(o);
   return;
} 

...

bool updtPos(const ulong p, const ulong o) {
   static ulong      delPos=0;
   static datetime   tmePos=0;
   int i,k;

   if ( p==delPos && tmePos>TimeCurrent() ) {
      return(false);
   } else {
      delPos=p;
      tmePos=TimeCurrent()+2;
   }

   if (!PositionSelectByTicket(p)) { 
      if (_LastError==4753) ResetLastError(); // Err[4753] = ERR_TRADE_POSITION_NOT_FOUND:
      if (_LastError>1) { Print("e:",err()); DebugBreak(); }
....

As said, this would work ONLY if the values of the respective open position or pending order are NOT changed anymore between the subsequent calls of OnTradeTransaction() in the terminal. In other words: Does the changed position/order arrive before or with the first call (after ORDER_STATE_STARTED - but not even that is the first call!) of OnTradeTransaction() in the terminal or are they still changed/updated after the first call of OnTradeTransactio() concerning this order?

Documentation on MQL5: Event Handling / OnTradeTransaction
Documentation on MQL5: Event Handling / OnTradeTransaction
  • www.mql5.com
OnTradeTransaction - Event Handling - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Ошибка при выполнении:
#define MACRO(X)        #X
void OnStart()
{
    Print(MACRO("ABCD"));
}
Результат:    ABCD

Ожидалось:  "ABCD"