Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools

Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools (http://www.expert-advisor.com/forum/index.php)
-   Programmierung MQL4 (http://www.expert-advisor.com/forum/forumdisplay.php?f=220)
-   -   Abfrage der Werte der letzten Kerze bei neuer Kerze (http://www.expert-advisor.com/forum/showthread.php?t=6350)

gpi 03.03.19 18:44

Abfrage der Werte der letzten Kerze bei neuer Kerze
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo liebe User,

habe folgendes Problem, das mir beim Backtest im MT4 nach einer neuen Kerze die Werte der letzten Kerze nicht zurückgegeben werden.

weder mit High[1] noch mit iHigh()

hier mein Code

Code:

void OnTick(){
     
      //myComment = myCandleTrail(buySL,sellSL);
      if(isNewBar()){
        CheckForNewTrade();      //Eröffnet neue Trades
        mySignal = SignalLage(); //Prüft ob ein Gegensignal vorliegt

        //CandleTrail Stopp nachziehen
        myComment = myCandleTrail(buySL,sellSL); //buySLPrice u. sellSLPrice aus Funktion wird übergeben
        Comment(myComment);
        Print(myComment);
      }
   
   
   
    //Comment(myComment);
    if (SpeedControl == true)
        f_BackTestSpeed(mySpeed,myComment);
   
   
 }


isNewBar Funktion Methode 1:


Code:

bool isNewBar(){
  static datetime lastTime= 0;
  if(lastTime == 0)
      lastTime = Time[0];    // Initialisierung beim ersten Tick
        if(Time[0] == lastTime)
            return(false);
        else {
            lastTime= Time[0];
            return(true);
        }
}


Funktion isNewBar Methode 2:


Code:

bool IsNewBar()
{
  static int BarsOnChart=0;
        if (Bars == BarsOnChart)
        return (false);
        BarsOnChart = Bars;
        return(true);
}


Ich bekomme immer die Werte der vorletzten Kerze!
bei i = 2 bei i = 1 und bei i=0
Diesen kommischen Fehler bekomme ich beim Tester.
Funktion TrailingStopp:

Code:

//+------------------------------------------------------------------+
//| Funktion myCandleStop!                                          |
//+------------------------------------------------------------------+
// Funktion myCandleStop gibt folgende Werte zurück
// buySLPrice = Stoppkurs für Kauforder, sellSLPrice =  Stoppkurx für Sellorder
// cBuySL = Kerze des Stopps für Kauforder, cSellSL = Kerze des Stopps für SellOrder
// cB = ist der Wert
void myCandleStop(int cB,int cBRW, string mySig, double & buySLPrice, double & sellSLPrice, int & cBuySL, int & cSellSL){
      int i = 1;
      if (mySig=="Long"){
        //int i = 1;  //Shiftwert von der alktuellen Kerze
        // gibt die Stoppkurse zurück
        buySLPrice=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,cB,i));
        sellSLPrice=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,cBRW,i));
       
        // gibt die Kerze von der der Stoppkurs berechnet wurde zurück
        cBuySL = iLowest(_Symbol,_Period,MODE_LOW,cB,i);
        cSellSL = iHighest(_Symbol,_Period,MODE_HIGH,cBRW,i);
        if (High[i]<sellSLPrice) sellSLPrice=High[i];
      }
     
      if (mySig=="Short"){
        //int i = 1;  //Shiftwert von der alktuellen Kerze
        // gibt die Stoppkurse zurück
        buySLPrice=iLow(_Symbol,_Period,iLowest(_Symbol,_Period,MODE_LOW,cBRW,i));
        sellSLPrice=iHigh(_Symbol,_Period,iHighest(_Symbol,_Period,MODE_HIGH,cB,i));
       
        // gibt die Kerze von der der Stoppkurs berechnet wurde zurück
        cBuySL = iLowest(_Symbol,_Period,MODE_LOW,cBRW,i);
        cSellSL = iHighest(_Symbol,_Period,MODE_HIGH,cB,i);
        if (High[i]<sellSLPrice) sellSLPrice=High[i];
      }

//return (0); 
     
 }


Ich hab diesen zusätztlichen Unsinn:
"if (High[i]<sellSLPrice) sellSLPrice=High[i];"

mal testweise in die Funktion zusätzlich eingesetzt.

Da nicht die Werte der letzten Kerze zurückgegeben werden, entstehen unnötige Fehltrades, wenn die letzte Kerze höher, bzw. tiefer als die vorletzte Kerze war.

Siehe Nr. 1 und 2 auf angehängter Grafik "NewBar".


Für Infos wäre ich dankbar.

Gruß
Günter

gpi 03.03.19 19:29

Abfrage bei jedem Tick: funktioniert
 
Noch zur Info,

mache ich die Stoppabfrage bei jedem Tick und nicht nur, wenn eine neue Kerze anfägt, dann funktioniert es interssanter weise richtig.

Dies wäre aber blod, da man dann in besonderen Situationen den Stopp nicht selber eventuell manuell weiter wegzogenen werden kann, ohne bei dem nächsten Tick wieder angepasst zu werden.

Gruß

Günter

traderdoc 04.03.19 19:27

Mein Standardcode dazu wäre:
Code:

if (OldTime != Time[0]) {
  //Kerzenabfrage
  OldTime = Time[0];
}

Das funktioniert immer.

traderdoc

gpi 05.03.19 21:45

Dank für die Info,

hab es auch gleich ausprobiert, aber genau das gleiche Problem mit dem Strategietester. Ist halt Schade, da der Backtest dadurch nicht mehr so ganz stimmt.

Hab es auch auf dem Live-Konto im 1-min-Chart getestet. Da existiert das Problem nicht.

Trozdem danke.

Gruß

Günter

traderdoc 05.03.19 22:20

Liste der Anhänge anzeigen (Anzahl: 1)
Das funktioniert wirklich immer.

traderdoc

gpi 06.03.19 11:05

Hallo Traderdok, hab's so eingebunden und funktioniert auch nicht korrekt. Der Fehler tritt nur im Backtest auf.

Code:

void OnTick(){
     
      //myComment = myCandleTrail(buySL,sellSL);
      //if(IsNewCandle()){
      if (OldTime != Time[0]) {
        //Kerzenabfrage
       
        CheckForTrade();
        mySignal = SignalLage();
        //CandleTrail Stopp nachziehen
        myComment = myCandleTrail(buySL,sellSL); //buySLPrice u. sellSLPrice aus Funktion wird übergeben
        Comment(myComment);
        Print(myComment);
      //}
   
        OldTime = Time[0];
      }   
   
    //Comment(myComment);
    if (SpeedControl == true)
        f_BackTestSpeed(mySpeed,myComment);
}

Progamm hat folgenden Ablauf:

Code:

Bei jedem Tick: Prüfung ob neue Kerze => Wenn nein, nichts

Wenn ja: 
  1. Prüfen ob neuer Trade zu machen ist  =>
    Wenn ja: 1. Trade wird eröffnet! Funktion CheckForTrade
                Diese öffnet zuerst Trade und setzt danach TakeProfit und den initialten Stopp ist (sehr weit weg) mittel OrderModify
              2. Funktion: SignalLage Prüft bei jeder neuen Kerze ob ein Gegensignal vorliegt und speichert dis in mySignal.
                Dann wird der Stopp näher gezogen als sonst. Siehe Funktion myCandleStop oben im Post Stopp letzets Tief der x-Kerzen
                zB. noch kein Gebensignal 20 Kerzen und Gegensignal nur mehr 3 Kerzen
              3. Funktion myCandleTrail wird aufgerufen: diese ruft als 1. die Funktion myCandleStop auf und fragt
             
                      string myCandleTrail(double buySLPrice,double sellSLPrice){
                              myCandleStop(cBack,cBackRW,mySignal,buySL,sellSL,cBuyStop,cSellStop);
                              string myCom = ("\nbuySL: " + DoubleToString(buySL,Digits) + "  Kerze: " + IntegerToString(cBuyStop) +
                              "\nsellStop: " + DoubleToString(sellSL,Digits) + "  Kerze: " + IntegerToString(cSellStop) +
                              "\n\nSignal: " + mySignal);
                              //buy order section
                              for(int b=OrdersTotal()-1;b>=0;b--){
                                if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
                                    if(OrderMagicNumber()==MagicNumber)
                                      if(OrderSymbol()==Symbol())
                                          if(OrderType()==OP_BUY)
                                            if(OrderStopLoss() < buySLPrice-PadAmount)
                                                //Print("GP: BuySL: ", buySL2-PadAmount2);
                                                if(!OrderModify(OrderTicket(),OrderOpenPrice(),buySLPrice-PadAmount,OrderTakeProfit(),0,CLR_NONE))
                                                  Print("error modifying buy order ",GetLastError());
                            }
                            //sell order section
                            for(int s=OrdersTotal()-1;s>=0;s--){
                            if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
                                if(OrderMagicNumber()== MagicNumber)
                                    if(OrderSymbol()==Symbol())
                                      if(OrderType()==OP_SELL)
                                          if(OrderStopLoss()>sellSLPrice+PadAmount2)
                                          // Print("GP: sellSL: ", sellSL2);
                                            if(!OrderModify(OrderTicket(),OrderOpenPrice(),sellSLPrice+PadAmount2,OrderTakeProfit(),0,CLR_NONE))
                                                Print("error modifying sell order ",GetLastError());
                            }
                            return (myCom); //Rückgabe für Ausgabe auf Chart von welcher Kerze Nr. und Preis für beide Richtungen

Es passiert beim Backtest folgendes:

Neue Kerze => Trade wird eröffnet, =>
Inital-SL u. TP werden gesetzt, =>
SL wird falsch gesetzt, falls die letzte Kerze die höchste oder tiefste Kerze war, da die Berechnung des Stopps im Backtest anscheinend immer ab der vorletzten Kerze beginnt.

Der Shitfwert wird eigentlich von der Variable "i" aus der Funktion myCandleStop bestimmt.

Gruß

Günter

gpi 06.03.19 11:12

Noch was, man kann zwar beim Backtest die Funktion myCandleTrail bei jedem Tick aufrufen, weil dann funktioniert die Stoppstetzung korrekt, aber dann dauert ein Backtest auch entsprechend länger.

Gruß

Günter

traderdoc 06.03.19 11:43

Keine Ahnung, was in Deinem Code nicht stimmt, aber das von mir angehängte Bild resultierte aus dem Backtest mit der Abfrage über
High[1] und Low[1] gemäß meines Codeschnipsels. Und am Bild und den Kommentarzeilen des Terminals sind die korrekten Werte dafür ablesbar.

traderdoc

gpi 06.03.19 14:02

Hallo Traderdoc,

es funktioneren alle 3 Möglichkeiten(Funktionen isNewBar) nun.

Der Fehler lag an der Variablenzuweisung.

Code:

string myCandleTrail(double buySLPrice,double sellSLPrice){
      myCandleStop(cBack,cBackRW,mySignal,buySL,sellSL,cBuyStop,cSellStop);

      // Danach fehlte folgende Variablenzuweisung:
      buySLPrice = bySL;
      sellSLPrice = sellSL;
      //somit standen immer die Werte in noch aus dem letzten Periodenwert drinnen1

Oft sieht man den Wald vor lauter Bäume nicht mehr!
Trotzdem vielen Dank für deine Mühe.

Gruß

Günter


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:58 Uhr.

Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.6.1
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum