TradeManager - Seite 2

 

Ja, diese Klassen kenne ich bereits, Christian. Die CTrade klasse wird in der von mir bereits erwähnten Trade.mqh Datei implementiert. Und wenn MetaQuotes an solchen Dingen etwas verdienen will, dann ist das ihr Problem. Solange es mir nicht verboten wird, so einen Artikel zu schreiben, gibt es für mich keinen Grund, das zu lassen.

Und das mit der Slippage wird so nicht berücksichtigt, wie mir der ein oder andere Fehlercode verdeutlicht hat. Denn der abgefragte Bid- oder Ask-Wert ist beim Auftreten der Slippage nicht der gehandelte Bid- oder Ask-Wert. Daher ist eine Überprüfung gegen die abgefragten Bid- und Ask-Werte wegen vorkommender Verzögerungen (Lags) und der damit verbundenen Änderung der Ask- und Bid-Werte nicht gesichert gegen akzeptierte Slippages, die als "Deviation" Wert an den Broker weitergeleitet werden können und einige Requotes verhindern.

 

Kleiner Nachtrag, was mir eben aufgefallen ist: Natürlich kann man in dem EA überprüfen, ob der bestehende StopLoss von dem neu erechneten StopLoss abweicht und nur dann die Methode ModifyPositionStopLoss aufrufen, aber da diese mqh-Datei dafür da ist, dass man sich auch über solche Sachen möglichst keine Sorgen machen muss, sollte diese Überprüfung selbstverständlich auch darin enthalten sein. Darum sollten in ModifyPosition noch die drei kursiv und fett markierten drei Zeilen hinzugefügt werden.

bool ModifyPosition(double newStopLoss, double newTakeProfit) {
      if (positionId == 0 || isPositionClosing) return false;
      if (!PositionSelectByTicket(positionId)) return false;
      if (symbol != PositionGetString(POSITION_SYMBOL)) return false;
      
      double oldTakeProfit = PositionGetDouble(POSITION_TP);
      double oldStopLoss = PositionGetDouble(POSITION_SL);
      if (newStopLoss == oldStopLoss && newTakeProfit == oldTakeProfit) return false;
      if (CheckPositionFreeze(positionId)) return false;
      
      double price = 0;
      ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      if (positionType == POSITION_TYPE_BUY) price = SymbolInfoDouble(symbol, SYMBOL_BID);
      else if (positionType == POSITION_TYPE_SELL) price = SymbolInfoDouble(symbol, SYMBOL_ASK);
      if (!CheckStopsLevel(price, newStopLoss, newTakeProfit)) return false;
      
      MqlTradeResult result;
      return ModifyPosition(positionId, newStopLoss, newTakeProfit, result);
   }
 

Hallo Benjamin,

kurz gesagt ist das was du suchst bereits in den einzelnen Include Daten bzw. den darin enthaltenen Klassen innerhalb von Metatrader 5 zu finden. Auch die Checks werden in den Klassen abgedeckt. Die Klassen die zum Beispiel von ExpertBase abgeleitet sind enthalten ein vollständiges System das die Basis Klassen wie CTrade, etc. verwendet bzw. die Klassen Implementiert, Vererbt und ggf. durch Erweiterung überschreibt. Alle Funktionen werden darin abgedeckt und du kannst sie selbst verständlich auch erweitern oder in der Form nutzen und in deine Expert Klassen einbinden.

Wie du selbst schreibst benötigen die als Beispiel genannten Expert Klassen "Signale" wodurch die Basis des gewünschten TradeMangers bzw. einer EA Basis vorhanden ist und du im einfachsten Fall nur neue Signal Klassen entwickeln musst um deine Strategie zu implementieren. Die Expert Klassen sind sehr komplex und erfordern ein tiefgreifendes Verständnis von OOP darauf aufbauend sind die Klassen aber für jeden EA der diese Funktionen nutzen möchte sehr ausführlich und decken auch die beschriebenen Checks ab.

Die Include Datei die du hochgeladen hast ist eine Ansammlung von vielen kopierten Funktionen aber keine Basis Klasse die man zur Implementierung und somit als OOP Basis nutzen könnte. Die beschrieben Check Methoden, aus dem Artikel, "Wofür die Überprüfung vor der Veröffentlichung im Market nötig ist" sind Beispiele um Checks durchzuführen, selbstverständlich sind diese nicht für jeden EA geeignet und dienen eher der Erklärung als einer perfekten Basis für alle Checks.

 
Benjamin Fotteler #:

Kleiner Nachtrag, was mir eben aufgefallen ist: Natürlich kann man in dem EA überprüfen, ob der bestehende StopLoss von dem neu erechneten StopLoss abweicht und nur dann die Methode ModifyPositionStopLoss aufrufen, aber da diese mqh-Datei dafür da ist, dass man sich auch über solche Sachen möglichst keine Sorgen machen muss, sollte diese Überprüfung selbstverständlich auch darin enthalten sein. Darum sollten in ModifyPosition noch die drei kursiv und fett markierten drei Zeilen hinzugefügt werden.

Du solltest im besten Fall die Checks vor dem Aufruf der jeweiligen ausführenden Funktion durchführen und dafür ggf. eine "Check" Funktion entwickeln und nicht die Checks in die ausführenden Funktion implementieren. Da ist die Verwendung von "if(CheckModify()) ModifyPosition();" sinnvoller als die vorhanden Funktionen zu verändern bzw. die eigentlichen Funktionen durch Checks einzuschränken da es der Prozessoptimierung dient und dadurch den Ablauf beschleunigt. Im fall das der "Check" fehlschlägt kannst du dann den Aufruf der ausführenden Funktion auslassen.

 
Carl Schreiber #:
Die Funktion, die Du kritisierst, arbeitet mit Ask und Bid statt Slippage:
Buying is done at the Ask price
Selling is done at the Bid price
TakeProfit >= Bid
StopLoss <= Bid
TakeProfit <= Ask
StopLoss >= Ask
Das bedeutet, dass so, ohne den Slippage-Wert direkt zu verwenden, er tatsächlich berücksichtigt wird, da Slippage = Ask-Bid.

Kleine Korrektur zu der Anmerkung: Slippage ist nicht der Unterschied bzw. die Differenz zwischen Ask und Bid (Ask-Bid) das ist der Spread (Spread=Ask-Bid). Slippage ist der Unterschied zwischen dem Preis in dem die Order angefordert wird und dem Preis zu dem die Order beim Broker ausgeführt wird.

Als Beispiel wenn eine Buy-Order zum Preis von 1.10010 vom Terminal in Auftrag gegeben wird (Request) und die Order zum Preis von 1.10020 ausgeführt wird (Result) dann beträgt der Slippage 10 Punkte (Slippage=Anforderung Order(Request)-Ausgeführte Order(Result)).

 

@Dominik

Die Expert.mqh Datei kenne ich natürlich auch schon. Ich denke auch nicht, dass ich das Rad neu erfinden sollte, und ich möchte auch keine OOP-Basisklasse implementieren.

Um es an einem Beispiel festzumachen: Im bereits erwähnten NinjaTrader kann man Strategien (hier heißen sie EAs) programmieren und dabei Market-, Limit- und andere Order ausführen. Dann kann man die interne Strategie-Position abfragen, welche im Hintergrund ermittelt und bereitgestellt wird. Der Entwickler muss sich eigentlich um nichts als nur um die Handelslogik kümmern. Jetzt könnte man vorerst meinen, dass dies doch absolut der Entwicklung eines Signals entspricht, aber das ist nicht richtig. Bei einem Signal kommen am Ende Kauf- und Verkauf-Empfehlungen raus. Die Handelslogik kann aber weit Komplexer sein und dann fängt das Gewurstel an. Dann muss man einen TrailingStop für den CExpert programmieren, der eventuell dieselben Berechnungen anstellt wie die in der Handelslogik, sodass man, um die Performance zu schonen, irgendwie die Resourcen koppeln muss; dann muss man eventuell einen eigenen MoneyManager entwickeln, wenn die ganze Sache nicht mit statischer Lotgröße oder statischer Risikogröße ablaufen wird, etc.

Und auch wenn ich es noch nicht ganz einsehe, aber ich meine, Beispiel-Quellcodes wie "At random full" von Karputov benutzen aus gutem Grund nicht den CExpert, sondern die von Christian genannten Klassen. Aber da greift ja wieder mein Argument. Und jetzt können wir weiterdiskutieren, inwiefern das Sinn macht, oder anfangen darüber zu diskutieren, wie man den TradeManager "Artikeltauglich" macht.

 
Benjamin Fotteler #:

@Dominik

Die Expert.mqh Datei kenne ich natürlich auch schon. Ich denke auch nicht, dass ich das Rad neu erfinden sollte, und ich möchte auch keine OOP-Basisklasse implementieren.

Um es an einem Beispiel festzumachen: Im bereits erwähnten NinjaTrader kann man Strategien (hier heißen sie EAs) programmieren und dabei Market-, Limit- und andere Order ausführen. Dann kann man die interne Strategie-Position abfragen, welche im Hintergrund ermittelt und bereitgestellt wird. Der Entwickler muss sich eigentlich um nichts als nur um die Handelslogik kümmern. Jetzt könnte man vorerst meinen, dass dies doch absolut der Entwicklung eines Signals entspricht, aber das ist nicht richtig. Bei einem Signal kommen am Ende Kauf- und Verkauf-Empfehlungen raus. Die Handelslogik kann aber weit Komplexer sein und dann fängt das Gewurstel an. Dann muss man einen TrailingStop für den CExpert programmieren, der eventuell dieselben Berechnungen anstellt wie die in der Handelslogik, sodass man, um die Performance zu schonen, irgendwie die Resourcen koppeln muss; dann muss man eventuell einen eigenen MoneyManager entwickeln, wenn die ganze Sache nicht mit statischer Lotgröße oder statischer Risikogröße ablaufen wird, etc.

Und auch wenn ich es noch nicht ganz einsehe, aber ich meine, Beispiel-Quellcodes wie "At random full" von Karputov benutzen aus gutem Grund nicht den CExpert, sondern die von Christian genannten Klassen. Aber da greift ja wieder mein Argument. Und jetzt können wir weiterdiskutieren, inwiefern das Sinn macht, oder anfangen darüber zu diskutieren, wie man den TradeManager "Artikeltauglich" macht.

Hallo Benjamin,

Irgendwie werde ich nicht ganz schlau aus dem was du Schreibst bzw. aus dem was du Suchst...

Das genannte Beispiel "At random full" stellt im Endeffekt eine eigene Entwicklung von CExpert da. Oftmals weil der CExpert Code zu komplex ist und viele Funktionen nicht benötigt werden oder auch gar nicht erst Verstanden werden. Aber auch im Gegensatz zum Beispiel, wobei ich dieses nicht schlecht machen möchte, ist der CExpert besser Aufgeteilt und weitaus Komfortabler. Die Aufteilung in die einzelne Klassen wie Money, Trailing und Signal machen schon sinn da auf der Basis viele verschiede EA´s mit unterschiedlichen Strategien und teils gleicher Basis wie MoneyManagement und Trailing entwickelt werden können. Man sollte halt bedenken das die CExpert Klassen u.a. für einen Strategie Generator genutzt werden und durch die Aufteilung ist halt erst die Vielfältigkeit gegeben, sonst würde ja immer die selbe Strategie erzeugt werden...

Ich habe heute mal einige Stunden damit verbracht aus den genannten Klassen die Funktionen in eine Datei zu übernehmen und daraus eine Klasse als Basis zu entwickeln. Die Basis ist im groben das was die, in den Include Dateien enthaltene, CExpert Klasse darstellt. Nur habe ich die Aufteilung in einzelnen Include Dateien gespart und auch die benannten Basis Klassen wie SymbolInfo, Trade, etc. habe ich nur zum Teil benutzt da z.B. MarketOrder als direkter Befehl schneller ausgeführt wird als wenn man die Funktionen der einzelne Basis Klassen wie CTrade nutzt.

Darüber hinaus habe ich auch nur die benötigten Funktionen implementiert und den Rest weggelassen. Als Basis habe ich nun eine Klasse die in einem neuen EA aufgerufen werden kann und der EA selbst hat nur noch, Input Parameter, die Funktion welche die nötigen Preisdaten und Indikatoren Initialisieren und danach rein die Strategie bezogenen Funktionen welche die Daten der Strategie verarbeiten und dieses dann global als Signal ausgeben, womit dann die eigentlichen ausführenden Funktionen angetriggert werden. Ich kann somit mit jeder neuen Strategie ein Signal erzeugen und dann mit dem Signal einfach die gewünschten Aufträge an die Basis übergeben wie z.B. Open, Close, Trailing, Reverse, Limit- und Stopp Orders sowie die jeweiligen Parameter.

Kurz gesagt muss man nicht zwingend die vorhanden Include Dateien verwenden, die Funktionen daraus reichen bzw. deren Abwandlung dessen was man benötigt. Für das eigentliche Signal benötigt man dann nur eine ENUM Deklaration welche die jeweilige Funktion anspricht so das man mit einem Signal alle Funktionen inkl. der Übergabe von Daten (Parameter, Preisdaten, etc.) triggern kann. Also eigentlich ganz Easy!

Die Frage ist also was du wirklich suchst oder bemängeln möchtest. Eine Basis Klasse zu entwickeln bzw. die Vorhandenen zu strukturieren und in eine Datei zu packen dauert wenige Stunden oder ggf. Tage. Danach kann man rein die Strategie entwickeln und Ideen umsetzen.

Darum denke ich nicht das die guten Entwickler solche Klassen mit der Community schreiben wollen, da am Ende vor allem die Profitieren welche es nicht selbst hinbekommen. Die Entwickler nutzen die Basis Klassen oder schreiben sich in kurzer Zeit solche Klassen selbst oder erweitern einfach die Methoden bzw. Funktionen. Im Ergebnis ist es zumindest gleich, wenn man die Entwicklung nicht beherrscht wird man am Ende weder die, bereits im MetaTrader vorhanden Klassen verstehen, noch die neue Klassen welche von einer Community entwickelt wurden.

Viele Grüße,

 
Dominik Rueffer #:

Kleine Korrektur zu der Anmerkung: Slippage ist nicht der Unterschied bzw. die Differenz zwischen Ask und Bid (Ask-Bid) das ist der Spread (Spread=Ask-Bid). Slippage ist der Unterschied zwischen dem Preis in dem die Order angefordert wird und dem Preis zu dem die Order beim Broker ausgeführt wird.

Als Beispiel wenn eine Buy-Order zum Preis von 1.10010 vom Terminal in Auftrag gegeben wird (Request) und die Order zum Preis von 1.10020 ausgeführt wird (Result) dann beträgt der Slippage 10 Punkte (Slippage=Anforderung Order(Request)-Ausgeführte Order(Result)).

Da hast Du Recht, das habe ich verwechselt, weil die meisten Beschwerden und Fragen durch falsch gesetzte Preise (falsch rum, zu eng, ..) entstehen und sich letztendlich auf Ask und Bid beziehen.


In der Trade.mqh heißt die Slippage m_deviation und ist dort standardmäßig durch den Konstruktor auf 10 gesetzt - oder sehe ich das falsch?

Ich kämpfe aber m it einem anderen Problem: CLOSE_BY, dazu mach ich aber einen eigenen  Thread morgen auf..

 
Carl Schreiber #:
Da hast Du Recht, das habe ich verwechselt, weil die meisten Beschwerden und Fragen durch falsch gesetzte Preise (falsch rum, zu eng, ..) entstehen und sich letztendlich auf Ask und Bid beziehen.


In der Trade.mqh heißt die Slippage m_deviation und ist dort standardmäßig durch den Konstruktor auf 10 gesetzt - oder sehe ich das falsch?

Ich kämpfe aber m it einem anderen Problem: CLOSE_BY, dazu mach ich aber einen eigenen  Thread morgen auf..

Das siehst du richtig. Du kannst aber den Standardwert bei dem Aufruf/ Nutzung der CTrade klasse angeben bzw. überschreiben z.B.: "m_trade.SetDeviationInPoints".

Bei PositionOpen wird dann der mit "SetDeviationInPoints" angegeben Wert genutzt oder halt ohne Änderung der Default wert von 10 aus dem Konstruktor.

Bei PositionClose hingegen kann man die Slippage mit dem Parameter ulong=deviation mit dem Funktionsaufruf übertragen.

Dann schaue ich mir den Thread Close_By morgen einmal an, vielleicht kann ich helfen...

 

Wenn jemand immer noch nicht weiß, wofür ich den Thread eröffnet habe, so weise ich darauf hin, dass ich dies bereits ausdrücklich gesagt habe. Es wird mir leider immer wieder bewusst:

Seid die Menschheit aufgehört hat, Lüge als Sünde anzusehen,

haben die Menschen verlernt, einander zu verstehen.

Denn wenn die Unehrlichkeit nicht allgegenwärtig um uns wäre, dann würde es viel selbstverständlicher sein, die Aussagen anderer stehen zu lassen und anzunehmen.

Grund der Beschwerde: