//+------------------------------------------------------------------+ //| JMASlope.mq4 | //| Copyright © 2005, TrendLaboratory Ltd. | //| http://finance.groups.yahoo.com/group/TrendLaboratory | //| Thanks to Weld, Jurik Research http://weld.torguem.net| //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, TrendLaboratory Ltd." #property link "http://finance.groups.yahoo.com/group/TrendLaboratory" //---- #property indicator_separate_window #property indicator_buffers 2 #property indicator_color1 Green #property indicator_color2 Red //---- input parameters extern int Length=14; extern int Phase =0; //---- buffers double UpBuffer []; double DnBuffer []; double JMAValueBuffer []; double fC0Buffer []; double fA8Buffer []; double fC8Buffer []; //---- temporary buffers double list[128], ring1[128], ring2[11], buffer[62]; //---- bool flag bool initFlag; //---- integer vars int limitValue, startValue, loopParam, loopCriteria; int cycleLimit, highLimit, counterA, counterB; //---- double vars double cycleDelta, lowDValue, highDValue, absValue, paramA, paramB; double phaseParam, logParam, JMAValue, series, sValue, sqrtParam, lengthDivider; //---- temporary int variables int s58, s60, s40, s38, s68; //+------------------------------------------------------------------+ //| JMA initFlagization function | //+------------------------------------------------------------------+ int init() { double lengthParam; //---- 3 additional buffers are used for counting. IndicatorBuffers(6); //---- drawing settings SetIndexStyle (0, DRAW_HISTOGRAM); SetIndexStyle (1, DRAW_HISTOGRAM); SetIndexDrawBegin(0, 30); SetIndexDrawBegin(1, 30); //---- 4 indicator buffers mapping SetIndexBuffer (0, UpBuffer); SetIndexBuffer (1, DnBuffer); SetIndexBuffer (2, JMAValueBuffer); SetIndexBuffer (3, fC0Buffer); SetIndexBuffer (4, fA8Buffer); SetIndexBuffer (5, fC8Buffer); //---- initialize one buffer (neccessary) ArrayInitialize (ring2, 0); ArrayInitialize (ring1, 0); ArrayInitialize (buffer, 0); //---- name for DataWindow and indicator subwindow label IndicatorShortName ("JMASlope(" + Length + "," + Phase + ")"); SetIndexLabel (0, "UpSlope"); SetIndexLabel (1, "DownSlope"); //---- initial part limitValue=63; startValue=64; //---- for(int i=0; i<=limitValue; i++) list [i]=-1000000; for(i=startValue; i<=127; i++) list [i]=1000000; //---- initFlag =true; if (Length < 1.0000000002) lengthParam=0.0000000001; else lengthParam=(Length - 1)/2.0; //---- if (Phase < -100) phaseParam=0.5; else if (Phase > 100) phaseParam=2.5; else phaseParam=Phase/100.0 + 1.5; //---- logParam=MathLog (MathSqrt (lengthParam))/MathLog (2.0); //---- if (logParam + 2.0 < 0) logParam=0; else logParam=logParam + 2.0; //---- sqrtParam =MathSqrt(lengthParam) * logParam; lengthParam =lengthParam * 0.9; lengthDivider=lengthParam/(lengthParam + 2.0); //---- return(0); } //+------------------------------------------------------------------+ //| JMA iteration function | //+------------------------------------------------------------------+ int start() { //---- get already counted bars int counted_bars=IndicatorCounted(); //---- check for possible errors if (counted_bars < 0) return(-1); int limit=Bars - counted_bars - 1; if(counted_bars==0) limit--; //---- main cycle for(int shift=limit; shift>=0; shift--) { series=Close [shift]; //---- if (loopParam < 61) { loopParam++; buffer [loopParam]=series; } if (loopParam > 30) { if (initFlag) { initFlag=false; //---- int diffFlag=0; for(int i=1; i<=29; i++) { if (buffer [i + 1]!=buffer [i]) diffFlag=1; } highLimit=diffFlag * 30; //---- if (highLimit==0) paramB=series; else paramB=buffer[1]; paramA=paramB; if (highLimit > 29) highLimit=29; } else highLimit=0; //---- big cycle for(i=highLimit; i>=0; i--) { if (i==0) sValue=series; else sValue=buffer [31 - i]; if (MathAbs (sValue - paramA) > MathAbs (sValue - paramB)) absValue=MathAbs(sValue - paramA); else absValue=MathAbs(sValue - paramB); double dValue=absValue + 0.0000000001; //1.0e-10; //---- if (counterA<=1) counterA=127; else counterA--; if (counterB<=1) counterB=10; else counterB--; if (cycleLimit < 128) cycleLimit++; cycleDelta+=(dValue - ring2 [counterB]); ring2 [counterB]=dValue; if (cycleLimit > 10) highDValue=cycleDelta/10.0; else highDValue=cycleDelta/cycleLimit; if (cycleLimit > 127) { dValue=ring1 [counterA]; ring1 [counterA]=highDValue; s68=64; s58=s68; while(s68 > 1) { if (list [s58] < dValue) { s68=s68/2.0; s58+=s68; } else if (list [s58]<=dValue) { s68=1; } else { s68=s68/2.0; s58-=s68; } } } else { ring1 [counterA]=highDValue; if ((limitValue + startValue) > 127) { startValue--; s58=startValue; } else { limitValue++; s58=limitValue; } if (limitValue > 96) s38=96; else s38=limitValue; if (startValue < 32) s40=32; else s40=startValue; } //---- s68=64; s60=s68; while(s68 > 1) { if (list [s60]>=highDValue) { if (list [s60 - 1]<=highDValue) { s68=1; } else { s68=s68/2.0; s60-=s68; } } else { s68=s68/2.0; s60+=s68; } if ((s60==127) && (highDValue > list[127])) s60=128; } if (cycleLimit > 127) { if (s58>=s60) { if (((s38 + 1) > s60) && ((s40 - 1) < s60)) lowDValue+=highDValue; else if ((s40 > s60) && ((s40 - 1) < s58)) lowDValue+=list [s40 - 1]; } else if (s40>=s60) { if (((s38 + 1) < s60) && ((s38 + 1) > s58)) lowDValue+=list[s38 + 1]; } else if ((s38 + 2) > s60) lowDValue+=highDValue; else if (((s38 + 1) < s60) && ((s38 + 1) > s58)) lowDValue+=list[s38 + 1]; if (s58 > s60) { if (((s40 - 1) < s58) && ((s38 + 1) > s58)) lowDValue-=list [s58]; else if ((s38 < s58) && ((s38 + 1) > s60)) lowDValue-=list [s38]; } else { if (((s38 + 1) > s58) && ((s40 - 1) < s58)) lowDValue-=list [s58]; else if ((s40 > s58) && (s40 < s60)) lowDValue-=list [s40]; } } if (s58<=s60) { if (s58>=s60) list[s60]=highDValue; else { for(int j=s58 + 1; j<=(s60 - 1); j++) { list [j - 1]=list[j]; } list [s60 - 1]=highDValue; } } else { for(j=s58 - 1; j>=s60; j--) { list [j + 1]=list [j]; } list [s60]=highDValue; } if (cycleLimit<=127) { lowDValue=0; for(j=s40; j<=s38; j++) { lowDValue+=list[j]; } } //---- if ((loopCriteria + 1) > 31) loopCriteria=31; else loopCriteria++; double JMATempValue, sqrtDivider=sqrtParam/(sqrtParam + 1.0); //---- if (loopCriteria<=30) { if (sValue - paramA > 0) paramA=sValue; else paramA=sValue - (sValue - paramA) * sqrtDivider; if (sValue - paramB < 0) paramB=sValue; else paramB=sValue - (sValue - paramB) * sqrtDivider; JMATempValue=series; if (loopCriteria==30) { fC0Buffer [shift]=series; int intPart; //---- if (MathCeil(sqrtParam)>=1) intPart=MathCeil(sqrtParam); else intPart=1; int leftInt=IntPortion (intPart); if (MathFloor(sqrtParam)>=1) intPart=MathFloor(sqrtParam); else intPart=1; int rightPart=IntPortion (intPart); //---- if (leftInt==rightPart) dValue=1.0; else dValue=(sqrtParam - rightPart)/(leftInt - rightPart); if (rightPart<=29) int upShift=rightPart; else upShift=29; if (leftInt<=29) int dnShift=leftInt; else dnShift=29; fA8Buffer [shift]=(series - buffer [loopParam - upShift]) * (1 - dValue)/rightPart + (series - buffer[loopParam - dnShift]) * dValue/leftInt; } } else { double powerValue, squareValue; //---- dValue=lowDValue/(s38 - s40 + 1); if (0.5<=logParam - 2.0) powerValue=logParam - 2.0; else powerValue=0.5; if (logParam>=MathPow(absValue/dValue, powerValue)) dValue=MathPow (absValue/dValue, powerValue); else dValue=logParam; if (dValue < 1) dValue=1; //---- powerValue=MathPow (sqrtDivider, MathSqrt (dValue)); if (sValue - paramA > 0) paramA=sValue; else paramA=sValue - (sValue - paramA) * powerValue; if (sValue - paramB < 0) paramB=sValue; else paramB=sValue - (sValue - paramB) * powerValue; } } // ---- end of big cycle if (loopCriteria > 30) { JMATempValue=JMAValueBuffer [shift + 1]; powerValue =MathPow (lengthDivider, dValue); squareValue =MathPow (powerValue, 2); //---- fC0Buffer [shift]=(1 - powerValue) * series + powerValue * fC0Buffer [shift + 1]; fC8Buffer [shift]=(series - fC0Buffer [shift]) * (1 - lengthDivider) + lengthDivider * fC8Buffer [shift + 1]; fA8Buffer [shift]=(phaseParam * fC8Buffer [shift] + fC0Buffer [shift] - JMATempValue) * (powerValue * (-2.0) + squareValue + 1) + squareValue * fA8Buffer [shift + 1]; JMATempValue+=fA8Buffer [shift]; } JMAValue=JMATempValue; } if (loopParam<=30) JMAValue=0; JMAValueBuffer [shift]=JMAValue; double rel=JMAValueBuffer [shift]-JMAValueBuffer [shift+1]; if(rel>=0) { UpBuffer[shift]=rel; DnBuffer[shift]=0; } else { DnBuffer[shift]=rel; UpBuffer[shift]=0; } //---- End of main cycle } return(0); } //+------------------------------------------------------------------+ int IntPortion (double param) { if (param > 0) return(MathFloor (param)); if (param < 0) return(MathCeil (param)); return(0.0); } //+------------------------------------------------------------------+