Bibliotheken: MT4Orders - Seite 11

 
Aliaksandr Kryvanos:
Ich sehe, können Sie mir eine Idee geben, wie GetLastError() zu bekommen , um Handel Server-Fehler als auch ausgeben, ich würde es selbst schreiben, wenn Sie nicht Zeit noch haben. Danke
Ähnlich wie OrdersTotal implementiert ist. Ich werde wahrscheinlich ein erweitertes GetLastError schreiben. Und auch GetLastTradeRequest() und GetLastTradeResult().
 
fxsaber:
Wahrscheinlich werde ich ein erweitertes GetLastError schreiben. Und auch GetLastTradeRequest() und GetLastTradeResult().

Nachdem ich GetLastError untersucht habe, bin ich zu dem Schluss gekommen, dass es nicht sinnvoll ist, es zu ergänzen.

Nach der Überprüfung wird ein Update verfügbar sein

// Liste ändern:
// 08.02.2017:
// Hinzufügen: Die Variablen MT4ORDERS::LastTradeRequest und MT4ORDERS::LastTradeResult enthalten die entsprechenden MT5-OrderSend-Daten.

Jetzt ist es möglich, alle MT5-OrderSend-Daten vollständig zu empfangen.

 
// Das Skript ermöglicht es Ihnen, schnell herauszufinden, wie man einen MT5-konformen MT4-analogen MqlTradeRequest-Request in MT5-OrderSend bildet.

#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)));
  
  // Position öffnen
  const int TicketPosition = PRINT(OrderSend(NULL, OP_BUY, 1, Ask, 100, 0, 0, "My Position"))

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

    // Schließen der Position
    PRINT(OrderClose(OrderTicket(), OrderLots(), Bid, 100))
  }

  // Einen schwebenden Auftrag einstellen
  const int TicketOrder = PRINT(OrderSend(NULL, OP_BUYLIMIT, 1, Ask - 100 * Point, 100, 0, 0, "My Order"))

  if (OrderSelect(TicketOrder, SELECT_BY_TICKET))
  {
    // Der Haftbefehl wurde entfernt
    PRINT(OrderDelete(OrderTicket()))
  }
}
[Gelöscht]  
Funktioniert prima, danke
 
Das Ergebnis der Skriptarbeit
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
Jetzt ist es leicht zu verstehen, wie man im MT5 die richtigen Handelsaufträge generiert.
 
// Das Skript prüft die Geschwindigkeitscharakteristiken der Verarbeitung der wichtigsten Arten von MT5-Handelsaufträgen.

#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/de/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) // kommentieren Sie aus, wenn Sie das echte Ding überprüfen wollen
  {
    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));
  }
}

Mit Hilfe dieses Skripts ist es mir gelungen, Ausführungsprobleme im MT5 zu finden. Ich empfehle Ihnen, Ihren Terminal+Trading Server zu überprüfen und im Falle von Problemen dem Service Desk zu berichten.

[Gelöscht]  
fxsaber:

Mit Hilfe dieses Skripts ist es mir gelungen, Ausführungsprobleme im MT5 zu finden. Ich empfehle Ihnen, Ihren Terminal+Trading Server zu überprüfen und im Falle von Problemen dem Service Desk zu berichten.

D.h. in Build 1533 gibt es bereits Informationen über Verzögerungen in result.comment?
 
Alexey Kozitsyn:
Gibt Build 1533 also bereits Verzögerungsinformationen in result.comment an?

Nein, dies wird von der Bibliothek erledigt.

Die zweite Zahl gibt an, wie lange es dauert, die Historie der Aufträge (Trades) nach der OrderSend-Ausführung zu synchronisieren (nach der Zeit, in der das entsprechende Ereignis in OnTradeTransaction empfangen wird).

Auf dem Screenshot hat diese Zahl 28 ms erreicht - das ist extrem hoch. Auch die SDs haben mit diesem Problem zu kämpfen.

Wenn MT5 diesen Stresstest ohne Fragen besteht, ist das sehr gut. Jeder kann seinen MT5 testen.

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Skripte: CloseAllPositions

fxsaber, 2017.03.30 14:11

// MQL4&5-Code

#property script_show_inputs

#include <MT4Orders.mqh>

sinput int RTOTAL = 4;            // Anzahl der Wiederholungen für erfolglose Transaktionen
sinput int SLEEPTIME = 1;         // Pausenzeit zwischen den Wiederholungen in Sekunden
sinput int Deviation_ = 10;       // Preisabweichung
sinput bool exAllSymbols = false; // false - nur das aktuelle Zeichen, true - alle Zeichen

#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);
}