I guess it's time for a question

 

Hey, Folks

Some of you have corresponded with me in previous threads and may remember me saying that I wouldn't come with questions unless I needed to. I guess the time has come. I've been working on an indicator that I plan to sell and have encountered a situation that I can't find a way to remedy. I've spent more than a week searching, researching and trying every and anything I can think of to no avail. What I've devised is a very useful tool but unless I can remedy this last piece, I won't offer it for sale. As a software professional my ethics won't allow me to offer a product that doesn't cover all the bases. The indicator is a money management tool that is designed to provide information on risk, lot sizes, pip values, etc. based on user adjustable parameters for any currency pair and account denomination. It works perfectly with one exception. I want to be sure that if there is an unexpected shutdown of the trading platform that the platform can be restarted with full knowledge of its state at the time of shutdown. Unfortunately, if I shut the platform down and restart it, things go totally South. This is a copy of the log I've generated by using Alerts in the code to track the execution of the program:

00:55:45 LotSizeCalculator EURNZD,M5: Alert: In EURNZD Init() - Monetary Risk is: 7.22 Pip Value is: 0.24Lot size is: 0.02
00:55:45 LotSizeCalculator EURNZD,M5: initialized
00:55:45 TA_1.14b EURNZD,M5: initialized
00:55:45 Stochastic EURNZD,M5: initialized
00:55:46 LotSizeCalculator EURNZD,M5: Alert: In beginning of EURNZD Start() block - Monetary Risk is: 7.22 Pip Value is: 0.24 Account Currency is:  Number of open trades: 0
00:55:46 LotSizeCalculator EURNZD,M5: Alert: In IsTradeInProgress() for EURNZD Number of open orders is 0
00:55:46 LotSizeCalculator EURNZD,M5: Alert: In EURNZD GetMonetaryRisk - Monetary Risk is: 7.22 Pip Value is: 0.24
00:55:46 LotSizeCalculator EURNZD,M5: Alert: In GetUnitCost for pair EURNZDBase Currency is: EUR
00:55:46 LotSizeCalculator EURNZD,M5: Alert: In GetUnitCost for pair EURNZDQuote Currency is: NZD
00:55:46 LotSizeCalculator EURNZD,M5: Alert: In GetUnitCost for pair EURNZDAccount Currency is: 
00:55:46 LotSizeCalculator EURNZD,M5: Alert: In GetUnitCost for pair EURNZD Ask Pair is:         NZD
00:55:46 LotSizeCalculator EURNZD,M5: zero divide
00:55:47 LotSizeCalculator EURNZD,M5: Alert: In beginning of EURNZD Start() block - Monetary Risk is: 7.22 Pip Value is: 0.24 Account Currency is:  Number of open trades: 0
00:55:47 LotSizeCalculator EURNZD,M5: Alert: In IsTradeInProgress() for EURNZD Number of open orders is 0
00:55:47 LotSizeCalculator EURNZD,M5: Alert: In beginning of EURNZD Start() block - Monetary Risk is: 7.22 Pip Value is: 0.24 Account Currency is: USD Number of open trades: 1
00:55:47 LotSizeCalculator EURNZD,M5: Alert: In IsTradeInProgress() for EURNZD Number of open orders is 1
00:55:49 LotSizeCalculator EURNZD,M5: Alert: In beginning of EURNZD Start() block - Monetary Risk is: 7.22 Pip Value is: 0.24 Account Currency is: USD Number of open trades: 1
00:55:49 LotSizeCalculator EURNZD,M5: Alert: In IsTradeInProgress() for EURNZD Number of open orders is 1
00:55:49 LotSizeCalculator EURNZD,M5: Alert: In beginning of EURNZD Start() block - Monetary Risk is: 7.22 Pip Value is: 0.24 Account Currency is: USD Number of open trades: 1
00:55:49 LotSizeCalculator EURNZD,M5: Alert: In IsTradeInProgress() for EURNZD Number of open orders is 1
00:55:49 Quik_Trailing EURNZD,M5: initialized
00:55:49 LotSizeCalculator EURNZD,M5: Alert: In beginning of EURNZD Start() block - Monetary Risk is: 7.22 Pip Value is: 0.24 Account Currency is: USD Number of open trades: 1
00:55:49 LotSizeCalculator EURNZD,M5: Alert: In IsTradeInProgress() for EURNZD Number of open orders is 1

As you can see, there is some weird crap going on at the restart of the terminal and re-initialization of the charts. The zero divide is happening because it doesn't know what the account currency is. Why the server isn't giving me that when it should and why it doesn't know that there are trades in progress is probably at the heart of later problems. For example, I should be getting an alert when it goes into the IsTradeInProgress() method but I don't. The Alert is the very first statement in the method. It apparently blows out on that but all it's doing is saying, "Hey, I'm in this method and the number of open orders is x."

I'm mystified by why it runs through the Start() method multiple times before it knows what the account currency is and that there are open orders as well as to why it blows a cork on the Alert. I can remove the indicator from the chart and put it back and it re-initializes and runs perfectly or I can change time frames and it re-initializes and runs perfectly. In addition, when I place a trade everything works like a charm. It's just when I shut the platform down and re-start it that things go gaga.

Has anyone else encountered this sort of thing? Is it a MetaTrader flaw that I'm just going to have to live with and give users a workaround in the documentation if I market the thing? BTW, the only information I'm going after in the Init() function is terminal globals that I've saved so that necessary info can be persisted if the terminal is shut down and re-started. I'm not doing any calculations of any kind or querying the server for any information until I hit the Start() function. I can provide code if necessary but since I want to take this commercial I'd rather not.

I'll be majorly grateful for any advice or insights that anyone can provide. I'm about to pull my hair out. :-)

Thanks,

Jeff

 
ProfessorMetal:

Hey, Folks

00:55:46 LotSizeCalculator EURNZD,M5: zero divide

Jeff


that is the problem restarting.....

Check if some where in the code is done something like

PipsProfit = PipsProfitPerLot/lots;

then see what happens if you change it like

if(lots>0)PipsProfit = PipsProfitPerLot/lots;

test it closing account and restart

 
ProfessorMetal:

Hey, Folks

Some of you have corresponded with me in previous threads and may remember me saying that I wouldn't come with questions unless I needed to. I guess the time has come. I've been working on an indicator that I plan to sell and have encountered a situation that I can't find a way to remedy. I've spent more than a week searching, researching and trying every and anything I can think of to no avail. What I've devised is a very useful tool but unless I can remedy this last piece, I won't offer it for sale. As a software professional my ethics won't allow me to offer a product that doesn't cover all the bases. The indicator is a money management tool that is designed to provide information on risk, lot sizes, pip values, etc. based on user adjustable parameters for any currency pair and account denomination. It works perfectly with one exception. I want to be sure that if there is an unexpected shutdown of the trading platform that the platform can be restarted with full knowledge of its state at the time of shutdown. Unfortunately, if I shut the platform down and restart it, things go totally South. This is a copy of the log I've generated by using Alerts in the code to track the execution of the program:

As you can see, there is some weird crap going on at the restart of the terminal and re-initialization of the charts. The zero divide is happening because it doesn't know what the account currency is. Why the server isn't giving me that when it should and why it doesn't know that there are trades in progress is probably at the heart of later problems. For example, I should be getting an alert when it goes into the IsTradeInProgress() method but I don't. The Alert is the very first statement in the method. It apparently blows out on that but all it's doing is saying, "Hey, I'm in this method and the number of open orders is x."

I'm mystified by why it runs through the Start() method multiple times before it knows what the account currency is and that there are open orders as well as to why it blows a cork on the Alert. I can remove the indicator from the chart and put it back and it re-initializes and runs perfectly or I can change time frames and it re-initializes and runs perfectly. In addition, when I place a trade everything works like a charm. It's just when I shut the platform down and re-start it that things go gaga.

Getting incorrect symbol info in init() has been reported before . . . why don't you simply ad a few seconds delay at the indicator start . . . not using sleep but check the time, time1, then don't do anything until time is greater than time1 + required delay . . . then do what you need to do, this delay should allow things to settle and allow all the symbol data to be refreshed.
 

Hey, deVries. Thanks for the suggestion. I already know what's causing the zero divide. When the pair is cross currency, I construct a pair using the account and quote currencies in order to get the Ask price to use in the calculation of the pip value for the pair. The division to get the pip value for the cross currency pair is where the explosion occurs. In this case what I'm doing specifically is this:

PipValue = 100000*PipSize/AskPrice;

The account currency coming in as a blank string causes me to get a 0 value Ask price because MarketInfo() is is being sent only the quote currency and BAM! Like I said, it works perfectly in all situations other than that of a re-start of the terminal. When things initialize properly, the string I construct to send to MarketInfo() is a valid currency pair and all is well.

Hey, Raptor. I had already tried forcing a delay using sleep(). I had it sleep for a half second when going into the Start() function with no joy. I don't try to get any kind of symbol info in init() other than the terminal globals I've saved off. I remember seeing somewhere in the documentation that trying to get anything from the server in init() is a sure fire path to trouble. Your suggestion sounds like it's worth a try. Are you suggesting doing this in the init() method rather than the start() method?

You did bring another thing to mind. I know that you can force a refresh of rates with the RefreshRates() method. I'm guessing that since you didn't mention it that there isn't anything you can use to force a refresh for all the symbol info at the beginning of start(). Thanks for the advice, Man.

Thanks again, both of you. Your input's much appreciated.

 
ProfessorMetal:

Hey, deVries. Thanks for the suggestion. I already know what's causing the zero divide. When the pair is cross currency, I construct a pair using the account and quote currencies in order to get the Ask price to use in the calculation of the pip value for the pair. The division to get the pip value for the cross currency pair is where the explosion occurs. In this case what I'm doing specifically is this:

The account currency coming in as a blank string causes me to get a 0 value Ask price because MarketInfo() is is being sent only the quote currency and BAM! Like I said, it works perfectly in all situations other than that of a re-start of the terminal. When things initialize properly, the string I construct to send to MarketInfo() is a valid currency pair and all is well.

Hey, Raptor. I had already tried forcing a delay using sleep().

You can't use sleep() in an Indicator . . .

ProfessorMetal:

I don't try to get any kind of symbol info in init() other than the terminal globals I've saved off. I remember seeing somewhere in the documentation that trying to get anything from the server in init() is a sure fire path to trouble.

You may not be trying to get any symbol info when the terminal restarts ad calls your Indicator's init() but the terminal may well be getting new info . . .

ProfessorMetal:

Your suggestion sounds like it's worth a try. Are you suggesting doing this in the init() method rather than the start() method?

You did bring another thing to mind. I know that you can force a refresh of rates with the RefreshRates() method. I'm guessing that since you didn't mention it that there isn't anything you can use to force a refresh for all the symbol info at the beginning of start().

I'm saying let init() run and complete and let start() run but return(0); until a preset time has elapses, maybe 5 seconds, then let start() run as normal and update any variables you may have set in init().

RefreshRates() only updates predefined variables and that happens on each tick anyway . . . I'm pretty sure it won't help you.
 

As to sleep(), I missed that in the documentation. Didn't read deep enough, I guess. I see now why you said not to use sleep().

On the subject of init(), from what I read you can't really count on getting specific info there. It may or not be available. The terminal globals that I have set are the only things I would try to get there. I know those are available since they're stored locally. I didn't think RefreshRates() would do any good. On reflection it occurred to me that if the info wasn't available when I asked for it, it wouldn't be available even if there was something that you could use to force a "re-get" of all symbol info. I knew RefreshRates() wouldn't be useful.

I thought that's what you meant about setting a delay to allow time for everything to be available. I just wanted to be sure. Programming for MetaTrader is definitely a different animal than I'm used to with programming Windows and Web apps. They're still event based but they're a lot more straightforward and predictable. Anyway, it's time I hit the sack for some downtime. I'm in the US and it's 10:00 AM for me. I need to grab a smoke and crash before I pass out on the keyboard. I need to get some rest and start fresh this evening. I'll post and let you know how things turn out.

Thanks again, Raptor.

 

Hey, Guys

I got it working. I tried the time delay idea and stranger results than before. Then I had an epiphany. It struck me that when it finally got the account currency it also got the number of open trades, so at that point things were sorted and that symbol info was available.. I changed the code in the start() method to first go after the account currency and then bounce out if it was blank. Now it's working like a charm. It was one of those Homer Simpson, "DOH!" moments. I can't believe that I've fought with this for a week without seeing what was right front of my eyes the whole time. Oh well, the important thing is that it works. It's a lesson I won't forget.

Thanks again for your help. Catch you later.

 
ProfessorMetal:

Hey, Guys

I got it working. I tried the time delay idea and stranger results than before. Then I had an epiphany. It struck me that when it finally got the account currency it also got the number of open trades, so at that point things were sorted and that symbol info was available.. I changed the code in the start() method to first go after the account currency and then bounce out if it was blank. Now it's working like a charm. It was one of those Homer Simpson, "DOH!" moments. I can't believe that I've fought with this for a week without seeing what was right front of my eyes the whole time. Oh well, the important thing is that it works. It's a lesson I won't forget.

Thanks again for your help. Catch you later.


//+-------------------------------------------------------------------------------------------+
//| Indicator Start                                                                           |                                                        
//+-------------------------------------------------------------------------------------------+ 
int start()
{
//----
   while(AccountCurrency()=="")
      {return(0);}

thank you this solution is more simple then i did to avoid this error

 
deVries:


thank you this solution is more simple then i did to avoid this error


You're most welcome, deVries. I used an if conditional rather than a while but the end result is the same. I'm happy to be able to give back. This forum is about helping one another. I'm glad to be a part of it.

Have a great one, Man.

Reason: