Multi-Currency-Timeframe-Scanner. Help needed!

 

Hi Forum,

This indicator should analyze all currency pairs in all timeframes by searching for a Pinbar. My definition of a Pinbar is this:

Long Pinbar = the lower shadow must be at least 75% of the whole candle. Short Pinbar the same with the upper shadow.

It is a very simple definition but I put more emphasis on the scanner itself. I don't know why it doesn't work. I see no logical error.

Besides one thing is also very confusing for me: When I change the timeframe in the window with the indicator, the results are different. Thats confusing because the indicator should analyze all timeframes regardless the window's timeframe.

Maybe someone can help?

PS. If you attach the indicator to your chart, please set all chart-colors to "None".

//+------------------------------------------------------------------+
//|                                                      Scanner.mq4 |
//|                                               Copyright 2013, MR |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MR"
#property link      ""

#property indicator_chart_window

int dist_X, dist_Y, i, j;
string Timeframe[7] = {"M5", "M15", "M30", "H1", "H4", "D1", "W1"};
string CurrPair[27] = {"AUDCAD", "AUDCHF", "AUDJPY", "AUDNZD", "AUDUSD", "CADCHF", "CHFJPY", "EURAUD", "EURCAD", "EURCHF", "EURGBP", "EURJPY", "EURNZD", "EURUSD", "GBPAUD", "GBPCAD", "GBPCHF", "GBPJPY", "GBPNZD", "GBPUSD", "NZDCAD", "NZDCHF", "NZDJPY", "NZDUSD", "USDCAD", "USDCHF", "USDJPY"};
bool PinbarLong, PinbarShort;
color col;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   datetime Now = 0;
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ObjectsDeleteAll();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//---- Indicator calculation once a bar ---
   //if(Now==Time(0)) return(0);
   //Now=Time(0);
//---- Timeframe Objects ----
   dist_X = 80;
   for(i=0; i<=6; i++)
   {
      if (ObjectFind(Timeframe[i]+"txt") == -1)
      {
         ObjectCreate(Timeframe[i]+"txt", OBJ_LABEL, 0, 0, 0);
         ObjectSet(Timeframe[i]+"txt", OBJPROP_CORNER, 0);
         ObjectSet(Timeframe[i]+"txt", OBJPROP_XDISTANCE, dist_X);
         ObjectSet(Timeframe[i]+"txt", OBJPROP_YDISTANCE, 0);
         ObjectSetText(Timeframe[i]+"txt", Timeframe[i], 9, "Calibri", White);
         dist_X = dist_X+40;     
      }
   }
//---- Currency pairs objects ----
   dist_Y = 30;
   for(i=0; i<=26; i++)
   {
      if (ObjectFind(CurrPair[i]+"txt") == -1)
      {
         ObjectCreate(CurrPair[i]+"txt", OBJ_LABEL, 0, 0, 0);
         ObjectSet(CurrPair[i]+"txt", OBJPROP_CORNER, 0);
         ObjectSet(CurrPair[i]+"txt", OBJPROP_XDISTANCE, 0);
         ObjectSet(CurrPair[i]+"txt", OBJPROP_YDISTANCE, dist_Y);
         ObjectSetText(CurrPair[i]+"txt", CurrPair[i], 9, "Calibri", White);
         dist_Y = dist_Y+17;     
      }
   }
//---- Dot matrix ----   
   dist_X=80;
   dist_Y=4;
   for(j=0; j<=6; j++)
   {
      for(i=0; i<=26; i++)
      {
         ObjectCreate(CurrPair[i]+Timeframe[j], OBJ_LABEL, 0, 0, 0);
         ObjectSet(CurrPair[i]+Timeframe[j], OBJPROP_CORNER, 0);
         ObjectSet(CurrPair[i]+Timeframe[j], OBJPROP_XDISTANCE, dist_X);
         ObjectSet(CurrPair[i]+Timeframe[j], OBJPROP_YDISTANCE, dist_Y);
//-- Conditions --            
         PinbarLong =   MathMax(iOpen(CurrPair[i], "PERIOD_"+Timeframe[j], 1),iClose(CurrPair[i], "PERIOD_"+Timeframe[j], 1))-
                        iLow(CurrPair[i], "PERIOD_"+Timeframe[j], 1)
                        >= (iHigh(CurrPair[i], "PERIOD_"+Timeframe[j], 1)-iLow(CurrPair[i], "PERIOD_"+Timeframe[j], 1))*0.75;
         
         PinbarShort =  iHigh(CurrPair[i], "PERIOD_"+Timeframe[j], 1)-
                        MathMax(iOpen(CurrPair[i], "PERIOD_"+Timeframe[j], 1),iClose(CurrPair[i], "PERIOD_"+Timeframe[j], 1))
                        >= (iHigh(CurrPair[i], "PERIOD_"+Timeframe[j], 1)-iLow(CurrPair[i], "PERIOD_"+Timeframe[j], 1))*0.75;
//--            
         if (PinbarLong) col=Lime;
         else if (PinbarShort) col=Red;
         else col=Gray;
         ObjectSetText(CurrPair[i]+Timeframe[j], "-", 35, "Calibri", col);   
         dist_Y = dist_Y+17;
      }
      dist_Y=4;
      dist_X=dist_X+40;     
   }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

Check

https://docs.mql4.com/series/iOpen

You are passing it a string for timeframe when it should be an integer. A string by definition is always 0.

 
mar:

Hi Forum,

This indicator should analyze all currency pairs in all timeframes by searching for a Pinbar. My definition of a Pinbar is this:

Long Pinbar = the lower shadow must be at least 75% of the whole candle. Short Pinbar the same with the upper shadow.

It is a very simple definition but I put more emphasis on the scanner itself. I don't know why it doesn't work. I see no logical error.

Besides one thing is also very confusing for me: When I change the timeframe in the window with the indicator, the results are different. Thats confusing because the indicator should analyze all timeframes regardless the window's timeframe.

Maybe someone can help?

PS. If you attach the indicator to your chart, please set all chart-colors to "None".


PERIOD_M1, PEROD_M5, etc are not strings they are constant names . . . at compile time they get replaced with the numeric equivalents. Click this --> PERIOD_M1, PEROD_M5
 
So obviously the problem is this expression?
"PERIOD_"+Timeframe[j]
But what can I do to solve this problem? Maybe creating a function which uses Timeframe[j] as a parameter and returns the integer value? I am not very familiar with functions, so I don't know if this is a correct solution..
 
//{Timeframe conversion utilities
string   tfAsText[]={   "n/a",   "M1",      "M5",      "M15",      "M30",
                                 "H1",      "H4",      "D1",       "W1"       };
int      tfPeriods[]={  0, PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30,
                           PERIOD_H1, PERIOD_H4, PERIOD_D1,  PERIOD_W1        };
int      ITFmaximum(){  return(8);                                      }  // W1
int      ITFtoPeriod(int iTf){      return(tfPeriods[iTf]);                   }
string   ITFtoPeriodText(int iTf){  return(tfAsText[iTf]);                    }
string   PeriodToText(int p=0){  return(ITFtoPeriodText( PeriodToITF(p) ));   }
int PeriodToITF(int p=0){  if(p == 0)  p = Period();
   for(int iTf = 1; p > tfPeriods[iTf]; iTf++){}
   return(iTf);                                                               }
//}Timeframe conversion utilities
 
Thanks, William! Although your solution was a little bit to complex for me but when I saw it, I got the idea to create another Array with the integer numbers of the timeframes. Now it works.
 
mar: Although your solution was a little bit to complex for me but when I saw it, I got the idea to create another Array with the integer numbers of the timeframes.
What's the difference between your idea and
int      tfPeriods[]={  0, PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30,
                           PERIOD_H1, PERIOD_H4, PERIOD_D1,  PERIOD_W1        };
int      ITFtoPeriod(int iTf){      return(tfPeriods[iTf]);                   }
 

I never worked with a function returning some value. I have no idea how to use it. Therefore I did it this way:

int TimeframeNo[7] = {PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1};

and then so:

         PinbarLong =   MathMax(iOpen(CurrPair[i], TimeframeNo[j], 1),iClose(CurrPair[i], TimeframeNo[j], 1))-
                        iLow(CurrPair[i], TimeframeNo[j], 1)
                        >= (iHigh(CurrPair[i], TimeframeNo[j], 1)-iLow(CurrPair[i], TimeframeNo[j], 1))*0.75;
         
         PinbarShort =  iHigh(CurrPair[i], TimeframeNo[j], 1)-
                        MathMax(iOpen(CurrPair[i], TimeframeNo[j], 1),iClose(CurrPair[i], TimeframeNo[j], 1))
                        >= (iHigh(CurrPair[i], TimeframeNo[j], 1)-iLow(CurrPair[i], TimeframeNo[j], 1))*0.75;
I don't know how to implement ITFtoPeriod into my code...
 

So, the basic indicator is finished and it works. But the last thing I want to do seems to be quite difficult.

As you can see, the indicator checks different time frames. But they are all checked on every tick.

My inner loop prints the result of each currency pair and the outer loop works with the different time frames. Now I would like to know if it is possible to let the indicator not update on every tick but on the timeframe which is shown. So the M5 column should only be updated on every M5 bar's open, the H1 loop should only be calculated at every H1 bar's open and so on. I can imagine that it is somehow possible to check the timeframe for the current loop and compare it with the current time. But I have no concrete idea how to do that. And I have also no idea what happens with D1 when the MetaTrader is offline at midnight. And the weekly would be even more complicated...

I would very thankful if someone helped my with that.

//+------------------------------------------------------------------+
//|                                                      Scanner.mq4 |
//|                                               Copyright 2013, MR |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MR"
#property link      ""

#property indicator_chart_window

int dist_X, dist_Y, i, j;
string Timeframe[] = {"M5", "M15", "M30", "H1", "H4", "D1", "W1"};
int TimeframeNo[] = {PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1};
string CurrPair[] = {"AUDCAD", "AUDCHF", "AUDJPY", "AUDNZD", "AUDUSD", "CADCHF", "CHFJPY", "EURAUD",
                     "EURCAD", "EURCHF", "EURGBP", "EURJPY", "EURNZD", "EURUSD", "GBPAUD", "GBPCAD",
                     "GBPCHF", "GBPJPY", "GBPNZD", "GBPUSD", "NZDJPY", "NZDUSD", "USDCAD", "USDCHF",
                     "USDJPY"};
bool PinbarLong, PinbarShort;
color col;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   ObjectsDeleteAll();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//---- Timeframe Objects ----
   dist_X = 80;
   for(i=0; i<=ArrayRange(Timeframe,0)-1; i++)
   {
      if (ObjectFind(Timeframe[i]+"txt") == -1)
      {
         ObjectCreate(Timeframe[i]+"txt", OBJ_LABEL, 0, 0, 0);
         ObjectSet(Timeframe[i]+"txt", OBJPROP_CORNER, 0);
         ObjectSet(Timeframe[i]+"txt", OBJPROP_XDISTANCE, dist_X);
         ObjectSet(Timeframe[i]+"txt", OBJPROP_YDISTANCE, 0);
         ObjectSetText(Timeframe[i]+"txt", Timeframe[i], 9, "Calibri", White);
         dist_X = dist_X+40;     
      }
   }
//---- Currency pairs objects ----
   dist_Y = 30;
   for(i=0; i<=ArrayRange(CurrPair,0)-1; i++)
   {
      if (ObjectFind(CurrPair[i]+"txt") == -1)
      {
         ObjectCreate(CurrPair[i]+"txt", OBJ_LABEL, 0, 0, 0);
         ObjectSet(CurrPair[i]+"txt", OBJPROP_CORNER, 0);
         ObjectSet(CurrPair[i]+"txt", OBJPROP_XDISTANCE, 0);
         ObjectSet(CurrPair[i]+"txt", OBJPROP_YDISTANCE, dist_Y);
         ObjectSetText(CurrPair[i]+"txt", CurrPair[i], 9, "Calibri", White);
         dist_Y = dist_Y+17;     
      }
   }
//---- Dot matrix ----   
   dist_X=80;
   dist_Y=4;
   for(j=0; j<=ArrayRange(Timeframe,0)-1; j++)
   {
      for(i=0; i<=ArrayRange(CurrPair,0)-1; i++)
      {
         ObjectCreate(CurrPair[i]+Timeframe[j], OBJ_LABEL, 0, 0, 0);
         ObjectSet(CurrPair[i]+Timeframe[j], OBJPROP_CORNER, 0);
         ObjectSet(CurrPair[i]+Timeframe[j], OBJPROP_XDISTANCE, dist_X);
         ObjectSet(CurrPair[i]+Timeframe[j], OBJPROP_YDISTANCE, dist_Y);
//-- Conditions --            
         PinbarLong =   MathMin(iOpen(CurrPair[i], TimeframeNo[j], 1),iClose(CurrPair[i], TimeframeNo[j], 1))-
                        iLow(CurrPair[i], TimeframeNo[j], 1)
                        >= (iHigh(CurrPair[i], TimeframeNo[j], 1)-iLow(CurrPair[i], TimeframeNo[j], 1))*0.75;
         
         PinbarShort =  iHigh(CurrPair[i], TimeframeNo[j], 1)-
                        MathMax(iOpen(CurrPair[i], TimeframeNo[j], 1),iClose(CurrPair[i], TimeframeNo[j], 1))
                        >= (iHigh(CurrPair[i], TimeframeNo[j], 1)-iLow(CurrPair[i], TimeframeNo[j], 1))*0.75;
//--            
         if (PinbarLong) col=Lime;
         else if (PinbarShort) col=Red;
         else col=Gray;
         ObjectSetText(CurrPair[i]+Timeframe[j], "-", 35, "Calibri", col);   
         dist_Y = dist_Y+17;
      }
      dist_Y=4;
      dist_X=dist_X+40;     
   }
   WindowRedraw();
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
mar:

So, the basic indicator is finished and it works. But the last thing I want to do seems to be quite difficult.

As you can see, the indicator checks different time frames. But they are all checked on every tick.

My inner loop prints the result of each currency pair and the outer loop works with the different time frames. Now I would like to know if it is possible to let the indicator not update on every tick but on the timeframe which is shown. So the M5 column should only be updated on every M5 bar's open, the H1 loop should only be calculated at every H1 bar's open and so on. I can imagine that it is somehow possible to check the timeframe for the current loop and compare it with the current time. But I have no concrete idea how to do that. And I have also no idea what happens with D1 when the MetaTrader is offline at midnight. And the weekly would be even more complicated...

I would very thankful if someone helped my with that.

It's very easy to do . . . search for "once per bar" on the forum and you should find what you need . . . use iTime() to check the time of the last bar off the timeframe you choose and if it hasn't changed don't do anything . . .
 

Hi Raptor,

there is one thing I don't get in my head... I would try it this way:

for(j=0; j<=ArrayRange(Timeframe,0)-1; j++)
   {
      if (iTime(CurrPair[i], TimeframeNo[j], 0)== ...........) return;
      for(i=0; i<=ArrayRange(CurrPair,0)-1; i++)
      {
         ObjectCreate(CurrPair[i]+Timeframe[j], OBJ_LABEL, 0, 0, 0);
         ObjectSet(CurrPair[i]+Timeframe[j], OBJPROP_CORNER, 0);
.....
.....

With iTime() I get the time-value of the bar which is addressed in the parameters. Let's assume it is AUDUSD, M15. So the result will be the (open)-time of the CURRENT M15 bar in the AUDUSD, correct?

My thinking-problem is this: I don't know with which timevalue I should compare it. When I use for example an Alert which should only be executed once a bar, I use static datetime Time0 = Time[0] and begin the int start() with if Time0==Time[0]... But in this case it seems to be different.

Reason: