Processamento OnTradeTransaction

 

Boa noite.

Rapazes, por favor, me ajudem. O problema provavelmente não é novo, mas não encontrei uma única solução (nem na prática nem nos fóruns).

Estou executando 2 robôs diferentes no terminal em 2 instrumentos diferentes. As magias são diferentes em todos os lugares. O robô coloca limites pendentes e o procedimento OnTradeTransaction me permite detectar uma transação e colocar ordens de parada pendentes usando esta transação.

Abaixo está o código para a transação comercial

case TRADE_TRANSACTION_DEAL_ADD:
        {
         drop_info2("TRADE_TRANSACTION_DEAL_ADD\r\n"+TransactionDescription(trans));
         if((trans.deal_type==DEAL_TYPE_BUY || trans.deal_type==DEAL_TYPE_SELL) && trans.order!=0)
           {
            if(getIsDealOfExpert(trans.deal)) //функция проверки принадлежности сделки к роботу
              {
               drop_info2("Сделка наша");
               analyzeFilledOrder(trans.order,trans.volume); //процедура по выставлению отложенных стоп ордеров
              }
           }
        }
      break;

Este é o código da função que verifica se o negócio pertence a um robô

bool getIsDealOfExpert(ulong dealTicket)
     {
      if(HistoryDealSelect(dealTicket) && HistoryDealGetInteger(dealTicket,DEAL_MAGIC)==magic_number && HistoryDealGetString(dealTicket,DEAL_SYMBOL)==symbol)
         return true;
      else
         return false;
     }

Este é o código do procedimento para ordens de parada pendentes

void analyzeFilledOrder(ulong orderTicket,double volume)
  {
   bool isFindOrder=false;
   string fullComment;
   ENUM_ORDER_TYPE orderType;
   if(getIsOrderOfExpert(orderTicket,true)) //Если ордер из сделки уже в истории
     {
      fullComment=HistoryOrderGetString(orderTicket,ORDER_COMMENT);
      orderType=ENUM_ORDER_TYPE(HistoryOrderGetInteger(orderTicket,ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли в истории
     }
   if(!isFindOrder && getIsOrderOfExpert(orderTicket,false)) //Если не нашли ордер в истории и ордер есть не в истории
     {
      fullComment=OrderGetString(ORDER_COMMENT); 
      orderType=ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли не в истории
     }
   if(isFindOrder) //если хоть где-то нашли, то выставляем отложенные стоп ордера
     {
     //выставляем стоп ордера

Este é o código da função de busca de uma ordem na história e fora da história

bool getIsOrderOfExpert(ulong OrderTicket,bool isHistory)
     {
      bool is_expert=false;
      //если ордер находится в истории
      if(isHistory)
        {
         if(HistoryOrderSelect(OrderTicket) && HistoryOrderGetInteger(OrderTicket,ORDER_MAGIC)==magic_number && HistoryOrderGetString(OrderTicket,ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      else
        {
         if(OrderSelect(OrderTicket) && OrderGetInteger(ORDER_MAGIC)==magic_number && OrderGetString(ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      return is_expert;
     }

Eu emitiria as informações sobre as transações recebidas nos arquivos de registro na ordem em que são recebidas no terminal. Agora eu tenho um problema que enfrentei ao negociar em uma conta de demonstração:

s vezes as transações vêm na seguinte ordem TRADE_TRANSACTION_ORDER_DELETE, depois TRADE_TRANSACTION_DEAL_ADD, depois TRADE_TRANSACTION_HISTORY_ADD. Neste caso, as ordens de parada não são frequentemente colocadas após uma negociação ter sido executada. Suponho que isso aconteça porque a ordem já foi apagada, mas ainda não foi acrescentada à história. Isso significa que não podemos encontrar a ordem do negócio nem na história nem no terminal. Embora seja duvidoso, o fato é que nenhuma ordem de parada é colocada porque o robô não a encontra depois de procurar a ordem em todas as dimensões(isFindOrder=false). A ordem das transações pode estar correta, mas a ordem ainda não foi encontrada em nenhum lugar. Em todos os casos, o robô detecta a transação corretamente, mas não chega a fazer pedidos.No entanto, ocasionalmente também funciona corretamente e os pedidos são feitos.

Tentei abordagens diferentes, nada funciona. Estou pensando agora em acrescentar um intervalo de 1 segundo no início do procedimento de colocação de pedidos pendentes. Não sei onde mais cavar.

Por favor, compartilhe suas experiências e idéias.

 
Илья Ребенок:

Boa noite.

Rapazes, por favor, me ajudem. O problema provavelmente não é novo, mas não encontrei uma única solução (nem na prática nem nos fóruns).

Estou executando 2 robôs diferentes no terminal em 2 instrumentos diferentes. As magias são diferentes em todos os lugares. O robô coloca limites pendentes e o procedimento OnTradeTransaction me permite detectar uma transação e colocar ordens de parada pendentes usando esta transação.

Abaixo está o código para a transação comercial

Este é o código da função que verifica se o negócio pertence a um robô

Este é o código do procedimento para ordens de parada pendentes

Este é o código da função de busca de uma ordem na história e fora da história

Eu emitiria as informações sobre as transações recebidas no log na ordem em que elas são recebidas no terminal. Agora eu tenho um problema que enfrentei ao negociar em uma conta de demonstração:

s vezes as transações vêm na seguinte ordem TRADE_TRANSACTION_ORDER_DELETE, depois TRADE_TRANSACTION_DEAL_ADD, depois TRADE_TRANSACTION_HISTORY_ADD. Neste caso, as ordens de parada não são frequentemente colocadas após uma negociação ter sido executada. Suponho que isso aconteça porque a ordem já foi apagada, mas ainda não foi acrescentada à história. Isso significa que não podemos encontrar a ordem do negócio nem na história nem no terminal. Embora seja duvidoso, o fato é que nenhuma ordem de parada é colocada porque o robô não a encontra depois de procurar a ordem em todas as dimensões(isFindOrder=false). A ordem de transação pode estar correta, mas a ordem ainda não foi encontrada em nenhum lugar.

Tentei abordagens diferentes, nada ajuda. Estou pensando agora em acrescentar um sono de 1 segundo no início de um procedimento para fazer pedidos pendentes, talvez o tempo não seja suficiente. Eu nem sei onde mais cavar.

Por favor, compartilhe suas experiências e idéias.

Eu ainda não comecei a procurar em todo o código. Não creio que esta abordagem esteja correta de forma alguma.

No momento da transação do tipo TRADE_TRANSACTION_DEAL_ADD, devemos escolher a posição trans.position e verificar sua magia.

if(PositionSelectByTicket(trans.position) && PositionGetInteger(POSITION_MAGIC) == mag)

Você também pode verificar trans.symbol == _Symbol e tomar uma decisão com base nos resultados destas verificações.

 
Alexey Viktorov:

Eu não investiguei todo o código. Na minha opinião, a abordagem não é de modo algum correta.

No momento da transação TRADE_TRANSACTION_DEAL_ADD tipo de transação deve-se escolher trans.position e verificar seu magik.

Você também pode verificar trans.symbol == _Symbol e tomar uma decisão com base nos resultados destas verificações.

Esqueci de acrescentar que o modo é de rede. A posição é a mesma para todos os robôs. Ou seja, um robô comprou uma posição, o segundo a comprou, os eventos TRADE_TRANSACTION_DEAL_ADD vieram em ordem inversa e como resultado, o primeiro robô não a viu.

E, logicamente, preciso obter o comentário do pedido do ofício, a posição não é de grande ajuda aqui.
 
Илья Ребенок:

Compartilhe suas experiências e idéias, por favor.

Uma situação

Fórum sobre comércio, sistemas automatizados de comércio e testes estratégicos

Bichos, insetos, perguntas

fxsaber, 2018.06.20 23:18

Decidiu verificar quanto tempo duram estas situações de ordem fantasma, quando uma ordem está no sistema mas não no Terminal.

// Советник отслеживает длительность ситуаций, когда ордер отсутствует среди текущих и исторических

#define  TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define  TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

bool OrderIsExist( const ulong &OrderTicket )
{
  return(OrderTicket ? OrderSelect(OrderTicket) || HistoryOrderSelect(OrderTicket) : true);
}

void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest&, const MqlTradeResult& )
{
  static bool PrevIsExist = true;
  static ulong StartTime = 0;
  static ulong MaxInterval = 0;
  
  const ulong NowTime = GetMicrosecondCount();
  const bool IsExist = OrderIsExist(Trans.order);
    
  if (!IsExist)
  {
    Print(TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
  
    if (PrevIsExist) 
      StartTime = NowTime;
  }
  else if (!PrevIsExist)
  {
    const ulong Interval = NowTime - StartTime;
    
    Print(TOSTRING(Interval) + TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
    
    if (Interval > MaxInterval)
    {
      MaxInterval = Interval;
      
      Comment(TOSTRING(MaxInterval) + TOSTRING(Trans.order)); // mcs.
    }
  }
          
  PrevIsExist = IsExist;
}


Resultado

2018.06.21 00:10:31.047 Trans.type = TRADE_TRANSACTION_ORDER_DELETE (2)
2018.06.21 00:10:31.047 Trans.order = 2210967406
2018.06.21 00:10:31.047 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 HistoryOrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 
2018.06.21 00:10:31.080 Interval = 32643
2018.06.21 00:10:31.080 Trans.type = TRADE_TRANSACTION_HISTORY_ADD (3)
2018.06.21 00:10:31.080 Trans.order = 2210967406
2018.06.21 00:10:31.080 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.080 HistoryOrderSelect(Trans.order) = true


32 milissegundos um pedido está lá, mas não no Terminal! Imagine as conseqüências se a lógica comercial fosse executada neste intervalo ...


É interessante que as ordens fantasmas estão mais freqüentemente presentes apenas nos tipos de transaçãoTRADE_TRANSACTION_ORDER_DELETE e TRADE_TRANSACTION_DEAL_ADD (muito mais raras).


Muito ruim nuance de plataforma.


ZZY, infelizmente, a velocidade questionável das transações comerciais em cinco.


Segundo

abrindo uma posição e as ordensTotal aumentaram em uma.

  • Foi executado e as OrdensTotal diminuíram em um, mas as PosiçõesTotal não aumentaram em um. Em outras palavras, há uma posição, mas o terminal não sabe sobre ela.
  • Por exemplo, não há posições ou ordens - PositionsTotal = 0, OrdersTotal = 0.

    Você estabelece uma ordem de mercado. PosiçõesTotal = 0, OrdensTotal = 1.

    A ordem de mercado é executada - OrdensTotal = 0. Mas PosiçõesTotal = 0!

     
    Илья Ребенок:

    Esqueci de acrescentar que o modo é de rede. A posição é a mesma para todos os robôs.

    Não importa. A posição sempre tem um bilhete, mas também pode ser selecionada por símbolo. Você pode ter que adicionar um cheque no volume do negócio ou outra coisa. Por exemplo, selecione as ordens e acordos de uma posição e agite-os para encontrar a posição certa. Mas um acordo é um acordo... E ninguém garante a consistência das transações. Não faz muito tempo, houve até mesmo um aviso sobre possíveis perdas de transações.


    Dado o adendo em seu posto, está tudo errado. Nesse caso, é preciso analisar com mais cuidado.

     
    Илья Ребенок:

    Tentei abordagens diferentes, nada funciona.

    Escreva uma ação simples que precisa ser implementada.

     
    fxsaber:

    Uma situação


    Segundo

    Obrigado, vou lê-lo, mas à primeira vista confirma minha suposição.

    Alexey Viktorov:

    Isso não importa. A posição sempre tem um bilhete, mas você também pode selecionar por símbolo. Você pode ter que adicionar um cheque sobre o volume da transação ou outra coisa. Por exemplo, selecione ordens e negócios de uma posição e sacuda-os para encontrar a posição certa. Mas um acordo é um acordo... E ninguém garante a consistência das transações. Não faz muito tempo, houve um aviso sobre possíveis perdas de transações.


    Considerando o adendo em seu posto, nem tudo se encaixa. Nesse caso, é preciso analisar com mais cuidado.

    Vi um post sobre a perda da transação, mas os moderadores de lá disseram que era uma relíquia do passado e esqueceram de removê-la da documentação.

    fxsaber:

    Escreva uma ação simples para ser implementada.

    Não entendo muito bem escrever uma simples ação) Por favor, explique.

     
    Илья Ребенок:


    Vi um posto sobre a perda de transações, mas os moderadores de lá disseram que era uma relíquia do passado e esqueceram de retirá-la da documentação.

    Eles fizeram, mas não foi assim há tanto tempo.

     
    Илья Ребенок:

    Não entendo muito bem como escrever uma simples ação) Explique, por favor.

    Qual é o objetivo comercial?

     
    fxsaber:

    Qual é seu objetivo comercial?

    Colocamos ordens de limite, e quando elas acionam, fazemos uma ordem de parada e uma ordem de lucro. Quando uma ordem de parada é acionada, nós retiramos o lucro e vice-versa. O bilhete de limite inicial, com base no qual definimos a ordem de parada e de obtenção de lucro, está escrito no comentário da ordem de parada e de obtenção de lucro. É por isso que é importante obter comentários para que, quando uma ordem de parada é acionada, você possa encontrar o lucro com o mesmo comentário e excluí-lo.

    Uma vez que nosso robô nos permite fazer pedidos de reabastecimento, devemos também fazer um pedido de parada e um take profit e deixar um comentário com a entrada de um bilhete de reabastecimento.

    Um segundo de sono pode ser uma boa idéia? Para ter tempo para todas as transaçõesTRADE_TRANSACTION_ORDER_DELETE eTRADE_TRANSACTION_HISTORY_ADD

    Общие принципы - Торговые операции - MetaTrader 5
    Общие принципы - Торговые операции - MetaTrader 5
    • www.metatrader5.com
    Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит...
     

    Илья Ребенок:

    O robô permite o escalonamento, portanto, quando compramos mais, também fazemos um pedido de parada e um take profit, e registramos o escalonamento no comentário do bilhete

    Podemos ter >=2 receber e interromper pedidos ao mesmo tempo?