Bibliotheken: MT4Orders - Seite 19

 
Jeka77769:

Hallo! In der Beschreibung steht: "Dementsprechend kann OrderSelect im SELECT_BY_TICKET Modus in MT5 in seltenen Fällen (im Tester) nicht das auswählen, was in MT4 vorgesehen war. "Können Sie genauer erläutern, in welchen Fällen genau?

Wenn Position/Handel/Auftragstickets übereinstimmen.

 
Ein weiteres Beispiel(Beschreibung) für plattformübergreifenden Code

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Expert Advisors: eaBreakeven

fxsaber, 2018.01.11 08:13 Uhr.

#include <MT4Orders.mqh>     // https://www.mql5.com/de/code/16006
#include <Price_Compare.mqh> // https://www.mql5.com/de/code/16169

input int    Breakeven           = 15;           //Breakeven in Punkten
input int    Distance            = 5;            //Breakeven-Abstand in Punkten vom Eröffnungskurs der Position
input int    MagicNumber         = 16112017;     //Magische Zahl
input bool   EnableSound         = true;         /Aktivieren/Deaktivieren der Tonwiedergabe bei Erreichen des Break-Even-Wertes
input string SoundFile           = "alert1.wav"; //Tondateiname

void OnTick()
{
  DoBreakeven();
}

double GetNewStopLoss()
{
  const double point = SymbolInfoDouble(OrderSymbol(), SYMBOL_POINT);  
  const double stop_level = SymbolInfoInteger(OrderSymbol(), SYMBOL_TRADE_STOPS_LEVEL) * point;
  
  const double price_open = OrderOpenPrice();
  const double latest_price = OrderClosePrice();  
  const double stoploss = OrderStopLoss();

  double new_stoploss = 0;
  
  //--- Stop-Loss zum Breakeven-Kurs + Abstand verschieben, wenn Positionsgewinn größer als Breakeven-Punkte 
  return(((OrderType() == OP_BUY)  && (CP(latest_price - price_open, point) >= Breakeven * point) &&
                                      (CP(new_stoploss = price_open + Distance * point, point) > stoploss) &&
                                      (CP(latest_price - new_stoploss, point) > stop_level)) ||
         ((OrderType() == OP_SELL) && (CP(price_open - latest_price, point) >= Breakeven * point) &&
                                      ((CP(new_stoploss = price_open - Distance * point, point) < stoploss) || !stoploss) &&
                                      (CP(new_stoploss - latest_price, point) > stop_level))
         ? NormalizeDouble(new_stoploss, (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_DIGITS)) : 0);
}

void DoBreakeven()
{
//Wenn Breakeven negativ ist, dann deaktivieren Sie die Breakeven-Funktion
  if (Breakeven >= 0)      
  //Schleife für Positionen
    for (int i = OrdersTotal() - 1; i >= 0; i--)
      if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (!MagicNumber || (OrderMagicNumber() == MagicNumber)))
      {
        const double new_stoploss = GetNewStopLoss();
        
        if (new_stoploss)      
        {
          if (!OrderModify(OrderTicket(), OrderOpenPrice(), new_stoploss, OrderTakeProfit(), OrderExpiration()))
            Print(GetLastError());
          else if(EnableSound)
            PlaySound(SoundFile);
        }
      }
}
 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wie kann man das Volumen einer Pending Order ändern?

fxsaber, 2018.01.19 16:34

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

// Ändert das Volumen des anhängigen Auftrags. Async = true - asynchroner Modus für das Senden von Aufträgen
bool OrderChangeLots( const long Ticket, const double Lots, const bool Async = false )
{
  return(OrderSelect(Ticket, SELECT_BY_TICKET) && (Lots != OrderLots()) && (Async
         ? (OrderDeleteAsync(Ticket) &&
            OrderSendAsync(OrderSymbol(), OrderType(), Lots, OrderOpenPrice(), 0, OrderStopLoss(), OrderTakeProfit(), OrderComment(), OrderMagicNumber(), OrderExpiration()))
         : (OrderDelete(Ticket) &&
            (OrderSend(OrderSymbol(), OrderType(), Lots, OrderOpenPrice(), 0, OrderStopLoss(), OrderTakeProfit(), OrderComment(), OrderMagicNumber(), OrderExpiration()) != -1))));
}

void OnStart()
{
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderType() >= OP_BUYLIMIT))
      OrderChangeLots(OrderTicket(), OrderLots() + 1, true);
}
 
Je besser ein MT4 Expert Advisor geschrieben ist, desto einfacher ist es, ihn in MT5 zu konvertieren. Und die Größe/Komplexität des ursprünglichen EAs spielt bei der Konvertierung keine Rolle.

Forum über Trading, automatisierte Handelssysteme und das Testen von Handelsstrategien.

Expert Advisors: Three Point Arbitrage

fxsaber, 2018.01.20 09:58

#define  MT4_TICKET_TYPE  // OrderSend und OrderTicket müssen einen Wert desselben Typs wie in MT4 zurückgeben - int.
#include <MT4Orders.mqh> // https://www.mql5.com/de/code/16006

#define MODE_MARGINREQUIRED 0

// https://www.mql5.com/ru/forum/170952/page9#comment_4134898
// Der Betrag der freien Mittel, der erforderlich ist, um 1 Los zum Kauf zu eröffnen
double MarketInfo( const string Symb, const int )
{
  MqlTick Tick;
  double MarginInit, MarginMain;

  return((SymbolInfoTick(Symb, Tick) && SymbolInfoMarginRate(Symb, ORDER_TYPE_BUY, MarginInit, MarginMain)) ? MarginInit * Tick.ask *
          SymbolInfoDouble(Symb, SYMBOL_TRADE_TICK_VALUE) / (SymbolInfoDouble(Symb, SYMBOL_TRADE_TICK_SIZE) * AccountInfoInteger(ACCOUNT_LEVERAGE)) : 0);
}

int DayOfWeek( void )
{
  MqlDateTime sTime = {0};

  TimeToStruct(TimeCurrent(), sTime);

  return(sTime.day_of_week);
}

int Hour( void )
{
  return((int)((TimeCurrent() % (24 * 3600)) / 3600));
}

#include "ThreePoint.mq4"
 
Wenn die OnTradeTransaction ermöglicht es Ihnen, einen Nicht-Handels-Advisor (Service) zu schreiben, der das Vorhandensein eines Handels-"Klon"-Advisors verfolgt, der auf dem Konto läuft.
 

Schließung einer Position sofort vom Saldo abgezogen.

  • Aus diesem Grund zeigt Equity vor dem Schließen aller Positionen nicht an, wie hoch der Saldo nach dem Schließen sein wird.
  • Dies bedeutet, dass es einfach nicht möglich ist, den Break-even in MT5 zu berechnen.
  • MT4Orders hat immer noch eine Kommission für Positionen. Aus diesem Grund tritt die folgende Situation auf

    #include <MT4Orders.mqh>
    
    #define  PRINT(A) Print(#A + " = " + (string)(A))
    
    void OnStart()
    {
      double ProfitWithoutCommission = 0;
      double ProfitWithCommission = 0;  
      
      for (int i = OrdersTotal(); i >= 0; i--)
        if (OrderSelect(i, SELECT_BY_POS))
        {
          OrderPrint();
          
          ProfitWithoutCommission += OrderProfit() + OrderSwap(); // Berechnen Sie den aktuellen Gewinn ohne Berücksichtigung der Provision
          
          ProfitWithCommission += OrderProfit() + OrderSwap() + OrderCommission(); // Berechnen Sie den aktuellen Gewinn unter Berücksichtigung der Provision
        }
            
      PRINT(AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE));
      
      PRINT(ProfitWithoutCommission);
      PRINT(ProfitWithCommission);  
    }


    Ergebnis

    #895889 2018.02.08 09:08:26 sell 1.00 EURUSD 1.22807 0.00000 0.00000 1.22877 -6.14 0.00 -70.00 0
    AccountInfoDouble(ACCOUNT_EQUITY)-AccountInfoDouble(ACCOUNT_BALANCE) = -70.0
    ProfitWithoutCommission = -70.0
    ProfitWithCommission = -76.14


    Wie Sie sehen, unterscheidet sich die Differenz zwischen Equity und Balance um die Höhe der Provision. Und es mag scheinen, dass der klassische MT4-Ausdruck

    ProfitWithCommission += OrderProfit() + OrderSwap() + OrderCommission(); // Berechnen Sie den aktuellen Gewinn unter Berücksichtigung der Provision

    in MT5 seine Bedeutung verliert. Aber das ist nicht der Fall. Wenn Sie nämlich eine Position schließen, ändert sich der Saldo um diesen Betrag, nicht um den, den das Eigenkapital vorher anzeigte. Grob gesagt, ist der Wert des Eigenkapitals im MT5 falsch, wenn man dieses Konzept im MT4 betrachtet.

    Berücksichtigen Sie diese Besonderheit von MT5. Die Bibliothek ist in diesem Fall genauer. Und es wird einfach sein, den gleichen Break-Even zu berechnen.

     

    offenen Position zu verlieren. Um dies zu tun, reicht es aus, einen Handel ohne Kommentar zum Positionssymbol zu machen.

    Die Bibliothek wird den Kommentar in dem beschriebenen Fall nicht verlieren - OrderComment() wird den Kommentar erzeugen, der bei der Eröffnung der Position vorhanden war.

     
    // Liste ändern:
    // 13.02.2018
    // Hinzufügen: MT5-OrderSend-Fehlerprotokollierung hinzugefügt.
    // Fix: Jetzt sind nur noch schließende MT5-Orders (SL/TP/SO, partial/full close) "unsichtbar".
    // Fix: Der Mechanismus zur Bestimmung von SL/TP von geschlossenen Positionen nach OrderClose wurde korrigiert - funktioniert, wenn StopLevel es erlaubt.
     

    Eine Besonderheit des MT5-Betriebswird hier im Detail beschrieben. Die Bibliothek hat diese Situation lange Zeit korrekt verarbeitet. Aber sie hat geflucht (Alert), dass die Situation nicht standardisiert ist.

    Jetzt wird sie nicht mehr fluchen.

    // Liste ändern:
    // 15.02.2018
    // Fix: MT5-OrderSend-Synchronisationsprüfung berücksichtigt nun mögliche Besonderheiten der ECN/STP-Implementierung.


    Als Test können Sie dieses Skript auf einem komplizierten Demokonto FXOpen-MT5 ausführen.

    #include <Debug.mqh> // https://c.mql5.com/3/173/Debug.mqh
    #include <MT4Orders.mqh>
    
    #define Bid (SymbolInfoDouble(_Symbol, SYMBOL_BID))
    #define Ask (SymbolInfoDouble(_Symbol, SYMBOL_ASK))
    
    void OnStart()
    {
      _P(OrderCloseBy(_P(OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0)), _P(OrderSend(_Symbol, OP_SELL, 1, Bid, 0, 0, 0))));
    }


    Ergebnis

    void OnStart(), Line = 9: OrderSend(_Symbol,OP_SELL,1,Bid,0,0,0) = 897247
    void OnStart(), Line = 9: OrderSend(_Symbol,OP_BUY,1,Ask,0,0,0) = 897248
    void OnStart(), Line = 9: OrderCloseBy(_P(OrderSend(_Symbol,OP_BUY,1,Ask,0,0,0)),_P(OrderSend(_Symbol,OP_SELL,1,Bid,0,0,0))) = true
    Dateien:
    Debug.mqh  1 kb
     

    Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

    Organisation des Zyklus der Bestellung brute force

    fxsaber, 2018.02.16 09:40

    MT5 läuft überhaupt nicht gut. Ein Beispiel, das das Problem zeigt

    // Beispiel für eine falsche Ablesung der Handelsumgebung bei jedem Tick
    // Das Skript emuliert zwei Ticks des TS, der eine Position öffnen soll, wenn es keine gibt.
    
    #include <Trade/Trade.mqh>
    
    // Gibt die Anzahl der Positionen pro Zeichen zurück
    int GetAmountPositions( const string Symb )
    {
      int Res = 0;
      
      // Dieser MQL5-Code hat einen Fehler
      for (int i = PositionsTotal() - 1; i >= 0; i--)
        if (PositionGetSymbol(i) == Symb)
          Res++;
    
    /*
    // In MT4 wird dieser Code ohne Fehler ausgeführt
      for (int i = OrdersTotal() - 1; i >= 0; i--)
        if (OrderSelect(i, SELECT_BY_POS) && (OrderType() <= OP_SELL) && (OrderSymbol() == Symb))
          Res++;
    */      
      return(Res);
    }
    
    // Beispiel OnTick
    void ExampleOnTick()
    {
      static CTrade Trade;
      
      // Wenn keine Position vorhanden ist, öffnen
      if (!GetAmountPositions(_Symbol))
        Trade.Buy(1);    
    }
    
    // Emulation der Ankunft von zwei Tick-Ereignissen
    void OnStart()
    {
      ExampleOnTick(); 
      
      Sleep(10); // Zwischen zwei Ticks ~10 ms.
      
      ExampleOnTick();
    }

    Was denken Sie, wenn Sie dieses Skript auf ein Symbol ohne Positionen ausführen, was wird am Ende passieren?

    Die richtige Antwort ist, dass eine oder zwei Positionen geöffnet werden.

    Dieses Problem wird umgangen, wenn Sie zumindest teilweise im MQL4-Stil schreiben. Um dies sicherzustellen, reicht es aus, GetAmountPositions im MQL4-Stil zu schreiben (im Quellcode auskommentiert) und MQL5-Stil zu entfernen.

    Seien Sie besonders wachsam mit MQL5-Stil.