Zum Inhalt springen
View in the app

A better way to browse. Learn more.

#T/N/X/T

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Projekt: Entwicklung Community-EA

Geschrieben

da hier viel Mitglieder KnowHow in Forex, Aktien oder Rohstoffe haben, könnten wir dieses Wissen bündeln und einen Expert Advisor machen, der jedem Mitglied hier frei zu Verfügung steht.

 

Ich würde mich anbieten diesen zu bauen bzw. mit anderen Mitgliedern zusammen.

 

Interesse? :happymailgirl:

  • Antworten 395
  • Aufrufe 56,3Tsd
  • Erstellt
  • Letzte Antwort

Top-Benutzer in diesem Thema

Most Popular Posts

  • Ok Leute, ich entschuldige mich gleichmal vorweg für den (vermutlicherweise) Megapost den ich hier verfasse. So mancher EA-Experte wird sich großteils sicher denken "nona, für wir blöd hältst du un

  • Dann machen wir mal weiter.   Hier der Report über das Jahr 2011: StrategyTesterCut.htm (Trades gelöscht um Speicherplatz zu sparen, wer den vollen Auszug braucht einfach melden)   Einstellungstechn

  • Soda, bin endlich auch zu was gekommen und hab den HA (also das Entry-Signal) eingebaut:   int calcEntrySignal() { double ha_open_1= iCustom(Symbol(),Period(),"Heiken Ashi",White,White,White,White,

Veröffentlichte Bilder

Wir bauen ein TomNext EA für Metatrader 60 Benutzer abgestimmt

  1. 1. Besteht Interesse zusammen ein EA zu bauen für Metatrader??

Bitte melde Dich an oder registriere Dich, um an dieser Umfrage teilzunehmen.

Featured Replies

Geschrieben

Ich schnappe mir mal ein paar Stellen:

 

(1)

Den Funktionsnamen checkForOpen() finde ich nicht korrekt. Hier wird nicht nur geprüft, sondern auch schon geordert. Also sollte entweder die Funktion umbenannt oder die Prüfung und das Ordern getrennt werden.

 

(2)

  if(filterSignal == FLAT || filterSignal*entrySignal <= 0)

Ich liebe solche schlanken und effizienten Programmierungen. Allerdings erschweren diese die Lesbarkeit des Codes vor allem für Außenstehende, aber auch für einen selbst, wenn man länger nicht mehr drauf geschaut hat. Ich vermeide daher gerne solche Konstrukte, da sie aus Performance-Sicht in heutigen Programmiersprachen eher irrelevant sind (außer es kommt auf jede Nanosekunde an).

 

Vielleicht zur Erklärung für diejenigen Mitleser, denen sich der Sinn der Zeile nicht sofort erschließt:

Die Signale werden durch -1 (short), 0 (flat) und +1 (long) gekennzeichnet. Damit ergbit sich nachfolgende Entscheidungstabelle.

filterSignal 0, entrySignal 0 --> true

filterSignal 0, entrySignal 1 --> true

filterSignal 0, entrySignal -1 --> true

filterSignal 1, entrySignal 0 --> true

filterSignal 1, entrySignal 1 --> false

filterSignal 1, entrySignal -1 --> true

filterSignal -1, entrySignal 0 --> true

filterSignal -1, entrySignal 1 --> true

filterSignal -1, entrySignal -1 --> false

 

Heißt auf deutsch: zeigen FilterSignal und EntrySignal in die gleiche Richtung, ergibt der Ausdruck false, ansonsten ist das Ergebnis true. Im Falle von true wird mit dem return (ohne ein Entry vorzunehmen) die Funktion verlassen. Finde ich schwer zu lesen. Warum nicht einfach:

 

if !(filterSignal == entrySignal) return; 
//oder
if (filterSignal != entrySignal) return;

 

(3)

     stop=calcInitStopDiff(OP_BUY);
  lots= calcLots(stop);
  if(stop > 0)
	stop = entry - stop;
     tp=calcTPDiff(OP_BUY);
  if(tp > 0)
	tp= entry + tp;
     res = tbSendOrder(Symbol(),OP_BUY,lots,entry,3,stop,tp,"buy",MAGICNR, 0,-1);

Hierzu gleich zwei Anmerkungen:

Was soll geschehen, wenn stop oder tp 0 bzw. negativ sind? Da es sich anscheinend um Differenzwerte handelt, wird tbSendOrder mit invaliden Parametern gefüttert.

Der Aufruf von calcInitStopDiff und calcTPDiff sollte mit den nötigen Parametern geschen, sodass diese Funktionen auch losgelöst einsetzbar sind. Ich würde es gerne vermeiden, dass innerhalb dieser beiden Funktionen noch Indikatoren o.ä. ausgewertet werden. Dann ist ein späterer Austausch eher schwer.

Geschrieben

Juhu Beteiligung :shakehands: ;)

 

(1)

Den Funktionsnamen checkForOpen() finde ich nicht korrekt. Hier wird nicht nur geprüft, sondern auch schon geordert. Also sollte entweder die Funktion umbenannt oder die Prüfung und das Ordern getrennt werden.

guter Punkt, ich wär dafür es in einer Funktion zu lassen. wie wärs mit checkAndHandleSignals() ?

 

Ich liebe solche schlanken und effizienten Programmierungen. Allerdings erschweren diese die Lesbarkeit des Codes vor allem für Außenstehende, aber auch für einen selbst, wenn man länger nicht mehr drauf geschaut hat. Ich vermeide daher gerne solche Konstrukte, da sie aus Performance-Sicht in heutigen Programmiersprachen eher irrelevant sind (außer es kommt auf jede Nanosekunde an).

hoppla, hast natürlich recht. Ich merks schon gar nimmer, vermutlich ne Berufskrankheit ;)

 

also so?

if(filterSignal == FLAT || filterSignal != entrySignal)
 return;

 

Was soll geschehen, wenn stop oder tp 0 bzw. negativ sind?

hoppla... um sicher zu gehen sollte es wohl eher so heißen:

if(stop > 0)
 stop = entry - stop;
else
 stop= 0;

Die calcStop soll auch die Möglichkeit haben ein "kein Stop" zurückzugeben, was einer Stopdiff von 0 entspricht. Wär dann konsistent mit dem Parameter für die OrderSend.

 

Der Aufruf von calcInitStopDiff und calcTPDiff sollte mit den nötigen Parametern geschen, sodass diese Funktionen auch losgelöst einsetzbar sind. Ich würde es gerne vermeiden, dass innerhalb dieser beiden Funktionen noch Indikatoren o.ä. ausgewertet werden. Dann ist ein späterer Austausch eher schwer.

ich hätts genau umgekehrt gesehen.

Wenn man ihnen Logikspezifische Parameter dazugibt, muss man im Fall einer Änderung der Logik, den Code hier auch ändern. Im aktuellen Fall ist der "checkForOpen" egal wie die "calcInitStopDiff" zu ihrem Wert kommt, geht sie genaugenommen ja auch nix an. Somit kann man innerhalb der calcInitStopDiff jederzeit was ändern ohne das man hier nachbessern muss. Ändert man später die Logik für den Stop, ändert man nur diese eine Funktion, und nix drumherum...

oder versteh ich dich falsch?

 

Innerhalb der calcInitStopDiff kann man dann die Entscheidung "welchen Stopp verwenden wir?" etc. einbauen...

Geschrieben

wie wärs mit checkAndHandleSignals() ?

Passt besser.

 

also so?

if(filterSignal == FLAT || filterSignal != entrySignal)
 return;

Finde ich besser lesbar.

 

if(stop > 0)
 stop = entry - stop;
else
 stop= 0;

Die calcStop soll auch die Möglichkeit haben ein "kein Stop" zurückzugeben, was einer Stopdiff von 0 entspricht. Wär dann konsistent mit dem Parameter für die OrderSend.

Finde ich in Ordnung. Allerdings muss dann darauf geachtet werden, dass calcStop nicht unabsichtlich 0 zurückliefert, was "keinem Stop" entsprechen würde. Wie sieht es eigentlich mit einer Prüfung des Mindestabstands von SL und TP zum aktuellen Kurs aus? Manche Broker lassen keine Platzierung zu, wenn sie zu dicht liegen. Andere Broker hingegen lassen erst nach einem Order-Fill das Anhängen von SL und TP zu. Beachtet das dann die tbSendOrder-Funktion?

 

Im aktuellen Fall ist der "checkForOpen" egal wie die "calcInitStopDiff" zu ihrem Wert kommt, geht sie genaugenommen ja auch nix an. Somit kann man innerhalb der calcInitStopDiff jederzeit was ändern ohne das man hier nachbessern muss. Ändert man später die Logik für den Stop, ändert man nur diese eine Funktion, und nix drumherum...

Hast Recht. So rum ist es nachher doch einfacher, den Baustein auszutauschen.

Geschrieben

Finde ich in Ordnung. Allerdings muss dann darauf geachtet werden, dass calcStop nicht unabsichtlich 0 zurückliefert, was "keinem Stop" entsprechen würde. Wie sieht es eigentlich mit einer Prüfung des Mindestabstands von SL und TP zum aktuellen Kurs aus? Manche Broker lassen keine Platzierung zu, wenn sie zu dicht liegen. Andere Broker hingegen lassen erst nach einem Order-Fill das Anhängen von SL und TP zu. Beachtet das dann die tbSendOrder-Funktion?

 

Also wenn die calcStop "unabsichtlich" stop

zu den Mindestabständen: die tbSendOrder überprüft das automatisch und setzt stop und tp so nahe wie möglich an das gewünschte Level. Wenn gar keine Stops beim eröffnen gesetzt werden dürfen, gibt die TB derzeit glaub ich einfach nach x versuchen auf. das müsste man dann ggf. für den konkreten Broker anpassen. Is mMn ein sehr spezielles Problem, das hier gleich allgemein zu lösen (mit Parameter etc.) bläst den Code eher unnötig auf oder?

Geschrieben

Is mMn ein sehr spezielles Problem, das hier gleich allgemein zu lösen (mit Parameter etc.) bläst den Code eher unnötig auf oder?

Da hieße, dass ich bspw. auf meinem Flatex-CFD-Forex-Account den EA nicht laufen lassen könnte. Aber ich habe genügen Alternativen :wink2: Letztlich gehört die spezielle Orderbehandlung in Abhängigkeit von Broker-Eigenheiten mit in die tbSendOrder. Kommt mit auf die ToDo-Liste für - äh - 2013 :hourglass:

Geschrieben
Letztlich gehört die spezielle Orderbehandlung in Abhängigkeit von Broker-Eigenheiten mit in die tbSendOrder. Kommt mit auf die ToDo-Liste für - äh - 2013 :hourglass:

 

Stimmt, am schönsten wär ein Parameter bei der tbSendOrder, sodass die Stops einmal direkt beim eröffnen mitgesendet, einmal nachträglich gesetzt werden.

bzw. gar nicht zur tbSendOrder sondern ein "globaler" Parameter in der TradeBox den man im init() setzt so wie das infolevel. Damit wär hier keine Codeänderung nötig ;)

Geschrieben

Stimmt, am schönsten wär ein Parameter bei der tbSendOrder, sodass die Stops einmal direkt beim eröffnen mitgesendet, einmal nachträglich gesetzt werden.

bzw. gar nicht zur tbSendOrder sondern ein "globaler" Parameter in der TradeBox den man im init() setzt so wie das infolevel. Damit wär hier keine Codeänderung nötig ;)

Ich wollte Euch auf eine Funktionssammlung namens common_function.mqh aufmerksam machen, wo genau dies mit der Konstanten "IS_ECN_BROKER" gelöst wird.

 

Unter dem Thread "3rd Party Tools"/"Interessantes Projekt 7bit" #5 steht etwas dazu.

 

hier nochmal der Link und eine Anmerkung dazu:

 

Unter https://sites.google.com/site/prof7bit/common_functions bzw. der Dokumentation hierzu http://7bit.99k.org/common__functions_8mqh.html

gibt es eine Sammlung von allgemeinen Funktionen, die über die Funktionen des reinen Order-Managements einige interessante Goodies bieten.

 

z.B. die print(string text, bool clear)-Funktion, mit der man bis zu 20 Debug-Ausgaben auf das Chart-Window schicken kann

...

Bearbeitet von Der Wolf

Geschrieben

mit der Konstanten "IS_ECN_BROKER"

sorry ist eine statische Variable, kam mit der Großschreibung ins Schleudern.

Geschrieben

Und wiedermal ein sorry von mir für die Funkstille. Bin derzeit beruflich jede Woche ein paar Tage Graz wo gar nix geht, und daheim geht leider auch recht wenig weil dann natürlich die liegen gebliebenen Dinge gemacht werden wollen.

 

Da es keine weiteren Meldungen zum letzten Codeblock gab, hier die "finale" Version zur "Abstimmung" :

 

void checkAndHandleSignals()
{
  int res;
  int filterSignal=FLAT;
  int entrySignal =FLAT;
  double stop=0.0;
  double tp=0.0;
  double entry= 0;
  double lots= 1.0;
//---- get Signals for opening positions
  entrySignal = calcEntrySignal();
  filterSignal = calcFilterSignal();
  if(filterSignal == FLAT || filterSignal != entrySignal)
    return;
//---- open buy
  if(filterSignal + entrySignal == 2*LONG && 
     (calculateCurrentOrders() == 0 || calcOpenDirection() == LONG || HedgeAllowed)) {
  entry= Ask;
     stop=calcInitStopDiff(OP_BUY);
     lots= calcLots(stop);
     if(stop > 0)
       stop = entry - stop;
     else
       stop= 0;
     tp=calcTPDiff(OP_BUY);
     if(tp > 0)
       tp= entry + tp;
     else
       tp= 0;
     res = tbSendOrder(Symbol(),OP_BUY,lots,entry,3,stop,tp,"buy",MAGICNR, 0,-1);
  }
//---- open sell
  if(filterSignal + entrySignal == 2*SHORT && 
     (calculateCurrentOrders() == 0 || calcOpenDirection() == SHORT || HedgeAllowed)) {
     entry= Bid;
     stop=calcInitStopDiff(OP_SELL);
     lots= calcLots(stop);
     if(stop > 0)
       stop = entry - stop;
     else
       stop= 0;
     tp=calcTPDiff(OP_SELL);
     if(tp > 0)
       tp= entry + tp;
     else
       tp= 0;
     res = tbSendOrder(Symbol(),OP_SELL,lots,entry,3,stop,tp,"sell",MAGICNR, 0,-1);
  }
//----
}

 

wegen Namensänderung wird somit start angepasst:

void start()
{
  handleOpenOrders();
  if(isTradeAllowed()) 
    checkAndHandleSignals();
}

 

Als nächstes fehlt eh nur mehr ein Punkt im Struktogramm:

Verarbeitung offener Positionen:

Für alle offenen Positionen

- ziehe TrailingStop/Breakeven nach

? Position aufgrund von Timeout zu schließen?

+ JA: schließe Pos und geh zur nächsten.

? Position aufgrund von Zeitfilter zu schließen?

+ JA: schließe Pos und geh zur nächsten.

 

@Wolf: hab dich nicht überlesen. Danke für den Hinweis. Mir fehlt derzeit leider die Zeit mir die Bibliothek anzuschauen. Aber klingt interessant.

Geschrieben

@Wolf: hab dich nicht überlesen. Danke für den Hinweis. Mir fehlt derzeit leider die Zeit mir die Bibliothek anzuschauen. Aber klingt interessant.

kein Problem, neben der Funktion "print(..., ...)", die ich für's Testen intensiv nutze habe ich zwar einige nützliche weitere Funktionen der common_functions ausprobiert, die eigentlichen Order-Funktionen habe ich bisher mangels Zeit auch nur kurz angetestet.

 

Das gehört ja eigentlich auch nicht in diesen Thread, ich habe die common_funktions in diesen Thread nur reingebracht, weil hier ECN-Broker-Eigenheiten angesprochen wurden, bei denen man sich evtl. von den common_functions inspirieren lassen könnte.

 

Noch eine Anregung meinerseits, die eigentlich allgemeiner Natur ist, aber vielleicht im Sinne der Entwicklung eines SW-Projektes gerade gut an dieser Stelle in dieses Projekt hineinpasst:

In meinen jüngsten EA's habe ich bisher als Orderfunktionalität eigene MT4-Orderfunktionen oder die TradeBox-Orderfunktionen direkt eingebaut.

 

Demnächst werde ich meine EA's dahingehend umschreiben, daß ich nicht die TradeBox-Orderfunktionen direkt aufrufe, sondern eigene "Funktions-Hüllen" als Orderfunktionen aufrufen werde, also z.B. myBuy(...), myBuyStop(...), myBuyLimit(...), mySell(...) u.s.w.

 

Innerhalb dieser Funktions-Hüllen kann ich dann Order-Funktionalitäten entweder aus der TradeBox, den common_funktions.mqh, einer evtl. dritten fremden Funktionssammlung oder einer zukünftig eigenen Funtkionssammlung aufrufen. Dazu brauche ich nur eine Variable bzw. Konstante definieren, um dementsprechend "switchen" zu können.

 

Der große Vorteil wäre: in den verschiedenen EA-Quellcode's muss ich so gut wie keine Änderungen mehr vornehmen, d.h. ich kann per Switch (oder externem Paramter) Orderfunktionalitäten aus verschiedenen, austauschbaren Bibliotheken nutzen - und evtl. auch gegeneinander testen !

 

Fazit:

==> Vielleicht "nehmt ihr den Ball auf" - und wenn auch nur im Hinterkopf - und gar nicht auf dieses Projekt bezogen.

 

Je abstrakter man derartige Dienst-Funktionen definiert, umso mehr Freiheiten hat man später bei möglichen Erweiterungen !

 

Wie gesagt, nur als Anregung verstehen - vielleicht selbst für spätere Projekte anwenden - ich bau solche "Funktions-Hüllen" auch nicht sofort ein, aber spätestens bei der zweiten Alternative !

Geschrieben

...hier die "finale" Version zur "Abstimmung" :

find ich soweit okay

Bearbeitet von Der Wolf

Geschrieben
sondern eigene "Funktions-Hüllen"

 

Ernten 4.2. (dazu an anderer Stelle mehr ) arbeitet mit 2 #Include :

 

Dabei ruft der EA Funktionen auf, die die Order vorbereiten , d.h. die individuellen Variablen belegt werden :

 

     OrderSelect (B21,SELECT_BY_TICKET)         ;//                                               |
    if ((B21 == 0 || OrderCloseTime() > 0) && ( Mas_Tip[4] == 0))   //                           |
      {                                         //                                               |
       Alert("B21 Open aus Hauptprogramm")     ;//                                               |
       Pair1_B21();return                      ;//                                               |
      }                                         //                                               |

 

Pair1_B21() bedeutet, dass die erste Buy-Order aufgerufen werden soll (es können bis zu 5 werden)

 

In Pair_B21() geschieht nun folgendes :

 

//-------------------------------------------------------------------------------------------------+
int Pair1_B21()                                  //                                                |
{                                                //                                                |
bool PRT = (Bars > bb && hilfe)                ;//                                                |
double Entry = CurrentEnterLong                ;//                                                |
if (OrderSelect (B21,SELECT_BY_TICKET) == true )// gibt oder gab es je einen B21 ?                |
  {                                             //                                                |
   if (OrderCloseTime() == 0 )                  // ja , auch aktiv oder schon geschlossen ?       |
     {                                          //                                                |
      return(0)                                ;// dann braucht keiner mehr gesetzt werden        |
     }                                          //                                                |
  }                                             // Flag im Commenttext setzen 1= Handel , 0=Hedge |
if(Long == 1)string text = "1 B21 @ Time ="+ jetzt +" dAsk = "+dAsk;//                            |
if(PRT ) Print(text,",CurrentEnterLong=",Entry,",SL = ",ip_dSL,",TP=",(Entry+TPLong*Point));//    |
                                                //                                                |
        B21 = OrderEx( Symbol()                ,//                                                |
                       OP_BUYSTOP              ,// int (0 B , 1 S , 2 BL , 3 SL , 4 BS , 5 SS )   |
                       Lots                    ,// Volumen , double                               |
                       Entry                   ,// Entrypreis                                     |
                       Slippage                ,// Slip , int                                     |
                       ip_dSL                  ,// SL , double                                    |
                       Entry+TPLong*Point      ,// TP , double                                    |
                       text                    ,// Comment , strg                                 |
                       ER_MAGIC_B21            ,// Magic , int                                    |
                       0)                      ;// Expiration , datetime                          |
                                                //                                                |
                                                //                                                |
        if (B21>-1)                             // Benachrichtigen das alles OK                   |
       {                                        //                                                |
        Alert("2 START Trade B21 aus TradePair1_B21") ;//                                         |
       }                                        //                                                |
        else                                    //   irgend etwas ist schief gegangen             |
       {                                        //                                                |
        Print("FAIL Start B21 at : ", jetzt ,   //                                                |
              " /Code = ",B21," /dAsk = ",dAsk ," /dBid = ",dBid ,            //                  |
              "/ Entry = ",Entry,"/ SL= ",ip_dSL,"/ TP = ",(Entry+TPLong*Point));//               |
        Alert(" FAIL B21 , Code =",B21)        ;//                                                |
        deinit()                               ;//                                                |
       }                                        //                                                |
                                                //                                                |
      return(0)                                ;//                                                |
 }                                              //                                                |
//+------------------------------------------------------------------------------------------------+

 

In der Zeile "B21 = OrderEx( Symbol() " beginnt die Orderbelegung und die Funktion OrderEx() führt dann in einer

weiteren Funktion OrderEx() , den eigentlichen Entry durch .

 

Oben schon erwähnt, Ernten kann max 5 Long oder 5 Short in den Markt legen . Die Ordervorbereitung liegt in einer

Include schlicht um Übersichtlichkeit zu wahren . Dann das Durchführen der Order selber , Ordersend in der Funktion

"OrderEx()" , Orderclose , Ordermodify (Mythos Tradebox hier) und Orderdelete , sind in einer weiteren Include gehalten .

 

KB

Geschrieben

@Funktionshüllen: An sich find ich so einen Aufbau sehr gut, eben genau aus dem Grund das man bei späteren Änderungen den bestehenden Code möglichst wenig anpassen muss. Aber man muss mMn auch darauf achten das es nicht zuviel des Guten wird. IMHO reicht eine Ebene völlig aus. Also im EA wird eine Funktion zum senden der Order aufgerufen. In dieser Funktion wird dann die Order gesendet und nicht wieder per Weiche entschieden welche andere Lib aufgerufen wird. Wenn man im Laufe der Zeit draufkommt das diese Funktion was anderes tun sollte, kann man sie ja anpassen. Ansonsten wirds (vor allem für so simple Programme wie EAs) ein extremer Strukturoverhead.

Das schöne an openSource Geschichten is aber, das sich jeder den Code anpassen kann wie er will ;)

Geschrieben
IMHO reicht eine Ebene völlig aus

 

Das finde ich auch . In diesem Fall , Ernten , stand ich vor dem Problem, dass ich 10 Orders , 5 B und 5 S ,individuell platzieren will um diese dann (in meinen Träumen) individuell steuern (TP/SL) zu können . Wie an anderer Stelle zu lesen, wäre ich heute froh, wenn ich schonmal einen Trade in den TP treiben könnte . Dieser Nachsatz/Post für den Fall, dass jemand zufällig eine Lösung in seiner Box hat, wie man "Pair1_B21()" so coden kann, dass eine oder zwei Fkten denselben Zweck erfüllen könnten . Ist aber sicher kein Schwerpunkt , mehr meine Neugierde . KB

Geschrieben
Sorry Leute, bin in den letzten Wochen kaum dazu gekommen hier rein zu schauen. Sieht ja bisher ganz gut aus. Wenn es okay ist, steige ich tiefer mit ein, wenn es um die Abhandlung der Trades bzw. um Definieren des MM geht.
Geschrieben
Wenn es okay ist, steige ich tiefer mit ein, wenn es um die Abhandlung der Trades bzw. um Definieren des MM geht.

 

Natürlich, zugegebenermaßen gehts im Moment mehr um das "langweilige" Gerüst rundherum. Aber damit sind wir auch demnächst durch (fehlt nur noch 1 Block), dann gehts an die spannenden Details wo die Logik implementiert wird.

 

Zeigt für die "Neulinge" natürlich auch sehr gut, wieviel rundherum zu beachten ist, das nichts mit der Entry/Exitlogik zu tun hat. Aber ohne das rundherum wird der EA nicht lauffähig ;)

Geschrieben

Verarbeitung offener Positionen:

Für alle offenen Positionen

- ziehe TrailingStop/Breakeven nach

? Position aufgrund von Timeout zu schließen?

+ JA: schließe Pos und geh zur nächsten.

? Position aufgrund von Zeitfilter zu schließen?

+ JA: schließe Pos und geh zur nächsten.

Zum Timeout: sollte dieser in Stunden/Minuten oder besser in Anzahl Bars angegeben werden? Ich bin für die Anzahl an vergangenen Bars, da somit der Wechsel des Timeframes indirekt berücksichtigt wird.

 

Dann zu Zeitfilter: Einen Zeitfilter finde ich schwer paramatrisierbar. Wahrscheinlich wird dieser hardcoded in einer eigenständigen Funktion am besten aufgehoben sein. Nur so lassen sich Wochentage/Abendstunden/Nachtstunden einfach definieren.

 

@Mythos: Könntest du bei deinen wöchentlichen Reports bitte den derzeitigen Code immer unten mit anhängen? Ich tue mich gerade schwer, die bislang verabschiedeten Fragmente zusammenzusetzen. Auch wenn der Code noch nicht lauffähig ist, wäre es für mich eine große Hilfe :biggrin: Deinen aktuellen Codevorschlag kannst du dann mit (Kommentar) darunter packen. Den aktuellen Codebaustein kannst du in deinem Post ja dennoch darstellen. Dann kann man den Thread gut lesen und wenn man was machen will, downloaded man einfach den aktuellen Gesamtcode.

Geschrieben

Zum Timeout: sollte dieser in Stunden/Minuten oder besser in Anzahl Bars angegeben werden? Ich bin für die Anzahl an vergangenen Bars, da somit der Wechsel des Timeframes indirekt berücksichtigt wird.

Klingt gut.

 

Dann zu Zeitfilter: Einen Zeitfilter finde ich schwer paramatrisierbar. Wahrscheinlich wird dieser hardcoded in einer eigenständigen Funktion am besten aufgehoben sein. Nur so lassen sich Wochentage/Abendstunden/Nachtstunden einfach definieren.

Ja, den Zeitfilter hätt ich auch als eigene Funktion ähnlich wie "isTradingTime" gesehen.

 

@Mythos: Könntest du bei deinen wöchentlichen Reports bitte den derzeitigen Code immer unten mit anhängen?

 

bitte sehr ;)

eTomNextCommunity.mq4

(EDIT: hab die Struktogrammteile dazugefügt)

Code is nicht lauffähig, da fehlen noch die Funktionen und externen Parameter.

Geschrieben

Mangels anderer Vorschläge stell ich mal eine Quick and Dirty Version als Diskussionsgrundlage rein.

 

Es geht darum:

Verarbeitung offener Positionen:

Für alle offenen Positionen

- ziehe TrailingStop/Breakeven nach

? Position aufgrund von Timeout zu schließen?

+ JA: schließe Pos und geh zur nächsten.

? Position aufgrund von Zeitfilter zu schließen?

+ JA: schließe Pos und geh zur nächsten.

 

Ich hab die Reihenfolge umgedreht (wozu trailen, wenn pos sowieso geschlossen wird ;)

void handleOpenOrders() {
  double stop=0;
  int index= 0;
  for(index= OrdersTotal() -1;index >= 0;index--) {
   if(OrderSelect(index,SELECT_BY_POS,MODE_TRADES)==false) 
     break; //some error
   if(OrderMagicNumber() != MAGICNR || OrderSymbol()!=Symbol()) 
     continue;
   //handle only open orders
   if(OrderType() != OP_BUY && OrderType() != OP_SELL)
     continue;
   
   //check timeout and Timefilter
   if(isTimeOut(OrderOpenTime())){
     tbCloseOrder(OrderTicket(),OrderLots(),3);
     continue;
   }    
   
   //do trailing
   stop= OrderStopLoss();
   stop= calcNewTrailingStop(stop,OrderType());
   //check for breakeven
   if(isBreakEven(OrderOpenPrice(),OrderType())) {
     if(OrderType() == OP_BUY) 
        stop= MathMax(stop,OrderOpenPrice());
     if(OrderType() == OP_SELL)
        stop= MathMin(stop,OrderOpenPrice());
   }
   if(NormalizeDouble(stop - OrderStopLoss()) != 0)
     tbModifyOrder(OrderTicket(),OrderOpenPrice(),stop,OrderTakeProfit(), OrderExpiration());
 }  
}

Geschrieben

Ich hangel mich dann mal durch:

 

   if(OrderSelect(index,SELECT_BY_POS,MODE_TRADES)==false) 
     break; //some error

Warum im Fehlerfall ganz aus der Schleife? Mal davon abgesehen, dass ich gar nicht wüsste, was da schief gehen könnte, so könnte man doch ruhig mit der nächsten Position weitermachen, oder?

 

 

   //check timeout and Timefilter
   if(isTimeOut(OrderOpenTime())){
     tbCloseOrder(OrderTicket(),OrderLots(),3);
     continue;
   }    

Oh, ist das hier nicht ein sowohl typischer, wie auch gemeiner Fehler!? Ich habe 10 offene Positionen, also geht die Schleife von 9 bis 0. Nun bin ich z.B. bei Pos 5, die geschlossen wird. Danach würde die Schleife mit Nummer 4 weiter machen. Wer sagt denn, dass die 4 überhaupt die nächste Order ist und nicht nochmals die 5 (weil andere nachgerückt sind). Das hängt von der Sortierung der internen Positionsliste ab. Und die ist abhängig von der Sortierung der Positionsliste in der GUI(!) im MT4. Also nichts, worauf man sich verlassen könnte. Oder sehe ich das falsch?

 

   //check for breakeven
   if(isBreakEven(OrderOpenPrice(),OrderType())) {

Wie ist denn isBreakEven angedacht? Auf BE nachziehen, wenn x Punkte im Plus?

 

Ansonsten hätte ich nur Kleinigkeiten, will aber hier nicht der Erbsenzähler sein. So z.B.:

Warum wird index initialisiert, wenn die Variable in der Schleife schon initialisiert wird? Auch stop bräuchte keinen Initialwert. Die erste Zuweisung von stop ist dann auch noch überflüssig und könnte in der Zeile danach direkt erfolgen.

Geschrieben

   if(OrderSelect(index,SELECT_BY_POS,MODE_TRADES)==false) 
     break; //some error

Warum im Fehlerfall ganz aus der Schleife? Mal davon abgesehen, dass ich gar nicht wüsste, was da schief gehen könnte, so könnte man doch ruhig mit der nächsten Position weitermachen, oder?

Dieser Codeteil stammt aus einem Metaquotes-Sample-Programm.

Es spricht im Pirnzip nichts dagegen, mit continue weiterzumachen, aber dann würde ich zuvor mit GetLastError() zumindest der Fehler protokollieren bzw. weiter untersuchen.

Geschrieben

   if(OrderSelect(index,SELECT_BY_POS,MODE_TRADES)==false) 
     break; //some error

Warum im Fehlerfall ganz aus der Schleife? Mal davon abgesehen, dass ich gar nicht wüsste, was da schief gehen könnte, so könnte man doch ruhig mit der nächsten Position weitermachen, oder?

Da is die Frage was genau falsch ist. Normal sollte es kein Problem geben, aber da OrderSelect die Möglichkeit hat "einen Fehler zu zeigen", dann sollte man ihn mMn auch behandeln. Ich behandle es immer als ein "Fatal Error", sprich "Wenn beim selektieren was daneben geht, is irgendwas gerade falsch-> Normaler Funktionsablauf sinnlos".

 

Oh, ist das hier nicht ein sowohl typischer, wie auch gemeiner Fehler!? Ich habe 10 offene Positionen, also geht die Schleife von 9 bis 0. Nun bin ich z.B. bei Pos 5, die geschlossen wird. Danach würde die Schleife mit Nummer 4 weiter machen. Wer sagt denn, dass die 4 überhaupt die nächste Order ist und nicht nochmals die 5 (weil andere nachgerückt sind). Das hängt von der Sortierung der internen Positionsliste ab. Und die ist abhängig von der Sortierung der Positionsliste in der GUI(!) im MT4. Also nichts, worauf man sich verlassen könnte. Oder sehe ich das falsch?

AFAIK: Die Sortierung ist zufällig, aber nicht so schnell wechselnd. Sprich es wird nicht durchs Schließen neu gereiht/sortiert. Das Problem das mir schön öfters untergekommen ist, passiert bei aufsteigendem durchlaufen. Denn wenn ich Ordernr. 3 schließe, rückt die aktuelle 4 auf Platz 3 nach und ich darf nicht als nächstes die 4 betrachten, sondern müsste die 3 nochmal anschauen. Deswegen ist hier das durchlaufen von oben sinnvoller.

Zugegeben könnt ich dir jetzt nicht garantieren das es immer funktioniert. Aber ggf. wirds beim nächsten Tick alles überprüft.

Alternative wäre nur alle OrderTickets die geschlossen werden sollen, zu merken und danach zu schließen. Wär natürlich sauberer.

 

Wie ist denn isBreakEven angedacht? Auf BE nachziehen, wenn x Punkte im Plus?

 

Aus Zusammenfassungspost Nr. 171 (werd den Inhalt dann auch in den EA packen)

Breakeven nach Anstieg um x*ATR

 

Ansonsten hätte ich nur Kleinigkeiten, will aber hier nicht der Erbsenzähler sein. So z.B.:

Warum wird index initialisiert, wenn die Variable in der Schleife schon initialisiert wird? Auch stop bräuchte keinen Initialwert. Die erste Zuweisung von stop ist dann auch noch überflüssig und könnte in der Zeile danach direkt erfolgen.

 

Ja, das sind mMn ein bissl "Glaubensfragen". Ich initialisier gern aus Prinzip um unerwünschtes Verhalten und dumme Fehler zu verhindern. (außer auf Mikrokontroller wenns um speed geht ;)

Beim Stop könnte man es kürzen, stimmt.

 

Wie gesagt, war ein bissl Quick and Dirty :white_flag:

 

btw. ihr dürft gern auch selber Codeblöcke vorschlagen/meinen anpassen. Muss ja nit alles meine Handschrift haben ;)

Geschrieben

Ok, da es keine weiteren Meldungen gibt, hier mal die aktualisierte Version.

Ich hab auch gleich Platzhalter für die Logik-Funktionen eingebaut damit das ganze kompiliert.

(gsd hat vorher niemand bemerkt das in MQL das return anders aussieht als in java :punishR: )

 

Aus meiner Sicht wär der strukturelle Teil fertig und es folgt die Logik.

Falls wir unterwegs merken das wir was übersehen haben können wirs ja ändern.

 

Da ich ein bissl das Einschlafrisiko bei der Beteiligung sehe, stellt sich die Frage ob wir in dem Stil weitermachen, oder einfach die verschiedenen Logik-Funktionen jetzt aufteilen und in einer Woche den ersten Test fahren. Was meint ihr?

 

Die Funktionen wären folgende:

(KB) bool isTradingTime()    //nicht unbedingt notwenig, aber bereits vorbereitet für Zeitfilter
int calcEntrySignal()   //check ob Heiken Ashi gedreht hat
(KB 26.12.)int calcFilterSignal()  //check ob MAs auf höherer Ebene entsprechenden Abstand haben
(Wolf) double calcInitStopDiff(int orderType) // Berechnung des Chandelier
double calcTPDiff(int orderType)  // calc des TP 
double calcLots(double stopDiff)  // Lotsizeberechnung nach abhängig von externem Parameter
(Wolf) double calcNewTrailingStop(double curStop,int orderType) // trail des stops
bool isBreakEven(double openPrice,int orderType) // check ob BreakEven-Trigger erreicht
(KB 26.12.)bool isTimeOut(datetime openTime,int orderType)  // check ob Timout-Trigger erreicht

 

Ein paar der Funktionen sind sicher sehr schnell geschrieben. Die beinhaltende Logik und "gewünschten" Returnwerte sollten eigentlich selbsterklärend bzw. im Kommentar über der Funktion (im Source) stehen. ggf. einfach fragen. Es wird sicher einige Externe Parameter geben die wir noch einfügen müssen. Sofern es Parameter gibt die in mehreren Modulen verwendet werden (zB ATR-Period), werden wirs ggf. nachträglich abgleichen.

 

Hier noch der aktuelle Code:eTomNextCommunity.mq4

 

und jetzt einen schönen 3. Advent ;)

Geschrieben

Gleich die erste geschnappt :

 

 

bool isTradingTime()    //nicht unbedingt notwenig, aber bereits vorbereitet für Zeitfilter

 

Variablen Tradinghour1 ....6 können externe Variablen (logo: Format Datetime ) sein .

 

 

//+-----------------------------------------------------------------------------------------------+
//|                                Community_Istradingtime.mqh                                    |
//|                           The code should be used for Community-EA only                       |
//+-----------------------------------------------------------------------------------------------+
//+-----------------------------------------------------------------------------------------------+
//|   function  :  checks if EA is allowed to trade or off-time                                   |
//+-----------------------------------------------------------------------------------------------+
                                                //                                               |
bool Istradingtime()                             //                                               |
 {                                              //                                               |
  if ((Tradinghour1 <= Hour()) && (Tradinghour2 > Hour()) ||        //                           |
      (Tradinghour3 <= Hour()) && (Tradinghour4 > Hour()) ||        //                           |
      (Tradinghour5 <= Hour()) && (Tradinghour6 > Hour()))          //                           |
                                                //                                               |
      return(true);                             //                                               |
     else                                       //                                               |
      return(false);                            //                                               |
 }                                              //                                               |
//------------------------------------------------------------------------------------------------+

 

Vor dem Heiken habe ich Respekt, den darauf , die MA , kann ich wieder relativ easy machen ...soll ich ? Wer

macht bitte Heikin ?

 

KB

 

PS.: Beruflicher Stress (Edit) plus gewisser Frustlevel bei meinem Ernten haben mich dem Wolf u.a. den Vortritt gewähren lassen .

Aber ich bin da ..... was sonst .

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

Account

Navigation

Suche

Suche

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.