多交易所永续交易命令行工具,支持15+交易所(如Orderly、Bybit、Binance、Hyperliquid、dYdX、OKX、Bitget、BloFin、AsterDEX等),通过TTC Box AP...
This skill governs how an AI assistant should interact with the bundled
skill-trading Rust CLI. It exists to prevent hallucination and unsafe order
execution across 15+ exchange integrations routed through the TTC Box API.
This is a self-contained skill — the binary ships inside the bundle, no side-install or PATH mutation is required.
text
skill-trading/
├── SKILL.md
├── scripts/
│ ├── skill-trading # POSIX launcher — exec the right binary
│ ├── skill-trading-darwin-arm64 # Mach-O, Apple Silicon
│ └── skill-trading-linux-x64 # ELF, Linux x86_64
└── references/
├── api-reference.md # full TTC Box REST API
├── exchanges.md # per-exchange credential setup
└── troubleshooting.md # error → cause → fix
The launcher detects uname -s/ -m and execs the matching binary. Always
invoke skill-trading (the launcher) — never call a platform-suffixed binary
directly. uname -m returns arm64 on macOS and aarch64 on Linux; the
launcher handles both.
If the launcher errors with binary for <OS>-<ARCH> not bundled, this skill
does not yet ship that platform. Currently supported: darwin-arm64, linux-x64.
The skill requires two TTC Box session credentials in the environment. Both are
issued by the TTC Box API after skill-trading register or skill-trading login.
Env varPurposeTTC_AUTH_TOKEN24h session token returned by login / register``TTC_PASSKEY64-char hex key that encrypts the local wallet
Optional but commonly set:
Env varPurposeTTC_EXCHANGEDefault exchange when -e is omitted (e.g. orderly)TTC_PUBLIC_KEYWallet public key (set automatically by register)TTC_OUTPUTDefault output format: table (default), json, csv, quiet``{EXCHANGE}_API_KEY / {EXCHANGE}_API_SECRET / {EXCHANGE}_API_PASSPHRASEPer-exchange credentials
Never put API keys in config.toml. Exchange credentials and TTC Box
session tokens belong in .env only. config.toml is for non-secret
preferences (default exchange, output format, watchlist, portfolio thresholds,
market-maker tunables).
text
skill-trading status
Returns READY when the API is reachable, the session token is valid, and the
target exchange has credentials configured. Exit code is 0 when READY, 1
when NOT READY — usable as a shell gate.
Load these on demand when deeper context is needed:
references/api-reference.md — full TTC Box REST API: all methods, param shapes, response formats, supported exchanges, quirksreferences/exchanges.md — exchange names, credential setup, ORDERLY_MAIN_WALLET_ADDRESS guidereferences/troubleshooting.md — every error message with cause and fixBefore placing any order ( limit, market, stop), you MUST run these checks in order.
Do not skip steps. Do not place an order if any check fails.
text
skill-trading account balance
Parse the Available value from the output.
Available is negative or zero → STOP. Do not place the order.
Available is positive → continue to Step 2.text
skill-trading position get
Review open positions:
position close not a new order.Estimate required margin:
text
required_margin = (quantity × price) / leverage
required_margin > available → STOP. Reduce quantity or skip.text
skill-trading order open
Never place a real order without user confirmation unless explicitly told to automate.
Always show the order summary before executing: text
Symbol: NEARUSDT
Side: BUY
Type: LIMIT
Price: $1.168
Quantity: 17
Value: ~$19.86
Exchange: orderly
Use --dry-run first when testing a new order type or exchange.
If the user says "place an order at 1% under price", always fetch the current price first via: text
skill-trading market best-bid-ask -e <exchange> --symbol <SYMBOL>
Then calculate: price = bid × 0.99, quantity = budget / price.
All order operations live under the order group:
OperationCommandAliasesList open ordersorder open``order list, order lsCancel one orderorder cancel``order cxlCancel all ordersorder cancel-all``order cxl-all
--symbol is optional on open and cancel-all — omit to act across all symbols, pass to scope to one.
Always list before you cancel. Use the id returned by order open — not the id printed by order limit or order market.
Placement returns a client-generated id (e.g. dydx client_id); the cancel endpoint expects the exchange's canonical order id (e.g. dydx indexer UUID). These differ on several exchanges, so passing the placement id can fail with errors like Indexer error 400.
text
skill-trading order open -e <exchange> # fetch canonical ids
skill-trading order cancel -e <exchange> -s <SYMBOL> --order-id <id> # use the id from order open
Do this even when placement just succeeded — never assume the printed id is cancellable.
FieldMeaningbalanceTotal USDT in accountlockedMargin currently committed to open positions/ordersavailableFree margin = balance − locked. This is what matters for new orders.
A negative available means the account is over-committed. No new orders can be placed until a position is closed or margin is freed.
FieldMeaningsizePosition size in base assetentry_priceAverage entry pricemark_priceCurrent market pricepnlUnrealized profit/lossliqLiquidation price — dangerous if approachedleverageCurrent leverage multiplier
If mark_price is approaching liq, warn the user immediately.
For a full breakdown of a position including margin used, % from entry, and liquidation distance:
text
skill-trading position pnl -e <exchange> -s <SYMBOL>
Output:
text
── NEARUSDT BUY 10x ─────────────────────────────────
Size: 1160 units ($1356.62 notional)
Entry price: $1.2425
Mark price: $1.1695 (-5.88% from entry)
Unrealized PnL: -52.17 USDT (-5.88%)
Margin used: $135.66 (10x leverage, cross mode)
Liquidation: $1.0816 (7.52% away)
Use position pnl when you need to assess risk (liquidation distance) or explain the position to the user in detail. Use position get for a quick summary.
Leverage is set per symbol, on the exchange, via:
text
skill-trading account leverage -e <exchange> -s <SYMBOL> -l <N>
Example — set RAVEUSDT to 5× on asterdex:
text
skill-trading account leverage -e asterdex -s RAVEUSDT -l 5
Exchanges only accept a leverage change when there is no open position on the symbol. If a position (or even a resting reduce-only stop/TP for that symbol) is open, the call returns an error like leverage not modified or position exists.
To change leverage on a symbol you already hold:
skill-trading position get -e <exchange> — confirm the current positionskill-trading position close -e <exchange> -s <SYMBOL> (or wait for TP/SL to fill)skill-trading order cancel-all -e <exchange> -s <SYMBOL> — clear any resting reduce-only ordersskill-trading account leverage -e <exchange> -s <SYMBOL> -l <N> — now acceptedOpen orders that are not on the same symbol do not block a leverage change.
twap --leverage#skill-trading twap accepts an optional --leverage <N> flag. It does two things:
setLeverage on the exchange before slice 1 (same underlying API as account leverage).budget / leverage) for balance checks.Because step 1 runs before any order is placed, twap --leverage only succeeds if the symbol has no open position at the moment of the first tick. If you are adding to an existing position via TWAP, either omit --leverage (use whatever the exchange already has set) or close the position first.
The leverage in effect for a symbol shows up in the position pnl output ( ── NEARUSDT BUY 10x ──). When flat, query the exchange via the TTC Box API ( getPositions returns leverage even for size=0 on most exchanges), or simply set it explicitly before your next order.
account margin-mode). Set margin mode before leverage.If account leverage errors, check references/troubleshooting.md or run with -v for the raw API response.
These are cross-exchange, public endpoints — no API key required.
text
skill-trading market hybrid-tickers [OPTIONS]
Options:
--market-type spot|futures — filter by market type (default: both)--source <exchange> — filter by exchange name (e.g. binance, orderly)--symbol <SYM> — filter by symbol (e.g. NEARUSDT)--min-volume <USD> — minimum 24h volume in USD--min-price <price> — minimum price filter--max-price <price> — maximum price filter--up <pct> — show only markets up ≥ N% today (e.g. --up 5)--down <pct> — show only markets down ≥ N% todayNote: Do NOT pass
-e/--exchangehere — use--sourceto filter by exchange. The globalTTC_EXCHANGEenv var does not affect this command.
text
skill-trading market funding-rates [--symbol <SYM>]
Shows current funding rates across all exchanges for a symbol (or all symbols).
text
skill-trading market open-interest [--symbol <SYM>]
Shows open interest in USD across all exchanges.
text
skill-trading market volume-snapshot
Shows 24h volume, open interest, and TVL per exchange (CEX + DEX).
Two modes: single symbol or watchlist scan.
text
skill-trading market scanner --symbol <SYM> [--timeframe 1h] [--bars 1000] [--swing-strength 10]
Full output: direction, confidence, Vola unit, momentum, stop, TP1-3, R/R, reasoning note.
text
NEARUSDT / 1h — LONG HIGH (strength 79/100)
Entry: $1.1940
Vola unit: $0.000558/bar (1x1) | Momentum: +0.000700/bar (flat) | Avg range: $0.014500/bar
Stop Loss: $1.1862 (0.65% risk)
TP1: $1.4214 (+19.04%)
TP2: $1.8918 (+58.44%)
TP3: $2.3622 (+97.84%)
R/R: 29.14x
Note: bull composite 79.0 (score 65, R/R 29.14) vs opposite 39.6
text
# Use config.toml [watchlist] symbols (default)
skill-trading market scanner
# Custom list
skill-trading market scanner --watchlist BTCUSDT,ETHUSDT,SOLUSDT,NEARUSDT
# Filters
skill-trading market scanner --only-high # HIGH confidence only
skill-trading market scanner --min-rr 3.0 # R/R ≥ 3.0 only
skill-trading market scanner --timeframe 4h --only-high --min-rr 3.0
Output — compact table, one row per symbol:
text
Scanner — 1h │ 3 symbols │ filter: R/R ≥ 2.0
──────────────────────────────────────────────────────────────────────────────────────
Symbol Dir Conf Str Entry SL TP1 R/R
──────────────────────────────────────────────────────────────────────────────────────
NEARUSDT LONG HIGH 79 $1.1940 $1.1862 $1.4214 29.1x
BTCUSDT NEUTRAL —
ETHUSDT LONG MEDIUM 66 $2094.01 $2044.89 $2293.77 4.1x
──────────────────────────────────────────────────────────────────────────────────────
2 signal(s) match │ 1 NEUTRAL │ 0 below filter
filtered tag — not hiddenRules:
brief--only-high + --min-rr 3.0 is the recommended filter for new entriesbrief before acting: check portfolio health is not DANGER firstParameters:
--timeframe — 1m, 5m, 15m, 1h, 4h, 1d (default: 1h)--bars — bars to analyze, max 1000 (default: 1000)--swing-strength — lookback for swing detection (default: 10)--min-rr — minimum R/R to show as a match (default: 2.0)--only-high — filter to HIGH confidence onlyVola fan note: Descending fan lines from a high pivot can project below zero after many bars — this is mathematically correct, not a bug. Use the Vola unit and momentum to assess whether the move is realistic given the timeframe.
text
skill-trading market tickers --symbol <SYM>
Shows ticker data for a specific exchange (requires -e <exchange>).
text
skill-trading market best-bid-ask --symbol <SYM>
Shows the best bid and ask on a specific exchange (requires -e <exchange>).
text
skill-trading market hybrid-tickers --up 5 --min-volume 1000000
skill-trading market hybrid-tickers --down 5 --market-type futures
text
skill-trading market funding-rates --symbol BTCUSDT
account balance → verify available > 0position get → check no conflicting positionsmarket best-bid-ask --symbol <SYM> → get current priceorder limit or order marketposition get → get symbol and sizeposition close --symbol <SYM> (uses market order)
OR order limit --sell --reduce-only for a limit closetext
skill-trading account balance
skill-trading position get
Together these give a full picture of margin usage and risk.
config.toml via skill-trading config set-default <exchange>-e <exchange>.env using {EXCHANGE}_API_KEY / {EXCHANGE}_API_SECRET / {EXCHANGE}_API_PASSPHRASEwhat_exchange, woofi_pro, ttc)Places multiple limit orders stepping away from the current price. Levels and per-level size are auto-calculated from your total amount and the min_usd_entry in config (default $15).
text
skill-trading order dca -e <exchange> -s <SYMBOL> --buy|--sell --amount <USD> -d <distance%>
FlagDescription--amountTotal USD notional for the entire ladder-d, --distance% gap between each level (e.g. 1 = 1% per step)--start-priceOverride base price (defaults to current last price)--price-decimalsDecimal places for limit prices (default: 4)--qty-decimalsDecimal places for quantities (default: 0 = integer)
Calculation:
text
levels = floor(amount / min_usd_entry)
level_usd = amount / levels
price_n = base_price × (1 - distance%)^n (buy: steps down)
= base_price × (1 + distance%)^n (sell: steps up)
qty_n = floor(level_usd / price_n)
Example — $150 across 10 levels, 1% apart:
text
skill-trading order dca -e orderly -s NEARUSDT --buy --amount 150 -d 1 --dry-run
DCA Ladder — NEARUSDT BUY on orderly
Amount: $150.00 total | Levels: 10 | Per level: $15.00
Base: $1.1667 | Step: 1.00% per level | Min entry: $15.00
─────────────────────────────────────────────────────
Level 1/10 $1.1667 Qty: 12 Cost: ~$15.00
Level 2/10 $1.1550 Qty: 12 Cost: ~$15.00
...
Level 10/10 $1.0658 Qty: 14 Cost: ~$15.00
Rules:
--dry-run first to confirm levels and prices before going liveorder open after placing to confirm all levels were acceptedorder cancel-all if you want to clear the laddertext
skill-trading risk sl -e <exchange> -s <SYMBOL> --stop-price <price>
skill-trading risk tp -e <exchange> -s <SYMBOL> --tp-price <price>
Places a single stop/TP order against the current open position. Reduce-only, triggered by mark price.
text
skill-trading risk trail-watch -e <exchange> -s <SYMBOL> --trail-pct <pct> --interval <seconds>
Runs a foreground loop that:
peak × (1 - trail_pct%)Default: --trail-pct 2.0, --interval 30. Press Ctrl+C to stop.
Progress file: writes JSON state to ~/.trail-watch-{symbol}-{exchange}.json on every tick. An agent can read this file on demand to check trail-watch status without interrupting the loop.
FieldDescriptionactive``false while waiting for profit, true once trailingmark_price, entry_priceCurrent pricespeak_priceTracked peak ( null while inactive)current_stop, stop_order_idActive stop level and order ID ( null if none placed)unrealized_pnl, position_sizePosition stateupdated_atISO 8601 timestamp of last tick
Use this after entering a position — it watches passively and only activates once you're in profit.
Run once at the start of every session to get a full picture before touching anything:
bash
skill-trading brief -e orderly
# aliases: morning, mb
Single command. Runs all fetches concurrently and presents them in one report:
SectionDataSessionToken validity + time remainingWatchlist PricesPrice, 24h%, volume, OI, funding rate per symbolSignalsScanner direction, confidence, entry, SL, TP1, R/R per symbolPortfolioBalance, utilization, all positions with PnL and liq distanceOpen OrdersAll live orders with price and qtyOverallREADY / WATCH / DANGER banner
Override watchlist on the fly:
bash
skill-trading brief -e orderly --watchlist SOLUSDT,BTCUSDT,NEARUSDT
Change signal timeframe:
bash
skill-trading brief -e orderly --timeframe 4h
Watchlist defaults come from config.toml:
toml
[watchlist]
symbols = ["NEARUSDT", "BTCUSDT", "ETHUSDT"]
Rules:
brief before starting a new session's tradingBefore starting any loop ( /loop, twap, trail-watch, portfolio summary cycle), always verify the session is healthy:
bash
skill-trading status
Output:
text
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SKILL-TRADING STATUS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ TTC Box API
✓ Session token VALID 23h 43m remaining
✓ Exchange credentials orderly configured
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STATUS: READY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Decision tree:
StatusActionREADYProceed with loop or order placementNOT READY — session expiredRun skill-trading login firstNOT READY — no credentialsSet {EXCHANGE}_API_KEY / {EXCHANGE}_API_SECRET in .envNOT READY — API unreachableCheck connectivity; retry in 30s
Rules:
STATUS: NOT READY, do not start any loop or place any order.When a CLI command exits non-zero, you MUST distinguish pre-flight failures from in-flight failures before deciding whether to retry. The wrong choice can place duplicate orders, double exposure, or trip leverage limits.
Read operations are idempotent — re-running them is safe. Write operations mutate exchange state and CANNOT be safely re-run without verification.
Read (idempotent — retry freely)Write (NOT idempotent — verify before any retry)account balance``order limit / market / stop / tp``position get / position pnl``order cxl / order cxl-all``order open``position close / position close-all``market * (tickers, funding, OI, scanner)account leverage / account hedge``portfolio summary / status / brief``risk sl / risk tp / risk trail / trail-watch``info / config show / config path``twap / twap-slice / market-maker
Pre-flight failure — the request never reached the exchange. Safe to fix the cause and retry the exact same command. Signatures:
Invalid order parameters: ... — local validation rejected the argsMissing credentials for exchange: ... — never sentConfiguration error: ... — never sentAPI error [400]: ...tick size... / ...lot size... / ...insufficient balance... — TTC Box rejected before forwardingAPI error [401]: Unauthorized — session expired; never reached the exchange (run login, then retry)API error [403]: Forbidden — bad method; never reached the exchangePosition not found: <symbol> — read-side miss; nothing was mutatedFor these: fix the cause (see references/troubleshooting.md), then retry. The exchange has not been touched, so retrying creates exactly one order.
In-flight failure — the request MAY have reached the exchange. Outcome is uncertain. Signatures:
API error [500]: ... (TTC Box catch-all — could mean upstream filled then storage threw)API request failed: ... (transport error after retries were exhausted)Rate limited - retry after N seconds (CLI already auto-retried — if you see this, the retry budget is spent)For in-flight failures on a write op, do NOT retry. Run the verification protocol first.
Run all three commands. Do not skip any.
bash
skill-trading order open -e <exchange>
skill-trading position get -e <exchange> -s <symbol>
skill-trading account balance -e <exchange>
Actual stateMeaningActionDesired position open at expected sizeOrder filled; the error was a downstream blipReport success. **Do not retry.**Matching order is in order openAccepted and working at the exchangeLet it run, or cancel deliberately. **Do not place another.**Neither position nor pending orderDid not reach exchange OR was rejectedSafe to retry the original command once.Position size differs from intended (partial fill)Partial fill before the errorReport state to the user. Do not auto-place a "fill the rest" order without explicit instruction.
cancel that errors with 5xx is usually safe to verify+retry (cancelling an already-cancelled order returns a 4xx, not a duplicate). Still verify with order open first.account leverage / account hedge — these are settings, not orders. A 5xx here is verifiable: re-read state with the corresponding get and compare. If the desired setting is already in effect, do not retry.risk trail-watch — single tick error is recoverable; the next tick re-reads state. Two or more consecutive errors → stop the loop, run verification.[401] Unauthorized during a loop means the session expired. Run skill-trading login, then run the verification protocol before resuming. Do not assume the loop's last action succeeded.When a write op fails in-flight, your report to the user should include:
Do not summarize the error away. The user needs the raw verification output to make the call.
order open before referencing open orders. Orders may have been filled, cancelled, or expired since they were last placed.position get for the current state before making decisions based on a position.