Probleme beim Schließen, bitte helfen - Seite 5

 

Hallo Ais
Deine Antwort ist erfreulich. Zu hören, dass du mir helfen würdest, die Komplexität zu verstehen, und dann helfen würdest, die Komplexität zu reduzieren, war mehr, als ich verlangen konnte. Ich demütige mich vor deiner Großzügigkeit. Ich danke Dir.
Ich habe eine Frage zur Kommentarstruktur in Ihren Programmen. Nicht, dass ich von dem Gedankengang, der sich entwickelt hat, abkommen möchte, aber eine Frage, wie das Format aussieht, ist mir nicht vertraut.

Beispiel:

// < Struktur 17 Elemente in 4 Domains > //< >
// < 1. Daten 8 Elemente in 2 Domänen /> //< >
// < 2. Code 9 Elemente in 2 Domains /> //< >
// </Struktur 17 Elemente in 4 Bereichen > //< >
// //< >
// < 1. Daten 8 = 5 i 3 d - s > //< >
// < 1.1. Eingabe 7 = 4 i 3 d - s /> //< >
// < 1.2. Puffer 1 = 1 i - d - s /> //< >
// </1. Daten 8 = 5 i 3 d - s > //< >
// //< >

Die Kommentare sind so prägnant strukturiert. Mit Überschriften und Unterkommentaren kann ich am besten beschreiben, was ich lese. Als ob die Kommentare von einer Code-Maschine entwickelt und formatiert oder strukturiert werden? Es ist beeindruckend. Nicht, dass ich alles, was kommentiert wird, verstehe. Ihre Fähigkeit zur Organisation finde ich erfrischend.

Nochmals vielen Dank. Ich werde das Programm studieren und in naher Zukunft weitere Fragen haben.
Zum Wohl

 

Hallo Huckleberry

Schön, von Ihnen zu hören.


1. Die Struktur

Die Struktur ist von mir selbst entwickelt und formatiert.

//                                                                //<          >
// < Structure             16 elements  in      4 domains       > //<          >
// < 1. Data                7 elements  in      2 domains      /> //<          >
// < 2. Code                9 elements  in      2 domains      /> //<          >
// </Structure             16 elements  in      4 domains       > //<          >
//                                                                //<          >
     

Die erste Absicht ist, die globalen Daten und den Code strikt zu trennen.
Das Computerprogramm ist für mich ein Modell der realen Welt.
Globale Daten sind die Dinge dieser Welt.
Code ist die Menge der Aktionen.
Durch die Trennung will ich unterstreichen, dass ich den Unterschied zwischen ihnen verstehe.
Das Zählen der Elemente hilft mir, alles im Programm zu überprüfen und zu kontrollieren.


2. Die Formatierung

Die Formatierung ist ein einfaches HTML.
Der folgende Tag öffnet den Teil des Programms:

// <                                                            > //<          >
      


Der folgende Tag schließt den Teil des Programms:

// </                                                           > //<          >
      


Der folgende Tag wird für Programmteile in einer einzigen Zeile verwendet:

// <                                                           /> //<          >
      

Der abschließende Teil des Tags wird jetzt für die Seitenzählung verwendet.
In Zukunft kann die Verwendung dieses Teils der Tags erweitert werden.

                                                                  //<          >
      

Die Seitenstruktur hilft bei der einfachen Navigation durch das Programm.
Mit <Page Up> und <Page Down> sehe ich immer die gleichen Typen von Tags an den gleichen Stellen.



3. Die Elemente

Das Element der Daten ist eine einzelne globale Variable.
Ich sehe auch ein Array als einzelnes Element.
Lokale Variablen sind nur temporäre Einheiten von Code-Elementen.

Das Element des Codes ist eine einzelne Funktion.
Ich kann auch das Wort "Methode" verwenden.
Ich verwende das Wort "Schnittstelle" für eine einheitliche Gruppe von Funktionen.

Um die Komplexität zu reduzieren, teile ich Daten und Code in logische Domänen auf.
Die Anzahl der Bereiche hängt von der Programmstruktur ab.
Übliche Domänen für Daten: "input", "settings", "control", "buffer" ...
Übliche Domänen für Code: "special" für spezielle Funktionen, "interface" für andere Funktionen.
Bei großen Programmen kann ich "Objekte" mit verschiedenen "Schnittstellen" erstellen.

Zur Kontrolle der Integrität von Datenelementen und Codeelementen wird die Zählung verwendet.


//                                                                //<          >
// < 1. Data                7 =       4 i       3 d       - s   > //<          >
// < 1.1. Input             7 =       4 i       3 d       - s  /> //<          >
// < 1.2. Buffer            - =       - i       - d       - s  /> //<          >
// </1. Data                7 =       4 i       3 d       - s   > //<          >
//                                                                //<          >
// < 2. Code                9 /       - i      82 l       4 o   > //<          >
// < 2.1. Interface         6 /       - i      71 l       4 o  /> //<          >
// < 2.2. Special           3 /       - i      11 l       - o  /> //<          >
// </2. Code                9 /       - i      82 l       4 o   > //<          >
//                                                                //<          >
     

Öffnende und schließende Tags enthalten die gleichen Summen.
Normalerweise zähle ich die Summe im öffnenden Tag.
Dann kopiere ich einfach das öffnende Tag und füge es anstelle des schließenden Tags ein und füge dann den schließenden Schrägstrich "/" hinzu.

Um die Integrität der Daten zu kontrollieren, wird die folgende Notation verwendet.
Die Anzahl der Datenelemente von "integer" wird als "i" notiert.
Die Anzahl der Datenelemente von "double" wird als "d" notiert.
Die Anzahl der Datenelemente von "string" wird als "s" notiert.
Die linke Spalte enthält die Summe aus der Zeile "i" + "d" + "s".

Zur Kontrolle der Integrität des Codes wird die folgende Notation verwendet.
Die Anzahl der Funktionseingänge, d.h. die Anzahl der Funktionsargumente, wird als "i" notiert.
Die Anzahl der offenen Codezeilen wird als "l" notiert.
Die Anzahl der Funktionsausgänge wird als "o" notiert.
Immer "1" für eine einzelne Funktion, die einen beliebigen Wert zurückgibt, und "-" in allen anderen Fällen.
Die linke Spalte enthält die Anzahl der Funktionen im Bereich.


4. Die Domänen

Dies sind die Kopfzeilen der Domänen.

////////////////////////////////////////////////////////////////////<         2>
// < 1.1. Data : Input >                                          //<          >
//                                                                //<          >
// < 1.1. Input             7 =       4 i       3 d       - s   > //<          >
// <      1. Strategy       4 =       2 i       2 d       - s  /> //<          >
// <      2. Trading        3 =       2 i       1 d       - s  /> //<          >
// </1.1. Input             7 =       4 i       3 d       - s   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<         3>
// < 1.2. Data : Buffer >                                         //<          >
//                                                                //<          >
// < 1.2. Buffer            - =       - i       - d       - s   > //<          >
// </1.2. Buffer            - =       - i       - d       - s   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<         4>
// < 2.1. Code : Interface >                                      //<          >
//                                                                //<          >
// < 2.1. Interface         6 /       - i      71 l       4 o   > //<          >
// <      1. iNewBar                  - i       4 l       1 o  /> //<          >
// <      2. iSignalOpen              - i      15 l       1 o  /> //<          >
// <      3. iSignalClose             - i      15 l       1 o  /> //<          >
// <      4. iGetTicket               - i       7 l       1 o  /> //<          >
// <      5. iTryOpen                 - i      15 l       - o  /> //<          >
// <      6. iTryClose                - i      15 l       - o  /> //<          >
// </2.1. Interface         6 /       - i      71 l       4 o   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<        11>
// < 2.2. Code : Special >                                        //<          >
//                                                                //<          >
// < 2.2. Special           3 /       - i      11 l       - o   > //<          >
// <      1. init                     - i       1 l       - o  /> //<          >
// <      2. deinit                   - i       1 l       - o  /> //<          >
// <      3. start                    - i       9 l       - o  /> //<          >
// </2.2. Special           3 /       - i      11 l       - o   > //<          >
//                                                                //<          >
     


Die Regeln und Notationen für die Zählung sind dieselben wie für die Kopfzeile des Programms.
Ich kopiere einfach die öffnenden Tags der Kopfzeilen der Domains in die Kopfzeile des Programms.

Jede Seite in der Domäne hat öffnende und schließende Tags.
Zum Beispiel:

////////////////////////////////////////////////////////////////////<        12>
// < 2.2.1. Code : Special : Init >                               //<          >
..
// </2.2.1. Code : Special : Init >                               //<          >
     

Führende Nummern werden für die Zählung und Navigation der Teile der Struktur verwendet.
Dann folgt die Notation für den Programmteil "Daten" oder "Code".
Dann folgt der Name der Domäne.
Dann folgt der Name des Elements der Domäne.


Ich hoffe, dass dies hilfreich ist.

Auf Wiedersehen und ich warte auf Ihre Antwort

 

Hallo Ais
Dein Sinn für Organisation ist ......wie soll man es sagen ..... praktisch und sinnvoll.
Die Einbindung des HTML macht die Navigation einfach, auch wenn sie mir im Moment noch nicht geläufig ist.
Sehr gut!
Im Moment untersuche ich das Programm, das du mir geschickt hast, eine Anweisung nach der anderen. Die Konzepte
die Sie zu den Variablen haben, sind verständlich. Ich danke Ihnen nochmals.
Ich werde sicher mit Fragen antworten.
Auf Wiedersehen

 

Hallo Ais,,,<das wurde bearbeitet>
Das Programm ist noch nicht aufgenommen worden. Es tut mir leid,, dass es so viel von deiner Zeit in Anspruch nimmt. Es gibt einen Bereich, den ich wohl übersehen habe,
denn ich habe mit einem Fehler zu kämpfen.
Ich muss jetzt gehen, werde aber morgen wiederkommen.
Auf Wiedersehen für jetzt

 

Hallo Huckleberry
Einige Funktionen wurden zum Beispiel hinzugefügt und können leicht geändert oder entfernt werden.
Die Verbesserung des Programms ist ein ständiger Prozess.
Auf Wiedersehen für jetzt
:)

 
Ais wrote >>

Hallo Huckleberry
Einige Funktionen wurden zum Beispiel hinzugefügt und können leicht geändert oder entfernt werden.
Die Verbesserung des Programms ist ein ständiger Prozess.
Bye for now
:)


Hallo Ais
vielen Dank für alles, was Sie getan haben.
Letzte Nacht habe ich endlich meinen Fehler gefunden, als ich dein Programm kopiert habe.
Im Moment versuche ich zu verstehen, wofür einige der Variablen da sind und wie sie funktionieren würden.
In iSignalClose füge ich einen Teil meines anderen Programms ein, um den OrderClosePrice zu ermitteln. Mit
Ihrem Vorschlag:

dDelta = OrderOpenPrice () - OrderClosePrice

hat das Programm mehr Flexibilität.
Ich melde mich mit weiteren Fragen zurück. Und Kommentaren.
Zum Wohl
 

Hallo Ais
Die Fragen sind aufgetreten. In deinem Programm steht unter ..... iTryOpen ()

else if     ( iCommand       == OP_BUY )
   {          
string        sType           = "Buy"   ;   
int           iColor          =  Blue   ;               }
else         
   {          sType           = "Sell"  ;    
              iColor          =  Red    ;           

Aus meiner Neugier heraus, sollte es

else if     ( iCommand       == OP_BUY  )
   {          
string        sType           = "Buy"   ;   
int           iColor          =  Blue   ;               }
else if     ( iCommand       == OP_SELL )   // Was this ommitted     
   {          sType           = "Sell"  ;    
              iColor          =  Red    ;               }
Hier eine weitere Frage zum besseren Verständnis
// < 2.1.1. Code : Interface : iNewBar >                          //<          >
int       iNewBar ()         //       - i       4 l       1 o     //<          >
{                                                                 //<          >
static    int       iTime_0 = 0                                 ; //<          >
//                                                                //<          >
if      ( iTime_0 < iTime   ( 0 , 0 , 0 ) )                       //<          >
        { iTime_0 = iTime   ( 0 , 0 , 0 ) ;  return ( TRUE  ) ; } //<          >
else    {                                    return ( EMPTY ) ; } //<          >
//                                                  
Wenn iNewBar TRUE ist, wird die Kontrolle an iSignalOpen übergeben. Wenn iNewBar TRUE ist (gleich dem aktuellen Balken??), ODER iFirstRun ==1, dann ist iFirstBar = 0. Dies ist nur verwirrend, weil ich die iNewBar () Definition und/oder iFirstRun Definition nicht verstehe. Ich kann sehen, wo iFirstRun deklariert und initialisiert wird, aber was bedeutet das.
Es tut mir leid, dass ich Sie mit solch einfachen Fragen belaste. Ich kann nicht berechnen oder sehen, wie die beiden innerhalb der Funktion funktionieren. Wenn Sie Zeit haben, könnten Sie das bitte aufklären.
Nochmals vielen Dank für Ihre Bemühungen : )
Vielen Dank
 

Hallo Huckleberry

Beide Fragen sind wichtig!

Antwort 1.

Beide Bedingungen sind wahr, aber wenn:
1.1. wir wissen, dass

int       iCommand          = iSignalOpen ()                    ; //<          >
     

1.2. wir wissen, dass "iSignalOpen ()" nur 3 mögliche Werte zurückgeben kann: "EMPTY", "OP_BUY" und "OP_SELL";
1.3. der erste Wert ist bereits geprüft

if      ( iCommand         == EMPTY  )                return    ; //<          >
     

1.4. der zweite Wert auch geprüft wird

if      ( iCommand         == OP_BUY )                            //<          >
     

dann ist es möglich, die letzte Prüfung "if" wegzulassen, um die Berechnungen etwas zu beschleunigen.

else if     ( iCommand       == OP_SELL )                    //<          >
     


Antwort 2.

2.1. Wir erkennen, dass die Taktnummer 0 geändert wird, indem wir die Öffnungszeit von Taktnummer 0 mit der zuletzt gespeicherten Öffnungszeit von Taktnummer 0 vergleichen.
"iTime ( 0, 0, 0 )" gibt die Öffnungszeit des aktuellen unvollständigen Takts zurück.
Der Index des aktuellen Takts ist immer 0, er ist der dritte Wert in "iTime ( 0, 0, 0 )".
Die Variable "int iTime_0" als "static" zu deklarieren bedeutet, dass der Wert dieser Variable zwischen den Funktionsaufrufen gespeichert wird.
Jedes Mal, wenn die Öffnungszeit geändert wird, müssen wir:
2.1.1. "iTime_0 = iTime ( 0, 0, 0 ) ;" zuweisen, um die Öffnungszeit des aktuellen Balkens zu speichern;
2.1.2. "TRUE" zurückgeben, was bedeutet, dass der aktuelle Balken ein neuer Balken ist, der letzte Balken Nummer 0 wurde zum Balken Nummer 1.


////////////////////////////////////////////////////////////////////<         5>
// < 2.1.1. Code : Interface : iNewBar >                          //<          >
int       iNewBar ()         //       - i       4 l       1 o     //<          >
{                                                                 //<          >
static    int       iTime_0 = 0                                 ; //<          >
//                                                                //<          >
if      ( iTime_0 < iTime   ( 0 , 0 , 0 ) )                       //<          >
        { iTime_0 = iTime   ( 0 , 0 , 0 ) ;  return ( TRUE  ) ; } //<          >
else    {                                    return ( EMPTY ) ; } //<          >
}                                                                 //<          >
// </2.1.1. Code : Interface : iNewBar >                          //<          >
     

2.2. Unser Ausgangsbalken für die Berechnungen von "dHigh" und "dLow" in "iSignalOpen ()", und "dATR" in "iSignalClose ()", ist "iBaseBar=1".
Da die Taktnummer 1 die gleiche ist, sind diese Werte gleich.
Dies ist ein Grund, diese Werte nur bei neuen Takten zu berechnen.
Dies beschleunigt das Programm.
Die Variable "static int iFirstRun" ist ein einfacher Auslöser.
Der Anfangswert "1" erzwingt die Berechnung von "dHigh", "dLow" und "dATR" beim ersten Programmdurchlauf, unabhängig von einer Bedingung.
Dadurch wird die Zuverlässigkeit des Programms verbessert.

<später hinzugefügt>
Genau, beim ersten Programmlauf gibt "iNewBar ()" in "iSignalOpen ()" "TRUE" zurück, und in "iSignalClose" "EMPTY"!
Das liegt daran, dass beim ersten Aufruf von "iNewBar ()", also innerhalb des ersten Durchlaufs von "iSignalOpen ()", der Wert von "iTime_0 = 0"und beim zweiten Aufruf von "iNewBar ()", also innerhalb des ersten Durchlaufs von "iSignalClose ()", "iTime_0 = iTime ( 0, 0, 0 )"!
Als Ergebnis ohne ersten Durchlauf kann "dATR = 0" stehen.
Das ist der erste Durchlauf.
</später eingefügt>

Unmittelbar danach weisen wir "iFirstRun = 0" zu und die folgende Bedingung wird nur bei neuen Bars wahr:

if    ( ( iNewBar () == TRUE )   ||   ( iFirstRun  == 1 ) )       //<          >
     

Aber!
Die Reste des Codes von "iSignalOpen ()" und "iSignalClose ()" werden bei jedem Tick ausgeführt!
Nur Berechnungen von unveränderten Werten werden übersprungen.

////////////////////////////////////////////////////////////////////<         6>
// < 2.1.2. Code : Interface : iSignalOpen >                      //<          >
int       iSignalOpen ()     //       - i      15 l       1 o     //<          >
{                                                                 //<          >
static    int                           iFirstRun   = 1         ; //<          >
if    ( ( iNewBar () == TRUE )   ||   ( iFirstRun  == 1 ) )       //<          >
        {                               iFirstRun   = 0         ; //<          >
          int iIndexH = iHighest      ( 0 , 0    , MODE_HIGH  ,   //<          >
                                        iBaseLag , iBaseBar   ) ; //<          >
          int iIndexL = iLowest       ( 0 , 0    , MODE_LOW   ,   //<          >
                                        iBaseLag , iBaseBar   ) ; //<          >
          static double dHigh ; dHigh = High     [ iIndexH    ] ; //<          >
          static double dLow  ; dLow  = Low      [ iIndexL    ] ; //<          >
        } // if                                                   //<          >
//                                                                //<          >
double    dAsk    = MarketInfo        ( Symbol () , MODE_ASK  ) ; //<          >
if      ( dAsk    > dHigh )             return    ( OP_BUY    ) ; //<          >
//                                                                //<          >
double    dBid    = MarketInfo        ( Symbol () , MODE_BID  ) ; //<          >
if      ( dBid    < dLow  )             return    ( OP_SELL   ) ; //<          >
//                                                                //<          >
                                        return    ( EMPTY     ) ; //<          >
}                                                                 //<          >
// </2.1.2. Code : Interface : iSignalOpen >                      //<          >
     


Ich hoffe, das kann helfen.
Danke!
:)

P.S. Einige Bemerkungen wurden später hinzugefügt.
Und wenn man sich diese Bemerkungen ansieht, ist es offensichtlich, dass "iNewBar ()" korrigiert werden muss.
Das liegt daran, dass diese Funktion zweimal aufgerufen wird, um ein einzelnes Ereignis zu prüfen.
Jetzt gibt "iNewBar ()" für dasselbe Ereignis beim ersten Aufruf den richtigen Wert zurück, und beim zweiten den falschen.
Wird korrigiert.



 

Hallo Ais
Danke für die Klarstellung. Ich werde mich noch weiter einlesen. Ich habe den Code noch nicht vollständig im Griff.
Aber Sie erwähnten, dass es etwas gab, das in Bezug auf die iNewBar? korrigiert werden musste? Ich bin mir nicht sicher, ob der iNewBar für das Problem verantwortlich ist, was der Backtest gezeigt hat. Möglicherweise zwei Probleme?
Das habe ich gesehen, als ich den Chart nach einem Backtest geöffnet habe. Wir wissen, dass es einen Buy-Eintrag gibt, wenn der Ask über dem höchsten Hoch der letzten zwanzig Bars liegt. Der Verkauf ist genau das Gegenteil. Dennoch sind die Einträge nicht konsistent. Ist das der Bereich, den Sie gesehen haben?
Ich habe noch eine Sache gefunden. Der Hard Stop wird mit Atr*2 berechnet. Das ist korrekt, aber ich sehe nicht, wo das berechnet wird. Aber das eigentliche Problem ist, dass der TakeProfit die gleiche Atr*2-Berechnung hat. Wenn ich wüsste, wo der Hard Stop berechnet wird, könnte ich möglicherweise den TakeProfit korrigieren. TakeProfit sollte in diesem Fall nur Atr*1 sein.
Passen Sie auf sich auf und ich werde morgen wiederkommen.
Prost

 

Hallo Huckleberry

TakeProfit Bedingung wurde von mir selbst zu Testzwecken erfunden.
Jetzt ist sie geändert.
Statt "Atr*2" und "Atr*1" verwende ich "dATR * dFactorTP" und "dATR * dFactorSL".
Die Ausgangswerte "dFactorTP = 1.0" und "dFactorSL = 2.0" sind auf der Seite 2 "Daten : Input".
Eine solche Lösung erlaubt es, diese Werte leicht zu optimieren.

Ich habe die Funktionen "iSignalOpen ()" und "iSignalClose ()" geändert.
Die Prüfung auf einen neuen Balken ist jetzt in diesen Funktionen implementiert.
Die Bedingungen für "Buy" und "Sell" in "iSignalOpen ()" scheinen wahrscheinlich korrekt zu sein.

Das komplette Programm ist in der angehängten Datei auf der nächsten Seite.

Prost

Grund der Beschwerde: