PureBytes Links
Trading Reference Links
|
Hello all,
I found this metatrader code for JMA from Jurik Research - a well
respected zero lag MA. Can some one please translate it to AFL - it
should be pretty easy and straight forward because both are based on
C++
This code works fine with metatrader - I checked it out.
Thanks in advance
//+------------------------------------------------------------------+
//| JMA.mq4 |
//| Weld, Jurik Research |
//| http://weld.torguem.net |
//+------------------------------------------------------------------+
#property copyright "Weld"
#property link "http://weld.torguem.net"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Aqua
//---- input parameters
extern int Length = 14;
extern int Phase = 0;
//---- buffers
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(4);
//---- drawing settings
SetIndexStyle (0, DRAW_LINE);
SetIndexDrawBegin(0, 30);
//---- 4 indicator buffers mapping
SetIndexBuffer (0, JMAValueBuffer);
SetIndexBuffer (1, fC0Buffer);
SetIndexBuffer (2, fA8Buffer);
SetIndexBuffer (3, fC8Buffer);
//---- initialize one buffer (neccessary)
ArrayInitialize (ring2, 0);
ArrayInitialize (ring1, 0);
ArrayInitialize (buffer, 0);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName ("JMAValue(" + Length + "," + Phase + ")");
SetIndexLabel (0, "JMAValue");
//---- 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;
}
//+------------------------------------------------------------------+
//| 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;
//---- 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;
//---- End of main cycle
}
return;
}
//+------------------------------------------------------------------+
int IntPortion (double param) {
if (param > 0) return (MathFloor (param));
if (param < 0) return (MathCeil (param));
return (0.0);
}
//+------------------------------------------------------------------+
------------------------------------
Please note that this group is for discussion between users only.
To get support from AmiBroker please send an e-mail directly to
SUPPORT {at} amibroker.com
For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
http://www.amibroker.com/devlog/
For other support material please check also:
http://www.amibroker.com/support.html
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/amibroker/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/amibroker/join
(Yahoo! ID required)
<*> To change settings via email:
mailto:amibroker-digest@xxxxxxxxxxxxxxx
mailto:amibroker-fullfeatured@xxxxxxxxxxxxxxx
<*> To unsubscribe from this group, send an email to:
amibroker-unsubscribe@xxxxxxxxxxxxxxx
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|