Wie man im MT5 mit OrderSend korrekt arbeitet - Seite 9

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

Tut mir leid, ich habe keine Lust, mich mit Ihren Skripten zu beschäftigen.

Hinzugefügt von

Aber es gibt einen Ausweg.

Da die Funktion OrderrSend() synchron ist, werden wir nach Erhalt der Bestellung

Sicherstellen, dass die Historie in OnTradeTransaction() synchronisiert wird

//+------------------------------------------------------------------+
// 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;
     }
  }

Und nicht tanzen!

 
prostotrader:

Tanzen verboten!

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Wie man im MT5 mit OrderSend korrekt arbeitet

fxsaber, 2016.11.10 10:00

Beachten Sie, dass es sich um ein Skript handelt und es keine Event-overs geben kann. Der einzige Ausweg ist ein dummer Schlaf.

Wenn Sie dieses Skript mit SB neu schreiben, wird sich nichts ändern.

 
fxsaber:
DU kannst dich mit Sleep.... nach Herzenslust austoben.
 
prostotrader:
Sie können mit dem Schlaf spielen, wie Sie wollen....

Warum sollte man dasselbe wiederholen, was bereits von anderen vorgeschlagen und geäußert wurde?

Der Thread sagt alles über mögliche Probleme mit OnTradeTransaction. Dies betrifft insbesondere den gleichzeitigen Betrieb mehrerer Expert Advisors.

Die Leute machen Krücken, was nicht bedeutet, dass sie die Dokumentation nicht kennen und nicht wissen, wie sie die Funktionen nutzen können.

OnTrade und OnTradeTransaction sind genau für diesen Zweck entwickelt worden. Als sie damit begannen, dachten die Entwickler, dass es idiotisch wäre, mehr als einen Expert Advisor gleichzeitig in einem Konto zu verwenden.

Nun, damit lagen sie falsch.

Versuchen Sie, die folgende Funktion in Ihren Expert Advisor zu schreiben

  1. i = 0.
  2. Wir eröffnen eine Position auf Symbol[i].
  3. Wenn i++ >= 5 ist, wird der Vorgang abgebrochen.
  4. Wenn es keinen Schlupf gibt, kehren wir zu Schritt 2 zurück, wenn es einen Schlupf gibt, verlassen wir den Vorgang.
 
fxsaber:

Warum sollte man das Gleiche wiederholen, was bereits von anderen vorgeschlagen und geäußert wurde?

Der Thread sagt alles über mögliche Probleme mit OnTradeTransaction. Dies betrifft insbesondere den gleichzeitigen Betrieb mehrerer Expert Advisors.

Die Leute machen Krücken, was nicht bedeutet, dass sie die Dokumentation nicht kennen und nicht wissen, wie sie die Funktionen nutzen können.

OnTrade und OnTradeTransaction sind genau für diesen Zweck entwickelt worden. Als sie damit begannen, dachten die Entwickler, dass es idiotisch wäre, mehr als einen Expert Advisor gleichzeitig in einem Konto zu verwenden.

Nun, damit lagen sie falsch.

Versuchen Sie, die folgende Funktion in Ihren Expert Advisor zu schreiben

  1. i = 0.
  2. Wir eröffnen eine Position auf Symbol[i].
  3. Wenn i++ >= 5 ist, wird der Vorgang abgebrochen.
  4. Wenn es keinen Schlupf gibt, kehren wir zu Schritt 2 zurück, wenn es einen Schlupf gibt, verlassen wir den Vorgang.

Ich habe derzeit 41 Expert Advisors auf einem realen Konto (in einem Terminal), die gemeinsam während eines Handelstages arbeiten

Sie stellen 2000 Aufträge zum Öffnen und Schließen von Positionen ein, und ich habe überhaupt keine Schwierigkeiten!

Hinzugefügt

Was den Funktionsumfang angeht, so sollte er sich an dem orientieren, was wir haben, und nicht an dem, was wir "brauchen".

Entwickler, wenn möglich, beheben Fehler und Bugs, unter Berücksichtigung der Wünsche der

Nutzer (wenn auch sehr langsam).

Ich denke, sie werden sich bald auch mit OederSend() beschäftigen.

 
prostotrader:

Ich habe 41 Expert Advisors auf meinem realen Konto (in einem Terminal), die alle zusammen an einem Handelstag arbeiten.

Sie setzen 2000 Aufträge, öffnen und schließen Positionen und ich habe überhaupt keine Probleme!

Das nennt man "vom Thema abweichen".

Auch wenn es um die einfachste Logik geht.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wie man im MT5 mit OrderSend korrekt arbeitet

fxsaber, 2016.11.15 13:30

Versuchen Sie, die folgende Funktion in Ihren EA zu schreiben

  1. i = 0.
  2. Eröffnen Sie eine Position auf Symbol[i].
  3. Wenn i++ >= 5 ist, wird der Vorgang abgebrochen.
  4. Wenn die neue Position keinen Slippage aufweist, kehren wir zu Schritt 2 zurück, bei einem Slippage verlassen wir den Markt.
Jemand tauscht es sofort aus.
// 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);
}

Und jemand wartet auf Mana von den Entwicklern.
 

Ich habe bereits gesagt, dass es Ihnen freisteht, den Text so zu verdrehen, wie Sie wollen (dieses Recht hat jeder).

 
prostotrader:

Ich habe bereits gesagt, dass es Ihnen freisteht, die Dinge so zu verdrehen, wie Sie wollen (jeder hat dieses Recht).

Es ist schon lange her, aber ich erinnere mich an diesen Kerl, nun, dieserfxsaber hat Wunder vollbracht,

seine Codes sind immer noch in der MT4-Codebasis gespeichert, sein Code zum Lesen von Websites im WinInet

wird immer noch von vielen Programmierern verwendet...

und deshalb, so scheint es mir, ist er kein Perverser...

 
Riss die OrderSendSync aus der Bibliothek hier
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
Die Idee des Codes sollte klar sein. Vielleicht habe ich etwas übersehen. Ich habe keine Fehler im Betrieb festgestellt.