Sviluppatori! Testate anche quello che create? - pagina 10

 
Mikalas:

Oh, mio Dio! È valido nella storia?

papaklass probabilmente intendeva dire che OnTradeTransaction restituisce errori?

Se l'informazione in OnTradeTransaction potrebbe non essere valida, dobbiamo prenderla dalla storia per assicurarci che sia valida.

Se le informazioni di onTradeTransaction non sono sempre affidabili, dobbiamo prenderle dalla storia per essere sicuri che le informazioni siano state processate.

La domanda è: perché diavolo abbiamo bisogno di OnTradeTransaction se dobbiamo comunque prendere le informazioni dalla storia? - Ne ha bisogno solo per il controllo degli errori. Il broker ha rifiutato l'ordine e abbiamo ricevuto la risposta al motivo del rifiuto in OnTradeTransaction e l'abbiamo analizzato.

 
sergeev:
ma perché sbavare su 9 pagine?

Per favore, non essere scortese! A proposito, sono già le 10!

E lei ha il diritto di non leggere affatto ciò che è scritto qui!

 
Mikalas:

C-4, sarà elaborato, naturalmente, ma perché la necessità di OnRefresh()?

Molti eventi -> un solo gestore.
 
C-4:
Molti eventi -> un solo gestore.
Errori da tutti gli angoli in un unico mucchio! :)
 
Mikalas:
Errori da tutti gli angoli in un unico mucchio! :)

Non sono gli errori che vengono inviati, ma i dati. Gli errori possono essere nel gestore, ma sono facili da risolvere perché c'è solo un gestore.

cartapesta:
Questo è esattamente quello che voglio dire. Avete bisogno di una separazione degli eventi.
Non avete bisogno di una separazione degli eventi, ma di una separazione dei gestori. Gli eventi generano dati. Ogni tipo di dati è gestito da un proprio gestore. Non importa chi ha ricevuto i dati, l'importante è che ci sia un gestore unico per ogni tipo di dati.
 
C-4:

Non sono gli errori che vengono inviati, ma i dati. Gli errori possono essere nel gestore, ma sono facili da risolvere perché c'è solo un gestore.

Non avete bisogno di separare gli eventi, ma i gestori. Gli eventi generano dati. Ogni tipo di dati gestisce il proprio gestore. Non importa chi ha ricevuto i dati, l'importante è che ci sia un gestore unico per ogni tipo di dati.

Cosa non viene condiviso qui?

void OnTradeTransaction( const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result )
{
 // Print( "Ticket = ", string( trans.order ), " --> ", EnumToString( trans.type ), " --> ", EnumToString(trans.order_state) );
  
  switch( trans.type )
  {
    TRADE_TRANSACTION_ORDER_DELETE:      switch( trans.order_state )
                                         {
                                           Удаление ордера из списка открытых.
                                           Ордер может быть удален из открытых в результате выставления
                                           соответствующего запроса либо в результате исполнения (заливки) и переноса в историю.
 
                                         } 
                                         break;
    
    TRADE_TRANSACTION_ORDER_ADD:         switch( trans.order_state )
                                         {
                                           Добавление нового открытого ордера.
                                         } 
                                         break;
                                          
    TRADE_TRANSACTION_DEAL_ADD:          switch( trans.order_state )
                                         {
                                           Добавление сделки в историю. Осуществляется в результате исполнения ордера или проведения операций с балансом счета.
                                         }
                                         break;
                                                    
    case TRADE_TRANSACTION_HISTORY_ADD:  switch( trans.order_state )
                                         {
                                           Добавление ордера в историю в результате исполнения или отмены.
                                         }
                                         break;
    
    case TRADE_TRANSACTION_ORDER_DELETE:  switch( trans.order_state )
                                         {
                                           Удаление ордера из списка открытых.
                                           Ордер может быть удален из открытых в результате выставления
                                           соответствующего запроса либо в результате исполнения (заливки) и переноса в историю.
                                         }
                                         break;
                                         
    case TRADE_TRANSACTION_ORDER_UPDATE: switch( trans.order_state )
                                         {
                                           Изменение открытого ордера. 
                                           К данным изменениям относятся не только явные изменения
                                           со стороны клиентского терминала или торгового сервера,
                                           но также и изменение его состояния при выставлении
                                           (например, переход из состояния ORDER_STATE_STARTED в ORDER_STATE_PLACED или
                                           из ORDER_STATE_PLACED в ORDER_STATE_PARTIAL и т.д.).
                                         }
                                         break;
                                         
    case TRADE_TRANSACTION_DEAL_UPDATE:  switch( trans.order_state )
                                         {
                                           Изменение сделки в истории. Возможны ситуации, 
                                           когда ранее исполненная сделка изменяется на сервере.
                                           Например, сделка была изменена во внешней торговой системе (бирже),
                                           куда она была выведена брокером.
                                         }
                                         break;
                                         
    case TRADE_TRANSACTION_DEAL_DELETE: switch( trans.order_state )
                                        {
                                          Удаление сделки из истории.
                                          Возможны ситуации, когда ранее исполненная сделка удаляется на сервере.
                                          Например, сделка была удалена во внешней торговой системе (бирже), куда она была выведена брокером.
                                        }
                                        break; 
             
    case TRADE_TRANSACTION_HISTORY_UPDATE: switch( trans.order_state )
                                           {
                                             Изменение ордера, находящегося в истории ордеров.
                                             Данный тип предусмотрен для расширения функциональности на стороне торгового сервера.
                                           }
                                           break;
                                          
    case TRADE_TRANSACTION_HISTORY_DELETE: switch( trans.order_state )
                                           {
                                             Удаление ордера из истории ордеров.
                                             Данный тип предусмотрен для расширения функциональности на стороне торгового сервера.
                                           }
                                           break;
                                                                                 
    case TRADE_TRANSACTION_POSITION:       switch( trans.order_state )
                                           {
                                            Изменение позиции, не связанное с исполнением сделки. 
                                            Данный тип транзакции свидетельствует именно о том,
                                            что позиция была изменена на стороне торгового сервера.
                                            У позиции может быть изменен объем, цена открытия,
                                            а также уровни Stop Loss и Take Profit.
                                            Информация об изменениях передается в структуре MqlTradeTransaction
                                            через обработчик OnTradeTransaction.
                                            Изменение позиции (добавление, изменение или ликвидация) в результате совершения
                                            сделки не влечет за собой появление транзакции TRADE_TRANSACTION_POSITION.
                                           }
                                           break;                                                                                                                                                                                  
  case TRADE_TRANSACTION_REQUEST:  Уведомление о том, что торговый запрос обработан сервером,
                                     и результат его обработки получен.
                                      Для транзакций данного типа в структуре MqlTradeTransaction
                                      необходимо анализировать только одно поле - type (тип транзакции).
                                      Для получения дополнительной информации необходимо анализировать второй
                                      и третий параметры функции OnTradeTransaction (request и result).
                                    break;
}
 

E poi ci sono

const MqlTradeRequest &request, const MqlTradeResult &result
 
Mikalas:

Cosa non viene condiviso qui?

Un sacco di combinatoria. In conclusione: foglio gigante in OnTradeTransaction e logica complicata. Non posso rispondere come farei io, perché non conosco il compito. Comunque, caso->caso->caso... è un po' sospetto.
 
papaklass:

Quello che suggerisci (elaborazione dei tipi di dati) è ciò che MK ha al momento. Il gestore OnTradeTransaction gestisce un certo tipo di dati MqlTradeTransaction. È vero, hanno messo un sacco di cose in questo tipo di dati, cioè tipi di dati corrispondenti a diversi eventi.

Suggerisco che ogni evento abbia i suoi dati e il suo gestore. Tanti eventi, tanti gestori. La divisione degli eventi (aprire una posizione, chiudere una posizione, piazzare un ordine, modificare un ordine, modificare una posizione, ecc.) E sta agli sviluppatori decidere quali tipi di dati assegnare a quali eventi.

Con la parola "gestore", non intendo una funzione di sistema che riceve qualche evento, ma un modulo Expert Advisor che analizza questo evento. Per moltiplicare il numero di funzioni su... Ognuno di loro per il proprio evento - non ha senso, tanto più che è elementare creare un numero necessario di gestori personalizzati. È così che si fa nel mio caso:

///
/// Принимаем событие.
///
void OnEvent(Event* event)
{
   switch(event.EventId())
   {
       case EVENT_MOUSE_MOVE:
           OnMouseMove(event);
           break;
       case EVENT_KEY_DOWN:
           OnKeyDown(event);
           break;
       case EVENT_ORDER_CHANGE:
           OnOrderChange(event);
           break;
       //etc...
   }
}

Può sembrare strano che una stessa classe Event sia passata a gestori completamente diversi che richiedono tipi di dati completamente diversi. Per esempio, OnMouseMove richiede una maschera di tasti premuti sul mouse e le sue coordinate, OnKeyDown() richiede il codice di un tasto premuto, OnOrderChange richiede un biglietto dell'ordine che è stato cambiato e probabilmente un enum che descrive il cambiamento esatto. Si potrebbe pensare che la classe degli eventi contenga campi per tutti gli eventi possibili. Ma non è questo il caso. In effetti, l'oggetto della classe evento non può nemmeno esistere, poiché il suo costruttore è nascosto nell'area protetta. Ma i suoi discendenti esistono in abbondanza - ogni discendente per gestire solo un evento diverso. Tuttavia, per ogni evento, c'è un identificatore che indica a quale tipo appartiene. Conoscendo questo identificatore si può tranquillamente convertire da un tipo più grande a uno più piccolo. Questo è il tipo del figlio a cui viene eseguita la conversione implicita quando viene passato il gestore. Vediamo come i nostri gestori vedono effettivamente l'evento:

///
/// Реагируем на перемещение мыши.
///
OnMouseMove(EventMouseMove* event)
{
   int yCoord = event.YCoord();
   int xCoord = event.XCoord();
   printf("X координата: " + xCoord + "; Y координата: " + yCoord);
}

///
/// Реагируем на перемещение мыши.
///
OnOrderChange(EventOrderChange* event)
{
   int ticket = event.Ticket();
   ENUM_ORDER_STATE state = event.OrderState();
   printf("Ордер с тикетом " + ticket + " изменил свое состояние на " + EnumToString(state));
}

//etc...
Bello... Sembra che ci sia un solo evento, ma in realtà potrebbero essercene decine. L'evento sembra non contenere quasi nessuna informazione, tranne il suo tipo, ma in realtà i gestori fanno liberamente riferimento a metodi noti solo a loro.
 

Non ci sono eventi "esterni" e "interni", solo eventi. E il numero di questi eventi è potenzialmente infinito. Un evento può essere qualsiasi cosa. Un evento può contenere tutti i tipi di dati. Seguendo questa filosofia raggiungiamo un nuovo e più alto livello di astrazione dei dati. Perché creare restrizioni nella tua testa, perché imporre una classificazione che limita l'astrazione!

papaklass:

La differenza essenziale tra eventi interni ed esterni è il tempo di esecuzione. Gli eventi interni hanno un tempo di esecuzione praticamente nullo, mentre gli eventi esterni hanno centinaia di millisecondi o secondi.

Gli eventi non hanno un tempo di esecuzione. Se un evento è arrivato, è già stato eseguito. Questo è il modo in cui funziona la modalità asincrona. Quindi è sbagliato classificare gli eventi in interni ed esterni a causa di quanto velocemente vengono eseguiti. È corretto non classificare affatto, ma pensare in modo molto astratto dall'attuazione concreta.

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