Problèmes de fermeture, aidez-nous - page 5

 

Bonjour Ais
Votre réponse me fait plaisir. Entendre que vous m'aideriez à comprendre la complexité, puis à la réduire, était plus que je ne pouvais demander. Je m'humilie devant votre générosité. Je vous remercie.
J'ai une question concernant la structure des commentaires dans vos programmes. Non pas que je veuille m'écarter du train de pensée qui a progressé, mais une question sur la façon dont le format se présente ne m'est pas familière.

Exemple :

// < Structure 17 éléments dans 4 domaines > //< >.
// < 1. Données 8 éléments dans 2 domaines //> //< >
// < 2. Code 9 éléments dans 2 domaines //< > //< >
// </Structure 17 éléments dans 4 domaines > //< >
// //< >
// < 1. Données 8 = 5 i 3 d - s > //< >
// < 1.1. Données 7 = 4 i 3 d - s /> //< >
// < 1.2. Tampon 1 = 1 i - d - s /> //< >.
// </1. Données 8 = 5 i 3 d - s > //< >
// //< >

Les commentaires sont structurés de façon si percussive. Avec des titres et des sous commentaires, ce serait la meilleure façon pour moi de décrire ce que je lis. Comme si les commentaires étaient élaborés et mis en forme ou structurés par une machine à code ? C'est impressionnant. Non pas que je comprenne tout ce qui est commenté. Je trouve votre capacité d'organisation rafraîchissante.

Je vous remercie encore. Je vais étudier le programme et j'aurai d'autres questions dans un avenir très proche.
Au revoir

 

Bonjour Huckleberry

Heureux d'avoir de vos nouvelles.


1. La structure

La structure est développée et mise en forme par mes soins.

//                                                                //<          >
// < 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       > //<          >
//                                                                //<          >
     

La première intention est de séparer strictement les données globales et le code.
Le programme informatique est pour moi un modèle du monde réel.
Les données globales sont les choses de ce monde.
Le code est l'ensemble des actions.
En les séparant, je souligne que je comprends la différence entre eux.
Compter le nombre d'éléments m'aide à vérifier et à contrôler tout ce qui se trouve dans le programme.


2. La mise en forme

La mise en forme est un simple HTML.
La balise suivante ouvre la partie du programme :

// <                                                            > //<          >
      


La balise suivante ferme la partie du programme :

// </                                                           > //<          >
      


La balise suivante est utilisée pour les parties du programme sur une seule ligne :

// <                                                           /> //<          >
      

La partie finale de la balise est maintenant utilisée pour le comptage des pages.
A l'avenir, l'utilisation de cette partie de balise pourra être étendue.

                                                                  //<          >
      

La structure des pages permet de naviguer facilement dans le programme.
En utilisant <Page Up> et <Page Down>, je vois toujours les mêmes types de balises aux mêmes endroits.



3. Les éléments

L'élément de données est une variable globale unique.
Je vois aussi le tableau comme l'élément unique.
Les variables locales ne sont que des entités temporaires des éléments de code.

L'élément de code est une fonction unique.
Je peux aussi utiliser le mot "méthode".
J'utilise le mot "interface" pour désigner un ensemble uni de fonctions.

Pour réduire la complexité, je divise les données et le code en domaines logiques.
Le nombre de domaines dépend de la structure du programme.
Domaines habituels pour les données : "entrée", "paramètres", "contrôle", "tampon" ...
Domaines habituels pour le code : "spécial" pour l'ensemble des fonctions spéciales, "interface" pour l'ensemble des autres fonctions.
Dans le cas de grands programmes, je peux créer des "objets" avec différentes "interfaces".

Pour contrôler l'intégrité des éléments de données et des éléments de code, on utilise le comptage.


//                                                                //<          >
// < 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   > //<          >
//                                                                //<          >
     

Les balises d'ouverture et de fermeture contiennent les mêmes sommes.
En général, je compte la somme dans la balise d'ouverture.
Ensuite, je copie et insère la balise d'ouverture à la place de la balise de fermeture, puis j'ajoute la barre oblique de fermeture "/".

Pour contrôler l'intégrité des données, la notation suivante est utilisée.
Le nombre d'éléments de données de "integer" est noté "i".
Le nombre d'éléments de données de "double" est noté "d".
Le nombre d'éléments de données de la "chaîne" est noté "s".
La colonne de gauche contient la somme de la ligne "i" + "d" + "s".

Pour contrôler l'intégrité du code, la notation suivante est utilisée.
Le nombre d'entrées de fonction, c'est-à-dire le nombre d'arguments de fonction, est noté "i".
Le nombre de lignes de code ouvertes est noté "l".
Le nombre de sorties de fonction est noté "o".
Toujours "1" pour une fonction unique qui renvoie une valeur quelconque et "-" dans tous les autres cas.
La colonne de gauche contient le nombre de fonctions dans le domaine.


4. Les domaines

Ce sont les en-têtes des domaines.

////////////////////////////////////////////////////////////////////<         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   > //<          >
//                                                                //<          >
     


Les règles et notations pour le comptage sont les mêmes que pour l'en-tête du programme.
Je copie simplement les balises d'ouverture des en-têtes des domaines dans l'en-tête du programme.

Chaque page du domaine a des balises d'ouverture et de fermeture.
Par exemple :

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

Les chiffres de tête sont utilisés pour le comptage et la navigation des parties de la structure.
Suit la notation de la partie du programme "Données" ou "Code".
Suit le nom du domaine.
Puis suit le nom de l'élément du domaine.


J'espère que cela pourra vous aider.

Au revoir pour le moment et dans l'attente de votre réponse

 

Bonjour Ais
Ton sens de l'organisation est ......, comment dire ..... pratique et sensé.
L'intégration du HTML facilite la navigation, même si cela me dépasse pour l'instant.
Très bien.
Pour l'instant, je suis en train de décortiquer le programme que vous m'avez envoyé, une déclaration à la fois. Les concepts
que vous avez sur les variables, sont compréhensibles. Merci encore.
Je vous répondrai avec des questions, j'en suis sûr.
Au revoir

 

Bonjour Ais,,,<Cela a été édité>
Le programme n'a pas encore été absorbé. Désolé qu'il vous prenne autant de temps. Il y a une zone que j'ai dû manquer,
parce que je dois faire face à une erreur.
Je dois partir pour l'instant, mais je reviendrai demain.
Au revoir.

 

Hello Huckleberry
Certaines fonctionnalités ont été ajoutées à titre d'exemple et peuvent être facilement modifiées ou supprimées.
L'amélioration du programme est un processus permanent.
Au revoir pour le moment
:)

 
Ais wrote >>

Bonjour Huckleberry
Certaines fonctionnalités ont été ajoutées à titre d'exemple et peuvent facilement être modifiées ou supprimées.
L'amélioration du programme est un processus permanent.
Au revoir pour le moment
:)


Bonjour Ais
Je vous remercie pour tout ce que vous avez fait.
Hier soir, j'ai finalement trouvé mon erreur alors que je copiais votre programme.
En ce moment, j'essaie de comprendre à quoi servent certaines des variables et comment elles fonctionnent.
Le iSignalClose est l'endroit où j'insère une partie de mon autre programme pour établir le OrderClosePrice. Avec
votre suggestion :

dDelta = OrderOpenPrice () - OrderClosePrice

le programme a plus de flexibilité.
Je reviendrai avec d'autres questions. Et des commentaires.
Salutations
 

Bonjour Ais
Les questions se sont posées. Votre programme indique dans ..... iTryOpen ()

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

Par curiosité, devrait-il y avoir

else if     ( iCommand       == OP_BUY  )
   {          
string        sType           = "Buy"   ;   
int           iColor          =  Blue   ;               }
else if     ( iCommand       == OP_SELL )   // Was this ommitted     
   {          sType           = "Sell"  ;    
              iColor          =  Red    ;               }
Voici une autre question pour mieux comprendre
// < 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 ) ; } //<          >
//                                                  
Si iNewBar est VRAI, le contrôle est transmis à iSignalOpen. Si iNewBar est TRUE (égal à la barre actuelle ??), OU iFirstRun ==1, alors iFirstBar = 0. Cela prête à confusion uniquement parce que je ne comprends pas la définition de iNewBar () et/ou de iFirstRun. Je peux voir où iFirstRun est décarré et initialisé, mais qu'est-ce que cela signifie.
Je suis désolé de vous importuner pour des questions aussi simples. Je ne peux pas calculer ou voir comment les deux fonctionnent dans la fonction. Quand vous aurez le temps, pourriez-vous éclaircir ce point s'il vous plaît.
Merci encore pour vos efforts : )
Cheers
 

Bonjour Huckleberry

Les deux questions sont importantes !

Réponse 1.

Les deux conditions sont vraies, mais si :
1.1. nous savons que

int       iCommand          = iSignalOpen ()                    ; //<          >
     

1.2. nous savons que "iSignalOpen ()" peut retourner seulement 3 valeurs possibles : "EMPTY", "OP_BUY" et "OP_SELL" ;
1.3. la première valeur est déjà vérifiée

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

1.4. la deuxième valeur est également vérifiée

if      ( iCommand         == OP_BUY )                            //<          >
     

il est alors possible d'omettre la dernière vérification "si" pour accélérer légèrement les calculs.

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


Réponse 2.

2.1. Nous reconnaissons que la barre numéro 0 est changée en comparant l'heure d'ouverture de la barre numéro 0 avec la dernière heure d'ouverture enregistrée de la barre numéro 0.
"iTime ( 0, 0, 0 )" retourne l'heure d'ouverture de la barre incomplète actuelle.
L'index de la barre actuelle est toujours 0, c'est la troisième valeur dans "iTime ( 0, 0, 0 )".
Déclarer la variable "int iTime_0" comme "static" signifie que la valeur de cette variable est sauvegardée entre les invocations de la fonction.
Chaque fois que l'heure d'ouverture est modifiée, nous :
2.1.1. assignons "iTime_0 = iTime ( 0, 0, 0 ) ;" pour stocker l'heure d'ouverture de la barre actuelle ;
2.1.2. retournons "TRUE" ce qui signifie que la barre actuelle est une nouvelle barre, la dernière barre numéro 0 est devenue la barre numéro 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. Notre barre de départ pour les calculs de "dHigh" et "dLow" dans "iSignalOpen ()", et "dATR" dans "iSignalClose ()", est "iBaseBar=1".
Si la barre numéro 1 est la même, ces valeurs sont les mêmes.
C'est une raison pour ne calculer ces valeurs que sur les nouvelles barres.
Cela accélère le programme.
La variable "static int iFirstRun" est un simple déclencheur.
La valeur initiale "1" force le calcul de "dHigh", "dLow" et "dATR" à la première exécution du programme, indépendamment de toute condition.
Cela améliore la fiabilité du programme.

<ajouté plus tard>
Exactement, lors de la première exécution du programme, "iNewBar ()" dans "iSignalOpen ()" retourne "TRUE", et dans "iSignalClose" retourne "EMPTY" !
Ceci est dû au fait que lors de la première invocation de "iNewBar ()", c'est-à-dire à l'intérieur de la première exécution de "iSignalOpen ()", la valeur de "iTime_0 = 0".et lors de la deuxième invocation de "iNewBar ()", c'est-à-dire lors de la première exécution de "iSignalClose ()", "iTime_0 = iTime ( 0, 0, 0 )" !
Le résultat sans contrôle de la première exécution peut être "dATR = 0".
Telle est la première exécution.
</added later>

Immédiatement après, nous assignons "iFirstRun = 0" et la condition suivante ne sera vraie que sur les nouvelles barres :

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

Mais !
Reste du code de "iSignalOpen ()" et "iSignalClose ()" exécuté à chaque tick!
Seuls les calculs des valeurs inchangées sont ignorés.

////////////////////////////////////////////////////////////////////<         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 >                      //<          >
     


J'espère que cela pourra vous aider.
Cheers !
:)

P.S. Quelques remarques ajoutées plus tard.
Et, en regardant ces remarques, il est évident que "iNewBar ()" doit être corrigé.
C'est parce que cette fonction est invoquée deux fois pour vérifier un seul événement.
Maintenant, pour le même événement sur la première invocation "iNewBar ()" renvoie une valeur correcte, et sur la deuxième renvoie une valeur incorrecte.
Sera corrigé.



 

Bonjour Ais
Merci pour ces précisions. Je vais poursuivre mes lectures. Je n'ai pas encore une connaissance complète du code.
Mais vous avez mentionné qu'il y avait quelque chose qui devait être corrigé en ce qui concerne l'iNewBar ? Je ne suis pas sûr que l'iNewBar soit en cause dans le problème que le backtest a révélé. Deux problèmes possibles ?
Voici ce que j'ai vu lorsque j'ai ouvert le graphique après un backtest. Nous savons qu'il y a une entrée d'achat lorsque le Ask est au-dessus du plus haut des vingt dernières barres. La vente est exactement l'inverse. Pourtant, les entrées ne sont pas cohérentes. Est-ce la zone que vous avez vue ?
J'ai trouvé une chose de plus. Le Hard Stop est calculé Atr*2. C'est correct, mais je ne vois pas où il est calculé. Mais le vrai problème est que le TakeProfit a le même calcul Atr*2. Si je savais où le Hard Stop est calculé, je pourrais éventuellement corriger le TakeProfit. Le TakeProfit dans ce cas ne devrait être que Atr*1.
Prenez soin de vous et je serai de retour demain.
Au revoir

 

Salut Huckleberry

La condition TakeProfit a été inventée par moi-même à des fins de test.
Maintenant, elle est modifiée.
Au lieu de "Atr*2" et "Atr*1", j'utilise "dATR * dFactorTP" et "dATR * dFactorSL".
Les valeurs initiales "dFactorTP = 1.0" et "dFactorSL = 2.0" sont dans la page 2 "Data : Input".
Une telle solution permet d'optimiser facilement ces valeurs.

J'ai modifié les fonctions "iSignalOpen ()" et "iSignalClose ()".
La vérification de la nouvelle barre est maintenant implémentée dans ces fonctions.
Les conditions pour "Buy" et "Sell" dans "iSignalOpen ()" semblent probablement correctes.

Le programme complet est dans le fichier attaché à la page suivante.

Cheers