Followers Management

A collection of API methods to perform followers’ lookup / creation / amendment of copy rules / removal / querying copy trading actual and historical data.

com.nj4x.node.trade_copier.follower.create(follower)

WAMP procedure to add new copy trading configuration (leader/follower accounts pair) to the system.

Parameters:followerFollower object to create. ClientId, LeaderRef and TradeCopierAccountRef fields must be defined.
Returns:(dict) {Entity: Follower, Exception: object} - Entity element represents newly created Follower or None in case of error. Exception field is populated in case of follower creation error
Example:
@inlineCallbacks
def create(self, follower):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.create` `WAMP <https://wamp-proto.org>`_ API method.

    :return: :class:`.Follower` - newly created Follower or *None* in case of error.
    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.create", follower)
    #
    if res.get("Exception") is None:
        return res.get("Entity")
    raise Exception(res['Exception']["Message"])
# ---------------------------------
# Create Follower configuration
# ---------------------------------
follower = yield from ct_followers_service.create(
    {'ClientId': client_id,
     'TradeCopierAccountRef': mt4_follower_acct["Id"],
     'LeaderRef': leader["Id"],
     'IsVerified': True,
     'CutLossPercentage': 5.0,
     'CopyRules': [
         {
             'LeaderSymbol': 'EURUSD',
             'FollowerSymbol': 'EURUSD',
             'SymbolCopyRuleMode': {
                 'Mode': 0  # OneToOne
             },
             'MinLot': 0.01,
             'MaxLot': 100000.0
         },
         {
             'LeaderSymbol': 'AUDUSD',
             'FollowerSymbol': 'AUDUSD',
             'SymbolCopyRuleMode': {
                 'Mode': 1,  # WithPercentageMultiplier
                 'PercentageMultiplier': 50.0
             },
             'IsAdjustByLeverageRatio': True,
             'MinLot': 0.01,
             'MaxLot': 100000.0
         },
         {
             'LeaderSymbol': 'USDJPY',
             'FollowerSymbol': 'USDJPY',
             'SymbolCopyRuleMode': {
                 'Mode': 5,  # FixedNoOfLots
                 'FixedLots': 0.01
             },
             'MinLot': 0.01,
             'MaxLot': 100000.0
         }
     ]
     })
com.nj4x.node.trade_copier.follower.update(follower)

WAMP procedure to amend copy trading configuration .

param follower:Follower object to update.
return:(dict) {Entity: Follower, Exception: object} - Entity element represents updated Follower. Exception field is populated in case of Follower amendment error
Example:
@inlineCallbacks
def update(self, follower):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.update` `WAMP <https://wamp-proto.org>`_ API method.

    :return: updated :class:`.Follower` object
    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.update", follower)
    #
    if res.get("Exception") is None:
        return res.get("Entity")
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.delete(follower)

WAMP procedure to remove Follower from the system.

param follower:Follower object to delete. Only Id field may be filled, e.g. {“Id”: 1234}
return:(dict) {Exception: object} - Exception field is populated in case of Follower deletion error
Example:
@inlineCallbacks
def delete(self, follower):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.delete` `WAMP <https://wamp-proto.org>`_ API method.

    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.delete", follower)
    #
    if res.get("Exception") is None:
        return
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.find_by_client_id(clientId: int)

WAMP procedure to lookup all client’s Followers.

param clientId:(long) External system client ID to lookup linked Followers of.
return:(dict) {Entities: Follower [], Exception: object} - Entities list will be empty in case no Followers are defined for the client. Exception field is populated in case of any system error.
Example:
@inlineCallbacks
def find_by_client_id(self, client_id: int):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.find_by_client_id` `WAMP <https://wamp-proto.org>`_ API method.

    :return: list of :class:`.Follower` configurations defined for the client.
    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.find_by_client_id", client_id)
    #
    if res.get("Exception") is None:
        return res.get("Entities")
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.find_by_leader_id(leaderId: int)

WAMP procedure to lookup all Followers linked to the specified Leader’s account.

param leaderId:(long) Leader’s ID
return:(dict) {Entities: Follower [], Exception: object} - Entities list will be empty in case no Followers are subscribed to the Leader. Exception field is populated in case of any system error.
Example:
@inlineCallbacks
def find_by_leader_id(self, leader_id: int):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.find_by_leader_id` `WAMP <https://wamp-proto.org>`_ API method.

    :return: list of :class:`.Follower` linked to the specified Leader's account.
    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.find_by_leader_id", leader_id)
    #
    if res.get("Exception") is None:
        return res.get("Entities")
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.find_by_trade_copier_account_id(tradeCopyAccountId: int)

WAMP procedure to lookup all Follower configurations linked to the specified copier MT Account.

param tradeCopyAccountId:
 (long) MT Account primary key
return:(dict) {Entities: Follower [], Exception: object} - Entities list will be empty in case MT Account does not follow any Leader. Exception field is populated in case of any system error.
Example:
@inlineCallbacks
def find_by_trade_copier_account_id(self, mt_account_id: int):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.find_by_trade_copier_account_id` `WAMP <https://wamp-proto.org>`_ API method.

    :return: list of :class:`.Follower` configurations linked to the specified copier MT Account.
    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.find_by_trade_copier_account_id",
                                   mt_account_id)
    #
    if res.get("Exception") is None:
        return res.get("Entities")
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.find_all()

WAMP procedure to get a list of all configured Followers.

return:(dict) {Entities: Follower [], Exception: object} - Entities list will be empty in case no Followers are found. Exception field is populated in case of any system error.
Example:
@inlineCallbacks
def find_all(self):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.find_all` `WAMP <https://wamp-proto.org>`_ API method.

    :return: list of :class:`.Follower` objects (if found) or *None* in case of no copy trading Followers are defined.
    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.find_all")
    #
    if res.get("Exception") is None:
        return res.get("Entities")
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.find_by_id(id: int)

WAMP procedure to lookup a Follower by its primary key.

param id:(long) ID of the Follower to lookup.
return:(dict) {Entity: Follower, Exception: object} - Entity element will be None in case Follower with requested ID is not found. Exception field is populated in case of any system error.
Example:
@inlineCallbacks
def find_by_id(self, follower_id):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.find_by_id` `WAMP <https://wamp-proto.org>`_ API method.

    :return: :class:`.Follower` object (if found) or *None* in case a :class:`.Follower` with such ID does not exist.
    :raises: *Exception* in case of any server error.
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.find_by_id", follower_id)
    #
    if res.get("Exception") is None:
        return res.get("Entity")
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.get_paged_history(follower, paging, filter, sort)

WAMP procedure to get Follower’s historical trades.

param follower:Follower object to retrieve historical trades of.
param paging:dict {‘PageSize’: int, ‘PageNo’: int} - PageSize - number of rows per page, PageNo - requested page number (starting from 0)
param filter:dict - filtering predicate, e.g. {‘TradeOperation’: {‘$in’: [“OP_SELL”, “OP_BUY”]}
param sort:dict - sort parameter the field or fields to sort by and a value of 1 or -1 to specify an ascending or descending sort respectively., e.g. {‘CloseTime’: 1, ‘Ticket’: -1}
return:(dict) {‘Result’: (dict) {‘PageRows’: list of HistoricalTrade, ‘PageNo’: int, ‘TotalPages’: int, ‘TotalRows’: int}, ‘Exception’: object} - Exception field is populated in case of any system error.
Example:
@inlineCallbacks
def get_paged_history(self, follower, paging_req, filters=None, sorts=None):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.get_paged_history` `WAMP <https://wamp-proto.org>`_ API method.

    :return:    *(dict)* {'PageRows': *list* of :class:`.HistoricalTrade`, 'PageNo': int, 'TotalPages': int, 'TotalRows': int}
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.get_paged_history",
                                   **{'follower': {"Id": follower["Id"]}, "paging": paging_req, 'filter': filters,
                                      'sort': sorts})
    #
    if res.get("Exception") is None:
        return res.get("Result")
    raise Exception(res['Exception']["Message"])
com.nj4x.node.trade_copier.follower.get_paged_active_trades(follower, paging, filter, sort)

WAMP procedure to get active copy trades of the Follower.

param follower:Follower object to retrieve active trades of.
param paging:dict {‘PageSize’: int, ‘PageNo’: int} - PageSize - number of rows per page, PageNo - requested page number (starting from 0)
param filter:dict - filtering predicate, e.g. {‘TradeOperation’: {‘$in’: [“OP_SELL”, “OP_BUY”]}
param sort:dict - sort parameter the field or fields to sort by and a value of 1 or -1 to specify an ascending or descending sort respectively., e.g. {‘CloseTime’: 1, ‘Ticket’: -1}
return:(dict) {‘Result’: (dict) {‘PageRows’: list of HistoricalTrade, ‘PageNo’: int, ‘TotalPages’: int, ‘TotalRows’: int}, ‘Exception’: object} - Exception field is populated in case of any system error.
Example:
@inlineCallbacks
def get_paged_active_trades(self, follower, paging_req, filters=None, sorts=None):
    """
    This function is a wrapper for :func:`~com.nj4x.node.trade_copier.follower.get_paged_active_trades` `WAMP <https://wamp-proto.org>`_ API method.

    :return:    *(dict)* {'PageRows': *list* of :class:`.HistoricalTrade`, 'PageNo': int, 'TotalPages': int, 'TotalRows': int}
    """
    self._check_session()
    #
    res = yield self._session.call(u"com.nj4x.node.trade_copier.follower.get_paged_active_trades",
                                   **{'follower': {"Id": follower["Id"]}, "paging": paging_req, 'filter': filters,
                                      'sort': sorts})
    #
    if res.get("Exception") is None:
        return res.get("Result")
    raise Exception(res['Exception']["Message"])
class com.nj4x.node.trade_copier.follower.Follower(*args, **kwargs)

A class used to represent Copy Trading Follower

Id: long
Primary key
ClientId: long
External CRM system’s client ID
TradeCopierAccountRef: long
Reference to the MT Account (PK) which copies trades from a Leader
LeaderRef: long
Reference to the Leader (PK) which provides trades for copying to TradeCopierAccount
IsVerified: bool
Administrator-defined flag: True - in case Follower is allowed to copy trades
Status: int
(readonly) Current status of the Follower: Pending=0, Copying=1, Stopped=2, Error=3
StatusInfo: str
(readonly) Error message in case of erroneous *Status*(3)
IsDeleted: bool
(readonly) system defined property indicating Follower removal process initiation
IsKeepCopiedOrdersWhenDeleted: bool
User defined flag, True - in case a user wants to keep all active copied positions in the event of the Follower removal
IsRenewManuallyClosedCopies: bool
User defined flag, True - in case a user wants the system to copy leader’s orders again if they were closed manually
PaymentOption: int
User selected option to be charged for the following of the Leader: MonthlySubscription=0, TradedOrderFee=1, TradedVolumeFee=2
StartDateUtc: str
(optional) This setting allows Follower to copy Leader’s trades starting from a specific date and time (format: ‘0001-01-01T00:00:00Z’)
ExpireDateUtc: str
(optional) This setting allows Follower to stop copying Leader’s trades after a specific date and time (format: ‘0001-01-01T00:00:00Z’)
Magic: long
(readonly) system defined magic number attached to all copied trades
CutLossPercentage: float
User defined loss percentage (100 * (balance + credits - equity) / (balance + credits)) threshold the system should close existing copied positions and stop copy trades
CutLossAmount: float
User defined loss (balance + credits - equity) threshold the system should close existing copied positions and stop copy trades
CutLossEquity: float
User defined equity threshold the system should close existing copied positions and stop copy trades
ReducedPeriodAction: int
User defined action the system should take in case of StartDate/ExpireDate period reduction: CloseOrders=0, KeepOrders=1
RemovedRuleAction: 1
User defined action the system should take when particular copy rule is removed: CloseOrders=0, KeepOrders=1
MinMarginLevel: int
Minimum margin level (%) follower allows us to trade.
MinLotFractionToTrade: float
Minimal fraction of a MinLot follower allows us to trade.
CopyRules: list of SymbolCopyRule
User defined list of rules for the currency pairs a follower is interested to copy.
CurrentOrders: list of TradeCopierOrderInfo
List of currently active copy orders
class com.nj4x.node.trade_copier.follower.SymbolCopyRule(*args, **kwargs)

A class used to represent a rule by which the system should copy trades

LeaderSymbol: str
A Leader’s account instrument to copy trades from, e.g. ‘EURUSD’
FollowerSymbol: str
A Follower’s account instrument to copy trades to, e.g. ‘EURUSDm’
IsStopped: bool
A flag indicating activeness of this rule: True = rule is inactive
StopBuyTillDate: str
(optional) This setting allows Follower to suspend copying of BUY orders till a specific date/time (format: ‘0001-01-01T00:00:00Z’)
StopSellTillDate: str
(optional) This setting allows Follower to suspend copying of SELL orders till a specific date/time (format: ‘0001-01-01T00:00:00Z’)
IsStoppedByLeader: bool
System-defined flag which indicates inactivity of this copy rule due to a Leader’s configuration
SymbolCopyRuleMode: SymbolCopyRuleMode
Action mode for this copy trading rule
IsAdjustByLeverageRatio: bool
An indicator for the system to adjust copy volume by a follower/leader leverage ratio
MinLot: float
Minimum lot size to open trading position of
MaxLot: float
Maximum lot size to open trading position of
LeaderMinLot: float
Minimum lot size of the leader’s position (order) to copy
LeaderMaxLot: float
Maximum lot size of the leader’s position (order) to copy
Slippage: int
Order execution slippage value
HangTimeSeconds: int
Maximum number of seconds to be waited for the order execution before throwing the error
MaxOrderSendRetries: int
Maximum number of trade copy retries (in case of error)
IsReverseCopy: bool
Indicator of reverse copying, i.e. open follower’s long position (BUY) for Leader’s short position (SELL) and vice versa
class com.nj4x.node.trade_copier.follower.SymbolCopyRuleMode(*args, **kwargs)

A class used to represent a way the system calculates order’s lot size to copy

Mode: int
OneToOne=0, WithPercentageMultiplier=1, AccountToBalance=2, AccountToEquity=3, AccountToFreeMargin=4, FixedNoOfLots=5, AccountToMarginLevel=6
PercentageMultiplier: float
A percentage multiplier to be applied to the Leader’s order lot size
FixedLots: float
Lot size to be used for copied orders in case of *Mode*==5 (FixedNoOfLots)
class com.nj4x.node.trade_copier.follower.TradeCopierOrderInfo(*args, **kwargs)

A class used to represent trading order copy status

MOrderRef: long
Ticket number of the copying (Leader’s) order
MOrderInfo: TradeInfo
Detailed information of the Leader’s order
FOrderRef: long
Ticket number of the copied (Follower’s) order
FOrderInfo: TradeInfo
Detailed information of the Follower’s order
RejectReason: str
Description of a reason of the failed copy trade
IsError: bool
Indicator of the erroneous state
CanRecoverFromError: bool
Indicator of the future attempts the system will perform to recover from copy error
StartTimeUtc: str
Date/time the system has started to copy Leader’s order (format: ‘0001-01-01T00:00:00Z’)
NumTries: int
Number of tries the system has performed in order to establish copied trade
class com.nj4x.node.trade_copier.follower.TradeInfo(*args, **kwargs)

A class used to represent copied trading order

Ticket: long
Order’s ticket number.
TradeOperation: str
Orders operation type: OP_BUY (0), OP_SELL (1), OP_BUYLIMIT (2), OP_SELLLIMIT (3), OP_BUYSTOP (4), OP_SELLSTOP (5), OP_DEPOSIT (6)
OpenTime: str
Order’s open date. The server time order was opened at, e.g. ‘2018-11-09T15:57:53Z’
OpenTimeUtc: str
Order’s open date. The UTC time order was opened at, e.g. ‘2018-11-09T13:57:53Z’
CloseTime: str
Order’s close date. The server time order was closed at (format: ‘1970-01-01T00:00:00Z’)
CloseTimeUtc: str
Order’s close date. The UTC time order was closed at (format: ‘1970-01-01T00:00:00Z’)
Magic: long
User-defined magic number.
Lots: float
Amount of lots for the order.
OpenPrice: float
The price order was opened at.
ClosePrice: float
The price order was closed at.
StopLoss: float
Stop loss level.
TakeProfit: float
Take profit level.
Profit: float
Order’s net profit value (without swaps or commissions). For open positions, it is the current unrealized profit. For closed orders, it is the fixed profit.
Commission: float
Calculated commission value for the order.
Swap: float
Swap value for the order.
Symbol: str
Order’s symbol, e.g. ‘EURUSD’
Comment: str
User-defined order comments.