//+------------------------------------------------------------------+ //| ProbableTarget.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window //#property indicator_minimum 1 //#property indicator_maximum 10 #property indicator_buffers 10 #property indicator_plots 8 //--- plot targetProfit #property indicator_label1 "Target profit(%)" #property indicator_type1 DRAW_LINE #property indicator_color1 clrGreen #property indicator_style1 STYLE_SOLID #property indicator_width1 2 //--- plot stopLoss #property indicator_label2 "Stop loss(%)" #property indicator_type2 DRAW_LINE #property indicator_color2 clrRed #property indicator_style2 STYLE_SOLID #property indicator_width2 2 //--- plot maxAbsoluteReached #property indicator_label3 "Max absolute(%)" #property indicator_type3 DRAW_LINE #property indicator_color3 clrBrown #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot smaMaxAbsoluteReached #property indicator_label4 "Sma max absolute(%)" #property indicator_type4 DRAW_LINE #property indicator_color4 clrBrown #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- plot maxReachedInBothDirection #property indicator_label5 "Max Reached in both direc(%)" #property indicator_type5 DRAW_LINE #property indicator_color5 clrDodgerBlue #property indicator_style5 STYLE_SOLID #property indicator_width5 1 //--- plot smaMaxReachedInBothDirection #property indicator_label6 "Sma max Reached in both direc(%)" #property indicator_type6 DRAW_LINE #property indicator_color6 clrDodgerBlue #property indicator_style6 STYLE_SOLID #property indicator_width6 1 //--- plot maxReachedInBothDirectionFuzzyMode #property indicator_label7 "Mode max reached in both direct(%)" #property indicator_type7 DRAW_LINE #property indicator_color7 clrDodgerBlue #property indicator_style7 STYLE_SOLID #property indicator_width7 1 //--- plot signDiffInPercent #property indicator_label8 "Load balance from extreme by bar(%)" #property indicator_type8 DRAW_LINE #property indicator_color8 clrChocolate #property indicator_style8 STYLE_SOLID #property indicator_width8 1 //--- plot maxByBarInPercent #property indicator_label9 "Max extreme by bar(%)" #property indicator_type9 DRAW_LINE #property indicator_color9 clrYellow #property indicator_style9 STYLE_SOLID #property indicator_width9 1 //--- plot minByBarInPercent #property indicator_label10 "Min extreme by bar(%)" #property indicator_type10 DRAW_LINE #property indicator_color10 clrYellow #property indicator_style10 STYLE_SOLID #property indicator_width10 1 #include //inputs input double fuzzyFactor = 0.10; input int reachedPeriodLength = 24; input int maxPeriodLength = 24; //--- indicator buffers double maxAbsoluteReachedBuffer[]; double smaMaxAbsoluteReachedBuffer[]; double maxReachedInBothDirectionBuffer[]; double smaMaxReachedInBothDirectionBuffer[]; double maxReachedInBothDirectionFuzzyModeBuffer[]; double signDiffInPercentBuffer[]; double targetProfitBuffer[]; double stopLossBuffer[]; double maxByBarInPercentBuffer[]; double minByBarInPercentBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //chart settings ChartSetInteger(0,CHART_COLOR_BACKGROUND,0); ChartSetInteger(0, CHART_FOREGROUND,16777215); ChartSetInteger(0,CHART_COLOR_CHART_UP,7451452); ChartSetInteger(0,CHART_COLOR_CHART_DOWN,255); ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,7451452); ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,255); ChartSetInteger(0,CHART_COLOR_CHART_LINE,65280); ChartSetInteger(0,CHART_COLOR_GRID,2697513); ChartSetInteger(0,CHART_SHIFT,1); ChartSetInteger(0,CHART_SHOW_ASK_LINE,1); ChartSetInteger(0,CHART_SHOW_BID_LINE,1); ChartSetInteger(0,CHART_SHOW_LAST_LINE,1); ChartSetInteger(0,CHART_SHOW_PERIOD_SEP,1); //--- indicator buffers mapping SetIndexBuffer(0,targetProfitBuffer,INDICATOR_DATA); SetIndexBuffer(1,stopLossBuffer,INDICATOR_DATA); SetIndexBuffer(2,maxAbsoluteReachedBuffer,INDICATOR_DATA); SetIndexBuffer(3,smaMaxAbsoluteReachedBuffer,INDICATOR_DATA); SetIndexBuffer(4,maxReachedInBothDirectionBuffer,INDICATOR_DATA); SetIndexBuffer(5,smaMaxReachedInBothDirectionBuffer,INDICATOR_DATA); SetIndexBuffer(6,maxReachedInBothDirectionFuzzyModeBuffer,INDICATOR_DATA); SetIndexBuffer(7,signDiffInPercentBuffer,INDICATOR_DATA); SetIndexBuffer(8,maxByBarInPercentBuffer,INDICATOR_DATA); SetIndexBuffer(9,minByBarInPercentBuffer,INDICATOR_DATA); // as series ArraySetAsSeries(maxAbsoluteReachedBuffer,true); ArraySetAsSeries(smaMaxAbsoluteReachedBuffer,true); ArraySetAsSeries(maxReachedInBothDirectionBuffer,true); ArraySetAsSeries(smaMaxReachedInBothDirectionBuffer,true); ArraySetAsSeries(maxReachedInBothDirectionFuzzyModeBuffer,true); ArraySetAsSeries(signDiffInPercentBuffer,true); ArraySetAsSeries(targetProfitBuffer,true); ArraySetAsSeries(stopLossBuffer,true); ArraySetAsSeries(maxByBarInPercentBuffer,true); ArraySetAsSeries(minByBarInPercentBuffer,true); //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 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[]) { //--- convert to series ArraySetAsSeries(open,true); ArraySetAsSeries(close,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); if(rates_total= maxLength) { int shift = i - maxLength; double smaMaxAbsoluteReachedSumatory = 0; double smaMaxReachedInBothDirectionSumatory = 0; int occurrences []; ArrayResize(occurrences,reachedPeriodLength); ArrayFill(occurrences,0,reachedPeriodLength,0); double fuzzyValue []; ArrayResize(fuzzyValue,reachedPeriodLength); ArrayFill(fuzzyValue,0,reachedPeriodLength,-1); for(int j = shift; j< shift + maxLength && !IsStopped(); j++) { if(j < shift + maxPeriodLength) { smaMaxAbsoluteReachedSumatory += maxAbsoluteReachedBuffer[j]; } if(j < shift + reachedPeriodLength) { smaMaxReachedInBothDirectionSumatory += maxReachedInBothDirectionBuffer[j]; fuzzyValue[j - shift] = getRangeFuzzy(maxReachedInBothDirectionBuffer[j]); occurrences[j - shift] = countOccurrences(fuzzyValue, fuzzyValue[j - shift]); } } smaMaxAbsoluteReachedBuffer[shift] = smaMaxAbsoluteReachedSumatory / maxPeriodLength ; smaMaxReachedInBothDirectionBuffer[shift] = smaMaxReachedInBothDirectionSumatory / reachedPeriodLength ; int maxIndex = ArrayMaximum(occurrences, 0, WHOLE_ARRAY); maxReachedInBothDirectionFuzzyModeBuffer[shift] = maxIndex != -1 ? fuzzyValue[maxIndex] : -1; targetProfitBuffer[shift] = getTargetInPercent(shift); stopLossBuffer[shift] = getStopLossPercent(shift); } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double absDiffInPercent(const double initExtreme, const double endExtreme) { return MathAbs(((endExtreme - initExtreme) * 100) / initExtreme); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double getTargetInPercent(int index) { if(maxReachedInBothDirectionFuzzyModeBuffer[index] > maxReachedInBothDirectionBuffer[index] && smaMaxReachedInBothDirectionBuffer[index] > maxReachedInBothDirectionBuffer[index]) return maxReachedInBothDirectionFuzzyModeBuffer[index]; double minTmp = MathMin(smaMaxReachedInBothDirectionBuffer[index], maxReachedInBothDirectionFuzzyModeBuffer[index]); double min = MathMin(minTmp, maxReachedInBothDirectionBuffer[index]); double smaFactor = smaMaxReachedInBothDirectionBuffer[index] != 0 ? MathAbs(1- (maxReachedInBothDirectionBuffer[index] / smaMaxReachedInBothDirectionBuffer[index])) <= 0.25 : false; double modeFactor = maxReachedInBothDirectionFuzzyModeBuffer[index] != 0 ? MathAbs(1- (maxReachedInBothDirectionBuffer[index] / maxReachedInBothDirectionFuzzyModeBuffer[index])) <= 0.25 : false; double target = (smaFactor || modeFactor) ? maxReachedInBothDirectionBuffer[index] : min; return target; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double getStopLossPercent(int index) { double stopLoss = MathMax(maxAbsoluteReachedBuffer[index], smaMaxAbsoluteReachedBuffer[index]); return stopLoss; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class ReachedInfo { double maxAbsoluteReached; double maxAboveReached; double maxBelowReached; double signDiffInPercent; public: ReachedInfo(double maxAbsoluteReachedParam, double maxAboveReachedParam, double maxBelowReachedParam, double signDiffInPercentParam) { maxAbsoluteReached = maxAbsoluteReachedParam; maxAboveReached = maxAboveReachedParam; maxBelowReached = maxBelowReachedParam; signDiffInPercent = signDiffInPercentParam; }; ReachedInfo(ReachedInfo &reachedInfo) { maxAbsoluteReached = reachedInfo.getMaxAbsoluteReached(); maxAboveReached = reachedInfo.getMaxAboveReached(); maxBelowReached = reachedInfo.getMaxBelowReached(); signDiffInPercent = reachedInfo.getSignDiffInPercent(); }; void setMaxAbsoluteReached(double maxAbsoluteReachedParam) { maxAbsoluteReached = maxAbsoluteReachedParam; } void setMaxAboveReached(double maxAboveReachedParam) { maxAboveReached = maxAboveReachedParam; } void setMaxBelowReached(double maxBelowReachedParam) { maxBelowReached = maxBelowReachedParam; } void setSignDiffInPercent(double signDiffInPercentParam) { signDiffInPercent = signDiffInPercentParam; } double getMaxAbsoluteReached() { return maxAbsoluteReached; } double getMaxAboveReached() { return maxAboveReached; } double getMaxBelowReached() { return maxBelowReached; } double getSignDiffInPercent() { return signDiffInPercent; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ ReachedInfo getReachedInfo(int index, const double &open[], const double &high[], const double &low[]) { double init = open[index]; double lowInit = low[index]; double highInit = high[index]; double maxAbsoluteReached = MathMax(absDiffInPercent(init, highInit), absDiffInPercent(init, lowInit)); double maxAboveReached = absDiffInPercent(init, highInit); double maxBelowReached = absDiffInPercent(init, lowInit); double signDiffInPercent = absDiffInPercent(init, highInit) - absDiffInPercent(init, lowInit); int forLength = MathMax(reachedPeriodLength, maxPeriodLength); for(int i=index + 1; i init) { absDiffInPercentTmp = absDiffInPercent(init, high[i]); signDiffInPercent = signDiffInPercent + absDiffInPercentTmp; if(absDiffInPercentTmp > maxAboveReached && i < reachedPeriodLength + index) maxAboveReached = absDiffInPercentTmp; if(absDiffInPercentTmp > maxAbsoluteReached && i < maxPeriodLength + index) maxAbsoluteReached = absDiffInPercentTmp; } if(low[i] < init) { absDiffInPercentTmp = absDiffInPercent(init, low[i]); signDiffInPercent = signDiffInPercent - absDiffInPercentTmp; if(absDiffInPercentTmp > maxBelowReached && i < reachedPeriodLength + index) maxBelowReached = absDiffInPercentTmp; if(absDiffInPercentTmp > maxAbsoluteReached && i < maxPeriodLength + index) maxAbsoluteReached = absDiffInPercentTmp; } } ReachedInfo reachedInfo(maxAbsoluteReached, maxAboveReached, maxBelowReached, signDiffInPercent); return reachedInfo; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double getRangeFuzzy(double value) { int tmp = MathRound(value / fuzzyFactor); return tmp > 0 ? tmp * fuzzyFactor : fuzzyFactor; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int countOccurrences(const double &array[], const double condition) { int cnt=0; for(int i=0; i