MT5 manager JavaScript TypeScript grpc client from browser (Webpack)
npm install -g npx
npm install typescript --save-dev
You need protoc tool be installed
Install protoc plugins
npm install -g protoc-gen-js
npm install -g protoc-gen-grpc-web
You can find ready to run example here
Run example steps:
Step 1. Generate client files. JS and TS files generation by mt4mng.proto. Create grpc folder before runnig the script.
protoc proto/*.proto --js_out=import_style=commonjs,binary:./grpc --grpc-web_out=import_style=typescript,mode=grpcwebtext:./grpc
where ./grpc is a output folder
This script generates client's files to the "grpc" folder.
Step 2. Insert your ceredentials in the example
Step 3. Install all dependencies
npm install
Step 4. Compile typescript to js files.
tsc -p .
This script generates client.js file from client.ts file.
Step 5. Bild browser bundle.
npx webpack ./client.js
This script creates main.js file in the dist folder. This file could be consumed by a browser.
Step 6. Create a developer http server. Which would provide bundle files to a browser, by GET request.
For the purpose of prototype demonstration, I would like to recommend using lightweigt developer http server.
npm install --global http-server
Step 7. Finally, you can run a developer server
http-server
Step 8. Check how it works.
Full example:
import {MainClient} from "./grpc/proto/Mng5grpcServiceClientPb";
import {AccountDetailsRequest, AccountsRequest, ConnectRequest} from "./grpc/proto/mng5grpc_pb";
const host : string = ``;
const port : number = 443;
const userId : number = 1;
const password: string = `password`
const serverAddress = 'https://mng5grpcweb.mtapi.io:443';
const sessionId = generateUUID();
console.log(`Server:${serverAddress}`)
console.log(`Session id: ${sessionId}`)
console.log(`Demo has started!`)
try {
const mainControllerClient = new MainClient(serverAddress);
if (mainControllerClient)
{
console.log(`Main controller is created`)
DoTheDemo(mainControllerClient).then(() => {
console.log(`Demo is completed!`)
});
}
}
catch (exception) {
if (exception instanceof Error) {
console.log(`Main controller client init error: ${exception.message}`);
}
console.log(`Main controller client init error: ${exception}`);
}
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
let r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
async function DoTheDemo(mainControllerClient: MainClient) {
console.log(`Connection pending`);
const clientConnectionId = await Connect(mainControllerClient);
console.log(`Connection method is completed`);
if (clientConnectionId != undefined)
{
console.log(`Getting accounts list is next`);
const accountsIds = await GetAccountsList(mainControllerClient, clientConnectionId);
console.log(`Account ids: ${accountsIds}`);
if (accountsIds != undefined)
{
console.log(`Getting accounts data for the first 10 accounts`)
const accountDataPromises =
accountsIds.slice(0,10).map(accountId => GetAccountData(mainControllerClient, clientConnectionId, accountId));
await Promise.all(accountDataPromises);
}
}
}
async function Connect(mainControllerClient: MainClient): Promise<string | undefined> {
let result: string | undefined;
let connectRequest = new ConnectRequest();
connectRequest.setUser(userId);
connectRequest.setServer(`${host}:${port}`);
connectRequest.setPassword(password);
await mainControllerClient.connect(connectRequest, {"mt5-sticky-session-header" : sessionId})
.then(connectReply => {
if (connectReply.getError())
{
console.error(`mainControllerClient.connect(). Internal server error: ${connectReply?.getError()?.getMessage()}`);
}
else
{
let clientConnectionId = connectReply.getResult();
if (clientConnectionId)
{
console.log(`Successful connected`);
console.log(`Connection client id: ${clientConnectionId}`);
result = connectReply.getResult();
}
}
})
.catch(error => {
console.error(`RPC mainControllerClient.connect() error message: ${error.message}`);
})
return result;
}
async function GetAccountsList(mainControllerClient: MainClient, clientConnectionId: string) : Promise<number[] | undefined> {
let result : number[] | undefined;
let accountsRequest = new AccountsRequest();
accountsRequest.setId(clientConnectionId);
await mainControllerClient.accountsList(accountsRequest, {"mt5-sticky-session-header" : sessionId})
.then(accountsReply => {
if (accountsReply.getError())
{
console.error(`mainControllerClient.accountsList(). Internal server error: ${accountsReply?.getError()?.getMessage()}`);
}
else
{
console.log(`Successful getting accounts`);
let accountsIds = accountsReply.getResultList();
if (accountsIds)
result = accountsIds;
}
})
return result;
}
async function GetAccountData(mainControllerClient: MainClient, clientConnectionId: string, accountId: number) {
let accountDetailsRequest = new AccountDetailsRequest();
accountDetailsRequest.setId(clientConnectionId);
accountDetailsRequest.setLogin(accountId);
await mainControllerClient.accountDetails(accountDetailsRequest, {"mt5-sticky-session-header": sessionId})
.then(accountDetailsReply => {
if (accountDetailsReply?.getError())
console.error(`AccountDetails. Internal server error: ${accountDetailsReply?.getError()?.getMessage()}`);
else {
console.log(`AccountDetails. Successful response`);
console.log(`Account ID: ${accountId}`);
console.log(`Account Login: ${accountDetailsReply?.getResult()?.getLogin()}`);
console.log(`Account Credit: ${accountDetailsReply?.getResult()?.getCredit()}`);
console.log(`Account Balance: ${accountDetailsReply?.getResult()?.getBalance()}`);
console.log(`Account Assets: ${accountDetailsReply?.getResult()?.getAssets()}`);
console.log(`Account Margin: ${accountDetailsReply?.getResult()?.getMargin()}`);
}
})
.catch(error => {
console.error(`RPC mainControllerClient.accountDetails() error message: ${error.message}`);
})
}