//+------------------------------------------------------------------+
//|                                      Developed by : Mario Jemic  |                    
//|                                          mario.jemic@gmail.com   |
//|                     BitCoin: 15VCJTLaz12Amr7adHSBtL9v8XomURo9RF  |
//+------------------------------------------------------------------+



#property indicator_buffers 3
#property indicator_separate_window
#property indicator_color1  clrGreen
#property indicator_color2  clrRed
#property indicator_color3  clrBlue

//
//
//

 extern ENUM_TIMEFRAMES  TimeFrame            = PERIOD_CURRENT;      // Time frame to use 
extern int               RSI_Period           = 14;
extern int               RSI_Smoothing_Period = 5;
extern int               ATR_Period           = 14;
extern double            Fast_ATR_Multipliers = 2.618;
extern double            Slow_ATR_Multipliers = 4.236;
input  bool              Interpolate          = true;             // Interpolate in mtf mode
 

double TR[],QQE[],TS1[],TS2[],RSI[],ATR[],DELTA[],count[],WildersPeriod;
string indicatorFileName;
#define _mtfCall(_buff,_ind) iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,RSI_Period,RSI_Smoothing_Period,ATR_Period,Fast_ATR_Multipliers,Slow_ATR_Multipliers,_buff,_ind)

//
//
//

int init()
{
   IndicatorBuffers(8);
   SetIndexBuffer(0,QQE); SetIndexLabel(0,"QQE");
   SetIndexBuffer(1,TS1); SetIndexLabel(1,"TS1");
   SetIndexBuffer(2,TS2); SetIndexLabel(2,"TS2");  
   SetIndexBuffer(3,TR);
   SetIndexBuffer(4,RSI);
   SetIndexBuffer(5,ATR);
   SetIndexBuffer(6,DELTA);
   SetIndexBuffer(7,count);
   
   SetLevelValue(1,50);
   SetLevelValue(2,30);
   SetLevelValue(3,70);
   SetLevelStyle(STYLE_SOLID,1);
   
   WildersPeriod     = RSI_Period * 2 - 1;
   indicatorFileName = WindowExpertName();
   TimeFrame         = fmax(TimeFrame,_Period);
   
   IndicatorShortName(timeFrameToString(TimeFrame)+" QualitativeQuantitativeEstimation");
return(0);
}

int start()
{
   int i,counted_bars=IndicatorCounted();
      if(counted_bars<0) return(-1);
      if(counted_bars>0) counted_bars--;
         int limit = fmin(Bars-counted_bars,Bars-1); count[0] = limit;
         if (TimeFrame != _Period)
         {
            limit = (int)fmax(limit,fmin(Bars-1,_mtfCall(7,0)*TimeFrame/_Period));
            for (i=limit;i>=0 && !_StopFlag; i--)
            {
                int y = iBarShift(NULL,TimeFrame,Time[i]);
                   QQE[i] = _mtfCall(0,y);
                   TS1[i] = _mtfCall(1,y);
                   TS2[i] = _mtfCall(2,y);
                   
                   //
                   //
                   //
                     
                   if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;
                   #define _interpolate(buff) buff[i+k] = buff[i]+(buff[i+n]-buff[i])*k/n
                   int n,k; datetime time = iTime(NULL,TimeFrame,y);
                      for(n = 1; (i+n)<Bars && Time[i+n] >= time; n++) continue;	
                      for(k = 1; k<n && (i+n)<Bars && (i+k)<Bars; k++)
                      {
                         _interpolate(QQE);
                         _interpolate(TS1);
                         _interpolate(TS2);
                       }            
            }
   return(0);
   }
   
   //
   //
   //
      
   for(i=limit; i>=0; i--) RSI[i]= iRSI(NULL,0,RSI_Period,PRICE_CLOSE,i);
   for(i=limit; i>=0; i--)
   {
      QQE[i] = iMAOnArray(RSI,0,RSI_Smoothing_Period,0,MODE_EMA,i);  
		TR[i]  = fabs(QQE[i]-QQE[i+1]);  
   }
   for(i=limit; i>=0; i--) ATR[i]   = iMAOnArray(TR,0,ATR_Period,0,MODE_EMA,i);
   for(i=limit; i>=0; i--) DELTA[i] = iMAOnArray(ATR,0,WildersPeriod,0,MODE_EMA,i);
  

   double Stop1=QQE[limit];
   double Stop2=QQE[limit];
   for(i=limit; i>=0; i--)
   {
	   if(QQE[i] < TS1[i+1])														
	   {	
		  Stop1=QQE[i] + DELTA[i]*Fast_ATR_Multipliers;
		  if (Stop1 > TS1[i+1])  
		  {        
			  if (QQE[i+1] <  TS1[i+1])
 		     {
				  Stop1 = TS1[i+1];
			  }											     
		   }									
		}		
		else if (QQE[i] > TS1[i+1])
		{
          Stop1=QQE[i] - DELTA[i]*Fast_ATR_Multipliers;
		    if (Stop1 < TS1[i+1])
			 {       
				 if (QQE[i+1] >  TS1[i+1]) 
 			    {
					 Stop1 = TS1[i+1];
				 }											       
			 }												 
		 }	
		 TS1[i]=Stop1;
	}
   for(i=limit; i>=0; i--)
   {
      if (QQE[i] < TS2[i+1])												
      {		
		  Stop2=QQE[i] + DELTA[i]*Slow_ATR_Multipliers;												 
		  if (Stop2 > TS2[1+1])
		  {		 
			 if (QQE[i+1] <  TS2[i+1] )
 			 {
				Stop2 = TS2[i+1];
			 }
			}									
		  }			
		  else if (QQE[i] > TS2[i+1])																
		  {	 
		      Stop2 = QQE[i] - DELTA[i]*Slow_ATR_Multipliers;
				if (Stop2 < TS2[i+1])
				{		 
				  if (QQE[i+1] >  TS2[i+1])
				  {
					 Stop2 = TS2[i+1];
				  }
				}														 
			}															
		   TS2[i]=Stop2;
   }
return(0);
}

//+-------------------------------------------------------------------
//|                                                                  
//+-------------------------------------------------------------------

string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"};
int    iTfTable[] = {1,5,15,30,60,240,1440,10080,43200};

string timeFrameToString(int tf)
{
   for (int i=ArraySize(iTfTable)-1; i>=0; i--) 
         if (tf==iTfTable[i]) return(sTfTable[i]);
                              return("");
}
  