Probleme beim Schließen, bitte helfen - Seite 8

 
Ais:

Hallo Cameofx,
Danke für die freundliche Antwort.
Dieses Kodierungssystem ist sehr einfach und leicht.
Alles wird manuell in MetaEditor gemacht.
In der Tat wird das System entworfen, um große Programme leicht und mit hoher Geschwindigkeit zu entwickeln.
Das System sollte auch flexibel und zuverlässig sein.
Beste Grüße!

Ais, vielen Dank für Ihre Antwort. Ich habe viel aus Ihren Beiträgen gelernt :)

Kameo

 

Hallo Freunde!

Eine Sache aus der Vergangenheit belastet mich Tag für Tag.
Dies ist die Dokumentation zu AIS5 Trade Machine.
Ich werde zurückkommen, sobald Gott es will.

Bye for now!

 

Hallo Ais
Deine Abwesenheit wird schmerzlich vermisst werden. Pass auf dich auf.
Wir begrüßen deine Rückkehr.
Dein Freund, Prost

 

Hallo Ais
Nach Ihrer Rückkehr tut es mir leid, Sie sofort mit weiteren Fragen zu belasten. Es liegt nicht an Deinem System im Besonderen, ich habe dieses Problem mit fast allen Programmen. Es hat mit benutzerdefinierten Funktionen zu tun. Wie kommt die benutzerdefinierte Funktion zu ihrer Definition.
Zum Beispiel:

int       iSignalOpen ()     //       - i      17 l       1 o     //< This is what iSignalOpen function will do.....
{                                                                 //< When the chart is opened, first pass..
if    ( ( iTradeBarTime    == iTime   ( 0 , 0 , 0 ) )   //< false input, EMPTY == (0,0,0)------|
      &&         //                                         &&                                 |--(return)EMPTY
      ( iTradeBarOnce    == 1 ))                        //< true  input, 1 == 1 ---------------|
      return ( EMPTY);
      
// This proves, 'EMPTY' will always be returned when the chart first opens. At the next tick...       
// ... 'iTime' will have parameters, example: (EUR/USD,HOUR_1,1) it is a predefined function so that...
// ... these parameters will be collected so that an expression can be calculated. Where as the... 
// ... 'iTradeBarTime' is not predefined. 'iTradeBarTime' was assigned 'EMPTY' at declaration earlier in the program.
// 'iTradeBarTime' knows that it is 'EMPTY'and nothing else. 
// When and how did 'iTradeBarTime' get deifined to collect data so that it's value can be other than 'EMPTY'? 
// The 'iTradeBarTime' has to have the same values as the 'iTime', or the input will never be 'true'?
// If it is never 'true', the return is always 'EMPTY'? 
Ich kann weder im Buch noch im Forum eine eindeutige Antwort finden. In einem Schaltplan für eine Relaislogik würde ein UND-Gatter genauso funktionieren wie das obige Beispiel. Nur wenn es zwei "wahre" Eingänge gibt, gibt es auch einen "wahren" Ausgang. Erst dann wird die Steuerung fortgesetzt.
Ich warte auf Ihre Antwort. Ich danke Ihnen im Voraus.
Vielen Dank
 

Hallo Huckleberry

Lassen Sie uns diesen Teil des Codes klären.

1. Wahrscheinlich die größten Schwierigkeiten:
1.1. alle Menschen denken und handeln unterschiedlich;
1.2. Ich möchte eine streng begrenzte Anzahl von Datentypen verwenden;
1.3. Ich verwende gerne nur "Standard"-Datentypen:
1.3.1. "int",
1.3.2. "double",
1.3.3. "string";
1.4. Ich verwende andere Datentypen nur in besonderen Fällen;
1.5. Ich bezeichne den Typ meiner Programmelemente durch einen kleinen Buchstaben an der ersten Stelle des Namens:
1.5.1. "i" für den Datentyp "int",
1.5.2. "d" für den Datentyp "double",
1.5.3. "s" für den Datentyp "string",
1.5.4. "r" für den Datentyp "undefined";
1.6. diese Programmiertechnik hilft mir, das Type Casting zu kontrollieren;
1.7. vordefinierte Funktionen und Konstanten können auch folgende Datentypen haben:
1.7.1. "bool",
1.7.2. "color",
1.7.3. "datetime";
1.8. Ich versuche immer, diese Typen in den Typ "int" umzuwandeln;
1.9. heute ist mein Daten-Casting in der Regel implizit;
1.10. einige wesentliche Merkmale meiner Programmiertechniken:
1.10.1. Ich benutze gerne das Konstantenpaar "TRUE" und "EMPTY" anstelle des Konstantenpaares "TRUE" und "FALSE";
1.10.2. In "if"-Anweisungen habe ich manchmal "1" und "0" anstelle von "TRUE" und "FALSE" verwendet;
1.10.3. Ich habe die Konstante "EMPTY" mit dem negativen Wert "-1" verwendet, um ungültige Ergebnisse für Datenelemente ohne Vorzeichen zu kennzeichnen;
1.10.4. in Zukunft werde ich den Typ "bool" mit dem Präfix "b" in Namen verwenden.

2. Wir müssen die folgenden MQL4-Datentypen kennen:
2.1. "int" ist eine <!>vorzeichenbehaftete</!> lange 4-Byte-Ganzzahl mit Werten von -2147483648 bis 2147483647;
2.2. "datetime" ist eine <!>unsigned</!> long 4-byte integer number mit Werten von 0 bis 4294967295;
2.3. Wenn wir "datetime"-Werte den "int"-Variablen zuweisen, erhalten wir korrekte Ergebnisse bis ungefähr 2038.01.01.

3. Über die Funktion "iTime ( symbol, timeframe, shift )" müssen wir folgendes wissen:
3.1. diese Funktion gibt immer einen Wert vom Typ "datetime" zurück;
3.2. es gibt 2 verschiedene Fälle der Rückgabe:
3.2.1. "0", wenn die lokale Historie leer ist;
3.2.2. offene Zeit für den mit "shift" angegebenen Balken in allen anderen Fällen;
3.3. "iTime ( 0, 0, 0 )" gibt die Öffnungszeit für den Null-Balken des aktuellen Charts zurück;
3.4. wenn der Null-Balken derselbe ist, gibt "iTime ( 0, 0, 0 )" denselben Wert zurück;
3.5. Wenn der aktuelle Nullbalken abgeschlossen ist, wird dieser Balken zum Balken Nummer 1 und die Bildung eines neuen Nullbalkens beginnt;
3.6. "iTime ( 0, 0, 0 )" gibt den neuen Wert zurück;
3.7. Der Wert von "iTime ( 0, 0, 0 )" ändert sich also, wenn sich der Nullbalken ändert.

4. Wir haben die Arbeit mit der leeren Historie im Programmblock "2.2.3.1. Überprüfung der Verlaufsdaten".

5. Wenn der Auftrag in der Funktion "iTryClose" erfolgreich geschlossen wird, weisen wir "iTradeBarTime = iTime ( 0, 0, 0 ) ;" zu.

6. In der Funktion "iSignalOpen" prüfen wir, ob "iTradeBarTime == iTime ( 0, 0, 0 ) )".

7. Wenn es wahr ist und der wiederholte Handel durch "iTradeBarOnce = 1 ;" verboten ist, dann verbieten wir das Öffnen des Signals durch den Wert "EMPTY".

Prost

 

Hallo Ais
vielen Dank für deine Antwort. Ich werde mich damit befassen und mich bald wieder melden.
Auf Wiedersehen

 

Hallo Ais,
Entschuldigung für meine langsame Antwort. Ich habe am Montag wieder angefangen, in meinem normalen Beruf zu arbeiten. Die Zeit ist in diesen Tagen etwas kürzer. Die Studienzeit ist kürzer.
Wie ich schon früher in diesem Thread erwähnt hatte, mag ich es, die Dinge auf das Wesentliche herunterzubrechen. Wie liefert ein Ritzel dem anderen Kraft und so weiter. Ich habe festgestellt, dass die Kontrolle innerhalb des Programms faszinierend ist. Bitte haben Sie Verständnis dafür, dass ich Ihnen allen gebührenden Respekt für Ihre Geduld und Ihr Wissen zolle, aber ich habe Fragen dazu, warum der Block 2.2.3.1 notwendig ist.
Wie kann der iBaseLag + iBaseBar ein Ausdruck sein?
Ich habe verstanden, dass iBaseLag und iBaseBar innerhalb der Parameter für iHighest und iLowest liegen. Es sei denn, es sind explizite Zahlen,
iBaseLag ist 20, was für 20 Balken steht, die für die Berechnung des Durchschnitts verwendet werden.
iBaseBar gibt an, bei welchem Takt die Durchschnittsbildung beginnen soll. Bar 1 bis 20, in diesem Fall wird Bar Null nicht berücksichtigt.
Ich habe mir die Freiheit genommen, das Programm um /* 2.2.3.1*/ zu kürzen. Ich habe das Programm getestet und bin zu den gleichen Ergebnissen gekommen. Wenn das Programm unter realen Handelsbedingungen ausgeführt wird, ist dies möglicherweise keine gute Idee.
Was ist Ihre Meinung dazu?
Auch Ihre Erklärung zu Block 2.1.2 hat meine Verwirrung geklärt. Die iTime gibt die Eröffnungszeit des Nullbalkens zurück.
iTradeBarTime ist ebenfalls ein Typ cast datetime. Das Programm weiß, bei welchem Takt der Handel stattgefunden hat, daher nur ein Handel pro Takt. . . iTradeBarOnce == 1
Dankeschön
Ich werde in den nächsten Tagen mehr studieren. Aber kann der reservered Block 2.1.1 für eine Funktion verwendet werden, die zusätzliche Positionen zu bestehenden Positionen liefern würde. Beispiel: eine bestehende Long-Position, dann drei oder mehr Long-Positionen hinzufügen?
Würde es mit den Funktionen, die bereits im Programm vorhanden sind, zu Konflikten mit zusätzlichen Positionen kommen?
Nochmals vielen Dank für alles. Bleiben Sie gesund
Prost

 

Hallo Huckleberry,

Schauen wir uns den Hauptteil des Programms, einschließlich des Blocks 2.2.3.1. genau an:

////////////////////////////////////////////////////////////////////<        14>
// < 2.2.3. Code : Special : Start >                              //<          >
int       start   ()         //       - i       9 l       - o     //<          >
{                                                                 //<          >
// < 2.2.3.1. History data inspection 4 >`````````````````````````//<          >
static    int       iTrigger   = 0       ; if ( iTrigger == 0 ) { //<          >
  if  ( ( iTime ( 0 , 0 , 0 ) == 0                          )     //<          >
  ||    ( iBars ( 0 , 0     )  < iBaseLag     + iBaseBar    ) )   //<          >
          return                         ; else iTrigger  = 1 ; } //<          >
// </2.2.3.1. History data inspection 4 >`````````````````````````//<          >
//                                                                //<          >
// < 2.2.3.2. Main routine 3 >````````````````````````````````````//<          >
int       iTicket           = iGetTicket ()                     ; //<          >
//                                                                //<          >
if      ( iTicket < 0 )       iTryOpen   ()                     ; //<          >
else                          iTryClose  ()                     ; //<          >
// </2.2.3.2. Main routine 3 >````````````````````````````````````//<          >
//                                                                //<          >
// < 2.2.3.3. Exception handler 2 >```````````````````````````````//<          >
int       iTrap   =           GetLastError ()                   ; //<          >
if      ( iTrap   > 0 )       Alert  ( "Exception " , iTrap   ) ; //<          >
// </2.2.3.3. Exception handler 2 >```````````````````````````````//<          >
}                                                                 //<          >
// </2.2.3. Code : Special : Start >                              //<          >
////////////////////////////////////////////////////////////////////<         0>

Dieser Code funktioniert auf folgende Weise:

1. der Block 2.2.3.1., der allererste Block des Programms, ist ein einfacher Trigger:
1.1. "static int iTrigger" speichert den eigenen Wert während der gesamten Lebensdauer des Programms, also "static";
1.2. anfänglich "iTrigger == 0";
1.3. die Anweisung "if ( iTrigger == 0 )" wird bei jedem Tick ausgeführt;
1.4. beim ersten Mal, wenn "iTrigger == 0", wird die Überprüfung der historischen Daten innerhalb des Blocks {..} ausgeführt;
1.5. wenn die historischen Daten falsch sind, wird die Anweisung "return;" ausgeführt;
1.6. das bedeutet, dass die Ausführung der Hauptfunktion "start ()" beendet wurde;
1.7. beim nächsten Tick wird die Anweisung "if ( iTrigger == 0 )" erneut ausgeführt;
1.8. wenn die historischen Daten korrekt sind, wird die Anweisung "iTrigger = 1 ;" ausgeführt;
1.9. dann wird die Ausführung der Hauptfunktion "start ()" fortgesetzt;
1.10. beim nächsten Tick wird die Anweisung "if ( iTrigger == 0 )" erneut ausgeführt;
1.11. der Wert von "iTrigger" wird jetzt und in Zukunft immer "== 1" sein, da er statisch ist;
1.12. daher wird in Zukunft die Überprüfung der historischen Daten immer übersprungen;
1.13. das ist der einfache Trigger;

2. die Überprüfung der Verlaufsdaten besteht aus zwei Teilen:
2.1. prüfen, ob der lokale Verlauf leer ist "iTime ( 0, 0, 0 ) == 0";
2.2. prüfen, ob die Größe des lokalen Verlaufs für die Berechnung von "iATR ( 0, 0, iBaseLag, iBaseBar )" ausreicht, wobei:
2.2.1. "iBaseBar" ist der Startbalken für "iATR";
2.2.2. "iBaseLag" ist die Anzahl der Mittelungsbalken für "iATR";
2.2.3. "iBaseLag + iBaseBar" ist ein üblicher Ausdruck, das Ergebnis ist immer die Summe von "iBaseLag" und "iBaseBar";
2.2.4. mit anderen Worten, der Ausdruck "iBaseLag + iBaseBar" entspricht der Summe von "iBaseLag" und "iBaseBar";
2.2.5. Wir können in der Programmeingabe in Satz 1.1.1. beliebige Werte für "iBaseLag" und "iBaseBar" zuweisen;
2.2.6. lassen wir "iBaseLag = 100 ;" und "iBaseBar = 7 ;" zuweisen;
2.2.7. dann ist eine korrekte Berechnung von "iATR ( 0, 0, iBaseLag, iBaseBar )" möglich, wenn die Größe der lokalen Historie gleich 107 oder größer ist, weil die letzte Taktnummer für die Berechnung
#106ist und die Taktnummer Null immer berücksichtigt wird.

Es ist möglich, eine beliebige Anzahl von Funktionen in jedes Programm einzufügen, Block 2.1.1 zeigt nur ein Beispiel für eine mögliche Implementierung.
Die Bereitstellung zusätzlicher Positionen erfordert einen wesentlich komplexeren Code für die Positionsanalyse und -verwaltung als die Funktion 2.1.4.
Aber alles ist möglich.

Prost

 

Hallo Ais
Vielen Dank für Ihre schnelle Antwort. Ich kann vieles von dem, was Sie sagen, nachvollziehen. Vor allem über die iATR-Funktion. Sie sagen, dass die Verwendung des Ausdrucks iBaseLag + iBasebar an und für sich ein zulässiger Teil der Formel ist. Ich hatte den Eindruck, dass sie in den Parametern einer definierten Funktion enthalten sein müssen, oder sie sind nicht erlaubt. Dies dient dazu, die Größe des lokalen Verlaufs zu überprüfen, ob tatsächlich genügend Balken vorhanden sind, um fortzufahren. Ist es das, worauf Sie hinauswollen? So viele weitere Schritte, aber notwendige Schritte, um das Ziel zu erreichen. Schritte, die man übersehen oder als selbstverständlich ansehen würde.
Über den Rest werde ich noch nachdenken. Ich danke Ihnen für Ihre Zeit.
Zum Wohl

 

Hallo Huckleberry
MQL4 ist eine sehr freundliche Umgebung, insbesondere im Vergleich zu z.B. C oder Assemblern.
Die Anforderungen an diverse Prüfungen und andere Tricks sind deutlich reduziert.
Aber Implementierungen von maximal möglichen Checks in die Entwicklungsumgebung reduzieren immer die Leistung.
In jedem Fall ist der Programmierer immer für das schlechte Verhalten des Programms verantwortlich.
Daher ist für mich eine redundante Nachprüfung besser als z.B. eine elementare Verfälschung von Grenzen.
Prost