{"id":20489314,"url":"https://github.com/metaapi/metaapi-copyfactory-javascript-sdk","last_synced_at":"2025-04-13T16:32:36.885Z","repository":{"id":206157687,"uuid":"715987140","full_name":"metaapi/metaapi-copyfactory-javascript-sdk","owner":"metaapi","description":"Javascript SDK for CopyFactory trade copying API. Can copy trades both between MetaTrader 5 (MT5) and MetaTrader 4 (MT4)","archived":false,"fork":false,"pushed_at":"2024-01-18T16:47:12.000Z","size":23,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-25T13:00:32.776Z","etag":null,"topics":["api","cloud","copytrade","javascript","metaapi","metaapi-cloud","metatrader","metatrader4","metatrader5","mt4","mt4-api","mt5","mt5-api","nodejs","rest","risk-filters","trade-copying","trading"],"latest_commit_sha":null,"homepage":"https://metaapi.cloud","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metaapi.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-08T08:41:25.000Z","updated_at":"2024-06-19T17:12:55.683Z","dependencies_parsed_at":null,"dependency_job_id":"9df9ad0e-8f66-414c-aee6-fa0d3c9f20e4","html_url":"https://github.com/metaapi/metaapi-copyfactory-javascript-sdk","commit_stats":{"total_commits":8,"total_committers":1,"mean_commits":8.0,"dds":0.0,"last_synced_commit":"c14c640021dcc3fa01525f23bc80041cc9553676"},"previous_names":["metaapi/metaapi-copyfactory-javascript-sdk"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaapi%2Fmetaapi-copyfactory-javascript-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaapi%2Fmetaapi-copyfactory-javascript-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaapi%2Fmetaapi-copyfactory-javascript-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metaapi%2Fmetaapi-copyfactory-javascript-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metaapi","download_url":"https://codeload.github.com/metaapi/metaapi-copyfactory-javascript-sdk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248743779,"owners_count":21154739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","cloud","copytrade","javascript","metaapi","metaapi-cloud","metatrader","metatrader4","metatrader5","mt4","mt4-api","mt5","mt5-api","nodejs","rest","risk-filters","trade-copying","trading"],"created_at":"2024-11-15T17:12:19.433Z","updated_at":"2025-04-13T16:32:36.875Z","avatar_url":"https://github.com/metaapi.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# CopyFactory trade copying API for javascript (a member of [metaapi.cloud](https://metaapi.cloud) project)\n\nCopyFactory is a powerful copy trading API which makes developing forex trade copying applications as easy as writing few lines of code.\n\nCopyFactory API is a member of MetaApi project ([https://metaapi.cloud](https://metaapi.cloud)), a powerful cloud forex trading API which supports both MetaTrader 4 and MetaTrader 5 platforms.\n\nMetaApi is a paid service, however we may offer a free tier access in some cases.\n\nThe [MetaApi pricing](https://metaapi.cloud/#pricing) was developed with the intent to make your charges less or equal to what you would have to pay\nfor hosting your own infrastructure. This is possible because over time we managed to heavily optimize\nour MetaTrader infrastructure. And with MetaApi you can save significantly on application development and\nmaintenance costs and time thanks to high-quality API, open-source SDKs and convenience of a cloud service.\n\n## Why do we offer CopyFactory trade copying API\n\nWe found that developing reliable and flexible trade copier is a task\nwhich requires lots of effort, because developers have to solve a series\nof complex technical tasks to create a product.\n\nWe decided to share our product as it allows developers to start with a\npowerful solution in almost no time, saving on development and\ninfrastructure maintenance costs.\n## Frequently asked questions (FAQ)\nFAQ is located here: [https://metaapi.cloud/docs/copyfactory/faq/](https://metaapi.cloud/docs/copyfactory/faq/)\n\n## CopyFactory copytradging API features\n\nFeatures supported:\n\n- low latency trade copying API\n- reliable trade copying API\n- suitable for large-scale deployments\n- suitable for large number of subscribers\n- connect arbitrary number of strategy providers and subscribers\n- subscribe accounts to multiple strategies at once\n- select arbitrary copy ratio for each subscription\n- configure symbol mapping between strategy providers and subscribers\n- apply advanced risk filters on strategy provider side\n- override risk filters on subscriber side\n- provide multiple strategies from a single account based on magic or symbol filters\n- supports manual trading on subscriber accounts while copying trades\n- synchronize subscriber account with strategy providers\n- monitor trading history\n- calculate trade copying commissions for account managers\n- support portfolio strategies as trading signal source, i.e. the strategies which include signals of several other strategies (also known as combos on some platforms)\n- webhooks for external systems to create trading signals on strategies\n\nPlease note that trade copying to MT5 netting accounts is not supported in the current API version\n\nPlease check Features section of the [https://metaapi.cloud/docs/copyfactory/](https://metaapi.cloud/docs/copyfactory/) documentation for detailed description of all settings you can make\n\n## REST API documentation\nCopyFactory SDK is built on top of CopyFactory REST API.\n\nCopyFactory REST API docs are available at [https://metaapi.cloud/docs/copyfactory/](https://metaapi.cloud/docs/copyfactory/)\n\n## FAQ\nPlease check this page for FAQ: [https://metaapi.cloud/docs/copyfactory/faq/](https://metaapi.cloud/docs/copyfactory/faq/).\n\n## Code examples\nWe published some code examples in our github repository, namely:\n\n- Javascript: [https://github.com/metaapi/metaapi-copyfactory-javascript-sdk/tree/master/examples](https://github.com/metaapi/metaapi-copyfactory-javascript-sdk/tree/master/examples)\n\n## Installation\n```bash\nnpm install --save metaapi.cloud-sdk\n```\n\n## Installing SDK in browser SPA applications\n```bash\nnpm install --save metaapi.cloud-sdk\n```\n\n## Installing SDK in browser HTML applications\n```html\n\u003cscript src=\"unpkg.com/metaapi.cloud-sdk\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const token = '...';\n    const api = new CopyFactory(token);\n\u003c/script\u003e\n```\n\n## Retrieving API token\nPlease visit [https://app.metaapi.cloud/token](https://app.metaapi.cloud/token) web UI to obtain your API token.\n\n## Configuring trade copying\n\nIn order to configure trade copying you need to:\n\n- add MetaApi MetaTrader accounts with CopyFactory as application field value (see above)\n- create CopyFactory provider and subscriber accounts and connect them to MetaApi accounts via connectionId field\n- create a strategy being copied\n- subscribe subscriber CopyFactory accounts to the strategy\n\n```javascript\nimport MetaApi, {CopyFactory} from 'metaapi.cloud-sdk';\n\nconst token = '...';\nconst metaapi = new MetaApi(token);\nconst copyfactory = new CopyFactory(token);\n\n// retrieve MetaApi MetaTrader accounts with CopyFactory as application field value\n// provider account must have PROVIDER value in copyFactoryRoles\nconst providerMetaapiAccount = await api.metatraderAccountApi.getAccount('providerMetaapiAccountId');\nif(!providerMetaapiAccount.copyFactoryRoles || !providerMetaapiAccount.copyFactoryRoles.includes('PROVIDER')) {\n  throw new Error('Please specify PROVIDER copyFactoryRoles value in your MetaApi account in ' +\n    'order to use it in CopyFactory API');\n}\n// subscriber account must have SUBSCRIBER value in copyFactoryRoles\nconst subscriberMetaapiAccount = await api.metatraderAccountApi.getAccount('subscriberMetaapiAccountId');\nif(!subscriberMetaapiAccount.copyFactoryRoles || !subscriberMetaapiAccount.copyFactoryRoles.includes('SUBSCRIBER')) {\n  throw new Error('Please specify SUBSCRIBER copyFactoryRoles value in your MetaApi account in ' +\n    'order to use it in CopyFactory API');\n}\n\nlet configurationApi = copyfactory.configurationApi;\n\n// create a strategy being copied\nlet strategyId = await configurationApi.generateStrategyId();\nawait configurationApi.updateStrategy(strategyId.id, {\n  name: 'Test strategy',\n  description: 'Some useful description about your strategy',\n  accountId: providerMetaapiAccount.id,\n  maxTradeRisk: 0.1,\n  timeSettings: {\n    lifetimeInHours: 192,\n    openingIntervalInMinutes: 5\n  }\n});\n\n// subscribe subscriber CopyFactory accounts to the strategy\nawait configurationApi.updateSubscriber(subscriberMetaapiAccount.id, {\n  name: 'Demo account',\n  subscriptions: [\n    {\n      strategyId: strategyId.id,\n      multiplier: 1\n    }\n  ]\n});\n```\n\nSee esdoc in-code documentation for full definition of possible configuration options.\n\n### Retrieving paginated lists\n\nThere are two groups of methods to retrieve paginated lists:\n- with pagination in infinite scroll style\n- with pagination in a classic style which allows you to calculate page count\n\nThey are applied to following entities:\n- strategies: `getStrategiesWithInfiniteScrollPagination` and `getStrategiesWithClassicPagination`\n- provider portfolios: `getPortfolioStrategiesWithInfiniteScrollPagination` and `getPortfolioStrategiesWithClassicPagination`\n- subscribers: `getSubscribersWithInfiniteScrollPagination` and `getSubscribersWithClassicPagination`\n\nExample of retrieving strategies with pagination in infinite scroll style:\n```javascript\n// paginate strategies, see esdoc for full list of filter options available\nconst strategies = await api.metatraderAccountApi.getStrategiesWithInfiniteScrollPagination({limit: 10, offset: 0});\n\n// get strategies without filter (returns 1000 strategies max)\nconst strategies = await api.metatraderAccountApi.getStrategiesWithInfiniteScrollPagination();\nconst strategy = strategies.find(strategy =\u003e strategy._id === 'strategyId');\n```\n\nExample of retrieving strategies with paginiation in classic style:\n```javascript\n// paginate strategies, see esdoc for full list of filter options available\nconst strategies = await api.metatraderAccountApi.getStrategiesWithClassicPagination({limit: 10, offset: 0});\nconst strategy = strategies.items.find(strategy =\u003e strategy._id === 'strategyId');\n// number of all strategies matching filter without pagination options\nconsole.log(strategies.count);\n\n// get strategies without filter (returns 1000 strategies max)\nconst strategies = await api.metatraderAccountApi.getStrategiesWithClassicPagination();\n```\n\n## Retrieving trade copying history\n\nCopyFactory allows you to monitor transactions conducted on trading accounts in real time.\n\n### Retrieving trading history on provider side\n```javascript\nlet historyApi = copyfactory.historyApi;\n\n// retrieve trading history, please note that this method support pagination and limits number of records\nconsole.log(await historyApi.getProvidedTransactions(new Date('2020-08-01'), new Date('2020-09-01')));\n```\n\n### Retrieving trading history on subscriber side\n```javascript\nlet historyApi = copyfactory.historyApi;\n\n// retrieve trading history, please note that this method support pagination and limits number of records\nconsole.log(await historyApi.getSubscriptionTransactions(new Date('2020-08-01'), new Date('2020-09-01')));\n```\n\n## Resynchronizing subscriber accounts to providers\nThere is a configurable time limit during which the trades can be opened. Sometimes trades can not open in time due to broker errors or trading session time discrepancy.\nYou can resynchronize a subscriber account to place such late trades. Please note that positions which were\nclosed manually on a subscriber account will also be reopened during resynchronization.\n\n```javascript\nlet accountId = '...'; // CopyFactory account id\n\n// resynchronize all strategies\nawait copyfactory.tradingApi.resynchronize(accountId);\n\n// resynchronize specific strategy\nawait copyfactory.tradingApi.resynchronize(accountId, ['ABCD']);\n```\n\n## Sending external trading signals to a strategy\nYou can submit external trading signals to your trading strategy.\n\n```javascript\nconst accountId = '...';\nconst tradingApi = copyfactory.tradingApi;\nconst signalId = '...';\n\n// get signal client\nconst strategySignalClient = await tradingApi.getStrategySignalClient(strategyId);\n\n// add trading signal\nawait strategySignalClient.updateExternalSignal(signalId, {\n  symbol: 'EURUSD',\n  type: 'POSITION_TYPE_BUY',\n  time: new Date(),\n  volume: 0.01\n});\n\n// get external signals\nconsole.log(await signalClient.getStrategyExternalSignals(strategyId));\n\n// remove signal\nawait strategySignalClient.removeExternalSignal(signalId, {\n  time: new Date()\n});\n```\n\n## Retrieving trading signals\n\n```javascript\nconst accountId = '...';\nconst subscriberSignalClient = await tradingApi.getSubscriberSignalClient(accountId);\n\n// retrieve trading signals\nconsole.log(await subscriberSignalClient.getTradingSignals());\n```\n\n## Managing stopouts\nA subscription to a strategy can be stopped if the strategy have exceeded allowed risk limit.\n```javascript\nlet tradingApi = copyfactory.tradingApi;\nlet accountId = '...'; // CopyFactory account id\nlet strategyId = '...'; // CopyFactory strategy id\n\n// retrieve list of strategy stopouts\nconsole.log(await tradingApi.getStopouts(accountId));\n\n// reset a stopout so that subscription can continue\nawait tradingApi.resetSubscriptionStopouts(accountId, strategyId, 'daily-equity');\n```\n\n## Managing stopout listeners\nYou can subscribe to a stream of stopout events using the stopout listener.\n```javascript\nimport {StopoutListener} from 'metaapi.cloud-sdk';\n\nlet tradingApi = copyfactory.tradingApi;\n\n// create a custom class based on the StopoutListener\nclass Listener extends StopoutListener {\n\n  // specify the function called on event arrival\n  async onStopout(strategyStopoutEvent) {\n    console.log('Strategy stopout event', strategyStopoutEvent);\n  }\n\n  // specify the function called on error event\n  async onError(error) {\n    console.log('Error event', error);\n  }\n\n}\n\n// add listener\nconst listener = new Listener();\nconst listenerId = tradingApi.addStopoutListener(listener);\n\n// remove listener\ntradingApi.removeStopoutListener(listenerId);\n```\n\n## Retrieving subscriber trading logs\n```javascript\nlet tradingApi = copyfactory.tradingApi;\nlet accountId = '...'; // CopyFactory account id\n\n// retrieve subscriber trading log\nconsole.log(await tradingApi.getUserLog(accountId));\n\n// retrieve paginated subscriber trading log by time range\nconsole.log(await tradingApi.getUserLog(accountId, new Date(Date.now() - 24 * 60 * 60 * 1000), undefined, 20, 10));\n```\n\n## Log streaming\nYou can subscribe to a stream of strategy or subscriber log events using the user log listener.\n\n### Strategy logs\n```javascript\nimport {UserLogListener} from 'metaapi.cloud-sdk';\n\nlet tradingApi = copyfactory.tradingApi;\n\n// create a custom class based on the UserLogListener\nclass Listener extends UserLogListener {\n\n  // specify the function called on event arrival\n  async onUserLog(logEvent) {\n    console.log('Strategy user log event', logEvent);\n  }\n\n  // specify the function called on error event\n  async onError(error) {\n    console.log('Error event', error);\n  }\n\n}\n\n// add listener\nconst listener = new Listener();\nconst listenerId = tradingApi.addStrategyLogListener(listener, 'ABCD');\n\n// remove listener\ntradingApi.removeStrategyLogListener(listenerId);\n```\n\n### Subscriber logs\n```javascript\nimport {UserLogListener} from 'metaapi.cloud-sdk';\n\nlet tradingApi = copyfactory.tradingApi;\n\n// create a custom class based on the UserLogListener\nclass Listener extends UserLogListener {\n\n  // specify the function called on event arrival\n  async onUserLog(logEvent) {\n    console.log('Subscriber user log event', logEvent);\n  }\n\n  // specify the function called on error event\n  async onError(error) {\n    console.log('Error event', error);\n  }\n\n}\n\n// add listener\nconst listener = new Listener();\nconst listenerId = tradingApi.addSubscriberLogListener(listener, 'accountId');\n\n// remove listener\ntradingApi.removeSubscriberLogListener(listenerId);\n```\n\n## Transaction streaming\nYou can subscribe to a stream of strategy or subscriber transaction events using the transaction listener.\n\n### Strategy transactions\n```javascript\nimport {TransactionListener} from 'metaapi.cloud-sdk';\n\nlet historyApi = copyfactory.historyApi;\n\n// create a custom class based on the TransactionListener\nclass Listener extends TransactionListener {\n\n  // specify the function called on event arrival\n  async onTransaction(transactionEvent) {\n    console.log('Strategy transaction event', transactionEvent);\n  }\n\n  // specify the function called on error event\n  async onError(error) {\n    console.log('Error event', error);\n  }\n\n}\n\n// add listener\nconst listener = new Listener();\nconst listenerId = historyApi.addStrategyTransactionListener(listener, 'ABCD');\n\n// remove listener\nhistoryApi.removeStrategyTransactionListener(listenerId);\n```\n\n### Subscriber transactions\n```javascript\nimport {TransactionListener} from 'metaapi.cloud-sdk';\n\nlet historyApi = copyfactory.historyApi;\n\n// create a custom class based on the TransactionListener\nclass Listener extends TransactionListener {\n\n  // specify the function called on event arrival\n  async onTransaction(transactionEvent) {\n    console.log('Subscriber transaction event', transactionEvent);\n  }\n\n  // specify the function called on error event\n  async onError(error) {\n    console.log('Error event', error);\n  }\n\n}\n\n// add listener\nconst listener = new Listener();\nconst listenerId = historyApi.addSubscriberTransactionListener(listener, 'accountId');\n\n// remove listener\nhistoryApi.removeSubscriberTransactionListener(listenerId);\n```\n\n## Webhooks\n\nWebhooks can be created on specific strategies and their URLs can be provided to external systems to create external trading signals. The URL contains a secret webhook ID, so no extra authorization is required on a REST API invocation to a webhook.\n\n```javascript\nconst strategyId = '...';\n\nlet webhook = await copyfactory.configurationApi.createWebhook(strategyId);\nlet url = webhook.url;\n```\n\nFor example, if `webhook.url` is `https://copyfactory-api-v1.london.agiliumtrade.ai/webhooks/yMLd8aviewgFfS4NBxZETkoVPbWAJ92t` then a request can be sent to it to create an external signal:\n\n```bash\ncurl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{\n  \"symbol\": \"EURUSD\",\n  \"type\": \"POSITION_TYPE_BUY\",\n  \"time\": \"2024-12-19T06:52:19.679Z\",\n  \"volume\": 0.1\n}' 'https://copyfactory-api-v1.london.agiliumtrade.ai/webhooks/yMLd8aviewgFfS4NBxZETkoVPbWAJ92t'\n```\n\n## Related projects:\nTake a look at our website for the full list of APIs and features supported [https://metaapi.cloud/#features](https://metaapi.cloud/#features)\n\nSome of the APIs you might decide to use together with MetaStats API are:\n\n1. MetaApi cloud forex API [https://metaapi.cloud/docs/client/](https://metaapi.cloud/docs/client/)\n2. MetaTrader account management API [https://metaapi.cloud/docs/provisioning/](https://metaapi.cloud/docs/provisioning/)\n3. MetaStats forex trading metrics API [https://metaapi.cloud/docs/metastats/](https://metaapi.cloud/docs/metastats/)\n4. MetaApi MT manager API [https://metaapi.cloud/docs/manager/](https://metaapi.cloud/docs/manager/)\n5. MetaApi risk management API [https://metaapi.cloud/docs/risk-management/](https://metaapi.cloud/docs/risk-management/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaapi%2Fmetaapi-copyfactory-javascript-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetaapi%2Fmetaapi-copyfactory-javascript-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetaapi%2Fmetaapi-copyfactory-javascript-sdk/lists"}