//+------------------------------------------------------------------+ //| AbsoluteStrength.mq5 | //| Copyright 2010, Miklós Kiss | //| http://mikki.hu | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, Miklós Kiss" #property link "http://mikki.hu" #property version "1.00" #property indicator_separate_window #property indicator_buffers 8 #property indicator_plots 4 //--- plot Bulls #property indicator_label1 "Bulls" #property indicator_type1 DRAW_LINE #property indicator_color1 CornflowerBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Bears #property indicator_label2 "Bears" #property indicator_type2 DRAW_LINE #property indicator_color2 OrangeRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot SignalBulls #property indicator_label3 "SignalBulls" #property indicator_type3 DRAW_LINE #property indicator_color3 DeepSkyBlue #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot SignalBears #property indicator_label4 "SignalBears" #property indicator_type4 DRAW_LINE #property indicator_color4 Orange #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- input parameters input int Length = 10; input int Smooth = 5; input int Signal = 5; input int MA_Method = 3; input int MA_Price = 0; //0-C 1-O 2-H 3-L 4-Md 5-Tp 6-WghC, Md(HL/2)4,Tp(HLC/3)5,Wgh(HLCC/4)6 input int AbS_Mode = 0; //--- indicator buffers double Bulls[]; double Bears[]; double AvgBulls[]; double AvgBears[]; double SmthBulls[]; double SmthBears[]; double SigBulls[]; double SigBears[]; bool UseOBOSLevels = false; double OverBoughtL = 80; // OverBought Level double OverSoldL = 20; // OverSold Level int MaxBarsToCount = 300; // was 1500 int BarsToDraw; int MA_Handle; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, SmthBulls, INDICATOR_DATA); //BLUE BOLD SetIndexBuffer(1, SmthBears, INDICATOR_DATA); //ORENGE BOLD SetIndexBuffer(2, SigBulls, INDICATOR_DATA); //BLUE thin SetIndexBuffer(3, SigBears, INDICATOR_DATA); //ORANGE thin SetIndexBuffer(4, Bulls, INDICATOR_CALCULATIONS); SetIndexBuffer(5, Bears, INDICATOR_CALCULATIONS); SetIndexBuffer(6, AvgBulls, INDICATOR_CALCULATIONS); SetIndexBuffer(7, AvgBears, INDICATOR_CALCULATIONS); //--- string AbS_Mode_Str; switch(AbS_Mode) { case 0 : AbS_Mode_Str = "RSImode"; case 1 : AbS_Mode_Str = "STOmode"; break; default: AbS_Mode_Str = "ADXmode"; break; } string short_name = "AbsStr(" + IntegerToString(Length) + "," + IntegerToString(Smooth) + "," + IntegerToString(Signal) + "," + IntegerToString(MA_Method) + "," + AbS_Mode_Str + ")"; IndicatorSetString(INDICATOR_SHORTNAME, short_name); MA_Handle = iMA(Symbol(), Period(), 1, 0, MODE_SMA, MA_Price); return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { ArraySetAsSeries(time, false); ArraySetAsSeries(open, false); ArraySetAsSeries(high, false); ArraySetAsSeries(low, false); ArraySetAsSeries(close, false); if (rates_total < Length + Smooth + Signal) return(0); int pos; if (prev_calculated > 1) pos = prev_calculated - 1; else { pos = Length + Smooth + Signal; for (int i = 1; i < Length + Smooth + Signal; i++) { Bulls[i] = 0; Bears[i] = 0; AvgBulls[i] = 0; AvgBears[i] = 0; SmthBulls[i] = 0; SmthBears[i] = 0; SigBulls[i] = 0; SigBears[i] = 0; } } if (rates_total - pos > MaxBarsToCount) pos = rates_total - MaxBarsToCount; double Price1, Price2, smax, smin; for (int bar = pos; bar < rates_total; bar++) { double ma[]; CopyBuffer(MA_Handle, 0, rates_total - bar, 2, ma); ArraySetAsSeries(ma, true); Price1 = ma[0]; Price2 = ma[1]; switch (AbS_Mode) { case 0: Bulls[bar] = 0.5 * (MathAbs(Price1 - Price2) + (Price1 - Price2)); Bears[bar] = 0.5 * (MathAbs(Price1 - Price2) - (Price1 - Price2)); break; case 1: smax = high[ArrayMaximum(high, bar - Length, Length)]; smin = low[ArrayMinimum(low, bar - Length, Length)]; Bulls[bar] = Price1 - smin; Bears[bar] = smax - Price1; break; default: Bulls[bar] = 0.5 * (MathAbs(high[bar] - high[bar - 1]) + (high[bar] - high[bar - 1])); Bears[bar] = 0.5 * (MathAbs(low[bar - 1] - low[bar]) + (low[bar - 1] - low[bar])); break; } } for (int bar = pos; bar < rates_total; bar++) { AvgBulls[bar] = iMAOnArrayMQL4(Bulls, 0, Length, 0, MA_Method, rates_total - bar); AvgBears[bar] = iMAOnArrayMQL4(Bears, 0, Length, 0, MA_Method, rates_total - bar); } for (int bar = pos; bar < rates_total; bar++) { SmthBulls[bar] = iMAOnArrayMQL4(AvgBulls, 0, Smooth, 0, MA_Method, rates_total - bar); SmthBears[bar] = iMAOnArrayMQL4(AvgBears, 0, Smooth, 0, MA_Method, rates_total - bar); } for (int bar = pos; bar < rates_total; bar++) { if (UseOBOSLevels) { SigBulls[bar] = OverBoughtL / 100 * (SmthBulls[bar] + SmthBears[bar]); SigBears[bar] = OverSoldL / 100 * (SmthBulls[bar] + SmthBears[bar]); } else { SigBulls[bar] = iMAOnArrayMQL4(SmthBulls, 0, Signal, 0, MA_Method, rates_total - bar); SigBears[bar] = iMAOnArrayMQL4(SmthBears, 0, Signal, 0, MA_Method, rates_total - bar); } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ double iMAOnArrayMQL4(double &array[], int total, int period, int ma_shift, int ma_method, int shift) { double buf[], arr[]; if (total == 0) total = ArraySize(array); if (total > 0 && total <= period) return(0); if (shift > total - period - ma_shift) return(0); switch (ma_method) { case MODE_SMA: { total = ArrayCopy(arr, array, 0, shift + ma_shift, period); if (ArrayResize(buf, total) < 0) return(0); double sum = 0; int i, pos = total - 1; for (i = 1; i < period; i++, pos--) sum += arr[pos]; while (pos >= 0) { sum += arr[pos]; buf[pos] = sum / period; sum -= arr[pos + period - 1]; pos--; } return(buf[0]); } case MODE_EMA: { if (ArrayResize(buf, total) < 0) return(0); double pr = 2.0 / (period + 1); int pos = total - 2; while (pos >= 0) { if (pos == total - 2) buf[pos + 1] = array[pos + 1]; buf[pos] = array[pos] * pr + buf[pos + 1] * (1 - pr); pos--; } return(buf[shift + ma_shift]); } case MODE_SMMA: { if (ArrayResize(buf, total) < 0) return(0); double sum = 0; int i, k, pos; pos = total - period; while (pos >= 0) { if (pos == total - period) { for (i = 0, k = pos; i < period; i++, k++) { sum += array[k]; buf[k] = 0; } } else sum = buf[pos + 1] * (period - 1) + array[pos]; buf[pos] = sum / period; pos--; } return(buf[shift + ma_shift]); } case MODE_LWMA: { if (ArrayResize(buf, total) < 0) return(0); double sum = 0.0, lsum = 0.0; double price; int i, weight = 0, pos = total - 1; for (i = 1; i <= period; i++, pos--) { price = array[pos]; sum += price * i; lsum += price; weight += i; } pos++; i = pos + period; while (pos >= 0) { buf[pos] = sum / weight; if (pos ==0 ) break; pos--; i--; price = array[pos]; sum = sum - lsum + price * period; lsum -= array[i]; lsum += price; } return(buf[shift + ma_shift]); } default: return(0); } return(0); }