J'ai trouvé quelques pistes pour la recherche de cette fameuse JMA.
Ces 2 codes revendiquent être le code original et se ressemblent (et la logique est comparable au RSX de Jurik) :
https://www.wisestocktrader.com/indicators/5965-the-real-jurik-moving-average-jma-translated-to-amibroker-for-amibroker-afl
https://ctrader.com/algos/indicators/show/191
J'ai essayé de convertir ça en ProBuilder, le code semble correct mais le temps de calcul est hallucinant et rend la chose inexpoitable. Il doit y avoir une erreur mais je ne vois pas où.
Paramètres :
Periods (default 15)
Phase (default 0)
Code : #
//SetBarsRequired( ceil( 20 + 80 * ( Periods ^ 0.36 ) ) );
// Downloaded From https://www.WiseStockTrader.com
//+------------------------------------------------------------------+
//SetBarsRequired(ceil(20+80*(r1^0.36)));
//SetBarsRequired(200,0);
//function IntPortion( Paramet )
//{
//return IIf( Paramet > 0, floor( Paramet ), ceil( Paramet ) );
//};
//+------------------------------------------------------------------+
//function JJMA( Array, Length, Phase )
//{
//----buffers
if barIndex > ceil( 20 + 80 * ( exp(log(Periods) * 0.36 ) ) ) then
Length = Periods
Array = CustomClose
fC0Buffer = 0
fC8Buffer = 0
fA8Buffer = 0
JMAValueBuffer = Array
JMAValue = 0
loopCriteria = 0
cycleDelta = 0
cycleLimit = 0
counterA = 0
counterB = 0
JMATempValue = 0
//+------------------------------------------------------------------+
//|JMAinitFlagizationfunction|
//+------------------------------------------------------------------+
//ring2 = 0
//ring1 = 0
buffer = 0
//----initialpart
limitValue = 63
startValue = 64
//----
for i = 0 to limitValue do
$list[i] = -1000000
next
for i = startValue to 127 do
$list[i] = 1000000
next
//----
initFlag = 1
if Length < 1.0000000002 then
lengthParam = 0.0000000001
else
lengthParam = ( Length - 1 ) / 2.0
endif
//----
if Phase < -100 then
phaseParam = 0.5
elsif Phase > 100 then
phaseParam = 2.5
else
phaseParam = Phase / 100.0 + 1.5
endif
//----
logParam = log( sqrt( lengthParam ) ) / log( 2.0 )
//----
if ( logParam + 2.0 ) < 0 then
logParam = 0
else
logParam = logParam + 2.0
endif
//----
sqrtParam = sqrt( lengthParam ) * logParam
lengthParam = lengthParam * 0.9
lengthDivider = lengthParam / ( lengthParam + 2.0 )
//----
//+------------------------------------------------------------------+
//|JMAiterationfunction|
//+------------------------------------------------------------------+
//----maincycle
loopParam = 0
for shift = 0 to BarIndex - 1 do
series = Array[shift]
if loopParam < 61 then
loopParam = loopParam + 1
$buffer[loopParam] = series
endif
if loopParam > 30 then
if initFlag > 0 then
initFlag = 0
diffFlag = 0
for i = 1 to 29 do
if $buffer[i + 1] <> $buffer[i] then
diffFlag = 1
endif
next
highLimit = diffFlag * 30
if highLimit = 0 then
paramB = series
else
paramB = $buffer[1]
endif
paramA = paramB
if highLimit > 29 then
highLimit = 29
endif
else
highLimit = 0
endif
//----bigcycle
for i = highLimit downto 0 do
if i = 0 then
sValue = series
else
sValue = $buffer[31 - i]
endif
if abs( sValue - paramA ) > abs( sValue - paramB ) then
absValue = abs( sValue - paramA )
else
absValue = abs( sValue - paramB )
endif
dValue = absValue + 0.0000000001 //1.0e-10;
if counterA <= 1 then
counterA = 127
else
counterA = counterA - 1
endif
if counterB <= 1 then
counterB = 10
else
counterB = counterB - 1
endif
if cycleLimit < 128 then
cycleLimit = cycleLimit + 1
endif
cycleDelta = cycleDelta + ( dValue - $ring2[counterB] )
$ring2[counterB] = dValue
if cycleLimit > 10 then
highDValue = cycleDelta / 10.0
else
highDValue = cycleDelta / cycleLimit
endif
if cycleLimit > 127 then
dValue = $ring1[counterA]
$ring1[counterA] = highDValue
s68 = 64
s58 = s68
while s68 > 1 do
if $list[s58] < dValue then
s68 = s68 / 2.0
s58 = s58 + s68
elsif $list[s58] <= dValue then
s68 = 1
else
s68 = s68 / 2.0
s58 = s58 - s68
endif
wend
else
$ring1[counterA] = highDValue
if ( limitValue + startValue ) > 127 then
startValue = startValue - 1
s58 = startValue
else
limitValue = limitValue + 1
s58 = limitValue
endif
if limitValue > 96 then
s38 = 96
else
s38 = limitValue
endif
if startValue < 32 then
s40 = 32
else
s40 = startValue
endif
endif
//----
s68 = 64
s60 = s68
while s68 > 1 do
if $list[s60] >= highDValue then
if $list[s60 - 1] <= highDValue then
s68 = 1
else
s68 = s68 / 2.0
s60 = s60 - s68
endif
else
s68 = s68 / 2.0
s60 = s60 + s68
endif
if ( s60 = 127 ) and ( highDValue > $list[127] ) then
s60 = 128
endif
wend
if cycleLimit > 127 then
if s58 >= s60 then
if( ( ( s38 + 1 ) > s60 ) and ( ( s40 - 1 ) < s60 ) ) then
lowDValue = lowDValue + highDValue
elsif( ( s40 > s60 ) and ( ( s40 - 1 ) < s58 ) ) then
lowDValue = lowDValue + $list[s40 - 1]
endif
else
if( s40 >= s60 ) then
if( ( ( s38 + 1 ) < s60 ) and ( ( s38 + 1 ) > s58 ) ) then
lowDValue = lowDValue + $list[s38 + 1]
else
if( ( s38 + 2 ) > s60 ) then
lowDValue = lowDValue + highDValue
else
if( ( ( s38 + 1 ) < s60 ) and ( ( s38 + 1 ) > s58 ) ) then
lowDValue = lowDValue + $list[s38 + 1]
endif
endif
endif
endif
endif
if( s58 > s60 ) then
if( ( ( s40 - 1 ) < s58 ) and ( ( s38 + 1 ) > s58 ) ) then
lowDValue = lowDValue - $list[s58]
else
if( ( s38 < s58 ) and ( ( s38 + 1 ) > s60 ) ) then
lowDValue = lowDValue - $list[s38]
endif
endif
else
if( ( ( s38 + 1 ) > s58 ) and ( ( s40 - 1 ) < s58 ) ) then
lowDValue = lowDValue - $list[s58]
else
if( ( s40 > s58 ) and ( s40 < s60 ) ) then
lowDValue = lowDValue - $list[s40]
endif
endif
endif
endif
if( s58 <= s60 ) then
if( s58 >= s60 ) then
$list[s60] = highDValue
else
for j = s58 + 1 to s60 - 1 do
$list[j - 1] = $list[j]
next
$list[s60 - 1] = highDValue
endif
else
for j = s58 - 1 downto s60 do
$list[j + 1] = $list[j]
next
$list[s60] = highDValue
endif
if( cycleLimit <= 127 ) then
lowDValue = 0
for j = s40 to s38 do
lowDValue = lowDValue + $list[j]
next
endif
//----
if( ( loopCriteria + 1 ) > 31 ) then
loopCriteria = 31
else
loopCriteria = loopCriteria + 1
endif
JMATempValue = sqrtParam / ( sqrtParam + 1.0 )
sqrtDivider = JMATempValue
if( loopCriteria <= 30 ) then
if( sValue - paramA > 0 ) then
paramA = sValue
else
paramA = sValue - ( sValue - paramA ) * sqrtDivider
endif
if( sValue - paramB < 0 ) then
paramB = sValue
else
paramB = sValue - ( sValue - paramB ) * sqrtDivider
endif
JMATempValue = series
if( loopCriteria = 30 ) then
$fC0Buffer[shift] = series
if( ceil( sqrtParam ) >= 1 ) then
intPart = ceil( sqrtParam )
else
intPart = 1
endif
if intPart > 0 then
leftInt = floor(intPart)
else
leftInt = ceil(intPart)
endif
if( floor( sqrtParam ) >= 1 ) then
intPart = floor( sqrtParam )
else
intPart = 1
endif
if intPart > 0 then
rightPart = floor(intPart)
else
rightPart = ceil(intPart)
endif
if( leftInt = rightPart ) then
dValue = 1.0
else
dValue = ( sqrtParam - rightPart ) / ( leftInt - rightPart )
endif
if( rightPart <= 29 ) then
upShift = rightPart
else
upShift = 29
endif
if( leftInt <= 29 ) then
dnShift = leftInt
else
dnShift = 29
endif
$fA8Buffer[shift] = ( series - $buffer[loopParam - upShift] ) * ( 1 - dValue ) / rightPart + ( series - $buffer[loopParam - dnShift] ) * dValue / leftInt
endif
else
dValue = lowDValue / ( s38 - s40 + 1 )
if( 0.5 <= logParam - 2.0 ) then
powerValue = logParam - 2.0
else
powerValue = 0.5
endif
// a^Pow = EXP(LOG(a)*Pow)
if( logParam >= exp(log(absValue / dValue) * powerValue) ) then
dValue = exp(log(absValue / dValue) * powerValue)
else
dValue = logParam
endif
if( dValue < 1 ) then
dValue = 1
endif
powerValue = exp(log(sqrtDivider) * ( sqrt( dValue ) ))
if( sValue - paramA > 0 ) then
paramA = sValue
else
paramA = sValue - ( sValue - paramA ) * powerValue
endif
if( sValue - paramB < 0 ) then
paramB = sValue
else
paramB = sValue - ( sValue - paramB ) * powerValue
endif
endif
next
//----endofbigcycle
if( loopCriteria > 30 ) then
JMATempValue = $JMAValueBuffer[shift - 1]
powerValue = exp(log(lengthDivider) * dValue)
squareValue = powerValue * powerValue
$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 = JMATempValue + $fA8Buffer[shift]
endif
JMAValue = JMATempValue
endif
if( loopParam <= 30 ) then
JMAValue = close[BarIndex - 1]
endif
$JMAValueBuffer[shift] = JMAValue
//----Endofmaincycle
next
endif
return $JMAValueBuffer[0]