Como trabalhar corretamente em MT5 com OrderSend - página 9

 
prostotrader:
https://www.mql5.com/ru/forum/97557/page4#comment_2891988
Документация по MQL5: Программы MQL5 / Выполнение программ
Документация по MQL5: Программы MQL5 / Выполнение программ
  • www.mql5.com
Программы MQL5 / Выполнение программ - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
fxsaber:

Desculpe, nenhum desejo de lidar com seus roteiros

Adicionado por

Mas há uma saída para isso.

Como a função OrderrSend() é síncrona, após recebermos o pedido, nós

certifique-se de que o histórico esteja sincronizado na OnTradeTransaction()

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
    switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
         switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Ордер синхронизирован с историей
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }

E nada de danças!

 
prostotrader:

Nada de dançar!

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

Como trabalhar corretamente em MT5 com OrderSend

fxsaber, 2016.11.10 10:00

Note que este é um roteiro e não pode haver nenhum evento. A única saída é um sono idiota.

Se você reescrever este roteiro com SB, nada vai mudar.

 
fxsaber:
VOCÊ pode ficar tão distorcido quanto quiser com Sleep....
 
prostotrader:
Você pode parafusar com Sleep como quiser....

Por que repetir a mesma coisa que já foi sugerida e expressa antes por outros?

A linha diz tudo sobre possíveis problemas com a OnTradeTransaction. Em particular, diz respeito à operação de vários Expert Advisors simultaneamente.

As pessoas estão fazendo muletas, isso não significa que não estejam familiarizadas com a documentação e não saibam como utilizar os recursos.

A OnTrade e a OnTradeTransaction foram desenvolvidas exatamente para este fim. Quando a iniciaram, os desenvolvedores pensaram que seria idiotice lidar com mais de um Expert Advisor simultaneamente em uma conta.

Bem, eles estavam errados a esse respeito.

Tente escrever a seguinte função em seu Consultor Especialista

  1. i = 0.
  2. Abrimos uma posição no símbolo[i].
  3. Se i++ >= 5, nós saímos.
  4. Se não houver deslizamento, voltamos ao passo 2. Se houver deslizamento, saímos.
 
fxsaber:

Por que repetir a mesma coisa que já foi sugerida e expressa antes por outros?

A linha diz tudo sobre possíveis problemas com a OnTradeTransaction. Em particular, diz respeito à operação de vários Expert Advisors simultaneamente.

As pessoas estão fazendo muletas, isso não significa que não estejam familiarizadas com a documentação e não saibam como utilizar os recursos.

A OnTrade e a OnTradeTransaction foram desenvolvidas exatamente para este fim. Quando a iniciaram, os desenvolvedores pensaram que seria idiotice lidar com mais de um Expert Advisor simultaneamente em uma conta.

Bem, eles estavam errados a esse respeito.

Tente escrever a seguinte função em seu Consultor Especialista

  1. i = 0.
  2. Abrimos uma posição no símbolo[i].
  3. Se i++ >= 5, nós saímos.
  4. Se não houver deslizamento, voltamos ao passo 2. Se houver deslizamento, saímos.

Atualmente, tenho 41 consultores especialistas trabalhando em uma conta real (em um terminal) que juntos durante um dia de negociação

Eles estabelecem 2000 ordens abertas e fechadas e eu não estou passando por nenhuma dificuldade!

Adicionado

Quanto à funcionalidade que temos, ela deve ser baseada no que temos e não no que "precisamos".

Os desenvolvedores, se possível, consertam bugs e bugs, levando em conta os desejos de

usuários (embora muito lentamente).

Acho que em breve eles também irão lidar com OederSend().

 
prostotrader:

Tenho 41 consultores especialistas em minha conta real (em um terminal) trabalhando todos juntos durante um dia de negociação.

Eles estabelecem 2000 ordens, posições abertas e fechadas e eu não tenho nenhum problema!

Isto é chamado de sair do tópico.

Quando se trata até mesmo da lógica mais simples.

Fórum sobre comércio, sistemas comerciais automatizados e estratégias comerciais de teste

Como trabalhar corretamente em MT5 com OrderSend

fxsaber, 2016.11.15 13:30

Tente escrever a seguinte função em sua EA

  1. i = 0.
  2. Abrir uma posição sobre o símbolo[i].
  3. Se i++ >= 5, nós saímos.
  4. Se a nova posição não tiver deslizamento, voltamos ao passo 2. Se houver deslizamento, saímos.
Alguém a comercializa imediatamente.
// MQL4&5-code

#property strict

#include <MT4Orders.mqh>    // https://www.mql5.com/ru/code/16006

void Func( const string &Symbols[] )
{
  const int Total = ArraySize(Symbols);
  
  for (int i = 0; i < Total; i++)
  {
    const double Price = SymbolInfoDouble(Symbols[i], SYMBOL_ASK);
    const int digits = (int)SymbolInfoInteger(Symbols[i], SYMBOL_DIGITS);
    
    if (!OrderSelect(OrderSend(Symbols[i], OP_BUY, 1, Price, 100, 0, 0, DoubleToString(Price, digits)), SELECT_BY_TICKET) ||
        (NormalizeDouble(Price - OrderOpenPrice(), digits) != 0)) // если не получилось открыть или есть проскальзывание - выходим
      break;
  }
}

void OnStart() // OnTick
{
  const string Symbols[] = {"EURUSD", "GBPUSD", "AUDUSD", "USDCAD", "USDJPY"};
  
  Func(Symbols);
}

E alguém espera por mana dos desenvolvedores.
 

Já disse que você é livre de torcer como quiser (todos têm esse direito).

 
prostotrader:

Eu já disse que você é livre para torcer como quiser (todos têm esse direito).

foi há muito tempo, mas eu me lembro deste cara, bem, estefxsaber fez maravilhas,

seus códigos ainda estão armazenados na base de códigos MT4, seu código para leitura de sites no WinInet

ainda é usado por muitos programadores...

e, portanto, parece-me que ele não é um pervertido.

 
Rasgou a OrderSendSync da biblioteca aqui
uint OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.

const bool IsTester = (::MQLInfoInteger(MQL_TESTER) || ::MQLInfoInteger(MQL_OPTIMIZATION) ||
                       ::MQLInfoInteger(MQL_VISUAL_MODE) || ::MQLInfoInteger(MQL_FRAME_MODE));
                      
                      

bool Waiting( const bool FlagInit = false )
{
  static ulong StartTime = 0;

  if (FlagInit)
    StartTime = ::GetMicrosecondCount();

  const bool Res = (::GetMicrosecondCount() - StartTime < OrderSend_MaxPause);

  if (Res)
    ::Sleep(0);

  return(Res);
}

bool EqualPrices( const double Price1, const double Price2, const int digits)
{
  return(::NormalizeDouble(Price1 - Price2, digits) == 0);
}

#define WHILE(A) while (!(Res = (A)) && Waiting())

bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
{
  bool Res = ::OrderSend(Request, Result);

  if (Res && !IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (OrderSend_MaxPause > 0))
  {
    Res = (Result.retcode == TRADE_RETCODE_DONE);
    Waiting(true);

    if (Request.action == TRADE_ACTION_DEAL)
    {
      WHILE(::HistoryOrderSelect(Result.order))
        ;

      Res = Res && (((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_FILLED) ||
                    ((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_PARTIAL));

      if (Res)
        WHILE(::HistoryDealSelect(Result.deal))
          ;
    }
    else if (Request.action == TRADE_ACTION_PENDING)
    {
      if (Res)
        WHILE(::OrderSelect(Result.order))
          ;
      else
      {
        WHILE(::HistoryOrderSelect(Result.order))
          ;

        Res = false;
      }
    }
    else if (Request.action == TRADE_ACTION_SLTP)
    {
      if (Res)
      {
        bool EqualSL = false;
        bool EqualTP = false;

        const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

        if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
        {
          EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
          EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
        }

        WHILE((EqualSL && EqualTP))
          if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
          {
            EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
            EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
          }
      }
    }
    else if (Request.action == TRADE_ACTION_MODIFY)
    {
      if (Res)
      {
        bool EqualSL = false;
        bool EqualTP = false;

        const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);

        if (::OrderSelect(Result.order))
        {
          EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
          EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
        }

        WHILE((EqualSL && EqualTP))
          if (::OrderSelect(Result.order))
          {
            EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
            EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
          }
      }
    }
    else if (Request.action == TRADE_ACTION_REMOVE)
      if (Res)
        WHILE(::HistoryOrderSelect(Result.order))
          ;
  }

  return(Res);
}

#undef WHILE
A idéia do código deve ser clara. Talvez eu tenha esquecido algo. Eu não notei nenhum erro na operação.