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)
-   -   WIe benutze ich iCLose() bzw. Close[] und Co. richtig? (http://www.expert-advisor.com/forum/showthread.php?t=6667)

berndao 18.05.20 21:27

WIe benutze ich iCLose() bzw. Close[] und Co. richtig?
 
Hallo,
ich bin noch recht neu beim EA Programmierung und wollte für den Anfang nur mal einen EA, der mir bei jedem Tick den aktuellen Close Preis gibt sowie die Zeit.

Ich hatte daher in der OnTick Funktion mit Sachen wie
Code:

Print(iTime(NULL,0,0));
oder
Print(iTime(NULL,0,Bars-1));

experimentiert und im Backtesting laufen lassen.
Erwartet hätte ich, dass ich zumindest bei einem von beiden, eine Reihe von Close Preisen kriege, eben zu jedem zeitpuntk den aktuellen Close Preis.

index 1 würde auch noch Sinn machen um nciht den aktuellen bar zu nehmen sondern den letzten abgeschlossenen.

Aber egal, mit welchem Index ich da vorging, so erhielt ich nach speichern, kompilieren und im Strategietester laufen lassen immer nur ein Log dass mir immer den selben preis hinschreibt, so als hätte er sich während der rund 50000 Bars kein Bisschen verändert.

Und ich verstehe nicht warum.
Die dokumentation auf https://docs.mql4.com/series/iclose
schreibt doch eindeutig:
"Returns Close price value for the bar of specified symbol with timeframe and shift."

sprich: gibt mir den close price der Bar zurück, den ich mittels shift (und dem timeframe, währungspaar; was hier aber unwichtig sei)angegeben habe.

meiner logischen Auffassung ändert sich der Chart doch sobald ein neuer balken abgeshclossen wird, oder?

wird ein balken abgeschlossen, so erscheint rechts ein neuer Balken, alle alten balken gehen indexmässig eins nach oben (0->1,1->2, usw)
und der balken ganz links fliegt visuell raus.

Jedenfalls dürfte der jetzige index 0 balken doch bitteschön nciht derselbe sein wie der index 0 balken einige zeitperioden später, oder?

Ich verstehe einfach nicht warum mit neu erscheinenden Balken sich nicht audch die Daten des (jeweiligen) 0-ten oder 1-ten bars entsrechend ändert.

wenn ich wie erwähnt meinen kurzen Code (der in der iOnTick Funktion ist) backteste, zeigt er mir im Log in all den zeilen immer die selbe Zahl.
Was ja nicht sein kann.

Der Close Preis ändert sich doch mit jedem Balken!


Kann mir bitte wer weiterhelfen?
Hatte shcon einmal anderswo gefragt aber dort konnte (oder wollte?) man mir nicht weiterhelfen und verwies nur unfreundlich auf die Dokumentation.
Die, wie oben erwähnt, dem realen Ergebnis widerspricht :-(

Hatte das selbe Prozedere zu beginn mit dem Close[] Array versucht aber gleiches Problem auch dort :-/

Irgendwie kriege ich einfahc nicht periodenaktuell den letzten close preis geliefert :-/

MA-EA 19.05.20 00:46

Man müsste iClose() abfragen und nicht iTime(). :confused:
Code:

double CP_1=iClose(Symbol(),TimeFrame,1);

berndao 19.05.20 10:56

Das ist schon klar....

Es geht um Folgendes:
Wenn ich bspw. diesen Code habe:
Code:

//+------------------------------------------------------------------+
//|                                                        Test3.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                            https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version  "1.00"
#property strict




//+------------------------------------------------------------------+
//| Expert initialization function                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
 
  Print("Start Time is= ",TimeCurrent());
 
//---
  return(INIT_SUCCEEDED);
  }
 
 
//+------------------------------------------------------------------+
//| Expert tick function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
 
 
  Print("Last Bar Time is= ",Time[1], "and last Close Price is= ",Close[1]);
  }
//+------------------------------------------------------------------+

habe den gespeichert, kompiliert und backteste damit, dann steht im journal in dutzenden zeilen der selbe Text.

Wie kriege ich das hin dass der Text nur einmal pro Balken geschrieben wird?

Weil irgendwie vermute ich dass der Preis der Balken, der mir da ausgegeben wird, einfach falsch ist :-/

berndao 19.05.20 11:15

Okay, ich habe wohl eine Lösung gefunden:
Code:

//+------------------------------------------------------------------+
//|                                                        Test3.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                            https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version  "1.00"
#property strict

datetime LastActiontime;

//+------------------------------------------------------------------+
//| Expert initialization function                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
 
  Print("Start Time is= ",TimeCurrent());
  LastActiontime=Time[1];
  Print("die Zahl ",1.23456789," gerundet auf die ",_Digits,"te Nachkommastelle ergibt ",roundD(1.23456789));
 
//---
  return(INIT_SUCCEEDED);
  }
 
 
//+------------------------------------------------------------------+
//| Expert tick function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
  if(LastActiontime==Time[1]){
    return;
  }
  else
  {
    LastActiontime=Time[1];
  }
  Print("Last Bar Time is= ",Time[1], "and last Close Price is= ",Close[1]);
 
 
//+------------------------------------------------------------------+
}


double roundD(double number){
  double n=number*MathPow(10,_Digits);
  int b=MathRound(n);
  double c=b;
  double result=c/MathPow(10,_Digits);
  return result;

}

Letztlich habe ich eind datetime Variable, die trackt ob sich seit dem letzten Tick die Open Zeit des letzten balkens geändert hat.
Nur dann wird der Code ausgeführt.

TogoTiger 19.05.20 13:11

Richtig.
In meinen EAs steht das so drin:

datetime TimeOld;

void OnTick()
{
if(Time[0] != TimeOld)
{
hier haben wir eine neue Kerze
}

TimeOld = Time[0];

hier den Rest von OnTick
}

berndao 19.05.20 13:26

Das geht natürlich auch.
Ich will nur insofern index 1 benutzen weil ich später sowieso für alles index 1 benutze (will ja nur abgeschlossene Kerzen betrachten).

Etwas, was mich etwas verwundert:
Soweit funktioniert das erstaunlicherweise Alles, wie es soll.

Nur habe ich im Log dann mnachmal Zeilen wie
Code:

... Last Bar Time is= 2020.04.09 12:00:00and last Close Price is= 0.8764999999999999
Sprich:
statt 0.8765 kriege ich diese krumme Zahl.
(wenn ich im Chart mit der Maus über den Balken gehe, sehe ich dass die letze Stelle 5 sien muss, daher)


Jetzt dachte ich anfangs, da liefe was beim berechnen shcief und habe daher die Rundungsfunktion gebaut, die gerade auf die letzte verfügbare Stelle rundet.

Leider ohne Erfolg, die Preise werden teilweise trptzdem mit eunendlich vielen Nachkommazahlen angezeigt wie oben.

Liegt das eventuell an metatrader selbst irgendwie?
Kann ich das irgendwie umgehen?

AVT 19.05.20 13:42

Print( DoubleToString(Wert, _Digits) );
Die _Digits schneiden hinten alles weg, was länger als Digits ist.
AVT

berndao 19.05.20 13:51

Zitat:

Zitat von AVT (Beitrag 43739)
Print( DoubleToString(Wert, _Digits) );
Die _Digits schneiden hinten alles weg, was länger als Digits ist.
AVT

Ich bin gerade ziemlich schockiert dass es so eine einfache vordefinierte Lösung gibt...

jetzt würde mich natürlich interessieren wie intern diese DoubleToString Funktion aussieht.
kann man das irgendwo nachlesen?

die Dokumentation gibt bei sowas ja nur Inputs und Output an, aber nicht wie die Funktion genau funtkionert

AVT 19.05.20 14:14

Zitat:

Zitat von berndao (Beitrag 43740)
jetzt würde mich natürlich interessieren wie intern diese DoubleToString Funktion aussieht.
kann man das irgendwo nachlesen?

die Dokumentation gibt bei sowas ja nur Inputs und Output an, aber nicht wie die Funktion genau funtkionert

Guck mal den Inlcude Ordner durch, würde vermuten, daß man das unter sowas wie Strings oder Tools findet. AVT

TogoTiger 19.05.20 14:52

Doubles sind nun mal so.
Der Typ Double ist eine Gleitkommavariablen mit einer Größe von 8 Byte. Damit kannst du 15 Dezimalstellen darstellen, als sehr grosse Zahl oder auch sehr kleine. Sie ist aber immer nur auf 15 Stellen genau.
Wenn du damit rechnest kann es passieren, dass es nicht 'aufgeht'. z.B. 1/3 gibt 0.333333..... unendlich. Du kannst das ohne Rundungsfunktion in einem Double darstellen, aber es stimmt eben in der 15. Nachkommastelle nicht mehr ganz genau.
Ich treffe heute noch ab und zu auf alte Software die damit so seine Probleme hat. Grad letzthin hat der Revisor eines Kunden die Buchhaltung bemängelt, weil Total Soll - Total Haben 0.01 angezeigt hat, obwohl eigentlich alles stimmt. Ist schwierig zu beheben, ausser der Kunde kauft endlich ein moderneres Buchhaltungsprogramm :)
Aber DoubleToString hilft dir ja weiter.

berndao 19.05.20 16:49

Ich will ja auch gar nichts gesagt haben :-)

Ich glaube, so langsam kriege ich den Dreh raus.
Habe mir mal einen EA gebaut, der guckt ob für 5 hintereinanderfolgende Balken sich der Abstand von oberer Linie zu Mittellinie koninuierlich verringert :-)

Sowie eine Funktion, die mir bei jedem balken anzeigt wie sich prozentual der Abstand verändert hat :-)


Code:

//+------------------------------------------------------------------+
//|                                                        Test3.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                            https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version  "1.00"
#property strict

datetime LastActiontime;


bool BBcontract(){
  for(int i=1;i<=5;i++){
      double Band_Highcur = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_UPPER,i);
      double Band_Modecur = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_MAIN,i);
      double Band_Highprev = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_UPPER,i+1);
      double Band_Modeprev = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_MAIN,i+1);
 
    if((Band_Highprev-Band_Modeprev)*0.98<(Band_Highcur-Band_Modecur)){
      return false;
    }
  }
  return true;
}


double BBContpercent(){

      double Band_Highcur = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_UPPER,1);
      double Band_Modecur = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_MAIN,1);
      double Band_Highprev = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_UPPER,2);
      double Band_Modeprev = iBands(NULL,0,20,2.0,0,PRICE_CLOSE,MODE_MAIN,2);
 
      return ((Band_Highcur-Band_Modecur) /(Band_Highprev-Band_Modeprev));
}


//+------------------------------------------------------------------+
//| Expert initialization function                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
 
  Print("Start Time is= ",TimeCurrent());
  LastActiontime=Time[1];
  //Print("die Zahl ",1.23456789," gerundet auf die ",_Digits,"te Nachkommastelle ergibt ", roundD(1.23456789));
  Print("");
  //Print( DoubleToString(Wert, _Digits) );
 
//---
  return(INIT_SUCCEEDED);
  }
 
 
 
//+------------------------------------------------------------------+
//| Expert tick function                                            |
//+------------------------------------------------------------------+
void OnTick() {
  if(LastActiontime==Time[1]){
    return;
  }
  else
  {
    LastActiontime=Time[1];
  }
 
  //Print("Last Bar Time is= ",Time[1], "and last Close Price is= ",DoubleToString(Close[1],_Digits));
  Print("At the previous Bar, are the Bollinger Bands contracting? ", BBcontract() );
  Print("by how much compared to the previous bar? ", DoubleToString(BBContpercent(),2));
  Print("");
 
//+------------------------------------------------------------------+
}





//Round a double number down to the last visible digit
double roundD(double number){
  double n=number*MathPow(10,_Digits);
  int b=MathRound(n);
  double c=b;
  double result=c/MathPow(10,_Digits);
  return result;

}


berndao 20.05.20 21:07

Eine Frage habe ich doch noch:
Je nahcdem, werde ich eventuell mehrere EAs auf dem selben Chart arbeiten lassen.

In jedem Fall wird es aber wohl so kommen dass mehrere EAs Orders öffnen und schließen.

Natürlich sollen sich die EAs nicht gegenseitig in die Quere kommen.

Daher wäre es praktisch wenn ich in einer zeile den EA einen Trade machen lasse und mir im nächsten befehl direkt die ID oder was auch immer des Trades espeichere (Hauptsache was, was den trade eindeutig identifizierbar macht)
Sodass ich später anhand der ID oder Ähnlichem den trade direkt wieder schließen kann.
Je nach Lust und Laune bastel ich mir vielleicht auch irgendwann ein Array (wer weiß ob der EA nicht irgendwann mehrere Trades gleichzeitig laufen hat) in der die IDs aller von diesem EA eröffneten Trades gespeichert sind oder so.

So oder so will ich mir , direkt nachdem vom EA ein Trade gemacht wurde, diesen irgendwie speichern für später.

Gibts da eine gute Variante?

Habe gelesen dass man sich eine Lsite aller offenen Trades besorgen kann.
Durch die ich mich dann durcharbeiten mpüsste und mit opentimes oder so abgleichen mpsste, welcher der richtige sein könnte.

Kann ich nicht irgendwie direkt den Trade abfangen und abspeichern?

Indikator-Trading 20.05.20 21:29

Das machst du mit OrderSelect() OrderSymbol() und der Magic Number der Order.

Indikator-Trading 20.05.20 21:35

Beim öffnen des Trades gibt dir die OrdnerSend () Funktion als Rückgabewert die Ticketnummer der Ordner zurück. Danach kannst du ebenfalls suchen um die Order zu managen

berndao 23.05.20 21:39

Ich habe gerade ein kleines Verständnisproblem (hat nicht mal was direkt mit der Programmierung zu tun):
neben anderen Sachen kann ich ja den aktuellen Ask und Bid Preis rausfinden.

Der Chart, der gezeichnet wird, hat ja auch einen eigenen Preis, der sich dauernd ändert (und dessen maximum in einer periode den high wert, tief punkt den low wert, etc. ergibt)

wenn ich nun eine order öffne, benutze ich ja bei einem buy order den ask price und bei einer sell order den bid preis.

aber wenn ich nun einen dieser trades laufen hab und diesen schließen will, welchn preis benutze ich da? sprich: zu welchem reis schließe ich letztlich einen trade? oder ist das nur das "gegenstück" zum eröffnungspreis?
(also beio buy order ask zum öffnen, bid zum schließen. und bei sell order umgekehrt)

hintergrund ist dass ich mir einen trailing stoploss basteln will, der den stoploss jeden tick , falls erforderlich, nahczieht.

zwangsläufig komme ich zu der bedingung
OrderStopLoss()<aktuellerPreis-stoplosswert*point

diesen aktuellen preis, welcher Wert ist das dann nochmal?

AVT 23.05.20 22:42

Zitat:

Zitat von berndao (Beitrag 43762)
hintergrund ist dass ich mir einen trailing stoploss basteln will, der den stoploss jeden tick , falls erforderlich, nahczieht.

zwangsläufig komme ich zu der bedingung
OrderStopLoss()<aktuellerPreis-stoplosswert*point

diesen aktuellen preis, welcher Wert ist das dann nochmal?

Beim SL mußt Du drauf achten, daß der "Gegenwert" den SL nicht trifft:
Kaufe zum Ask, dann achte drauf, daß Bid nicht den SL trifft.
Verkaufen zum Bid, dann achte drauf, daß Ask den SL nicht trifft.
Klar soweit? AVT

berndao 23.05.20 23:08

Zitat:

Zitat von AVT (Beitrag 43764)
Beim SL mußt Du drauf achten, daß der "Gegenwert" den SL nicht trifft:
Kaufe zum Ask, dann achte drauf, daß Bid nicht den SL trifft.
Verkaufen zum Bid, dann achte drauf, daß Ask den SL nicht trifft.
Klar soweit? AVT

Das heißt, wenn ich bspw eine buy order habe, dann öffne ich diese zum jeweiligen ask price und schließe sie zum bid preis?
Okay, das macht dann sinn :-)

berndao 24.05.20 01:26

Okay, ich frage mich gerade:
schwankt der spread (=ask-bid preis) eigentlich im Laufe der Zeit?

Weil ich überlege gerade schwer wie ich das beim Stoploss ansetze.
Meines Wissens nach ist der CHartpreis ja üblicherweise der bid preis.

sollte ich den Stoploss am bid oder ask preis besser orientieren?

ich meine, wenn sich im laufe der Zeit der spread ändern könnte, insbesondere größeren werden könnte, dann wäre ich ja bei bspw. stoploss 20 pips unter ask preis in Gefahr dass vielleicht der spread zu groß wird und ich rein dadurch ausgestoppt werden würde.

Wobei ich gerade eins nicht checke bzw. vermute:
Wonach richten sich eigentlich Stoploss und take profit, nahc welchem preis?
bspw. bei einem buy trade wäre es irgendwie nur logisch, beides nach dem bid preis zu orientieren.
geht der bid preis unter den stoploss, wird die order geschlossen.
ebenso wird geschlossen wenn der bid preis den takeprofit wert übersteigt.

Das würde dann weiter heißen das nach dem öffnen des trades eignetlich der ask price unwichtig geworden ist und, egal ob takeprofit oder stoploss, sich alles nur noch danach richtig wo der bid preis gerade ist?

das heißt, eigentlich müsste ich mich bei meinen überlegungen zur formel für takeprofit und stoploss gar nicht wirklich mit spreead befassen.

im endergebnis würde es so oder so nur bedeuten dass der endprofit (egal ob positiv oder negativ) eben noch um die 4 pips spread verringert ist.



demnach brauche ich mich eigentlich, solange ich nciht unbedingt zu einem bestimmten kurs einkaufen will, mich nicht näher mit ask preis zu beschäftigen.

ich muss das Ganze mal schwer durchdenken...

Edit:
Sehe ich folgendes recht:
wenn ich bei einem Buy Trade einfahc mal gucken will, welchen Endgewinn ich gemacht habe, bestimme ich das dann letztlich über
-bidnow-spread+bidlater=(bidlater-bidnow)-spread?
wobei bidnow eben der bid preis zum eröffnungszeitpunkt ist, bidlater beim schließungszeitpunkt und spread eben der spread?

sprich endgewinn= die bidpreisdifferenz abzüglich dem spread (vorausgesetzt, der verändert sich nicht im laufe der zeit)?


Alle Zeitangaben in WEZ +2. Es ist jetzt 05:57 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