This projects create a request/reply communication layer between MetaTrader 4 and your application.
The communication is currently exchanged with ZeroMQ (this could be extended to support more protocols in the future).
A message parser is implemented to make message interpretation task easier to handle.
Parsed messages create bindings for account info, accounts orders and orders management.
- node-mt4-zmq-bridge node.js library.
This projects depend on mql-zmq. Install it first.
Then copy MetaTrader4Bridge.mq4 from this projects to Experts folder and compile it in MetaEditor.
Enable Auto Trading in your MetaTrader 4 client application.
Add MetaTrader4Bridge Expert Advisor to your chart.
Enable "Allow live trading" and "Allow DLL imports" in Common tab.
Then configure the server in Inputs tab for your needs.
There are two servers which should start along with Expert Advisor. First is REP server and second is PUSH server. The client should subscribe to those servers as REQ and PULL (respectively).
REP server serves the purpose of accepting the messages.
PUSH server is used to send the messages, as well as push data update events (symbol rates, account info, orders change) to the client.
The protocol assumes that request/response messages are strings separated with pipe |
character (string split).
First value from request message is always an id of the request.
Second value is the id of a request type.
Request types are:
REQUEST_TYPE | ID | Description |
---|---|---|
REQUEST_PING |
1 |
Ping MT4 client. |
REQUEST_TRADE_OPEN |
11 |
Create new order. |
REQUEST_TRADE_MODIFY |
12 |
Modify placed order. |
REQUEST_TRADE_DELETE |
13 |
Delete pending order. |
REQUEST_DELETE_ALL_PENDING_ORDERS |
21 |
Delete all pending orders. |
REQUEST_CLOSE_MARKET_ORDER |
22 |
Close open market orders. |
REQUEST_CLOSE_ALL_MARKET_ORDERS |
23 |
Close all open market orders. |
REQUEST_RATES |
31 |
Get current rate for the symbol. |
REQUEST_ACCOUNT |
41 |
Get account info. |
REQUEST_ORDERS |
51 |
Get account orders. |
Please see the API section for detailed description and list of arguments of request types.
Modify an order.
1|12|140602286|108.252|107.525|109.102
Delete pending order.
2|13|140602286
Get current rates for USDJPY.
2|31|USDJPY
First value from response message is always an id of the request.
Second value is the id of response status.
Response statuses are:
RESPONSE_STATUS | ID | Description |
---|---|---|
RESPONSE_OK |
0 |
Response is successful. |
RESPONSE_FAILED |
1 |
Response has failed. |
In case of success, rest of the values are response values.
2|0|108.926000|108.947000|USDJPY
First value 2
is request id. Second value 0
tells us that the response from the server is successful and rest of the message 108.926000|108.947000|USDJPY
can be parsed according to request type.
In case of failure, third value indicates error code. No more values are returned.
2|1|134
First value 2
is request id. Second value 1
indicates that the response from the server has failed and the third value is error code of 134
which means "Free margin is insufficient".
Request id should be unique with every request (e.g. incremented int).
But there are cases in which you might want to use static values, like "ACCOUNT" - which could periodically send account info to the client so it can have up to date data about the account.
Trade operations for opening market order and placing pending order requests.
Operations are:
OPERATION_TYPE | ID | Description |
---|---|---|
OP_BUY |
0 |
Buy operation. |
OP_SELL . |
1 |
Sell operation. |
OP_BUYLIMIT |
2 |
Buy limit pending order. |
OP_SELLLIMIT |
3 |
Sell limit pending order. |
OP_BUYSTOP |
4 |
Buy stop pending order. |
OP_SELLSTOP |
5 |
Sell stop pending order. |
Unit types for order volume management requests.
Unit types are:
UNIT_TYPE | ID | Description |
---|---|---|
UNIT_CONTRACTS |
0 |
Use contracts volume unit. |
UNIT_CURRENCY |
1 |
Use currency volume unit. |
For 0
UNIT_CONTRACTS
no additional calculations are performed, so the volume is unchanged.
For 1
UNIT_CURRENCY
the volume specified for the trade is divided by the result price.
Let's assume that we place two orders for USDJPY
with volume 10
price 110
and two different unit types of 0
and 1
.
In case of order with unit 0
, then the volume will stay at 10
.
In case of order with unit 1
, then the volume of 10
will be divided by the price 110
, resulting with the final volume of ~0.0909
.
Price modificator are used to undercut or overcut the price value.
Price modificators are:
MODIFICATOR_TYPE | Description | Example |
---|---|---|
- |
Undercut market price by specified value. | -5 |
+ |
Overcut market price by specified value. | +10 |
% |
Undercut/overcut market price by specified percentage. | -15% , +20% |
If modificator wasn't found (it's always first character in BASE_PRICE
/BASE_STOPLOSS
/BASE_TAKEPROFIT
value), then it's treated as literal value.
Let's assume that the market price is 200
(it's irrelevant if it's bid or ask).
In case of modificator -5
, the result price will be 195
.
In case of modificator +10
, the result price will be 210
.
In case of modificator -15%
, the result price will be 170
.
In case of modificator +20%
, the result price will be 240
.
In case of literal value 250
, the result price will be 250
.
All listed request values are required.
Ping MetaTrader 4 Client.
<none>
102|1
TS
current MT4 client timestamp in seconds.
102|0|140602286
Open an order.
Key function from MT4 client used for this request is OrderSend.
SYMBOL
(string) symbol for trading.
OPERATION
(int) operation type.
VOLUME
(double | string) trade volume.
BASE_PRICE
(double) literal value or modificator for order price.
SLIPPAGE
(int) maximum price slippage for buy or sell orders.
BASE_STOPLOSS
(double | string) literal value or modificator for stop loss level.
BASE_TAKEPROFIT
(double | string) literal value or modificator for take profit level.
COMMENT
(string) order comment text. Limit is 27 characters. Do not use pipe |
. Can be empty.
MAGIC_NUMBER
(int) order magic number. May be used as user defined identifier.
UNIT
(int) unit type.
236|11|USDJPY|2|1|108.848|0|0|0|comment message goes here|123|0
TICKET
order ticket received from trade server.
236|0|140602286
Modify an order.
Key function from MT4 client used for this request is OrderModify.
TICKET
(int) order ticket.
BASE_PRICE
(double | string) literal value or modificator for order price.
BASE_STOPLOSS
(double | string) literal value or modificator for stop loss level.
BASE_TAKEPROFIT
(double | string) literal value or modificator for take profit level.
312|12|140602286|108.252|107.525|109.102
TICKET
order ticket.
312|0|140602286
Delete pending order.
Key function from MT4 client used for this request is OrderDelete.
TICKET
(int) pending order ticket.
318|13|140602286
TICKET
order ticket.
318|0|140602286
Delete all pending orders.
SYMBOL
(string) symbol for which pending orders should be deleted.
345|21|USDJPY
DELETED_COUNT
number of deleted pending orders.
345|0|2
Close market order.
Key function from MT4 client used for this request is OrderClose.
TICKET
(int) market order ticket.
380|22|140612332
TICKET
order ticket.
380|0|140612332
Close all market orders.
SYMBOL
(string) symbol for which market orders should be closed.
383|23|USDJPY
DELETED_COUNT
number of deleted pending orders.
383|0|3
Get current rates for requested symbol.
SYMBOL
(string)
397|31|USDJPY
BID
current bid price.
ASK
current ask price.
SYMBOL
the symbol.
397|0|108.926000|108.947000|USDJPY
Get account info.
<none>
415|41
CURRENCY
account currency.
BALANCE
account balance in the deposit currency.
PROFIT
current profit of an account in the deposit currency.
EQUITY_MARGIN
account equity in the deposit currency.
MARGIN_FREE
free margin of an account in the deposit currency.
MARGIN_LEVEL
account margin level in percents.
MARGIN_SO_CALL
margin call level.
MARGIN_SO_SO
margin stop out level.
415|0|USD|10227.43|-129.46|10097.97|4000.00|6097.97|252.45|50.00|20.00
Get account orders.
In this specific case, order values are separated by comma ,
and orders are separated by pipe |
. So after splitting the response, you will have the orders which you would probably need to split again with ,
as a separator (e.g. response.split('|').map(item => item.split(','))
).
<none>
467|51
ORDERS
orders with values separated by comma ,
.
TICKET
order ticket.
OPEN_TIME
order open price.
TYPE
order type.
LOTS
order volume.
SYMBOL
order symbol.
OPEN_PRICE
order open price.
467|0|140617577,2018.05.31 10:40,1,0.01,EURUSD,1.17017,|140623054,2018.05.31 14:20,3,0.11,USDJPY,130.72600,
MIT