Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools
Zurück   Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools > Metatrader 4 > Programmierung MQL4

Programmierung MQL4 Hier gehts rund ums Programmieren in MQL4.

Login
Benutzername:
Kennwort:


Statistik
Themen: 4483
Beiträge: 40714
Benutzer: 6.866
Aktive Benutzer: 251
Links: 80
Wir begrüßen unseren neuesten Benutzer: hk0163
Mit 2.475 Benutzern waren die meisten Benutzer gleichzeitig online (16.01.20 um 22:38).
Neue Benutzer:
vor einem Tag
- hk0163
vor 2 Tagen
- magnr1
vor 2 Tagen
- boypac007
vor 3 Tagen
- Anja
vor 5 Tagen
- ThaScorp

Onlineuser
'Wer ist online' anzeigen Benutzer: 1
Gäste: 74
Gesamt: 75
Team: 0
Team:  
Benutzer:  traderdoc
Freunde anzeigen

Empfehlungen

Antwort
 
Themen-Optionen Thema durchsuchen Ansicht
  #1 (permalink)  
Alt vor 4 Wochen
LQK LQK ist offline
Mitglied
 
Registriert seit: Nov 2019
Beiträge: 54
LQK befindet sich auf einem aufstrebenden Ast
Standard New Tick-Event künstlich erzeugen zwecks Debugging?

Hallo,

ich habe meinen ersten kleinen EA fertiggestellt. Seine Funktion:

Öffne jeden Tag beim ersten Tick der nach 9 Uhr eintritt einen Trade. Wenn an diesem Tag bereits ein Trade geöffnet wurde, kann an diesem Tag kein weiterer Trade geöffnet werden. Ein Trade darf Overnight offen bleiben, d.h. es kann dennoch der Fall eintreten, dass mehrere Trades gleichzeitig geöffnet sind.

Wollte jetzt in MT einen kleinen Backtest machen. Der Backtest endet aber nach längerer Rechenzeit nicht, auch wenn ich nur ganz kurze Zeitfenster (z.B. drei Tage) als Grundlage für den Backtest nehme.

Ich muss also debuggen. Beim kompilieren gab es keine offensichtlichen Fehlermeldungen. Wollte daher mit Hilfe von Print() schrittweise die einzellnen Abschnitte des Quellcodes testen, ob die Ihre Arbeit ordnungsgemäß machen.

Wollte jetzt erstmal testen, ob der EA um 9 Uhr ordnungsgemäß eine action durchführt, wenn noch kein Trade offen ist (eben mit der Print-Funktion). Die Uhrzeit kann ich testen, indem ich halt die Systemzeit auf 8:59 umstelle (die Abfrage der Uhrzeit erfolgt bei meine EA mit TimeHour(LocalTime()) oder halt indem ich die aktuelle Stunde zum testen als Wert in den Code eintrage.

Dummerweise gibt es neben der Uhrzeit noch eine zweite Bedingung, die zum Öffnen eines Trades erforderlich ist: Es muss ein Tick auftreten (weil sonst ja die Funktion OnTick() nicht abläuft.

Aus verschiedenen Gründen habe ich derzeit kein Konto, dass ich verwenden kann. bzw. verwenden will, um den EA mit Ticks zu füttern. Überdies wäre es mitunter vielleicht auch lästig, auf den nächsten Tick warten zu müssen.

---

Ich habe mich daher gefragt, ob ich irgendwie einen Tick "künstlich" erzeugen und den EA damit füttern kann? Dem EA (oder Teilen des EA) gewissermaßen vorgaukeln, dass ein neuer Tick aufgetreten wäre. Also ein Ereignis New Tick auf Knopfdruck oder mit ein bisw zwei Codezeilen erzeugen und den EA oder Teile des EA damit füttern.

Gibt es da eine Möglichkeit? Oder wie ist einem solchen Fall, wenn man Ticks für das Debugging braucht, die "kanonische" Vorgehensweise?


Ich freue mich über jeden konstruktiven Hinweis!

Besten Dank und Grüße,
LQK
Mit Zitat antworten
  #2 (permalink)  
Alt vor 4 Wochen
Elite Mitglied
 
Registriert seit: Sep 2015
Beiträge: 950
MA-EA befindet sich auf einem aufstrebenden Ast
Standard

Code:
int start()
Mit Zitat antworten
  #3 (permalink)  
Alt vor 4 Wochen
Mitglied
 
Registriert seit: Jun 2013
Beiträge: 295
Ca$hDigger befindet sich auf einem aufstrebenden Ast
Standard

Stecke einfach eine Endlosschleife in zB ein Skript, dieses kann immer ausgeführt werden

Code:
while(1)
{
   Sleep(1000); // Trigger jede Sekunde

   // hier der zu triggernde code

}
Mit Zitat antworten
  #4 (permalink)  
Alt vor 4 Wochen
LQK LQK ist offline
Mitglied
 
Registriert seit: Nov 2019
Beiträge: 54
LQK befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von MA-EA Beitrag anzeigen
Code:
int start()
Ich verstehe nicht, was man mit dieser Funktion machen kann. Könntest Du ein oder zwei Sätze dazu verlieren?

---

Ich habe die Funktion Start() nicht in der Reference gefunden. Ist diese Funktion überhaupt noch Bestantdteil des aktuellen Release von MQL?

Habe auch im Web nicht viel zu Start() gefunden, was ich gefunden habe:

https://www.mql5.com/en/forum/172489

Die beiden in o.g. Link zitierten Code-Schnipsel sind:

Code:
int  OnInit(void) { return(INIT_SUCCEEDED); }
void OnDeinit(const int reason) {}
void OnTick() 
{
   Comment("I am here "+TimeToString(TimeLocal(),TIME_SECONDS));
}

und


Code:
int init(void) { return(INIT_SUCCEEDED); }
int deinit() { return(0); }
void start() 
{
   Comment("I am here "+TimeToString(TimeLocal(),TIME_SECONDS));
}

Beide Syntax-Schnipsel führen bei mir zu keiner Bildschirmausgabe und ich erkenne auch nicht, dass diese einer für mich sichtbaren Tätigkeit nachgehen (nach Kompilieren und Ausführen tun diese anscheinend "nichts").

Da ich mir nicht sicher bin, was die Funktion Comment() macht, habe ich diese durch Print(Test); ersetzt, was aber auch nichts geändert hat.

Grüße,
LQK
Mit Zitat antworten
  #5 (permalink)  
Alt vor 4 Wochen
LQK LQK ist offline
Mitglied
 
Registriert seit: Nov 2019
Beiträge: 54
LQK befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Ca$hDigger Beitrag anzeigen
Stecke einfach eine Endlosschleife in zB ein Skript, dieses kann immer ausgeführt werden

Code:
while(1)
{
   Sleep(1000); // Trigger jede Sekunde

   // hier der zu triggernde code

}

Danke für diesen Codeschnipsel. Die Programmieridee dahinter ist mir noch nicht ganz klar geworden. Die Endlos-Schleife führt dazu, dass der Schleifenrumpf immer und immer wieder ausgeführt wird, klar.

Aber warum sollte daraus ein Ereignis New Tick entstehen?


---

Habe jetzt mal die von Dir vorgeschlagene Endlos-Schleife getestet. Bislang noch nicht zum echten Debuggen, sondern nur probeweise.

Bislang ist es mir offenbar noch nicht gelungen, die Schleife zum Laufen zu bringen. Hab zuerst eine Funktion Test() welche mit Print(TimeLocal()) die aktuelle Uhrzeit ausgeben soll in den Schleifenrumpf geschrieben und dann von OnInit() aus die Funktion Test() aufgerufen.

Das hat nicht funktioniert, und nach einigem Ausprobieren, ist mir auch der Grund klargeworden, warum es nicht funktioniert: Wenn ich Test() von OnInit() aus aufrufe, wird deswegen ja noch lange nicht die While-Schleife aufgerufen.

Das hat mich auf die Idee gebraucht, dass ich eine Art Rahmenfunktion() brauche, welche die While-Schleife umschließt. Test() bzw. die Funktion die iteriert werden soll, sollte dann im Schleifenrumpf der While-Schleife stehen.

Habe das so umgesetzt und es ergibt sich der unten stehende Code.
Passiert ist aber nach Kompilieren und Ausführen dieses Codes tatsächlich gar nichts. Es wurde keine Uhrzeit ausgegeben, aber auch keine Fehlermeldung.

Hier der Code:

Code:
void OnInit() 
   {
   
     rahmenfunktion()
   
   }


void rahmenfunktion() 
   {
  
      while(1)
         {
            Sleep(1000); // Trigger jede Sekunde
            
            void test() 
               {
                  Print(TimeLocal());
               }
         }            
   }

Um sicherzugehen habe ich dann noch Print(TimeLocal()); durch Print("Test"); ersetzt. Den sich daraus ergebenden Code poste ich unten stehend, Änderung rot markiert. Allerdings hat die Änderung nichts bewirkt, weder kommt eine Fehlermeldung, noch eine Ausgabe.

Hier der Code:
Code:

void OnInit() 
   {
   
     rahmenfunktion()
   
   }


void rahmenfunktion() 
   {
  
      while(1)
         {
            Sleep(1000); // Trigger jede Sekunde
            
            void test() 
               {
                  Print("TEST");
               }
         }            
   }

Es ist mir somit letzten Endes nicht klar, was ich falsch mache. Habe ich die Idee mit der Schleife konzeptionell falsch umgesetzt, z.B. dasss die Idee mit der rahmenfunktion() nichts taugt, oder etwas in der Art?

Oder ist meine Idee der konzeptionellen Umsetzung richtig, und ich habe nur irgendwo Programmierfehler gemacht?

---

Würde mich über einen Hinweis freuen!


Beste Grüße,
LQK
Mit Zitat antworten
  #6 (permalink)  
Alt vor 4 Wochen
Mitglied
 
Registriert seit: Jun 2013
Beiträge: 295
Ca$hDigger befindet sich auf einem aufstrebenden Ast
Standard

Wenn ich es richtig verstanden habe willst du einfach nur Code triggern unabhängig von Kursdaten etc. Die whileschleife als Endlosschleife sollte funktionieren, die kann man direkt in OnInit() (EA) bzw OnStart() (Skript) einfügen.

EA:
Code:
int z=0;
int OnInit()
  {
      while(1)
         {
            Sleep(1000); // Trigger jede Sekunde
            Print("TEST: ",  ++z);
         }     
   return(INIT_SUCCEEDED);
  }
SKRIPT:
Code:
int z=0;
void OnStart()
  {
      while(1)
         {
            Sleep(1000); // Trigger jede Sekunde
            Print("TEST: ",  ++z);
         }     
  }
Eine Endlos-Whileschleife funktioniert zwar, ist aber natürlich nicht besonders toller Programmierstil da beim Deinitialisieren eine "abnormal termination" auftreten kann.
Die sauberte Lösung wäre daher einen EventTimer zum künstlichen Triggern zu nutzen (dies geht nicht bei Skripten, nur EA und Indis)

Code:
int z=0;
int OnInit()
  {
   EventSetTimer(1);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTimer()
  {
     Print("TEST: ",  ++z);
  }
Alle gezeigten Beispiele funktionieren. Das bei dir die Dinge zum Teil nicht laufen, liegt vielleicht daran, dass du entweder nicht korrekt in ein Konto eingeloggt bist bzw die Märkte nicht offen haben. Dein OnInit() beim EA wird ggf deshalb nie aufgerufen. Jedes beliebige Demokonto würde da Abhilfe schaffen
Mit Zitat antworten
  #7 (permalink)  
Alt vor 4 Wochen
Elite Mitglied
 
Registriert seit: Sep 2015
Beiträge: 950
MA-EA befindet sich auf einem aufstrebenden Ast
Standard

init wird ausgeführt, wenn der EA in den Chart des jeweiligen Symbol gepackt wird. Wenn dabei was Spezielles passieren soll, muss der entsprechende Code auch zwischen den { } von init stehen, und nicht irgendwo ausserhalb.

z.B.
Code:
int init(){


   ChartSetSymbolPeriod(0,Symbol(),TimeFrame);


   return(NULL);}
Mit int start(){ nach init() / deinit() und return;} am Ende des EA wartet er nicht auf neue Ticks, sondern müsste sofort tun, was er soll.
Code:
int start(){ ( nicht OnTick() )

 ...

return(NULL);}
Mit Zitat antworten
  #8 (permalink)  
Alt vor 4 Wochen
LQK LQK ist offline
Mitglied
 
Registriert seit: Nov 2019
Beiträge: 54
LQK befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von Ca$hDigger Beitrag anzeigen
Alle gezeigten Beispiele funktionieren. Das bei dir die Dinge zum Teil nicht laufen, liegt vielleicht daran, dass du entweder nicht korrekt in ein Konto eingeloggt bist bzw die Märkte nicht offen haben. Dein OnInit() beim EA wird ggf deshalb nie aufgerufen. Jedes beliebige Demokonto würde da Abhilfe schaffen
Ja, genau das war ja meine Frage im EP. Ich will irgendwie triggern, d.h. ein Ereignis New Tick auslösen, ohne dass ich dafür in irgendeinem Konto eingeloggt bin.

Geht das mit EventSetTimer() auch nicht? Habe gerade das dritte von Dir gepostete Code-Beispiel probiert, ohne Konto-Login geht das auch nicht. (Mit Konto-Login habe ich es noch nicht probiert.)


Heißt das, diese Anforderung ist unlösbar, ich kann ohne in ein Konto eingeloggt zu sein grundsätzlich kein Ereignis New Tick auslösen?

Wenn das so ist, wäre es bedauerlich, andererseits ist es dann gut für mich, Bescheid zu wissen, dann brauche ich nicht mehr nach einer Lösung zu suchen, die es nicht gibt.

Oder gibt es doch eine Möglichkeit?



Besten Dank und Grüße
LQK
Mit Zitat antworten
  #9 (permalink)  
Alt vor 4 Wochen
Mitglied
 
Registriert seit: Jun 2013
Beiträge: 295
Ca$hDigger befindet sich auf einem aufstrebenden Ast
Standard

Probiere es doch mal mit einem Skript (siehe mein Beispiel 2 "SKRIPT:") statt mit einem EA. Ein Skript sollte auch offline funktionieren (zumindest ging das vor Jahren bei mir in MT4)
Mit Zitat antworten
  #10 (permalink)  
Alt vor 4 Wochen
Elite Mitglied
 
Registriert seit: Sep 2015
Beiträge: 950
MA-EA befindet sich auf einem aufstrebenden Ast
Standard

Wenn ich das Alles richtig verstehe, dann soll ein mal täglich eine einzige Order geöffnet werden. Und zwar ab 9 Uhr.
Code:
bool TagesOrderGeöffnet = false;

if( Hour >= 9 || Hour<= 8 ) {

for ( i=OrdersTotal ... eben feststellen, ob ne Order offen ist ... )

if ( ...ja... ) TagesOrderGeöffnet = true ;

if ( ...nein... ) Ticket = OrderSend... eben die Order senden ... )

if ( ...Ticket... Ticket zurück liefert... ) TagesOrderGeöffnet = true ;
Vom Prinzip her müsste das ungefähr klappen.
Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus




Alle Zeitangaben in WEZ +2. Es ist jetzt 10:59 Uhr.





Die Suchmaschine - Der Wavesnode - Facebook Forum - Spam Firewall
-----------------------------------------------------------------------------------------------------------------------------
Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Powered by vBCMS® 2.7.0 ©2002 - 2020 vbdesigns.de
SEO by vBSEO 3.6.1
Copyright ©2009 - 2020 by Expert-Advisor.com - Das Metatrader Forum
MetaTrader bzw. MetaTrader 4 und MetaTrader 5 sind eingetragene Marken der MetaQuotes Software Corp.
-----------------------------------------------------------------------------------------------------------------------------