MT3 API for VB.net and C# - page 4

 

That's good news--that's when I'm getting the messages as well. One less bug to worry about! I was getting a few extraneous UPDATE_TRADES events when no trade activity had occurred, which is what made me think I might be missing a bunch more, but I believe those were due to the pumping connection timing out and reconnecting (I also get UPDATE_TRADES right after initializing pumping, which makes sense.) My cable connection at home is a little unreliable...luckily my server is much better connected!

According to Slawa (or one of those other less-than-helpful guys at MetaQuotes), you're supposed to wait 5 seconds between calls to MtGetTrades, right? If you call it every time new prices arrive you're definitely exceeding that limit. There's also (supposedly) a 2-minute connection time limit for non-pumping sockets, so I assume you're opening a new connection for each GetTrades/GetTradeRecords call? Have you had any problems opening so many connections? Isn't the connection operation a little too expensive to be run so often?

My plan was to get the updates only once every minute or so. For my purposes, the account/trades data doesn't really need to be updated on every tick--it's mostly just for the user to look at.

Interesting to hear about the message loop problems. For now, that shouldn't affect me as that part runs only on the Windows side.

How do you determine if the ticks are flowing? Do you just timeout if there've been no ticks for some number of seconds? I've considered doing that myself. The connection from my server has (so far) been very stable, but it does get dropped perhaps once every few days. Currently, the way I detect it is with the END_PUMPING event--I'm not sure what causes the connection to die, but after about 2 minutes of no ticks coming in, I get an END_PUMPING message, then I reconnect and restart pumping. This method hasn't failed me yet, but I do lose 2 minutes of tick data every time it happens...would be nice to shorten that to a few seconds.

One more thing (sorry!) -- as far as I can tell, the only way to get the final data on a closed trade is to call GetTradeHistory. Right? It doesn't get pumped in--it just disappears from the open trades list without informing us of its close time or price. How do you handle this? I figure I can either a) grab the data for each trade after it disappears from the list, or b) do a "sweep" of the history at regular intervals, starting from the earliest opening time of all trades whose closing data I don't yet have. I'm leaning toward the second option.

 

Hello there,

Let's me answer your questions one-by-one.

so I assume you're opening a new connection for each GetTrades/GetTradeRecords call? Have you had any problems opening so many connections? Isn't the connection operation a little too expensive to be run so often?

Actually, my program initially open two static connections: one for msg pump and another one for calling functions, so the program does not have to spawn a new connection every function call. This is quite efficient for me since first tested months ago.

My plan was to get the updates only once every minute or so. For my purposes, the account/trades data doesn't really need to be updated on every tick--it's mostly just for the user to look at.

You don't need to update the account and trades info everytime a msg comes in, but you cannot fresh the info more than once between each msg.

How do you determine if the ticks are flowing? Do you just timeout if there've been no ticks for some number of seconds? I've considered doing that myself. The connection from my server has (so far) been very stable, but it does get dropped perhaps once every few days. Currently, the way I detect it is with the END_PUMPING event--I'm not sure what causes the connection to die, but after about 2 minutes of no ticks coming in, I get an END_PUMPING message, then I reconnect and restart pumping. This method hasn't failed me yet, but I do lose 2 minutes of tick data every time it happens...would be nice to shorten that to a few seconds.

I use 1 min interval for ticks flowing and END_PUMPING msg. The interval is relative to connection speed. For fast connection, 1 min is ok. I'm still finding out the correct interval for my server connection.

the only way to get the final data on a closed trade is to call GetTradeHistory. Right? It doesn't get pumped in--it just disappears from the open trades list without informing us of its close time or price

Yes, right. Call GetTradeHistory to get closed trades info. Actually, when a trade or an order is closed, there will be an UPDATE_TRADES msg pumped in.

Feel free to ask more questions

 

scorpion,

I really appreciate your taking the time to answer so many questions, as I'm sure do many others you've helped around here. How do you find the time? All I seem to have time for recently is working on my bot.

Just want to clarify a few things you said. Perhaps this thread will help some other developers out there who are as frustrated as I am with the lack of documentation...not that it will matter once brokers stop supporting this API! Did you ever determine which API you'll switch to after MT3? GAIN Capital looks very appealing to me--they don't charge for development or production use of their API.

scorpion:
Actually, my program initially open two static connections: one for msg pump and another one for calling functions, so the program does not have to spawn a new connection every function call. This is quite efficient for me since first tested months ago.

I take it this means that both the 2-minute connection limit and the 5-second limitation on GetTrades are bogus? Does your program actually call it on every UPDATE_BIDASK message, as you suggested?

scorpion:
You don't need to update the account and trades info everytime a msg comes in, but you cannot fresh the info more than once between each msg.

Not sure what you mean here. I don't seem to have any problems calling GetTrades/GetTradeRecords repeatedly in between UPDATE_TRADES messages (on a separate connection though, not on the pumping connection--the documentation indicates one is not allowed to call GetTrades while in pumping mode, so I've never tried.)

scorpion:
I use 1 min interval for ticks flowing and END_PUMPING msg. The interval is relative to connection speed. For fast connection, 1 min is ok. I'm still finding out the correct interval for my server connection.

That makes sense. So you do both--reconnect if no ticks arrive for the interval, or whenever you get END_PUMPING?

scorpion:
Yes, right. Call GetTradeHistory to get closed trades info. Actually, when a trade or an order is closed, there will be an UPDATE_TRADES msg pumped in.

I do get an UPDATE_TRADES after closing a position, but as the purpose of GetTradeRecords is to list the current open positions, all this message tells me is that the trade has closed (since it's no longer in the list.) At that point, I don't know what the actual closing price was, so I must fetch it manually by calling GetTradeHistory so that my local database is accurate.

I think this is in fact what you meant, but that second sentence made me think you might be somehow determining the close info from only the UPDATE_TRADES message?

Ok, time to get some sleep so I can wake up early and get some more work done! I'm sure I'll be back to bug you with more questions later, or at least to let you know how my project is coming along.

 

Hey,

Others will absolutely find this thread helpful, since the whole api doc is 1-page.

Well, I'm looking to split a portion of project fund to obtain Oanda API for 2 months. You can find further discussion on this at "Have you successfully analysed any broker api protocol?" thread.

I take it this means that both the 2-minute connection limit and the 5-second limitation on GetTrades are bogus? Does your program actually call it on every UPDATE_BIDASK message, as you suggested?

Yes, those functions are called on every UPDATE_BIDASK without any problem. You'll find further discussion about 5-second limitation from page 1 (this thread).

That makes sense. So you do both--reconnect if no ticks arrive for the interval, or whenever you get END_PUMPING?

I do both, as mentioned.

I do get an UPDATE_TRADES after closing a position, but as the purpose of GetTradeRecords is to list the current open positions, all this message tells me is that the trade has closed (since it's no longer in the list.) At that point, I don't know what the actual closing price was, so I must fetch it manually by calling GetTradeHistory so that my local database is accurate.

To get a list of recently closed trades, my bot compares the list of open trades before UPDATE_TRADES with the list after UPDATE_TRADES. The missing trades must be closed.

Ok, have a sweet wet chocolate dream!

 

I'm awake! I don't recall whether I had any chocolate dreams, but chances are that I did -- my girlfriend works for Godiva!

I've read through that broker API thread several times already, as I was just as concerned as you when I first learned about the lack of client API for MT4. I'm curious--where did you learn that GAIN's execution time is slow? How slow are we talking about?

I think some further discussion of these 5-second frequency limitations imposed by the DLL is warranted, for anyone (like me) who didn't quite "get it" from reading the rest of this thread. For reference, here is the number of seconds one is supposed to wait between calling certain functions:

  • Login => 1 sec
  • OpenDemoAccount => 30 sec
  • ChangePassword => 60 sec
  • RefreshSecurities, GetTrades, GetTradeHistory, GetNewsBody, GetPrices => 5 sec
  • [Send/Delete/Modify/Close/CloseBy]Order => 5 sec

This was posted in some random thread on the MetaQuotes forum, and has crept its way into the online documentation at several MT3 brokers -- don't ask me why it wasn't in the docs to begin with! Anyway, this list raises some questions:

  • Do the limits apply individually to each connection, or to all connections as a whole? If it's "all", does that mean all connections to a specific server, from a single IP address, for a specific account, or from a single running process?
  • Which of these limitations are actually enforced, not just recommended?

From the other comments posted, I'm guessing the answer to #1 is that the limitation is imposed per process, since sccz97 was able to solve the problem by launching separate console applications. From my testing, the limitations do appear to be enforced for RefreshSecurities and GetPrices. I'm not sure about the rest--it's difficult for me to test because my wrapper is currently structured to use a new connection for each call, as recommended by the MetaQuotes guys.

And...

scorpion:
In standard account 1 lot of EURUSD = 100,000 units (100k), so the Lots value should be 100 for standard, while 10 for mini. (The Lots parameter expects lot size in kilo)
scorpion:
Be careful with currency pair. If you play with GetSecurities(), you will see the lot size of GBPUSD = 70,000 while EURUSD = 100,000 in standard account.

When I first read this thread, I was confused by this. I thought you were stating that all functions expect lots/volume in kilos. For anyone reading along, this only applies to MtGetPrices and scorpion's GetCurrentRate (personally, I call this method "quote", cuz that's what it is!) When passing volume to the Order functions, or when getting it from a trade record, the value is simply multiplied by 100. I'm assuming this is so that fractional sizes as small as 0.01 lot can be represented with an integer instead of a floating point value.

So, you should always use Lots = 100 to place an order for 1 lot, regardless of contract size. In my wrapper, the multiplication and division is handled transparently, so I don't have to think about it. When I want to buy 1 lot, I pass in Lots = 1!

Here's a question, though: I just called MtGetPrices on Alpari's demo server for GBPUSD (where the GBPUSD contract = 70,000) with a lot value of 7, on both a regular and mini demo account. According to your instructions, this would be the correct value to use for 1 mini lot. But I got an INVALID_VOLUME error! The only values that work are multiples of 10. This leads me to believe that, perhaps, the lots parameter to MtGetPrices works the same way as the volume parameter elsewhere--it's simply Lots * 100. Any thoughts?

 

I'm late coming into this tread... but, THANK YOU for this tool!!!

Is there any documentation, or sample code available in VB? I'm a little lost interpreting the C++ calls.

BTW, InterBankFX says they will continue MT3 as long as they have customers using it. (08/22/05)

Thanks!

-charlie

 

Anyone longing for full example demostrating connect & login, execute orders, and get open & closed orders?

 
scorpion:
Anyone longing for full example demostrating connect & login, execute orders, and get open & closed orders?

I'd suggest if you have that info that can be easily copy/paste into a reply that it might even promote others to look further into the great work you've already done on the MT3 API so thus, scorpion.

I know there's a saying about 'from an acorn grows something ...' - what was that now ??

 

No it's very long multiple files with binary data included, so it's impossible to reply for copy-n-paste. But of course the example is opensource, so people have chance to inspect the code, learn from it, and use portion of the code in personal project (no redistribution and no selling).

 

Hi,

I just ran across this thread yesterday, and am very impressed and thankful for your contributions. I was able to get your sample up and running, and start to play with some of the other methods. I did run into one problem that I was hoping you could shed some light on. When I call GetHistoricalRates and loop through the results, I am able to pull out all the Fields from RateInfo except CTMDateTime. It gives me some strange error saying that the source code cannot be found. My .Net experience is very limited compared to others here, so it may be obvious to you. I think its something to do with the # symbols at both ends of the datetime value. The watch window shows this: CTMDateTime #10/20/2005 5:44:00 AM# Date.

Thanks for any suggestions you might have for me.

-Tom

Reason: