Taking copy trading offline, and offboarding a leader with a book

The five switches and three destructive actions that each stop a different part of copy trading, which of them leave follower money sitting in the COPY_TRADING wallet, and the order that finishes cleanly.

11 min readUpdated 6 August 2026shutdown, offboarding, refunds, allocations, kill-switch

Every allocation in copy trading is a real transfer. When a follower subscribes, their money leaves their ECO or SPOT wallet and sits in a COPY_TRADING wallet, which has no withdrawal path and no transfer path out other than the ones this addon provides. Turning something off does not move it back.

So the question to hold in your head through this whole page is not "did copying stop" — several switches will do that in seconds. It is "whose money is still in COPY_TRADING, and what will take it out again."

Disabling copy trading, enabling maintenance mode, turning off spot or binary copying, and disabling the Ecosystem extension all stop activity. Not one of them cancels an open copy, releases a wallet hold, deactivates an allocation or moves a balance.

Only three actions move money: a follower's own stop, an admin leader delete with refunds, and the ordinary settlement of a position. Read the whole page before you flip anything on a live install.

The five switches, and exactly what each one stops

All five are decisions you make and then live with; four are on /admin/copy-trading/settings and the fifth is the Ecosystem extension itself.

copyTradingEnabled — the master switch

Master switch. An unset key reads as ON

Off, it does three things: every user-facing eligibility check refuses with "Copy trading is currently disabled", and the replication backstop (processPendingCopyTrades) skips its entire run — including the binary backstop nested inside it, which is checked after the master gate.

It does not cancel open copies, does not release holds, and does not return capital.

The live spot path (the order hook that fires the moment a leader places an order) checks copyTradingEnableSpot, not copyTradingEnabled. The live binary path checks copyTradingEnableBinary. Neither consults the master switch.

So with copyTradingEnabled off, a leader placing an order still has it copied onto their followers' accounts in real time. What stops is new applications, new subscriptions, and the database-driven backstop that catches copies the live path dropped.

If your intent is "stop money moving", the master switch is not the control. The two class switches below are.

copyTradingMaintenanceMode — pause the front door

Blocks applications, follows and every eligibility check

The gentlest of the five. It refuses with "Copy trading is currently under maintenance" on the same checks the master switch refuses on, and leaves existing subscriptions, open positions, the backstop and live replication completely alone.

Use it for a maintenance window on the surrounding platform. It is not a wind-down step on its own.

copyTradingEnableSpot and copyTradingEnableBinary — the real kill switches

Allows spot copying. Checked on new applications, new allocations, the backstop and every live replication
Allows binary copying. Additionally requires platform-wide binary trading to be enabled

These are the two that actually stop replication, because they are checked on the live path as well as on setup. Turn spot off and the next leader order is not copied to anybody.

The backstop checks the spot switch once per run, before it selects any rows. With spot off it logs "Spot copy trading is disabled, skipping" and stops — the pending leader trades stay PENDING, untouched, with no attempt counted against them. That is deliberate: turning the switch back on resumes from where you were rather than burning through a backlog and parking it as REPLICATION_FAILED.

Binary is gated twice on purpose. If platform-wide binary trading is off, the binary engine would reject a copied order anyway, so the copy layer refuses up front with a message naming the real reason.

Neither switch touches a position that is already open, and neither returns capital.

Disabling the Ecosystem extension

Turning ecosystem off at /admin/system/extension makes spot copying fail closed. Every spot path re-checks that the extension is enabled — not merely that its files resolve — before it writes anything, so replication, reconciliation and stop-loss monitoring all log "Ecosystem extension not available" and skip. No copy-trade rows are written for orders that were never placed.

Every follower's allocation is still sitting funded in their COPY_TRADING wallet, every open spot copy is still open, and the reconciler that would normally tear down a stale copy is itself disabled — so drift accumulates instead of being cleaned up.

Worse, the follower's own stop route needs the ecosystem wallet service to move the money back, so your customers cannot self-serve their way out while it is off.

Binary copying is unaffected and keeps running. A binary-only deployment can run with Ecosystem disabled indefinitely; a spot deployment cannot.

The three destructive actions

Suspending a leader

Suspend an active leader. Reason required

Sets the leader to SUSPENDED and pauses every follower behind them in one statement. Refuses if the leader is not currently ACTIVE. The reason is mandatory and is carried into the notification the leader reads.

Money is untouched — every allocation stays funded in COPY_TRADING, and it moves to the dashboard's Stranded band immediately, because the leader can no longer trade.

resetCopyTradingDailyLimits deliberately skips any follower whose leader is not ACTIVE, and even for an active leader it only lifts a pause whose latest audit action is DAILY_LOSS_LIMIT_REACHED from a previous UTC day. A pause caused by a suspension is logged against the leader, not the follower, so no automatic path will ever lift it.

Reactivating the leader restores their ability to trade and leaves every one of their followers paused, indefinitely, with money committed. Each subscription has to be resumed — by the follower, or by you at /admin/copy-trading/follower.

Before suspending a leader with a large book, decide how you will unwind it.

Deleting a leader — the only bulk refund path

Delete a leader. refundFollowers defaults to true

This is the action that returns money, and it is the backbone of a planned wind-down.

It first refuses if that leader has any trade — their own or a follower copy — in OPEN, PENDING or PARTIALLY_FILLED, with a message naming the count. Positions must be closed first.

With refundFollowers true (the default), for every non-STOPPED follower and every active allocation it:

  • computes the unused portion — baseAmount − baseUsedAmount and quoteAmount − quoteUsedAmount;
  • moves it back to the wallet it came from: COPY_TRADING → ECO for a spot allocation, COPY_TRADING → SPOT for a binary stake budget;
  • writes a REFUND transaction row per leg with ADMIN_LEADER_DELETED in its metadata;
  • deactivates the allocation and writes down its recorded amounts to the used portion;
  • sets the subscription to STOPPED.

Then it sets the leader INACTIVE and soft-deletes them. The whole thing runs in one database transaction, and each transfer carries a stable idempotency key, so repeating the deletion cannot refund a second time.

With refundFollowers false, subscriptions are stopped and nothing is refunded — every allocation stays funded in COPY_TRADING, unreachable by the customer. There is no supported reason to do this on a live install.

Deleting sends no notification. Tell the followers yourself.

Force-stopping one subscription

Administratively stop one subscription

The Stop button on /admin/copy-trading/follower and on the subscription detail page. It takes a reason, locks the row, refuses if the subscription is already STOPPED, sets it to STOPPED, and writes an ADMIN_FORCE_STOP audit row.

It is not the same teardown the follower's own stop runs. It cancels no orders, releases no wallet holds, deactivates no allocation and transfers nothing. The code says so explicitly: "funds remain in individual allocations".

A subscription stopped this way is exactly the case the dashboard's Stranded band was built to surface — "held against a follower who stopped and whose allocation was never released". It also sends the follower no notification, because the FORCE_STOPPED event has no call site.

Use it to stop copying now, during an investigation. It is a containment action, not a closure. The money still has to come out via a leader delete with refunds, or by the follower stopping the subscription themselves.

For comparison, the follower's own stop at POST /api/copy-trading/follower/{id}/stop does the full teardown: it cancels live copy orders and releases their COPY_TRADING holds, then refuses outright if any position has actually filled — telling the customer which symbols and suggesting they pause instead — and only then transfers every allocation's unused balance back to ECO or SPOT, writes DEALLOCATION rows, deactivates the allocations and sets the subscription STOPPED.

That refusal is deliberate: a filled position is coins in a wallet, not an order, and nothing in a single request can unwind it. It is also why the customer path is the one that returns money cleanly, and the admin path is not.

Pausing, for completeness

Administratively pause. Funds and allocations untouched

Only works on an ACTIVE subscription, notifies the follower, and writes an ADMIN_PAUSE audit row. Use it while you are still working out what happened — pausing leaves the money where it is, which is what you want mid-investigation.

Note that the list screen offers Resume and Stop but no Pause button; the pause endpoint exists and is reachable from the API and the detail page.

A wind-down that finishes

The order matters, because the delete step is blocked by open positions and the positions only close while copying is still functioning.

  1. Announce it. Every follower is about to have money returned to a wallet they did not choose, and every leader is about to lose their book. Nothing in this sequence notifies them except the leader-suspension mail.

  2. Stop replication — set copyTradingEnableSpot and copyTradingEnableBinary to off on /admin/copy-trading/settings → Trading. These are the switches the live path actually reads. No new copy is placed from this moment.

  3. Close the front door — set copyTradingMaintenanceMode on, or copyTradingEnabled off. Either refuses new applications and new subscriptions. Do this second, not first, so you are not fielding "I can't subscribe" while copies are still firing.

  4. Drain the open positions. Filter /admin/copy-trading/trade for OPEN, PARTIALLY_FILLED, CLOSING, PENDING and PENDING_REPLICATION. Leave processClosedCopyTrades, reconcileCopyTradingOrders and monitorCopyTradingStopLevels running — they are what settles and cleans up. Anything stuck in REPLICATION_FAILED needs a human before you proceed.

  5. Delete each leader with refundFollowers true. This is the step that returns the money. It will refuse while any of that leader's trades are still open, which is why step 4 comes first. Use the bulk status endpoint to move a large set to INACTIVE first if you want them off the leaderboard immediately — but understand that a bulk status change refunds nothing.

  6. Sweep the remainder. Any subscription still holding capital behind a leader you have already deleted shows in the Stranded band. Those are follower-side stops that never released; the customer has to run their own stop, or you delete the leader they sat behind if you have not already.

  7. Prove it. See below.

How to prove it finished

A falling total is not proof. The dashboard at /admin/copy-trading splits allocated capital into four bands computed in one server-side pass, and they sum exactly to the total beside them.

Band Must read Because
Copying 0 Nothing should still be behind an active leader with an active subscription
Paused 0 Paused money is still committed. A paused subscription is a live claim on funds sitting in COPY_TRADING
Leader dormant 0 Capital behind an ACTIVE leader who has not traded for 7 days
Stranded 0 Behind a leader who cannot trade, or held against a follower who stopped and was never released

Zero in Stranded and zero in Paused is the finish line. A total that has fallen 90% while Stranded holds the rest means the wind-down stopped halfway and somebody's money is sitting in a wallet they cannot reach.

Two further checks worth doing:

  • capital.currency in the dashboard response is null whenever the open allocations span more than one quote asset. While that is the case, the totals are a correct sum of a column and not an amount in any currency — read the bands as "is it zero", never as "how many dollars".
  • The at-risk leader table beneath the meter names a reason per leader: leader-inactive (reinstate or refund), dormant (ask the leader), or unreleased (the teardown did not finish). It is capped at eight rows and reports the true count, so read "showing 8 of 23" literally.

Rate limits and doing it at scale

Every route under /api/admin/copy-trading that changes something is limited to 50 actions per hour, per admin — approve, reject, activate, suspend, delete, recalculate, bulk status, the leader and subscription edit routes, pause, resume, force stop, and transaction reversal. Approving, suspending or deleting a backlog by hand will hit that ceiling, and the 51st action fails with "Too many admin actions. Please wait."

The read routes carry no limiter at all — the dashboard, analytics, audit, health, and the leader, subscription, trade and transaction lists and detail pages. Refreshing a screen while you work costs you nothing against the ceiling, so watch the capital bands as often as you like.

Change the status of several leaders at once. Reason required

The bulk endpoint takes leaderIds, a status of ACTIVE, SUSPENDED or INACTIVE, and a mandatory reason, and counts as one action against the limit. Its behaviour differs from the single-action routes in ways that matter:

  • SUSPENDED pauses every active follower of each leader, exactly as a single suspend does.
  • ACTIVE on a PENDING leader is refused per row with "Use approve endpoint for pending leaders" — the rest of the batch still processes.
  • A leader already at the target status is reported as skipped.
  • Reactivating from SUSPENDED leaves followers paused, same as the single route.
  • It sends no notifications at all. Not to leaders, not to followers, not to administrators. It writes BULK_<STATUS> audit rows and nothing else.

It cannot delete and cannot refund, so it is a way to clear a leaderboard quickly, not a way to return capital.

  • Admin console — reading the capital bands and the audit trail
  • Settings — every key, and the six that are never enforced
  • Notifications — who gets told what, and who does not