Bibliotecas: MT4Orders - página 11

 
Aliaksandr Kryvanos:
Entendo. Você pode me dar uma ideia de como fazer com que o GetLastError() também produza erros do servidor de comércio? Obrigado
Da mesma forma que o OrdersTotal está implementado. Provavelmente escreverei um GetLastError estendido. E também GetLastTradeRequest() e GetLastTradeResult().
 
fxsaber:
Provavelmente, escreverei um GetLastError estendido. E também GetLastTradeRequest() e GetLastTradeResult().

Depois de estudar o GetLastError, concluí que não é conveniente complementá-lo.

Após a verificação, uma atualização estará disponível

// Lista de modificações:
// 08.02.2017:
// Adicionar: As variáveis MT4ORDERS::LastTradeRequest e MT4ORDERS::LastTradeResult contêm os dados MT5-OrderSend correspondentes.

Agora é possível receber todos os dados do MT5-OrderSend por completo.

 
// O script permite que você descubra rapidamente como formar uma solicitação MqlTradeRequest-request análoga à MT5 no MT5-OrderSend.

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

string ToString( const MqlTradeRequest &Request )
{
  return(TOSTRING2(Request.action) + TOSTRING(Request.magic) + TOSTRING(Request.order) +
         TOSTRING(Request.symbol) + TOSTRING(Request.volume) + TOSTRING(Request.price) +
         TOSTRING(Request.stoplimit) + TOSTRING(Request.sl) +  TOSTRING(Request.tp) +
         TOSTRING(Request.deviation) + TOSTRING2(Request.type) + TOSTRING2(Request.type_filling) +
         TOSTRING2(Request.type_time) + TOSTRING(Request.expiration) + TOSTRING(Request.comment) +
         TOSTRING(Request.position) + TOSTRING(Request.position_by));
}

string ToString( const MqlTradeResult &Result )
{
  return(TOSTRING(Result.retcode) + TOSTRING(Result.deal) + TOSTRING(Result.order) +
         TOSTRING(Result.volume) + TOSTRING(Result.price) + TOSTRING(Result.bid) +
         TOSTRING(Result.ask) + TOSTRING(Result.comment) + TOSTRING(Result.request_id) +
         TOSTRING(Result.retcode_external));
}

#include <MT4Orders.mqh>

#define PRINT(A) A; Print(#A + "\n" + ToString(MT4ORDERS::LastTradeRequest) + ToString(MT4ORDERS::LastTradeResult));

#define Point _Point
#define Bid (::SymbolInfoDouble(_Symbol, ::SYMBOL_BID))
#define Ask (::SymbolInfoDouble(_Symbol, ::SYMBOL_ASK))

void OnStart()
{
  Print(TOSTRING(AccountInfoString(ACCOUNT_SERVER)));
  
  // Posição aberta
  const int TicketPosition = PRINT(OrderSend(NULL, OP_BUY, 1, Ask, 100, 0, 0, "My Position"))

  if (OrderSelect(TicketPosition, SELECT_BY_TICKET))
  {
    // Definir SL/TP
    PRINT(OrderModify(OrderTicket(), OrderOpenPrice(), Bid - 100 * Point, Bid + 100 * Point, 0))

    // Fechou a posição
    PRINT(OrderClose(OrderTicket(), OrderLots(), Bid, 100))
  }

  // Definir uma ordem pendente
  const int TicketOrder = PRINT(OrderSend(NULL, OP_BUYLIMIT, 1, Ask - 100 * Point, 100, 0, 0, "My Order"))

  if (OrderSelect(TicketOrder, SELECT_BY_TICKET))
  {
    // O mandado foi removido
    PRINT(OrderDelete(OrderTicket()))
  }
}
[Excluído]  
Funciona muito bem, obrigado
 
O resultado do trabalho do script
AccountInfoString(ACCOUNT_SERVER) = FXOpen-MT5

OrderSend(NULL,OP_BUY,1,Ask,100,0,0,My Position)
Request.action = TRADE_ACTION_DEAL (1)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 1.0
Request.price = 1.06455
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 100
Request.type = ORDER_TYPE_BUY (0)
Request.type_filling = ORDER_FILLING_IOC (1)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment = My Position
Request.position = 0
Request.position_by = 0
Result.retcode = 10009
Result.deal = 9320
Result.order = 57775
Result.volume = 1.0
Result.price = 0.0
Result.bid = 0.0
Result.ask = 0.0
Result.comment = My Position
Result.request_id = 589
Result.retcode_external = 0

OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-100*Point,OrderOpenPrice()+100*Point,0)
Request.action = TRADE_ACTION_SLTP (6)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 0.0
Request.price = 0.0
Request.stoplimit = 0.0
Request.sl = 1.06355
Request.tp = 1.06555
Request.deviation = 0
Request.type = ORDER_TYPE_BUY (0)
Request.type_filling = ORDER_FILLING_FOK (0)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment =
Request.position = 57775
Request.position_by = 0
Result.retcode = 10009
Result.deal = 0
Result.order = 0
Result.volume = 1.0
Result.price = 0.0
Result.bid = 0.0
Result.ask = 0.0
Result.comment = Request executed
Result.request_id = 590
Result.retcode_external = 0

OrderClose(OrderTicket(),OrderLots(),Bid,100)
Request.action = TRADE_ACTION_DEAL (1)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 1.0
Request.price = 1.0645
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 100
Request.type = ORDER_TYPE_SELL (1)
Request.type_filling = ORDER_FILLING_IOC (1)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment =
Request.position = 57775
Request.position_by = 0
Result.retcode = 10009
Result.deal = 9321
Result.order = 57776
Result.volume = 1.0
Result.price = 0.0
Result.bid = 0.0
Result.ask = 0.0
Result.comment = Request executed
Result.request_id = 591
Result.retcode_external = 0

OrderSend(NULL,OP_BUYLIMIT,1,Ask-100*Point,100,0,0,My Order)
Request.action = TRADE_ACTION_PENDING (5)
Request.magic = 0
Request.order = 0
Request.symbol = EURUSD
Request.volume = 1.0
Request.price = 1.06356
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 100
Request.type = ORDER_TYPE_BUY_LIMIT (2)
Request.type_filling = ORDER_FILLING_IOC (1)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment = My Order
Request.position = 0
Request.position_by = 0
Result.retcode = 10009
Result.deal = 0
Result.order = 57777
Result.volume = 1.0
Result.price = 1.06356
Result.bid = 0.0
Result.ask = 0.0
Result.comment = My Order
Result.request_id = 592
Result.retcode_external = 0

OrderDelete(OrderTicket())
Request.action = TRADE_ACTION_REMOVE (8)
Request.magic = 0
Request.order = 57777
Request.symbol =
Request.volume = 0.0
Request.price = 0.0
Request.stoplimit = 0.0
Request.sl = 0.0
Request.tp = 0.0
Request.deviation = 0
Request.type = ORDER_TYPE_BUY (0)
Request.type_filling = ORDER_FILLING_FOK (0)
Request.type_time = ORDER_TIME_GTC (0)
Request.expiration = 1970.01.01 00:00:00
Request.comment =
Request.position = 0
Request.position_by = 0
Result.retcode = 10009
Result.deal = 0
Result.order = 57777
Result.volume = 1.0
Result.price = 1.06356
Result.bid = 0.0
Result.ask = 0.0
Result.comment = My Order
Result.request_id = 593
Result.retcode_external = 0
Agora é fácil entender como gerar corretamente as solicitações de negociação apropriadas no MT5.
 
// O script verifica as características de velocidade do processamento dos principais tipos de ordens de negociação do MT5.

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

string ToString( const MqlTradeRequest &Request )
{
  return(TOSTRING2(Request.action) + TOSTRING(Request.magic) + TOSTRING(Request.order) +
         TOSTRING(Request.symbol) + TOSTRING(Request.volume) + TOSTRING(Request.price) +
         TOSTRING(Request.stoplimit) + TOSTRING(Request.sl) +  TOSTRING(Request.tp) +
         TOSTRING(Request.deviation) + TOSTRING2(Request.type) + TOSTRING2(Request.type_filling) +
         TOSTRING2(Request.type_time) + TOSTRING(Request.expiration) + TOSTRING(Request.comment) +
         TOSTRING(Request.position) + TOSTRING(Request.position_by));
}

string ToString( const MqlTradeResult &Result )
{
  return(TOSTRING(Result.retcode) + TOSTRING(Result.deal) + TOSTRING(Result.order) +
         TOSTRING(Result.volume) + TOSTRING(Result.price) + TOSTRING(Result.bid) +
         TOSTRING(Result.ask) + TOSTRING(Result.comment) + TOSTRING(Result.request_id) +
         TOSTRING(Result.retcode_external));
}

ENUM_DAY_OF_WEEK GetDayOfWeek( const datetime time )
{
  MqlDateTime sTime = {0};

  ::TimeToStruct(time, sTime);

  return((ENUM_DAY_OF_WEEK)sTime.day_of_week);
}

bool SessionTrade( const string Symb )
{
  datetime TimeNow = ::TimeTradeServer();

  const ENUM_DAY_OF_WEEK DayOfWeek = GetDayOfWeek(TimeNow);

  TimeNow %= 24 * 60 * 60;

  bool Res = false;
  datetime From, To;

  for (int i = 0; (!Res) && ::SymbolInfoSessionTrade(Symb, DayOfWeek, i, From, To); i++)
    Res = ((From <= TimeNow) && (TimeNow < To));

  return(Res);
}

bool SymbolTrade( const string Symb )
{
  MqlTick Tick;

  return(::SymbolInfoTick(Symb, Tick) ? ((Tick.bid != 0) && (Tick.ask != 0) && SessionTrade(Symb) &&
         ((ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(Symb, SYMBOL_TRADE_MODE) == SYMBOL_TRADE_MODE_FULL)) : false);
}

#define MT4ORDERS_BENCHMARK Alert(MT4ORDERS::LastTradeRequest.symbol + " " +       \
                                  (string)MT4ORDERS::LastTradeResult.order + " " + \
                                  MT4ORDERS::LastTradeResult.comment);             \
                            Print(ToString(MT4ORDERS::LastTradeRequest) +          \
                                  ToString(MT4ORDERS::LastTradeResult));

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


#define Point (SymbolInfoDouble(Symb, SYMBOL_POINT))
#define Bid (SymbolInfoDouble(Symb, SYMBOL_BID))
#define Ask (SymbolInfoDouble(Symb, SYMBOL_ASK))

void Benchmark( string Symb = NULL, uint LimitOffset = 1000 )
{
  if (Symb == NULL)
    Symb = _Symbol;

  if (SymbolTrade(Symb))
  {
    const bool DemoAccount = ((ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_DEMO);
    const double MinLot = SymbolInfoDouble(Symb, SYMBOL_VOLUME_MIN);

    const uint StopLevel = (uint)SymbolInfoInteger(Symb, SYMBOL_TRADE_STOPS_LEVEL);

    if (StopLevel != 0)
      LimitOffset = StopLevel;

    if (DemoAccount && OrderSelect(OrderSend(Symb, OP_BUY, MinLot, Ask, 100, 0, 0, __FUNCTION__ + "_Position"), SELECT_BY_TICKET))
    {
      OrderModify(OrderTicket(), OrderOpenPrice(), 0, Bid + LimitOffset * Point, 0);
      OrderClose(OrderTicket(), OrderLots(), Bid, 100);
    }

    double PriceMin = SymbolInfoDouble(Symb, SYMBOL_SESSION_PRICE_LIMIT_MIN);

    if (PriceMin < Point)
      PriceMin = MathMax(Ask - LimitOffset * Point, Point);

    if ((PriceMin < Ask) &&
        OrderSelect(OrderSend(Symb, OP_BUYLIMIT, MinLot, PriceMin, 100, 0, 0, __FUNCTION__ + "_Order"), SELECT_BY_TICKET) &&
        (!OrderDelete(OrderTicket())) && (!DemoAccount))
    {
      Alert("OrderDelete ERROR, Check Now!");

      ExpertRemove();
    }
  }
}
void OnStart()
{
  if ((ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_DEMO) // comente se quiser verificar o que é real
  {
    Alert(TOSTRING(AccountInfoString(ACCOUNT_SERVER)));
    Alert(TOSTRING(TerminalInfoInteger(TERMINAL_PING_LAST)));

    while (!IsStopped())
      for (int i = SymbolsTotal(true) - 1; (i >= 0) && (!IsStopped()); i--)
        Benchmark(SymbolName(i, true));
  }
}

Com a ajuda desse script, consegui encontrar problemas de execução no MT5. Recomendo que você verifique seu Terminal+Servidor de Negociação e, em caso de problemas, informe a Central de Serviços.

[Excluído]  
fxsaber:

Com a ajuda desse script, consegui encontrar problemas de execução no MT5. Recomendo que você verifique seu Terminal+Trading Server e, em caso de problemas, informe ao Service Desk.

Ou seja, a versão 1533 já fornece informações sobre atrasos no result.comment?
 
Alexey Kozitsyn:
Então o build 1533 já fornece informações de atraso no result.comment?

Não, isso é feito pela biblioteca.

O segundo número é o tempo que leva para sincronizar o histórico de ordens (negociações) após a execução do OrderSend (depois de quanto tempo o evento correspondente em OnTradeTransaction é recebido).

Na captura de tela, esse número chegou a 28 ms, o que é extremamente alto. Os SDs também estão lidando com esse problema.

Se o MT5 passar nesse teste de estresse sem nenhuma dúvida, será muito bom. Todos podem testar seu MT5.

 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Scripts: CloseAllPositions

fxsaber, 2017.03.30 14:11

// Código MQL4&5

#property script_show_inputs

#include <MT4Orders.mqh>

sinput int RTOTAL = 4;            // Número de repetições para transações malsucedidas
sinput int SLEEPTIME = 1;         // Tempo de pausa entre as repetições em segundos
sinput int Deviation_ = 10;       // Desvio de preço
sinput bool exAllSymbols = false; // false - somente o caractere atual, true - todos os caracteres

#define _CS(A) ((!IsStopped()) && (A))

bool CloseAllPositions( const bool AllSymbols = true, const int Slippage = 0 )
{
  bool Res = true;
  
  MqlTick Tick;
  
  for (int i = OrdersTotal() - 1; _CS(i >= 0); i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) &&
        (AllSymbols ? true : (OrderSymbol() == Symbol())) && SymbolInfoTick(OrderSymbol(), Tick))
      Res &= OrderClose(OrderTicket(), OrderLots(), (OrderType() == OP_BUY) ? Tick.bid : Tick.ask, Slippage);
      
  return(Res);
}

void OnStart()
{
  for (int i = 0; _CS((i < RTOTAL) && (!CloseAllPositions(exAllSymbols, Deviation_))); i++)
    Sleep(SLEEPTIME * 1000);
}