Rejoindre la communauté
banner_forum
Devenez membre de la plus grande
communauté francophone sur le Forex
Partagez, échangez et apprenez en gagnant des crédits sur votre compte de trading

Indicateur Bicolore en style ligne sur MT4

  • B0gs67

    Bonjour à tous,

    Souhaitant appréhender le développement d'indicateur pour MT4, j'ai commencé par réaliser une moyenne mobile bicolore, rouge lorsqu'elle descend et bleu lorsqu'elle monte.

    Toutefois lorsque la moyenne mobile est montante seulement entre 2 bougies, celle-ci n’apparaît pas de couleur bleu, mais rouge.

    Voici le code de l'init :
    Code
    int draw_begin = MA.Period - 1; SetIndexStyle(0,DRAW_NONE); SetIndexDrawBegin(0,draw_begin); SetIndexBuffer(0,MA); SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,SignalSize); SetIndexDrawBegin(1,draw_begin); SetIndexBuffer(1,MA.up); SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,SignalSize); SetIndexDrawBegin(2,draw_begin); SetIndexBuffer(2,MA.do);

    Et voici le code de la fonction start() :
    Code
    int countedBars=IndicatorCounted(); for(int i=Bars-countedBars-1;i>=0;i--){ MA[i]=iMA(Symbol(),Period(),MA.Period,MA.Shift,MA.Type,MA.Price,i); if(MA[i]>MA[i+1]){ MA.do[i]=0; MA.up[i]=MA[i]; MA.up[i+1]=MA[i+1]; }else{ MA.up[i]=0; MA.do[i]=MA[i]; MA.do[i+1]=MA[i+1]; } }

    J'ai valorisé à 0 plutôt que EMPTY_VALUE, afin de mieux visualiser le changement de couleur.

    Etant donné que les valeurs de la moyenne mobile descendante sont dans le dernier buffer, la moyenne mobile descendante cache la moyenne mobile montante.
    Afin d'afficher une courbe continue, lors d'un changement de tendance, je dois valorisé la valeur précédente de la moyenne mobile montante ou descendante, ceci est réalisé via le code précédent :
    Code
    MA.up[i+1]=MA[i+1];
    ou
    Code
    MA.do[i+1]=MA[i+1];

    Donc lorsque j'ai une moyenne mobile descendante, puis montante entre seulement deux bougies, puis à nouveau descendante, j'aurai ceci dans mes buffers :
    MA[a,b,c,d]
    MA.up[0,b,c,0]
    MA.do[a,b,c,d]

    Lorsque la moyenne mobile est montante sur un plus long terme, le problème ne se reproduira pas. Voir en pièce jointe le résultat.


    Quelqu'un aurait-il une solution à mon problème, afin d'afficher correctement le changement de couleur ?
    B0gs67 a joint une image
    creer-un-indicateur-bicolore-en-style-ligne-sur-mt4-8078
  • liva

    Salut,

    Sur ton premier cercle vert, la MA n' est pas haussière, pourquoi voudrais tu qu' elle change de couleur ?
  • B0gs67

    Elle est haussière mais de très peu, elle passe de 155.4507 à 155.4514
  • JJFlash

    Salut,
    Je pense que c'est juste une erreur d'indiçage. Essaie de décaler tout tes indices de 1
    C'est a dire, i devient i-1, et i+1 devient i
    Pas sûr que sa marche mais bon...
  • liva — en réponse à B0gs67 dans son message #84496

    C' est étonnant effectivement si on oublie que l' on est sur MT4, il aime faire ce genre de choses.
    Je pense que tant que ta MA ne sera pas haussière graphiquement parlant, il ne te la mettra pas en bleu.
    En plus d' afficher l' indicateur comme tu le désires, MT4 doit faire une mise à l' échelle dans la fenêtre de l' indic.
    Je pense que ça peut venir de là.

    Sinon, n' hésite pas à bien séparer toutes les conditions : else if(MA[i]<MA[i+1])
  • B0gs67

    MT4 détecte bien que la moyenne mobile est haussière. On voit bien la ligne bleu partir de 0 et revenir à la valeur de la moyenne mobile.

    Si je ne me trompe pas, MT4 trace des droites entre 2 points. Ici la moyenne mobile baissière doit être affichée puis nulle puis réaffichée, or on constate bien qu'elle n'est jamais nulle. Si je la valorise à nulle, la courbe sera discontinue.

    Pour expliquer ça, prenons l'image jointe :
    entre t0 et t1, la moyenne mobile est baissière
    entre t1 et t2, la moyenne mobile est haussière
    entre t2 et t3, la moyenne mobile est baissière

    Pour tracer cette courbe :
    - t0 et t1 doivent être valorisée dans le buffer de la moyenne mobile baissière.
    - t1 et t2 doivent être valorisée dans le buffer de la moyenne mobile haussière.
    - t2 et t3 doivent être valorisée dans le buffer de la moyenne mobile baissière.

    On s'aperçoit donc que le buffer de la moyenne mobile baissière détient toutes les valeurs, et de ce fait MT4 trace simplement toutes les droites entres ces points, et du coup n'est jamais valorisée à nulle.
    La moyenne mobile haussière est bien affichée, mais vu qu'elle se trouve sur le 2ème buffer, elle est affichée en dessous du 3ème buffer correspondant à la moyenne mobile baissière, et est donc pas visible.

    Le but serait donc de spécifier qu'entre t1 et t2 la valeur de la moyenne mobile baissière est nulle. Etant donné qu'aucun point ne se trouve entre t1 et t2, je ne sais pas si cela est possible.
    B0gs67 a joint une image
    creer-un-indicateur-bicolore-en-style-ligne-sur-mt4-8079
  • mikroub

    Salut,

    B0gs67, le 27/10/2013 dit :
    J'ai valorisé à 0 plutôt que EMPTY_VALUE, afin de mieux visualiser le changement de couleur.

    Moi c'est tes 0 qui me gènent, tu veux dire que tu préfères voir des lignes verticales dans ton indicateur pour identifier le chgt de couleur? Moi je trouve ça un peu crado, sans compter les pb de rafraîchissement quand tu te balades sur ton graph...

    Tu as bien cibler le problème avec tes t1, t2, etc... Effectivement, MT4 a besoin de deux points pour tracer une droite à partir d'un tableau de données...

    Tu utilises un buffer 0 donnant la MA qui te sert à faire les calculs pour remplir ton buffer 1 (MA Up) et ton buffer 2 (MA down), donc:

    Code
    for( int i=Bars-countedBars-1; i>=0; i--) { MA[i] = iMA( Symbol(), Period(), MA.Period, MA.Shift, MA.Type, MA.Price, i ); if( MA[i] > MA[i+1]) { MA.up[i] = MA[i]; if( MA.up[i+1] == EMPTY_VALUE) MA.up[i+1] = MA[i+1]; if( MA.do[i] != EMPTY_VALUE ) MA.do[i] = EMPTY_VALUE; //anti-doublon si repaint } else { MA.do[i]=MA[i]; if( MA.do[i+1] == EMPTY_VALUE ) MA.do[i+1] = MA[i+1]; if( MA.up[i] != EMPTY_VALUE ) MA.up[i] = EMPTY_VALUE; //anti-doublon si repaint } }
    Qu'en penses-tu?

    P.S. je n'ai pas compilé le code, il est possible que tu obtiennes des erreurs de syntaxe...
    Modifié le 2013-10-28 19:05:26 par mikroub
  • B0gs67

    J'ai valorisé les moyennes mobiles à 0 simplement pour visualiser le problème, mais au final elle sera bien valorisée à EMPTY_VALUE.

    Code
    if( MA.up[i] != EMPTY_VALUE ) MA.up[i] = EMPTY_VALUE; //anti-doublon si repaint
    Je ne comprends pas à quoi sert cette condition ?

    Sinon avec ton code le problème est toujours le même.

    Etant donné qu'il s'agit d'un comportement normal à MT4, je pense que la solution serait d'ajouter un second buffer pour la moyenne mobile baissière. Il suffira donc de switcher 1 fois sur deux sur ces 2 buffers. Je ne vois pas d'autre solution.
  • mikroub — en réponse à B0gs67 dans son message #84652

    Plop,

    Cette condition sert à détruire la valeur précédemment enregistrée dans le cas ou l'indicateur repeint par rapport au nouveau tick... En temps réel et par rapport à la structure de ton code, l'indicateur repeint entre [i+1] et [i] à chaque nouveaux tick car ta bougie [i] n'est pas clôturée, le pb étant que tu utilises deux buffers différents pour tracer ta courbe bicolore...

    Hummmm je crois comprendre, essayes comme ça:

    Code
    for( int i=Bars-countedBars-1; i>=0; i--) { MA[i] = iMA( Symbol(), Period(), MA.Period, MA.Shift, MA.Type, MA.Price, i ); if( MA[i] > MA[i+1]) { MA.up[i] = MA[i]; if( MA.up[i+1] == EMPTY_VALUE && MA.up[i+2] != EMPTY_VALUE ) MA.up[i+1] = MA[i+1]; if( MA.do[i] != EMPTY_VALUE ) MA.do[i] = EMPTY_VALUE; //anti-doublon si repaint } else { MA.do[i]=MA[i]; if( MA.do[i+1] == EMPTY_VALUE && MA.do[i+2] != EMPTY_VALUE ) MA.do[i+1] = MA[i+1]; if( MA.up[i] != EMPTY_VALUE ) MA.up[i] = EMPTY_VALUE; //anti-doublon si repaint } }

    B0gs67, le 28/10/2013 dit :
    Etant donné qu'il s'agit d'un comportement normal à MT4, je pense que la solution serait d'ajouter un second buffer pour la moyenne mobile baissière. Il suffira donc de switcher 1 fois sur deux sur ces 2 buffers. Je ne vois pas d'autre solution.

    Ça risque de complexifier ton code, je ne pense pas que cela soit la bonne solution... De plus, MT4 est limité au niveau des buffers, restons simple.

    +

    P.S. si tu peux compiler l'indic et nous poster le résultat graphique sur la même période que ton premier essai, cela pourrait aider...
    Modifié le 2013-10-29 07:02:12 par mikroub
  • B0gs67

    Tu trouveras en pièce jointe le résultat graphique, donc qui n'est toujours pas correcte (courbe non continue, et manque l'indication haussière).

    Je ne vois pas pourquoi chercher à réaliser ceci via 2 buffers seulement car il est clairement impossible de le faire.

    Je reprends un exemple :
    - à t0, la MA est haussière
    - à t1, la MA est baissière
    - à t2, la MA est haussière

    Pour tracer une courbe continue, tu es obligé de spécifier la valeur précédente, ce qui donne :
    - à t0, la MA est haussière => MA.up[t0] = MA[t0] et MA.up[t0 - 1] = MA[t0 - 1]
    - à t1, la MA est baissière => MA.do[t1] = MA[t1] et MA.do[t0] = MA[t0]
    - à t2, la MA est haussière => MA.up[t2] = MA[t2] et MA.up[t1] = MA[t0]

    On voit bien qu'à t0 et t1, les deux MA sont renseignés. MT4 réagit simplement en traçant la courbe 2 fois entre ces points.
    Pour résoudre ceci, il faudrait arrivé à indiquer à MT4 de ne pas tracer cette courbe entre deux points renseignés. Or je ne pense pas que cela soit possible.
    B0gs67 a joint une image
    indicateur-bicolore-en-style-ligne-sur-mt4-8097
  • mikroub

    LoL, c'est pire... Tu as raison, et je ne pense pas que ton double buffer sur la baissière fonctionnera...

    Sinon on peut tricher, je remanie le code:

    Code
    for( int i=Bars-countedBars-1; i>=0; i--) { MA.up[i] = iMA( Symbol(), Period(), MA.Period, MA.Shift, MA.Type, MA.Price, i ); MA.do[i] = iMA( Symbol(), Period(), MA.Period, MA.Shift, MA.Type, MA.Price, i ); if ((MA.up[i] > MA.up[i+1])&&(MA.up[i+1] > MA.up[i+2])) MA.do[i+1] = EMPTY_VALUE; else if((MA.up[i] < MA.up[i+1])&&(MA.up[i+1] < MA.up[i+2])) MA.up[i+1] = EMPTY_VALUE ; }

    Et tu vires le buffer MA, qu'en penses-tu?

    P.S. Un screen est bienvenu... ;)
  • mikroub — en réponse à mikroub dans son message #84729

    Non, j'ai réfléchis pareil, la condition est sur deux périodes dans le dernier code, on tourne en rond...

    Restes avec le premier code que j'ai posté avec la fonction anti-doublon et te prends pas la tête... De toute façon, par inertie ta MA baissière sur une période ne te fera pas perdre un trade, ce n'est pas ça qui fera que ton trading sera profitable ou non...

    Ou programmes sur une autre plateforme plus conciliante... ;)
    Modifié le 2013-10-29 18:27:47 par mikroub
  • B0gs67

    En effet, on ne peut pas faire ce qu'on veut, il faudrait redévelopper MT4 pour réagir autrement...

    Je suis aussi d'accord avec toi, ce n'est pas une période qui va changer, je dirai presque au contraire. Mais c'est le principe qui compte.
    D'ailleurs tous les exemples de ligne bicolore, que j'ai pu trouver, considérait un "mouvement" baissier ou "haussier" à partir de 2 périodes "baissière" ou "haussière". Et dans ce cas, le problème ne se pose plus.
  • B0gs67

    En doublant les buffers, le problème est résolu. Le but est de switcher une fois sur deux sur chaque buffer :
    Code
    int countedBars=IndicatorCounted(); int bufferMAUp = 1; bool modifMAUp = true; int bufferMADo = 1; bool modifMADo = true; for(int i=Bars-countedBars-1;i>=0;i--){ MA[i]=iMA(Symbol(),Period(),MA.Period,MA.Shift,MA.Type,MA.Price,i); if(MA[i]>MA[i+1]){ modifMAUp = false; if(!modifMADo) { bufferMADo++; modifMADo = true; } if(bufferMAUp % 2 == 0) { MA.up2[i]=MA[i]; MA.up2[i+1]=MA[i+1]; MA.up[i] = EMPTY_VALUE; } else { MA.up[i]=MA[i]; MA.up[i+1]=MA[i+1]; MA.up2[i] = EMPTY_VALUE; } MA.do[i]=EMPTY_VALUE; MA.do2[i]=EMPTY_VALUE; } else { modifMADo = false; if(!modifMAUp) { bufferMAUp++; modifMAUp = true; } if(bufferMADo % 2 == 0) { MA.do2[i]=MA[i]; MA.do2[i+1]=MA[i+1]; MA.do[i] = EMPTY_VALUE; } else { MA.do[i]=MA[i]; MA.do[i+1]=MA[i+1]; MA.do2[i] = EMPTY_VALUE; } MA.up[i]=EMPTY_VALUE; MA.up2[i]=EMPTY_VALUE; } }

    Et une capture d'écran en pièce jointe
    B0gs67 a joint une image
    indicateur-bicolore-en-style-ligne-sur-mt4-8101
  • mikroub — en réponse à B0gs67 dans son message #84738

    intéressant mais un peu lourd pour un indicateur simple, ça vaut tout de même un +1, bonne continuation dans tes recherches. :)

    +