Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 3

 
fxsaber:

Was könnte OnTradeTransaction in einem Handelsskript sein? Nicht in Ihrem Code, sondern in dem Handelsskript eines anderen.
Glauben Sie ernsthaft, dass ein vollwertiger Handelsroboter in einem Skript geschrieben werden kann?
 
Freunde, lasst uns bitte näher am Thema bleiben: Ich würde gerne Beispiele für die Umsetzung dieser oder jener Aussage sehen. Nicht unbedingt Code, wenn es viel davon gibt, kann man die Logik beschreiben, z. B. Anfrage senden, um sicherzugehen, dass sie gesendet wurde, dort nachsehen, wenn wir so und so einen Rückgabewert erhalten, so und so machen. D.h. Beispiele für die zuverlässigste Art und Weise, Daten zu erhalten.

Andernfalls werden wir, wenn wir uns streiten, von einem nützlichen Thema zu einem seitenlangen Gezänk übergehen. Dann müssen wir das Ganze säubern, um das Wesentliche zu erhalten... Genau, ich möchte die Essenz dieses oder jenes Prozesses. Es soll mehrere Versionen einer Implementierung von etwas geben. Es wird möglich sein, die Vor- und Nachteile der einzelnen Methoden zu erörtern.

Wenn dann genügend verschiedene nützliche Informationen zusammengekommen sind, besteht die Idee, diese in einer Tabelle zusammenzufassen. Und füllen Sie es immer wieder auf, wenn die nächsten nützlichen Chips gesammelt werden.
Ich denke, das wird für alle nützlich sein.
 
Frage: Wie konvertiert man eine Zahl in das Oktal- und Hexadezimalsystem?

Antworten:
1.

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

8 und 16 ricas

Taras Slobodyanik, 2017.02.24 22:16

string DecToHex(int n)
  {
   string s = "", c;
   while(n != 0)
     {
      if(n%16<10)
         c=CharToStr(n%16+'0');
      else
         c=CharToStr(n%16+'A'-10);
      s = c + s;
      n = n / 16;
     }
   return(s);
  }
2.

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

8 und 16 ricas

Maxim Kuznetsov, 2017.02.24 22:20

Plötzlich, StringFormat, PrintFormat :-)

PrintFormat("Hex %x und octal %o",1122,1122);
3.

Forum zum Thema Handel, automatische Handelssysteme und Testen von Handelsstrategien

8 und 16 ricas

fxsaber, 2017.02.24 22:21

string NumToString( uint Num, const uint Scale = 10 )
{
  static const string digits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
                                  "A", "B", "C", "D", "E", "F", "G", "H", "I", "K",
                                  "L", "M", "N", "O", "P", "Q", "R", "S", "T", "V", "X", "Y", "Z"};
  
  string Str = (Num == 0) ? "0" : "";
  
  while (Num > 0)
  {
    Str = digits[Num % Scale] + Str;
    
    Num /= Scale;
  }
  
  return(Str);
}

void OnStart()
{
  Print(NumToString(123, 8));
  Print(NumToString(123, 16));
}



 
Prostotrader:
Glauben Sie ernsthaft, dass ein vollwertiger Handelsroboter in einem Skript geschrieben werden kann?
Sie können
 
Alexey Kozitsyn:

Verschieben Sie die Diskussion der Kameraden fxsaber und prostotrader in einen separaten Thread, wenn hier diskutiert wird, verliert der Thread seine praktische Relevanz. Wenn sie eine echte Lösung gefunden haben, werden sie sie hier veröffentlichen. Und meiner Meinung nach sollte dies kein Zweifels- oder Forschungsbereich sein. Es sollte eine Branche mit praktischen Lösungen sein. Und wenn ein paar Leute unterschiedliche Ansichten zu dem Thema haben, dann sollen sie es woanders diskutieren.

<Post zum Löschen

Lassen wir die Wahrheit ans Licht kommen. Ich hatte Zeit, darüber nachzudenken und beschloss, es zu posten, und Vitya (Vinin), den ich gefragt und gebeten hatte, meine Zweifel zu zerstreuen, schlug ebenfalls vor, eine Diskussion zu posten (was meine Zweifel an der Löschung bestätigte) - damit die Wahrheit ans Licht kommt. Ich denke, das wäre das Richtige zu tun. Ich werde nachher sowieso mit der Auswertung beginnen, so dass ich sie hier veröffentlichen kann, wenn sie sich füllt.
 
Prostotrader:

Sie müssen nicht ein paar Millisekunden warten.

Die Nachricht wird in OnTradeTransaction erscheinen

siehe Code

Was ist der Sinn Ihrer Botschaft? Es wird in OnTradeTransaction() eintreffen, was bedeutet, dass wir auf das Ereignis warten müssen. Wir warten trotzdem. Die Meldung von fxsaber besagt, dass nach der Ausführung von OrderSend() nicht sofort Informationen über die ausgeführte Aktion im Terminal erscheinen. Manche Leute warten gerne auf OnTradeTransaction(), während andere gerne einen Auftrag oder ein Geschäft in der Liste sehen möchten. Hier ist der Unterschied zu MT4, als Beispiel. In M4 befindet sich der Auftrag nach OrderSend() bereits in der Auftragsliste und nach OrderClose() immer in der Historie.

 
Artyom Trishkin:
Lassen wir die Wahrheit ans Licht kommen. Ich hatte Zeit, darüber nachzudenken und beschloss, die Diskussion zu beenden, und Vitya (Vinin), den ich gebeten hatte, meine Zweifel zu zerstreuen, schlug ebenfalls vor, die Diskussion zu beenden (und bestätigte damit meine Zweifel an der Löschung) - die Wahrheit möge geboren werden. Ich denke, das wäre das Richtige zu tun. Ich werde nachher sowieso eine Tabelle erstellen, die hier veröffentlicht wird, sobald sie sich füllt.
In Auseinandersetzungen mit prostotrader mag die Wahrheit nicht auftauchen, das ist nicht der Grund, warum er sie beginnt. Wie üblich weiß er nicht einmal, wovon er spricht.
 
Was für ein Argument gibt es überhaupt? Dies ist unbestritten. fxsaber hat uns auf eine Funktion des Terminals aufmerksam gemacht, die wirklich undokumentiert ist und die jeder kennen sollte, da es sonst bei der Entwicklung von EAs zu Problemen kommt, die man später suchen und bereinigen muss.
 
Artyom Trishkin:
Lassen wir die Wahrheit ans Licht kommen...

Artjom!

Sie sind ein vernünftiger und politisch korrekter Mensch!

Welche Wahrheit? Sie wissen genau, wovon wir sprechen.

fxsaber hat ein Skript geschrieben (nicht schlecht), aber niemand hat es gelobt, also hat er

versucht, in jedem Thread daran zu erinnern.

Gut gemacht!

Aber hier ist das Problem, können Sie nicht verwenden OnTradeTransaction in diesem Skript, so hat er zu "rollen Bälle" (wie Sleep oder einem anderen Timer) von "Mr. OnTradeTransaction".

Und natürlich die "Sorge" um andere Nutzer, die noch nicht wissen, dass SCRIPT besser ist als COUNTER!

Dmitry Fedoseev ist immer gegen das, was ich sage, egal, ob ich Recht habe oder nicht.

Die Wahrheit kann hier nicht gefunden werden, denn es ist keine Ursache, sondern eine persönliche, die im Vordergrund steht.

 
class ORDERSEND  
{
private:
  static const bool IsTester;
  
  static bool Waiting( const bool FlagInit = false )
  {
    static ulong StartTime = 0;

    const bool Res = FlagInit ? false : (::GetMicrosecondCount() - StartTime < ORDERSEND::OrderSend_MaxPause);

    if (FlagInit)
      StartTime = ::GetMicrosecondCount();
    else if (Res)
      ::Sleep(0);

    return(Res);
  }

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

  static bool HistoryDealSelect( MqlTradeResult &Result )
  {
    if ((Result.deal == 0) && (Result.order != 0))
    {
      if (::HistorySelectByPosition(::HistoryOrderGetInteger(Result.order, ORDER_POSITION_ID)))
        for (int i = ::HistoryDealsTotal() - 1; i >= 0; i--)
        {
          const ulong DealTicket = ::HistoryDealGetTicket(i);

          if (Result.order == ::HistoryDealGetInteger(DealTicket, DEAL_ORDER))
          {
            Result.deal = DealTicket;

            break;
          }
        }
    }

    return(::HistoryDealSelect(Result.deal));
  }

#define TMP_ORDERSEND_BENCHMARK(A) \
  static ulong Max##A = 0;         \
                                   \
  if (Interval##A > Max##A)        \
  {                                \
    ORDERSEND_BENCHMARK            \
                                   \
    Max##A = Interval##A;          \
  }

  static void OrderSend_Benchmark( const ulong Interval1, const ulong Interval2 = 0 )
  {
    #ifdef ORDERSEND_BENCHMARK
      TMP_ORDERSEND_BENCHMARK(1)
      TMP_ORDERSEND_BENCHMARK(2)
    #endif // ORDERSEND_BENCHMARK

    return;
  }

#undef TMP_ORDERSEND_BENCHMARK

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

public:
  static uint OrderSend_MaxPause; // максимальное время на синхронизацию в мкс.
  
  // Полностью синхронизированный с торговым окружением OrderSend.
  // По окончании работы ГАРАНТИРОВАННО и за МИНИМАЛЬНОЕ время доступно корректное торговое окружение.
  // По скорости ничем не уступает связке OrderSendAsync + OnTradeTransaction.
  // Учтены MT5-нюансы: Result.deal == 0, STATE_STARTED и STATE_MODIFY pending.
  // В тестере/оптимизаторе производительность равна штатной OrderSend.

  static bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
  {
    const ulong StartTime1 = ::GetMicrosecondCount();

    bool Res = ::OrderSend(Request, Result);

    const ulong Interval1 = ::GetMicrosecondCount() - StartTime1;

    const ulong StartTime2 = ::GetMicrosecondCount();

    if (Res && !ORDERSEND::IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (ORDERSEND::OrderSend_MaxPause > 0))
    {
      Res = (Result.retcode == TRADE_RETCODE_DONE);
      ORDERSEND::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(ORDERSEND::HistoryDealSelect(Result))
            ;
      }
      else if (Request.action == TRADE_ACTION_PENDING)
      {
        if (Res)
          WHILE(::OrderSelect(Result.order) && ((ENUM_ORDER_STATE)::OrderGetInteger(ORDER_STATE) == ORDER_STATE_PLACED))
            ;
        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 = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
            EqualTP = ORDERSEND::EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
          }

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

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

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

          WHILE((EqualSL && EqualTP && EqualPrice))
            if (::OrderSelect(Result.order) && ((ENUM_ORDER_STATE)::OrderGetInteger(ORDER_STATE) != ORDER_STATE_REQUEST_MODIFY))
            {
              EqualSL = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
              EqualTP = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
              EqualPrice = ORDERSEND::EqualPrices(::OrderGetDouble(ORDER_PRICE_OPEN), Request.price, digits);
            }
        }
      }
      else if (Request.action == TRADE_ACTION_REMOVE)
        if (Res)
          WHILE(::HistoryOrderSelect(Result.order))
            ;
    }

    const ulong Interval2 = ::GetMicrosecondCount() - StartTime2;

    Result.comment += " " + ::DoubleToString(Interval1 / 1000.0, 3) + " + " + ::DoubleToString(Interval2 / 1000.0, 3) + " ms";

    ORDERSEND::OrderSend_Benchmark(Interval1, Interval2);

    return(Res);
  }

#undef WHILE
};

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

static uint ORDERSEND::OrderSend_MaxPause = 1000000; // максимальное время на синхронизацию в мкс.

// Эта строчка позволяет сделать все OrderSend корректными.
#define OrderSend ORDERSEND::OrderSendSync

Im Klassenzimmer wird alles absichtlich verpackt, um die Zahl der möglichen Probleme zu verringern.

Verwendung von

OrderSend(Request, Result); // Все так же, как со штатной OrderSend

Das heißt, um alle OrderSend mit der Handelsumgebung zu synchronisieren und die Fallstricke zu vermeiden, ist es ausreichend, diesen Quellcode als mqh-Datei zu schreiben und das entsprechende #include in Ihren Programmen zu verwenden.

Grund der Beschwerde: