4kk4.MQL5/Indicators/KG Moving Average.mq5

222 lines
7.4 KiB
MQL5
Raw Permalink Normal View History

2026-04-27 07:00:02 +07:00
#property copyright "4kk4"
#property link "https://www.mql5.com/en/users/4kk4"
#property description "KG Moving Average"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_type1 DRAW_LINE
#property indicator_color1 Red
#property indicator_width1 2
//--- input parameters
input ENUM_TIMEFRAMES InpTimeFrame = PERIOD_CURRENT; // Timeframe Terapan
input int InpMAPeriod = 60 ; // Period
input int InpMAShift = 0; // Shift
input ENUM_MA_METHOD InpMAMethod = MODE_SMA ; // Method
input ENUM_APPLIED_PRICE InpMAPrice= PRICE_CLOSE ; // Method
//--- indicator buffers
double ExtLineBuffer[];
int MAPeriod; //= PeriodSeconds(InpMAPeriod) / (PeriodSeconds() ); // Period
//+------------------------------------------------------------------+
//| simple moving average |
//+------------------------------------------------------------------+
void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[])
{
int i,limit;
//--- first calculation or number of bars was changed
if(prev_calculated==0)// first calculation
{
limit=MAPeriod+begin;
//--- set empty value for first limit bars
for(i=0;i<limit-1;i++)
ExtLineBuffer[i]=0.0;
//--- calculate first visible value
double firstValue=0;
for(i=begin;i<limit;i++)
firstValue+=price[i];
firstValue/=MAPeriod;
ExtLineBuffer[limit-1]=firstValue;
}
else
limit=prev_calculated-1;
//--- main loop
for(i=limit;i<rates_total && !IsStopped();i++)
ExtLineBuffer[i]=ExtLineBuffer[i-1]+(price[i]-price[i-MAPeriod])/MAPeriod;
//---
}
//+------------------------------------------------------------------+
//| exponential moving average |
//+------------------------------------------------------------------+
void CalculateEMA(int rates_total,int prev_calculated,int begin,const double &price[])
{
int i,limit;
double SmoothFactor=2.0/(1.0+MAPeriod);
//--- first calculation or number of bars was changed
if(prev_calculated==0)
{
limit=MAPeriod+begin;
ExtLineBuffer[begin]=price[begin];
for(i=begin+1;i<limit;i++)
ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor);
}
else
limit=prev_calculated-1;
//--- main loop
for(i=limit;i<rates_total && !IsStopped();i++)
ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor);
//---
}
//+------------------------------------------------------------------+
//| linear weighted moving average |
//+------------------------------------------------------------------+
void CalculateLWMA(int rates_total,int prev_calculated,int begin,const double &price[])
{
int i,limit;
static int weightsum;
double sum;
//--- first calculation or number of bars was changed
if(prev_calculated==0)
{
weightsum=0;
limit=MAPeriod+begin;
//--- set empty value for first limit bars
for(i=0;i<limit;i++)
ExtLineBuffer[i]=0.0;
//--- calculate first visible value
double firstValue=0;
for(i=begin;i<limit;i++)
{
int k=i-begin+1;
weightsum+=k;
firstValue+=k*price[i];
}
firstValue/=(double)weightsum;
ExtLineBuffer[limit-1]=firstValue;
}
else
limit=prev_calculated-1;
//--- main loop
for(i=limit;i<rates_total && !IsStopped();i++)
{
sum=0;
for(int j=0;j<MAPeriod;j++)
sum+=(MAPeriod-j)*price[i-j];
ExtLineBuffer[i]=sum/weightsum;
}
//---
}
//+------------------------------------------------------------------+
//| smoothed moving average |
//+------------------------------------------------------------------+
void CalculateSmoothedMA(int rates_total,int prev_calculated,int begin,const double &price[])
{
int i,limit;
//--- first calculation or number of bars was changed
if(prev_calculated==0)
{
limit=MAPeriod+begin;
//--- set empty value for first limit bars
for(i=0;i<limit-1;i++)
ExtLineBuffer[i]=0.0;
//--- calculate first visible value
double firstValue=0;
for(i=begin;i<limit;i++)
firstValue+=price[i];
firstValue/=MAPeriod;
ExtLineBuffer[limit-1]=firstValue;
}
else
limit=prev_calculated-1;
//--- main loop
for(i=limit;i<rates_total && !IsStopped();i++)
ExtLineBuffer[i]=(ExtLineBuffer[i-1]*(MAPeriod-1)+price[i])/MAPeriod;
//---
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA);
//--- set accuracy
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- sets first bar from what index will be drawn
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod);
//---- line shifts when drawing
PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift);
//--- name for DataWindow
string short_name="unknown ma";
switch(InpMAMethod)
{
case MODE_EMA :
short_name="EMA";
break;
case MODE_LWMA :
short_name="LWMA";
break;
case MODE_SMA :
short_name="SMA";
break;
case MODE_SMMA :
short_name="SMMA";
break;
}
int period = PeriodSeconds()/60;
if(period == 10080)
period = 7200; //mingguan
if(period == 40320)
period = 28800; //bulanan
if(period == 161280)
period = 115200;//4 bulanan
if(period == 483840)
period = 345600;//tahunan
MAPeriod = (InpMAPeriod) / period; // Period
IndicatorSetString(INDICATOR_SHORTNAME,short_name+"("+string(MAPeriod)+")");
//---- sets drawing line empty value--
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---- initialization done
}
//+------------------------------------------------------------------+
//| Moving Average |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
//--- check for bars count
if(rates_total<MAPeriod-1+begin)
return(0);// not enough bars for calculation
//--- first calculation or number of bars was changed
if(prev_calculated==0)
ArrayInitialize(ExtLineBuffer,0);
//--- sets first bar from what index will be draw
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod-1+begin);
//--- calculation
switch(InpMAMethod)
{
case MODE_EMA:
CalculateEMA(rates_total,prev_calculated,begin,price);
break;
case MODE_LWMA:
CalculateLWMA(rates_total,prev_calculated,begin,price);
break;
case MODE_SMMA:
CalculateSmoothedMA(rates_total,prev_calculated,begin,price);
break;
case MODE_SMA:
CalculateSimpleMA(rates_total,prev_calculated,begin,price);
break;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+