#property copyright "Maku"
#property link "http://www.mql5.com"
#property version "1.00"
#property strict
// Chart settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
// Each indicator settings
#property indicator_type1 DRAW_LINE
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_color1 clrPink
// Input parameters
input int gPeriod = 25; // Period of WMA
// Indicator buffers
double gWmaBuffer[];
/**
* [Utility]
* How many candles should be re-calculated.
*/
int changedBars(int rates_total, int prev_calculated) {
if (prev_calculated == 0) {
return rates_total;
}
// The latest bar should be updated, so add 1.
return rates_total - prev_calculated + 1;
}
int OnInit() {
if (gPeriod <= 0) {
Alert("Period must be larger than 0");
return INIT_PARAMETERS_INCORRECT;
}
SetIndexBuffer(0, gWmaBuffer);
SetIndexLabel(0, StringFormat("WMA(%i)", gPeriod));
IndicatorShortName(StringFormat("WMA(%i)", gPeriod));
return INIT_SUCCEEDED;
}
/**
* Calculates WMA. The size of vals must be equal or larger than index + count.
*/
double calcWma(const double& vals[], int index, int count) {
double sum = 0;
for (int i = 0; i < count; ++i) {
sum += vals[i + index] * (count - i);
}
return (sum * 2) / (count * (count + 1));
}
int updateWma(const double& prices[], int rates_total, int prev_calculated) {
// Is there enough amount of price data?
if (rates_total < gPeriod) {
return 0;
}
int changed = changedBars(rates_total, prev_calculated);
int count = MathMin(changed, rates_total - gPeriod + 1);
for (int i = 0; i < count; ++i) {
gWmaBuffer[i] = calcWma(prices, i, gPeriod);
}
// Print("Latest WMA = ", gWmaBuffer[0]);
return rates_total;
}
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[]) {
// PlaySound("tick.wav");
return updateWma(close, rates_total, prev_calculated);
}