Count bars from ParamDate

This would look like a repeat question. However, there's a key difference. Start and End Date is supplied by user using Param Window. Then need to count bars between the 2 dates.

(The objective is to modify the GFX-multi-chart afl and make it adjust to user provided dates). Now the afl uses "FOR" loops so barindex can't be used.

How should barindex be converted to barcount (if at all it can be)?

Posting my code which uses barindex (incorrectly so)

startdate = ParamDate("Start Date", "2020-12-05")  ;
enddate = ParamDate("End Date", "2020-12-05") ;
EntryTime=ParamTime("Entry Time","09:15:00",0);
ExitTime=ParamTime("Exit Time","15:30:00",0);

startBI = ValueWhen(DateNum()==StartDate AND EntryTime, BarIndex());
endBI = ValueWhen(DateNum()==EndDate AND ExitTime, BarIndex());	

start_bar_count = BarIndex() - startBI;
end_bar_count = BarIndex() - endBI;

Bars = (start_bar_count - end_bar_count) +1;
LastBar =  end_bar_count;
FirstBar =  LastBar - Bars;

Please help me!

I think your going wrong because you are not comparing the functions correctly.

If you get DateNum from ParamDate, then in the same way, your should use ParamTime() with TimeNum()

dt = DateNum();
tn = TimeNum();
bi = BarIndex();
startBI = ValueWhen( dt == startdate AND tn == EntryTime , bi );
endBI  = /*  homework */

now startBI will have the start Bar Index. Do same for End Bar.

Then you will not need all this.

start_bar_count = BarIndex() - startBI;
end_bar_count = BarIndex() - endBI;

Just read the manual and exact return from 'ValueWhen' then rewrite this part but the values will not need all this code.

Bars = (start_bar_count - end_bar_count) +1;
LastBar =  end_bar_count;
FirstBar =  LastBar - Bars;

So directly get the result values:

Bars = endBI - startBI + 1;
/* LastBar = same as endBI */
/* FirstBar = same as startBI */
1 Like

I will try what you have suggested in a short while. However, the reason variables "FirstBar" and "LastBar" are used is to plot data from and to certain points. Only using "Bars" variable, i think, provides only the number of bars to plot. Won't give the start and end points. Still, let me get back to you on this.

Edit: startBI and endBI should suffice. I will post now once I have completed my trials.

Thanks for your time.

If i am guessing it right the problem is due to use of barindex in the "FOR" loop. Some how need to convert the BarIndex value to correct BarCount to solve this.

Below is the AFL for your reference.


//FIle: Multi-Chart
//http://stockconnection.blogspot.com
//January 10, 2008 
//
//

// GFX Drawing Example

function GetMonth( MonthNumber ) 
{ 
         switch (MonthNumber) { 
            case 2 : 
              result = "Feb"; 
               break ; 
            case 3 : 
              result = "Mar"; 
              break ; 
            case 4 : 
              result = "Apr"; 
            break ; 
          case 5 : 
            result = "May"; 
            break ; 
          case 6 : 
            result = "Jun"; 
            break ; 
          case 7 : 
            result = "Jul"; 
            break ; 
          case 8 : 
            result = "Aug"; 
            break ; 
          case 9 : 
            result = "Sep"; 
            break ; 
          case 10 : 
            result = "Oct"; 
            break ; 
          case 11 : 
            result = "Nov"; 
            break ; 
          case 12 : 
            result = "Dec"; 
      break ; 
   } 

   return result; 
} 



GfxSetOverlayMode( 2 );

String = "" ;
for ( x = 0 ; x < 200 ; x++ ) 
{ 
        WList = CategoryGetName( categoryWatchlist, x );
         if (WList != "" )
        {
                 String = String + WList +","   ;
        }
}
WatchList = ParamList ( "Watch List", String ); 
for ( x = 0 ; x < 200 ; x++ ) 
{ 
        sym = StrExtract ( String, x );
         if (sym == WatchList)
        {
                 listNum = x  ;
        }
}

BarsS =Param ( "Number Of Bars", 450 , 50 , 750 , 1 ) ;   
startdate = ParamDate("Start Date", "2020-12-05")  ;
enddate = ParamDate("End Date", "2020-12-05") ;
EntryTime=ParamTime("Entry Time","09:15:00",0);
ExitTime=ParamTime("Exit Time","15:30:00",0);
bars_or_date = ParamToggle("Bars or Dates","UsingDates|UsingBars",1);

dt = DateNum();
tn = TimeNum();
bi = BarIndex();
startBI = ValueWhen( dt == startdate AND tn == EntryTime , bi );
endBI  =  ValueWhen( dt == enddate AND tn == ExitTime , bi );

if(bars_or_date)
{
Bars = BarsS;
LastBar =  BarCount ;
FirstBar =  LastBar - Bars;
}
else
{
Bars = endBI - startBI + 1;
LastBar = endBI;
FirstBar = startBI;
}


Page = Param ( "Page #", 0 , 0 , 12 , 1 );
ChartsWiNum = Param ( "# Charts Wide", 3 , 1 , 4 , 1 );
ChartsHiNum = Param ( "# Charts High", 3 , 1 , 4 , 1 );
//Bars =Param ( "Number Of Bars", 195 , 50 , 250 , 1 ) ;   
lDays =Param ( "Long MA", 200 , 50 , 250 , 1 ) ;
sDays =Param ( "Short MA", 50 , 5 , 100 , 1 ) ;
vDays =Param ( "Volume MA", 50 , 5 , 100 , 1 ) ;
ChartMargin = 5 ;
DateMargin = 10 ;
DataMargin = 20 ;
NumCharts = ChartsWiNum * ChartsHiNum ;
ScreenHeight = Status ( "pxheight" )  ;
SceernWidth = Status ( "pxwidth" ) ;
ChartHeight = ScreenHeight / ChartsHiNum -2   ;
Width = SceernWidth / ChartsWiNum - 2 ;
BarChartHeight=  (0.75 ) * ChartHeight - DataMargin;
VolChartHeight = ChartHeight - BarChartHeight - DataMargin*2 ;
NumberPriceLevels = BarChartHeight / 25 ;
BarChartWidth=  Width - 45 ;
BarWidth = (BarChartWidth - ChartMargin * 3 ) / Bars  ;
LastBar =  BarCount ;
FirstBar =  LastBar - Bars;
_N (list = CategoryGetSymbols( categoryWatchlist, listnum ));
printf ( "Watch List Name\n");
WL = CategoryGetName( categoryWatchlist, listnum );
SymbolNum = Page * NumCharts;

for ( x = 0 ; x < ChartsHiNum ; x++ ) 
{ 
         for ( i = 0 ; i < ChartsWiNum ; i++ ) 
        { 
                 notDone = True;
                 sym = StrExtract ( list, SymbolNum );
                  if (sym != "" )
                 {
                 x1 = Width * i + 5 ; 
                 y1 = ChartHeight * x + 5 ;
                 x2 = Width * (i + 1 );
                 y2 = ChartHeight * (x + 1 )-DateMargin;
                  GfxSelectPen ( colorBlack ); 
                  GfxRectangle ( x1, y1, x2, y2 );
                 SymbolNum++;

                  SetForeign (sym);

                 EMAShort= EMA (C,sDays);
                 EMALong= EMA (C,lDays);
                 EMAVol= EMA (V,vDays);

                 D = Day ();
                 M = Month ();
                 Y = Year ();

                 priceHigh = 0 ;
                 VolHigh = 0 ;
                 priceMin = 1000000 ;
                  for ( z = FirstBar; z < LastBar ; z++ ) 
                 { 
                          Vol = V[z];
                          BarH = H[z];
                          BarL = L[z];
                           if ( Vol > VolHigh ) 
                          { 
                                   VolHigh = Vol;
                          }
                           if ( BarH > priceHigh ) 
                          { 
                                   priceHigh = BarH;
                          }
                           if ( BarL < priceMin ) 
                          { 
                                   priceMin = BarL;
                          }
                 }

                 LOpen = O[LastBar- 1];
                 LHigh = H[LastBar- 1];
                 LLow = L[LastBar- 1];
                 LClose = C[LastBar- 1];
                 LVol = V[LastBar- 1];
                  GfxSelectFont ( "Tahoma" , 8 ); 
                  GfxSetTextColor (colorBlack); 
                  GfxTextOut (sym + "   O: " +LOpen + "   H: " +LHigh + "   L: " +LLow + "   C: " +LClose + "   Vol: " +LVol/ 1000000 + " M", x1+5 , y1+2 ); 

                 VolRatio = VolChartHeight /  VolHigh ;
                 Range = priceHigh - priceMin;
                 Ratio = BarChartHeight / Range ;
                 PriceLineLevel = Range / NumberPriceLevels;
                 yHi=(((priceHigh - priceMin )* Ratio) - BarChartHeight) * -1 + y1 + DataMargin;
                  GfxTextOut ( WriteVal (priceHigh, 1.2 ),   x1 + BarChartWidth, yHi -8 );
                  GfxSelectPen ( colorLightGrey ); 
                  GfxMoveTo ( x1 , yHi );
                  GfxLineTo ( x1 + BarChartWidth -5 , yHi );
                  for ( z = 0 ; z < NumberPriceLevels- 1   ; z++ ) 
                 { 
                          PriceLevel = PriceLineLevel*z + priceMin;

                          yHi=(((PriceLevel - priceMin )* Ratio) - BarChartHeight) * -1 + y1 + DataMargin;
                           GfxTextOut ( WriteVal (PriceLevel, 1.2 ),   x1 + BarChartWidth, yHi -8 );
                           GfxSelectPen ( colorLightGrey ); 
                           GfxMoveTo ( x1 , yHi );
                           GfxLineTo ( x1 + BarChartWidth -5 , yHi );
                 }

                 HighestLast = 0 ;
                 w = 1 ;
                 sEMAlast = EMAShort[FirstBar];
                 lEMAlast = EMALong[FirstBar];
                 vEMAlast = EMAVol[FirstBar];
                  for ( z = FirstBar; z < LastBar ; z++ ) 
                 {
                          BarH = H[z];
                          BarL = L[z];
                          BarO = O[z];
                          BarC = C[z];
                          Vol = V[z];
                          sEMA = EMAShort[z];
                          lEMA = EMALong[z];
                          vEMA = EMAVol[z];
                          BarDay = D[z];
                          BarMonth = M[z];
                          BarYear = Y[z];

                          yO = (((BarO - priceMin )* Ratio)- BarChartHeight ) * -1 + y1 + DataMargin;
                          yC = (((BarC - priceMin )* Ratio)- BarChartHeight ) * -1 + y1 + DataMargin;
                          yHi = (((BarH - priceMin )* Ratio)- BarChartHeight ) * -1 + y1 + DataMargin;
                          yLo = (((BarL - priceMin )* Ratio) - BarChartHeight) * -1 + y1 + DataMargin ;
                          ysEMAlast = (((sEMAlast - priceMin )* Ratio) - BarChartHeight) * -1 + y1 + DataMargin;
                          ysEMA = (((sEMA - priceMin )* Ratio) - BarChartHeight) * -1 + y1 + DataMargin;
                          ylEMAlast = (((lEMAlast - priceMin )* Ratio) - BarChartHeight) * -1 + y1 + DataMargin;
                          ylEMA = (((lEMA - priceMin )* Ratio) - BarChartHeight) * -1 + y1 + DataMargin;
                          vHi = y2 - (Vol * VolRatio)  ;
                          yvEMAlast = y2 - (vEMAlast  * VolRatio) ;
                          yvEMA = y2 - (vEMA * VolRatio)  ;
                          
                           if ( BarH > HighestLast ) 
                          { 
                                   HighestLast = BarH;
                                    GfxSelectPen ( colorBlue );
                          }

                           else
                          { 
                                    GfxSelectPen ( colorRed );
                          }
								// Plot bar
                           GfxMoveTo ( BarWidth * w + x1 + ChartMargin , yHi );
                           GfxLineTo ( BarWidth * w + x1 + ChartMargin, yLo );
                           GfxMoveTo ( BarWidth * w + x1 + ChartMargin -1   , yO );
                           GfxLineTo ( BarWidth * w + x1 + ChartMargin, yO );
                           GfxMoveTo ( BarWidth * w + x1 + ChartMargin +1   , yC );
                           GfxLineTo ( BarWidth * w + x1 + ChartMargin, yC );
                           if ( BarO > BarC)
                          {
                                    GfxSelectPen ( colorRed ); 
                          }
                           else
                          { 
                                    GfxSelectPen ( colorLime );
                          }
								// Plot Volume
                           GfxMoveTo ( BarWidth * w + x1 + ChartMargin , vHi );
                           GfxLineTo ( BarWidth * w + x1 + ChartMargin, y2 );

								// Plot Price and Volume EMAs
                           GfxSelectPen ( colorLime ); 
                           GfxMoveTo ( BarWidth * (w -1 ) + x1  + ChartMargin , ysEMAlast );
                           GfxLineTo ( BarWidth * w + x1 + ChartMargin, ysEMA );
                           GfxSelectPen ( colorDarkRed ); 
                           GfxMoveTo ( BarWidth * (w -1 ) + x1  + ChartMargin , ylEMAlast );
                           GfxLineTo ( BarWidth * w + x1 + ChartMargin, ylEMA );
                           GfxSelectPen ( colorBlack ); 
                           GfxMoveTo ( BarWidth * (w -1 ) + x1  + ChartMargin , yvEMAlast );
                           GfxLineTo ( BarWidth * w + x1 + ChartMargin, yvEMA );
                          w++;
                          
                          sEMAlast = sEMA ;
                          lEMAlast = lEMA ;
                          vEMAlast = vEMA ;
                          
                           GfxSelectFont ( "Tahoma" , 7 ); 
                           GfxSelectPen ( colorLightGrey ); 

								// Draw vertical month separator and X-axis labels
                           if (BarDay== 1 & notDone )
                          {
                                    if (BarMonth == 1 ) myLabel =WriteVal (BarYear, 1.0 );                                  
                                    else myLabel =GetMonth(BarMonth);
                                    GfxTextOut (myLabel,   BarWidth * w + x1 + ChartMargin - 5 , y2 +DateMargin/3 );
                                    GfxMoveTo ( BarWidth * w + x1 + ChartMargin , y2  );
                                    GfxLineTo ( BarWidth * w + x1 + ChartMargin, y1 + DataMargin  );
                                   notDone = False;
                          }

                           if (BarDay== 2 & notDone )
                          {
                                    if (BarMonth == 1 ) myLabel =WriteVal (BarYear, 1.0 );
                                    else myLabel =GetMonth(BarMonth);
                                    GfxTextOut (myLabel,   BarWidth * w + x1 + ChartMargin - 5 , y2 +DateMargin/3 );
                                    GfxMoveTo ( BarWidth * w + x1 + ChartMargin , y2  );
                                    GfxLineTo ( BarWidth * w + x1 + ChartMargin, y1 + DataMargin  );
                                   notDone = False;
                          }

                           if (BarDay== 3 & notDone )
                          {
                                    if (BarMonth == 1 ) myLabel =WriteVal (BarYear, 1.0 );
                                    else myLabel =GetMonth(BarMonth);
                                    GfxTextOut (myLabel,   BarWidth * w + x1 + ChartMargin - 5 , y2 +DateMargin/3 );
                                    GfxMoveTo ( BarWidth * w + x1 + ChartMargin , y2  );
                                    GfxLineTo ( BarWidth * w + x1 + ChartMargin, y1 + DataMargin  );
                                   notDone = False;
                          }

                           if (BarDay== 4 & notDone )
                          {
                                    if (BarMonth == 1 ) myLabel =WriteVal (BarYear, 1.0 );
                                    else myLabel =GetMonth(BarMonth);
                                    GfxTextOut (myLabel,   BarWidth * w + x1 + ChartMargin - 5 , y2 +DateMargin/3 );
                                    GfxMoveTo ( BarWidth * w + x1 + ChartMargin , y2  );
                                    GfxLineTo ( BarWidth * w + x1 + ChartMargin, y1 + DataMargin  );
                                   notDone = False;
                          }

                           if (BarDay== 5 & notDone )
                          {
                                    if (BarMonth == 1 ) myLabel =WriteVal (BarYear, 1.0 );
                                    else myLabel =GetMonth(BarMonth);
                                    GfxTextOut (myLabel,   BarWidth * w + x1 + ChartMargin - 5 , y2 +DateMargin/3 );
                                    GfxMoveTo ( BarWidth * w + x1 + ChartMargin , y2 - VolChartHeight );
                                    GfxLineTo ( BarWidth * w + x1 + ChartMargin, y1 + DataMargin );
                                   notDone = False;
                          }
                           if (BarDay== 6 |BarDay== 7 |BarDay== 8 |BarDay== 9 |BarDay== 10 )
                          {
                                   notDone = True;
                          }
                                                     
                 }
                  RestorePriceArrays (); 
                 }
        } 
}

1 Like

Hello @vtriv,

Based on your original post, the main objective is to determine how many bars (quotes) there are between two dateTime values.

I suspect that the following code from your post last won't work (correctly) when one of the components doesn't exit, eg there isn't a quote in the database that exactly matches what the user specified:
startBI = ValueWhen( dt == startdate AND tn == EntryTime , bi );

The following might help to achieve the objective, but doesn't use BarIndex():

// Get the user inputs
selStartdate 	= ParamDate("Start Date", "2020-12-05", 0)  ;		// Returns a dateNum
selEnddate 		= ParamDate("End Date", "2020-12-15", 0) ;			
selEntryTime	= ParamTime("Entry Time","09:15:00", 0) ;			// Returns a timeNum
selExitTime		= ParamTime("Exit Time","15:30:00", 0) ;

//selEndDate		= 1201215 ;		// Force AB to have diff date, needed in debug mode, because AB doesn't re-read any in-editor changes to Param()

// Get bar info
cnsInterval		= Interval(0) ;
arrBarDate		= DateNum() ;
arrBarTime		= TimeNum() ;

// Create an array of true(1)/false(0) values
	// EoD quotes have a time of "0" (midnight), and entry/exit _time_ is irrelevant
if (cnsInterval >= inDaily)
{
	// For debugging purposes - check that each condition is "working" properly
		// Wrong specification
	cndBarGtLo		= ((selStartDate >= arrBarDate)) ;
	cndBarLtHi		= ((selEndDate <= arrBarDate)) ;
		// Right way of specifying
	cndBarGtLo		= ((arrBarDate >= selStartDate)) ;
	cndBarLtHi		= ((arrBarDate <= selEndDate)) ;
		// Where do the two conditions overlap
	cndBarInLoHi	= cndBarGtLo AND cndBarLtHi ;
	// All-in-one, assumes we also count the start and end date/times
	cndBarInRange	= ((arrBarDate >= selStartDate)) AND ((arrBarDate <= selEndDate)) ;
}
else
{
	// For debugging purposes - check that each condition is "working" properly
		// Wrong specification
	cndBarGtLo		= ((selStartDate >= arrBarDate) AND (selEntryTime >= arrBarTime)) ;
	cndBarLtHi		= ((selEndDate <= arrBarDate) AND (selExitTime <= arrBarTime)) ;
		// Right specification
	cndBarGtLo		= ((arrBarDate >= selStartDate) AND (arrBarTime >= selEntryTime)) ;
	cndBarLtHi		= ((arrBarDate <= selEndDate) AND (arrBarTime <= selExitTime)) ;
		// Where do the two conditions overlap
	cndBarInLoHi	= cndBarGtLo AND cndBarLtHi ;
	// All-in-one, assumes we also count the start and end date/times
	cndBarInRange	= ((arrBarDate >= selStartDate) AND (arrBarTime >= selEntryTime)) AND ((arrBarDate <= selEndDate) AND (arrBarTime <= selExitTime)) ;
}

// Get the number
cumBarsA		= Cum(cndBarInLoHi) ;
cumBarsB		= Cum(cndBarInRange) ;
numBarsInRangeA	= LastValue(cumBarsA) ;
numBarsInRangeB	= LastValue(cumBarsB) ;


debugInfo			= " numBarsInRange: A=" + NumToStr(numBarsInRangeA, 1.0) +  " B=" + NumToStr(numBarsInRangeB, 1.0) ;


And here's a more compact version:

// Get the user inputs
selStartdate 	= ParamDate("Start Date", "2020-12-05", 0)  ;		// Returns a dateNum
selEnddate 		= ParamDate("End Date", "2020-12-15", 0) ;				// Changed the date to force a difference
selEntryTime	= ParamTime("Entry Time","09:15:00", 0) ;			// Returns a timeNum
selExitTime		= ParamTime("Exit Time","15:30:00", 0) ;

// Get bar info
cnsInterval		= Interval(0) ;
arrBarDate		= DateNum() ;
arrBarTime		= TimeNum() ;

// Create an array of true(1)/false(0) values
	// EoD quotes have a time of "0" (midnight), and entry/exit _time_ is irrelevant
if (cnsInterval >= inDaily)
{
	cndBarInRange	= ((arrBarDate >= selStartDate)) AND ((arrBarDate <= selEndDate)) ;
}
else
{
	cndBarInRange	= ((arrBarDate >= selStartDate) AND (arrBarTime >= selEntryTime)) AND ((arrBarDate <= selEndDate) AND (arrBarTime <= selExitTime)) ;
}

// Get the number
numBarsInRangeB	= LastValue(Cum(cndBarInRange)) ;

It would be faster and shorter to use Lookup http://www.amibroker.com/f?lookup

bi = BarIndex();
barsbetween =  Lookup( bi, _DT( "2020-12-15 09:15:00" ), -1 ) - Lookup( bi, _DT( "2020-12-05 15:30:00" ), -1 );
8 Likes

Thanks for your responses. Really grateful. And, apologies for this late reply.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.