├── readme.md ├── .gitignore ├── package.json ├── main.js ├── helpers ├── connectionErrorHandler.js └── accountConnection.js └── periodStatisticsStream.js /readme.md: -------------------------------------------------------------------------------- 1 | # SWIT Trade Bot 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | servers.dat 3 | /node_modules 4 | .env 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metaapi-examples-nodejs", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "parceProce": "node -r dotenv/config parsePrice.js" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "dotenv": "^16.4.5", 13 | "form-data": "^4.0.0", 14 | "metaapi.cloud-sdk": "^27.0.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const {connectionHandler} = require('./helpers/accountConnection'); 2 | const {errorDetailsHandler} = require('./helpers/connectionErrorHandler'); 3 | 4 | async function monitorEURUSDPrice() { 5 | try { 6 | const accountConnection = await connectionHandler(); 7 | const connection = accountConnection.connection; 8 | const account = accountConnection.account; 9 | // Підписка на пару 10 | await connection.subscribeToMarketData('EURUSD'); 11 | setTimeout(async () => { 12 | const terminalState = connection.terminalState; 13 | console.log('EURUSD price:', terminalState.price('EURUSD')); 14 | }, 10); 15 | } catch (err) { 16 | if(err.details) { 17 | errorDetailsHandler(err) 18 | } 19 | console.error(err); 20 | } 21 | } 22 | 23 | monitorEURUSDPrice(); 24 | -------------------------------------------------------------------------------- /helpers/connectionErrorHandler.js: -------------------------------------------------------------------------------- 1 | const errorDetailsHandler = (error) => { 2 | // returned if the server file for the specified server name has not been found 3 | // recommended to check the server name or create the account using a provisioning profile 4 | if(error.details === 'E_SRV_NOT_FOUND') { 5 | console.error(error); 6 | // returned if the server has failed to connect to the broker using your credentials 7 | // recommended to check your login and password 8 | } else if (error.details === 'E_AUTH') { 9 | console.log(error); 10 | // returned if the server has failed to detect the broker settings 11 | // recommended to try again later or create the account using a provisioning profile 12 | } else if (error.details === 'E_SERVER_TIMEZONE') { 13 | console.log(error); 14 | } 15 | } 16 | 17 | module.exports = { errorDetailsHandler }; 18 | -------------------------------------------------------------------------------- /helpers/accountConnection.js: -------------------------------------------------------------------------------- 1 | const MetaApi = require('metaapi.cloud-sdk').default; 2 | require('dotenv').config(); 3 | 4 | // Note: for information on how to use this example code please read https://metaapi.cloud/docs/client/usingCodeExamples 5 | 6 | const token = process.env.TOKEN || ''; 7 | const login = process.env.LOGIN || ''; 8 | const password = process.env.PASSWORD || ''; 9 | const serverName = process.env.SERVER || ''; 10 | const api = new MetaApi(token); 11 | 12 | const connectionHandler = async () => { 13 | const accounts = await api.metatraderAccountApi.getAccountsWithInfiniteScrollPagination(); 14 | let account = accounts.find(a => a.login === login && a.type.startsWith('cloud')); 15 | if (!account) { 16 | console.log('Adding MT5 account to MetaApi'); 17 | account = await api.metatraderAccountApi.createAccount({ 18 | name: 'Test account', 19 | type: 'cloud', 20 | login: login, 21 | password: password, 22 | server: serverName, 23 | platform: 'mt5', 24 | magic: 1000 25 | }); 26 | } else { 27 | console.log('MT5 account already added to MetaApi'); 28 | } 29 | 30 | // wait until account is deployed and connected to broker 31 | console.log('Deploying account'); 32 | await account.deploy(); 33 | console.log('Waiting for API server to connect to broker (may take couple of minutes)'); 34 | await account.waitConnected(); 35 | 36 | // connect to MetaApi API 37 | const connection = account.getStreamingConnection(); 38 | await connection.connect(); 39 | 40 | // wait until terminal state synchronized to the local state 41 | console.log('Waiting for SDK to synchronize to terminal state (may take some time depending on your history size)'); 42 | await connection.waitSynchronized(); 43 | 44 | return {"connection": connection, "account": account}; 45 | }; 46 | 47 | 48 | module.exports = { connectionHandler }; 49 | -------------------------------------------------------------------------------- /periodStatisticsStream.js: -------------------------------------------------------------------------------- 1 | const RiskManagement = require('metaapi.cloud-sdk').RiskManagement; 2 | const PeriodStatisticsListener = require('metaapi.cloud-sdk').PeriodStatisticsListener; 3 | 4 | // your MetaApi API token 5 | const token = 'eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI4OGI4OWUxZTlmNzE5ZTZkNGRjM2ZmMjAyMDdjMzkzZCIsInBlcm1pc3Npb25zIjpbXSwiYWNjZXNzUnVsZXMiOlt7ImlkIjoidHJhZGluZy1hY2NvdW50LW1hbmFnZW1lbnQtYXBpIiwibWV0aG9kcyI6WyJ0cmFkaW5nLWFjY291bnQtbWFuYWdlbWVudC1hcGk6cmVzdDpwdWJsaWM6KjoqIl0sInJvbGVzIjpbInJlYWRlciJdLCJyZXNvdXJjZXMiOlsiYWNjb3VudDokVVNFUl9JRCQ6MDdiNTZhZGEtYWM1Ny00MWI3LWJkYjEtMTExNjQ2MmNhZmQ4Il19LHsiaWQiOiJtZXRhYXBpLXJlc3QtYXBpIiwibWV0aG9kcyI6WyJtZXRhYXBpLWFwaTpyZXN0OnB1YmxpYzoqOioiXSwicm9sZXMiOlsicmVhZGVyIiwid3JpdGVyIl0sInJlc291cmNlcyI6WyJhY2NvdW50OiRVU0VSX0lEJDowN2I1NmFkYS1hYzU3LTQxYjctYmRiMS0xMTE2NDYyY2FmZDgiXX0seyJpZCI6Im1ldGFhcGktcnBjLWFwaSIsIm1ldGhvZHMiOlsibWV0YWFwaS1hcGk6d3M6cHVibGljOio6KiJdLCJyb2xlcyI6WyJyZWFkZXIiLCJ3cml0ZXIiXSwicmVzb3VyY2VzIjpbImFjY291bnQ6JFVTRVJfSUQkOjA3YjU2YWRhLWFjNTctNDFiNy1iZGIxLTExMTY0NjJjYWZkOCJdfSx7ImlkIjoibWV0YWFwaS1yZWFsLXRpbWUtc3RyZWFtaW5nLWFwaSIsIm1ldGhvZHMiOlsibWV0YWFwaS1hcGk6d3M6cHVibGljOio6KiJdLCJyb2xlcyI6WyJyZWFkZXIiLCJ3cml0ZXIiXSwicmVzb3VyY2VzIjpbImFjY291bnQ6JFVTRVJfSUQkOjA3YjU2YWRhLWFjNTctNDFiNy1iZGIxLTExMTY0NjJjYWZkOCJdfSx7ImlkIjoibWV0YXN0YXRzLWFwaSIsIm1ldGhvZHMiOlsibWV0YXN0YXRzLWFwaTpyZXN0OnB1YmxpYzoqOioiXSwicm9sZXMiOlsicmVhZGVyIl0sInJlc291cmNlcyI6WyJhY2NvdW50OiRVU0VSX0lEJDowN2I1NmFkYS1hYzU3LTQxYjctYmRiMS0xMTE2NDYyY2FmZDgiXX0seyJpZCI6InJpc2stbWFuYWdlbWVudC1hcGkiLCJtZXRob2RzIjpbInJpc2stbWFuYWdlbWVudC1hcGk6cmVzdDpwdWJsaWM6KjoqIl0sInJvbGVzIjpbInJlYWRlciJdLCJyZXNvdXJjZXMiOlsiYWNjb3VudDokVVNFUl9JRCQ6MDdiNTZhZGEtYWM1Ny00MWI3LWJkYjEtMTExNjQ2MmNhZmQ4Il19LHsiaWQiOiJjb3B5ZmFjdG9yeS1hcGkiLCJtZXRob2RzIjpbImNvcHlmYWN0b3J5LWFwaTpyZXN0OnB1YmxpYzoqOioiXSwicm9sZXMiOlsicmVhZGVyIiwid3JpdGVyIl0sInJlc291cmNlcyI6WyIqOiRVU0VSX0lEJDowN2I1NmFkYS1hYzU3LTQxYjctYmRiMS0xMTE2NDYyY2FmZDgiXX0seyJpZCI6Im10LW1hbmFnZXItYXBpIiwibWV0aG9kcyI6WyJtdC1tYW5hZ2VyLWFwaTpyZXN0OmRlYWxpbmc6KjoqIiwibXQtbWFuYWdlci1hcGk6cmVzdDpwdWJsaWM6KjoqIl0sInJvbGVzIjpbInJlYWRlciIsIndyaXRlciJdLCJyZXNvdXJjZXMiOlsiKjokVVNFUl9JRCQ6KiJdfSx7ImlkIjoiYmlsbGluZy1hcGkiLCJtZXRob2RzIjpbImJpbGxpbmctYXBpOnJlc3Q6cHVibGljOio6KiJdLCJyb2xlcyI6WyJyZWFkZXIiXSwicmVzb3VyY2VzIjpbIio6JFVTRVJfSUQkOioiXX1dLCJ0b2tlbklkIjoiMjAyMTAyMTMiLCJpbXBlcnNvbmF0ZWQiOmZhbHNlLCJyZWFsVXNlcklkIjoiODhiODllMWU5ZjcxOWU2ZDRkYzNmZjIwMjA3YzM5M2QiLCJpYXQiOjE3MTIwNjMzNDIsImV4cCI6MTcxOTgzOTM0Mn0.g-52P3c8koAhpuBRsp5wYHfy6O6ES67TxcL9swk_HKCXxRQ85KLbf3H3nFEmudJmOz7cfiTlOJqwO754oEGOTEoLi0Vjjm9tGkL-8dcJF0TEUWyWy_8Uwod9uxVw-92_qNiWbehvCCCSWOcGjRPnZXwElT0TJ8TI08D9OxcCmLoIhenZmjGd2sWws5jCXZBxn5K7y-Z28wHwPLhAPHDpw1hnfdu03iatMiS0h7MnmuR3HHPuM6-IQYPK_vf0RuJ5EMzWw-reh413DNbMfS9mycYspfgGXfOixf7oDvElIlZbVd6LSuBAE6knR6y7_LP01hRyD69v4dDBDCyg_mRFZIB8wYqMrVNGUl299UzK-pzjxu7uB6CEyuLDLJK6mShQrulDaYp5-ChkPIrMG0oxRlnf4tQhhHzfgskUhaTkmBevA1N86F57-9ZUows22YgGNAem3c3v1vmxI91-A6I1vPRSAPEdnSRzkLRqFg0FeLi4-PPvDvTnrTih9Qk8h932ddE7Kbsh581v0meTLgAmcq9sPCVkdXEQF-FLzBZpJjX_T3vz52JbwknVEORiNAKxLd64TsVYnMfDuIuRlywnv8EjFLKTHISNZmW3huxLQ5yen7irS6MwWW9U3UfFsiL7djPFDQGLulMIm7Iym-H22rPi1KANPEowHokfxeUJDyE'; 6 | // your MetaApi account id 7 | // the account must have field riskManagementApiEnabled set to true 8 | const accountId = '07b56ada-ac57-41b7-bdb1-1116462cafd8'; 9 | const domain = 'agiliumtrade.agiliumtrade.ai'; 10 | 11 | const riskManagement = new RiskManagement(token, {domain}); 12 | const riskManagementApi = riskManagement.riskManagementApi; 13 | 14 | class ExamplePeriodStatisticsListener extends PeriodStatisticsListener { 15 | async onPeriodStatisticsUpdated(periodStatisticsEvent) { 16 | console.log('period statistics updated', periodStatisticsEvent); 17 | } 18 | 19 | async onPeriodStatisticsCompleted() { 20 | console.log('period completed event received'); 21 | } 22 | 23 | async onTrackerCompleted(){ 24 | console.log('tracker completed event received'); 25 | } 26 | 27 | async onConnected() { 28 | console.log('on connected event received'); 29 | } 30 | 31 | async onDisconnected() { 32 | console.log('on disconnected event received'); 33 | } 34 | 35 | async onError(error) { 36 | console.log('error event received', error); 37 | } 38 | } 39 | 40 | async function main() { 41 | try { 42 | // creating a tracker 43 | const trackerId = await riskManagementApi.createTracker(accountId, { 44 | name: 'example-tracker', 45 | absoluteDrawdownThreshold: 5, 46 | period: 'day' 47 | }); 48 | console.log('Created an event tracker ' + trackerId.id); 49 | 50 | // adding a period statistics listener 51 | const periodStatisticsListener = new ExamplePeriodStatisticsListener(accountId, trackerId.id); 52 | const listenerId = 53 | await riskManagementApi.addPeriodStatisticsListener(periodStatisticsListener, accountId, trackerId.id); 54 | 55 | console.log('Streaming period statistics events for 1 minute...'); 56 | await new Promise(res => setTimeout(res, 1000 * 60)); 57 | riskManagementApi.removePeriodStatisticsListener(listenerId); 58 | 59 | const equityChart = await riskManagementApi.getEquityChart(accountId); 60 | console.log('period statistics', JSON.stringify(equityChart)); 61 | } catch (err) { 62 | console.error(err); 63 | } 64 | process.exit(); 65 | } 66 | 67 | main(); 68 | --------------------------------------------------------------------------------