Desenvolvedores! Testa sequer o que cria? - página 10

 
Mikalas:

Oh, meu Deus! É válido na história?

Papaklass provavelmente significava que a OnTradeTransaction devolve erros?

Se a informação na OnTradeTransaction pode não ser válida, temos de a retirar do histórico para nos certificarmos de que é válida.

Se a informação da onTradeTransaction nem sempre é fiável, temos de a retirar do histórico para nos certificarmos de que a informação foi processada.

A questão é por que raio precisamos da OnTradeTransaction se de qualquer forma temos de tirar a informação da história? - Só precisa dele para a verificação de erros. O corretor rejeitou a encomenda e recebemos a resposta porque foi rejeitada na OnTradeTransaction e analisámo-la.

 
sergeev:
mas porquê babar-se ao longo de 9 páginas?

Por favor não seja mal-educado! A propósito, já são 10!

E está no seu direito de não ler de todo o que aqui está escrito!

 
Mikalas:

C-4, será processado, claro, mas porquê a necessidade de OnRefresh()?

Muitos eventos -> um manipulador.
 
C-4:
Muitos eventos -> um manipulador.
Erros de todos os cantos em uma só pilha! :)
 
Mikalas:
Erros de todos os cantos em uma só pilha! :)

Não são os erros que são enviados, mas sim os dados. Os erros podem estar no manipulador, mas são fáceis de corrigir porque existe apenas um manipulador.

papaklass:
É exactamente isso que eu quero dizer. É necessária a separação de eventos.
Não é necessária uma separação de eventos, é necessária uma separação de manipuladores. Os eventos geram dados. Cada tipo de dados é tratado pelo seu próprio manipulador. Não importa quem recebeu os dados, o importante é que existe um manipulador único para cada tipo de dados.
 
C-4:

Não são os erros que são enviados, mas sim os dados. Os erros podem estar no manipulador, mas são fáceis de corrigir porque existe apenas um manipulador.

Não é preciso separar eventos, é preciso separar manipuladores. Os eventos geram dados. Cada tipo de dados lida com o seu próprio manipulador. Não importa quem recebeu os dados, o importante é que existe um manipulador único para cada tipo de dados.

O que é que não está separado aqui?

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 depois há

const MqlTradeRequest &request, const MqlTradeResult &result
 
Mikalas:

O que é que não é partilhado aqui?

Muitos combinatórios. Conclusão: folha gigante na OnTradeTransaction e lógica complicada. Não posso responder como o faria, porque não conheço a tarefa. Em qualquer caso>caso>caso... é um pouco suspeito.
 
papaklass:

O que sugere (processamento de tipos de dados) é o que a MK tem neste momento. O manipulador da OnTradeTransaction trata de um certo tipo de dados da MqlTradeTransaction. É verdade, eles colocam muitas coisas neste tipo de dados, ou seja, tipos de dados correspondentes a diferentes eventos.

Sugiro que cada evento tenha os seus próprios dados e o seu próprio manipulador. Tantos eventos, como muitos manipuladores. A divisão dos eventos (abrir uma posição, fechar uma posição, colocar uma ordem, modificar uma ordem, modificar uma posição, etc.). E cabe aos criadores decidir quais os tipos de dados a atribuir a que eventos.

Pela palavra "manipulador", não me refiro a uma função do sistema que recebe algum evento, mas a algum módulo de Expert Advisor que analisa este ou aquele evento. Para multiplicar o número de funções Em... Cada um deles para o seu próprio evento - não faz sentido, tanto mais que é elementar criar um número necessário de manipuladores personalizados. É assim que se faz no meu 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...
   }
}

Pode parecer estranho que uma mesma classe de Eventos seja transmitida a manipuladores completamente diferentes que requerem tipos de dados completamente diferentes. Por exemplo, OnMouseMove requer uma máscara de teclas premida no rato e as suas coordenadas, OnKeyDown() requer o código de uma tecla premida, OnOrderChange requer um bilhete da ordem que foi alterada e provavelmente um enumero descrevendo a alteração exacta. Pode-se pensar que a classe do evento contém campos para todos os eventos possíveis. Mas não é esse o caso. De facto, o objecto da classe do evento não pode sequer existir, uma vez que o seu construtor está escondido na área protegida. Mas os seus descendentes existem em abundância - cada descendente para lidar apenas com um evento diferente. Contudo, para qualquer evento, existe um identificador que indica a que tipo pertence. Conhecendo este identificador, pode efectuar uma conversão segura de um tipo maior para um tipo menor. Este é o tipo de criança a quem a conversão implícita é feita quando o manipulador é passado. Vamos ver como os nossos manipuladores vêem realmente o 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...
Bonito... Parece que há apenas um evento, mas na realidade pode haver dezenas deles. O evento parece não conter quase nenhuma informação, excepto o seu tipo, mas de facto, os manipuladores referem-se livremente a métodos conhecidos apenas por eles.
 

Não há eventos "externos" e "internos", apenas eventos. E o número destes eventos é potencialmente infinito. Um evento pode ser qualquer coisa. Um evento pode conter todo o tipo de dados. Seguindo esta filosofia, alcançamos um novo nível de abstracção de dados mais elevado. Porquê criar restrições na sua cabeça, porquê impor uma classificação limitando a abstracção!

papaklass:

A diferença essencial entre eventos internos e externos é o tempo de execução. Os eventos internos têm praticamente tempo de execução zero, enquanto que os eventos externos têm centenas de milissegundos a segundos.

Os eventos não têm um tempo de execução. Se chegou um evento, este já foi executado. É assim que funciona o modo assíncrono. Portanto, é errado classificar os eventos em internos e externos devido à rapidez com que são executados. É correcto não classificar de todo, mas pensar de forma muito abstracta a partir da implementação concreta.

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