Error using multiple instance of a class with different time frames.

 

Dear Members

Wish all of you happy weekend.

I have created CDivergence CLASS to calculate divergence and trying to use multiple instances of it to get divergence on different time frames. The challenge I am facing is that it return only last time frame defined in the instance declaration. Below is the tester report.

Seems CLASS did instantiate THREE time frames in Constructor, but...

2022.11.04 12:13:41.784 2022.01.01 00:00:00   CDivergence::CDivergence: mTimeFrame[PERIOD_M15] pTimeFrame[PERIOD_M15]

2022.11.04 12:13:41.784 2022.01.01 00:00:00   CDivergence::CDivergence: mTimeFrame[PERIOD_M5] pTimeFrame[PERIOD_M5]

2022.11.04 12:13:41.784 2022.01.01 00:00:00   CDivergence::CDivergence: mTimeFrame[PERIOD_M1] pTimeFrame[PERIOD_M1]

but it took only the last time frame when running OnInit(), I have tried to shift code into Constructor() but results are same.

2022.11.04 12:13:41.784 2022.01.01 00:00:00   CDivergence::OnInit: mTimeFrame[PERIOD_M1]

2022.11.04 12:13:41.897 2022.01.01 00:00:00   CDivergence::OnInit: mTimeFrame[PERIOD_M1]

2022.11.04 12:13:41.897 2022.01.01 00:00:00   CDivergence::OnInit: mTimeFrame[PERIOD_M1]

I have attached the scale down version of code (other wise there are too many files and codes which are not relevant.

Will need one more favor, in scale down version when I compile CDivergence.mqh it does compile without any error. However when I compile the TestDivergence EXPERT, it gives the following error, which I have failed to figure out. Please support me on this and then try to run the EA.

'CStochMQL5' - unexpected token, probably type is missing? DivergenceMQL5.mqh 31 3

'cStoch' - semicolon expected DivergenceMQL5.mqh 31 18

'CFractalsMQL5' - unexpected token, probably type is missing? DivergenceMQL5.mqh 32 3

'cFractal' - semicolon expected DivergenceMQL5.mqh 32 20

Look forward to solution to the issue at the earliest.

Regards

//+-----------------------------------------------------------------------------------------------------------------------------+
//| EXPERT:       TestDivergenceMQL5.mqh
//+-----------------------------------------------------------------------------------------------------------------------------+
        #include "../Include/MQL5 Forum/EnumsMQL5.mqh"
        #include "../Include/MQL5 Forum/IncludeClassesMQL5.mqh"
        string  InpSymbol = "US30";

        CDivergenceMQL5         cDVRG_M15(InpSymbol,PERIOD_M15,5,3,3);
        CDivergenceMQL5         cDVRG_M05(InpSymbol,PERIOD_M5,5,3,3);
        CDivergenceMQL5         cDVRG_M01(InpSymbol,PERIOD_M1,5,3,3);

int OnInit() {

                cDVRG_M15.OnInit();
                cDVRG_M05.OnInit();
                cDVRG_M01.OnInit();
                return(INIT_SUCCEEDED);

} // END of function OnInit()

void OnDeinit(const int reason) {

   
} // END of function OnDeinit()

void OnTick() {

        cDVRG_M15.OnTick();
        cDVRG_M05.OnTick();
        cDVRG_M01.OnTick();

} // END of function OnTick()

bool IsNewBarD01() {

  static datetime vCurrTFD01 = WRONG_VALUE;
         datetime vPrevTFD01 = vCurrTFD01;

  vCurrTFD01 = (datetime)SeriesInfoInteger(InpSymbol,PERIOD_H1,SERIES_LASTBAR_DATE);
  if(vPrevTFD01 != vCurrTFD01)  return(true);
  else                          return(false);

} // END of method IsNewBarD01()

bool IsNewBarH01() {

  static datetime vCurrTFH01 = WRONG_VALUE;
         datetime vPrevTFH01 = vCurrTFH01;

  vCurrTFH01 = (datetime)SeriesInfoInteger(InpSymbol,PERIOD_H1,SERIES_LASTBAR_DATE);
  if(vPrevTFH01 != vCurrTFH01)  return(true);
  else                          return(false);

} // END of method IsNewBarH01()

        #include "../MQL5 Forum/EnumsMQL5.mqh"
        #include "../MQL5 Forum/IncludeClassesMQL5.mqh"

class CDivergenceMQL5 {

public:
                CDivergenceMQL5(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,int pStochKPeriod,int pStochDPeriod,int pStochSlowing);
         ~CDivergenceMQL5();
        
                int                                                                     OnInit();
                void                                                            OnTick();

private:
                CStochMQL5                                      cStoch;
                CFractalsMQL5                           cFractal;

private:
                long                                                            mChartID;
                int                                                                     mSubWindow;
                string                                                  mNameDVRG;
                string                                                  mNameCVRG;
private:
                int                                                             mLookBack;                                                                              // LOOK BACK MAXIMUM THREE FRACTALS TO FIND DIVERGENCE / CONVERGENCE

                bool                                                            IsDVRG_BullishClassic(SDiverge &pDVRG);
                bool                                                            IsDVRG_BullishHidden(SDiverge &pDVRG);

                bool                                                            IsDVRG_BearishClassic(SDiverge &pDVRG);
                bool                                                            IsDVRG_BearishHidden(SDiverge &pDVRG);
public:
                bool                                                            IsDVRG_Bullish(SDiverge &pDVRG);
                bool                                                            IsDVRG_Bearish(SDiverge &pDVRG);

public:


private:
                bool                                                            IsNewBar();

}; // END of Class declaration

CDivergenceMQL5::CDivergenceMQL5(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,int pStochKPeriod,int pStochDPeriod,int pStochSlowing) {

                mSymbol                 = pSymbol;
        mDigits     = (int)SymbolInfoInteger(mSymbol,SYMBOL_DIGITS);
                mTimeFrame      = pTimeFrame;
                PrintFormat("%s: mTimeFrame[%s] pTimeFrame[%s]",(string)__FUNCTION__,EnumToString(mTimeFrame),EnumToString(mTimeFrame));

                mStochKPeriod   = pStochKPeriod;
                mStochDPeriod   = pStochDPeriod;
                mStochSlowing = pStochSlowing;

                mLookBack       = 5;

} // End of method CDivergenceMQL5()

int CDivergenceMQL5::OnInit() {

                PrintFormat("%s: mTimeFrame[%s]",(string)__FUNCTION__,EnumToString(mTimeFrame));
                cStoch.InitHandle(mSymbol,mTimeFrame,mStochKPeriod,mStochDPeriod,mStochSlowing);
                cFractal.InitHandle(mSymbol,mTimeFrame);
                return(INIT_SUCCEEDED);

} // End of method InitClass()

void CDivergenceMQL5::OnTick(void) {

                if(IsNewBar()) {
                        PrintFormat("%s: mTimeFrame[%s]",(string)__FUNCTION__,EnumToString(mTimeFrame));
                        cFractal.GetArrayBULLISH(mLookBack,sFractal_BULL);
                        cFractal.GetArrayBEARISH(mLookBack,sFractal_BEAR);

                        // DIVERGENCE ON MOST RECENT HIGHEST / LOWEST OF FIVE BARS
                        int k = 1;
                        mIdxHighest = iHighest(mSymbol,mTimeFrame,MODE_HIGH,5,k);
                        mIdxLowest  = iLowest(mSymbol,mTimeFrame,MODE_LOW,5,k);

                        IsDVRG_Bullish(sDVRG);
                }

} // End of method OnTick()

bool CDivergenceMQL5::IsDVRG_Bullish(SDiverge &pDVRG) {

        bool result = false;
        SDiverge sDVRG_C;
        SDiverge sDVRG_H;

        IsDVRG_BullishClassic(sDVRG_C);
        IsDVRG_BullishHidden(sDVRG_H);

        if(sDVRG_C.direction == LONG && sDVRG_C.isStoch == true) {
                pDVRG  = sDVRG_C;
                result = true;
        } else
        if(sDVRG_H.direction == LONG && sDVRG_H.isStoch == true) {
                pDVRG  = sDVRG_H;
                result = true;
        }
        else {
                ZeroMemory(pDVRG);
                pDVRG.direction = WRONG_VALUE;
                pDVRG.type                      = WRONG_VALUE;
                result                                  = false;
        }

        return(result);

} // End of method IsDVRG_Bullish()

bool CDivergenceMQL5::IsDVRG_BullishClassic(SDiverge &pDVRG) {

        ZeroMemory(pDVRG);
        int IndexA = mIdxLowest;
        //+---------------------------------------------------------------------------------------------------------------------------+
        //| DIVERGENCE AT FRACTAL[IndexB] AND IndexA
        //+---------------------------------------------------------------------------------------------------------------------------+
                for(int i = 1; i <= mLookBack; i++) {
                        int IndexB = sFractal_BULL[i].idx;

                        // STOCHASTIC DIVERGENCE
                        if(cStoch.IsClassicDVRG_BULLISH(IndexB,IndexA)) {
                                PrintFormat("%s: [%s] IsDVRG_BullishClassic STOCH[%i][%i][%s]",(string)__FUNCTION__,EnumToString(mTimeFrame),
                                                                                IndexB,IndexA,(string)cStoch.IsClassicDVRG_BULLISH(IndexB,IndexA));

                                pDVRG.direction = LONG;
                                pDVRG.type                      = CLASSIC;
                                pDVRG.idxB                      = IndexB;
                                pDVRG.idxA                      = IndexA;
                                pDVRG.isMFI             = false;
                                pDVRG.isStoch   = true;
                                return(true);
                        }
                } // End of for..loop
                return(false);

} // End of method IsDVRG_BullishClassic()

bool CDivergenceMQL5::IsDVRG_BullishHidden(SDiverge &pDVRG) {

        ZeroMemory(pDVRG);
        int IndexA = mIdxLowest;
        //+---------------------------------------------------------------------------------------------------------------------------+
        //| DIVERGENCE AT FRACTAL[IndexB] AND IndexA
        //+---------------------------------------------------------------------------------------------------------------------------+
                for(int i = 1; i <= mLookBack; i++) {
                        int IndexB = sFractal_BULL[i].idx;

                        // STOCHASTIC DIVERGENCE
                        if(cStoch.IsHiddenDVRG_BULLISH(IndexB,IndexA)) {
                                PrintFormat("%s: [%s] IsDVRG_BullishHidden STOCH[%i][%i][%s]",(string)__FUNCTION__,EnumToString(mTimeFrame),
                                                                                IndexB,IndexA,(string)cStoch.IsHiddenDVRG_BULLISH(IndexB,IndexA));

                                pDVRG.direction = LONG;
                                pDVRG.type                      = HIDDEN;
                                pDVRG.idxB                      = IndexB;
                                pDVRG.idxA                      = IndexA;
                                pDVRG.isMFI             = false;
                                pDVRG.isStoch   = true;
                                return(true);
                        }
                } // End of for..loop

                return(false);

} // End of method IsDVRG_BullishHidden()

bool CDivergenceMQL5::IsDVRG_BearishClassic(SDiverge &pDVRG) {

        ZeroMemory(pDVRG);
        int IndexA = mIdxHighest;

                for(int i = 1; i <= mLookBack; i++) {
                        int IndexB = sFractal_BEAR[i].idx;

                        // STOCHASTIC DIVERGENCE
                        if(cStoch.IsClassicDVRG_BEARISH(IndexB,IndexA)) {
                                PrintFormat("%s: [%s] IsDVRG_BearishClassic STOCH[%i][%i][%s]",(string)__FUNCTION__,EnumToString(mTimeFrame),
                                                                                IndexB,IndexA,(string)cStoch.IsClassicDVRG_BEARISH(IndexB,IndexA));

                                pDVRG.direction = SHORT;
                                pDVRG.type                      = CLASSIC;
                                pDVRG.idxB                      = IndexB;
                                pDVRG.idxA                      = IndexA;
                                pDVRG.isMFI             = false;
                                pDVRG.isStoch   = true;
                                return(true);
                        }
                } // End of for..loop
                return(false);

} // End of method IsDVRG_BearishClassic()

bool CDivergenceMQL5::IsDVRG_BearishHidden(SDiverge &pDVRG) {

        ZeroMemory(pDVRG);
        int IndexA = mIdxHighest;

                for(int i = 1; i <= mLookBack; i++) {
                        int IndexB = sFractal_BEAR[i].idx;

                        // STOCHASTIC DIVERGENCE
                        if(cStoch.IsHiddenDVRG_BEARISH(IndexB,IndexA)) {
                                PrintFormat("%s: [%s] IsDVRG_BearishHidden STOCH[%i][%i][%s]",(string)__FUNCTION__,EnumToString(mTimeFrame),
                                                                                IndexB,IndexA,(string)cStoch.IsHiddenDVRG_BEARISH(IndexB,IndexA));

                                pDVRG.direction = SHORT;
                                pDVRG.type                      = HIDDEN;
                                pDVRG.idxB                      = IndexB;
                                pDVRG.idxA                      = IndexA;
                                pDVRG.isMFI             = false;
                                pDVRG.isStoch   = true;
                                return(true);
                        }
                } // End of for..loop
        //+---------------------------------------------------------------------------------------------------------------------------+
                return(false);

} // End of method IsDVRG_BearishHidden()

bool CDivergenceMQL5::IsNewBar() {

  static datetime vCurrTF = WRONG_VALUE;
         datetime vPrevTF = vCurrTF;

  vCurrTF = (datetime)SeriesInfoInteger(mSymbol,mTimeFrame,SERIES_LASTBAR_DATE);
  if(vPrevTF != vCurrTF)                        return(true);
  else                          return(false);

} // End of method IsNewBar()other files and these two are attached herewith for down load.

Error CDivergence.txt for much more detailed Tester Results as message characters limit is exceeding.

 
As far as I know an new instance of  a class has to be created by new.
Documentation on MQL5: Language Basics / Operators / Object Create Operator new
Documentation on MQL5: Language Basics / Operators / Object Create Operator new
  • www.mql5.com
Object Create Operator new - Operators - Language Basics - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
  vCurrTFD01 = (datetime)SeriesInfoInteger(InpSymbol,PERIOD_H1,SERIES_LASTBAR_DATE);
  ⋮
  vCurrTFH01 = (datetime)SeriesInfoInteger(InpSymbol,PERIOD_H1,SERIES_LASTBAR_DATE);

Same value assigned.

 
William Roeder #:

Same value assigned.

Hi William

thanks for reply. However this error is in EA and irrelavant as IsNewBar() were never used in the EA.

 
Carl Schreiber #:
As far as I know an new instance of  a class has to be created by new.

Hi Carl

Thanks for reply.

If Parametric Constructor is defined in the class to be loaded, we can use direct method instead of new method.

However, as per your suggestion I have tried loading class by new method, the results are still same and time frame error continues.

 
You should define all the instance variables like mTimeFrame inside the class in private part when possible, protected if not possible and public otherwise.

Right now they are global variables defined outside the class.
 

Hey mate,

I am not a native English speaker,

So if my answer is not clear, please tell me and I'll try to rephrase it in a more clear way.


Your problem is not shown in the code fragments you've posted (which is also a big hint for the problem).


Amir Yacoby explained it correctly-

In your init function of your "CDivergenceMQL5" class,

you set the mTimeFrame variable,

HOWEVER-

mTimeFrame is not a variable that is part of the "CDivergenceMQL5" class,

It is a global variable which is declared in the "IncludeClassesMQL5.mqh" file.

So essentially all of your "CDivergenceMQL5" instances are using the same variable to hold the timeframe,

So in your EA's "OnInit()" function, each of the below calls, overwrite the value stored in the "mTimeFrame" variable-

cDVRG_M15.OnInit(); // mTimeFrame gets the initial value of PERIOD_M15
cDVRG_M05.OnInit(); // mTimeFrame now gets overwritten with the value of PERIOD_M5
cDVRG_M01.OnInit(); // mTimeFrame gets overwritten again, now with the value of PERIOD_M1


Set a variable to save the timeframe as Amir Yacoby had suggested, and your code should work as expected.


Cheers.

 
Amir Yacoby #:
You should define all the instance variables like mTimeFrame inside the class in private part when possible, protected if not possible and public otherwise.

Right now they are global variables defined outside the class.

Thanks Amir for your reply.

I realized that mTimeFrame was declared in the "IncludeClassesMQL5.mqh" file and not within CDivergenceMQL5 class. With this change I have also declared mSymbol and mDigits locally. It has helped at least to separate the instances time frame.

class CDivergence {

public:
                CDivergence() { }
                CDivergence(string pSymbol,ENUM_TIMEFRAMES pTimeFrame,int pMFIPeriod,int pMFIOnBBPeriod,double pMFIOnBBDeviation,
                                                                int pStochKPeriod,int pStochDPeriod,int pStochSlowing);
         ~CDivergence();
        
                int                                                                     OnInit();
                void                                                            OnTick();

private:

        int                             mDigits;                                                        // NO OF PRICE DECIMAL DIGITS (_Digits) OF THE ASSETS
        string                          mSymbol;
        ENUM_TIMEFRAMES                 mTimeFrame;

                CiMFI                                                           cMFI;
                CiStoch                                                 cStoch;
                CFractals                                               cFractals;

However, it seems IsNewBar() method is failing to catch the time frame and returns value almost on each tick.

A little extra help is highly appreciated.

Please review Rev1 tester results in the attached file to reply to AMI289. 

 
AMI289 #:

Hey mate,

I am not a native English speaker,

So if my answer is not clear, please tell me and I'll try to rephrase it in a more clear way.


Your problem is not shown in the code fragments you've posted (which is also a big hint for the problem).


Amir Yacoby explained it correctly-

In your init function of your "CDivergenceMQL5" class,

you set the mTimeFrame variable,

HOWEVER-

mTimeFrame is not a variable that is part of the "CDivergenceMQL5" class,

It is a global variable which is declared in the "IncludeClassesMQL5.mqh" file.

So essentially all of your "CDivergenceMQL5" instances are using the same variable to hold the timeframe,

So in your EA's "OnInit()" function, each of the below calls, overwrite the value stored in the "mTimeFrame" variable-


Set a variable to save the timeframe as Amir Yacoby had suggested, and your code should work as expected.


Cheers.

Hi AMI

Thanks a lot for your reply and much more detailed explanation to the solution. Your english is well and enough for me to understand.

I have implemented your suggestion (please see reply to Amir above), however there seems still problem with NewBar detection, as it is printing on almost ever tick.

Attached is the revised Tester Results for your review.

" It is a global variable which is declared in the "IncludeClassesMQL5.mqh" file." ... your pointer to this way of declaring variable will go long way to improve my codes and I realized that short cuts are not always good.

Files:
 
Anil Varma #:

Thanks Amir for your reply.

I realized that mTimeFrame was declared in the "IncludeClassesMQL5.mqh" file and not within CDivergenceMQL5 class. With this change I have also declared mSymbol and mDigits locally. It has helped at least to separate the instances time frame.

However, it seems IsNewBar() method is failing to catch the time frame and returns value almost on each tick.

A little extra help is highly appreciated.

Please review Rev1 tester results in the attached file to reply to AMI289. 

Hey Anil,

static variables declared in a class are same as global variables, meaning there is only one instance of them thru all instances and it is the same.

You only need one of them, declared in the class private part

datetime vPrevTF;

Initialize with WRONG_VALUE in the constructor. 

And the method IsNewBar() // not tested 

  datetime vCurrTF = (datetime)SeriesInfoInteger(mSymbol,mTimeFrame,SERIES_LASTBAR_DATE);
  if(vPrevTF != vCurrTF)
    {
     vPrevTF = vCurrTF;  
     return true;
    }	
  else 
     return false;
 
Amir Yacoby #:

Hey Anil,

static variables declared in a class are same as global variables, meaning there is only one instance of them thru all instances and it is the same.

You only need one of them, declared in the class private part

Initialize with WRONG_VALUE in the constructor. 

And the method IsNewBar() // not tested 

Hi Amir

This is amazing, you really have excellent knowledge of OOP. These causes of problem as well as their solutions were beyond my imaginations. Hats off to you man.

It did worked perfectly well ... THANKS A LOT

2022.11.06 15:11:18.309 2022.01.03 01:00:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][CLASSIC] [11][5] isMFI[false] isStoch[true]
2022.11.06 15:11:18.309 2022.01.03 01:00:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M5][LONG][CLASSIC] [6][1] isMFI[true] isStoch[false]
2022.11.06 15:11:18.309 2022.01.03 01:00:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M15][LONG][CLASSIC] [9][5] isMFI[false] isStoch[true]

2022.11.06 15:11:18.352 2022.01.03 01:01:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][CLASSIC] [12][5] isMFI[false] isStoch[true]
2022.11.06 15:11:18.434 2022.01.03 01:02:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][CLASSIC] [24][4] isMFI[false] isStoch[true]
2022.11.06 15:11:18.537 2022.01.03 01:03:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][CLASSIC] [25][5] isMFI[false] isStoch[true]
2022.11.06 15:11:18.580 2022.01.03 01:04:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][CLASSIC] [31][5] isMFI[true] isStoch[true]

2022.11.06 15:11:18.660 2022.01.03 01:05:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [27][4] isMFI[true] isStoch[true]
2022.11.06 15:11:18.660 2022.01.03 01:05:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M5][LONG][CLASSIC] [7][2] isMFI[true] isStoch[false]

2022.11.06 15:11:18.751 2022.01.03 01:06:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [28][5] isMFI[true] isStoch[true]
2022.11.06 15:11:18.808 2022.01.03 01:07:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [29][4] isMFI[true] isStoch[true]
2022.11.06 15:11:18.868 2022.01.03 01:08:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [30][5] isMFI[true] isStoch[true]
2022.11.06 15:11:18.937 2022.01.03 01:09:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [31][5] isMFI[false] isStoch[true]

2022.11.06 15:11:18.984 2022.01.03 01:10:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [32][5] isMFI[false] isStoch[true]
2022.11.06 15:11:18.984 2022.01.03 01:10:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M5][LONG][CLASSIC] [8][3] isMFI[true] isStoch[false]

2022.11.06 15:11:19.080 2022.01.03 01:11:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [33][5] isMFI[false] isStoch[true]
2022.11.06 15:11:19.123 2022.01.03 01:12:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][CLASSIC] [2][5] isMFI[true] isStoch[false]
2022.11.06 15:11:19.209 2022.01.03 01:13:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [35][1] isMFI[true] isStoch[true]
2022.11.06 15:11:19.304 2022.01.03 01:14:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [36][1] isMFI[true] isStoch[true]

2022.11.06 15:11:19.349 2022.01.03 01:15:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [37][1] isMFI[true] isStoch[true]
2022.11.06 15:11:19.349 2022.01.03 01:15:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M5][LONG][CLASSIC] [9][4] isMFI[true] isStoch[false]
2022.11.06 15:11:19.349 2022.01.03 01:15:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M15][LONG][CLASSIC] [2][5] isMFI[true] isStoch[true]

2022.11.06 15:11:19.409 2022.01.03 01:16:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [38][2] isMFI[true] isStoch[true]
2022.11.06 15:11:19.469 2022.01.03 01:17:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [39][3] isMFI[true] isStoch[true]
2022.11.06 15:11:19.552 2022.01.03 01:18:00   CDivergence::IsDVRG_Bullish: DVRG[PERIOD_M1][LONG][HIDDEN] [40][4] isMFI[true] isStoch[true]
Reason: