Warum kauft er so komisch???

 

Guten Tag Leute,

Um ein paar selbst gebastelte Module zu testen verwende ich einen MA Crossover als Signalgeber. Also von dem geschriebenen Programm erst alle unnötigen Module deaktivieren und dann eins nach dem Anderen wieder hinzufügen und sehen wo das Problem liegt.

Leider wurden auch die Signale alleine nicht so umgesetzt wie in den Bedingungen. Vielleicht habe ich etwas übersehen... so werden zum Beispiel nicht immer die Inputs angewandt, die man im Editor einträgt, auch wenn man schon oft kompiliert hat. Gibt es da einen Trick, außer eine neue Datei erstellen, damit man am veränderten Baum erkennt, dass Änderungen wahrscheinlich übernommen wurden?

Aber was sehr seltsam ist, ist dass die Bedingungen nicht so umgesetzt werden, wie man sie eingegeben hat (s. u. orange).

//+------------------------------------------------------------------+
//|                                   CrossoverTrailingCounter01.mq5 |
//|                        Copyright 2020, pennyhunter               |
//|                                                                  |
//+------------------------------------------------------------------+
#property description ""
#property description ""
#property description ""

//--- input parameters
#include<Trade\Trade.mqh>
#include<Trade\SymbolInfo.mqh>
                              //MagicManager evtl. später hinzufügen
input int      Periode1=20;
input int      Periode2=50;
input int      Shift=0;
input int      SL=8500;
input int      TP=40000;
input double   Lotsize=0.01; //dynamische Lotsize-Berechnung später hinzufügen
//input int      Step=15;
//input int      CandlesPause=2;   // hier wurden Variablen stillgelegt um sie später zu aktivieren
input int      PosMax=2;
   
//   int BuyCounter;
//   int SellCounter;
   
   double MA1[],MA2[];
//   double SLValueCurrent, TPValueCurrent;
     
   bool Kaufsignal=false;
   bool Verkaufssignal=false;
   
   double Ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   double Balance=AccountInfoDouble(ACCOUNT_BALANCE);
   double Equity=AccountInfoDouble(ACCOUNT_EQUITY);

   int MADef1;
   int MADef2;
   
CTrade      trade;
CSymbolInfo symbolinfo;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MADef1 = iMA(_Symbol,_Period,20,0,MODE_EMA,PRICE_CLOSE);
   MADef2 = iMA(_Symbol,_Period,50,0,MODE_EMA,PRICE_CLOSE);

   ArraySetAsSeries(MA1,true);
   ArraySetAsSeries(MA2,true);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   CopyBuffer(MADef1,0,0,3,MA1); 
   CopyBuffer(MADef2,0,0,3,MA2);
   
/*
   CheckTrailingStopAsk();                      //Code ausgeschlossen
   CheckTrailingStopBid();
   CheckTrailingTakeAsk();
   CheckTrailingTakeBid();

   CheckNewCandle();
*/
   CheckBuy();   
   CheckSell();         

   BuyResetCount();
   SellResetCount();   
   
    
   }
        
bool   CheckBuy()
   {
   if (     (MA1[0]>MA2[0])                                //das ist die einfachste Bedingung für zwei MAs. Ich verstehe nicht, warum sie nicht die
                                                           //ganze Zeit feuert und zwar Kaufsignal, wenn der schnelle über dem langsamen MA ist.
//       &&   (BuyCounter>=CandlesPause)  
      )
            {
            Comment("Kaufen");
            Kaufsignal=true;
            }
            return(true);
            }
   
bool   CheckSell()         
   {
   if (     (MA1[0]<MA2[0])                                //Und auch umgekehrt, denn wie man unten sieht, ist die Handelspause noch gar nicht aktiv.
//       &&   (SellCounter>=CandlesPause)  
      )
            {
            Comment("Verkaufen");
            Verkaufssignal=true;           
            }
            return(true);
            }
       
void BuyResetCount()
   {
   if  (
        (Kaufsignal == true)  
   &&   (PositionsTotal()<PosMax)
       )
        {
        trade.Buy(Lotsize,NULL,Ask,(Ask-SL*_Point),(Ask+TP*_Point),NULL);
//        BuyCounter = 0;
        }
   }     
 
      
void SellResetCount()      
   {
   if  (
        (Verkaufssignal == true)  
   &&   (PositionsTotal()<PosMax)
       )
        {
        trade.Sell(Lotsize,NULL,Bid,(Bid+SL*_Point),(Bid-TP*_Point),NULL);
//        SellCounter = 0;
        }
   }  


/*
void CheckNewCandle()                                                  //code excluded
  {
      static datetime saved_candle_time;
      if(iTime(_Symbol,_Period,0)==saved_candle_time)
      {
      BuyCounter++;
      SellCounter++;
      }
      else saved_candle_time=iTime(_Symbol,_Period,0);
   }   
          
/*

void CheckTrailingStopAsk()

  {
  SLValueCurrent=NormalizeDouble(Ask-SL*_Point,_Digits);
   for(int i=PositionsTotal()-1; i>=0; i--)
    {
     string symbol=PositionGetSymbol(i);
     if(_Symbol==symbol)
        {
        ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
        double PositionStopLoss=PositionGetDouble(POSITION_SL);
        if (PositionStopLoss<SLValueCurrent)
         trade.PositionModify ( PositionTicket,(PositionStopLoss+10*_Point),0);
  }}}

void CheckTrailingStopBid()

  {
   SLValueCurrent=NormalizeDouble(Bid+SL*_Point,_Digits);
   for(int i=PositionsTotal()-1; i>=0; i--)
    {
     string symbol=PositionGetSymbol(i);
     if(_Symbol==symbol)
        {
        ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
        double PositionStopLoss=PositionGetDouble(POSITION_SL);
        if (PositionStopLoss<SLValueCurrent)
         trade.PositionModify ( PositionTicket,(PositionStopLoss+10*_Point),0);
  }}}
//+------------------------------------------------------------------+
void CheckTrailingTakeAsk()

  {
   TPValueCurrent=NormalizeDouble(Ask-150*_Point,_Digits);
   for(int i=PositionsTotal()-1; i>=0; i--)
    {
     string symbol=PositionGetSymbol(i);
     if(_Symbol==symbol)
        {
        ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
        double PositionTakeProfit=PositionGetDouble(POSITION_TP);
        if (PositionTakeProfit<TPValueCurrent)
         trade.PositionModify ( PositionTicket,(PositionTakeProfit+10*_Point),0);
  }}}

void CheckTrailingTakeBid()

  {
   TPValueCurrent=NormalizeDouble(Bid+150*_Point,_Digits);
   for(int i=PositionsTotal()-1; i>=0; i--)
    {
     string symbol=PositionGetSymbol(i);
     if(_Symbol==symbol)
        {
        ulong PositionTicket = PositionGetInteger(POSITION_TICKET);
        double PositionTakeProfit=PositionGetDouble(POSITION_TP);
        if (PositionTakeProfit<TP)
         trade.PositionModify ( PositionTicket,(PositionTakeProfit+10*_Point),0);
  }}}  
  
*/

Das passiert im Test (Es geht dann nicht mehr weiter):

Warum?

Ein Blick ins Journal verrät uns, dass ungültige Stops der Grund dafür sein sollen.

Warum invalid stops?

Sind sie vielleicht zu groß? Zu klein jedenfalls nicht (s.o.)...

Na gut, dann eben im visuellen Modus...

hm

Dieser Kauf sieht noch nachvollziehbar aus.

Aber das

Aber warum wird die obere Position gleich wieder aufgelöst?

Kaufverkauf

Und hier, warum wird denn hier gekauft und gleich wieder verkauft?


Gibt es Gründe, die nicht klar ersichtlich sind? Vielleicht eine Eigenheit der CTrade in Verbindung mit boolean Signalen (Signalumkehr??)
Der Plan war ja, die Komplexität zu vermindern um eine Reproduzierbarkeit zu erreichen. Aber das was er mir da ausspuckt hat ja mit Reproduzierbarkeit nicht mehr so viel zu tun...
Danke schon mal für jede Hilfe.

Nachtrag: Kann das vielleicht wirklich sein, dass das was mit den Booleanfunktionen zu tun hat? Es gibt da noch eine älteree Version von dem Crossoversignal mit string signal= "" und das funktioniert ein Bisschen besser, jedenfalls vekauft es nicht direkt nach  dem Kauf wieder.

 

1. Würd ich nix in der Init()-Funktion deklarieren

2. Seh ich bei den MA-Deklarationen irgendwie keine Angaben zu Kerzen

3. Sind das bei CheckSell/CheckBuy, wenn ich richtig gesehn habe, mehr ( ) - Klammern als nötig

4. Hab ich aber nur überflogen und vielleicht was übersehn.
 

Die Log-Einträge sind nicht ausreichend :(

Um den Fehler zu erkennen musst Du zusätzlich den Kauf- bzw. Verkaufspreis ausweisen (Ask oder Bid, je nachdem), außerdem wie groß der Abstand sein muss: SYMBOL_TRADE_STOPS_LEVEL von hier: https://www.mql5.com/de/docs/constants/environment_state/marketinfoconstants#enum_symbol_info_double

Dokumentation zu MQL5: Konstanten, Enumerationen und Strukturen / Medium Zustand / Information über das Symbol
Dokumentation zu MQL5: Konstanten, Enumerationen und Strukturen / Medium Zustand / Information über das Symbol
  • www.mql5.com
Information über das Symbol - Medium Zustand - Konstanten, Enumerationen und Strukturen - Nachschlagewerk MQL5 - Nachschlagewerk über die Sprache des algothitmischen/automatischen Handels für MetaTrader 5
 
pennyhunter:

Aber warum wird die obere Position gleich wieder aufgelöst?

Und hier, warum wird denn hier gekauft und gleich wieder verkauft?


Du hast einen Denkfehler im Chart.

Die Position wird nicht gleich wieder verkauft.

Es wird NACH dem verkauf gleich eine neue Position aufgemacht.

Du hast kein Zeitpuffer in deine Logik für das Öffnen von neuen Positionen.


Das Bild zeigt es deutlich.


 
Und wie soll ich jetzt erkennen warum was schief gelaufen ist? Gründe gebe mehrere - der Debugger ist Dein Freund.
 
Carl Schreiber:
Und wie soll ich jetzt erkennen warum was schief gelaufen ist? Gründe gebe mehrere - der Debugger ist Dein Freund.

Meinst Du mich gerade? Falls ja  ich gebe nur die Antwort auf die eine Frage.

Er hat ja mehrere Fragen.

 
Jain - ich dachte in meiner Hast, Deine Antwort sei von ihm.
 
Christian:

Du hast einen Denkfehler im Chart.

Die Position wird nicht gleich wieder verkauft.

Es wird NACH dem verkauf gleich eine neue Position aufgemacht.

Du hast kein Zeitpuffer in deine Logik für das Öffnen von neuen Positionen.


Das Bild zeigt es deutlich.


Oh... da mir leider nicht in den Sinn kam, diesen Thread zu favorisieren, ist mir entgangen, dass Ihr so zahlreich geantwortet habt. Also danke für Eure rege Teilnahme!

Du hast Recht mit dem Zeitpuffer, ich habe da seitdem auch drüber nachgedacht und angefangen Bots zu bauen, die nur einmal pro Kerze kaufen. Da werde ich jetzt die Tage noch etwas mehr Rafinesse investieren müssen. Das Problem ist schon länger her und ich durch zu große Stops einen Margin Call provoziert... obwohl dann müsste da ja "not enough money" stehen .


Carl Schreiber:
Und wie soll ich jetzt erkennen warum was schief gelaufen ist? Gründe gebe mehrere - der Debugger ist Dein Freund.

Muss mal schauen ob ich einen Leitfaden finde, Du hast das schon öfter geschrieben bei verschiedenen Leuten mit den Haltepunkten, aber da ich nicht aus dem Programmierbetrieb komme, kann ich mir das nicht richtig vorstellen. Ich habe die Option Haltepunkte zwar im Editor schon gesehen, weiß aber nicht sicher was man damit bewirkt (außer dass das Progamm vielleicht an der Stelle hält?!?)

Ich mache mir mittlerweile immer Print Statements an den entscheidenden Stellen um zu wissen, ob eine Funktio ausgeführt wird oder nicht bzw. lasse mir Werte in einem Array als Comment() anzeigen um zu sehen wie sie durchlaufen usw.