Rejoignez notre page de fans
- Vues:
- 7
- Note:
- Publié:
- 2025.06.19 12:06
-
Besoin d'un robot ou d'un indicateur basé sur ce code ? Commandez-le sur Freelance Aller sur Freelance
Définition des variables
Tout d'abord, vous devez modifier les premières lignes du fichier pour qu'elles correspondent au nom de vos variables et tableaux. Ci-dessous, vous pouvez voir que j'ai utilisé g_rates pour la variable MqlRates qui contient l'ouverture, la fermeture, le haut et le bas de la bougie. Vous devez remplacer g_rates par le nom de votre variable. Le "i" est un nom de variable fictif qui n'interférera avec aucune autre variable de votre code. La variable "i" est le numéro de la bougie utilisée. Exemple : pour utiliser la clôture de la bougie 3, utilisez CANDLECLOSE(3). // Candle (define g_rates as : MqlRates g_rates[] ;) #define CANDLELOW(i) g_rates[i].low #define CANDLEHIGH(i) g_rates[i].high #define CANDLEOPEN(i) g_rates[i].open #define CANDLECLOSE(i) g_rates[i].close #define CANDLETIME(i) g_rates[i].time
Vous pouvez également obtenir les valeurs ASK et BID en utilisant MqlTick comme je l'ai fait ci-dessous, ou vous pouvez appeler SymbolInfoDouble(_Symbol,SYMBOL_ASK) si vous préférez. Cela ne change rien à la valeur renvoyée.
// Prix (define g_tick as : MqlTick g_tick ;)) #define ASK g_tick.ask #define BID g_tick.bid
Enfin, des tableaux sont également définis pour les moyennes mobiles, atr, ou tout autre tableau supplémentaire dont vous avez besoin. Exemple : pour utiliser l'Average True Range de la bougie 1, utilisez ATR(1).
IMPORTANT : on suppose que les tableaux sont AsSeries ( par exemple,ArraySetAsSeries(g_MA20_arr, true) ; ). Ce point est essentiel dans les déclarations #define présentées plus loin.
// définir ces tableaux comme suit : double g_MA20_arr[] ; // Moyennes mobiles et ATR #define MOVAVG20(i) g_MA20_arr[i] #define MOVAVG40(i) g_MA40_arr[i] #define MOVAVG50(i) g_MA50_arr[i] #define MOVAVG200(i) g_MA200_arr[i] #define ATR(i) g_atr_arr[i]
Une fois que vous avez défini les instructions ci-dessus, vous ne devriez plus avoir besoin de modifier quoi que ce soit. D'autres instructions #define adaptées à votre EA peuvent également être ajoutées si nécessaire.
Caractéristiques des bougies
Les bougies ont des caractéristiques qui sont utiles lors du développement d'un EA, en particulier si l'EA est basé sur l'action des prix. Les noms des définitions suivantes indiquent ce qu'elles représentent. WICK fait référence à l'ombre de la bougie supérieure et TAIL à l'ombre de la bougie inférieure. Exemple : pour obtenir le prix au milieu du corps de la dernière bougie, utilisez CANDLEBODYMIDDLE(1).
// caractéristiques des bougies #define CANDLEBODYTOP(i) fmax(CANDLEOPEN(i),CANDLECLOSE(i)) #define CANDLEBODYBOT(i) fmin(CANDLEOPEN(i),CANDLECLOSE(i)) #define CANDLEMEDIAN(i) (0.5*(CANDLEHIGH(i)+CANDLELOW(i))) #define CANDLEWEIGHTED(i) (0.25*(CANDLEHIGH(i)+CANDLELOW(i)+2*CANDLECLOSE(i))) #define CANDLETYPICAL(i) (1./3.*(CANDLEHIGH(i)+CANDLELOW(i)+CANDLECLOSE(i))) #define CANDLEBODYMIDDLE(i) (0.5*(CANDLEBODYTOP(i)+CANDLEBODYBOT(i))) #define CANDLESIZE(i) (CANDLEHIGH(i)-CANDLELOW(i)) #define CANDLEBODYSIZE(i) fabs(CANDLECLOSE(i)-CANDLEOPEN(i)) #define CANDLEWICKSIZE(i) (CANDLEHIGH(i)-CANDLEBODYTOP(i)) #define CANDLETAILSIZE(i) (CANDLEBODYBOT(i)-CANDLELOW(i))
En outre, nous définissons deux tailles en utilisant l'ATR comme référence. Exemple : vous voulez savoir quelle est la taille de la bougie 4 par rapport à l'ATR, utilisez ATRCANDLESIZE(4).
#define ATRCANDLESIZE(i) (CANDLESIZE(i)/ATR(i)) #define ATRCANDLEBODYSIZE(i) (CANDLEBODYSIZE(i)/ATR(i))
De plus, les bougies qui montent (clôture>ouverture) sont dites avoir une direction +1, tandis que les bougies qui descendent ont une direction -1. Si clôture==ouverture, la direction = 0. Exemple : if(CANDLEDIRECTION(10)==1) Print("La bougie 10 est une bougie haussière") ;
#define CANDLEDIRECTION(i) (CANDLECLOSE(i)>CANDLEOPEN(i)?1:(CANDLECLOSE(i)<CANDLEOPEN(i)?-1:0))
Deux types de "runs" sont définis : UP et DOWN. Le runUP est défini dans une bougie en hausse comme Close-Low, sinon 0. Le runDOWN est défini dans une bougie en baisse comme High-Close, sinon 0 ; Les "runs" sont utilisés utilement pour capturer un fort mouvement du prix dans une direction. Par exemple, pour obtenir le run-up de la bougie 3, utilisez CANDLERUNUP(3).
#define CANDLERUNUP(i) ((CANDLECLOSE(i)>CANDLEOPEN(i))?(CANDLECLOSE(i)-CANDLELOW(i)):0) #define CANDLERUNDOWN(i) ((CANDLECLOSE(i)<CANDLEOPEN(i))?(CANDLEHIGH(i)-CANDLECLOSE(i)):0)
Demandes de renseignements sur les caractéristiques des bougies
Ces définitions sont des variables booléennes qui nous indiquent le comportement d'une ou d'un groupe de bougies. Elles utilisent les déclarations #define précédentes pour les rendre plus courtes.
isCANDLERIGHTDIR(i,dir) sera vrai si la direction de la bougie(i) est égale à dir, sinon faux ;
Il existe deux types de fractales : l'une utilisant cinq bougies et l'autre (la fractale faible) utilisant trois bougies. Dans les #définitions de fractales ci-dessous, la bougie(i) est la bougie du milieu ayant le plus haut (TOP) ou le plus bas (BOT). Assurez-vous qu'il existe des données pour les bougies i-2,i-1,i,i+1,i+2 pour les fractales à cinq bougies. Il existe également d'autres variantes utilisant l'inégalité stricte ">" ou "<", et utilisant "<=" ou ">=". Enfin, il existe des #définitions pour identifier les fractales supérieures (TOP) ou inférieures (BOT). En examinant les définitions, vous pouvez déterminer la définition à utiliser.
is3CANDLEGAPUP(i,gap,size) est utilisé pour trouver un gap UP (où le haut d'une bougie est en dessous du bas de deux bougies plus tard). Candle(i) sera la plus récente des trois bougies en question. Une fois de plus, on suppose que les bougies sont "AsSeries". "gap" est le delta de prix minimum du gap, et "size" est le delta de prix minimum de la taille du corps de la bougie du milieu.
is3CANDLEGAPDOWN(i,gap,size) est utilisé pour trouver un écart DOWN en utilisant la même logique.
is3CANDLEGAPUPTREND(i,gap,size) est identique à is3CANDLEGAPUP(i,gap,size) mais ajoute une condition supplémentaire pour être vrai : la plus ancienne des trois bougies doit être de direction positive.
Il y a deux façons de déterminer si une bougie est un doji : isCANDLEDOJIPOINTS(i,n) et isCANDLEDOJIFRACTION(i,f). La première version utilise n*_Point et la seconde utilise f*CANDLESIZE(i) pour déterminer si (vrai ou faux) la bougie est un Doji.
Exemple : si vous voulez savoir si la bougie 20 est un sommet fractal non strict (utilisant des égalités), utilisez isCANDLEFRACTALEQTOP(20), et la sortie sera vraie ou fausse.
Comme vous pouvez le voir, les définitions sont une forme comprimée des requêtes, ce qui rend le code de votre EA plus court et plus facile à lire.
// demande de renseignements sur les caractéristiques de la bougie (booléen) #define isCANDLEUP(i) (CANDLEDIRECTION(i)==1) #define isCANDLEDOWN(i) (CANDLEDIRECTION(i)==-1) #define isCANDLEFLAT(i) (CANDLEDIRECTION(i)==0) #define isCANDLEWICKLESS(i) (CANDLEWICKSIZE(i)==0) #define isCANDLETAILLESS(i) (CANDLETAILSIZE(i)==0) #define isCANDLESOLID(i) (CANDLEWICKSIZE(i)==0 && CANDLETAILSIZE(i)==0) #define isCANDLERIGHTDIR(i,dir) (dir*(CANDLECLOSE(i) - CANDLEOPEN(i))>0) #define isCANDLEFRACTALTOP(i) (CANDLEHIGH(i) > CANDLEHIGH(i-1) && CANDLEHIGH(i-1) > CANDLEHIGH(i-2) && CANDLEHIGH(i) > CANDLEHIGH(i+1) && CANDLEHIGH(i+1) > CANDLEHIGH(i+2)) #define isCANDLEFRACTALBOT(i) (CANDLELOW(i) < CANDLELOW(i-1) && CANDLELOW(i-1) < CANDLELOW(i-2) && CANDLELOW(i) < CANDLELOW(i+1) && CANDLELOW(i+1) < CANDLELOW(i+2)) #define isCANDLEFRACTALEQTOP(i) (CANDLEHIGH(i) >= CANDLEHIGH(i-1) && CANDLEHIGH(i-1) >= CANDLEHIGH(i-2) && CANDLEHIGH(i) >= CANDLEHIGH(i+1) && CANDLEHIGH(i+1) >= CANDLEHIGH(i+2)) #define isCANDLEFRACTALEQBOT(i) (CANDLELOW(i) <= CANDLELOW(i-1) && CANDLELOW(i-1) <= CANDLELOW(i-2) && CANDLELOW(i) <= CANDLELOW(i+1) && CANDLELOW(i+1) <= CANDLELOW(i+2)) #define isCANDLEWEAKFRACTALTOP(i) (CANDLEHIGH(i) > CANDLEHIGH(i-1) && CANDLEHIGH(i) > CANDLEHIGH(i+1)) #define isCANDLEWEAKFRACTALBOT(i) (CANDLELOW(i) < CANDLELOW(i-1) && CANDLELOW(i) < CANDLELOW(i+1)) #define isCANDLEWEAKFRACTALEQBOT(i) (CANDLELOW(i) <= CANDLELOW(i-1) && CANDLELOW(i) <= CANDLELOW(i+1)) #define isCANDLEWEAKFRACTALEQTOP(i) (CANDLEHIGH(i) >= CANDLEHIGH(i-1) && CANDLEHIGH(i) >= CANDLEHIGH(i+1)) #define is3CANDLEGAPUP(i,gap,size) (CANDLELOW(i)-CANDLEHIGH(i+2)>gap && CANDLEBODYSIZE(i+1)>=size) #define is3CANDLEGAPDOWN(i,gap,size) (CANDLELOW(i+2)-CANDLEHIGH(i)>gap && CANDLEBODYSIZE(i+1)>=size) #define is3CANDLEGAPUPTREND(i,gap,size) (CANDLELOW(i)-CANDLEHIGH(i+2)>gap && CANDLEBODYSIZE(i+1)>=size && isCANDLEUP(i+2)) #define is3CANDLEGAPDOWNTREND(i,gap,size) (CANDLELOW(i+2)-CANDLEHIGH(i)>gap && CANDLEBODYSIZE(i+1)>=size && isCANDLEDOWN(i+2)) #define isCANDLEDOJIPOINTS(i,n) (CANDLEBODYSIZE(i) <= n*_Point) #define isCANDLEDOJIFRACTION(i,f) (CANDLEBODYSIZE(i) <= f*CANDLESIZE(i))
Fonctions et opérations mathématiques
Nous allons maintenant définir quelques fonctions et opérations mathématiques utiles dans l'EA. Certaines d'entre elles sont spécifiques aux EE que j'ai développées, mais vous pouvez les modifier ou les supprimer si vous le souhaitez.
BRACKET(x,minV,maxV) renvoie une valeur de x à l'intérieur de l'intervalle [minV,maxV]. Cette fonction est utile pour restreindre les variables d'entrée dans l'EA.
CONVEXCOMB(a,x1,x2) est une combinaison convexe de x1 et x2 sous la forme a*x1+x2. Cette fonction est utile pour calculer une valeur intermédiaire entre x1 et x2, mais vous voulez plus que la moyenne (a=0,5).
EVALLINE(x,x1,y1,x2,y2,ymin,ymax) est l'évaluation d'une ligne droite définie par deux points [x1,y1] et [x2,y2]. Une fois évaluée en x, elle renvoie une valeur entre crochets à l'intérieur de [ymin, ymax].
MAPAB11(x,A,B) fait passer la valeur x d'une parenthèse [A,B] à une parenthèse [-1,1]. MAP11AB(x,A,B) fait passer la valeur x d'une parenthèse [-1,1] à une parenthèse [A,B]. Ces deux fonctions sont utiles pour travailler avec des variables normalisées dans l'intervalle [-1,1].
Les quatre dernières fonctions sont utilisées dans mes EA et ne sont pas nécessairement utiles à tout le monde, mais je les ai laissées là, juste au cas où.
#define BRACKET(x,minV,maxV) (x<minV?minV:(x>maxV?maxV:x)) #define CONVEXCOMB(a,x1,x2) (a*x1+(1.0-a)*x2) #define EVALLINE(x,x1,y1,x2,y2,ymin,ymax) BRACKET((y2-y1)/(x2-x1)*(x-x1)+y1,ymin,ymax) #define MAPAB11(x,A,B) (2./(B-A)*(BRACKET(x,A,B)-A)-1.) #define MAP11AB(x,A,B) ((B-A)/2.*(BRACKET(x,-1,1)-1)+B) #define SIGMOID(x,a) (1.0/(1.0 + exp(-a*x))) #define NN1(x,w,b) (w*x+b) #define EVALPOLY(X,X0,X1,Y0,Y1,EX,ymin,ymax) BRACKET(Y1*pow((X-X0)/(X1-X0),EX)+Y0,ymin,ymax) #define EVALPOLY2P(X,X0,X1,Y0,Y1,EX,ymn,ymx) BRACKET((Y1-Y0)*pow((X-X0)/(X1-X0),EX)+Y0,ymn,ymx)
En outre, en tant que fonctions et opérations, il y a des calculs de différences (en tant qu'approximation des pentes).
MA20DIFF(i,n) donne la différence entre les deux valeurs de la moyenne mobile à 20 périodes séparées par n bougies. Les autres fonctions suivent la même logique. Exemple : pour calculer la différence entre la moyenne mobile 200 périodes à la bougie 3 et à la bougie 13, utilisez MA200DIFF(3,10).
#define MA20DIFF(i,n) (MOVAVG20(i)-MOVAVG20(i+n)) #define MA40DIFF(i,n) (MOVAVG40(i)-MOVAVG40(i+n)) #define MA50DIFF(i,n) (MOVAVG50(i)-MOVAVG50(i+n)) #define MA200DIFF(i,n) (MOVAVG200(i)-MOVAVG200(i+n)) #define CANDLECLOSEDIFF(i,n) (CANDLECLOSE(i)-CANDLECLOSE(i+n)) #define CANDLEOPENDIFF(i,n) (CANDLEOPEN(i)-CANDLEOPEN(i+n)) #define CANDLEHIGHDIFF(i,n) (CANDLEHIGH(i)-CANDLEHIGH(i+n)) #define CANDLELOWDIFF(i,n) (CANDLELOW(i)-CANDLELOW(i+n)) #define CANDLEMEDIANDIFF(i,n) (CANDLEMEDIAN(i)-CANDLEMEDIAN(i+n)) #define CANDLEWEIGHTEDDIFF(i,n) (CANDLEWEIGHTED(i)-CANDLEWEIGHTED(i+n)) #define CANDLETYPICALDIFF(i,n) (CANDLETYPICAL(i)-CANDLETYPICAL(i+n)) #define CANDLEBODYMIDDLEDIFF(i,n) (CANDLEBODYMIDDLE(i)-CANDLEBODYMIDDLE(i+n))
Les requêtes sont également incluses en tant que fonctions mathématiques. La mise entre parenthèses et la convexité sont vérifiées ci-dessous.
#define isINBRACKET(x,minV,maxV) (x<=maxV && x>=minV) #define isINBRACKETSTRICT(x,minV,maxV) (x<maxV && x> minV) #define isOUTBRACKET(x,minV,maxV) (x>=maxV || x<=minV) #define isOUTBRACKETSTRICT(x,minV,maxV) (x> maxV || x< minV) #define isCONVEX(yl,yc,yr) (yl>=yc && yc<=yr) #define isCONCAVE(yl,yc,yr) (yl<=yc && yc>=yr) #define isCONVEXTSTRICT(yl,yc,yr) (yl>yc && yc<yr) #define isCONCAVESTRICT(yl,yc,yr) (yl<yc && yc> yr)
Constantes
Je définis quelques constantes que j'utilise. C'est à vous de choisir de les utiliser.
// Constantes #define PIVALUE (M_PI) #define MINSTOPPOINTS (30) #define MINFREEZEPOINTS (30) #define STOPLEVEL (fmax(MINSTOPPOINTS,(double)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL))*_Point) #define FREEZELEVEL (fmax(MINFREEZEPOINTS,(double)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_FREEZE_LEVEL))*_Point)
Débogage
Tout programmeur chevronné sait que le meilleur outil pour déboguer son code est l'instruction Print. Les définitions suivantes permettent de mettre en place des instructions Print dans l'ensemble de votre programme, et de les activer/désactiver en fonction de la valeur du niveau de débogage qui vous intéresse.
Tout d'abord, vous devez définir le niveau de débogage en utilisant #define DEBUG_LEVEL0, #define DEBUG_LEVEL1, ou #define DEBUG_LEVEL2. Lorsque vous utilisez DEBUG_LEVEL0, il n'y aura pas d'impression sur l'onglet Journal du terminal Metatrader 5. Avec DEBUG_LEVEL1, seules les instructions PRINTVARn seront actives et s'imprimeront sur l'onglet Journal. Avec DEBUG_LEVEL2, les déclarations PRINTVARn et VPRINTVARn seront toutes deux imprimées sur l'onglet Journal. DEBUG_LEVEL2 correspond au cas "V "erbose utilisant VPRINTVARn.
PRINTVARn imprime n variables. Par exemple, si vous souhaitez imprimer i, x et z, utilisez PRINTVAR3(i,x,z) ; pour imprimer une chaîne, utilisez PRINTTEXT("n'importe quelle chaîne") ; L'impression comprendra le nom de la fonction et le numéro de ligne du fichier dans lequel l'instruction PRINTVARn est insérée.
// Débogage avec Print // Au début de votre code, définissez le niveau de débogage x={0,1,2} comme suit : #define DEBUG_LEVELx #ifdef DEBUG_LEVEL0 #define PRINTTEXT(text) #define PRINTVAR(x1) #define PRINTVAR1(x1) #define PRINTVAR2(x1,x2) #define PRINTVAR3(x1,x2,x3) #define PRINTVAR4(x1,x2,x3,x4) #define PRINTVAR5(x1,x2,x3,x4,x5) #define PRINTVAR6(x1,x2,x3,x4,x5,x6) #define VPRINTTEXT(text) #define VPRINTVAR(x1) #define VPRINTVAR1(x1) #define VPRINTVAR2(x1,x2) #define VPRINTVAR3(x1,x2,x3) #define VPRINTVAR4(x1,x2,x3,x4) #define VPRINTVAR5(x1,x2,x3,x4,x5) #define VPRINTVAR6(x1,x2,x3,x4,x5,x6) #endif #ifdef DEBUG_LEVEL1 #define PRINTTEXT(text) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :",text) #define PRINTVAR(x1) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1)) #define PRINTVAR1(x1) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1)) #define PRINTVAR2(x1,x2) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2)) #define PRINTVAR3(x1,x2,x3) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3)) #define PRINTVAR4(x1,x2,x3,x4) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4)) #define PRINTVAR5(x1,x2,x3,x4,x5) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4),", " #x5 + "=", (x5)) #define PRINTVAR6(x1,x2,x3,x4,x5,x6) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4),", " #x5 + "=", (x5),", " #x6 + "=", (x6)) #define VPRINTTEXT(text) #define VPRINTVAR(x1) #define VPRINTVAR1(x1) #define VPRINTVAR2(x1,x2) #define VPRINTVAR3(x1,x2,x3) #define VPRINTVAR4(x1,x2,x3,x4) #define VPRINTVAR5(x1,x2,x3,x4,x5) #define VPRINTVAR6(x1,x2,x3,x4,x5,x6) #endif #ifdef DEBUG_LEVEL2 #define PRINTTEXT(text) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :",text) #define PRINTVAR(x1) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1)) #define PRINTVAR1(x1) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1)) #define PRINTVAR2(x1,x2) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2)) #define PRINTVAR3(x1,x2,x3) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3)) #define PRINTVAR4(x1,x2,x3,x4) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4)) #define PRINTVAR5(x1,x2,x3,x4,x5) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4),", " #x5 + "=", (x5)) #define PRINTVAR6(x1,x2,x3,x4,x5,x6) Print("*/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4),", " #x5 + "=", (x5),", " #x6 + "=", (x6)) #define VPRINTTEXT(text) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :",text) #define VPRINTVAR(x1) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1)) #define VPRINTVAR1(x1) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1)) #define VPRINTVAR2(x1,x2) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2)) #define VPRINTVAR3(x1,x2,x3) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3)) #define VPRINTVAR4(x1,x2,x3,x4) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4)) #define VPRINTVAR5(x1,x2,x3,x4,x5) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4),", " #x5 + "=", (x5)) #define VPRINTVAR6(x1,x2,x3,x4,x5,x6) Print("V/*/*/* ",__FUNCTION__,"(",__LINE__,") :", #x1 + "=", (x1),", " #x2 + "=", (x2),", " #x3 + "=", (x3),", " #x4 + "=", (x4),", " #x5 + "=", (x5),", " #x6 + "=", (x6)) #endif
Traduit de l’anglais par MetaQuotes Ltd.
Code original : https://www.mql5.com/en/code/56149
![Stochastic multi-timeframe [v04]](https://c.mql5.com/i/code/indicator.png)
L'indicateur stochastique peut être appliqué à n'importe quel horizon temporel (supérieur ou inférieur à l'horizon temporel du graphique actuel).
![RSI multi-timeframe [v03]](https://c.mql5.com/i/code/indicator.png)
L'indicateur RSI peut être appliqué à n'importe quel horizon temporel (supérieur ou inférieur à l'horizon temporel du graphique actuel).

L'indicateur trace deux lignes. La ligne inférieure est calculée sur la base de la dernière période de la SMA qui a provoqué un rebond à la hausse. La ligne supérieure est calculée sur la base de la dernière période de la SMA qui a provoqué un rebond à la baisse.
![Moving Averages, multi-timeframe [v03]](https://c.mql5.com/i/code/indicator.png)
Moving Average indicator, can be applied to any timeframe (higher or lower than the current chart's timeframe). Includes: SMA, EMA, SMMA, LWMA, AMA, DEMA, TEMA, FRAMA, and VIDYA