Skip to main content
Package: monaco.api.copy_trading Source: protos/api/copy_trading.proto Use CopyTradingService to register as a lead trader, browse and follow lead traders, and manage your follows. A follow allocates collateral to a copy account (a cross risk bucket inside your margin account) and mirrors the leader’s fills into it as market orders under your own account.

Notes

  • ListLeadTraders, GetLeadTrader and ListLeadTraderClosedTrades are public (no auth). Every other RPC requires authentication and is scoped to the session’s account.
  • A leader is addressed by their custom TraderCode handle. The sequencer allows one lead profile per wallet (a second application’s registration from the same wallet is refused with INVALID_ARGUMENT), so a handle names one leader; a leader without a custom handle is not publicly addressable and is not listed. Users appear by wallet address and a display string (the custom handle when claimed), never an internal id. GetLeadTrader returns NOT_FOUND for a suspended leader.
  • UpsertLeadTrader registers you or edits your profile. A registration must meet the platform’s eligibility rules (account equity, trading history, closed positions, and a claimed custom TraderCode handle); a refused registration returns INVALID_ARGUMENT naming the rule. The profile is replaced as sent: an omitted bio or min_allocation clears it, an omitted status means ACTIVE, and an omitted share_bps keeps your current share. Each call spends the per-account settings-write rate limit UpsertFollow shares (about one write per second, burst 10; RESOURCE_EXHAUSTED past it).
  • UpsertFollow without follow_id creates a follow; with it, edits one of your follows. An edit takes the leader from the follow, so it keeps working after the leader releases their handle (leader may be empty; a handle naming a different leader is refused). copy_existing on a create also copies the leader’s open positions into the new copy account; it applies only to a create (INVALID_ARGUMENT on an edit), and the follow keeps recording whether it copied at creation. A create and an edit each spend the per-account settings-write rate limit UpsertLeadTrader and the self-trade-prevention default share (about one write per second, burst 10; RESOURCE_EXHAUSTED past it).
  • PreviewFollow shows what a follow with those terms would open if it set copy_existing, as totals only: estimated_margin (what the copies would reserve at placement) and estimated_fee, both rounded up to cents, plus copied_positions, skipped_positions and truncated. It names no market, side or reason: the caller does not follow the leader yet. It is read-only and has the same session and terms rules as UpsertFollow: PERMISSION_DENIED for delegated agent and sub-account sessions, NOT_FOUND for an unknown or suspended leader, INVALID_ARGUMENT for terms a follow would refuse, and FAILED_PRECONDITION while copy trading is off. It spends the order-risk preview budget and the engine’s preview lane share. At most 64 positions are sized; truncated is set when more matched.
  • StopFollow stops one of your own follows. It is an exit and is never refused for the state of the account or the platform: a banned or sub-account session can still stop its own follow, and it stays available during an operations block, when registrations and follows do not. Only three things apply: ownership, the refusal of a delegated agent session, and a per-account rate limit of its own (about one stop per second, burst 20; RESOURCE_EXHAUSTED past it), which closes and follow edits never spend.
  • CloseFollowPositions closes every position in one of your follows’ copy accounts at market (reduce-only, immediate-or-cancel) and cancels the resting orders and conditional orders (TP/SL) on its copy risk buckets (a TWAP cannot run there), keeping the follow: the leader’s next trades keep mirroring. CloseAllCopyPositions does it for every live follow of yours, one batch per follow. Not a flatten guarantee: a thin or halted market can leave part of a position open (positions_not_closed), and the leader’s next trade opens copies again. Both are exits with StopFollow’s rules: never gated by copy trading being off or an operations block, no order budget, and only a delegated agent session is refused (PERMISSION_DENIED). Both share a per-account rate limit (about one close per second, burst 5; RESOURCE_EXHAUSTED past it). Proceeds stay in the copy account. A follow that is not yours is NOT_FOUND; a stopped follow or one whose stop is in progress is ALREADY_EXISTS (HTTP 409, the gateway’s conflict code; CloseAllCopyPositions lists stopping follows in stopping_follow_ids). A refused close is INVALID_ARGUMENT and one that cannot run right now UNAVAILABLE; CloseAllCopyPositions lists such a follow in failed_follows with a fixed reason and closes the others. The response comes once the batch is durably logged (close orders placed, positions still open); fills arrive on the order, position and copy streams.
  • AddFollowPositionMargin adds margin to one of your copy positions. AddFollowPositionMarginRequest carries follow_id (the follow’s UUID), trading_pair_id (the copy position’s trading pair UUID) and amount (margin to add in quote units, a positive decimal string). It moves amount from the follow’s copy account into the margin of its isolated copy position on that pair: the position’s initial margin requirement rises by exactly amount at the current mark (its leverage drops to what that amount buys at this price), the copy account’s remaining collateral falls by the same, and your margin account is never touched. It lowers the position’s leverage and moves its liquidation price away; it opens no exposure, so it works while copy trading is switched off and on a CLOSE_ONLY follow. AddFollowPositionMarginResponse returns follow_id, trading_pair_id, risk_bucket_id (the copy position’s isolated risk bucket), position_id, position_margin (the position’s stored margin after the add, in entry-price terms: it rises by amount × entry price ÷ mark) and copy_account_available (what the copy account can still put into this position after the add). There is no margin reduction: a follow exits by being stopped. PERMISSION_DENIED for delegated agent and sub-account sessions; NOT_FOUND unless the follow is yours; ALREADY_EXISTS (the REST 409) while the follow is stopping or once it is stopped; INVALID_ARGUMENT with code COPY_TRADING_REJECTED in its google.rpc.ErrorInfo detail when the add is refused (no isolated copy position on the pair, the copy position is being liquidated or is in bad debt, or more than the copy account can put in); switching copy trading off does not block an add, which opens no exposure; UNAVAILABLE when the matching engine is unavailable, and during an operations block (a margin move, unlike StopFollow); RESOURCE_EXHAUSTED over the per-user movement budget withdrawals and collateral transfers share. It is not idempotent: after a timeout, read the follow before retrying, or the amount may be added twice.
  • ListLeadTraderOpenPositions is visible only to the leader’s current followers (a live follow in the session’s application); anyone else gets PERMISSION_DENIED. It is addressed by handle, so once a leader releases their handle it answers NOT_FOUND even for current followers, who still see the follow through ListMyFollows and GetFollow, and the leader’s positions through ListFollowLeaderPositions.
  • ListFollowLeaderPositions lists the open positions of the leader one of your follows copies, taking the leader from the follow. NOT_FOUND unless the follow is yours; PERMISSION_DENIED unless it is live (ACTIVE or CLOSE_ONLY).
  • GetFollowResponse.copy_account_equity is the copy account’s equity at the engine’s marks: its collateral plus the unrealized PnL of its positions. It is a balance, not trading PnL, and it is absent when the engine cannot be read.
  • Delegated agent sessions and sub-account sessions cannot register or follow (PERMISSION_DENIED); a delegated agent session cannot stop a follow either. A follow or profile that is not yours returns NOT_FOUND.
  • When copy trading is switched off, registrations and new follows return FAILED_PRECONDITION.
  • Stats (LeadTraderStats) come from the leader’s account PnL rollups over 7d, 30d, 90d and all-time. pnl is trading PnL (realized plus unrealized, net of fees and funding). roi_pct divides it by the highest base balance over the window (starting equity plus net deposits), so a withdrawal cannot inflate it; it is absent when that base is not positive. max_drawdown_pct is the largest peak-to-trough fall of cumulative PnL over the same base, sampled at the window’s rollup interval (1h for 7d, 4h for 30d and 90d, 1d for all-time). win_rate_pct counts winning over winning plus losing closes. A risk bucket’s cash balance never feeds these figures.
  • LeadTraderFollowSummary.allocated is the collateral allocated by live follows (AUM as allocated, not marked to market). aum_equity is the same AUM marked: the summed equity of the live follows’ copy accounts at the engine’s marks, absent when it could not be read. sort=aum ranks by it, with leaders lacking it last.
  • ListLeadTraders serves a leaderboard snapshot refreshed about once a minute (as_of); it lists ACTIVE leaders only, sorted highest first by sort, with leaders lacking a value for the metric last.
  • Lists use cursor pagination: omit page_token for the first page, then send each response’s next_page_token until it is empty. A token only works with the filters and sort that produced it (INVALID_ARGUMENT otherwise). There are no totals. Page size: up to 1000 on your own lists (ListMyFollows, ListMyFollowers), up to 100 on the public lists.