//+------------------------------------------------------------------+ //| Fuzzy_Envelopes.mq5 | //| maksvp | //| "http://www.mql5.com" | //+------------------------------------------------------------------+ #property copyright "maksvp" #property link "http://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_minimum -1.4 // Setting fractional values #property indicator_maximum 1.4 // Expert Advisors wizard ignores fractional parts for some reason #property indicator_buffers 14 // Changing the value from 7 to 12 (5 more buffers have been added) #property indicator_plots 4 //--- plot Result #property indicator_label1 "Result" #property indicator_type1 DRAW_COLOR_HISTOGRAM #property indicator_color1 Red,DarkOrange,Gold,GreenYellow,Lime #property indicator_style1 STYLE_SOLID #property indicator_width1 3 //--- plot Rule1 #property indicator_label2 "Rule1" #property indicator_type2 DRAW_LINE #property indicator_color2 Red #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot Rule2 #property indicator_label3 "Rule2" #property indicator_type3 DRAW_LINE #property indicator_color3 Blue #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot Signal #property indicator_label4 "Signal" #property indicator_type4 DRAW_COLOR_HISTOGRAM2 #property indicator_color4 Red,Blue #property indicator_style4 STYLE_SOLID #property indicator_width4 3 //--- 1. Editing the Input parameters. Adding the lists of smoothing methods // and calculated prices. input string txt1="----------"; input int Period_Fast=8; input ENUM_MA_METHOD Method_Fast=MODE_SMA; /*Smoothing method*/ //moving average smoothing method input ENUM_APPLIED_PRICE Price_Fast=PRICE_CLOSE; input double Dev_Fast=0.08; input string txt2="----------"; input int Period_Slow=32; input ENUM_MA_METHOD Method_Slow = MODE_SMA; input ENUM_APPLIED_PRICE Price_Slow = PRICE_CLOSE; input double Dev_Slow=0.15; /*Deviation parameter*/ input string txt3="----------"; input int Period_Signal=2; input ENUM_MA_METHOD Method_Signal = MODE_EMA; input ENUM_APPLIED_PRICE Price_Signal = PRICE_TYPICAL; input string txt4="----------"; //--- indicator buffers double ResultBuffer[]; double ResultColors[]; double Rule1Buffer[]; double Rule2Buffer[]; double SignalBuffer1[]; double SignalBuffer2[]; double SignalColors[]; //--- 2. Declaring the indicator handles that are necessary for our further calculations //--- 3. Declaring intermediate indicator buffers. We need 7 more int Envelopes_Fast; // Fast envelope int Envelopes_Slow; // Slow envelope int MA_Signal; // Signal line double Env_Fast_Up[]; // Fast envelope upper border double Env_Fast_Dn[]; // Fast envelope lower border double Env_Slow_Up[]; // Slow envelope upper border double Env_Slow_Dn[]; // Slow envelope lower border double Mov_Sign[]; // Signal line //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ResultBuffer,INDICATOR_DATA); SetIndexBuffer(1,ResultColors,INDICATOR_COLOR_INDEX); SetIndexBuffer(2,Rule1Buffer,INDICATOR_DATA); SetIndexBuffer(3,Rule2Buffer,INDICATOR_DATA); SetIndexBuffer(4,SignalBuffer1,INDICATOR_DATA); SetIndexBuffer(5,SignalBuffer2,INDICATOR_DATA); SetIndexBuffer(6,SignalColors,INDICATOR_COLOR_INDEX); IndicatorSetInteger(INDICATOR_DIGITS,1); // setting display accuracy, we do not need some outstanding accuracy values string name; // indicator name StringConcatenate(name,"FLE ( ",Period_Fast," , ",Dev_Fast," | ",Period_Slow," , ",Dev_Slow," | ",Period_Signal," )"); IndicatorSetString(INDICATOR_SHORTNAME,name); //--- 5. Adding indicator buffers SetIndexBuffer(7,Env_Fast_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(8,Env_Fast_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(9,Env_Slow_Up,INDICATOR_CALCULATIONS); SetIndexBuffer(10,Env_Slow_Dn,INDICATOR_CALCULATIONS); SetIndexBuffer(11,Mov_Sign,INDICATOR_CALCULATIONS); //--- 6. Filling the handles //--- iEnvelopes() indicator has two indicator buffers 0- UPPER_LINE , 1 - LOWER_LINE Envelopes_Fast = iEnvelopes(NULL,0,Period_Fast,0,Method_Fast,Price_Fast,Dev_Fast); Envelopes_Slow = iEnvelopes(NULL,0,Period_Slow,0,Method_Slow,Price_Slow,Dev_Slow); MA_Signal=iMA(NULL,0,Period_Signal,0,Method_Signal,Price_Signal); 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[]) { //--- 7. Preparations are over. Variables and buffers are declared, handles are assigned. // now it is time to proceed to the basic function. First of all, we need to write // the values of the necessary indicators in the intermediate buffers. To do this, we should use // CopyBuffer() function CopyBuffer(Envelopes_Fast, // Indicator handle UPPER_LINE, // Indicator buffer 0, // The point to start 0 - from the very beginning rates_total, // How many to be copied - All Env_Fast_Up); // The buffer the values are written in // - the rest are done in a similar way CopyBuffer(Envelopes_Fast,LOWER_LINE,0,rates_total,Env_Fast_Dn); CopyBuffer(Envelopes_Slow,UPPER_LINE,0,rates_total,Env_Slow_Up); CopyBuffer(Envelopes_Slow,LOWER_LINE,0,rates_total,Env_Slow_Dn); CopyBuffer(MA_Signal,0,0,rates_total,Mov_Sign); // as the work of CopyBuffer() function is optimized, there is no point in // its further optimization in the Expert Advisor code. But it would be wise to optimize the further calculations. // Let's add the following code, considering the fact that we will need to recalculate only the last bar: // declaring start variable for storing the index of the bar, recalculation of the indicator buffers // will be carried out from. int start; if(prev_calculated==0) // in case no bars have been calculated { start=Period_Slow; // not all indicators have been calculated up to this value, therefore, there is no point in executing the code } else start=prev_calculated-1; for(int i=start;i0.2*ColorIndex && MathAbs(ResultBuffer[i])<=0.2*(ColorIndex+1)) { ResultColors[i]=ColorIndex; break; } } // adding the signal buffer if(ResultBuffer[i]==1) { SignalBuffer1[i]=1.1; SignalBuffer2[i]=1.3; SignalColors[i]=1; } else if(ResultBuffer[i]==-1) { SignalBuffer1[i]=-1.1; SignalBuffer2[i]=-1.3; SignalColors[i]=0; } else { SignalBuffer1[i]=EMPTY_VALUE; SignalBuffer2[i]=EMPTY_VALUE; SignalColors[i]=EMPTY_VALUE; } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ double Fuzzy(double x,double a,double c) { double F; if(a=c) F=(1-2*(a-x)/(a-c));// Flat else if(x