ChartSetSymbolPeriod() and a problem with the message queue

 

Hi coders,

here is a little test script I made. My problem is that I would like to switch timeframes and do something when the timeframe has changed. But the problem is that ChartSetSymbolPeriod() is not executed immediately and so everything after that will be executed on the timeframe before. Does someone has an idea how to solve that problem?

void OnStart()
  {
//---
   ChartSetSymbolPeriod(0, _Symbol, PERIOD_MN1);
   ChartScreenShot(0, "test.gif", 1280, 720);  
  }

 This script always saves a screenshot of the chart before switching to the MN1.

 
mar:

Hi coders,

here is a little test script I made. My problem is that I would like to switch timeframes and do something when the timeframe has changed. But the problem is that ChartSetSymbolPeriod() is not executed immediately and so everything after that will be executed on the timeframe before. Does someone has an idea how to solve that problem?

 This script always saves a screenshot of the chart before switching to the MN1.

"Changes the symbol and period of the specified chart. The function is asynchronous, i.e. it sends the command and does not wait for its execution completion. The command is added to chart message queue and executed only after all previous commands have been processed."

https://docs.mql4.com/chart_operations/chartsetsymbolperiod

 
ggekko:

"Changes the symbol and period of the specifiedchart. The function is asynchronous, i.e. it sends the command and doesnot wait for its execution completion. The command is added to chartmessage queue and executed only after all previous commands have beenprocessed."

https://docs.mql4.com/chart_operations/chartsetsymbolperiod

Well, finally it is asynchronous, but in the beginning it really was synchronous, i.e. it ran deinit(), changed the period, then init() and then it continued with a command following the ChartSetSymbolPeriod. A complete disaster.
 
@ggekko: Yes, I read that. I also mentioned in my question that it is not executed immediately. So I know I can't use ChartSetSymbolPeriod(). But do you have an idea how to solve this problem?
 
mar:
@ggekko: Yes, I read that. I also mentioned in my question that it is not executed immediately. So I know I can't use ChartSetSymbolPeriod(). But do you have an idea how to solve this problem?
Check whether the timeframe has been changed or not . If yes, then make the screenshot.
 
In this case it would work but if I use it in a more complex indicator it's not so easy to implement. I think I will try it by using the user32.dll.
 

You need a flag that can survive the reinit. Example using an EA:

#property strict
   
bool FirstRun=true;

int OnInit()
  {
   EventSetTimer(3);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTick()
  {
  }

void OnTimer()
  {
   if(FirstRun)
     {
      FirstRun=false;
      Print("Changing timeframe");
      ChartSetSymbolPeriod(0,NULL,PERIOD_MN1);
     }
   else
     {
      EventKillTimer();
      Print("Taking screenshot");
      ChartScreenShot(0,"Screenshot.png",1024,768);
     }  
  }
 
I never worked with a timer but I'll give it a try. Thanks you!
 

alternatively, you can just wait until it is changed (in case you don't mind to wait here and loose the asynchronity)

void OnStart()  
{
//---   
ChartSetSymbolPeriod(0, _Symbol, PERIOD_MN1);   
while (ChartSymbol(0) != _Symbol && ChartPeriod(0) != PERIOD_MN1)
{
   Sleep(1500); 
}
ChartScreenShot(0, "test.gif", 1280, 720);   
}
 
That won't work Amir, on chart change you go through a deinit/init cycle witch won't happen in the while loop.
 
I know that, WHRoeder, I thought that what Ovo said earliear in this thread - "Well, finally it is asynchronous, but in the beginning it really was synchronous, i.e. it ran deinit(), changed the period, then init() and then it continued with a command following the ChartSetSymbolPeriod. A complete disaster." - meant that it doesn't happen anymore. If it still runs through you are right of course.
Reason: