vdemydiuk / mtapi

MetaTrader API (terminal bridge)
http://mtapi4.net/
MIT License
521 stars 281 forks source link

[MT4]MtExecutionException(ErrorCode: MtApiCustomError) with Message "Response from MetaTrader is null" #145

Open DoryeongPark opened 5 years ago

DoryeongPark commented 5 years ago

When it keeps fetching data with MtApiClient Instance about 20 ~ 30 times a sec, after few minutes later(about 5~10 min I guess), all of MtApiClient instances return the exception above.

Victoriadd2007 commented 5 years ago

I have a similar project and faced that issue... Works with some premises:

1, NEVER change the timeframe on the chart where the api is loaded. as the expert will be loaded again on each change, you will find yourself trying to connect while MT loads the connector again. Open a chart, add the MtApi, and leave it on a corner to rot.

  1. It would be awesome if the ApiClient were disposable, as you could use a using clause. But as it is not, do not use it as a private readonly, and make ApiClient api = new ApiClient() on each call. Then add a Connect2Server() and a DisconnectServer() function, to create object+open connection, get data, and close it again. It works better than if you just use one and leave it open.

  2. 30 times per second? no chart ticks so fast as far as I know... I use a method to reduce memory usage and set the timers to 0.500/1.000 seconds, that is more than enough

  3. I trade indexes, and I know when are they idle or closed. I have a function that closes MetaTrader first, then restarts it and after restarts the C# application during those low activity times. That helps refreshing everything.

Happy coding!

cod3r85 commented 3 years ago

I've had a similar experience recently with the "Response from MetaTrader is null" with MT4 connections. However it seems to only occur on connections that are more active in placing orders. I have two open connections, both make the same queries for rates and account information, but one attempts to place significantly more trades. I only ever see the Null Response on the more active terminal connection.

Strangely however, even when receiving a Null Response from a query for Account Balance, Spread, etc I have noticed that events such as QuoteUpdates continue to fire and update without issue.

My project connects to multiple terminals each connected to different account. It then routes orders to each terminal based on alerts from yet another app (connected via named pipes) and a set of system rules. This way one alert can fire trades on multiple accounts.

There are 8 (eight) API requests per alert for Rates, account information and finally and order placement. API connection is established at the beginning of the software session and held in a global list(of MtApiClient)

As a test I have one clientApi connection ( Terminal[0] ) sending trade instructions for every alert. And another ( Terminal[1] ) that is highly selective (places trades on less than 10% of alert scenarios)

I've set up 7 Alerts to stream in during a 5 minute period (to simulate processor intensive 5 minute bar analysis of 7 charts). Sometimes these come close together, sometimes not and are processed on different threads.

All threads make the same initial GetRates and GetAccountData calls (7 clientAPI calls in total).

Over the course of 15-20 minutes Terminal[0] may have placed or attempted to place up to 30-35 trades, where as Terminal[1] may only attempt 2 or 3 entries.

As mentioned previously ONLY Terminal [0] produces the RESPONSE FROM METATRADER IS NULL exception. Generally this happens after about 15-20 minutes of operation.

After reading the above post by @Victoriadd2007 I created a solution that appears to be working (7 hours of continual run without error)

The solution had two components.

1) I created a simple ApiRequest queue system so that multiple threads were not attempting to use the same connection simultaneously. ie: changing experthandlers while another thread was waiting for a GetRates response. If a thread is using a connection or waiting on a response, other threads trying to access the shared connection wait until it is "released". This allows other alert processing / rule checking to continue and only wait at the point of making the clientAPI call.

2) using @Victoriadd2007 's suggestion, during times of no alert activity AND when all processing threads have completed, (usually once every 5-10 minutes) I refresh the terminal connections in the global List(of MtApiClient)

The above combination appears to have resolved my issues, however, a more thorough test next week will confirm.