WindowsScreenshot function hides indicator lines

 

Hello everyone, I want to take a screenshot every time a certain event happen. In this example I take a screenshot every time a MA upward crossover happen:

int OnCalculate(
   const int      rates_total,
   const int      prev_calculated,
   const datetime &time[],
   const double   &open[],
   const double   &high[],
   const double   &low[],
   const double   &close[],
   const long     &tick_volume[],
   const long     &volume[],
   const int      &spread[]
)
  {
// Define maximum index for the buffer array

   int lookback = 100; //trying to display 1D open on last 100 1h candles
// Replacing loop function with the one you pointed out
   for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar)
     {

      buff_average[iBar] = iMA(Symbol(),0,60,0,1,0,iBar);


      if(iBar<200 && Close[iBar]>buff_average[iBar] && Close[iBar+1]<buff_average[iBar+1])
        {
         ObjectCreate(0,StringConcatenate("h"+IntegerToString(iBar)),OBJ_VLINE,0,Time[iBar+1],Close[iBar]);
         ObjectSetInteger(0,StringConcatenate("h"+IntegerToString(iBar)),OBJPROP_COLOR,clrAqua);
         
         WindowScreenShot("Crossover screen"+"\\"+TimeDay(Time[iBar])+"-"+TimeMonth(Time[iBar])+"-"+TimeYear(Time[iBar])+".png",1200,1200,iBar+40,-3,1);
        }

     }
   return rates_total-1; // Recalculate current bar next tick.
// Return value of prev_calculated for next call
  };

Unfortunately results are quite unsatisfying, in fact it take the screenshot but everything after the "iBar" location of the screenshots is not being showed, here's a couple of outputs:



Please note I can't use the MoveChart function combined with ChartScreenshot as a solution because that produces screenshots where I'm not able to locate properly the thing I want to look at (I need this on something more complicated than a MA crossover). Currently the only solution would be to make the screenshot event a bool and loading the indicator two times, one with screenshot enabled and one without it. Any other ideas? Thank's

 
ironhak:

Unfortunately results are quite unsatisfying, in fact it take the screenshot but everything after the "iBar" location of the screenshots is not being showed, here's a couple of outputs:

Don't you think it's strange that this is related to "iBar"?

Your screenshots are taken when the OnCalculate() is executed for the first time.

Look here:

{
// Define maximum index for the buffer array

   int lookback = 100 ; //trying to display 1D open on last 100 1h candles
// Replacing loop function with the one you pointed out
   for ( int iBar = Bars - 1 - MathMax (lookback, prev_calculated); iBar >= 0 ; --iBar)
     {

      buff_average[iBar] = iMA ( Symbol (), 0 , 60 , 0 , 1 , 0 ,iBar);


       if (iBar< 200 && Close[iBar]>buff_average[iBar] && Close[iBar+ 1 ]<buff_average[iBar+ 1 ])
        {
         ObjectCreate ( 0 , StringConcatenate ( "h" + IntegerToString (iBar)), OBJ_VLINE , 0 ,Time[iBar+ 1 ],Close[iBar]);
         ObjectSetInteger ( 0 , StringConcatenate ( "h" + IntegerToString (iBar)), OBJPROP_COLOR , clrAqua );
         
         WindowScreenShot( "Crossover screen" + "\\" +TimeDay(Time[iBar])+ "-" +TimeMonth(Time[iBar])+ "-" +TimeYear(Time[iBar])+ ".png" , 1200 , 1200 ,iBar+ 40 ,- 3 , 1 );
        }

     }
   return rates_total- 1 ; // Recalculate current bar next tick.
// Return value of prev_calculated for next call
  };


MA values for bars to the right of "iBar" will be calculated after the screenshot. Remember that your screenshots are taken when prev_calculated = 0

 
ironhak:

Hello everyone, I want to take a screenshot every time a certain event happen. In this example I take a screenshot every time a MA upward crossover happen:

This happens either on bars 1 and 2, or on bars 0 and 1. Why do you need a cycle? Why do you need a lookback?

When a new bar appears, check the intersection on the last 2 bars. This is enough to take a screenshot every time a MA upward crossover happen.


If you have an MA buffer, then calculate it separately and before checking the signal. Not in the same cycle

 
Vladislav Boyko #:

This happens either on bars 1 and 2, or on bars 0 and 1. Why do you need a cycle? Why do you need a lookback?

When a new bar appears, check the intersection on the last 2 bars. This is enough to take a screenshot every time a MA upward crossover happen.


If you have an MA buffer, then calculate it separately and before checking the signal. Not in the same cycle

Yes, I get it thank you. 

So if I create a "for" loop inside OnCalculate and make it so that it runs only when iBar==0, would that be a solution? Thank's.

 

Ok, I managed to do it, this seems to work well. 

   int lookback = 100; //trying to display 1D open on last 100 1h candles
// Replacing loop function with the one you pointed out
   for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar)
     {

      buff_average[iBar] = iMA(Symbol(),0,60,0,1,0,iBar);

      if(iBar==0 && stop == true)
        {
         for(int i=0; i<200; i++)
           {

            if(i<200 && Close[i]>buff_average[i] && Close[i+1]<buff_average[i+1])
              {
               ObjectCreate(0,StringConcatenate("h"+IntegerToString(i)),OBJ_VLINE,0,Time[i+1],Close[i]);
               ObjectSetInteger(0,StringConcatenate("h"+IntegerToString(i)),OBJPROP_COLOR,clrAqua);

               WindowScreenShot("Crossover screen"+"\\"+TimeDay(Time[i])+"-"+TimeMonth(Time[i])+"-"+TimeYear(Time[i])+i+".png",1200,1200,i+40,-3,1);
               ObjectDelete(0,StringConcatenate("h"+IntegerToString(i)));
              }
           }

        }
 
ObjectCreate ( 0 , StringConcatenate ( "h" + IntegerToString (iBar)), OBJ_VLINE , 0 ,Time[iBar+ 1 ],Close[iBar]);
ObjectSetInteger ( 0 , StringConcatenate ( "h" + IntegerToString (iBar)), OBJPROP_COLOR , clrAqua );

Do not use series index in object names, as they are not unique. As soon as a new bar starts, you will be trying to create a new name (e.g., “name0”), same, existing, previous, name (e.g., “name0” now on bar one.)

Use time (as int) or a non-series index:

#define  SERIES(I)   (Bars - 1 - I) // As-series to non-series or back.
 
William Roeder #:

Do not use series index in object names, as they are not unique. As soon as a new bar starts, you will be trying to create a new name (e.g., “name0”), same, existing, previous, name (e.g., “name0” now on bar one.)

Use time (as int) or a non-series index:

Hello, thank you. 

I have another question, with adding the string ".png" at the end of the image file name creates a .png image, but it's a .gif image in fact some sites does not recognize it as .png. Is there a way to native save the file as .png given the fact that adding the string ".png" does not work?

 
ironhak #:

Hello, thank you. 

I have another question, with adding the string ".png" at the end of the image file name creates a .png image, but it's a .gif image in fact some sites does not recognize it as .png. Is there a way to native save the file as .png given the fact that adding the string ".png" does not work?

Seems like there is no easy way. You can convert the image manually before posting.


 
ironhak #: with adding the string ".png" at the end of the image file name creates a .png image,

Changing the extension of a file changes nothing but the name. It does not create a different type.