FX
FXSOCKET
  • Features
  • How it Works
  • Use Cases
  • Pricing
  • Blog
Sign InGet API Key
Use Case

Copy Trading API for MT4 & MT5

Build your own trade copier with FxSocket. Detect new trades on a master account through WebSocket streams and replicate them to any number of follower accounts via the REST API — all in real time, all from your own code.

Why Build a Trade Copier with FxSocket

  • Real-time trade detection. WebSocket streams push order updates the moment they happen on the master account. No polling delays.
  • Instant replication. Place mirrored orders on follower accounts through the REST API. Sub-30ms execution keeps slippage minimal.
  • Multi-account management. Connect dozens or hundreds of accounts under one integration. Switch between them with a single parameter.
  • Full control over copy logic. Adjust lot sizing, filter symbols, add risk rules, or transform orders before copying. Your code, your rules.
  • Cross-broker support. Master and followers can be on different brokers. As long as each account has MT4 or MT5 credentials, it works.
  • No MQL, no VPS. Traditional copy trading setups require Expert Advisors running on dedicated VPS instances. FxSocket replaces all of that with a simple API you can call from anywhere — a cloud function, a Docker container, or your laptop.
  • Official SDKs. Use the official FxSocket SDK for Python, JavaScript/Node.js, Go, or Rust to get started in minutes instead of hours.

How It Works

Connect the master account and all follower accounts to FxSocket. Subscribe to the master account's WebSocket stream. When a new trade opens, your service receives the event, applies any custom logic (lot scaling, symbol filtering, risk checks), and fires a POST request to each follower account to replicate the trade.

When the master closes or modifies a position, you receive that event too. Your copier can then close or adjust the corresponding positions on every follower account. The entire loop — detection, transformation, execution — typically completes in under 50ms end-to-end.

Example: Listen for Master Trades

The following Python example connects to a master account's WebSocket stream, listens for new orders, and replicates them to two follower accounts at half the lot size:

import websocket
import json
import requests

API_KEY = "your_api_key"
BASE = "https://api.fxsocket.com/v1"
MASTER_ID = "acc_master"
FOLLOWERS = ["acc_follower_1", "acc_follower_2"]

def on_message(ws, message):
    event = json.loads(message)
    if event["type"] == "order_opened":
        order = event["data"]
        for follower in FOLLOWERS:
            requests.post(
                f"{BASE}/orders",
                headers={"Authorization": f"Bearer {API_KEY}"},
                json={
                    "account_id": follower,
                    "symbol": order["symbol"],
                    "type": order["type"],
                    "volume": order["volume"] * 0.5,
                }
            )

ws = websocket.WebSocketApp(
    f"wss://ws.fxsocket.com/v1/stream?account={MASTER_ID}",
    on_message=on_message,
    header={"Authorization": f"Bearer {API_KEY}"}
)
ws.run_forever()

Production-Ready Example with Error Handling

The basic example above works for prototyping, but a production copier needs reconnection logic, error handling, lot size validation, and follower account health checks. Here is an expanded version that handles all of these:

import websocket
import json
import requests
import time
import threading

API_KEY = "your_api_key"
BASE = "https://api.fxsocket.com/v1"
MASTER_ID = "acc_master"

# Follower config: account ID -> lot multiplier
FOLLOWERS = {
    "acc_follower_1": 0.5,
    "acc_follower_2": 1.0,
    "acc_follower_3": 2.0,
}

# Symbol mapping for cross-broker support
SYMBOL_MAP = {
    "acc_follower_2": {"EURUSD": "EURUSDm", "GBPUSD": "GBPUSDm"},
}

HEADERS = {"Authorization": f"Bearer {API_KEY}"}
processed_orders = set()  # Idempotency tracking


def check_follower_status(account_id):
    """Verify follower account is connected and tradeable."""
    try:
        resp = requests.get(
            f"{BASE}/accounts/{account_id}",
            headers=HEADERS, timeout=5
        )
        data = resp.json()
        return data.get("status") == "connected"
    except Exception as e:
        print(f"[WARN] Cannot reach follower {account_id}: {e}")
        return False


def map_symbol(account_id, symbol):
    """Map symbol names for cross-broker compatibility."""
    mapping = SYMBOL_MAP.get(account_id, {})
    return mapping.get(symbol, symbol)


def copy_to_follower(account_id, multiplier, order):
    """Copy a single order to a follower with error handling."""
    symbol = map_symbol(account_id, order["symbol"])
    volume = round(order["volume"] * multiplier, 2)
    volume = max(volume, 0.01)  # Enforce minimum lot size

    if not check_follower_status(account_id):
        print(f"[SKIP] {account_id} is disconnected")
        return

    try:
        resp = requests.post(
            f"{BASE}/orders",
            headers=HEADERS,
            json={
                "account_id": account_id,
                "symbol": symbol,
                "type": order["type"],
                "volume": volume,
            },
            timeout=10,
        )
        if resp.status_code == 201:
            print(f"[OK] Copied to {account_id}: {symbol} {volume} lots")
        else:
            error = resp.json()
            print(f"[ERR] {account_id}: {error.get('message', resp.text)}")
    except requests.exceptions.Timeout:
        print(f"[ERR] Timeout copying to {account_id}")
    except Exception as e:
        print(f"[ERR] {account_id}: {e}")


def on_message(ws, message):
    event = json.loads(message)
    if event["type"] == "order_opened":
        order = event["data"]
        order_id = order["ticket"]

        # Idempotency: skip if already processed
        if order_id in processed_orders:
            return
        processed_orders.add(order_id)

        # Fan out to all followers in parallel
        threads = []
        for acct, mult in FOLLOWERS.items():
            t = threading.Thread(
                target=copy_to_follower,
                args=(acct, mult, order)
            )
            t.start()
            threads.append(t)
        for t in threads:
            t.join(timeout=15)


def on_error(ws, error):
    print(f"[WS ERROR] {error}")


def on_close(ws, code, reason):
    print(f"[WS CLOSED] {code} - {reason}, reconnecting...")


def connect():
    while True:
        try:
            ws = websocket.WebSocketApp(
                f"wss://ws.fxsocket.com/v1/stream?account={MASTER_ID}",
                on_message=on_message,
                on_error=on_error,
                on_close=on_close,
                header={"Authorization": f"Bearer {API_KEY}"},
            )
            ws.run_forever(ping_interval=30, ping_timeout=10)
        except Exception as e:
            print(f"[RECONNECT] Connection lost: {e}")
        time.sleep(3)  # Wait before reconnecting


if __name__ == "__main__":
    connect()

SDK Comparison: WebSocket Subscription

FxSocket provides official SDKs for Python, JavaScript/Node.js, Go, and Rust. Here is how you subscribe to a master account's trade stream in each language:

Python

from fxsocket import FxSocketClient

client = FxSocketClient(api_key="your_api_key")

def on_trade(event):
    print(f"New trade: {event.data.symbol} {event.data.volume} lots")

client.subscribe("acc_master", on_event=on_trade)
client.connect()  # Blocks, auto-reconnects on disconnect

JavaScript / Node.js

import { FxSocketClient } from "fxsocket";

const client = new FxSocketClient({ apiKey: "your_api_key" });

client.subscribe("acc_master", (event) => {
  console.log(`New trade: ${event.data.symbol} ${event.data.volume} lots`);
});

await client.connect(); // Auto-reconnects on disconnect

Go

package main

import (
    "fmt"
    "github.com/fxsocket/fxsocket-go"
)

func main() {
    client := fxsocket.NewClient("your_api_key")

    client.Subscribe("acc_master", func(event fxsocket.Event) {
        fmt.Printf("New trade: %s %.2f lots\n",
            event.Data.Symbol, event.Data.Volume)
    })

    client.Connect() // Blocks, auto-reconnects on disconnect
}

Scale from 2 Accounts to 200

Whether you're copying trades between your own accounts or building a copy trading platform for clients, FxSocket handles the infrastructure. No VPS to manage, no MetaTrader terminals to install, no MQL scripts to maintain.

Architecture Patterns for Copy Trading

As your copy trading system grows from a handful of followers to hundreds, the architecture needs to evolve. Here are proven patterns for building reliable, scalable copiers with FxSocket.

Fan-Out Pattern

The simplest approach: one WebSocket listener fans out each trade event to all followers in parallel. This works well for up to roughly 50 follower accounts. The production example above uses this pattern with threading. For higher concurrency, use Python's asyncioor Node.js's native async model to fire all REST calls simultaneously.

Queue-Based Copying

For 50+ followers, introduce a message queue (Redis, RabbitMQ, or SQS) between the WebSocket listener and the copy workers. The listener publishes each trade event to the queue, and multiple worker processes consume from it. This decouples detection from execution, prevents backpressure on the WebSocket connection, and lets you scale workers horizontally.

Idempotency and Duplicate Handling

Network issues can cause your WebSocket to reconnect mid-event, delivering the same trade event twice. Always track processed order tickets (using a set in memory, or a database for persistence) and skip duplicates. The production example above demonstrates this with the processed_orders set. For distributed systems, use a shared cache like Redis to coordinate idempotency across multiple worker instances.

Graceful Close Handling

When the master closes a position, your copier should close the corresponding position on every follower. Store a mapping of master ticket numbers to follower ticket numbers so that when an order_closed event arrives, you know exactly which follower orders to close. This prevents orphaned positions that remain open on followers after the master has exited.

Cross-Broker Symbol Mapping

One of the trickiest parts of cross-broker copy trading is symbol name differences. The same currency pair can have different names depending on the broker:

  • EURUSD on Broker A might be EURUSDm or EURUSD.raw on Broker B
  • XAUUSD (gold) is sometimes listed as GOLD, GOLDm, or XAUUSDx
  • Indices like US30 can appear as DJ30, US30.cash, or WS30

Build a symbol mapping table per follower account. You can either hardcode the mappings in a configuration file or fetch the available symbols from each account via the FxSocket API and perform fuzzy matching. The production example above includes a simple SYMBOL_MAP dictionary for this purpose.

Handling Different Lot Size Minimums

Brokers differ on minimum lot sizes: some allow 0.01, others require 0.1, and a few use 1.0 as the minimum. When scaling lot sizes from master to follower, always clamp the result to the follower broker's minimum lot size. If the scaled volume falls below the minimum, you have two choices: skip the trade entirely or round up to the minimum. For accounts with per-account multipliers below 1x, rounding up can significantly increase relative risk, so skipping is usually the safer default.

Different Trading Hours Across Brokers

Brokers in different regions may have different trading sessions or roll-over times for certain instruments. A trade that opens at 23:59 server time on the master broker might fail on a follower broker where the market has already closed. Handle this by checking the follower account's trading hours for the target symbol before placing the order, and queueing the trade for execution when the market reopens if needed.

Common Copy Trading Setups

  • Signal provider mirroring trades to subscribers
  • Prop firm master account copying to funded traders
  • Personal strategy running on demo, auto-copying to live
  • Multi-broker arbitrage and cross-account hedging

Troubleshooting Common Errors

Copy trading across multiple accounts introduces failure modes you won't encounter with single-account trading. Here are the most common issues and how to handle them.

Order Rejection: Insufficient Margin

The most frequent copy failure. The master account has enough margin for a trade, but one or more followers don't. The API will return a margin error. Best practice: before copying, query the follower account's free margin via GET /v1/accounts/{id} and compare it against the required margin for the order. If the margin is insufficient, either reduce the lot size or skip the trade and log a warning. Never retry margin rejections without reducing size — the result will be the same.

Order Rejection: Symbol Not Available

If the follower broker doesn't offer a symbol, the order will be rejected. This is especially common with exotic pairs, indices, or commodities. Use your symbol mapping table to translate names, and maintain a per-account whitelist of available instruments. When a symbol is not available, log the skip and alert the account owner.

Partial Fills

In rare cases — particularly with large lot sizes or illiquid instruments — an order may be partially filled. The API response includes the actual filled volume. Compare it to the requested volume and decide whether to submit a follow-up order for the remaining amount or accept the partial fill. For copy trading, most operators accept partial fills and record the difference.

Latency Between Master and Follower Execution

Even with sub-30ms API execution, real-world latency includes your network round-trip time plus any processing in your copy logic. For most setups, total end-to-end latency is 30–80ms. To minimize it: deploy your copier service in a region close to FxSocket's API servers, use persistent HTTP connections (connection pooling), and minimize processing between receiving the WebSocket event and sending the REST request. Avoid synchronous operations like database writes in the critical path — log asynchronously instead.

WebSocket Disconnections

Internet hiccups happen. Your WebSocket connection will occasionally drop. Always implement automatic reconnection with exponential backoff. After reconnecting, query the master account's open orders via the REST API to detect any trades you may have missed during the disconnection window. Compare against your followers' open positions and reconcile any gaps.

Frequently Asked Questions

What happens if a follower account has insufficient margin?

The API returns a clear error indicating insufficient margin. Your copier should catch this and decide how to proceed — reduce lot size, skip the trade, or alert the user. The master trade is not affected; only the follower order is rejected. We recommend pre-checking free margin before placing copy orders so you can proactively adjust lot sizes.

Can I copy trades across different brokers?

Yes. FxSocket works with any MT4 or MT5 broker. The master and every follower can each be on a different broker. The only requirement is that each account is connected to FxSocket with valid broker credentials. You'll need to handle symbol name mapping and lot size differences between brokers, but the API itself is broker-agnostic.

How do I handle lot size differences between master and followers?

Use a per-follower multiplier. For example, if the master opens 1.0 lots and a follower has a 0.5x multiplier, you copy at 0.5 lots. Always round to the follower broker's allowed precision (usually 0.01) and clamp to their minimum lot size. Account for the follower's balance and leverage — a 0.5x multiplier based on lot size alone doesn't account for different leverage or account balances.

What about slippage between master and followers?

With FxSocket's sub-30ms execution and real-time WebSocket delivery, slippage between master and follower is typically under 1 pip for major pairs during liquid market hours. During news events or low-liquidity periods, slippage may increase. To protect against extreme slippage, you can set a maximum allowed price deviation in your copy logic and reject copies where the current price has moved too far from the master's fill price.

How many follower accounts can I copy to simultaneously?

There is no hard limit. FxSocket customers routinely copy to 100+ accounts from a single master. For very large fan-outs (200+ accounts), we recommend the queue-based architecture pattern described above, which lets you scale worker processes horizontally. At €11/account/month on the Starter plan, the cost scales linearly and predictably.

Start BuildingView API Docs
FX
FXSOCKET

Cloud-hosted MT4 & MT5 terminals with REST APIs and real-time WebSocket streams. No VPS required.

Product
  • Features
  • Pricing
  • Documentation
  • Status
Use Cases
  • Algo Trading
  • Copy Trading
  • Backtesting
  • Prop Firms
Company
  • Contact
  • Terms
  • Privacy
  • info@fxsocket.com
Connect
  • Telegram
  • WhatsApp

© 2026 Quantum Performance Labs LLC. All rights reserved.