Custom iTSA class returns different values than indicator. Please help

 

Hi Folks

I usually create Class to use indication values in my Expert. For all my indicators I follow a standard practice to get data from indicator.

Recently I have created CiTSV class with same standard practice. However with this class, I am getting different values than shown by indicator on the Chart. I have looked into all possible areas of error but failed to trace the problem.

I have made some changes to original indicator by https://www.mql5.com/en/code/42000, mainly to remove MT4 Compatibility. I have however tested iTSV.ex5 results with the original indicator results and they are matching, so I believe the problem is not in the indicator itself.

Looking forward to solution from experts.

#define         iTSVPath "iTSV.ex5"
#resource       "\\" + iTSVPath

struct SiTSV {
        double                                                  tsv;                                                                                            // TSV VALUE
        double                                                  ema;                                                                                            // EMA OF TSV VALUES
        double                                                  slope;                                                                                  // SLOPE OF EMA
};

//+-----------------------------------------------------------------------------------------------------------------------------+
//| CLASS:        CiTSV
//| APPLICATION:  RELATIVE (PERIODIC) VOLUME INDICATOR
//+-----------------------------------------------------------------------------------------------------------------------------+
class CiTSV {

public:

    CiTSV(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,uint pTSV_SumPeriod,uint pTSV_MAPeriod,ENUM_APPLIED_PRICE pTSV_AppliedPrice);
   ~CiTSV() { IndicatorRelease(mHandleTSV); }

private:

                int                                                                     mHandleTSV;
                string                                                  mSymbol;
                ENUM_TIMEFRAMES                 mTimeFrame;
                uint                                                            mTSV_SumPeriod;                                 // TSV SUMMATION PERIOD [13]
    uint                                                                mTSV_MAPeriod;                                  // TSV AVERAGING PERIOD [7]
    ENUM_APPLIED_PRICE  mTSV_AppliedPrice;                      // TSV APPLIED PRICE [PRICE_CLOSE]

public:
    void                                        GetArrayTSV(int pCount,SiTSV &pTSV[]);
private:
    double                                              CopyBufferTSV(int pBufferNo,int pIndex);

}; // END Of Class declaration
//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:       CiTSV()
//| APPLICATION:  Parametric Constructor method
//+-----------------------------------------------------------------------------------------------------------------------------+
CiTSV::CiTSV(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,uint pTSV_SumPeriod,uint pTSV_MAPeriod,ENUM_APPLIED_PRICE pTSV_AppliedPrice) {

        // ASSIGN VALUES TO INDICATOR MEMBER VARIABLES
                mSymbol                                         = pSymbol;
                mTimeFrame                              = pTimeFrame;
    mTSV_SumPeriod              = pTSV_SumPeriod;
                mTSV_MAPeriod                   = pTSV_MAPeriod;
                mTSV_AppliedPrice       = pTSV_AppliedPrice;

                //TesterHideIndicators(true);
    mHandleTSV = iCustom(mSymbol,mTimeFrame,"::" + iTSVPath,mTSV_SumPeriod,mTSV_MAPeriod,PRICE_CLOSE);
    if(mHandleTSV == INVALID_HANDLE) {
                        ResetLastError();
                        string vMethod = "[" + mSymbol + "," + EnumToString(mTimeFrame) + "] " + (string)__FUNCTION__;
      PrintFormat("%s Error#[%i] creating handle iTSV",vMethod,GetLastError());
                }
                //TesterHideIndicators(false);

} // END Of parametric constructor()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:                     GetArrayTSV()
//| APPLICATION:  Method to return range of values into parameter passed in as &pVolume
//+-----------------------------------------------------------------------------------------------------------------------------+
void CiTSV::GetArrayTSV(int pCount,SiTSV &pTSV[]) {

                string vMethod = "[" + mSymbol + "," + EnumToString(mTimeFrame) + "] " + (string)__FUNCTION__;
                string vIndexTime = TimeToString(iTime(mSymbol,mTimeFrame,0),TIME_DATE|TIME_MINUTES);

    if(mHandleTSV == INVALID_HANDLE) {
                        CiTSV(mSymbol,mTimeFrame,mTSV_SumPeriod,mTSV_MAPeriod,mTSV_AppliedPrice);
                }

    ArrayResize(pTSV,pCount+1);                                                                                                                 // Index[0] added
    ArraySetAsSeries(pTSV,true);

    for(int i = 0; i <= pCount; i++) {                                                                                  // Copy from Index[0] to keep compatibility with Chart
      pTSV[i].tsv               = CopyBufferTSV(0,i);
      pTSV[i].ema                       = CopyBufferTSV(2,i);
                        double prevEMA  = CopyBufferTSV(2,i+2);
      pTSV[i].slope     = (pTSV[i].ema - prevEMA) / prevEMA;
        if(i!=0) PrintFormat("%s [%s] index[%i] TSV[%+i] EMA[%+i] - prevEMA[%+i] = [%+i] / prevEMA[%+i] = Slope[%+.3f]",vMethod,vIndexTime,i,pTSV[i].tsv,pTSV[i].ema,prevEMA,(pTSV[i].ema - prevEMA),prevEMA,pTSV[i].slope);
    }

    return;

} // END Of method GetArrayTSV()
//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:                     CopyBufferTSV()
//| APPLICATION:  Method to return specified Index value for TSV Indicator
//+-----------------------------------------------------------------------------------------------------------------------------+
double CiTSV::CopyBufferTSV(int pBufferNo,int pIndex) {

    double bufferData[1];                                       // static buffer
    if(CopyBuffer(mHandleTSV,pBufferNo,pIndex,1,bufferData) == -1) {
                        ResetLastError();
                        string vMethod = "[" + (string)mSymbol + "," + EnumToString(mTimeFrame) +"]" + (string)__FUNCTION__;
      PrintFormat("%s Error#[%i] Getting value from iTSV at Buffer[%i] Index[%i]",vMethod,GetLastError(),pBufferNo,pIndex);
      return(0);
    }

    return(bufferData[0]);

} // END Of method CopyBufferTSV()
//+-----------------------------------------------------------------------------------------------------------------------------+

Indicator source code, class source code and Expert Code (to run and test indicator) are enclosed herewith.

Best regards.

Strategy Testing - Algorithmic Trading, Trading Robots - MetaTrader 5 Help
  • www.metatrader5.com
The Strategy Tester allows you to test and optimize trading strategies ( Expert Advisors ) before using them for live trading. During testing, an...
Files:
EA_iTSV.mq5  3 kb
iTSV.mq5  12 kb
iTSV.mqh  5 kb
TSV_Error.png  475 kb
 
    if(mHandleTSV == INVALID_HANDLE) {
                        CiTSV(mSymbol,mTimeFrame,mTSV_SumPeriod,mTSV_MAPeriod,mTSV_AppliedPrice);
                }
Do you understand what that does? It creates an anonymous class object and then destroys it. Totally useless.
 
William Roeder #:
Do you understand what that does? It creates an anonymous class object and then destroys it. Totally useless.

Hi William

Thanks for quick reply.

Well I am not much expert at technical part of coding. I learned about the indicator class in one of YouTube tutorials, and implemented it in my coding style.

However, I will admit that I made a change and instead of using Init() for class initialization (as was recommended in tutorial), I used CiTSV constructor itself.

When you pointed it, I realized change I made and corrected the code as highlighted below:

        // NOW USE 'new' OPERATOR FOR PARAMETRIC CONSTRUCTOR TO SET CORRECT PARAMETERS
    CiTSV(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,uint pTSV_SumPeriod,uint pTSV_MAPeriod,ENUM_APPLIED_PRICE pTSV_AppliedPrice)
        { Init(pSymbol,pTimeFrame,pTSV_SumPeriod,pTSV_MAPeriod,pTSV_AppliedPrice); }
   ~CiTSV() { IndicatorRelease(mHandleTSV); }

private:
                void  Init(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,uint pTSV_SumPeriod,uint pTSV_MAPeriod,ENUM_APPLIED_PRICE pTSV_AppliedPrice);

private:

                int                                                                     mHandleTSV;
                string                                                  mSymbol;
                ENUM_TIMEFRAMES                 mTimeFrame;
                uint                                                            mTSV_SumPeriod;                                 // TSV SUMMATION PERIOD [13]
    uint                                                                mTSV_MAPeriod;                                  // TSV AVERAGING PERIOD [7]
    ENUM_APPLIED_PRICE  mTSV_AppliedPrice;                      // TSV APPLIED PRICE [PRICE_CLOSE]

public:
    void                                        GetArrayTSV(int pCount,SiTSV &pTSV[]);
    double                                              CopyBufferTSV(int pBufferNo,int pIndex);

}; // END Of Class declaration
//+-----------------------------------------------------------------------------------------------------------------------------+
//| METHOD:       Init()
//| APPLICATION:  Parametric Constructor method
//+-----------------------------------------------------------------------------------------------------------------------------+
void CiTSV::Init(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,uint pTSV_SumPeriod,uint pTSV_MAPeriod,ENUM_APPLIED_PRICE pTSV_AppliedPrice) {

        // ASSIGN VALUES TO INDICATOR MEMBER VARIABLES
                mSymbol                                         = pSymbol;
                mTimeFrame                              = pTimeFrame;
                mTSV_SumPeriod                  = pTSV_SumPeriod;
                mTSV_MAPeriod                   = pTSV_MAPeriod;
                mTSV_AppliedPrice                       = pTSV_AppliedPrice;

                //TesterHideIndicators(true);
    mHandleTSV = iCustom(mSymbol,mTimeFrame,"::" + iTSVPath,mTSV_SumPeriod,mTSV_MAPeriod,PRICE_CLOSE);
    if(mHandleTSV == INVALID_HANDLE) {
                        ResetLastError();
                        string vMethod = "[" + mSymbol + "," + EnumToString(mTimeFrame) + "] " + (string)__FUNCTION__;
      PrintFormat("%s Error#[%i] creating handle iTSV",vMethod,GetLastError());
                }
                //TesterHideIndicators(false);

} // END of Init()

void CiTSV::GetArrayTSV(int pCount,SiTSV &pTSV[]) {

                string vMethod = "[" + mSymbol + "," + EnumToString(mTimeFrame) + "] " + (string)__FUNCTION__;
                string vIndexTime = TimeToString(iTime(mSymbol,mTimeFrame,0),TIME_DATE|TIME_MINUTES);

        /*
    if(mHandleTSV == INVALID_HANDLE) {
                        Init(mSymbol,mTimeFrame,mTSV_SumPeriod,mTSV_MAPeriod,mTSV_AppliedPrice);
                }
        */

    ArrayResize(pTSV,pCount+1);                                                                                                                 // Index[0] added
    ArraySetAsSeries(pTSV,true);

    for(int i = 0; i <= pCount; i++) {                                                                                  // Copy from Index[0] to keep compatibility with Chart
      pTSV[i].tsv               = CopyBufferTSV(0,i);
      pTSV[i].ema                       = CopyBufferTSV(2,i);
                        double prevEMA  = CopyBufferTSV(2,i+2);
      pTSV[i].slope     = (pTSV[i].ema - prevEMA) / prevEMA;
        if(i!=0) PrintFormat("%s [%s] index[%i] TSV[%+i] EMA[%+i] - prevEMA[%+i] = [%+i] / prevEMA[%+i] = Slope[%+.3f]",vMethod,vIndexTime,i,pTSV[i].tsv,pTSV[i].ema,prevEMA,(pTSV[i].ema - prevEMA),prevEMA,pTSV[i].slope);
    }

    return;

} // END Of method GetArrayTSV()

However, even this did not help with or without Init() method in the GetArrayTSV().

Do you recommend any solution/other practice if this is 'totally useless' ? Although I am using the same practice in all my other classes and do not have any problem in them!!!

Regards. 

 

UPDATE ... the issue have been resolved.