Organisation des Auftragszyklus - Seite 8

 
Alexey Viktorov:

Habe ich es so kompliziert ausgedrückt? Der DC verdient Geld mit Spreads und Provisionen, der Programmierer verdient Geld mit dem Schreiben von Code.

Einer der Händler sagt, dass wir bei den Spreads und Provisionen sparen sollten (nicht so viel wie möglich zahlen).

Der andere Händler sagt, dass es nicht fair ist, den Code für das Geld zu schreiben (wenn möglich, nicht bezahlen).

Beide achten auf ihr eigenes Portemonnaie. Sie scheinen sich nicht voneinander zu unterscheiden...

Nur, dass Sie als Programmierer das erste unterstützen und mit dem zweiten argumentieren und ihm damit Unrecht geben.

Ich verstehe den Händler, der einen billigeren Programmierer finden will. Ich verstehe auch den Händler, der nach besseren Handelsbedingungen sucht. Was ist das Problem? Was ist falsch daran, Geld sparen zu wollen?

Aber hier ist es eine andere Geschichte. Einen eigenen Algorithmus zu durchdenken, um ihn effektiver mit Aufträgen arbeiten zu lassen und dadurch den Gewinn des Systems zu erhöhen - das bedeutet, ein guter Entwickler zu sein. Meiner Meinung nach kann man nur in der Phase des groben Testens einer Idee einige Pips vernachlässigen.

 
Andrey Khatimlianskii:

Ich verstehe den Händler, der einen billigeren Programmierer finden will. Ich verstehe auch den Händler, der nach besseren Handelsbedingungen sucht. Was ist das Problem? Was ist falsch daran, Geld sparen zu wollen?

Aber hier ist es eine andere Geschichte. Einen eigenen Algorithmus zu durchdenken, um ihn effektiver mit Aufträgen arbeiten zu lassen und dadurch den Gewinn des Systems zu erhöhen - das bedeutet, ein guter Entwickler zu sein. Ich denke, wir können nur in der Phase der groben Prüfung einer Idee einige Punkte vernachlässigen.

Gut. Und irgendwie verstehe ich Ihre Abneigung, weiter umsonst zu schreiben. Auch kein Problem...

Im Allgemeinen bin ich nicht dagegen, dass man versucht, Geld zu sparen, aber nicht so sehr, dass es zum Wahnsinn wird. Sie können die Einsparungen bei der Spanne nicht an die Spitze des Handels stellen...

 
Alexey Viktorov:

Ich habe nichts dagegen, generell zu versuchen, Geld zu sparen, aber nicht so sehr, dass ich verrückt werde. Man kann nicht die Einsparungen bei den Spreads in den Mittelpunkt des Handels stellen...

Wenn man nachrechnet, ist das gar nicht so verrückt. Aber ich versuche nicht, sie zu überzeugen.

 
Andrey Khatimlianskii:

Wenn Sie nachrechnen, ist das gar nicht so dumm. Aber ich versuche nicht, sie zu überzeugen.

Man muss die Gewinne zählen, nicht die Kosten.

Wenn man Kosten spart, kann man sehr leicht Verluste machen. Wenn der TS so konzipiert ist, dass er die Kosten trägt, aber einen Gewinn abwirft, dann ist dies ein guter TS, denn in einem anderen Szenario könnte er einen Verlust machen.

Es gibt nämlich keine Bewertung der Gewinner!

 

Kann die Seite 7 der aktuellen Seite nicht in ein separates Thema verschoben werden (man könnte sogar einen Link wie "Weitere Diskussion hier" einfügen) und das, wofür sie erstellt wurde, in diesem Thema fortführen?

 
Vitaly Muzichenko:

Man muss die Gewinne zählen, nicht die Kosten.

Wenn man Kosten spart, kann man sehr leicht Verluste machen. Wenn der TS so konzipiert ist, dass er Ausgaben verursacht, aber gleichzeitig Einnahmen bringt, dann ist er ein guter TS, denn in einem anderen Szenario könnte er einen Verlust machen.

Und im Allgemeinen werden die Gewinner nicht bewertet!

Ich verstehe nicht, worum es in diesem Kommentar geht.

Geht es um die Unwichtigkeit der Provisionshöhe bei superprofitablen Strategien?

 
Lassen Sie uns den folgenden Expert Advisor auf dem MT4 EURUSD ausführen
// В случае изменения количества ордеров по основному символу, сигнализирует об их количестве

// #include <MT4Orders.mqh>

const bool Init =  EventSetMillisecondTimer(1);

int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

void OnTimer()
{
  static int PrevAmount = 0;
  
  const int Amount = AmountOrders(_Symbol);
  
  if (Amount != PrevAmount)
  {
    PrevAmount = Amount;
    
    Alert(Amount);
  }    
}


Eröffnen wir 5 EURUSD- und 5 USDJPY-Orders nach dem Zufallsprinzip. Werfen wir nun einen Blick auf den harmlosen Code von AmountOrders und stellen uns folgendes Szenario vor

  1. Wir befinden uns zur Laufzeit in AmountOrders mit i == 3.
  2. Wir schließen eine Position auf USDJPY. Die Aufträge werden dann in der Tabelle der aktuellen Aufträge aufgeschüttelt.
  3. Wenn i == 2 ist, können wir durch OrderSelect auf die gleiche Reihenfolge wie in Punkt 1 stoßen. Aus diesem Grund kann AmountOrders einen Wert mehr zurückgeben, als er tatsächlich war.


Hier ist eine Bestätigung unserer Aussagen

#property strict

void OnStart()
{
  for (int i = 0; i < 5; i++)
    OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);
    
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i > 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      if (OrderSelect(i - 1, SELECT_BY_POS))      
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    }
}


Ergebnis

2017.10.06 01:28:05.885 TestTets EURUSD,M1: close #240725107  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.775 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.775 TestTets EURUSD,M1: close #240725108  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.673 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.673 TestTets EURUSD,M1: close #240725110  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.578 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.578 TestTets EURUSD,M1: close #240725111  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.480 TestTets EURUSD,M1: open #240725112  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.343 TestTets EURUSD,M1: open #240725111  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.253 TestTets EURUSD,M1: open #240725110  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.138 TestTets EURUSD,M1: open #240725108  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.035 TestTets EURUSD,M1: open #240725107  buy 1.00 EURUSD at 1.17121 ok


Ein und dasselbe Ticket kann in einer harmlosen Schleife der Auftragszählung zweimal herauskommen!

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 
fxsaber:

Ein und dasselbe Ticket kann in einem harmlosen Zählzyklus zweimal ausgegeben werden!

Um alle Zweifel auszuräumen, gehen Sie wie folgt vor.

Installieren Sie den Expert Advisor

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

void OnTimer()
{
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}


Starten Sie das Skript

#property strict

void OnStart()
{
  // Открыли позиции
  for (int i = 0; i < 25; i++)
    OrderSend(_Symbol, OP_BUY, 1, SymbolInfoDouble(_Symbol, SYMBOL_ASK), 100, 0, 0);

  int Tickets[];
  const int Total = OrdersTotal();
  
  ArrayResize(Tickets, Total);
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS))
      Tickets[i] = OrderTicket();
    
  // Закрыли позиции
  for (int i = 0; i < Total; i++)
    OrderClose(Tickets[i], 1, SymbolInfoDouble(_Symbol, SYMBOL_BID), 100);
}


Und wir beobachten, dass der EA die gleichen Aufträge unter verschiedenen Indizes auswählt. Und das kann zu einem völligen Versagen der Handelslogik führen.

 
fxsaber:

der EA wählt die gleichen Aufträge unter verschiedenen Indizes aus. Und das kann zu einem vollständigen Zusammenbruch der Handelslogik führen.

Dies ist also das Hauptproblem in seiner Gesamtheit! Wie ist die Auftragsschleife zu gestalten? Wie schreibt man zum Beispiel eine solche Funktion richtig?

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}


Dieser Thread begann damit, die Notwendigkeit einiger wiederholter Aktionen bei einer Pause im Suchzyklus zu erläutern. Eine Pause von etwa einer Millisekunde reicht hier aus, um die Wirkung zu sehen.

Bislang eine solche Krücke.

bool IsChange( const bool InitFlag = false )
{
  static int PrevTotal = 0;
  static int PrevHistoryTotal = 0;
  
  const int Total = OrdersTotal();
  const int HistoryTotal = OrdersHistoryTotal();    
  
  if (InitFlag)
  {
    PrevTotal = Total;
    PrevHistoryTotal = HistoryTotal;    
  }
  
  return(!InitFlag && ((Total != PrevTotal) || (HistoryTotal != PrevHistoryTotal)));
}

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      Res = 0;
    }
    else if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

Es ist jedoch nicht sicher, dass es immer richtig funktioniert.

 
fxsaber:

Um alle Zweifel auszuräumen, gehen Sie wie folgt vor.

Installieren Sie den Expert Advisor

Das Skript ausführen

Und wir sehen, dass der EA die gleichen Aufträge unter verschiedenen Indizes auswählt. Und das kann zu einem völligen Versagen der Handelslogik führen.

Ich habe geändert

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

bool IsChange( const bool InitFlag = false )
{
  static int PrevTotal = 0;
  static int PrevHistoryTotal = 0;
  
  const int Total = OrdersTotal();
  const int HistoryTotal = OrdersHistoryTotal();    
  
  if (InitFlag)
  {
    PrevTotal = Total;
    PrevHistoryTotal = HistoryTotal;    
  }
  
  return(!InitFlag && ((Total != PrevTotal) || (HistoryTotal != PrevHistoryTotal)));
}

void OnTimer()
{
  int PrevTicket = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      PrevTicket = 0;
    }
    
    else if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}

Wir haben das Skript ohne Warnungen geändert.