Termos de Referência
Currently we are already implemented this documented process, but the issue is going on whenever we are requesting, each time it’s creates a new connection and there’s approximate more then 50000 to 100000 request each day. So, we need to build a efficient authentication process, by which one connection will be build up and all other requests will be managed by that.
Here’s the reference links of their authentication documentation
https://support.metaquotes.net/en/docs/mt5/api/webapi_rest_authentication
And below one is for maintaining the connection
https://support.metaquotes.net/en/docs/mt5/api/webapi_pings
We are seeking an experienced and skilled developer to join our team as an MT5 Server Authentication Developer. In this role, you will be responsible for implementing and maintaining the authentication process for our MetaTrader 5 (MT5) server. You will work closely with our development team to ensure a secure and efficient authentication process for our trading platform.
We are looking for:
-
Implement the authentication process for sending commands to the MT5 server.
-
Develop and integrate the necessary API endpoints (/api/auth/start, /api/auth/answer) for authentication.
-
Collaborate with the team to ensure seamless authentication across different stages of the process.
-
Generate and handle random sequences and hash passwords according to the provided algorithm.
-
Work on client-side and server-side authentication procedures.
-
Ensure maximum security and encryption for authentication and data exchange.
-
Maintain connection to the server by sending "ping" commands to prevent connection loss.
-
Implement connection status checks and handling of empty packets to maintain the connection.
-
Troubleshoot and resolve any issues related to authentication and connection maintenance.
Here's the codebase we followed in php
<?php class CMT5Request { private $m_curl=null; private $m_server=""; public function Init($server) { $this->Shutdown(); if($server==null) return(false); $this->m_curl=curl_init(); if($this->m_curl==null) return(false); //--- curl_setopt($this->m_curl,CURLOPT_SSL_VERIFYPEER,0); // comment out this line if you use self-signed certificates curl_setopt($this->m_curl,CURLOPT_MAXCONNECTS,1); // one connection is used curl_setopt($this->m_curl, CURLOPT_HTTPHEADER,array('Connection: Keep-Alive')); //--- $this->m_server=$server; //--- return(true); } public function Shutdown() { if($this->m_curl!=null) curl_close($this->m_curl); $this->m_curl=null; } public function Get($path) { if($this->m_curl==null) return(false); curl_setopt($this->m_curl,CURLOPT_POST,false); curl_setopt($this->m_curl,CURLOPT_URL,'https://'.$this->m_server.$path); curl_setopt($this->m_curl,CURLOPT_RETURNTRANSFER,true); $result=curl_exec($this->m_curl); if($result==false) { echo 'Curl GET error: '.curl_error($this->m_curl); return(false); } $code=curl_getinfo($this->m_curl,CURLINFO_HTTP_CODE); if($code!=200) { echo 'Curl GET code: '.$code; return(false); } return($result); } public function Post($path, $body) { if($this->m_curl==null) return(false); curl_setopt($this->m_curl,CURLOPT_POST,true); curl_setopt($this->m_curl,CURLOPT_URL, 'https://'.$this->m_server.$path); curl_setopt($this->m_curl,CURLOPT_POSTFIELDS,$body); curl_setopt($this->m_curl,CURLOPT_RETURNTRANSFER,true); $result=curl_exec($this->m_curl); if($result==false) { echo 'Curl POST error: '.curl_error($this->m_curl); return(false); } $code=curl_getinfo($this->m_curl,CURLINFO_HTTP_CODE); if($code!=200) { echo 'Curl POST code: '.$code; return(false); } return($result); } public function Auth($login, $password, $build, $agent) { if($this->m_curl==null) return(false); //--- send start $path='/api/auth/start?version='.$build.'&agent='.$agent.'&login='.$login.'&type=manager'; $result=$this->Get($path); if($result==false) return(false); $auth_start_answer=json_decode($result); if((int)$auth_start_answer->retcode!=0) { echo 'Auth start error : '.$auth_start_answer.retcode; return(false); } //--- Getting code from the hex string $srv_rand=hex2bin($auth_start_answer->srv_rand); //--- Hash for the response $password_hash=md5(mb_convert_encoding($password,'utf-16le','utf-8'),true).'WebAPI'; $srv_rand_answer=md5(md5($password_hash,true).$srv_rand); //--- Random string for the MetaTrader 5 server $cli_rand_buf=random_bytes(16); $cli_rand=bin2hex($cli_rand_buf); //--- Sending the response $path='/api/auth/answer?srv_rand_answer='.$srv_rand_answer.'&cli_rand='.$cli_rand; $result=$this->Get($path); if($result==false) return(false); $auth_answer_answer=json_decode($result); if((int)$auth_answer_answer->retcode!=0) { echo 'Auth answer error : '.$auth_answer_answer.retcode; return(false); } //--- Calculating a correct server response for the random client sequence $cli_rand_answer=md5(md5($password_hash,true).$cli_rand_buf); if($cli_rand_answer!=$auth_answer_answer->cli_rand_answer) { echo 'Auth answer error : invalid client answer'; return(false); } //--- Everything is done return(true); } } // Example of use $request = new CMT5Request(); // Authenticate on the server using the Auth command if($request->Init('my.broker.com:443') && $request->Auth(1000,"Password",1985,"WebManager")) { // Let us request the symbol named TEST using the symbol_get command $result=$request->Get('/api/symbol/get?symbol=TEST'); if($result!=false) { echo $result; $json=json_decode($result); if((int)$json->retcode==0) { $symbol=$json->answer; //--- Changing the description $symbol->Description='My Description'; // Sending changes to the server using the symbol_add command $result=$request->Post('/api/symbol/add',json_encode($symbol)); if($result!=false) echo $result; } } } $request->Shutdown(); ?>