JMA_StarLight

Author: Weld
JMA_StarLight

This script functions as a sophisticated technical analysis tool designed to smooth out price fluctuations on a trading chart. It calculates a specialized moving average that prioritizes clarity and responsiveness, aiming to filter out "market noise" while maintaining a close alignment with the current price trend.

Core Logic Overview

The indicator operates through several distinct mathematical layers to achieve its final result:

1. Data Input Selection The logic begins by identifying which specific price point to track. Users can choose between standard market data such as the Closing price, Opening price, the midpoint of the High/Low range, or the extreme High and Low prices. This flexibility allows the indicator to be tailored to different trading styles.

2. Adaptive Smoothing Engine Unlike a simple moving average that treats all historical data equally, this script employs an adaptive mechanism. It analyzes the "velocity" and volatility of price movements. By calculating how quickly the price is changing, the indicator determines how much weight to give to recent data versus older data. This helps prevent the indicator from reacting too wildly to temporary spikes while ensuring it doesn't lag significantly during strong trends.

3. Dynamic Weighted Calculations The script utilizes a series of internal "memory" buffers and calculations to handle weighted averages. It creates a distribution of values that adjusts based on specific parameters provided by the user:

  • Length: Determines the fundamental window of data considered.
  • Phase: Adjusts the quality of the transition process, effectively controlling how "smooth" or "reactive" the line appears.
  • Shift: Allows for a visual offset along the horizontal time axis.

4. Recursive Feedback Loop A key feature of this logic is its recursive nature. It doesn't just look at a static window of the past; it uses the previous calculated values as part of the current calculation. This creates a continuous "flow." It applies mathematical transformations—including logarithmic calculations and square roots—to stabilize the curve, ensuring that the resulting line remains fluid and less jagged than standard moving averages.

5. Precision Filtering The script includes logic to handle specific edge cases in price action. It monitors for sudden changes in the price series and applies corrections to ensure that the calculated average doesn't "break" or provide false signals during periods of extreme market volatility.

Summary for the User

In simple terms, this tool is designed to provide a clean, flowing line on your chart that represents the "true" trend of an asset. It works by intelligently balancing three competing goals:

  1. Smoothing: Removing the jagged "teeth" of minor price fluctuations.
  2. Responsiveness: Ensuring the line turns quickly enough to show a change in trend.
  3. Stability: Preventing the line from moving erratically due to one-off outliers or temporary noise.
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screen
13 Views
0 Downloads
0 Favorites
JMA_StarLight
//+GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+ 
//|                                                JMA_StarLight.mq4 | 
//|           JMA_Star_Light: Copyright © 2005, Weld, Jurik Research | 
//|                                          http://weld.torguem.net | 
//|                         MQL4: Copyright © 2005, Nikolay Kositsin | 
//|                                   Khabarovsk, violet@mail.kht.ru | 
//+GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+ 
#property copyright "Weld" 
#property link "http://weld.torguem.net" 
#property indicator_chart_window 
#property indicator_buffers 1 
#property indicator_color1 Red 
//---- input parameters 
extern int Length = 5; // ãëóáèíà ñãëàæèâàíèÿ 
extern int Phase  = 5; // ïàðàìåòð, èçìåíÿþùèéñÿ â ïðåäåëàõ -150 ... +150, âëèÿåò íà êà÷åñòâî ïåðåõîäíîãî ïðîöåññà; 
extern int Shift  = 0; // cäâèã èíäèêàòîðà âäîëü îñè âðåìåíè 
extern int Input_Price_Customs = 0;//Âûáîð öåí, ïî êîòîðûì ïðîèçâîäèòñÿ ðàñ÷¸ò èíäèêàòîðà (0-"Close", 1-"Open", 2-"(High+Low)/2", 3-"High", 4-"Low") 
//---- indicator buffers 
double JMA_Buf[ ]; 
double MEMORY1[9];
int    MEMORY2[12];
double MEMORY3[128]; 
//---- temporary double buffers 
double list[128], ring1[128], ring2[11], buffer[62]; 
//---- double vars 
double f8, f60,f20,f28,f30,f40,f48,f58,f68,f70,f90,f78,f88,f98;
double Kg,Dr,Ds,Dl,Pf,JMA,series,vv,v1,v2,v3,v4,s20,s10,fB0,fD0;
//---- integer vars 
int ii,jj,s28,s30,f0,v5,v6,fE0,fD8,fE8,val,s48,s58,s60,s68,T0;
//+GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+ 
//| JMA initFlagization function                                     | 
//+GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+ 
int init() 
{ 
SetIndexStyle(0, DRAW_LINE); 
SetIndexShift(0, Shift); 
//---- 1 indicator buffers mapping 
IndicatorBuffers(1);
SetIndexBuffer (0, JMA_Buf); 
SetIndexEmptyValue(0,0.0); 
//---- 
IndicatorShortName ("JMA Star Light( Length="+Length+", Phase="+Phase+", Shift="+Shift+")"); 
SetIndexLabel (0, "JMA Star Light"); 
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//+==== initial part ==============================================================================================================+ 
if(Phase<-100){Alert("Ïàðàìåòð Phase äîëæåí áûòü îò -100 äî +100" + " Âû ââåëè íåäîïóñòèìîå " + Phase+ " áóäåò èñïîëüçîâàíî -100");}
if(Phase> 100){Alert("Ïàðàìåòð Phase äîëæåí áûòü îò -100 äî +100" + " Âû ââåëè íåäîïóñòèìîå " + Phase+ " áóäåò èñïîëüçîâàíî  100");}
if(Length<  1){Alert("Ïàðàìåòð Length äîëæåí íå ìåíåå 1" + " Âû ââåëè íåäîïóñòèìîå " + Length+ " áóäåò èñïîëüçîâàíî  1");}
if(Input_Price_Customs<0){Alert("Ïàðàìåòð Input_Price_Customs äîëæåí íå ìåíåå 0" + " Âû ââåëè íåäîïóñòèìîå " + Input_Price_Customs+ " áóäåò èñïîëüçîâàíî 0");}
if(Input_Price_Customs>4){Alert("Ïàðàìåòð Input_Price_Customs äîëæåí íå áîëåå 4" + " Âû ââåëè íåäîïóñòèìîå " + Input_Price_Customs+ " áóäåò èñïîëüçîâàíî 0");}
if (Length < 1.0000000002) Dr = 0.0000000001; //{1.0e-10} 
else Dr = (Length - 1.0) / 2.0; 
if (Phase >   100) Pf = 2.5; 
if (Phase <  -100) Pf = 0.5; 
if((Phase >= -100)&&(Phase <= 100)) Pf = Phase / 100.0 + 1.5; 
Dr = Dr * 0.9; Kg = Dr / (Dr + 2.0); 
Ds=MathSqrt(Dr); Dl=MathLog(Ds);
//----==========================+ 
return(0); 
} 
//+GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+ 
//| JMA iteration function                                           | 
//+GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG+ 
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(limit==Bars-1)          
{
//---- Ïîâòîðíîå îáúÿâëåíèå ïåðåìåííûõ è èõ èíèöèàëèçàöèÿ ============+
ArrayInitialize (MEMORY1, 0.0);ArrayInitialize (MEMORY2, 0  );
ArrayInitialize (MEMORY3, 0.0);
ArrayInitialize (buffer,  0.0);ArrayInitialize (ring1,   0.0); 
ArrayInitialize (ring2,   0.0);ArrayInitialize (list,    0.0);
//----+===============================================================+

double f18=0.0,f38=0.0,fA0=0.0,fA8=0.0,fC0=0.0,fC8=0.0,s8=0.0,s18=0.0; 
int    s38=0,  s40=0,  s50=0,  s70=0,  LP2=0,  LP1=0;

//----+===============================================================+
f0=1; s28=63; s30=64;
for (ii=0;   ii<=s28; ii++)list[ii]=-1000000.0; 
for (ii=s30; ii<=127; ii++)list[ii]= 1000000.0;
//----+#########################################+
}
if (limit<Bars-1)
{   
//---- èíèöèàëèçàöèÿ ïåðåìåííûõ  èíèöèàëèçàöèÿ =======================+
ArrayInitialize (buffer,  0.0);ArrayInitialize (ring1,   0.0); 
ArrayInitialize (list,    0.0);ArrayInitialize (ring2,   0.0);
//----+===============================================================+
f8 =0.0;f60=0.0;f20=0.0;f28=0.0;f30=0.0;f40=0.0;f48=0.0;f58=0.0;f68=0.0;
f70=0.0;f90=0.0;f78=0.0;f88=0.0;f98=0.0;vv =0.0;v1 =0.0;v2 =0.0;v3 =0.0;
v4 =0.0;fB0=0.0;fD0=0.0;v5 =0;  v6 =0;  fE0=0;  fD8=0;  fE8=0;  val=0;             
//----+===============================================================+
if(Time[limit+1]!=T0)
{
//+--- Âîññòàíîâåíèå ïåðåìåííûõ ############+
if(Time[limit+1]!=MEMORY2[0])return(-1);   
           fC0=MEMORY1[00];
           fC8=MEMORY1[01];
           fA8=MEMORY1[02];
           s8 =MEMORY1[03];
           f18=MEMORY1[04];
           f38=MEMORY1[05];
           s18=MEMORY1[06];                     
           s20=MEMORY1[07];
           s10=MEMORY1[08]; 
//+=======================+                                      
           s38=MEMORY2[01];
           s48=MEMORY2[02];
           s50=MEMORY2[03];
           LP1=MEMORY2[04];
           LP2=MEMORY2[05];                              
           s28=MEMORY2[06];
           s30=MEMORY2[07];                                                         
           s48=MEMORY2[08]; 
           s58=MEMORY2[09];
           s60=MEMORY2[10];
           s68=MEMORY2[11];                                                                                   
           JMA=JMA_Buf[limit+1];
for(ii=0;ii<=127;ii++)list [ii]=MEMORY3[ii];
//+--- ####################################+
}
}
for(int bar = limit; bar >= 0; bar--) 
{
//XXXXXXXX main cycle XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+ 


if((Input_Price_Customs<=0)||Input_Price_Customs>4)series=Close[bar]; 
if (Input_Price_Customs==1)series= Open[bar]; 
if (Input_Price_Customs==2)series=(High[bar]+Low[bar])/2; 
if (Input_Price_Customs==3)series= High[bar]; 
if (Input_Price_Customs==4)series= Low [bar]; 
//---- 
if (LP1<61){LP1++; buffer[LP1]=series;} 
if (LP1>30)
{ 
//++++++++++++++++++ 
v1 = Dl; v2 = v1; 
if ((v1 / MathLog(2.0)) + 2.0 < 0.0) v3 = 0.0; else v3 = (v2 / MathLog(2.0)) + 2.0; 
f98 = v3; 
if ( f98 >= 2.5 ) f88 = f98 - 2.0; else f88 = 0.5; 
f78 = Ds * f98; f90 = f78 / (f78 + 1.0); 
if (f0 != 0) 
{ 
f0 = 0; v5 = 0; 
for( ii=0; ii<=29; ii++) {if (buffer[ii+1] != buffer[ii]) v5 = 1; break; } 
fD8 = v5*30; 
if (fD8 == 0) f38 = series; else f38 = buffer[1]; 
f18 = f38; 
if (fD8 > 29) fD8 = 29; 
} 
else fD8 = 0; 
for(ii=fD8; ii>=0; ii--) 
{ 
val=31-ii; 
if (ii == 0) f8 = series; else f8 = buffer[val]; 
f28 = f8 - f18; f48 = f8 - f38; 
if (MathAbs(f28) > MathAbs(f48)) v2 = MathAbs(f28); else v2 = MathAbs(f48); 
fA0 = v2; vv = fA0 + 0.0000000001; //{1.0e-10;} 
if (s48 <= 1) s48 = 127; else s48 = s48 - 1; 
if (s50 <= 1) s50 = 10;  else s50 = s50 - 1; 
if (s70 < 128) s70 = s70 + 1; 
s8 = s8 + vv - ring2[s50]; ring2[s50] = vv; 
if (s70 > 10) s20 = s8 / 10.0; else s20 = s8 / s70; 
if (s70 > 127) 
{ 
s10 = ring1[s48]; ring1[s48] = s20; s68 = 64; s58 = s68; 
while (s68 > 1) 
{ 
if (list[s58] < s10){s68 = s68 *0.5; s58 = s58 + s68;} 
else if (list[s58] <= s10) s68 = 1; else{s68 = s68 *0.5; s58 = s58 - s68;} 
} 
} 
else 
{ 
ring1[s48] = s20; 
if (s28 + s30 > 127){s30 = s30 - 1; s58 = s30;} 
else {s28 = s28 + 1; s58 = s28;} 
if (s28 > 96) s38 = 96; else s38 = s28; 
if (s30 < 32) s40 = 32; else s40 = s30; 
} 
s68 = 64; s60 = s68; 
while (s68 > 1) 
{ 
if (list[s60] >= s20) 
{ 
if (list[s60 - 1] <= s20) s68 = 1; else {s68 = s68 *0.5; s60 = s60 - s68; } 
} 
else{s68 = s68 *0.5; s60 = s60 + s68;} 
if ((s60 == 127) && (s20 > list[127])) s60 = 128; 
} 
if (s70 > 127) 
{ 
if (s58 >= s60) 
{ 
if ((s38 + 1 > s60) && (s40 - 1 < s60)) s18 = s18 + s20; 
else if ((s40 + 0 > s60) && (s40 - 1 < s58)) s18 = s18 + list[s40 - 1]; 
} 
else 
if (s40 >= s60) {if ((s38 + 1 < s60) && (s38 + 1 > s58)) s18 = s18 + list[s38 + 1]; } 
else if (s38 + 2 > s60) s18 = s18 + s20; else if ((s38 + 1 < s60) && (s38 + 1 > s58)) s18 = s18 + list[s38 + 1]; 
if (s58 > s60) 
{ 
if ( (s40 - 1 < s58) && (s38 + 1 > s58)) s18 = s18 - list[s58]; 
else if ((s38 < s58) && (s38 + 1 > s60)) s18 = s18 - list[s38]; 
} 
else 
{ 
if ((s38 + 1 > s58) && (s40 - 1 < s58)) s18 = s18 - list[s58]; 
else 
if ((s40 + 0 > s58) && (s40 - 0 < s60)) s18 = s18 - list[s40]; 
} 
} 
if (s58 <= s60) 
{ 
if (s58 >= s60) list[s60] = s20; 
else 
{ 
for( jj = s58 + 1; jj<=s60 - 1 ;jj++)list[jj - 1] = list[jj]; 
list[s60 - 1] = s20; 
} 
} 
else 
{ 
for( jj = s58 - 1; jj>=s60 ;jj--) list[jj + 1] = list[jj]; 
list[s60] = s20; 
} 
if (s70 <= 127) 
{ 
s18 = 0; 
for( jj = s40 ; jj<=s38 ;jj++) s18 = s18 + list[jj]; 
} 
f60 = s18 / (s38 - s40 + 1.0); 
if (LP2 + 1 > 31) LP2 = 31; else LP2 = LP2 + 1; 
if (LP2 <= 30) 
{ 
if (f28 > 0.0) f18 = f8; else f18 = f8 - f28 * f90; 
if (f48 < 0.0) f38 = f8; else f38 = f8 - f48 * f90; 
JMA = series; 
if (LP2!=30) continue; 
if (LP2==30) 
{ 
fC0 = series; 
if ( MathCeil(f78) >= 1) v4 = MathCeil(f78); else v4 = 1.0; 
fE8 = IntPortion(v4); 
if (MathFloor(f78) >= 1) v2 = MathFloor(f78); else v2 = 1.0; 
fE0 = IntPortion(v2); 
if (fE8== fE0) f68 = 1.0; else {v4 = fE8 - fE0; f68 = (f78 - fE0) / v4;} 
if (fE0 <= 29) v5 = fE0; else v5 = 29; 
if (fE8 <= 29) v6 = fE8; else v6 = 29; 
fA8 = (series - buffer[LP1 - v5]) * (1.0 - f68) / fE0 + (series - buffer[LP1 - v6]) * f68 / fE8; 
} 
} 
else 
{ 
if (f98 >= MathPow(fA0/f60, f88)) v1 = MathPow(fA0/f60, f88); 
else v1 = f98; 
if (v1 < 1.0) v2 = 1.0; 
else 
{if(f98 >= MathPow(fA0/f60, f88)) v3 = MathPow(fA0/f60, f88); 
else v3 = f98; v2 = v3;} 
f58 = v2; f70 = MathPow(f90, MathSqrt(f58)); 
if (f28 > 0.0) f18 = f8; else f18 = f8 - f28 * f70; 
if (f48 < 0.0) f38 = f8; else f38 = f8 - f48 * f70; 
} 
} 
if (LP2 >30) 
{ 
f30 = MathPow(Kg, f58); 
fC0 =(1.0 - f30) * series + f30 * fC0; 
fC8 =(series - fC0) * (1.0 - Kg) + Kg * fC8; 
fD0 = Pf * fC8 + fC0; 
f20 = f30 *(-2.0); 
f40 = f30 * f30; 
fB0 = f20 + f40 + 1.0; 
fA8 =(fD0 - JMA) * fB0 + f40 * fA8; 
JMA = JMA + fA8; 
} 
} 
//++++++++++++++++++ 
if (LP1 <=30)JMA=0.0; 
JMA_Buf[bar]=JMA; 

if (bar==1)
{
//+--- Ñîõðàíåíèå ïåðåìåííûõ 
        MEMORY1[00]=fC0;
        MEMORY1[01]=fC8;
        MEMORY1[02]=fA8;
        MEMORY1[03]= s8;
        MEMORY1[04]=f18;       
        MEMORY1[05]=f38;
        MEMORY1[06]=s18;        
        MEMORY1[07]=s20;
        MEMORY1[08]=s10; 
//+====================+        
        MEMORY2[01]=s38;
        MEMORY2[02]=s48;
        MEMORY2[03]=s50;
        MEMORY2[04]=LP1;
        MEMORY2[05]=LP2;      
        MEMORY2[06]=s28;
        MEMORY2[07]=s30;
        MEMORY2[08]=s48;
        MEMORY2[09]=s58;
        MEMORY2[10]=s60;
        MEMORY2[11]=s68;
        MEMORY2[00]=Time[1];
for (ii=0; ii<=127; ii++)
        MEMORY3[ii]=list[ii];   
        T0=Time[0];
//+--- ###################+
}
}
//XXXXXXX main cycle done XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+ 
return(0);  
} 
//+-----------------------------------------+ 
int IntPortion (double param) 
{ 
if (param > 0) return (MathFloor (param)); 
if (param < 0) return (MathCeil  (param)); 
return (0.0); 
} 
//+-----------------------------------------+

Comments