TICKERALL!
← All posts
August 28, 20265 min read

Copy Trading Across Your MetaTrader 5 Accounts with an API

Mirror one master MetaTrader 5 account's trades to many followers — each scaled, symbol-mapped, and risk-clamped to its own size — over a REST API. Create a set, tune the sizing and guards, arm it. TypeScript and Python examples.

MetaTrader 5Copy TradingREST APITrading

Say you run one strategy but several accounts: a demo you trust, a couple of funded/prop accounts, maybe one on a different broker. You want them to move together — when the strategy fires on the master, every other account takes the same trade, each sized to its own equity and clamped to its own risk limits.

That's Copy Trading: one master account whose fills are mirrored to a set of followers. TickerAll's copy engine is self-copy — the master and every follower are your own accounts. It is not a social/marketplace product where you follow strangers; it's a way to fan your own trading across your own roster, programmatically.

Master places a trade Copy set armed proportional ×0.5 risk 1% Follower 1 Follower 2 Follower 3
The master trades; the armed set mirrors it to each follower, scaled by that follower's own sizing rule — proportional to equity, a fixed multiplier, a risk percentage, or fixed lots.

Copy Trading is a Pro / Enterprise feature. Every /v1/copy/* call requires a Pro or Enterprise plan; on Free and Trader it returns 403 (COPY_REQUIRES_PRO). Self-copy only — the master and all followers must be your own accounts, and a follower can't also be the master.

The shape of it

A copy set is one master account plus N followers. The workflow is always the same: create the set (with followers inline or added later), tune each follower's sizing and guards, then arm it. A set is created paused — nothing mirrors until you arm it — so you can get the followers right before a single trade copies.

Install

npm install @tickerall/sdk    # TypeScript / Node 18+
pip install tickerall         # Python 3.9+

Create a set

import { Tickerall } from '@tickerall/sdk'

const client = new Tickerall({ apiKey: process.env.TICKERALL_API_KEY! })

const set = await client.copy.createSet({
  name: 'My desk',
  masterAccountId: 'acc_master',
  followers: [
    { followerAccountId: 'acc_demo',  sizingMethod: 'proportional' },              // scale by equity ratio
    { followerAccountId: 'acc_prop1', sizingMethod: 'multiplier', sizingValue: 0.5 }, // half the master's size
    { followerAccountId: 'acc_prop2', sizingMethod: 'risk_percent', sizingValue: 1 }, // risk 1% per trade
  ],
})

await client.copy.arm(set.id)   // start mirroring (pause again with client.copy.pause)
from tickerall import Tickerall

client = Tickerall(api_key="cf_live_...")

s = client.copy.create_set(
    "My desk", "acc_master",
    followers=[
        {"follower_account_id": "acc_demo",  "sizing_method": "proportional"},
        {"follower_account_id": "acc_prop1", "sizing_method": "multiplier", "sizing_value": 0.5},
        {"follower_account_id": "acc_prop2", "sizing_method": "risk_percent", "sizing_value": 1},
    ],
)

client.copy.arm(s.id)   # start mirroring (pause again with client.copy.pause)

Sizing: how a follower's volume comes from the master's

Every follower picks one sizingMethod. sizingValue means something different for each — that's the field to get right.

sizingMethod What the follower trades sizingValue
proportional (default) The master's volume scaled by the follower ÷ master equity ratio — a €5k follower behind a €50k master trades a tenth the size, automatically. not used
multiplier The master's volume × a fixed factor. the factor (e.g. 0.5 = half, 2 = double)
fixed The same fixed lot size on every copied trade, regardless of the master's. the lot size (e.g. 0.10)
risk_percent A volume sized so the trade's stop-distance risks a set percentage of follower equity. the risk % (e.g. 1 = 1%)

The computed volume is then snapped to the follower broker's lot step and clamped by minLot / maxLot.

Risk guards: what a follower will refuse to copy

Sizing decides how big; the guards decide whether to copy at all and within what limits. All are per-follower and optional.

Guard Effect
minLot / maxLot Clamp and snap the copied volume to the follower broker's lot step.
maxOpenTrades / maxExposureLots Caps — stop copying once the follower is at its open-trade or total-lots ceiling.
symbolAllow / symbolBlock Allow-list / block-list of follower symbols (string arrays).
dailyLossStop Auto-pause the follower once its loss for the day crosses this.
reverse Inverse copy — the follower sells when the master buys.
maxSlippagePips Skip the copy if the follower's price has moved too far from the master's fill.
minMasterLot Ignore the master's tiny trades below this size.
copyDelayMs Delay each copy by this many milliseconds.
symbolOverrides A { "MASTERSYMBOL": "followerSymbol" } map for cross-broker names the auto-normalizer can't resolve on its own.

symbolOverrides is the one that saves cross-broker desks. The engine normalizes common naming differences automatically (BTCUSDBTCUSDm), but if a master symbol has no obvious follower equivalent, map it explicitly:

await client.copy.addFollower(set.id, {
  followerAccountId: 'acc_xm',
  sizingMethod: 'multiplier',
  sizingValue: 1,
  symbolOverrides: { 'BTCUSDm': 'BTCUSD', 'XAUUSDm': 'GOLD' },
  maxSlippagePips: 3,
})

Tune followers after the fact

Add, update, or remove followers on a live set — a PATCH changes only the fields you pass.

await client.copy.addFollower(set.id, { followerAccountId: 'acc_prop3', reverse: true, maxSlippagePips: 3 })
await client.copy.updateFollower(set.id, 'follower_id', { maxLot: 1, symbolBlock: ['XAUUSD'] })
await client.copy.removeFollower(set.id, 'follower_id')
client.copy.add_follower(s.id, "acc_prop3", config={"reverse": True, "max_slippage_pips": 3})
client.copy.update_follower(s.id, "follower_id", {"max_lot": 1, "symbol_block": ["XAUUSD"]})
client.copy.remove_follower(s.id, "follower_id")

Arm, pause, and watch it work

arm and pause flip the whole set on and off. Pausing stops new mirroring; existing follower positions are left exactly as they are.

await client.copy.arm(set.id)     // mirror from now on
await client.copy.pause(set.id)   // stop mirroring; leave open positions alone

Two read endpoints tell you how it's going. Stats is the dashboard rollup; the log is the per-action audit trail.

const stats = await client.copy.getStats(set.id)
console.log(stats.totals)   // { ok, skipped, failed, replicationRate }
for (const f of stats.followers) {
  console.log(f.followerAccountId, 'ok', f.ok, 'skipped', f.skipped, 'open', f.openPositions)
}

// Every mirrored action, newest first; page with `before` + `limit` (max 200)
const page = await client.copy.getLog(set.id, { limit: 50 })
for (const e of page.entries) {
  console.log(e.action, e.followerAccountId, e.result, e.reason ?? '')
}
// page.nextBefore -> pass as `before` for the next page, or null at the end
stats = client.copy.get_stats(s.id)
print(stats.totals.ok, stats.totals.skipped, stats.totals.failed, stats.totals.replication_rate)

page = client.copy.get_log(s.id, limit=50)
for e in page.entries:
    print(e.action, e.follower_account_id, e.result, e.reason or "")
# page.next_before -> pass as `before` for the next page, or None at the end

A log entry with result: 'skipped' and a reason is exactly how you learn a guard did its job — a copy skipped for maxSlippagePips, symbolBlock, or maxOpenTrades shows up here, not as a silent no-op.

Optional: get pushed every outcome

If you'd rather be told than poll, attach a webhook when you create or update the set. Every mirror outcome then POSTs to your webhookUrl with an HMAC-SHA256 signature in the X-Tickerall-Signature header, keyed by your webhookSecret (16+ characters, write-only — it's never returned).

await client.copy.updateSet(set.id, {
  webhookUrl: 'https://your-app.example.com/hooks/copy',
  webhookSecret: process.env.COPY_WEBHOOK_SECRET!,
})

Validate on demo followers first

Sizing math is the part worth proving before real money is on the follower side. Point the master at your strategy and make the followers demo accounts to start: place a trade, then read getStats / getLog and confirm each follower took the size you expected — proportional scaling landed where you thought, the multiplier and risk-percent followers came out right, and the guards skipped what they should. Once the numbers match your intent, swap in the real followers.

Where to go next

Copy Trading is "mirror whatever the master does." If instead you want to push the same explicit action to many accounts at once — place, close, or read across a roster in one call — that's the Bulk API. New to the SDK? The TypeScript quickstart covers a single account end to end.

Full API reference: tickerall.com/docs

Was this useful?

Comments

Leave a comment

Comments are public.
Copy Trading Across Your MetaTrader 5 Accounts with an API · Ticker All!