EA funktioniert im Strategietester aber löst keinen Trade beim Livetrading aus.

 
//+------------------------------------------------------------------+
//|                                    Strategy: Breakout EA MT5.mq5 |
//|                                       Created with EABuilder.com |
//|                                        https://www.eabuilder.com |
//+------------------------------------------------------------------+
#property copyright "Created with EABuilder.com"
#property link      "https://www.eabuilder.com"
#property version   "1.00"
#property description ""


int LotDigits; //initialized in OnInit
int MagicNumber = 34664;
int NextOpenTradeAfterBars = 5; //next open trade after time
double MM_Percent = 0.1;
int MaxSlippage = 3; //slippage, adjusted in OnInit
int MaxSlippage_;
bool Push_Notifications = true;
int MaxOpenTrades = 1;
int MaxLongTrades = 1000;
int MaxShortTrades = 1000;
int MaxPendingOrders = 1000;
int MaxLongPendingOrders = 1000;
int MaxShortPendingOrders = 1000;
bool Hedging = false;
int OrderRetry = 5; //# of retries if sending order returns error
int OrderWait = 5; //# of seconds to wait if sending order returns error
double Close[];
int ATR_handle;
double ATR[];

double MM_Size(double SL) //Risk % per trade, SL = relative Stop Loss to calculate risk
  {
   double MaxLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MAX);
   double MinLot = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
   double tickvalue = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE);
   double ticksize = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_SIZE);
   double lots = MM_Percent * 1.0 / 100 * AccountInfoDouble(ACCOUNT_BALANCE) / (SL / ticksize * tickvalue);
   if(lots > MaxLot) lots = MaxLot;
   if(lots < MinLot) lots = MinLot;
   return(lots);
  }

void myAlert(string type, string message)
  {
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | Breakout EA MT5 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Push_Notifications) SendNotification(type+" | Breakout EA MT5 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
      if(Push_Notifications) SendNotification(type+" | Breakout EA MT5 @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "modify")
     {
     }
  }

int TradesCount(ENUM_ORDER_TYPE type) //returns # of open trades for order type, current symbol and magic number
  {
   if(type <= 1)
     {
      int result = 0;
      int total = PositionsTotal();
      for(int i = 0; i < total; i++)
        {
         if(PositionGetTicket(i) <= 0) continue;
         if(PositionGetInteger(POSITION_MAGIC) != MagicNumber || PositionGetString(POSITION_SYMBOL) != Symbol() || PositionGetInteger(POSITION_TYPE) != type) continue;
         result++;
        }
      return(result);
     }
   else
     {
      int result = 0;
      int total = OrdersTotal();
      for(int i = 0; i < total; i++)
        {
         if(OrderGetTicket(i) <= 0) continue;
         if(OrderGetInteger(ORDER_MAGIC) != MagicNumber || OrderGetString(ORDER_SYMBOL) != Symbol() || OrderGetInteger(ORDER_TYPE) != type) continue;
         result++;
        }
      return(result);
     }
  }

ulong LastHistoryTradeTicket(int deal_io)
  {
   HistorySelect(0, TimeCurrent());
   int total = HistoryDealsTotal();
   ulong ticket = 0;
   for(int i = total-1; i >= 0; i--)
     {
      if((ticket = HistoryDealGetTicket(i)) <= 0) continue;
      if(HistoryDealGetString(ticket, DEAL_SYMBOL) == Symbol()
      && HistoryDealGetInteger(ticket, DEAL_MAGIC) == MagicNumber
      && HistoryDealGetInteger(ticket, DEAL_TYPE) <= 1 && HistoryDealGetInteger(ticket, DEAL_ENTRY) == deal_io)
         return(ticket);
     } 
   return(0);
  }

datetime LastCloseTime()
  {
   ulong ticket = 0;
   if((ticket = LastHistoryTradeTicket(DEAL_ENTRY_OUT)) > 0)
      return((datetime)HistoryDealGetInteger(ticket, DEAL_TIME));
   return(0);
  }

ulong myOrderSend(ENUM_ORDER_TYPE type, double price, double volume, string ordername) //send order, return ticket ("price" is irrelevant for market orders)
  {
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(0);
   int retries = 0;
   int long_trades = TradesCount(ORDER_TYPE_BUY);
   int short_trades = TradesCount(ORDER_TYPE_SELL);
   int long_pending = TradesCount(ORDER_TYPE_BUY_LIMIT) + TradesCount(ORDER_TYPE_BUY_STOP) + TradesCount(ORDER_TYPE_BUY_STOP_LIMIT);
   int short_pending = TradesCount(ORDER_TYPE_SELL_LIMIT) + TradesCount(ORDER_TYPE_SELL_STOP) + TradesCount(ORDER_TYPE_SELL_STOP_LIMIT);
   string ordername_ = ordername;
   if(ordername != "")
      ordername_ = "("+ordername+")";
   //test Hedging
   if(!Hedging && ((type % 2 == 0 && short_trades + short_pending > 0) || (type % 2 == 1 && long_trades + long_pending > 0)))
     {
      myAlert("print", "Order"+ordername_+" not sent, hedging not allowed");
      return(0);
     }
   //test maximum trades
   if((type % 2 == 0 && long_trades >= MaxLongTrades)
   || (type % 2 == 1 && short_trades >= MaxShortTrades)
   || (long_trades + short_trades >= MaxOpenTrades)
   || (type > 1 && type % 2 == 0 && long_pending >= MaxLongPendingOrders)
   || (type > 1 && type % 2 == 1 && short_pending >= MaxShortPendingOrders)
   || (type > 1 && long_pending + short_pending >= MaxPendingOrders)
   )
     {
      myAlert("print", "Order"+ordername_+" not sent, maximum reached");
      return(0);
     }
   //prepare to send order
   MqlTradeRequest request;
   ZeroMemory(request);
   request.action = (type <= 1) ? TRADE_ACTION_DEAL : TRADE_ACTION_PENDING;
   
   //set allowed filling type
   int filling = (int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
   if(request.action == TRADE_ACTION_DEAL && (filling & 1) != 1)
      request.type_filling = ORDER_FILLING_IOC;

   request.magic = MagicNumber;
   request.symbol = Symbol();
   request.volume = NormalizeDouble(volume, LotDigits);
   request.sl = 0;
   request.tp = 0;
   request.deviation = MaxSlippage_;
   request.type = type;
   request.comment = ordername;

   int expiration=(int)SymbolInfoInteger(Symbol(), SYMBOL_EXPIRATION_MODE);
   if((expiration & SYMBOL_EXPIRATION_GTC) != SYMBOL_EXPIRATION_GTC)
     {
      request.type_time = ORDER_TIME_DAY;  
      request.type_filling = ORDER_FILLING_RETURN;
     }

   MqlTradeResult result;
   ZeroMemory(result);
   while(!OrderSuccess(result.retcode) && retries < OrderRetry+1)
     {
      //refresh price before sending order
      MqlTick last_tick;
      SymbolInfoTick(Symbol(), last_tick);
      if(type == ORDER_TYPE_BUY)
         price = last_tick.ask;
      else if(type == ORDER_TYPE_SELL)
         price = last_tick.bid;
      else if(price < 0) //invalid price for pending order
        {
         myAlert("order", "Order"+ordername_+" not sent, invalid price for pending order");
              return(0);
        }
      request.price = NormalizeDouble(price, Digits());     
      if(!OrderSend(request, result) || !OrderSuccess(result.retcode))
        {
         myAlert("print", "OrderSend"+ordername_+" error: "+result.comment);
         Sleep(OrderWait*1000);
        }
      retries++;
     }
   if(!OrderSuccess(result.retcode))
     {
      myAlert("error", "OrderSend"+ordername_+" failed "+IntegerToString(OrderRetry+1)+" times; error: "+result.comment);
      return(0);
     }
   string typestr[8] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop", "Buy Stop Limit", "Sell Stop Limit"};
   myAlert("order", "Order sent"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+IntegerToString(MagicNumber));
   return(result.order);
  }

int myOrderModify(ENUM_ORDER_TYPE type, ulong ticket, double SL, double TP) //modify SL and TP (absolute price), zero targets do not modify
  {
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(-1);
   bool netting = AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING;
   int retries = 0;
   int err = 0;
   SL = NormalizeDouble(SL, Digits());
   TP = NormalizeDouble(TP, Digits());
   if(SL < 0) SL = 0;
   if(TP < 0) TP = 0;
   //prepare to select order
   Sleep(10);
   if((type <= 1 && ((netting && !PositionSelect(Symbol())) || (!netting && !PositionSelectByTicket(ticket)))) || (type > 1 && !OrderSelect(ticket)))
     {
      err = GetLastError();
      myAlert("error", "PositionSelect / OrderSelect failed; error #"+IntegerToString(err));
      return(-1);
     }
   //ignore open positions other than "type"
   if (type <= 1 && PositionGetInteger(POSITION_TYPE) != type) return(0);
   //prepare to modify order
   double currentSL = (type <= 1) ? PositionGetDouble(POSITION_SL) : OrderGetDouble(ORDER_SL);
   double currentTP = (type <= 1) ? PositionGetDouble(POSITION_TP) : OrderGetDouble(ORDER_TP);
   if(NormalizeDouble(SL, Digits()) == 0) SL = currentSL; //not to modify
   if(NormalizeDouble(TP, Digits()) == 0) TP = currentTP; //not to modify
   if(NormalizeDouble(SL - currentSL, Digits()) == 0
   && NormalizeDouble(TP - currentTP, Digits()) == 0)
      return(0); //nothing to do
   MqlTradeRequest request;
   ZeroMemory(request);
   request.action = (type <= 1) ? TRADE_ACTION_SLTP : TRADE_ACTION_MODIFY;
   if (type > 1)
      request.order = ticket;
   else
      request.position = PositionGetInteger(POSITION_TICKET);
   request.symbol = Symbol();
   request.price = (type <= 1) ? PositionGetDouble(POSITION_PRICE_OPEN) : OrderGetDouble(ORDER_PRICE_OPEN);
   request.sl = NormalizeDouble(SL, Digits());
   request.tp = NormalizeDouble(TP, Digits());
   request.deviation = MaxSlippage_;
   MqlTradeResult result;
   ZeroMemory(result);
   while(!OrderSuccess(result.retcode) && retries < OrderRetry+1)
     {
      if(!OrderSend(request, result) || !OrderSuccess(result.retcode))
        {
         err = GetLastError();
         myAlert("print", "OrderModify error #"+IntegerToString(err));
         Sleep(OrderWait*1000);
        }
      retries++;
     }
   if(!OrderSuccess(result.retcode))
     {
      myAlert("error", "OrderModify failed "+IntegerToString(OrderRetry+1)+" times; error #"+IntegerToString(err));
      return(-1);
     }
   string alertstr = "Order modify: ticket="+IntegerToString(ticket);
   if(NormalizeDouble(SL, Digits()) != 0) alertstr = alertstr+" SL="+DoubleToString(SL);
   if(NormalizeDouble(TP, Digits()) != 0) alertstr = alertstr+" TP="+DoubleToString(TP);
   myAlert("modify", alertstr);
   return(0);
  }

double TrendlinePriceUpper(int shift) //returns current price on the highest horizontal line or trendline found in the chart
  {
   int obj_total = ObjectsTotal(0);
   double maxprice = -1;
   for(int i = obj_total - 1; i >= 0; i--)
     {
      string name = ObjectName(0, i);
      double price;
      if(ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_HLINE && StringFind(name, "#", 0) < 0
      && (price = ObjectGetDouble(0, name, OBJPROP_PRICE)) > maxprice
      && price > 0)
         maxprice = price;
      else if(ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_TREND && StringFind(name, "#", 0) < 0)
      {
         datetime cTime[];
         ArraySetAsSeries(cTime, true);
         CopyTime(Symbol(), Period(), 0, 1, cTime);
         price = ObjectGetValueByTime(0, name, cTime[0], 0);
         if(price > maxprice && price > 0)
            maxprice = price;            
      }
     }
   return(maxprice); //not found => -1
  }

double TrendlinePriceLower(int shift) //returns current price on the lowest horizontal line or trendline found in the chart
  {
   int obj_total = ObjectsTotal(0);
   double minprice = MathPow(10, 308);
   for(int i = obj_total - 1; i >= 0; i--)
     {
      string name = ObjectName(0, i);
      double price;
      if(ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_HLINE && StringFind(name, "#", 0) < 0
      && (price = ObjectGetDouble(0, name, OBJPROP_PRICE)) < minprice
      && price > 0)
         minprice = price;
      else if(ObjectGetInteger(0, name, OBJPROP_TYPE) == OBJ_TREND && StringFind(name, "#", 0) < 0)
      {
         datetime cTime[];
         ArraySetAsSeries(cTime, true);
         CopyTime(Symbol(), Period(), 0, 1, cTime);
         price = ObjectGetValueByTime(0, name, cTime[0], 0);
         if(price < minprice && price > 0)
            minprice = price;            
      }
     }
   if (minprice > MathPow(10, 307))
      minprice = -1; //not found => -1
   return(minprice);
  }

bool OrderSuccess(uint retcode)
  {
   return(retcode == TRADE_RETCODE_PLACED || retcode == TRADE_RETCODE_DONE
      || retcode == TRADE_RETCODE_DONE_PARTIAL || retcode == TRADE_RETCODE_NO_CHANGES);
  }

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {   
   MaxSlippage_ = MaxSlippage;
   //initialize LotDigits
   double LotStep = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
   if(NormalizeDouble(LotStep, 3) == round(LotStep))
      LotDigits = 0;
   else if(NormalizeDouble(10*LotStep, 3) == round(10*LotStep))
      LotDigits = 1;
   else if(NormalizeDouble(100*LotStep, 3) == round(100*LotStep))
      LotDigits = 2;
   else LotDigits = 3;
   ATR_handle = iATR(NULL, PERIOD_CURRENT, 14);
   if(ATR_handle < 0)
     {
      Print("The creation of iATR has failed: ATR_handle=", INVALID_HANDLE);
      Print("Runtime error = ", GetLastError());
      return(INIT_FAILED);
     }
   
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   ulong ticket = 0;
   double price;   
   double TradeSize;
   double SL;
   
   if(TrendlinePriceUpper(0) < 0 && TrendlinePriceLower(0) < 0) return;
   if(CopyClose(Symbol(), PERIOD_CURRENT, 0, 200, Close) <= 0) return;
   ArraySetAsSeries(Close, true);
   if(CopyBuffer(ATR_handle, 0, 0, 200, ATR) <= 0) return;
   ArraySetAsSeries(ATR, true);
   
   //Open Buy Order
   if(Close[1] > TrendlinePriceUpper(0) //Candlestick Close > Upper Trendline
   )
     {
      MqlTick last_tick;
      SymbolInfoTick(Symbol(), last_tick);
      price = last_tick.ask;
      SL = TrendlinePriceUpper(0) - ATR[0] * 1.5; //Stop Loss = Upper Trendline - Average True Range * fixed value
      TradeSize = MM_Size(price - SL);
      if(TradesCount(ORDER_TYPE_BUY) + TradesCount(ORDER_TYPE_SELL) > 0 || TimeCurrent() - LastCloseTime() < NextOpenTradeAfterBars * PeriodSeconds()) return; //next open trade after time after previous trade's close   
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
        {
         ticket = myOrderSend(ORDER_TYPE_BUY, price, TradeSize, "");
         if(ticket == 0) return;
        }
      else //not autotrading => only send alert
         myAlert("order", "");
      myOrderModify(ORDER_TYPE_BUY, ticket, SL, 0);
     }
   
   //Open Sell Order
   if(Close[1] < TrendlinePriceLower(0) //Candlestick Close < Lower Trendline
   )
     {
      MqlTick last_tick;
      SymbolInfoTick(Symbol(), last_tick);
      price = last_tick.bid;
      SL = TrendlinePriceLower(0) + ATR[0] * 1.5; //Stop Loss = Lower Trendline + Average True Range * fixed value
      TradeSize = MM_Size(SL - price);
      if(TradesCount(ORDER_TYPE_BUY) + TradesCount(ORDER_TYPE_SELL) > 0 || TimeCurrent() - LastCloseTime() < NextOpenTradeAfterBars * PeriodSeconds()) return; //next open trade after time after previous trade's close   
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
        {
         ticket = myOrderSend(ORDER_TYPE_SELL, price, TradeSize, "");
         if(ticket == 0) return;
        }
      else //not autotrading => only send alert
         myAlert("order", "");
      myOrderModify(ORDER_TYPE_SELL, ticket, SL, 0);
     }
  }
//+------------------------------------------------------------------+

Hallo,

Ich hab mir über Expert Advisor einen EA für Range-Breakout gebastelt zum semiautomatischen Handel

Der EA soll bei vorher eingezeichneten Trendlinien (Upper und Lower Trendline), nach Close der Candle im jewiligen Timeframe, über oder unter der jeweiligen Trendlinie einen Trade öffnen.

Der SL soll dann über oder unter der Trendlinie nach dem Wert der ATR (Periode 14) x Faktor 1,5 gesetzt werden.

Ich hab dann noch einen extra Trailing Stop EA den ich mir auf einen EMA einstellen kann. Den hab ich dann statt den SL.



Das ganze hab ich im Strategietester für MT4 getestet, weil in MT5 kann man ja keine Trendlinien mehr einfügen.

Da hat der EA gut funktioniert, jedoch beim Livetrading wird kein Trade aufgemacht.

Ich hab dann auch beim EA Builder den gleichen EA gemacht für MT5.Da funktioniert der EA auch nicht. Manchmal macht er eine Position auf, jedoch ohne den SL zu setzen.

Ich hoffe ich werde hier nicht gesteinigt, weil ich mir diesen EA Builder gekauft habe. Ich habe leider nicht die Zeit mir das Programmieren auf die schnelle beizubringen und mir wurde das Ding empfohlen. 

Vielleicht kann mir von euch jemand bei meinem Problem weiterhelfen bzw Tips geben wie ich zu meinem EA doch zum Laufen bringe.

Vielen Dank im voraus für eure Kommentare.

Strategietester - Algorithmisches Trading, Handelsroboter - MetaTrader 5 Hilfe
Strategietester - Algorithmisches Trading, Handelsroboter - MetaTrader 5 Hilfe
  • www.metatrader5.com
Der Strategietester erlaubt das Testen von Strategien mit Handelsrobotern ( Expert Advisors ) vor der Nutzung im Live-Trading. Während des...
 

Zusätzliche Information.

Im Journal bekomme ich eine Fehlermeldung:

ERR_TRADE_POSITION_NOT_FOUND

4753

Position ist nicht gefunden


Jedoch keine explizite Fehlermeldung für den SL.

 

Also generell, wenn eine EA ohne Fehler kompiliert, aber nicht tut was er soll, kann man:

  1. In Mt5 hat sich die Richtung der Zeitreihen geändert - mich verwirrt das immer noch, daher überprüfe IMMER (Comment,Print,Debugger,..), ob die Werte an einem Index auch die sind die ich will!
  2. Wieso soll das mit den Trendlinien im MT5 im Handel nicht funktionieren - IMMER die Logs (Expert und Journal) kontrollieren!!
  3. Was bei Dir fehlt, sind Print(), wenn eine Funktion nicht ausgeführt wurde, Stichwort: _LastError!
  4. Besonders im Tester, visueller Modus -  mit Comment() verfolgen, was anders läuft als gedacht, oder
  5. man schmeißt den Debugger (live oder mit historischen Daten, beides geht im MT5) an, um die relevanten Variablen gezielt zu verfolgen, wenn man die Haltepunkt dort setzt, wo was passieren sollte, dazu (man muss nicht alles lesen ;) :
        https://www.metatrader5.com/de/metaeditor/help/development/debug
        https://www.mql5.com/de/articles/654&nbsp; // Zur Fehlerbehebung von MQL5-Programmen (Debugging)
        https://www.mql5.com/de/articles/35 // Einführung in MQL5: Schreiben eines einfachen Expert Advisor und benutzerdefinierten Indikators, Siehe Ende: Starten und Debuggen
        https://www.mql5.com/de/articles/2041 // Die Fehlerverarbeitung und Protokollierung in MQL5
        https://www.mql5.com/de/articles/272
        https://www.mql5.com/de/articles/150 //Fehler finden und Protokollierung
  6. Such mal (oben rechts die Lupe) nach Breakout: CodeBase, Artikel - es gibt haufenweise Zeug, schau mal, da ist sicher etwas was Deinem nahe kommt und Du Teile herauszukopieren könntest.

Code-Debugging - Programme entwickeln - MetaEditor Hilfe
Code-Debugging - Programme entwickeln - MetaEditor Hilfe
  • www.metatrader5.com
MetaEditor hat einen eingebauten Debugger, mit dem Sie die Programmausführung Schritt für Schritt (durch einzelne Funktionen) ü...
 
Carl Schreiber #:

Also generell, wenn eine EA ohne Fehler kompiliert, aber nicht tut was er soll, kann man:

  1. In Mt5 hat sich die Richtung der Zeitreihen geändert - mich verwirrt das immer noch, daher überprüfe IMMER (Comment,Print,Debugger,..), ob die Werte an einem Index auch die sind die ich will!
  2. Wieso soll das mit den Trendlinien im MT5 im Handel nicht funktionieren - IMMER die Logs (Expert und Journal) kontrollieren!!
  3. Was bei Dir fehlt, sind Print(), wenn eine Funktion nicht ausgeführt wurde, Stichwort: _LastError!
  4. Besonders im Tester, visueller Modus -  mit Comment() verfolgen, was anders läuft als gedacht, oder
  5. man schmeißt den Debugger (live oder mit historischen Daten, beides geht im MT5) an, um die relevanten Variablen gezielt zu verfolgen, wenn man die Haltepunkt dort setzt, wo was passieren sollte, dazu (man muss nicht alles lesen ;) :
        https://www.metatrader5.com/de/metaeditor/help/development/debug
        https://www.mql5.com/de/articles/654&nbsp; // Zur Fehlerbehebung von MQL5-Programmen (Debugging)
        https://www.mql5.com/de/articles/35 // Einführung in MQL5: Schreiben eines einfachen Expert Advisor und benutzerdefinierten Indikators, Siehe Ende: Starten und Debuggen
        https://www.mql5.com/de/articles/2041 // Die Fehlerverarbeitung und Protokollierung in MQL5
        https://www.mql5.com/de/articles/272
        https://www.mql5.com/de/articles/150 //Fehler finden und Protokollierung
  6. Such mal (oben rechts die Lupe) nach Breakout: CodeBase, Artikel - es gibt haufenweise Zeug, schau mal, da ist sicher etwas was Deinem nahe kommt und Du Teile herauszukopieren könntest.

Hallo Carl, herzlichen Dank für deine Hilfe!!! Ich werd mich mal reinlesen in den Debugger und sehen wie weit ich komme. Vielleicht muss ich mich nochmal melden :)