Sub-Accounts — Isolate Strategies per Account
- Most major exchanges support sub-accounts under one master account.
- TVH routes to a sub-account by registering a separate TVH API key per sub-account, then referencing it by name in the TradeCommand's
apiKeyfield. - There is no
subAccountJSON field that you set per-trade — the routing happens via the named API key registration. - Per sub-account: one TVH API key with a descriptive name (
binance-scalper-sub1,bybit-swing-sub2, ...).
Why sub-accounts?
- Isolate strategy P&L — see at a glance which strategy is profitable
- Test new strategies without affecting the main account's balance / margin
- Separate funds (scalping vs swing vs DCA)
- Independent risk limits — one strategy blowing up cannot liquidate another
- Different leverage / margin modes per strategy
How TVH handles sub-account routing
TVH does not support a subAccount field inside the TradeCommand JSON that gets consumed by the exchange adapter at runtime. Instead, the routing is resolved at the API-key level:
- On the exchange: create a sub-account with its own dedicated API key.
- In TVH (Account → Settings → API Keys): add the sub-account's exchange API key as a new TVH key with a descriptive name.
- In the TradeCommand: reference the named key in the
apiKeyfield.
The TVH backend looks up the registered key by name and uses its credentials — automatically routing the call to the right sub-account.
Example
You run two strategies on Binance Futures: scalping and swing trading. Each gets its own Binance sub-account, each with its own API key.
| TVH key name | Underlying Binance credentials |
|---|---|
binance-scalper-sub1 | API key from sub-account "Scalper" |
binance-swing-sub2 | API key from sub-account "Swing" |
In your scalping Pine strategy:
{
"pair": "BTCUSDT",
"isBuy": true,
"isMarket": true,
"unitsType": "percent",
"unitsPercent": 95,
"leverage": 10,
"exchange": "BinanceFutures",
"apiKey": "binance-scalper-sub1",
"token": "{{strategy.order.alert_message}}"
}
And in your swing strategy:
{
"pair": "BTCUSDT",
"isBuy": true,
"isMarket": true,
"unitsType": "percent",
"unitsPercent": 25,
"leverage": 3,
"exchange": "BinanceFutures",
"apiKey": "binance-swing-sub2",
"token": "{{strategy.order.alert_message}}"
}
Both routes through TVH cleanly to the correct sub-account — no extra fields needed.
Supported exchanges
| Exchange | Sub-accounts | Setup notes |
|---|---|---|
| Binance Spot | Yes | Create sub on Binance, generate sub-specific API key |
| Binance Futures USD-M | Yes | Same — sub-specific API key |
| Bybit (UTA) | Yes | UTA supports sub-accounts; generate sub key |
| OKX | Yes | Requires sub-account authorization on master |
| KuCoin | Yes | UID-based; generate sub key |
| BitMex | No | Single-account exchange |
| Coinbase | No (via Coinbase Advanced) | Each account is independent |
| Hyperliquid | Limited | Single-key model; use separate wallets |
Per-exchange setup
The exact, screenshot-by-screenshot flow lives on each exchange page:
- Binance — create the sub-account (virtual email), then generate its API key from the master UI.
- OKX — create the sub-account, then generate a key + passphrase on it.
- KuCoin — create the sub-account, then View API on its row to mint its key.
- Bybit — create a UTA sub-account and generate a sub-scoped key.
In every case the principle is the same: add the sub-account's own key to TVH with a descriptive name and reference it via apiKey (see naming conventions below).
Naming conventions
A clean naming convention pays off when you have many keys. Recommended pattern:
<exchange>-<strategy>-<sub-id>
Examples:
binance-scalper-sub1binance-swing-sub2bybit-grid-sub1okx-arb-sub3
This makes Pine alerts self-documenting — anyone reading the alert message immediately knows which strategy and which sub-account it targets.
Pine snippet — multi-sub routing
//@version=5
strategy("Multi-Sub Strategy", overlay=true)
if (scalpEntry)
strategy.entry("Scalp", strategy.long, alert_message='{"pair":"BTCUSDT","isBuy":true,"isMarket":true,"unitsType":"percent","unitsPercent":95,"leverage":10,"exchange":"BinanceFutures","apiKey":"binance-scalper-sub1","token":"{{strategy.order.alert_message}}","alertTimestamp":"{{ticker}}-scalp-{{timenow}}"}')
if (swingEntry)
strategy.entry("Swing", strategy.long, alert_message='{"pair":"BTCUSDT","isBuy":true,"isMarket":true,"unitsType":"percent","unitsPercent":25,"leverage":3,"exchange":"BinanceFutures","apiKey":"binance-swing-sub2","token":"{{strategy.order.alert_message}}","alertTimestamp":"{{ticker}}-swing-{{timenow}}"}')
The two strategies write to two different sub-accounts via two different named API keys — fully isolated P&L.
Common pitfalls
- Trying to set
subAccount: "name"inside the JSON → the field is not consumed by the exchange adapter. Use a named API key instead. - Re-using the same API key for multiple subs → impossible by design. Each sub-account has its own credentials.
- Master-key permissions missing on Binance → some sub-account operations require the master key's sub-account permission. Verify in Binance settings.
- Forgetting to fund the sub → the trade fires successfully against the right account but fails on the exchange ("insufficient balance"). Check funding before going live.
- Exchanges without sub-account support (BitMex, Coinbase) → cannot be sub-isolated. Use multiple completely separate exchange accounts.
For the full per-exchange feature matrix, see Exchange Quirks Reference.