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.


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