-
for(int i = limit; i < rates_total; i++) int i_bar_shift = iBarShift(Symbol(), inpTimeFrame, time[i], false); buffer[i] = arr_ma[0];
You did not set the time[] array and your buffer[] to match your loop direction. In MT5, you must set the direction.To define the indexing direction in the time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[] arrays, call the ArrayGetAsSeries() function. In order not to depend on defaults, call the ArraySetAsSeries() function for the arrays to work with.
Event Handling / OnCalculate - Reference on algorithmic/automated trading language for MetaTrader 5 -
int limit = rates_total - prev_calculated; if(prev_calculated > 0) limit++; for(int i = limit; i < rates_total; i++)
First run, prev_calculated is zero, therefor limit is rates_total+1 and your loop does nothing.
How to do your lookbacks correctly #9 — #14 & #19 (2016)
Hi WIlliam, Thanks for your help, greatly appreciated.
I've set my time to ArraySetAsSeries(time, true) now. The Buffer was already set to ArraySeries 'true' at the top in the OnInit() funciton, was that what you were refering to?
I see what you mean about the limit never being smaller than rates_total;
If I understand the rest of your post correctly; these 2 components are counting in different directions is that the case?
Thanks
if(prev_calculated > 0) limit++; //for loop for(int i = limit; i < rates_total; i++) {
Hi
just starting out with mq5, got an version of HTF average working, leaving it here for anybody else looking for such
also an implementation with various average types (not using iMA and built ins)
just starting out with mq5, got an version of HTF average working, leaving it here for anybody else looking for such
//+------------------------------------------------------------------+ //| CB-.mq5 | //| Chris | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Chris" #property link "https://www.mql5.com" #property version "4.01" #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_color1 clrDodgerBlue #property indicator_label1 "MTF MA (Manual)" #property indicator_style1 STYLE_SOLID #property indicator_type1 DRAW_LINE #property indicator_width1 2 input int inpMAPeriod = 50; input ENUM_MA_METHOD inpMAMethod = MODE_EMA; input ENUM_APPLIED_PRICE inpAppliedPrice = PRICE_CLOSE; input ENUM_TIMEFRAMES inpTimeFrame = PERIOD_H4; double buffer[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, buffer, INDICATOR_DATA); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); 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 htf_bars_available = (int)SeriesInfoInteger(Symbol(), inpTimeFrame, SERIES_BARS_COUNT); if(htf_bars_available < inpMAPeriod) { PlotIndexSetString(0, PLOT_LABEL, "Waiting for " + EnumToString(inpTimeFrame) + " data..."); return(0); } PlotIndexSetString(0, PLOT_LABEL, "MTF MA (Manual)"); int limit; if(prev_calculated == 0) limit = 0; else limit = prev_calculated - 1; for(int i = limit; i < rates_total; i++) { int htf_shift = iBarShift(Symbol(), inpTimeFrame, time[i]); int num_bars_to_copy = inpMAPeriod; int start_pos_to_copy = htf_shift + 1; double htf_close_prices[]; ArraySetAsSeries(htf_close_prices, true); if(CopyClose(Symbol(), inpTimeFrame, start_pos_to_copy, num_bars_to_copy, htf_close_prices) == num_bars_to_copy) { double ma_value = CalculateEMA(htf_close_prices, inpMAPeriod); buffer[i] = ma_value; } else { if(i > 0) buffer[i] = buffer[i - 1]; else buffer[i] = 0.0; } } return(rates_total); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateEMA(const double &prices[], int period) { if(ArraySize(prices) < period) return 0.0; double multiplier = 2.0 / (period + 1.0); double ema = 0; for(int i = period - 1; i >= 0; i--) { ema += prices[i]; } ema /= period; for(int i = period - 2; i >= 0; i--) { ema = (prices[i] - ema) * multiplier + ema; } return ema; } //+------------------------------------------------------------------+
also an implementation with various average types (not using iMA and built ins)
//+------------------------------------------------------------------+ //| CB-.mq5 | //| Chris | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Chris" #property link "https://www.mql5.com" #property version "5.04" #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_color1 clrDodgerBlue #property indicator_label1 "MTF MA" #property indicator_style1 STYLE_SOLID #property indicator_type1 DRAW_LINE #property indicator_width1 2 enum ENUM_CUSTOM_MA_METHOD { CUSTOM_MODE_SMA, CUSTOM_MODE_EMA, CUSTOM_MODE_SMMA, CUSTOM_MODE_WMA, CUSTOM_MODE_DEMA, CUSTOM_MODE_TEMA, CUSTOM_MODE_HMA, CUSTOM_MODE_VWMA }; input int inpMAPeriod = 50; input ENUM_CUSTOM_MA_METHOD inpMAMethod = CUSTOM_MODE_HMA; input ENUM_TIMEFRAMES inpTimeFrame = PERIOD_H4; double buffer[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateSMA(const double &prices[], int period); double CalculateWMA(const double &prices[], int period); double CalculateEMA(const double &prices[], int period); double CalculateDEMA(const double &prices[], int period); double CalculateTEMA(const double &prices[], int period); double CalculateHMA(const double &prices[], int period); //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, buffer, INDICATOR_DATA); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0); 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 required_bars = inpMAPeriod * 3; int htf_bars_available = (int)SeriesInfoInteger(Symbol(), inpTimeFrame, SERIES_BARS_COUNT); if(htf_bars_available < required_bars) { PlotIndexSetString(0, PLOT_LABEL, "Waiting for " + EnumToString(inpTimeFrame) + " data..."); return(0); } PlotIndexSetString(0, PLOT_LABEL, "MTF MA"); int limit; if(prev_calculated == 0) limit = 0; else limit = prev_calculated - 1; for(int i = limit; i < rates_total; i++) { if(inpTimeFrame == Period() && i < required_bars) { buffer[i] = 0.0; continue; } int htf_shift = iBarShift(Symbol(), inpTimeFrame, time[i]); int start_pos; if(inpTimeFrame == Period()) start_pos = htf_shift; else start_pos = htf_shift + 1; double htf_prices[]; ArraySetAsSeries(htf_prices, true); long htf_volumes[]; if(inpMAMethod == CUSTOM_MODE_VWMA) { ArraySetAsSeries(htf_volumes, true); } int copied_prices = CopyClose(Symbol(), inpTimeFrame, start_pos, required_bars, htf_prices); bool data_ready = (copied_prices > 0); if(data_ready && inpMAMethod == CUSTOM_MODE_VWMA) { data_ready = (CopyTickVolume(Symbol(), inpTimeFrame, start_pos, inpMAPeriod, htf_volumes) > 0); } if(data_ready) { double ma_value = 0; switch(inpMAMethod) { case CUSTOM_MODE_SMA: ma_value = CalculateSMA(htf_prices, inpMAPeriod); break; case CUSTOM_MODE_EMA: ma_value = CalculateEMA(htf_prices, inpMAPeriod); break; case CUSTOM_MODE_SMMA: ma_value = CalculateSMMA(htf_prices, inpMAPeriod); break; case CUSTOM_MODE_WMA: ma_value = CalculateWMA(htf_prices, inpMAPeriod); break; case CUSTOM_MODE_DEMA: ma_value = CalculateDEMA(htf_prices, inpMAPeriod); break; case CUSTOM_MODE_TEMA: ma_value = CalculateTEMA(htf_prices, inpMAPeriod); break; case CUSTOM_MODE_HMA: ma_value = CalculateHMA(htf_prices, inpMAPeriod); break; case CUSTOM_MODE_VWMA: ma_value = CalculateVWMA(htf_prices, htf_volumes, inpMAPeriod); break; } buffer[i] = ma_value; } else { if(i > 0) buffer[i] = buffer[i - 1]; else buffer[i] = 0.0; } } return(rates_total); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CalculateMA_Series(const double &src[], int period, ENUM_CUSTOM_MA_METHOD method, double &dest[]) { int src_size = ArraySize(src); int dest_size = src_size - period + 1; if(dest_size <= 0) return; ArrayResize(dest, dest_size); ArraySetAsSeries(dest, true); for(int i = 0; i < dest_size; i++) { double temp_prices[]; ArrayCopy(temp_prices, src, 0, i, period); ArraySetAsSeries(temp_prices, true); switch(method) { case CUSTOM_MODE_EMA: dest[i] = CalculateEMA(temp_prices, period); break; case CUSTOM_MODE_WMA: dest[i] = CalculateWMA(temp_prices, period); break; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateSMA(const double &prices[], int period) { if(ArraySize(prices) < period) return 0.0; double sum = 0; for(int i = 0; i < period; i++) sum += prices[i]; return sum / period; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateWMA(const double &prices[], int period) { if(ArraySize(prices) < period) return 0.0; double sum_weights = 0, sum_weighted_prices = 0; for(int i = 0; i < period; i++) { double weight = period - i; sum_weighted_prices += prices[i] * weight; sum_weights += weight; } return (sum_weights > 0) ? sum_weighted_prices / sum_weights : 0.0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateEMA(const double &prices[], int period) { if(ArraySize(prices) < period) return 0.0; double multiplier = 2.0 / (period + 1.0); double ema = CalculateSMA(prices, period); for(int i = ArraySize(prices) - period - 1; i >= 0; i--) { ema = (prices[i] - ema) * multiplier + ema; } return ema; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateSMMA(const double &prices[], int period) { if(ArraySize(prices) < period) return 0.0; double smma = CalculateSMA(prices, period); for(int i = period - 2; i >= 0; i--) { smma = (smma * (period - 1) + prices[i]) / period; } return smma; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateDEMA(const double &prices[], int period) { if(ArraySize(prices) < 2 * period - 1) return 0.0; double ema1_series[]; CalculateMA_Series(prices, period, CUSTOM_MODE_EMA, ema1_series); if(ArraySize(ema1_series) == 0) return 0.0; double ema2 = CalculateEMA(ema1_series, period); return 2 * ema1_series[0] - ema2; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateTEMA(const double &prices[], int period) { if(ArraySize(prices) < 3 * period - 2) return 0.0; double ema1_series[], ema2_series[]; CalculateMA_Series(prices, period, CUSTOM_MODE_EMA, ema1_series); if(ArraySize(ema1_series) == 0) return 0.0; CalculateMA_Series(ema1_series, period, CUSTOM_MODE_EMA, ema2_series); if(ArraySize(ema2_series) == 0) return 0.0; double ema3 = CalculateEMA(ema2_series, period); return 3 * ema1_series[0] - 3 * ema2_series[0] + ema3; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateHMA(const double &prices[], int period) { if(period <= 1) return prices[0]; int period_half = period / 2; int period_sqrt = (int)sqrt(period); if(ArraySize(prices) < period + period_sqrt) return 0.0; double wma_half_series[]; CalculateMA_Series(prices, period_half, CUSTOM_MODE_WMA, wma_half_series); double wma_full_series[]; CalculateMA_Series(prices, period, CUSTOM_MODE_WMA, wma_full_series); int size_half = ArraySize(wma_half_series); int size_full = ArraySize(wma_full_series); if(size_full == 0) return 0.0; double diff_series[]; ArrayResize(diff_series, size_full); ArraySetAsSeries(diff_series, true); int offset = size_half - size_full; for(int i = 0; i < size_full; i++) { diff_series[i] = 2 * wma_half_series[i + offset] - wma_full_series[i]; } return CalculateWMA(diff_series, period_sqrt); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalculateVWMA(const double &prices[], const long &volumes[], int period) { if(ArraySize(prices) < period || ArraySize(volumes) < period) return 0.0; double sum_price_vol = 0, sum_vol = 0; for(int i = 0; i < period; i++) { sum_price_vol += prices[i] * volumes[i]; sum_vol += (double)volumes[i]; } return (sum_vol > 0) ? sum_price_vol / sum_vol : 0.0; } //+------------------------------------------------------------------+

You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hi,
I've been coding in MQL4 for a while, and am 'reasonably' good at it. Recently I have switched to MQL5 and having difficulty converting my higher timeframe indicators over.
This is a Higher Timeframe Moving average. I think the issue is I am referencing the shift from the curent timeframe but I cannot see how to fix it.
Any help you could offer would be greatly appreacisted as really racking my brains with this.
This is what it looks like on the chart:
https://screenrec.com/share/vDUFsz6J31
Thanks in Advance: