| name | bybit-trading |
| description | Bybit AI Trading Skill — Trade on Bybit using natural language. Covers spot, derivatives, earn, and more. Works with Claude, ChatGPT, OpenClaw, and any AI assistant. |
| metadata | {"version":"1.6.1","author":"Bybit","updated":"2026-09-02T00:00:00.000Z"} |
| license | MIT |
Bybit Trading Skill
Trade on Bybit using natural language. Supports spot, linear perpetuals (USDT/USDC), inverse contracts, options, and earn products.
Rule Priority
When rules in this skill conflict, follow this order: Safety > User Responsiveness > Convenience. For example, never skip confirmation to be faster; never block the user's first request to run an auto-update check.
Auto Update (MUST follow at session start)
This skill supports self-update with integrity verification. At the start of each new session, launch the update check as a background sub-agent so it never blocks the user's first request:
FOREGROUND (main agent — immediate):
1. Respond to the user's request using the current local version. Do NOT wait for the update check.
BACKGROUND (sub-agent — parallel):
1. LOCAL_VERSION = metadata.version (from YAML frontmatter above)
2. SKILL_DIR = directory where this SKILL.md is located
3. MANIFEST = curl -sf -H "User-Agent: bybit-skill/1.6.1" https://api.bybit.com/skill/manifest
(returns JSON: {"version":"x.y.z", "files":{"SKILL.md":"sha256:...","modules/market.md":"sha256:...",...}})
4. If fetch fails: return {status: "error", reason: "fetch_failed"}
5. Path validation: For each file in manifest.files, reject the entire update if ANY path:
- Does not match `SKILL.md`, `modules/<name>.md`, or `modules/<name>.js` (where <name> is [a-z0-9-]+)
- Contains `..`, starts with `/` or `~`, contains backslashes, or has an extension other than `.md` or `.js`
If any path is invalid: return {status: "error", reason: "invalid_path", path: "<rejected>"}
6. Version comparison (semver): split by ".", compare major → minor → patch numerically.
If manifest.version > LOCAL_VERSION:
a. For each file in manifest.files:
- Download: curl -sf -H "User-Agent: bybit-skill/1.6.1" https://raw.githubusercontent.com/bybit-exchange/skills/main/<file>
- Save content to temp file, then compute SHA256: shasum -a 256 <temp_file> | awk '{print $1}'
- Compare with manifest checksum (strip "sha256:" prefix)
- If mismatch: ABORT entire update. return {status: "error", reason: "checksum_mismatch", file: "<file>"}
- If file extension is `.js` AND the local file already exists at SKILL_DIR/<file>:
→ Show to user: "⚠️ Code module update: <file> (LOCAL_VERSION → manifest.version). Allow? [Y/n]"
→ If user declines: skip this file, continue with remaining files
- If match: save to SKILL_DIR/.skill-update-tmp/<file>
b. ALL files verified → move from temp to SKILL_DIR:
- For each file: mkdir -p parent dir, then mv .skill-update-tmp/<file> SKILL_DIR/<file>
- rm -rf SKILL_DIR/.skill-update-tmp/
c. return {status: "updated", from: LOCAL_VERSION, to: manifest.version}
If manifest.version == LOCAL_VERSION:
d. return {status: "current"}
WHEN SUB-AGENT COMPLETES (main agent receives result):
- If status="updated": notify user "Skill updated from {from} to {to}. Using latest version." Re-read updated SKILL.md.
- If status="current" or status="error": silently continue with current version.
- Cache manifest (if returned) in session memory for module loading (see Module Router).
Rules:
- Check at most ONCE per session. Do not re-check during the same conversation.
- If any network request fails (timeout, 404, etc.), skip silently and proceed with current version. (See Graceful Degradation below for unified fallback rules.)
- Never block the user's first request. The sub-agent runs in the background; the main agent responds immediately. If a module is needed before the sub-agent finishes, use the current local version.
- If checksum algorithm prefix is not "sha256:", refuse the update (fail closed).
Quick Start
Step 1: Get an API Key
Pick one of the two paths below. The AI Subaccount path is strongly preferred — it's Bybit's purpose-built account type for AI trading, with built-in cap limits and a public-key-based key flow.
Path A — AI Subaccount (Recommended)
Bybit's official AI-trading account type (help article).
- Create it (Bybit mobile app): Profile icon → Settings → Subaccount → Create → enter a name → select AI Subaccount → Confirm + security verification.
- Get the API key (Public Key flow): after creation, Bybit asks for a Public Key. Run your AI assistant and ask it to generate one (Claude Code, Open Claw, Cursor, etc. all support this); paste the public key into Bybit → it returns the API key + secret bound to that key. Configure them per Step 2 below.
- Built-in safety defaults: Cap Limit defaults to 5,000 USD (adjustable from main account → Subaccount → your AI Subaccount → More → Permissions). API key expires in 30 days; for permanent keys, IP whitelist, finer permission scoping, or higher rate limits, use the Bybit web platform instead of the app.
- Why prefer this: blast radius is bounded by the cap limit, permissions are managed centrally from the main account (Request Transfer In/Out, Move from Trading/Funding, Max Leverage, etc.), and the subaccount can be killed in one click if anything goes wrong.
Path B — Manual API Key (Fallback)
Use this only if AI Subaccount isn't available in your region or you need a non-AI key flow.
- Log in to Bybit → API Management → Create New Key (do this from inside a Standard sub-account if possible — never from the main account).
- Permissions: enable Read + Trade only (NEVER enable Withdraw for AI use).
- Bind your IP address (makes the key permanent; otherwise expires in 3 months).
- Fund the (sub-)account with only the amount you're willing to risk in one bad day.
Step 2: Configure Credentials
Credential setup depends on where the AI runs. Auto-detect the environment and follow the matching path:
Path A — Local CLI (Claude Code, Cursor, or any tool with shell access):
Copy-paste this into ~/.zshrc or ~/.bashrc:
export BYBIT_API_KEY="your_api_key"
export BYBIT_API_SECRET="your_secret_key"
export BYBIT_ENV="testnet"
Using an RSA API Key instead? (Self-generated: you uploaded a public key to Bybit and kept the private key locally.) Replace the BYBIT_API_SECRET line with:
export BYBIT_API_PRIVATE_KEY_PATH="/absolute/path/to/private.pem"
Everything else stays the same. Do NOT set both BYBIT_API_SECRET and BYBIT_API_PRIVATE_KEY_PATH — the skill will pick RSA if both are present, but it's clearer to keep only the one you actually use.
On first use, check if these environment variables exist. If they do, use them directly — do NOT ask the user to paste keys in the conversation. If they don't exist, guide the user to set them up:
- Tell the user: "For security, I recommend storing your API keys as environment variables instead of pasting them here."
- Provide the export commands above
- After the user has set them, verify with
echo $BYBIT_API_KEY | head -c5 (only show first 5 chars to confirm)
Path B — Self-hosted OpenClaw (user runs OpenClaw on their own machine/server):
Keys stay on the user's machine — same security level as Path A. Configure via .env file:
Paste into ~/.openclaw/.env (recommended) or ./.env in your working directory:
BYBIT_API_KEY=your_api_key
BYBIT_API_SECRET=your_secret_key
BYBIT_ENV=testnet
Using an RSA API Key instead? Replace the BYBIT_API_SECRET line with:
BYBIT_API_PRIVATE_KEY_PATH=/absolute/path/to/private.pem
Everything else stays the same. Only set one of BYBIT_API_SECRET or BYBIT_API_PRIVATE_KEY_PATH, not both.
Alternative: openclaw.json env block — { "env": { "vars": { "BYBIT_API_KEY": "...", "BYBIT_API_SECRET": "...", "BYBIT_ENV": "testnet" } } } (swap BYBIT_API_SECRET for BYBIT_API_PRIVATE_KEY_PATH if using RSA).
On first use, check if these environment variables exist. If they do, use them directly. If they don't, guide the user to create ~/.openclaw/.env with the variables above.
Path C — Cloud platforms (hosted OpenClaw, Claude.ai, ChatGPT, Gemini, and other hosted AI services):
These platforms have no secret store. Keys must be pasted in the conversation (sent to AI provider's servers).
On first use:
- Accept keys pasted in the conversation
- Warn once: "Your keys will be sent through this platform's servers. For safety, use a sub-account with limited balance and Read+Trade permissions only (no Withdraw)."
- Do NOT ask again in the same session
Path D — OAuth (one-click authorization):
For AI assistants with shell access (Claude Code, Cursor, OpenClaw, etc.), the OAuth flow lets users authorize their Bybit account with a single click — no manual key creation needed. This uses the oauth/ module bundled with this skill. Cloud agents (OpenClaw, remote servers) automatically use headless mode — the user pastes the authorization code from the popup instead of relying on a localhost callback.
⚠️ MANDATORY first step for Path D: load modules/oauth.md and execute its Bootstrap section. The OAuth executable (modules/oauth.js) is NOT delivered by auto-update — it is lazy-fetched from raw.github with a SHA256-pinned check inside oauth.md. Without running Bootstrap first, every node ... modules/oauth.js ... command below will fail with Cannot find module on fresh installs. Do NOT run the credential check below until Bootstrap reports success.
Once Bootstrap succeeds, check if the OAuth credential file exists and has a valid (non-expired) token:
node -e "console.log(require('<skill_dir>/modules/oauth.js').getCredentialPath())"
Read the file at that path. If it exists, created_at + expires_in > now, and ai-account is present → use ai-account.api_key and ai-account.api_secret as credentials. No further setup needed.
If the file is missing, expired, or incomplete → follow the full OAuth Authorization Flow section below.
Fallback (all platforms): If the user provides keys directly in the conversation, accept them but remind once about the more secure alternative for their platform.
Display rules (never show full credentials):
- API Key: show first 5 + last 4 characters (e.g.,
AbCdE...x1y2)
- Secret Key: show last 5 only (e.g.,
***...vWxYz)
- Code blocks (CRITICAL): NEVER include raw API Key or Secret Key values in generated code, scripts, or curl examples — even if the actual values are available in environment variables or session context. ALWAYS use
$BYBIT_API_KEY / $BYBIT_API_SECRET (or ${API_KEY} / ${SECRET_KEY}) as variable references. This applies to ALL output formats including bash, python, and JSON. Violation of this rule is a security incident.
Step 3: Verify Connection (auto-run on first use)
After credentials are configured, automatically run these checks:
0. Determine sign type (no network call):
If $BYBIT_API_PRIVATE_KEY_PATH is set:
- Expand leading ~/ to absolute path
- If file exists, is readable, and its first line contains "PRIVATE KEY":
→ Select RSA (X-BAPI-SIGN-TYPE: 2) for all subsequent requests
- Else:
→ Halt. Tell user: "Private key path set but file unreadable: <path>"
Do NOT silently fall back to HMAC.
Else if $BYBIT_API_SECRET is set:
→ Select HMAC (X-BAPI-SIGN-TYPE: 1 or omitted)
Else if OAuth credential file exists (Path D) and ai-account is present:
- Check expiration: created_at + expires_in > now
- If expired: attempt refresh (load oauth module, see "OAuth: Refresh token" section)
- If refresh fails or no refresh_token: re-run OAuth flow
- Use ai-account.api_key as $BYBIT_API_KEY and ai-account.api_secret as $BYBIT_API_SECRET
→ Select HMAC (same as branch above)
Else:
→ Tell user:
"Please configure credentials first.
- Quickest: run the OAuth flow (say 'authorize Bybit' or see Path D)
- HMAC secret string: export BYBIT_API_SECRET=...
- RSA private key file: export BYBIT_API_PRIVATE_KEY_PATH=/path/to/private.pem
See Bybit API management for how to create keys."
Stop; do not attempt authenticated calls.
If both $BYBIT_API_PRIVATE_KEY_PATH and $BYBIT_API_SECRET are set,
prefer RSA and emit once:
"Both BYBIT_API_SECRET and BYBIT_API_PRIVATE_KEY_PATH are set. Using RSA.
To force HMAC, unset BYBIT_API_PRIVATE_KEY_PATH."
If RSA is selected and the 'openssl' CLI is not available, halt with:
"RSA signing requires the 'openssl' CLI. Install it or switch to HMAC."
GET /v5/market/time
GET /v5/account/wallet-balance?accountType=UNIFIED
Step 4: Choose Environment
Default: Mainnet. Always start in Mainnet mode unless the user explicitly requests Testnet.
| Mode | Base URL | Behavior |
|---|
| Mainnet (default) | https://api.bybit.com | Write operations require confirmation. Real funds. |
| Testnet | https://api-testnet.bybit.com | All operations execute freely. No real funds at risk. |
Switching rules:
- To switch to Testnet, the user must explicitly say "switch to testnet" / "use test account" / "use demo"
- When switching to Testnet, display: "Switching to TESTNET. All operations will use test funds — no real money at risk."
- To switch back to Mainnet, the user must explicitly request it. Display a confirmation prompt: "You are switching back to MAINNET. All subsequent write operations will use real funds. Type CONFIRM to proceed." Wait for CONFIRM before switching.
- Always show the current environment in every response that involves API calls:
[MAINNET] or [TESTNET]
- If the user provides a Testnet API Key (starts with testing), automatically use Testnet URL
Step 5: Start Trading
Tell the user what they can do. Examples:
- "What's the BTC price?"
- "Buy 500 USDT worth of BTC"
- "Open a 10x BTC long position"
- "Check my balance"
Module Router
This skill uses modular on-demand loading. When the user's request matches a module below, fetch the corresponding file ONCE per session per module, then use it for all subsequent requests in that category.
How to load a module
1. Identify which module(s) the user's request needs from the table below
2. If the module has NOT been loaded in this session:
a. Ensure manifest is available:
- If cached from Auto Update: reuse it
- Otherwise: MANIFEST = curl -sf -H "User-Agent: bybit-skill/1.6.1" https://api.bybit.com/skill/manifest
- If fetch fails: use current local version of the module (SKILL_DIR/modules/<module>.md)
If no local version exists: inform user module unavailable, only GET operations permitted
- Cache manifest in session