Grid maker 1.1 - Seite 4

 
Tut mir leid, Cori, ich habe nur einen Auftrag für eine bestimmte Rasterposition, und ich habe so ziemlich alle Varianten getestet - über mehrere Wochen hinweg.

Gelegentlich lösche ich alle offenen Orders, damit unsere MT4-Freunde sich nicht aufregen.

Sie werden dieses Problem beim Backtesting bekommen, aber das ist kein Skriptproblem, sondern ein MT4-Backtesting-Problem.

Wenn es weiterhin auftritt, lassen Sie es mich bitte wissen oder senden Sie mir einige Berichte, die das Problem zeigen...

Danke und Reagrds,

hugues
 
Ich habe es gefunden. Und ich bin nicht amüsiert darüber.

Der Advisor erstellt das Grid mit meinem angegebenen Kommentar "GridEURUSD". Dieser Kommentar steht im Kommentarfeld, solange die Order wartet. Wenn die Order aktiviert wird, ändert sich der Kommentar in "activate/auto". Nach allem ist klar, dass dieses Verhalten zu dem beschriebenen Problem führt.

Ich handle mit Alpari. Sie unterstützen MT4 in Demokonten.

Ich werde prüfen, ob ich dieses Verhalten umgehen kann, d.h. die Magie der Order als Identifikator für das Grid verwenden kann und Sie über die Ergebnisse informieren.

Während ich das getestet habe, habe ich auch Änderungen am Bereinigungsskript für das Grid vorgenommen. Ich habe eine Funktion hinzugefügt, um auch offene Aufträge zu schließen. Leider erhalte ich die Fehlermeldung 129, d.h. Order locked, wenn ich versuche, eine offene Order zu schließen. Aber es löscht alle schwebenden Aufträge für das gegebene Raster.

//+------------------------------------------------------------------+ //| RemoveGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" extern string GridName = "Grid"; extern bool closeOpen = false; //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { #property show_inputs // zeigt die Parameter an - Danke Slawa... 

//---- int total = OrdersTotal(); int i ; for(i=total-1; i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); if ( OrderSymbol()==Symbol() && OrderComment() == GridName ) { bool result = false; switch(type) { case OP_BUY : if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Ask, 0, Blue ); } break; case OP_SELL : if ( closeOpen ) { result = OrderClose( OrderTicket(), OrderLots(), Bid, 0, Blue ); } break; //Schließung schwebender Aufträge case OP_BUYLIMIT : result = OrderDelete( OrderTicket() ); break; case OP_BUYSTOP : result = OrderDelete( OrderTicket() ); break; case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); break; case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); break; } if(result == false) { Print("Order " , OrderTicket() , " failed to close. Fehler:" , GetLastError() ); // Sleep(3000); }  
        } } //---- return(0); } //+------------------------------------------------------------------+




cori

 
OK Cori, danke..

lass mich wissen, ob es funktioniert, und ich werde die Magie nutzen, denn ich wusste nicht, dass der Broker solche seltsamen Dinge tut!

danke und grüsse,

hugues
 
So, das war's.

Ich habe den GridMaker geändert, um die OrderMagicNumber anstelle des Kommentars zu verwenden. Ich habe auch einige kleine Änderungen an der Erstellung des Kommentars vorgenommen.

Hier ist das Ergebnis.

//+------------------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.4beta" // modified by cori. Verwendung der OrderMagicNumber zur Identifikation der Gewerke des Grids extern int uniqueGridMagic = 11111; // Magische Nummer der Gewerke. muss eindeutig sein, um // die Gewerke eines Grids zu identifizieren extern double Lots = 0.1; // extern double GridSize = 6; // Pips zwischen den Orders - Grid- oder Mesh-Größe extern double GridSteps = 12; // Gesamtzahl der zu platzierenden Orders extern double TakeProfit = 6; // Anzahl der Ticks zur Gewinnmitnahme. normalerweise = Grid-Größe, kann aber überschrieben werden extern double StopLoss = 0; // wenn ein Stop-Loss hinzugefügt werden soll. normale Grids verwenden keine Stop Losses extern double UpdateInterval = 1; // Aktualisierung der Orders alle x Minuten extern bool wantLongs = true; // wollen wir Longpositionen extern bool wantShorts = true; // wollen wir Shortpositionen extern bool wantBreakout = true;       // wollen wir Longs oberhalb des Preises, Shorts unterhalb des Preises extern bool wantCounter = true; // wollen wir Longs unterhalb des Preises, Shorts oberhalb des Preises extern bool limitEMA34 = false; // wollen wir Longs nur oberhalb des Ema, Shorts nur unterhalb des Ema // geändert durch cori. nur interne Variablen double LastUpdate = 0; // Zähler zum Notieren des Zeitpunkts der letzten Aktualisierung double GridMaxOpen = 0; // maximale Anzahl offener Positionen string GridName = "Grid"; // identifiziert das Grid. ermöglicht mehrere nebeneinander existierende Grids //+------------------------------------------------------------------+ //| Experten-Initialisierungsfunktion | //+------------------------------------------------------------------+ int init() { //---- #property show_inputs // zeigt die Parameter an - danke Slawa...    
 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } //---- GridName = StringConcatenate( "Grid", Symbol() ); return(0);
  } //+------------------------------------------------------------------------+ //| prüft, ob es eine offene Position oder Order im Bereich von atRate gibt | //| prüft auf Longs, wenn checkLongs wahr ist, sonst prüft | //| auf Shorts | //+------------------------------------------------------------------------+ bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal(); for(int j=0;j<totalorders;j++) // scannt alle Order und Positionen... { OrderSelect(j, SELECT_BY_POS); // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren if ( OrderSymbol()==Symbol() && OrderMagicNumber() == uniqueGridMagic )  // nur suchen, wenn mygrid und Symbol... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // nicht nach exaktem Preis suchen, sondern Preisnähe (kleiner als gridsize) { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) ) { return(true); } } } } 

   return(false); } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // we update the first time it is called and every UpdateInterval minutes { LastUpdate = CurTime();
   Print("Updating"); point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // runden auf eine durch GridSize teilbare Anzahl von Ticks k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point ;          // Berechnung des niedrigsten Einstiegspunktes double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); for( i=0;i<GridSteps;i++) { traderate = startrate + i*Punkt*GridSize; if ( wantLongs && (!limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == false )           // Teste, ob ich keine offenen Orders in der Nähe meines Kurses habe: wenn ja, setze eine auf { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              sonst { entermode = OP_BUYLIMIT ; } 
              
              if ( ((traderate > Ask ) && (wantBreakout)) || ((traderate <= Ask ) && (wantCounter)) ) 

              { // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } } if ( wantShorts && (!limitEMA34 || traderate < EMA34)) { if (IsPosition(traderate,point*GridSize,false)== false )           // Teste, ob ich keine offenen Orders in der Nähe meines Preises habe: wenn ja, setze eine auf { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              sonst { entermode = OP_SELLSTOP ; } 
              
              if ((traderate < Bid ) && (wantBreakout)) || ((traderate >= Bid ) && (wantCounter)) ) 
               { // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } return(0); } //+------------------------------------------------------------------+



mit freundlichen Grüßen, cori

 
Danke Cori...

da ich selbst schon ein paar Änderungen vorgenommen hatte, habe ich deine Änderungen in die neuere Version integriert.

Ich habe 1 kleine Variation gemacht: um meine aktuellen Grids aktiv zu halten, habe ich einen Test auf magic OR gridname gesetzt...

kannst du überprüfen, ob ich es richtig gemacht habe?



//+------------------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //| http://www.dubois1.net/hdb | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.6beta" // modified by cori. Verwendung der OrderMagicNumber zur Identifikation der Gewerke des Grids extern int uniqueGridMagic = 11111; // Magische Nummer der Gewerke. muss eindeutig sein, um // die Gewerke eines Grids zu identifizieren extern double Lots = 0.1; // extern double GridSize = 6; // Pips zwischen den Orders - Grid- oder Mesh-Größe extern double GridSteps = 12; // Gesamtzahl der zu platzierenden Orders extern double TakeProfit = 12; // Anzahl der Ticks bis zur Gewinnmitnahme. normalerweise = Grid-Größe, kann aber überschrieben werden extern double StopLoss = 0; // wenn ein Stop-Loss hinzugefügt werden soll. normale Grids verwenden keine Stop Losses extern double UpdateInterval = 1; // Aktualisierung der Orders alle x Minuten extern bool wantLongs = true; // wollen wir Longpositionen extern bool wantShorts = false; // wollen wir Shortpositionen extern bool wantBreakout = true;     // wollen wir Longs oberhalb des Preises, Shorts unterhalb des Preises extern bool wantCounter = true; // wollen wir Longs unterhalb des Preises, Shorts oberhalb des Preises extern bool limitEMA34 = true; // wollen wir Longs nur oberhalb des Ema, Shorts nur unterhalb des Ema extern double GridMaxOpen = 0; // maximale Anzahl der offenen Positionen : noch nicht implementiert.. extern bool UseMACD = true; // wenn true, wird macd >0 nur für Longs verwendet, macd >0 nur für Shorts // bei Crossover werden alle schwebenden Orders gelöscht. Dies setzt alle // wantLongs und wantShort Einstellungen außer Kraft - zumindest im Moment. extern bool CloseOpenPositions = false;// falls UseMACD, schließen wir auch offene Positionen mit Verlust? // modifiziert von cori. nur interne Variablen string GridName = "Grid"; // identifiziert das Grid. erlaubt mehrere nebeneinander existierende Grids double LastUpdate = 0; // Zähler für den Zeitpunkt der letzten Aktualisierung //+------------------------------------------------------------------+ //| Experteninitialisierungsfunktion | //+------------------------------------------------------------------+ int init() { //---- #property show_inputs // zeigt die Parameter an - danke Slawa...    
 if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } //---- // von mir hinzugefügt und von hdb entfernt!! lol... nur um mit offenen Grids kompatibel zu bleiben...
// GridName = StringConcatenate( "Grid", Symbol() ); return(0); } //+------------------------------------------------------------------------+ //| testet, ob es eine offene Position oder Order im Bereich von atRate gibt | //| prüft auf Longs, wenn checkLongs true ist, sonst prüft | //| auf Shorts | //+------------------------------------------------------------------------+ bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal();
     for(int j=0;j<totalorders;j++) // alle Aufträge und Positionen scannen... { OrderSelect(j, SELECT_BY_POS); // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren // hdb hinzugefügt oder Gridname für Kompatibilität if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // suche nur, wenn mygrid und Symbol... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // suche nicht nach exaktem Preis, sondern Preisnähe (kleiner als gridsize) { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) ) { return(true); } } } } 
   return(false); } //+------------------------------------------------------------------------+ //| storniert alle ausstehenden Orders | //+------------------------------------------------------------------------+ void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // scannt alle Orders und Positionen... { OrderSelect(j, SELECT_BY_POS); // modifiziert wie in cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren // hdb hinzugefügt oder Gridname für Kompatibilität if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // nur suchen, wenn mygrid und Symbol...
         { int type = OrderType(); bool result = false; switch(type) { case OP_BUY : result = true ; case OP_SELL : result = true ; //Schließung schwebender Aufträge case OP_BUYLIMIT : result = OrderDelete( OrderTicket() ); case OP_BUYSTOP : result = OrderDelete( OrderTicket() ); case OP_SELLLIMIT : result = OrderDelete( OrderTicket() ); case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); } } 
   return; } //+------------------------------------------------------------------------+ //| Storniert alle ausstehenden Orders und schließt offene Positionen | //+------------------------------------------------------------------------+ void CloseOpenOrders() { int total = OrdersTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false; // geändert von cori. Verwendung von OrderMagicNumber zur Identifizierung der Trades des Grids // hdb hinzugefügt oder Gridname für Kompatibilität if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // nur suchen, wenn mygrid und Symbol...
     { // Print("Closing 2 ",type); switch(type) { //Geschlossene Long-Positionen case OP_BUY : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red ); break; //Geschlossene Short-Positionen case OP_SELL : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red ); break; //Schließen schwebende Aufträge case OP_BUYLIMIT : case OP_BUYSTOP :
           case OP_SELLLIMIT : case OP_SELLSTOP : result = OrderDelete( OrderTicket() ); } } if(result == false) { // Alert("Order " , OrderTicket() , " failed to close. Fehler:" , GetLastError() ); // Sleep(3000); }  
  } return; } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // wir aktualisieren beim ersten Aufruf und alle UpdateInterval Minuten { LastUpdate = CurTime();
   point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // auf eine durch GridSize teilbare Anzahl von Ticks runden k = startrate ; k = k * GridSize ;
   startrate = k * point - GridSize*GridSteps/2*point ; // Berechnung des niedrigsten Einstiegspunktes double EMA34=iMA(NULL,0,34,0,MODE_EMA,PRICE_CLOSE,0); if ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
      double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 && Macd1>0 && Macd2<0) // cross up { CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) // Kreuzung nach unten { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } wantLongs = false; wantShorts = false; if( Macd0>0 && Macd1>0 && Macd2>0) // liegt deutlich über Null { wantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2<0) // deutlich unter Null liegt { wantShorts = true; } } for( i=0;i<GridSteps;i++) { traderate = startrate + i*point*GridSize; if ( wantLongs && (!limitEMA34 || traderate > EMA34)) { if ( IsPosition(traderate,point*GridSize,true) == false )           // Teste, ob ich keine offenen Orders in der Nähe meines Preises habe: wenn ja, setze eine auf { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              sonst { entermode = OP_BUYLIMIT ; } 
              if ( ((traderate > Ask ) && (wantBreakout)) || ((traderate <= Ask ) && (wantCounter)) ) 
              { // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } } if ( wantShorts && (!limitEMA34 || traderate < EMA34)) { if (IsPosition(traderate,point*GridSize,false)== false )           // Teste, ob ich keine offenen Orders in der Nähe meines Preises habe: wenn ja, setze eine auf { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              sonst { entermode = OP_SELLSTOP ; } 
              
              if ((traderate < Bid ) && (wantBreakout)) || ((traderate >= Bid ) && (wantCounter)) ) 
                { // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } return(0); } //+------------------------------------------------------------------+
 
Hallo hdb,

scheint ok zu sein. Aber du solltest den GridName als extern definieren, was ich geändert habe, weil ich ihn nicht als Parameter brauchte.

Grüße, cori
 
ACHTUNG alle Benutzer von GridMaker - es gibt einen Fehler in der Funktion IsPosition - das Ergebnis ist, dass nicht alle Grid-Slots gefüllt werden.

Sie können die Zeile ändern:

if (MathAbs( OrderOpenPrice() - atRate ) < inRange) // suche nicht nach exaktem Preis, sondern nach Preisnähe (kleiner als gridsize)

zu

if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)) // sucht nicht nach dem exakten Preis, sondern nach der Preisnähe (kleiner als gridsize) - fügte 0,9 hinzu, um den Floating-Pont-Fehler zu vermeiden


und behebt damit das Problem.

Sorry für die Unannehmlichkeiten...

Umarmungen
 
Hallo hugues,

Gibt es dieses Problem schon?

Habe etwas ähnliches im alten MQL2 gefunden.

Der wirklich sichere Weg, um dieses Problem zu umgehen ist, etwas wie zu tun:

intOOP = MathRound( OrdeOpenPrice() / Point );

für alle Ihre Double-Variablen. Dann haben Sie alle direkten int-Variablen, die ohne Fehler vergleichbar sind.

Es ist ein bisschen mehr zu schreiben, um es klar und verständlich zu halten, aber es ist weniger fehlerhaft.

Mit freundlichen Grüßen,

cori
 
Du hast recht Cori, das ist viel eleganter! Ich war einfach zu faul!

Grüße,
hugues
 
Hier ist ein Update für den GridMaker EA. In dieser Version habe ich:

1) die Logik für UseMACD, wantLongs, wantShorts geändert. Zuvor, wenn useMACD gesetzt war, nahm der EA Longs und Shorts, unabhängig von wnatLongs und wantShorts Flags. Jetzt setzt useMACD diese Flags nicht mehr außer Kraft, so dass man mit useMACD nur long oder nur short sein kann.

2) Ich habe eine zusätzliche Prüfung hinzugefügt, um sicherzustellen, dass es keine offenen Aufträge auf der falschen Seite des EMA gibt, wenn das limitEMA34 gesetzt wurde. Früher wurden die Aufträge über oder unter dem EMA platziert, aber nach ein paar Stunden verschob sich der EMA, so dass es Aufträge auf beiden Seiten des EMAs gab.

3) Es scheint einen Fehler in der switch-Anweisung auf OrderType() zu geben. Ich bin nicht sicher, was es ist, aber es verhält sich wirklich komisch. Ich habe einfach die switch-Anweisungen eliminiert und durch "if" ersetzt... ich mag es nicht, aber es funktioniert!

4) Ich habe die EMA-Periode variabel gemacht... schön für Backtesting...

Ich habe auch ein paar begleitende Skripte, wenn jemand möchte:

1) um nicht ausgefüllte offene Aufträge für ein Paar zu entfernen
2) um alle offenen Aufträge für alle Paare in einem Rutsch zu entfernen
3) um alle Positionen zu schließen und offene Aufträge zu entfernen.
4) um einige einfache Statistiken über das Verhalten des Gitters anhand der offenen Positionen und der Historie zu erhalten.

Hier ist der Code von V1.08:


//+------------------------------------------------------------------+ //| MakeGrid.mq4 | //| Copyright © 2005, hdb | //|
http://www.dubois1.net/hdb | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, hdb" #property link "http://www.dubois1.net/hdb" //#property version "1.8" // DISCLAIMER ***** WICHTIGER HINWEIS ***** VOR BENUTZUNG LESEN ***** // Dieser Expert Advisor kann reale Positionen öffnen und schließen und somit reale Trades durchführen und echtes Geld verlieren.
// Es handelt sich nicht um ein "Handelssystem", sondern um einen einfachen Roboter, der nach festen Regeln handelt. // Der Autor erhebt keinen Anspruch auf die Rentabilität dieses Systems und empfiehlt die Verwendung // dieses EAs nur zu Testzwecken in Demokonten. // Die Verwendung dieses Systems ist kostenlos - darf aber nicht weiterverkauft werden - und ist ohne jegliche Garantie hinsichtlich seiner // Eignung für irgendeinen Zweck.
// Durch die Nutzung dieses Programms erkennen Sie implizit an, dass Sie verstehen, was es tut, und stimmen zu, dass // der Autor keine Verantwortung für etwaige Verluste trägt. // Bitte überprüfen Sie vor der Nutzung auch mit Ihrem Broker, ob seine Systeme für die häufigsten // Trades, die mit diesem Experten verbunden sind, geeignet sind. // 1.8 Änderungen // machten wantLongs und wantShorts zu lokalen Variablen. Wenn Sie zuvor UseMACD auf true setzten, // wurden die Flags wantLongs und wantShorts ignoriert und Long- und Short-Positionen gebildet. 
// Jetzt werden diese Flags nicht mehr ignoriert. // Es wurde eine Schleife hinzugefügt, um zu prüfen, ob es "unerlaubte" offene Aufträge über oder unter dem EMA gibt, wenn das limitEMA34 // Flag verwendet wird. Diese sammeln sich im Laufe der Zeit an und werden nie entfernt, was auf die Bewegung des EMA zurückzuführen ist. // Die switch-Anweisungen wurden entfernt, da sie nicht zu funktionieren scheinen - sie wurden durch if-Anweisungen ersetzt // und die EMA-Periodenvariable // // wurde von cori geändert. OrderMagicNumber zur Identifikation der Trades des Grids verwenden extern int uniqueGridMagic = 11111; // Magische Nummer der Trades. muss eindeutig sein, um // die Trades eines Grids zu identifizieren extern double Lots = 0.1; // extern double GridSize = 6; // Pips zwischen den Orders - Grid- oder Mesh-Größe extern double GridSteps = 12; // Gesamtzahl der zu platzierenden Orders extern double TakeProfit = 12; // Anzahl der Ticks bis zur Gewinnmitnahme. normalerweise = Grid-Größe, kann aber überschrieben werden extern double StopLoss = 0; // wenn ein Stop-Loss hinzugefügt werden soll. normale Grids verwenden keine Stop Losses extern double UpdateInterval = 1; // Aktualisierung der Orders alle x Minuten extern bool wantLongs = true; // wollen wir Longpositionen extern bool wantShorts = true; // wollen wir Shortpositionen extern bool wantBreakout = true;     // wollen wir Longs über dem Preis, Shorts unter dem Preis extern bool wantCounter = true; // wollen wir Longs unter dem Preis, Shorts über dem Preis extern bool limitEMA = true; // wollen wir nur Longs über dem EMA, nur Shorts unter dem EMA extern int EMAperiod = 34; // die Länge des EMA.. war vorher auf 34 festgelegt extern double GridMaxOpen = 0; // maximale Anzahl offener Positionen: noch nicht implementiert. extern bool UseMACD = true; // wenn true, wird macd >0 nur für Longs verwendet, macd >0 nur für Shorts // bei Crossover werden alle schwebenden Orders gelöscht. Dies überschreibt alle // wantLongs und wantShort Einstellungen - zumindest im Moment. extern bool CloseOpenPositions = false;// wenn UseMACD, schließen wir auch offene Positionen mit Verlust? extern bool doHouseKeeping = true; // nur ein Test // modifiziert von cori. nur interne Variablen string GridName = "Grid"; // identifiziert das Grid. erlaubt mehrere nebeneinander existierende Grids double LastUpdate = 0; // Zähler für den Zeitpunkt der letzten Aktualisierung //+------------------------------------------------------------------+ //| Experteninitialisierungsfunktion | //+------------------------------------------------------------------+ int init() { //---- #property show_inputs // zeigt die Parameter an - Danke Slawa...    
//---- // von mir hinzugefügt und von hdb entfernt!! lol.. nur um mit offenen Grids kompatibel zu bleiben...
// GridName = StringConcatenate( "Grid", Symbol() ); return(0); } //+------------------------------------------------------------------------+ //| testet, ob es eine offene Position oder Order im Bereich von atRate gibt | //| prüft auf Longs, wenn checkLongs true ist, sonst prüft | //| auf Shorts | //+------------------------------------------------------------------------+ bool IsPosition(double atRate, double inRange, bool checkLongs ) { int totalorders = OrdersTotal();
     for(int j=0;j<totalorders;j++) // alle Aufträge und Positionen scannen... { OrderSelect(j, SELECT_BY_POS); // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren // hdb hinzugefügt oder Gridname für Kompatibilität if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // nur suchen, wenn mygrid und Symbol... { int type = OrderType(); if (MathAbs( OrderOpenPrice() - atRate ) < (inRange*0.9)) // suche nicht nach exaktem Preis, sondern nach Preisnähe (kleiner als gridsize) - füge 0.9 hinzu wegen Gleitkommafehler { if ( ( checkLongs && ( type == OP_BUY || type == OP_BUYLIMIT || type == OP_BUYSTOP ) ) )  || (!checkLongs && ( type == OP_SELL || type == OP_SELLLIMIT || type == OP_SELLSTOP ) ) ) { return(true); } } } } 
   return(false); } //+------------------------------------------------------------------------+ //| bricht alle ausstehenden Aufträge ab | //+------------------------------------------------------------------------+ void CloseAllPendingOrders( ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // scannt alle Aufträge und Positionen... { OrderSelect(j, SELECT_BY_POS); // modifiziert gemäß cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren // hdb hinzugefügt oder Gridname für Kompatibilität if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // nur suchen, wenn mygrid und Symbol... { int type = OrderType(); if ( type > 1 ) bool result = OrderDelete( OrderTicket() ); } } 
   return; } //+------------------------------------------------------------------------+ //| Storniert alle ausstehenden Orders und schließt offene Positionen | //+------------------------------------------------------------------------+ void CloseOpenOrders() { int total = OrdersTotal(); for(int i=total-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS); int type = OrderType(); bool result = false; // geändert von cori. Verwendung von OrderMagicNumber zur Identifizierung der Trades des Grids // hdb hinzugefügt oder Gridname für Kompatibilität if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // nur suchen, wenn mygrid und Symbol...
     { //Geschlossene Long-Positionen schließen if ( type == OP_BUY ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
           //Geschlossene Leerverkaufspositionen if ( type == OP_SELL ) result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red ); //Schließung schwebender Aufträge if ( type > 1 ) result = OrderDelete( OrderTicket() ); } } return;
} //+------------------------------------------------------------------------+ //| Storniert alle offenen Orders, die auf die falsche Seite des EMA fallen | //+------------------------------------------------------------------------+ void CloseOrdersfromEMA( double theEMAValue ) { int totalorders = OrdersTotal(); for(int j=totalorders-1;j>=0;j--) // Scannt alle Orders und Positionen... { OrderSelect(j, SELECT_BY_POS); if ( OrderSymbol()==Symbol() && ( (OrderMagicNumber() == uniqueGridMagic) || (OrderComment() == GridName)) )  // nur suchen, wenn mygrid und Symbol...
         { int type = OrderType(); bool result = false; //if (type > 1) Print(type," ",theEMAValue," ",OrderOpenPrice()); if ( type == OP_BUYLIMIT && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() ); if ( type == OP_BUYSTOP && OrderOpenPrice() <= theEMAValue ) result = OrderDelete( OrderTicket() ); if ( type == OP_SELLLIMIT && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() ); if ( type == OP_SELLSTOP && OrderOpenPrice() >= theEMAValue ) result = OrderDelete( OrderTicket() ); } } 
   return; } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- int i, j,k, ticket, entermode, totalorders; bool doit; double point, startrate, traderate; //---- setup parameters if ( TakeProfit <= 0 ) // { TakeProfit = GridSize; } bool myWantLongs = wantLongs;
 bool myWantShorts = wantShorts; //---- if (MathAbs(CurTime()-LastUpdate)> UpdateInterval*60) // wir aktualisieren beim ersten Aufruf und alle UpdateInterval Minuten { LastUpdate = CurTime();
   point = MarketInfo(Symbol(),MODE_POINT); startrate = ( Ask + point*GridSize/2 ) / point / GridSize; // runden auf eine durch GridSize teilbare Anzahl von Ticks k = startrate ; k = k * GridSize ; startrate = k * point - GridSize*GridSteps/2*point ;          // den niedrigsten Einstiegspunkt berechnen double myEMA=iMA(NULL,0,EMAperiod,0,MODE_EMA,PRICE_CLOSE,0); if (limitEMA) { if (doHouseKeeping) CloseOrdersfromEMA(myEMA); } if ( UseMACD ) { double Macd0=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
      double Macd1=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); double Macd2=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2); if( Macd0>0 && Macd1>0 && Macd2<0) // Cross up { CloseAllPendingOrders(); if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } if( Macd0<0 && Macd1<0 && Macd2>0) // Cross down { CloseAllPendingOrders();
         if ( CloseOpenPositions == true ) { CloseOpenOrders(); } } myWantLongs = false; myWantShorts = false; if( Macd0>0 && Macd1>0 && Macd2>0 && wantLongs )     // liegt deutlich über Null { myWantLongs = true; } if( Macd0<0 && Macd1<0 && Macd2<0 && wantShorts )     // liegt deutlich unter Null { myWantShorts = true; } } for( i=0;i<GridSteps;i++) { traderate = startrate + i*punkt*GridSize; if ( myWantLongs && (!limitEMA || traderate > myEMA)) { if ( IsPosition(traderate,punkt*GridSize,true) == false )           // Teste, ob ich keine offenen Orders in der Nähe meines Kurses habe: wenn ja, setze eine auf { double myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate-point*StopLoss ; } if ( traderate > Ask ) { entermode = OP_BUYSTOP; } 
              sonst { entermode = OP_BUYLIMIT ; } 
              if ( ((traderate > Ask ) && (wantBreakout)) || ((traderate <= Ask ) && (wantCounter)) ) 
              { // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate+point*TakeProfit,GridName,uniqueGridMagic,0,Green); } } } if ( myWantShorts && (!limitEMA || traderate < myEMA)) { if (IsPosition(traderate,point*GridSize,false)== false )           // Teste, ob ich keine offenen Orders in der Nähe meines Preises habe: wenn ja, setze eine auf { myStopLoss = 0; if ( StopLoss > 0 ) { myStopLoss = traderate+point*StopLoss ; } if ( traderate > Bid ) { entermode = OP_SELLLIMIT; } 
              sonst { entermode = OP_SELLSTOP ; } 
              
              if ((traderate < Bid ) && (wantBreakout)) || ((traderate >= Bid ) && (wantCounter)) ) 
                { // geändert von cori. OrderMagicNumber verwenden, um die Trades des Grids zu identifizieren ticket=OrderSend(Symbol(),entermode,Lots,traderate,0,myStopLoss,traderate-point*TakeProfit,GridName,uniqueGridMagic,0,Red); } } } } return(0); } //+------------------------------------------------------------------+