Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools
Zurück   Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools > Metatrader 5 > Programmierung MQL5

Programmierung MQL5 Hier gehts rund ums Programmieren in MQL5.

Login
Benutzername:
Kennwort:


Statistik
Themen: 4982
Beiträge: 43280
Benutzer: 7.229
Aktive Benutzer: 70
Links: 84
Wir begrüßen unseren neuesten Benutzer: JinjianYu
Mit 2.475 Benutzern waren die meisten Benutzer gleichzeitig online (16.01.20 um 22:38).
Neue Benutzer:
vor einer Woche
- JinjianYu
vor einer Woche
- ben007
vor einer Woche
- sirius 888
vor einer Woche
- BessieGove
vor 2 Wochen
- RoKo

Onlineuser
'Wer ist online' anzeigen Benutzer: 0
Gäste: 341
Gesamt: 341
Team: 0
Team:  
Benutzer:  
Freunde anzeigen

Empfehlungen

Antwort
 
Themen-Optionen Thema durchsuchen Ansicht
  #1 (permalink)  
Alt 29.03.24
Neues Mitglied
 
Registriert seit: Feb 2024
Beiträge: 8
murkel befindet sich auf einem aufstrebenden Ast
Standard Nicht alle Orders löschen, sondern nur eine bestimmte...

Hallo zusammen,

da ich noch totaler Anfänger bin, habe ich einen "Übungs-EA" geschrieben, um mit diesem das eine oder andere zu lernen. Daher ist der unten anhängende Code keine Strategie, sondern dient in der Tat nur zu lernzwecken.

Durch den EA sollen lediglich bei höherem Hoch / tieferem Tief Buy- oder Sell-Stopp-Orders mit SL und TP in den Markt gesetzt werden. Das klappt schon mal fehlerfrei.

Dann soll, wenn die Order getriggert wurde, die Position mit erreichen des SL oder TP geschlossen werden. Auch das klappt fehlerfrei. Dass das fast nur Verluste bringt, soll hier keine Rolle spielen.

Orders, die im Markt sind und deren eigentlicher SL bereits vor dem Entry erreicht werden, sollen gelöscht werden. Dies klappt - aber nur teilweise.

Somit kommen wir zu meinem Problem:
Ich habe den SL mit der variablen "buyOrderDelete" und "sellOrderDelete" besetzt und wenn der Bid-Kurs <= buy/sellOrderDelete ist, soll die Order gelöscht werden. Macht der EA auch, doch wenn ich nun zwei (oder mehrere) offene Orders (in eine Richtung) habe, löscht er nur die erste Order - die anderen Order, deren SL ebenfalls erreicht wurde, bleiben im Markt.

Wie kann den jeweiligen SL der richtigen Order zuordnen - damit jede Order gelöscht wird, deren SL erreicht ist (nicht aber die Orders, deren SL noch nicht erreicht ist).

Code:
//+------------------------------------------------------------------+
//|                                            lern- und test-EA.mq5 |
//|                                         Copyright 2024, Anfänger |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Anfänger"
#property version   "1.00"

#include       <Trade/Trade.mqh>

enum ENUM_LOT  {LOT_FIX,LOT_AMOUNT,LOT_PERCENT};
enum ENUM_SL   {SL_FIX,SL_CANDLE};

input group    "SIGNAL"
input string   TimeRangeStart          = "11:02";
input string   TimeRangeEnd            = "11:12";

input group    "RISIKO"
input ENUM_LOT Lotcalculation          = LOT_AMOUNT;
input double   RiskInLots              = 0.2;
input double   RiskInAmount            = 10.00;
input double   RiskInPercent           = 0.25;

input group    "HANDEL"
input ENUM_SL  SlVariable              = SL_CANDLE;
input uint     SlInitial               = 1500;
input uint     TpInitial               = 3000;

input group    "DIVERS"
input uint     SymbolBuffer            = 100;
input ulong    Magic                   = 202403271656;

CTrade         trade;
ulong          buyTicket;
ulong          sellTicket;
double         high1;
double         low1;
double         buyOrderDelete;
double         sellOrderDelete;
bool           noSignal;
bool           longSignal;
bool           shortSignal;
datetime       timeRangeStart;
datetime       timeRangeEnd;
datetime       timeSignal;


int OnInit(){
   static bool isInit = false;
   if(!isInit){
      isInit = true;
      Print(__FUNCTION__," > EA (re)start");
   }
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason){
   
}

void OnTick(){
   //---TimeRange
   if(timeRangeStart != StringToTime(TimeRangeStart)){
      calcTimes();
   }
   
   //---Signal
   if(TimeCurrent() >= timeRangeStart && TimeCurrent() < timeRangeEnd){
      timeSignal = iTime(_Symbol,PERIOD_CURRENT,0);
      static datetime timestapSignal;
      if(timestapSignal != timeSignal){
         timestapSignal = timeSignal;
         calcSignal();
      }
   }
   
   //---Order
   if(longSignal == true){
      executeBuy();
   }
   longSignal = false;
   
   if(shortSignal == true){
      executeSell();
   }
   shortSignal = false;
   
   //---Close Order
   double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   
   if(bid <= buyOrderDelete && OrderSelect(buyTicket)){
      if(trade.OrderDelete(buyTicket)){
         Print("  -x-> Buy-Stop-Order #",buyTicket," cancelled, SL reached");
      }
   }
   if(bid >= sellOrderDelete && OrderSelect(sellTicket)){
      if(trade.OrderDelete(sellTicket)){
         Print("  -x-> Sell-Stop-Order #",sellTicket," cancelled, SL reached");
      }
   }
}

void calcTimes(){
   timeRangeStart = StringToTime(TimeRangeStart);
   timeRangeEnd   = StringToTime(TimeRangeEnd);
}

void calcSignal(){
   //---Candle 1
   double open1         = iOpen(_Symbol,PERIOD_CURRENT,1);
          high1         = iHigh(_Symbol,PERIOD_CURRENT,1);
          low1          = iLow(_Symbol,PERIOD_CURRENT,1);
   double close1        = iClose(_Symbol,PERIOD_CURRENT,1);
   
   //---Candle 2
   double open2         = iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2         = iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2          = iLow(_Symbol,PERIOD_CURRENT,2);
   double close2        = iClose(_Symbol,PERIOD_CURRENT,2);
   
   //---No Signal
   bool higherLowerBar  = (high1 > high2 && low1 < low2);
   bool insideBar       = (high1 <= high2 && low1 >= low2);
   bool doji            = (open1 == close1);
   
   if(higherLowerBar == true){
      noSignal = true;
      Print("  no signal - higherLowerBar ",higherLowerBar);
      return;
   }
   if(doji == true){
      noSignal = true;
      Print("  no signal - doji ",doji);
      return;
   }
   if(insideBar == true){
      noSignal = true;
      Print("  no signal - insideBar ",insideBar);
      return;
   }
   
   //---Long Signal
   bool lowerLow = (low1 < low2 && high1 <= high2);
   
   if(lowerLow == true){
      longSignal = true;
      Print("!!! LONG SIGNAL");
   }else
      {Print("  no long signal");
   }
   
   //---Short Signal
   bool higherHigh    = (high1 > high2 && low1 >= low2);
   
   if(higherHigh == true){
      shortSignal = true;
      Print("!!! SHORT SIGNAL");
   }else
      {Print("  no short signal");
   }
}

void executeBuy(){
   double ask     = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid     = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   double spread  = roundUp(ask - bid);
   double entry   = roundUp(high1 + spread + SymbolBuffer * _Point);
   double sl      = 0;
   
   if(SlVariable == SL_FIX){
      sl = entry - SlInitial * _Point;
   }else  sl = roundUp(low1 - SymbolBuffer * _Point);
   
   double tp = roundUp(entry + TpInitial * _Point);
   Print("  Long: entry ",entry," (spread ",spread,"), sl ",sl,", tp ",tp);
   
   double lots    = calclots(entry - sl);
   double price   = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   
   if(price < entry){  
      if(trade.BuyStop(lots,entry,_Symbol,sl,tp,0,0)){
         if(trade.ResultRetcode() == TRADE_RETCODE_DONE){
            buyTicket = trade.ResultOrder();
            Print("  --> Buy-Stop-Order #",buyTicket," was sent");
            buyOrderDelete = sl;
         }
      }
   }
   if(price >= entry){
      if(trade.Buy(lots,_Symbol,entry,sl,tp)){
         if(trade.ResultRetcode() == TRADE_RETCODE_DONE){
            buyTicket = trade.ResultOrder();
            Print("  --> Buy-Market-Order #",buyTicket," was sent");
         }
      }
   }
}

void executeSell(){
   double ask     = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double bid     = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   double spread  = roundUp(ask - bid);
   double entry   = roundDn(low1 - SymbolBuffer * _Point);
   double sl      = 0;
   
   if(SlVariable == SL_FIX){
      sl = entry + SlInitial * _Point;
   }else  sl = roundDn(high1 + spread + SymbolBuffer * _Point);
   
   double tp    = roundDn(entry - TpInitial * _Point);
   Print("  Short: entry ",entry,", sl ",sl," (spread ",spread,"), tp ",tp);
   
   double lots  = calclots(sl - entry);
   double price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   
   if(price > entry){  
      if(trade.SellStop(lots,entry,_Symbol,sl,tp,0,0)){
         if(trade.ResultRetcode() == TRADE_RETCODE_DONE){
            sellTicket = trade.ResultOrder();
            Print("  --> Sell-Stop-Order #",sellTicket," was sent");
            sellOrderDelete = sl;
         }
      }
   }
   if(price <= entry){
      if(trade.Sell(lots,_Symbol,entry,sl,tp)){
         if(trade.ResultRetcode() == TRADE_RETCODE_DONE){
            sellTicket = trade.ResultOrder();
            Print("  --> Sell-Market-Order #",sellTicket," was sent");
         }
      }
   }
}

double roundUp(double price){
   double ticksize = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE),_Digits);
   price = NormalizeDouble(price,_Digits);
   double rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
   rest = NormalizeDouble(rest,_Digits);
   if(rest != 0){
      for (double i = _Point; i <= ticksize; i += _Point){
         price = NormalizeDouble(price + _Point,_Digits);
         rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
         rest = NormalizeDouble(rest,_Digits);
         if(rest == 0) break;
      }
   }
   return price;
}

double roundDn(double price){
   double ticksize = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE),_Digits);
   price = NormalizeDouble(price,_Digits);
   double rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
   rest = NormalizeDouble(rest,_Digits);
   if(rest != 0){
      for (double i = _Point; i <= ticksize; i += _Point){
         price = NormalizeDouble(price - _Point,_Digits);
         rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
         rest = NormalizeDouble(rest,_Digits);
         if(rest == 0) break;
      }
   }
   return price;
}

double calclots(double slPoints){
   double lots = 0;
   double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
   double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   double moneyPerLotstep = slPoints / ticksize * tickvalue * lotstep;

   if(Lotcalculation == LOT_FIX){
      lots = RiskInLots;
      Print("  fixed lot size: ",lots," lot");
   }
   if(Lotcalculation == LOT_AMOUNT){
      lots = MathFloor(RiskInAmount / moneyPerLotstep) * lotstep;
      Print("  lot size caculated via amount: ",lots," lot");
   }
   if(Lotcalculation == LOT_PERCENT){
      double riskPerTrade = AccountInfoDouble(ACCOUNT_EQUITY) * RiskInPercent / 100;
      lots = MathFloor(riskPerTrade / moneyPerLotstep) * lotstep;
      Print("  lot size calculated as a percentage: ",lots," lot");
   }
   lots = MathMin(lots,SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX));
   lots = MathMax(lots,SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN));
   return lots;
}
Den Ansatz mit einer Schleife habe ich probiert - bin aber ehrlich gesagt noch "zu blöd" es hinzubekommen. Außerdem bin ich auch der Meinung, dass mit einer Schleife alle Order gelöscht werden - was wiederum ebenfalls nicht gewünscht ist.

Dennoch möchte ich euch zeigen, was ich hierzu geschrieben habe. In OnTick habe ich abgefragt (nur mal für die Buy-Variante):

Code:
   //---Close Order
   double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   
   if(bid <= buyOrderDelete && OrderSelect(buyTicket)){
      closeOrder();
   }
Und dazu weiter unten folgende Funktion:

Code:
void closeOrder(){
   for(int i = OrdersTotal()-1; i >= 0; i--){
      buyTicket = OrderGetTicket(i);
      if(OrderSelect(buyTicket)){
         if(OrderGetString(ORDER_SYMBOL) != _Symbol) continue;            
         if(OrderGetInteger(ORDER_MAGIC) != Magic) continue;
         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP){
            if(trade.OrderDelete(buyTicket)){
               Print("  -x-> Buy-Stop-Order #",buyTicket," gelöscht da SL erreicht");
            }
         }
      }
   }
}
Mit dieser Variante löscht er gar keine Buy-Orders.

Wie gesagt, so lange ich nur eine Order in jede Richtung habe, klappt die Löschung, sofern notwendig, problemlos ... aber halt nicht mit mehr als einer Order in eine Richtung.

Schon mal vielen Dank für Lösungsansätze. :-)
Mit Zitat antworten
  #2 (permalink)  
Alt 01.04.24
Elite Mitglied
 
Registriert seit: Apr 2011
Beiträge: 2.738
traderdoc befindet sich auf einem aufstrebenden Ast
Standard

Die Variable buyOrderDelete = sl; wird immer wieder überschrieben, wenn eine weitere PendingOrder desselben Typs gesetzt wird. Da diese PendingOrders sicherlich an verschiedenen Kursen ihre SLs haben, kann das so nicht funktionieren.

Ganz einfach fragt man die SL-Werte der PendingOrders über eine Schleife ab.
Dazu wird OrdersTotal() benutzt, in deren Variable die Anzahl der Markt- und! PendingOrders steht. Danach müssen noch die PendingOrders selektiert werden und dann kann der aktuelle Kurs mit den SL-Werten verglichen werden.

traderdoc
__________________
Ich erfülle Euch gern Eure EA-, Indikator- und Script-Programmierungswünsche auf Honorarbasis.
Mit Zitat antworten
  #3 (permalink)  
Alt 02.04.24
Neues Mitglied
 
Registriert seit: Feb 2024
Beiträge: 8
murkel befindet sich auf einem aufstrebenden Ast
Standard

Vielen Dank traderdoc - du bist mir ein paar Stunden zuvorgekommen, denn mittlerweile konnte ich das Problem lösen ... und zwar genau so, wie du es empfohlen hast.

In der OnTick-Funktion habe ich den Zeitpunkt deklariert:

Code:
//---Close Order
   double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
   
   if(OrderSelect(buyTicket) && bid <= OrderGetDouble(ORDER_SL)){
      closeOrder();
   }
   if(OrderSelect(sellTicket) && bid >= OrderGetDouble(ORDER_SL)){
      closeOrder();
   }
Und weiter unten in der closeOrder-Funktion den Code wie folgt:

Code:
void closeOrder(){
   for(int i = OrdersTotal()-1; i >= 0; i--){
      buyTicket = OrderGetTicket(i);
      if(OrderGetString(ORDER_SYMBOL) != _Symbol && OrderGetInteger(ORDER_MAGIC) != Magic) continue;
      if(OrderSelect(buyTicket) && OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP){
         if(trade.OrderDelete(buyTicket)){
            Print("  -x-> Buy-Stop-Order #",buyTicket," gelöscht da SL erreicht");
         }
      }
   }
   for(int i = OrdersTotal()-1; i >= 0; i--){
      sellTicket = OrderGetTicket(i);
      if(OrderGetString(ORDER_SYMBOL) != _Symbol && OrderGetInteger(ORDER_MAGIC) != Magic) continue;
      if(OrderSelect(sellTicket) && OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP){
         if(trade.OrderDelete(sellTicket)){
            Print("  -x-> Sell-Stop-Order #",sellTicket," gelöscht da SL erreicht");
         }
      }
   }
}
Nun klappt es ganau so, wie ich es mir gewünscht habe und ich habe wieder was dazugelernt ... :-)

Nochmals vielen Dank für den Hinweis! :-)
Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus




Alle Zeitangaben in WEZ +2. Es ist jetzt 00:45 Uhr.





Suchmaschine - Reisen - Wavesnode - Facebook Forum - Spam Firewall
-----------------------------------------------------------------------------------------------------------------------------
Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
SEO by vBSEO 3.6.1
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum
MetaTrader bzw. MetaTrader 4 und MetaTrader 5 sind eingetragene Marken der MetaQuotes Software Corp.
-----------------------------------------------------------------------------------------------------------------------------