
Security News
Feross on Risky Business Weekly Podcast: npm’s Ongoing Supply Chain Attacks
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.
metaapi.cloud-copyfactory-sdk
Advanced tools
Javascript SDK for SDK for CopyFactory trade copying API. Can copy trades both between MetaTrader 5 (MT5) and MetaTrader 4 (MT4). (https://metaapi.cloud)
CopyFactory is a powerful copy trading API which makes developing forex trade copying applications as easy as writing few lines of code.
CopyFactory API is a member of MetaApi project (https://metaapi.cloud), a powerful cloud forex trading API which supports both MetaTrader 4 and MetaTrader 5 platforms.
MetaApi is a paid service, however we may offer a free tier access in some cases.
The MetaApi pricing was developed with the intent to make your charges less or equal to what you would have to pay for hosting your own infrastructure. This is possible because over time we managed to heavily optimize our MetaTrader infrastructure. And with MetaApi you can save significantly on application development and maintenance costs and time thanks to high-quality API, open-source SDKs and convenience of a cloud service.
We found that developing reliable and flexible trade copier is a task which requires lots of effort, because developers have to solve a series of complex technical tasks to create a product.
We decided to share our product as it allows developers to start with a powerful solution in almost no time, saving on development and infrastructure maintenance costs.
FAQ is located here: https://metaapi.cloud/docs/copyfactory/faq/
Features supported:
Please note that trade copying to MT5 netting accounts is not supported in the current API version
Please check Features section of the https://metaapi.cloud/docs/copyfactory/ documentation for detailed description of all settings you can make
CopyFactory SDK is built on top of CopyFactory REST API.
CopyFactory REST API docs are available at https://metaapi.cloud/docs/copyfactory/
Please check this page for FAQ: https://metaapi.cloud/docs/copyfactory/faq/.
We published some code examples in our github repository, namely:
npm install --save metaapi.cloud-sdk
npm install --save metaapi.cloud-sdk
<script src="unpkg.com/metaapi.cloud-sdk"></script>
<script>
const token = '...';
const api = new CopyFactory(token);
</script>
Please visit https://app.metaapi.cloud/token web UI to obtain your API token.
In order to configure trade copying you need to:
import MetaApi, {CopyFactory} from 'metaapi.cloud-sdk';
const token = '...';
const metaapi = new MetaApi(token);
const copyfactory = new CopyFactory(token);
// retrieve MetaApi MetaTrader accounts with CopyFactory as application field value
// provider account must have PROVIDER value in copyFactoryRoles
const providerMetaapiAccount = await api.metatraderAccountApi.getAccount('providerMetaapiAccountId');
if(!providerMetaapiAccount.copyFactoryRoles || !providerMetaapiAccount.copyFactoryRoles.includes('PROVIDER')) {
throw new Error('Please specify PROVIDER copyFactoryRoles value in your MetaApi account in ' +
'order to use it in CopyFactory API');
}
// subscriber account must have SUBSCRIBER value in copyFactoryRoles
const subscriberMetaapiAccount = await api.metatraderAccountApi.getAccount('subscriberMetaapiAccountId');
if(!subscriberMetaapiAccount.copyFactoryRoles || !subscriberMetaapiAccount.copyFactoryRoles.includes('SUBSCRIBER')) {
throw new Error('Please specify SUBSCRIBER copyFactoryRoles value in your MetaApi account in ' +
'order to use it in CopyFactory API');
}
let configurationApi = copyfactory.configurationApi;
// create a strategy being copied
let strategyId = await configurationApi.generateStrategyId();
await configurationApi.updateStrategy(strategyId.id, {
name: 'Test strategy',
description: 'Some useful description about your strategy',
accountId: providerMetaapiAccount.id,
maxTradeRisk: 0.1,
timeSettings: {
lifetimeInHours: 192,
openingIntervalInMinutes: 5
}
});
// subscribe subscriber CopyFactory accounts to the strategy
await configurationApi.updateSubscriber(subscriberMetaapiAccount.id, {
name: 'Demo account',
subscriptions: [
{
strategyId: strategyId.id,
multiplier: 1
}
]
});
See esdoc in-code documentation for full definition of possible configuration options.
There are two groups of methods to retrieve paginated lists:
They are applied to following entities:
getStrategiesWithInfiniteScrollPagination
and getStrategiesWithClassicPagination
getPortfolioStrategiesWithInfiniteScrollPagination
and getPortfolioStrategiesWithClassicPagination
getSubscribersWithInfiniteScrollPagination
and getSubscribersWithClassicPagination
Example of retrieving strategies with pagination in infinite scroll style:
// paginate strategies, see esdoc for full list of filter options available
const strategies = await api.metatraderAccountApi.getStrategiesWithInfiniteScrollPagination({limit: 10, offset: 0});
// get strategies without filter (returns 1000 strategies max)
const strategies = await api.metatraderAccountApi.getStrategiesWithInfiniteScrollPagination();
const strategy = strategies.find(strategy => strategy._id === 'strategyId');
Example of retrieving strategies with paginiation in classic style:
// paginate strategies, see esdoc for full list of filter options available
const strategies = await api.metatraderAccountApi.getStrategiesWithClassicPagination({limit: 10, offset: 0});
const strategy = strategies.items.find(strategy => strategy._id === 'strategyId');
// number of all strategies matching filter without pagination options
console.log(strategies.count);
// get strategies without filter (returns 1000 strategies max)
const strategies = await api.metatraderAccountApi.getStrategiesWithClassicPagination();
CopyFactory allows you to monitor transactions conducted on trading accounts in real time.
let historyApi = copyfactory.historyApi;
// retrieve trading history, please note that this method support pagination and limits number of records
console.log(await historyApi.getProvidedTransactions(new Date('2020-08-01'), new Date('2020-09-01')));
let historyApi = copyfactory.historyApi;
// retrieve trading history, please note that this method support pagination and limits number of records
console.log(await historyApi.getSubscriptionTransactions(new Date('2020-08-01'), new Date('2020-09-01')));
There 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. You can resynchronize a subscriber account to place such late trades. Please note that positions which were closed manually on a subscriber account will also be reopened during resynchronization.
let accountId = '...'; // CopyFactory account id
// resynchronize all strategies
await copyfactory.tradingApi.resynchronize(accountId);
// resynchronize specific strategy
await copyfactory.tradingApi.resynchronize(accountId, ['ABCD']);
You can submit external trading signals to your trading strategy.
const accountId = '...';
const tradingApi = copyfactory.tradingApi;
const signalId = '...';
// get signal client
const strategySignalClient = await tradingApi.getStrategySignalClient(strategyId);
// add trading signal
await strategySignalClient.updateExternalSignal(signalId, {
symbol: 'EURUSD',
type: 'POSITION_TYPE_BUY',
time: new Date(),
volume: 0.01
});
// get external signals
console.log(await signalClient.getStrategyExternalSignals(strategyId));
// remove signal
await strategySignalClient.removeExternalSignal(signalId, {
time: new Date()
});
const accountId = '...';
const subscriberSignalClient = await tradingApi.getSubscriberSignalClient(accountId);
// retrieve trading signals
console.log(await subscriberSignalClient.getTradingSignals());
A subscription to a strategy can be stopped if the strategy have exceeded allowed risk limit.
let tradingApi = copyfactory.tradingApi;
let accountId = '...'; // CopyFactory account id
let strategyId = '...'; // CopyFactory strategy id
// retrieve list of strategy stopouts
console.log(await tradingApi.getStopouts(accountId));
// reset a stopout so that subscription can continue
await tradingApi.resetSubscriptionStopouts(accountId, strategyId, 'daily-equity');
You can subscribe to a stream of stopout events using the stopout listener.
import {StopoutListener} from 'metaapi.cloud-sdk';
let tradingApi = copyfactory.tradingApi;
// create a custom class based on the StopoutListener
class Listener extends StopoutListener {
// specify the function called on event arrival
async onStopout(strategyStopoutEvent) {
console.log('Strategy stopout event', strategyStopoutEvent);
}
// specify the function called on error event
async onError(error) {
console.log('Error event', error);
}
}
// add listener
const listener = new Listener();
const listenerId = tradingApi.addStopoutListener(listener);
// remove listener
tradingApi.removeStopoutListener(listenerId);
let tradingApi = copyfactory.tradingApi;
let accountId = '...'; // CopyFactory account id
// retrieve subscriber trading log
console.log(await tradingApi.getUserLog(accountId));
// retrieve paginated subscriber trading log by time range
console.log(await tradingApi.getUserLog(accountId, new Date(Date.now() - 24 * 60 * 60 * 1000), undefined, 20, 10));
You can subscribe to a stream of strategy or subscriber log events using the user log listener.
import {UserLogListener} from 'metaapi.cloud-sdk';
let tradingApi = copyfactory.tradingApi;
// create a custom class based on the UserLogListener
class Listener extends UserLogListener {
// specify the function called on event arrival
async onUserLog(logEvent) {
console.log('Strategy user log event', logEvent);
}
// specify the function called on error event
async onError(error) {
console.log('Error event', error);
}
}
// add listener
const listener = new Listener();
const listenerId = tradingApi.addStrategyLogListener(listener, 'ABCD');
// remove listener
tradingApi.removeStrategyLogListener(listenerId);
import {UserLogListener} from 'metaapi.cloud-sdk';
let tradingApi = copyfactory.tradingApi;
// create a custom class based on the UserLogListener
class Listener extends UserLogListener {
// specify the function called on event arrival
async onUserLog(logEvent) {
console.log('Subscriber user log event', logEvent);
}
// specify the function called on error event
async onError(error) {
console.log('Error event', error);
}
}
// add listener
const listener = new Listener();
const listenerId = tradingApi.addSubscriberLogListener(listener, 'accountId');
// remove listener
tradingApi.removeSubscriberLogListener(listenerId);
You can subscribe to a stream of strategy or subscriber transaction events using the transaction listener.
import {TransactionListener} from 'metaapi.cloud-sdk';
let historyApi = copyfactory.historyApi;
// create a custom class based on the TransactionListener
class Listener extends TransactionListener {
// specify the function called on event arrival
async onTransaction(transactionEvent) {
console.log('Strategy transaction event', transactionEvent);
}
// specify the function called on error event
async onError(error) {
console.log('Error event', error);
}
}
// add listener
const listener = new Listener();
const listenerId = historyApi.addStrategyTransactionListener(listener, 'ABCD');
// remove listener
historyApi.removeStrategyTransactionListener(listenerId);
import {TransactionListener} from 'metaapi.cloud-sdk';
let historyApi = copyfactory.historyApi;
// create a custom class based on the TransactionListener
class Listener extends TransactionListener {
// specify the function called on event arrival
async onTransaction(transactionEvent) {
console.log('Subscriber transaction event', transactionEvent);
}
// specify the function called on error event
async onError(error) {
console.log('Error event', error);
}
}
// add listener
const listener = new Listener();
const listenerId = historyApi.addSubscriberTransactionListener(listener, 'accountId');
// remove listener
historyApi.removeSubscriberTransactionListener(listenerId);
Webhooks 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.
const strategyId = '...';
let webhook = await copyfactory.configurationApi.createWebhook(strategyId);
let url = webhook.url;
For 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:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
"symbol": "EURUSD",
"type": "POSITION_TYPE_BUY",
"time": "2024-12-19T06:52:19.679Z",
"volume": 0.1
}' 'https://copyfactory-api-v1.london.agiliumtrade.ai/webhooks/yMLd8aviewgFfS4NBxZETkoVPbWAJ92t'
Take a look at our website for the full list of APIs and features supported https://metaapi.cloud/#features
Some of the APIs you might decide to use together with MetaStats API are:
FAQs
Javascript SDK for SDK for CopyFactory trade copying API. Can copy trades both between MetaTrader 5 (MT5) and MetaTrader 4 (MT4). (https://metaapi.cloud)
The npm package metaapi.cloud-copyfactory-sdk receives a total of 918 weekly downloads. As such, metaapi.cloud-copyfactory-sdk popularity was classified as not popular.
We found that metaapi.cloud-copyfactory-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.
Product
Socket’s new Tier 1 Reachability filters out up to 80% of irrelevant CVEs, so security teams can focus on the vulnerabilities that matter.
Research
/Security News
Ongoing npm supply chain attack spreads to DuckDB: multiple packages compromised with the same wallet-drainer malware.