'use strict'; import DomainClient from '../domain.client'; import MetaApiClient from '../metaapi.client'; import randomstring from 'randomstring'; import { ClassicPaginationList, CopyFactoryCloseInstructions, CopyFactoryPortfolioStrategy, CopyFactoryPortfolioStrategyUpdate, CopyFactoryStrategy, CopyFactoryStrategyUpdate, CopyFactorySubscriber, CopyFactorySubscriberUpdate, Webhook, GetPortfolioStrategiesOptions, GetStrategiesOptions, GetSubscribersOptions, GetWebhooksOptions, StrategyId, NewWebhook, WebhookIdAndUrl, WebhookUpdate } from './configuration.client.schemas'; export * from './configuration.client.schemas'; /** * metaapi.cloud CopyFactory configuration API (trade copying configuration API) client (see * https://metaapi.cloud/docs/copyfactory/) */ export default class ConfigurationClient extends MetaApiClient { /** * Constructs CopyFactory configuration API client instance * @param {DomainClient} domainClient domain client */ constructor(domainClient: DomainClient) { super(domainClient); this._domainClient = domainClient; } /** * Strategy id * @typedef {Object} StrategyId * @property {String} id strategy id */ /** * Retrieves new unused strategy id. Method is accessible only with API access token. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/generateStrategyId/ * @return {Promise} promise resolving with strategy id generated */ generateStrategyId(): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('generateStrategyId'); } const opts = { url: '/users/current/configuration/unused-strategy-id', method: 'GET', headers: { 'auth-token': this._token }, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Generates random account id * @return {String} account id */ generateAccountId(): string { return randomstring.generate(64); } /** * Retrieves CopyFactory copy trading strategies with pagination in infinite scroll style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getStrategies/ * @param {GetStrategiesOptions} [options] options * @return {Promise>} promise resolving with CopyFactory strategies found */ async getStrategiesWithInfiniteScrollPagination(options?: GetStrategiesOptions): Promise> { return this._getStrategies('1', options); } /** * Retrieves CopyFactory copy trading strategies with pagination in classic style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getStrategies/ * @param {GetStrategiesOptions} [options] options * @return {Promise>} promise resolving with CopyFactory strategies found */ async getStrategiesWithClassicPagination(options?: GetStrategiesOptions): Promise> { return this._getStrategies('2', options); } private async _getStrategies(apiVersion, options) { if (this._isNotJwtToken()) { return this._handleNoAccessError('getStrategies'); } return this._domainClient.requestCopyFactory({ url: '/users/current/configuration/strategies', method: 'GET', params: options, headers: { 'auth-token': this._token, 'api-version': apiVersion }, json: true }, true); } /** * Retrieves CopyFactory copy trading strategy by id. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getStrategy/ * @param {string} strategyId trading strategy id * @return {Promise} promise resolving with CopyFactory strategy found */ getStrategy(strategyId: string): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('getStrategy'); } const opts = { url: `/users/current/configuration/strategies/${strategyId}`, method: 'GET', headers: { 'auth-token': this._token }, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Updates a CopyFactory strategy or creates it if it does not exist. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/updateStrategy/ * @param {String} strategyId copy trading strategy id * @param {CopyFactoryStrategyUpdate} strategy trading strategy update * @return {Promise} promise resolving when strategy is updated */ updateStrategy(strategyId: string, strategy: CopyFactoryStrategyUpdate): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('updateStrategy'); } const opts = { url: `/users/current/configuration/strategies/${strategyId}`, method: 'PUT', headers: { 'auth-token': this._token }, data: strategy, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Deletes a CopyFactory strategy. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/removeStrategy/ * @param {String} strategyId copy trading strategy id * @param {CopyFactoryCloseInstructions} [closeInstructions] strategy close instructions * @return {Promise} promise resolving when strategy is removed */ removeStrategy(strategyId: string, closeInstructions?: CopyFactoryCloseInstructions): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('removeStrategy'); } const opts = { url: `/users/current/configuration/strategies/${strategyId}`, method: 'DELETE', headers: { 'auth-token': this._token }, data: closeInstructions, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Retrieves CopyFactory copy portfolio strategies with pagination in infinite scroll style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getPortfolioStrategies/ * @param {GetPortfolioStrategiesOptions} [options] options * @return {Promise>} promise resolving with CopyFactory portfolio strategies */ async getPortfolioStrategiesWithInfiniteScrollPagination(options?: GetPortfolioStrategiesOptions): Promise> { return this._getPortfolioStrategies('1', options); } /** * Retrieves CopyFactory copy portfolio strategies with pagination in classic style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getPortfolioStrategies/ * @param {GetPortfolioStrategiesOptions} [options] options * @return {Promise>} promise resolving with CopyFactory strategies found */ async getPortfolioStrategiesWithClassicPagination(options?: GetPortfolioStrategiesOptions): Promise> { return this._getPortfolioStrategies('2', options); } private async _getPortfolioStrategies(apiVersion, options) { if (this._isNotJwtToken()) { return this._handleNoAccessError('getPortfolioStrategies'); } return this._domainClient.requestCopyFactory({ url: '/users/current/configuration/portfolio-strategies', method: 'GET', params: options, headers: { 'auth-token': this._token, 'api-version': apiVersion }, json: true }, true); } /** * Retrieves CopyFactory copy portfolio strategy by id. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getPortfolioStrategy/ * @param {string} portfolioId portfolio strategy id * @return {Promise} promise resolving with CopyFactory portfolio strategy found */ getPortfolioStrategy(portfolioId: string): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('getPortfolioStrategy'); } const opts = { url: `/users/current/configuration/portfolio-strategies/${portfolioId}`, method: 'GET', headers: { 'auth-token': this._token }, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Updates a CopyFactory portfolio strategy or creates it if it does not exist. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/updatePortfolioStrategy/ * @param {String} portfolioId copy trading portfolio strategy id * @param {CopyFactoryPortfolioStrategyUpdate} portfolio portfolio strategy update * @return {Promise} promise resolving when portfolio strategy is updated */ updatePortfolioStrategy(portfolioId: string, portfolio: CopyFactoryPortfolioStrategyUpdate): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('updatePortfolioStrategy'); } const opts = { url: `/users/current/configuration/portfolio-strategies/${portfolioId}`, method: 'PUT', headers: { 'auth-token': this._token }, data: portfolio, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Deletes a CopyFactory portfolio strategy. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/removePortfolioStrategy/ * @param {String} portfolioId portfolio strategy id * @param {CopyFactoryCloseInstructions} [closeInstructions] strategy close instructions * @return {Promise} promise resolving when portfolio strategy is removed */ removePortfolioStrategy(portfolioId: string, closeInstructions?: CopyFactoryCloseInstructions): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('removePortfolioStrategy'); } const opts = { url: `/users/current/configuration/portfolio-strategies/${portfolioId}`, method: 'DELETE', headers: { 'auth-token': this._token }, data: closeInstructions, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Deletes a CopyFactory portfolio strategy member. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/removePortfolioStrategyMember/ * @param {String} portfolioId portfolio strategy id * @param {String} strategyId id of the strategy to delete member for * @param {CopyFactoryCloseInstructions} [closeInstructions] strategy close instructions * @return {Promise} promise resolving when portfolio strategy is removed */ removePortfolioStrategyMember( portfolioId: string, strategyId: string, closeInstructions?: CopyFactoryCloseInstructions ): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('removePortfolioStrategyMember'); } const opts = { url: `/users/current/configuration/portfolio-strategies/${portfolioId}/members/${strategyId}`, method: 'DELETE', headers: { 'auth-token': this._token }, data: closeInstructions, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Returns CopyFactory subscribers the user has configured with pagination in infinite scroll style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/history/getSubscribers/ * @param {GetSubscribersOptions} [options] options * @return {Promise>} promise resolving with subscribers found */ async getSubscribersWithInfiniteScrollPagination( options?: GetSubscribersOptions ): Promise> { return this._getSubscribers('1', options); } /** * Returns CopyFactory subscribers the user has configured with pagination in classic style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/history/getSubscribers/ * @param {GetSubscribersOptions} [options] options * @return {Promise>} promise resolving with subscribers found */ async getSubscribersWithClassicPagination(options?: GetSubscribersOptions): Promise> { return this._getSubscribers('2', options); } private async _getSubscribers(apiVersion, options) { if (this._isNotJwtToken()) { return this._handleNoAccessError('getSubscribers'); } return this._domainClient.requestCopyFactory({ url: '/users/current/configuration/subscribers', method: 'GET', params: options, headers: { 'auth-token': this._token, 'api-version': apiVersion }, json: true }, true); } /** * Returns CopyFactory subscriber by id. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getSubscriber/ * @param {String} subscriberId subscriber id * @returns {Promise} promise resolving with subscriber found */ getSubscriber(subscriberId: string): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('getSubscriber'); } const opts = { url: `/users/current/configuration/subscribers/${subscriberId}`, method: 'GET', headers: { 'auth-token': this._token }, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Updates CopyFactory subscriber configuration or creates it if it does not exist. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/updateSubscriber/ * @param {String} subscriberId subscriber id * @param {CopyFactorySubscriberUpdate} subscriber subscriber update * @returns {Promise} promise resolving when subscriber is updated */ updateSubscriber(subscriberId: string, subscriber: CopyFactorySubscriberUpdate): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('updateSubscriber'); } const opts = { url: `/users/current/configuration/subscribers/${subscriberId}`, method: 'PUT', headers: { 'auth-token': this._token }, data: subscriber, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Deletes subscriber configuration. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/removeSubscriber/ * @param {String} subscriberId subscriber id * @param {CopyFactoryCloseInstructions} [closeInstructions] subscriber close instructions * @returns {Promise} promise resolving when subscriber is removed */ removeSubscriber(subscriberId: string, closeInstructions?: CopyFactoryCloseInstructions): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('removeSubscriber'); } const opts = { url: `/users/current/configuration/subscribers/${subscriberId}`, method: 'DELETE', headers: { 'auth-token': this._token }, data: closeInstructions, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Deletes a subscription of subscriber to a strategy. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/removeSubscription/ * @param {String} subscriberId subscriber id * @param {String} strategyId strategy id * @param {CopyFactoryCloseInstructions} [closeInstructions] subscriber close instructions * @returns {Promise} promise resolving when subscriber is removed */ removeSubscription( subscriberId: string, strategyId: string, closeInstructions?: CopyFactoryCloseInstructions ): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('removeSubscription'); } const opts = { url: `/users/current/configuration/subscribers/${subscriberId}/subscriptions/${strategyId}`, method: 'DELETE', headers: { 'auth-token': this._token }, data: closeInstructions, json: true }; return this._domainClient.requestCopyFactory(opts); } /** * Retrieves CopyFactory user webhooks list with pagination in infinite scroll style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getWebhooks/ * @param strategyId strategy ID * @param options additional options * @return promise resolving with webhooks found */ async getWebhooksWithInfiniteScrollPagination(strategyId: string, options?: GetWebhooksOptions): Promise { let result: Webhook[] = await this._getWebhooks(strategyId, 'infiniteScroll', options); result.forEach(item => item.createdAt = new Date(item.createdAt)); return result; } /** * Retrieves CopyFactory user webhooks list with pagination in classic style. See * https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/getWebhooks/ * @param strategyId strategy ID * @param options additional options * @return promise resolving with webhooks found */ async getWebhooksWithClassicPagination( strategyId: string, options?: GetWebhooksOptions ): Promise> { let result: ClassicPaginationList = await this._getWebhooks(strategyId, 'classic', options); result.items.forEach(item => item.createdAt = new Date(item.createdAt)); return result; } private _getWebhooks( strategyId: string, paginationStyle: 'infiniteScroll' | 'classic', options?: GetWebhooksOptions ) { if (this._isNotJwtToken()) { return this._handleNoAccessError('getWebhooks'); } return this._domainClient.requestCopyFactory({ url: `/users/current/configuration/strategies/${strategyId}/webhooks`, method: 'GET', params: { ...options, paginationStyle }, headers: {'auth-token': this._token}, json: true }, true); } /** * Creates a new webhook. The webhook can be used for an external app (e.g. TradingView) to submit trading signals to * CopyFactory. See https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/createWebhook/ * @param strategyId strategy ID * @param webhook webhook * @returns promise resolving with created webhook ID and URL */ createWebhook(strategyId: string, webhook: NewWebhook): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('createWebhook'); } return this._domainClient.requestCopyFactory({ url: `/users/current/configuration/strategies/${strategyId}/webhooks`, method: 'POST', headers: {'auth-token': this._token}, data: webhook, json: true }); } /** * Updates a webhook. See https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/updateWebhook/ * @param strategyId webhook strategy ID * @param webhookId webhook ID * @param update webhook update * @returns promise resolving when updated */ updateWebhook(strategyId: string, webhookId: string, update: WebhookUpdate): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('updateWebhook'); } return this._domainClient.requestCopyFactory({ url: `/users/current/configuration/strategies/${strategyId}/webhooks/${webhookId}`, method: 'PATCH', headers: {'auth-token': this._token}, data: update, json: true }); } /** * Deletes a webhook. See https://metaapi.cloud/docs/copyfactory/restApi/api/configuration/deleteWebhook/ * @param strategyId webhook strategy ID * @param webhookId webhook ID * @returns promise resolving when deleted */ deleteWebhook(strategyId: string, webhookId: string): Promise { if (this._isNotJwtToken()) { return this._handleNoAccessError('deleteWebhook'); } return this._domainClient.requestCopyFactory({ url: `/users/current/configuration/strategies/${strategyId}/webhooks/${webhookId}`, method: 'DELETE', headers: {'auth-token': this._token}, json: true }); } }