UNPKG

metaapi.cloud-sdk

Version:

SDK for MetaApi, a professional cloud forex API which includes MetaTrader REST API and MetaTrader websocket API. Supports both MetaTrader 5 (MT5) and MetaTrader 4 (MT4). CopyFactory copy trading API included. (https://metaapi.cloud)

167 lines (150 loc) 5.55 kB
'use strict'; import MetaApiClient from '../metaApi.client'; import LoggerManager, {Logger} from '../../logger'; import {NotFoundError} from '../errorHandler'; import HttpClient from '../httpClient'; import DomainClient from '../domain.client'; /** * metaapi.cloud client API client (see https://metaapi.cloud/docs/client/) */ export default class ClientApiClient extends MetaApiClient { private _retryIntervalInSeconds: number; private _updateInterval: number; private _ignoredFieldListsCaches: {}; private _ignoredFieldListsFreshestCache: null; private _logger: Logger; /** * Constructs client API client instance * @param {HttpClient} httpClient HTTP client * @param {DomainClient} domainClient domain client */ constructor(httpClient: HttpClient, domainClient: DomainClient) { super(httpClient, domainClient); this._host = 'https://mt-client-api-v1'; this._retryIntervalInSeconds = 1; this._updateInterval = 60 * 60 * 1000; this._ignoredFieldListsCaches = {}; this._ignoredFieldListsFreshestCache = null; this._logger = LoggerManager.getLogger('ClientApiClient'); } /** * Type hashing ignored field lists * @typedef {Object} TypeHashingIgnoredFieldLists * @property {String[]} specification specification ignored fields * @property {String[]} position position ignored fields * @property {String[]} order order ignored fields */ /** * Hashing ignored field lists * @typedef {Object} HashingIgnoredFieldLists * @property {TypeHashingIgnoredFieldLists} g1 g1 hashing ignored field lists * @property {TypeHashingIgnoredFieldLists} g2 g2 hashing ignored field lists */ /** * Refreshes hashing ignored field lists * @param {String} region account region * @returns {Promise} promise resolving when the hashing field lists are updated. */ async refreshIgnoredFieldLists(region: string): Promise<any> { if(this._ignoredFieldListsCaches[region] && this._ignoredFieldListsCaches[region].requestPromise) { await this._ignoredFieldListsCaches[region].requestPromise; } else if (this._ignoredFieldListsCaches[region] && Date.now() - this._ignoredFieldListsCaches[region].lastUpdated < this._updateInterval) { return; } else { if(!this._ignoredFieldListsCaches[region]) { this._ignoredFieldListsCaches[region] = { lastUpdated: 0, data: null, requestPromise: null, updateJob: setInterval(() => this._refreshIgnoredFieldListsJob(region), 60000) }; } let resolve, reject; this._ignoredFieldListsCaches[region].requestPromise = new Promise((res, rej) => { resolve = res, reject = rej; }); let isCacheUpdated = false; while(!isCacheUpdated) { try { const host = await this._domainClient.getUrl(this._host, region); const opts = { url: `${host}/hashing-ignored-field-lists`, method: 'GET', json: true, headers: { 'auth-token': this._token } }; const response = await this._httpClient.request(opts, 'getHashingIgnoredFieldLists'); this._ignoredFieldListsCaches[region] = { lastUpdated: Date.now(), data: response, requestPromise: null }; this._ignoredFieldListsFreshestCache = response; resolve(response); isCacheUpdated = true; this._ignoredFieldListsCaches[region].retryIntervalInSeconds = this._retryIntervalInSeconds; } catch (err) { this._logger.error('Failed to update hashing ignored field list', err); this._ignoredFieldListsCaches[region].retryIntervalInSeconds = Math.min(this._ignoredFieldListsCaches[region].retryIntervalInSeconds * 2, 300); await new Promise(res => setTimeout(res, this._ignoredFieldListsCaches[region].retryIntervalInSeconds * 1000)); } } } } /** * Retrieves hashing ignored field lists * @param {String} region account region * @returns {HashingIgnoredFieldLists} promise resolving with hashing ignored field lists */ getHashingIgnoredFieldLists(region: string): HashingIgnoredFieldLists { if(region === 'combined') { if (this._ignoredFieldListsFreshestCache) { return this._ignoredFieldListsFreshestCache; } else{ throw new NotFoundError('Ignored field lists not found'); } } if(this._ignoredFieldListsCaches[region] && this._ignoredFieldListsCaches[region].data) { return this._ignoredFieldListsCaches[region].data; } else { throw new NotFoundError(`Ignored field lists for region ${region} not found`); } } async _refreshIgnoredFieldListsJob(region) { if(!this._ignoredFieldListsCaches[region].requestPromise && Date.now() - this._ignoredFieldListsCaches[region].lastUpdated > this._updateInterval) { await this.refreshIgnoredFieldLists(region); } } } /** * Type hashing ignored field lists */ export declare type TypeHashingIgnoredFieldLists = { /** * specifications ignored fields */ specification: string[], /** * position ignored fields */ position: string[], /** * order ignored fields */ order: string[], } /** * Hashing ignored field lists */ export declare type HashingIgnoredFieldLists = { /** * g1 hashing ignored field lists */ g1: TypeHashingIgnoredFieldLists, /** * g2 hashing ignored field lists */ g2: TypeHashingIgnoredFieldLists, }