153 lines
8.7 KiB
Plaintext
153 lines
8.7 KiB
Plaintext
//------------------------------------------------------------------
|
|
#property copyright "© mladen, 2020"
|
|
#property link "mladenfx@gmail.com"
|
|
#property version "1.00"
|
|
//------------------------------------------------------------------
|
|
#property indicator_separate_window
|
|
#property indicator_buffers 2
|
|
#property indicator_plots 1
|
|
#property indicator_label1 "Reflex"
|
|
#property indicator_type1 DRAW_COLOR_LINE
|
|
#property indicator_color1 clrDodgerBlue,clrCoral
|
|
#property indicator_width1 2
|
|
|
|
//
|
|
//---
|
|
//
|
|
|
|
input int inpReflexPeriod = 50; // Reflex period
|
|
double val[],valc[];
|
|
|
|
//------------------------------------------------------------------
|
|
//
|
|
//------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
|
|
int OnInit()
|
|
{
|
|
SetIndexBuffer(0,val ,INDICATOR_DATA);
|
|
SetIndexBuffer(1,valc ,INDICATOR_COLOR_INDEX);
|
|
|
|
iReflex.OnInit(inpReflexPeriod);
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
IndicatorSetString(INDICATOR_SHORTNAME,"Reflex ("+(string)inpReflexPeriod+")");
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
//
|
|
//------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
int OnCalculate(const int rates_total,
|
|
const int prev_calculated,
|
|
const datetime &time[],
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &low[],
|
|
const double &close[],
|
|
const long &tick_volume[],
|
|
const long &volume[],
|
|
const int &spread[])
|
|
{
|
|
int limit = MathMax(prev_calculated-1,0);
|
|
for(int i=limit; i<rates_total && !_StopFlag; i++)
|
|
{
|
|
val[i] = iReflex.OnCalculate((i>0 ? (close[i]+close[i-1])/2 : close[i]),i,rates_total);
|
|
valc[i] = (i>0) ? val[i]>val[i-1] ? 0 : val[i]<val[i-1] ? 1 : 0 : 0;
|
|
}
|
|
return(rates_total);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
//
|
|
//------------------------------------------------------------------
|
|
//
|
|
//
|
|
//
|
|
|
|
class CReflex
|
|
{
|
|
private :
|
|
double m_c1;
|
|
double m_c2;
|
|
double m_c3;
|
|
double m_multi;
|
|
struct sWorkStruct
|
|
{
|
|
double value;
|
|
double ssm;
|
|
double sum;
|
|
double ms;
|
|
};
|
|
sWorkStruct m_array[];
|
|
int m_arraySize;
|
|
int m_period;
|
|
|
|
public :
|
|
CReflex() : m_c1(1), m_c2(1), m_c3(1), m_arraySize(-1) { }
|
|
~CReflex() { }
|
|
|
|
//
|
|
//---
|
|
//
|
|
|
|
void OnInit(int period)
|
|
{
|
|
m_period = (period>1) ? period : 1;
|
|
|
|
double a1 = MathExp(-1.414*M_PI/m_period);
|
|
double b1 = 2.0*a1*MathCos(1.414*M_PI/m_period);
|
|
m_c2 = b1;
|
|
m_c3 = -a1*a1;
|
|
m_c1 = 1.0 - m_c2 - m_c3;
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
m_multi = 1; for (int k=1; k<m_period; k++) m_multi += (k+1);
|
|
}
|
|
double OnCalculate(double value, int i, int bars)
|
|
{
|
|
if (m_arraySize<bars) m_arraySize=ArrayResize(m_array,bars+500);
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
m_array[i].value = value;
|
|
if (i>1)
|
|
m_array[i].ssm = m_c1*(m_array[i].value+m_array[i-1].value)/2.0 + m_c2*m_array[i-1].ssm + m_c3*m_array[i-2].ssm;
|
|
else m_array[i].ssm = value;
|
|
if (i>m_period)
|
|
m_array[i].sum = m_array[i-1].sum + m_array[i].ssm - m_array[i-m_period].ssm;
|
|
else
|
|
{
|
|
m_array[i].sum = m_array[i].ssm;
|
|
for (int k=1; k<m_period && (i-k)>=0; k++) m_array[i].sum += m_array[i-k].ssm;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
double slope = (i>=m_period) ? (m_array[i-m_period].ssm - m_array[i].ssm)/m_period : 0;
|
|
double sum = m_period*m_array[i].ssm+m_multi*slope-m_array[i].sum;
|
|
sum /= m_period;
|
|
|
|
m_array[i].ms = (i>0) ? 0.04 * sum*sum+0.96*m_array[i-1].ms : 0;
|
|
return (m_array[i].ms!=0 ? sum/MathSqrt(m_array[i].ms) : 0);
|
|
}
|
|
};
|
|
CReflex iReflex; |