[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6HZHWZDS6Z9RGF4MHJJP7BN":3,"skill-same:01M6HZHWZDS6Z9RGF4MHJJP7BN":63},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":14,"repositoryHtmlUrl":46,"repositoryHomepageUrl":6,"ownerHtmlUrl":47,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":48,"install":49,"resources":62},"01M6HZHWZDS6Z9RGF4MHJJP7BN","rwa-trade",null,"Buy and sell tokenized stocks & ETFs on Solana via the rwa CLI. Use when the user wants to trade, buy, sell, preview a quote, check market hours, or list tokens. Triggers: \"buy TSLA\", \"sell stocks\", \"trade RWA\", \"quote NVDA\", \"market hours\", \"list tokens\", \"what can I buy on Solana\".","outputlayer\u002Frwa_skills","outputlayer","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43842477?v=4","01M6HZHQWCSVEY38ZT60FDGAHG","Outputlayer","01M6HZHR0X8AVZ1ZQMCEW0GJ31",0,"MIT","https:\u002F\u002Fgithub.com\u002Foutputlayer\u002Frwa_skills\u002Fblob\u002Fmain\u002Fskills\u002Frwa-trade\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"trade","rwa trade","rwa","user","use","Market","solana","preview","quote","cli","buy","sell","stocks","tokens","triggers","via","can","list","check","2026-11-10 10:12:30",false,"---\nname: rwa-trade\ndescription: >\n  Buy and sell tokenized stocks & ETFs on Solana via the rwa CLI.\n  Use when the user wants to trade, buy, sell, preview a quote, check market\n  hours, or list tokens. Triggers: \"buy TSLA\", \"sell stocks\", \"trade RWA\",\n  \"quote NVDA\", \"market hours\", \"list tokens\", \"what can I buy on Solana\".\n---\n\n# RWA Trade\n\nBuy\u002Fsell 450 tokenized stocks & ETFs (Ondo Global Markets) on Solana. Always pass `--json`; add `-y` to execute, `--dry-run` to preview. **Since v0.6.0 `--json` без `-y` НЕ исполняет** buy\u002Fsell\u002Fsend\u002Fbaskets\u002Fclose-all (fails closed). An otherwise-valid trade → `error_kind: confirmation_required`; a precondition failure (`insufficient_funds`\u002F`no_position`\u002F`amount_below_minimum`) surfaces its own kind first, and `close-all` on an empty wallet → `status:success`. Guarantee is \"never executes\", not \"always confirmation_required\". `reclaim` runs without confirmation (rent back to your own wallet).\n\n## Golden rules\n\n- **NEVER use `&`, background, or parallel shell processes** — one `rwa` process at a time (a lock enforces it). Multi-token commands parallelize internally.\n- Minimum buy: **5 USDC** (single buy and per basket item).\n- No `quote` command — preview with `--dry-run`.\n- `--quote-only` (buy) quotes any size without a balance check; never executes (rejects `-y`). JSON `status` is `dry_run`. Use to size a buy before funding.\n- `sell` swaps tokens → USDC; `send` transfers assets out. Never confuse them.\n- CLI auto-retries transient swap failures. **Do NOT retry manually** unless it reports failure after retries.\n- Multi-token = `buy-basket` \u002F `sell-basket` \u002F `close-all` — they run **in parallel by default** (bounded internally). Never loop `buy`\u002F`sell` by hand. `--sequential` is a rate-limit fallback only. Launches are staggered + adaptive (real runs and dry-run alike) to dodge Jupiter's per-wallet 429 — live: 5-token basket ≈ 3 s. Setting `RWA_JUPITER_API_KEY` auto-selects the faster keyed profile; no manual tuning.\n- Bulk filtering = `gm search` flags. **Never** pipe `gm list` through ad-hoc Python.\n\n## Commands\n\n```bash\nrwa --json gm hours                                          # session + tradable_count + paused_count + offhours flagships; next_session_at = epoch seconds (schedule on it)\nrwa --json gm search --tradable-only --sector Technology     # bulk scan\nrwa --json gm search --tag asia --tag \"fixed income\"         # any Ondo tag: region, asset class, factor\nrwa --json gm tradable TSLA NVDA                             # check specific symbols\nrwa --json gm buy  TSLA 100 --dry-run                        # preview (100 USDC in)\nrwa --json gm buy  TSLA 100 -y --slippage 50                 # execute, max 0.5% slippage\nrwa --json gm sell TSLA all  -y                              # sell all (also 50% \u002F exact)\nrwa --json gm buy  TSLA 100 --limit-price 400 -y             # conditional: fills only if quote \u003C= 400 USDC\u002Ftoken\nrwa --json gm sell TSLA all --limit-price 450 -y             # conditional: fills only if quote >= 450\nrwa --json gm buy  SPY 100 --limit-price 748 share -y        # limit per underlying SHARE (bare number = per token)\nrwa --json gm buy  TSLA 100 --max-bps 30 -y                  # reject if all-in cost (spread+fee) > 30 bps\nrwa --json gm buy-basket  AAPL 50 TSLA 50 NVDA 50 -y         # SYMBOL AMOUNT pairs (parallel)\nrwa --json gm buy-basket  TSLA 50% NVDA 30% SPY 20% --total 1000 -y  # weighted allocation of one USDC total\nrwa --json gm buy-basket  --total 1000 --equal TSLA NVDA SPY -y      # EVEN split across bare symbols (arbitrary N)\nrwa --json gm buy-basket  --from-file basket.txt --total 500 -y      # tokens from a file (- = stdin)\nrwa --json gm search --tradable-only --sector Technology | jq -r '.items[].symbol' | xargs rwa gm buy-basket --total 1000 --equal -y  # filter-driven bulk (compose search → buy-basket)\nrwa --json gm sell-basket SPY 5 TSLA 3 NVDA all  -y\nrwa --json gm close-all -y                                   # sell ALL positions (parallel, ~2-8s)\nrwa --json gm close-all 50% -y                               # sell 50% of every position\nrwa --json gm pnl                                            # avg entry + realized\u002Funrealized P&L\nrwa --json gm reclaim                                        # close empty accounts, reclaim rent\n```\n\n- `buy-basket --total \u003CUSDC>` (v0.7.8+): all pair amounts become percent weights that must sum to exactly 100; each computed item must clear the 5 USDC minimum; validation is local (`invalid_amount`\u002F`amount_below_minimum`) before any network. Success\u002Fdry-run JSON echoes `allocation: {total, weights}`. Percent amounts without `--total` (and absolute amounts with it) are rejected.\n- `buy-basket --equal` (v0.7.10+, requires `--total`): splits the total EVENLY across **bare symbols** (no per-token amounts) — `--total 1000 --equal TSLA NVDA SPY` → ~333.33 each (floor + dust to first, same 5 USDC\u002Fitem minimum). It's the only clean way to equal-weight an arbitrary N under the exact-100 `--total` rule (3×33.33 ≠ 100), so it's the go-to for filter-driven bulk. `--equal` with amount\u002Fpercent tokens (or without `--total`) → `invalid_amount` pre-network.\n- `buy-basket --from-file \u003Cpath>` (v0.7.10+): reads tokens from a file instead of args; `-` = stdin (pipe `search` output straight in). Whitespace\u002Fnewline separated; blank and `#` comment lines ignored. Mutually exclusive with positional tokens. Works with all three amount modes. **Filter-driven bulk buy** = compose, don't add flags: `rwa --json gm search --tradable-only --sector X | jq -r '.items[].symbol' | xargs rwa gm buy-basket --total N --equal -y` (or `search … > basket.txt` then `buy-basket --from-file basket.txt --total N --equal -y`). `--equal` is required here — the filtered N is arbitrary.\n- `close-all` skips positions \u003C $1.50 (MMs reject tiny swaps) and lists them separately.\n- **close-all exit 75 (since 0.7.14):** if any `skipped[]` entry is retryable (`trading_paused`, not tradable in current session, market data unavailable) the run reports `status:\"partial\"` + `incomplete_reason` and exits **75** — even when every position was skipped. Positions are still in the wallet: STOP the exit chain (no `reclaim`\u002F`send`), retry when the market reopens. Dust skips are `retryable:false` and keep `success`\u002Fexit 0. `--dry-run` exits 0 but carries `incomplete_reason`.\n- Slippage: default 100 bps; hard-blocked above 3%. Amounts: exact `100`, `50%`, or `all`. Percentages: max 2 decimals, `0 \u003C pct ≤ 100` (since 0.7.15 `33.333%`\u002F`0%` → `invalid_amount`, never rounded; `sell-basket` rejects them before any leg runs).\n- `search` items carry optional `asset_class`\u002F`region`; `--tag` matches any Ondo tag label (24 factor labels incl. Large Cap, Dividend, High Yield).\n\n## Conditional orders (synthetic limit orders)\n\n`--limit-price \u003CP>` (buy\u002Fsell only) executes **only if the quoted price** (USDC per token) is ≤ P for buy \u002F ≥ P for sell (equality fills); otherwise the command exits 1 with `error_kind: condition_not_met` — same in `--dry-run`. The quote that passes the check is the one executed, so worst-case fill = limit ± slippage; pair with a tight `--slippage 20`. JSON echoes `limit_price` on success. Conflicts with `--quote-only`.\n\nUnit: bare number = per **token**; add `share` (`--limit-price 748 share`; joined `748share` also accepted) to gate per underlying **share** instead. GM tokens are total-return trackers (dividends reinvested), so token price = share price × multiplier — previews expose `share_price`\u002F`shares_per_token` once the multiplier drifts from 1. If the multiplier can't be read for a `share`-limit, the command fails closed with exit 75 (transient — retry next tick).\n\n- **Limit order:** schedule `rwa --json gm buy TSLA 100 --limit-price 400 --slippage 20 -y` (cron\u002Floop, every N min) until it exits 0. `condition_not_met` = keep waiting, NOT an error to escalate.\n- **DCA:** plain scheduled `buy \u003CSYM> \u003CAMT> -y` — no limit-price needed.\n- **Stop-loss:** check the reference price yourself, then market `sell -y`. Do NOT use `--limit-price` for stops (a stop wants out, not a price guarantee).\n\n## Key JSON\n\n```json\n\u002F\u002F buy -y \u002F --dry-run (status \"success\" | \"dry_run\")\n{\"status\":\"success\",\"amount\":\"0.258\",\"token\":\"TSLAon\",\"counter_amount\":\"100.00\",\"counter_token\":\"USDC\",\"tx\":\"https:\u002F\u002Fsolscan.io\u002Ftx\u002F...\",\"slippage_pct\":-0.39}\n\u002F\u002F buy-basket → bought[]+total_usdc_spent · sell-basket → sold[]+total_usdc_received · close-all → sold[]+total_usdc\n{\"status\":\"success\",\"sold\":[{\"token\":\"TSLAon\",\"amount\":\"0.25\",\"usdc\":\"96.50\",\"tx\":\"...\"}],\"failed\":[],\"total_usdc\":\"96.50\"}\n```\n\nMulti-token status (baskets\u002Fclose-all, since 0.7.9): `\"success\"` = all items ok; `\"partial\"` = some failed (exit 0, check `failed[]`); `\"error\"` = ALL failed (exit ≠ 0). So don't treat exit 0 + `success` as \"everything bought\" without also checking `failed[]` — and an all-failed basket now exits non-zero.\nAn optional `gas_refuel: {\"usdc\":\"5\",\"sol\":\"0.02...\",\"tx\":\"...\"}` object appears when the CLI auto-bought SOL for fees before the trade (normal for USDC-only wallets — not an error).\n\n## Errors → action\n\n| Error \u002F error_kind | Agent action |\n|---|---|\n| `market_closed` | Weekend\u002Fholiday and this token doesn't trade off-hours. Flagships (TSLAon, NVDAon, SPYon, QQQon, GOOGLon…) trade 24\u002F7 — check `gm hours --tradable` |\n| `not_tradable` | Skip token; verify with `gm tradable \u003CSYM>` |\n| `slippage_too_high` | Reduce size or skip; MM cooldown after rapid buy+sell — wait 30–60s |\n| `condition_not_met` | `--limit-price` unmet — keep the order scheduled, retry next tick; not a failure |\n| `confirmation_required` | `--json` without `-y` — add `-y` to execute or `--dry-run` to preview; never retry as-is |\n| `trading_paused` | Ondo paused this asset: a dividend window OR the market is closed for it (weekends flag most non-24\u002F7 tokens, so a weekend non-flagship gives `trading_paused`, not `market_closed`). Check `gm hours`\u002F`next_session_at` for when it resumes — don't hammer-retry a weekend pause. In baskets → `failed[]`; close-all skips it |\n| `cost_too_high` | Quoted all-in cost exceeds `--max-bps` — raise the ceiling or wait for a tighter spread |\n| `amount_below_minimum` | Use ≥ 5 USDC per token |\n| `insufficient_funds` (SOL) | Non-gasless route needs ~0.002 SOL. The CLI normally auto-refuels from USDC; if it couldn't, retry (gasless route may fill) or fund SOL |\n| `insufficient_funds` (USDC) | Tell user to fund USDC |\n| `no_position` \u002F `Balance is 0` | No position to sell |\n| `unknown_token` | Symbol not in the GM list (typo?) — find it with `gm search --search \u003Ckeyword>`; don't retry as-is |\n| `invalid_amount` \u002F `invalid_address` | Bad user input (amount is a number, `NN%` with ≤2 decimals, or `all`; address must be valid Solana) — fix, don't retry |\n| `lock_contention` (exit 75) | Another rwa process holds the lock — the lock covers EVERY invocation (even reads), so serialize ALL rwa calls; wait and retry |\n| `route_unfillable` (exit 75 since 0.7.9, was 1) | No fillable route after retries — now rare, since RFQ makers fund fills just-in-time. Transient: try again \u002F larger amount \u002F wait. (A stderr `note: RFQ maker funds just-in-time…` during a buy is NORMAL, not an error — the swap still lands.) |\n| `recipient_not_allowed` (exit 1, on `send`) | The wallet has a send-policy whitelist and this address isn't on it. A HUMAN adds it (`rwa keys policy allow \u003CADDR>`, admin-class) — stop and tell the user; never try to bypass |\n| `interactive_required` (exit 1) | An admin-class `keys` command ran headless (decrypt\u002Fexport --reveal\u002Fpolicy allow\u002Fstore-passphrase) — needs a typed passphrase at a real terminal |\n| `missing_blockhash` \u002F `invalid_blockhash` (exit 75 since 0.7.11) | Transient RPC\u002Ftx-format hiccup — a fresh blockhash on retry fixes it; retry the command |\n| `simulation_failure` (exit 1) | The tx was proven to fail on-chain pre-send (nothing submitted) — permanent, don't retry as-is |\n| Swap failed code -1000\u002F-2003\u002F-2004\u002F-2005 | CLI already auto-retried — do NOT retry manually |\n| `rpc_unavailable` (exit 75) | Transient (network\u002F5xx\u002Frate-limit\u002Fnode-behind) — wait a few seconds; on repeats set `RWA_RPC_URL` to a dedicated endpoint. Since 0.7.15 an RPC 401\u002F403 or request error is `error_kind: null`, exit 1 — fix the RPC URL\u002Fkey, don't retry |\n| `execute_unavailable` (exit 75) | Transient (incl. a pre-sign-sim RPC failure since 0.7.11, and a Jupiter `\u002Forder` quote 429\u002F5xx since 0.7.15) — retry. In an all-failed basket\u002Fclose-all where every leg was transient, the command exits 75 (not 1) — safe to retry the whole batch |\n| `ondo_unavailable` (exit 75) | Ondo assets\u002Fsession-limits API temporarily down (network, 403 WAF block, 429, 5xx) — on `search`\u002F`tradable` and the off-hours pre-trade check (since 0.7.17; previously `search`\u002F`tradable` gave exit 1 and off-hours buy\u002Fsell a false `market_closed`). Wait 1–4 min and retry |\n\nExit code **75** = transient, safe to retry the command; **1** = permanent, don't.\n\n## Sessions & liquidity\n\nSessions (ET): Pre-Market 4:00, Regular 9:30, Post-Market 16:00, Overnight 20:00. **Weekends\u002Fholidays are off-hours: only flagship tokens trade** (`gm hours --tradable` shows the live set). Outside Regular hours many small caps are illiquid — on repeated `route_unfillable`\u002F`-2004`, substitute a token or wait; don't hammer the same one.\n\n## Safe pre-trade flow\n\n```bash\nrwa keys show && rwa --json gm portfolio && rwa --json gm hours   # wallet, funds, market open?\nrwa --json gm buy TSLA 100 -y\n```\n","# RWA Trade\n\nBuy\u002Fsell 450 tokenized stocks & ETFs (Ondo Global Markets) on Solana. Always pass `--json`; add `-y` to execute, `--dry-run` to preview. **Since v0.6.0 `--json` без `-y` НЕ исполняет** buy\u002Fsell\u002Fsend\u002Fbaskets\u002Fclose-all (fails closed). An otherwise-valid trade → `error_kind: confirmation_required`; a precondition failure (`insufficient_funds`\u002F`no_position`\u002F`amount_below_minimum`) surfaces its own kind first, and `close-all` on an empty wallet → `status:success`. Guarantee is \"never executes\", not \"always confirmation_required\". `reclaim` runs without confirmation (rent back to your own wallet).\n\n## Golden rules\n\n- **NEVER use `&`, background, or parallel shell processes** — one `rwa` process at a time (a lock enforces it). Multi-token commands parallelize internally.\n- Minimum buy: **5 USDC** (single buy and per basket item).\n- No `quote` command — preview with `--dry-run`.\n- `--quote-only` (buy) quotes any size without a balance check; never executes (rejects `-y`). JSON `status` is `dry_run`. Use to size a buy before funding.\n- `sell` swaps tokens → USDC; `send` transfers assets out. Never confuse them.\n- CLI auto-retries transient swap failures. **Do NOT retry manually** unless it reports failure after retries.\n- Multi-token = `buy-basket` \u002F `sell-basket` \u002F `close-all` — they run **in parallel by default** (bounded internally). Never loop `buy`\u002F`sell` by hand. `--sequential` is a rate-limit fallback only. Launches are staggered + adaptive (real runs and dry-run alike) to dodge Jupiter's per-wallet 429 — live: 5-token basket ≈ 3 s. Setting `RWA_JUPITER_API_KEY` auto-selects the faster keyed profile; no manual tuning.\n- Bulk filtering = `gm search` flags. **Never** pipe `gm list` through ad-hoc Python.\n\n## Commands\n\n```bash\nrwa --json gm hours                                          # session + tradable_count + paused_count + offhours flagships; next_session_at = epoch seconds (schedule on it)\nrwa --json gm search --tradable-only --sector Technology     # bulk scan\nrwa --json gm search --tag asia --tag \"fixed income\"         # any Ondo tag: region, asset class, factor\nrwa --json gm tradable TSLA NVDA                             # check specific symbols\nrwa --json gm buy  TSLA 100 --dry-run                        # preview (100 USDC in)\nrwa --json gm buy  TSLA 100 -y --slippage 50                 # execute, max 0.5% slippage\nrwa --json gm sell TSLA all  -y                              # sell all (also 50% \u002F exact)\nrwa --json gm buy  TSLA 100 --limit-price 400 -y             # conditional: fills only if quote \u003C= 400 USDC\u002Ftoken\nrwa --json gm sell TSLA all --limit-price 450 -y             # conditional: fills only if quote >= 450\nrwa --json gm buy  SPY 100 --limit-price 748 share -y        # limit per underlying SHARE (bare number = per token)\nrwa --json gm buy  TSLA 100 --max-bps 30 -y                  # reject if all-in cost (spread+fee) > 30 bps\nrwa --json gm buy-basket  AAPL 50 TSLA 50 NVDA 50 -y         # SYMBOL AMOUNT pairs (parallel)\nrwa --json gm buy-basket  TSLA 50% NVDA 30% SPY 20% --total 1000 -y  # weighted allocation of one USDC total\nrwa --json gm buy-basket  --total 1000 --equal TSLA NVDA SPY -y      # EVEN split across bare symbols (arbitrary N)\nrwa --json gm buy-basket  --from-file basket.txt --total 500 -y      # tokens from a file (- = stdin)\nrwa --json gm search --tradable-only --sector Technology | jq -r '.items[].symbol' | xargs rwa gm buy-basket --total 1000 --equal -y  # filter-driven bulk (compose search → buy-basket)\nrwa --json gm sell-basket SPY 5 TSLA 3 NVDA all  -y\nrwa --json gm close-all -y                                   # sell ALL positions (parallel, ~2-8s)\nrwa --json gm close-all 50% -y                               # sell 50% of every position\nrwa --json gm pnl                                            # avg entry + realized\u002Funrealized P&L\nrwa --json gm reclaim                                        # close empty accounts, reclaim rent\n```\n\n- `buy-basket --total \u003CUSDC>` (v0.7.8+): all pair amounts become percent weights that must sum to exactly 100; each computed item must clear the 5 USDC minimum; validation is local (`invalid_amount`\u002F`amount_below_minimum`) before any network. Success\u002Fdry-run JSON echoes `allocation: {total, weights}`. Percent amounts without `--total` (and absolute amounts with it) are rejected.\n- `buy-basket --equal` (v0.7.10+, requires `--total`): splits the total EVENLY across **bare symbols** (no per-token amounts) — `--total 1000 --equal TSLA NVDA SPY` → ~333.33 each (floor + dust to first, same 5 USDC\u002Fitem minimum). It's the only clean way to equal-weight an arbitrary N under the exact-100 `--total` rule (3×33.33 ≠ 100), so it's the go-to for filter-driven bulk. `--equal` with amount\u002Fpercent tokens (or without `--total`) → `invalid_amount` pre-network.\n- `buy-basket --from-file \u003Cpath>` (v0.7.10+): reads tokens from a file instead of args; `-` = stdin (pipe `search` output straight in). Whitespace\u002Fnewline separated; blank and `#` comment lines ignored. Mutually exclusive with positional tokens. Works with all three amount modes. **Filter-driven bulk buy** = compose, don't add flags: `rwa --json gm search --tradable-only --sector X | jq -r '.items[].symbol' | xargs rwa gm buy-basket --total N --equal -y` (or `search … > basket.txt` then `buy-basket --from-file basket.txt --total N --equal -y`). `--equal` is required here — the filtered N is arbitrary.\n- `close-all` skips positions \u003C $1.50 (MMs reject tiny swaps) and lists them separately.\n- **close-all exit 75 (since 0.7.14):** if any `skipped[]` entry is retryable (`trading_paused`, not tradable in current session, market data unavailable) the run reports `status:\"partial\"` + `incomplete_reason` and exits **75** — even when every position was skipped. Positions are still in the wallet: STOP the exit chain (no `reclaim`\u002F`send`), retry when the market reopens. Dust skips are `retryable:false` and keep `success`\u002Fexit 0. `--dry-run` exits 0 but carries `incomplete_reason`.\n- Slippage: default 100 bps; hard-blocked above 3%. Amounts: exact `100`, `50%`, or `all`. Percentages: max 2 decimals, `0 \u003C pct ≤ 100` (since 0.7.15 `33.333%`\u002F`0%` → `invalid_amount`, never rounded; `sell-basket` rejects them before any leg runs).\n- `search` items carry optional `asset_class`\u002F`region`; `--tag` matches any Ondo tag label (24 factor labels incl. Large Cap, Dividend, High Yield).\n\n## Conditional orders (synthetic limit orders)\n\n`--limit-price \u003CP>` (buy\u002Fsell only) executes **only if the quoted price** (USDC per token) is ≤ P for buy \u002F ≥ P for sell (equality fills); otherwise the command exits 1 with `error_kind: condition_not_met` — same in `--dry-run`. The quote that passes the check is the one executed, so worst-case fill = limit ± slippage; pair with a tight `--slippage 20`. JSON echoes `limit_price` on success. Conflicts with `--quote-only`.\n\nUnit: bare number = per **token**; add `share` (`--limit-price 748 share`; joined `748share` also accepted) to gate per underlying **share** instead. GM tokens are total-return trackers (dividends reinvested), so token price = share price × multiplier — previews expose `share_price`\u002F`shares_per_token` once the multiplier drifts from 1. If the multiplier can't be read for a `share`-limit, the command fails closed with exit 75 (transient — retry next tick).\n\n- **Limit order:** schedule `rwa --json gm buy TSLA 100 --limit-price 400 --slippage 20 -y` (cron\u002Floop, every N min) until it exits 0. `condition_not_met` = keep waiting, NOT an error to escalate.\n- **DCA:** plain scheduled `buy \u003CSYM> \u003CAMT> -y` — no limit-price needed.\n- **Stop-loss:** check the reference price yourself, then market `sell -y`. Do NOT use `--limit-price` for stops (a stop wants out, not a price guarantee).\n\n## Key JSON\n\n```json\n\u002F\u002F buy -y \u002F --dry-run (status \"success\" | \"dry_run\")\n{\"status\":\"success\",\"amount\":\"0.258\",\"token\":\"TSLAon\",\"counter_amount\":\"100.00\",\"counter_token\":\"USDC\",\"tx\":\"https:\u002F\u002Fsolscan.io\u002Ftx\u002F...\",\"slippage_pct\":-0.39}\n\u002F\u002F buy-basket → bought[]+total_usdc_spent · sell-basket → sold[]+total_usdc_received · close-all → sold[]+total_usdc\n{\"status\":\"success\",\"sold\":[{\"token\":\"TSLAon\",\"amount\":\"0.25\",\"usdc\":\"96.50\",\"tx\":\"...\"}],\"failed\":[],\"total_usdc\":\"96.50\"}\n```\n\nMulti-token status (baskets\u002Fclose-all, since 0.7.9): `\"success\"` = all items ok; `\"partial\"` = some failed (exit 0, check `failed[]`); `\"error\"` = ALL failed (exit ≠ 0). So don't treat exit 0 + `success` as \"everything bought\" without also checking `failed[]` — and an all-failed basket now exits non-zero.\nAn optional `gas_refuel: {\"usdc\":\"5\",\"sol\":\"0.02...\",\"tx\":\"...\"}` object appears when the CLI auto-bought SOL for fees before the trade (normal for USDC-only wallets — not an error).\n\n## Errors → action\n\n| Error \u002F error_kind | Agent action |\n|---|---|\n| `market_closed` | Weekend\u002Fholiday and this token doesn't trade off-hours. Flagships (TSLAon, NVDAon, SPYon, QQQon, GOOGLon…) trade 24\u002F7 — check `gm hours --tradable` |\n| `not_tradable` | Skip token; verify with `gm tradable \u003CSYM>` |\n| `slippage_too_high` | Reduce size or skip; MM cooldown after rapid buy+sell — wait 30–60s |\n| `condition_not_met` | `--limit-price` unmet — keep the order scheduled, retry next tick; not a failure |\n| `confirmation_required` | `--json` without `-y` — add `-y` to execute or `--dry-run` to preview; never retry as-is |\n| `trading_paused` | Ondo paused this asset: a dividend window OR the market is closed for it (weekends flag most non-24\u002F7 tokens, so a weekend non-flagship gives `trading_paused`, not `market_closed`). Check `gm hours`\u002F`next_session_at` for when it resumes — don't hammer-retry a weekend pause. In baskets → `failed[]`; close-all skips it |\n| `cost_too_high` | Quoted all-in cost exceeds `--max-bps` — raise the ceiling or wait for a tighter spread |\n| `amount_below_minimum` | Use ≥ 5 USDC per token |\n| `insufficient_funds` (SOL) | Non-gasless route needs ~0.002 SOL. The CLI normally auto-refuels from USDC; if it couldn't, retry (gasless route may fill) or fund SOL |\n| `insufficient_funds` (USDC) | Tell user to fund USDC |\n| `no_position` \u002F `Balance is 0` | No position to sell |\n| `unknown_token` | Symbol not in the GM list (typo?) — find it with `gm search --search \u003Ckeyword>`; don't retry as-is |\n| `invalid_amount` \u002F `invalid_address` | Bad user input (amount is a number, `NN%` with ≤2 decimals, or `all`; address must be valid Solana) — fix, don't retry |\n| `lock_contention` (exit 75) | Another rwa process holds the lock — the lock covers EVERY invocation (even reads), so serialize ALL rwa calls; wait and retry |\n| `route_unfillable` (exit 75 since 0.7.9, was 1) | No fillable route after retries — now rare, since RFQ makers fund fills just-in-time. Transient: try again \u002F larger amount \u002F wait. (A stderr `note: RFQ maker funds just-in-time…` during a buy is NORMAL, not an error — the swap still lands.) |\n| `recipient_not_allowed` (exit 1, on `send`) | The wallet has a send-policy whitelist and this address isn't on it. A HUMAN adds it (`rwa keys policy allow \u003CADDR>`, admin-class) — stop and tell the user; never try to bypass |\n| `interactive_required` (exit 1) | An admin-class `keys` command ran headless (decrypt\u002Fexport --reveal\u002Fpolicy allow\u002Fstore-passphrase) — needs a typed passphrase at a real terminal |\n| `missing_blockhash` \u002F `invalid_blockhash` (exit 75 since 0.7.11) | Transient RPC\u002Ftx-format hiccup — a fresh blockhash on retry fixes it; retry the command |\n| `simulation_failure` (exit 1) | The tx was proven to fail on-chain pre-send (nothing submitted) — permanent, don't retry as-is |\n| Swap failed code -1000\u002F-2003\u002F-2004\u002F-2005 | CLI already auto-retried — do NOT retry manually |\n| `rpc_unavailable` (exit 75) | Transient (network\u002F5xx\u002Frate-limit\u002Fnode-behind) — wait a few seconds; on repeats set `RWA_RPC_URL` to a dedicated endpoint. Since 0.7.15 an RPC 401\u002F403 or request error is `error_kind: null`, exit 1 — fix the RPC URL\u002Fkey, don't retry |\n| `execute_unavailable` (exit 75) | Transient (incl. a pre-sign-sim RPC failure since 0.7.11, and a Jupiter `\u002Forder` quote 429\u002F5xx since 0.7.15) — retry. In an all-failed basket\u002Fclose-all where every leg was transient, the command exits 75 (not 1) — safe to retry the whole batch |\n| `ondo_unavailable` (exit 75) | Ondo assets\u002Fsession-limits API temporarily down (network, 403 WAF block, 429, 5xx) — on `search`\u002F`tradable` and the off-hours pre-trade check (since 0.7.17; previously `search`\u002F`tradable` gave exit 1 and off-hours buy\u002Fsell a false `market_closed`). Wait 1–4 min and retry |\n\nExit code **75** = transient, safe to retry the command; **1** = permanent, don't.\n\n## Sessions & liquidity\n\nSessions (ET): Pre-Market 4:00, Regular 9:30, Post-Market 16:00, Overnight 20:00. **Weekends\u002Fholidays are off-hours: only flagship tokens trade** (`gm hours --tradable` shows the live set). Outside Regular hours many small caps are illiquid — on repeated `route_unfillable`\u002F`-2004`, substitute a token or wait; don't hammer the same one.\n\n## Safe pre-trade flow\n\n```bash\nrwa keys show && rwa --json gm portfolio && rwa --json gm hours   # wallet, funds, market open?\nrwa --json gm buy TSLA 100 -y\n```\n",{"name":5,"description":7},"main","2a9273a156cc37a3a22355053a8e6b1b91b8df5e","skills\u002Frwa-trade","https:\u002F\u002Fgithub.com\u002Foutputlayer\u002Frwa_skills","https:\u002F\u002Fgithub.com\u002Foutputlayer","2026-10-08 09:24:42",{"source":8,"skillName":5,"commands":50,"prompt":60,"zipAvailable":61},[51,54,57],{"tool":52,"command":53},"npx","npx skills add outputlayer\u002Frwa_skills --skill rwa-trade",{"tool":55,"command":56},"bunx","bunx skills add outputlayer\u002Frwa_skills --skill rwa-trade",{"tool":58,"command":59},"pnpm","pnpm dlx skills add outputlayer\u002Frwa_skills --skill rwa-trade","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Foutputlayer\u002Frwa_skills\u002Fblob\u002Fmain\u002Fskills\u002Frwa-trade\u002FSKILL.md",true,[],[64,85],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":38},"01M6HZJ08KZQX10GZGDT4G50SN","rwa-wallet","Set up Solana wallets and transfer funds for trading tokenized stocks via the rwa CLI. Use for wallet creation, import, export\u002Fbackup, encryption, sending\u002Fwithdrawing funds, or reclaiming rent. Triggers: \"create wallet\", \"generate keys\", \"import seed phrase\", \"export key\", \"backup wallet\", \"show address\", \"send SOL\", \"send USDC\", \"withdraw\", \"transfer\", \"reclaim rent\", \"encrypt wallet\", \"passphrase\".","https:\u002F\u002Fgithub.com\u002Foutputlayer\u002Frwa_skills\u002Fblob\u002Fmain\u002Fskills\u002Frwa-wallet\u002FSKILL.md",[],[71,21,72,73,28,74,75,76,23,77,78,25,79,80,33,81,34,82,83,84],"rwa wallet","Wallet","encryption","SET","backup","passphrase","up","show","usdc","creation","import","for","encrypt","create",{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":38},"01M6HZHSQ4RN8T2YERP55ZN6KG","rwa-portfolio","View portfolio holdings, P&L, allocation, and price history for tokenized stocks on Solana. Triggers: \"show portfolio\", \"my holdings\", \"positions\", \"how much TSLA\", \"price history\", \"P&L\", \"profit\", \"average entry\", \"24h change\", \"balance\", \"what do I own\".","https:\u002F\u002Fgithub.com\u002Foutputlayer\u002Frwa_skills\u002Fblob\u002Fmain\u002Fskills\u002Frwa-portfolio\u002FSKILL.md",[],[92,93,21,33,94,95,96,78,97,25,98,31,99,100,101,102,103,82,104],"portfolio","rwa portfolio","how","history","view","do","positions","price","balance","my","profit","allocation","change"]