
Okx Account
- 33 installs
- 21 repo stars
- Updated August 3, 2026
- starchild-ai-agent/official-skills
Helps with ai & agent building tasks during AI-assisted development.
About
okx-account is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- okx-account
- AI & Agent Building
- AI-coding skill
Okx Account by the numbers
- 33 all-time installs (skills.sh)
- +1 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #8,944 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/starchild-ai-agent/official-skills --skill okx-accountAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 33 |
|---|---|
| repo stars | ★ 21 |
| Last updated | August 3, 2026 |
| Repository | starchild-ai-agent/official-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
OKX Account (Read-Only)
Read-only OKX account tracker built on the official python-okx library. Use it for account tracking, daily/weekly reports, risk alerts, and cashflow attribution.
How to Get an OKX API Key (Read-Only)
1. Sign in at okx.com, top-right avatar → API
- Direct link: https://www.okx.com/account/my-api
2. Create V5 API Key → complete 2FA verification 3. Fill the form:
- API name: anything
- Passphrase: ⚠️ a brand-new password used to sign API requests, NOT your login password. Lose it and you can only delete the key and create a new one.
- Permissions: tick Read only, leave Trade / Withdraw off
- IP whitelist: leave empty
4. Submit → immediately copy and save all three values: API Key / Secret Key / Passphrase (Secret is shown only once) 5. Set them into this skill's environment variables
Reference: OKX official tutorial
Prerequisites
1) API key
In OKX API Management create a key with Read only. OKX requires three credentials: api_key / secret / passphrase (the password you set when creating the key — not the login password).
2) Environment variables
OKX_RO_API_KEY=...
OKX_RO_SECRET=...
OKX_RO_PASSPHRASE=...3) Geo restriction (required)
OKX geo-blocks server IPs. Scripts default to the SC internal HK proxy:
HK_PROXY = "http://hk:x@sc-vpn.internal:8080"Do not set a global HTTP_PROXY.
Scripts
python3 skills/okx-account/scripts/okx_account.py <action> [options]
python3 skills/okx-account/scripts/account_scenarios.py <scenario> [options]Actions
summary: one-shot summaryaccount_balance/account_config/positions/position_risk/fee_rates/billsopen_orders/order_history/fills_historyfunding_balance/deposits/withdrawals/currencies/funding_rate
Scenarios
portfolio_snapshot: full account snapshotperp_risk: perpetual risk monitoring (margin ratio + unrealized loss thresholds)cashflow: deposits + withdrawals + 7d bills aggregationtrading_activity: recent fills activity by instType
Common usage
python3 skills/okx-account/scripts/okx_account.py summary
python3 skills/okx-account/scripts/account_scenarios.py portfolio_snapshot
python3 skills/okx-account/scripts/account_scenarios.py perp_risk --loss-threshold 5000
python3 skills/okx-account/scripts/account_scenarios.py cashflow --limit 100
python3 skills/okx-account/scripts/account_scenarios.py trading_activity --inst-types SPOT,SWAPNotes
- The
passphraseis easy to forget — it is the password you set when creating the key, not your login password. - If you bound an IP whitelist when creating the key, either disable it or add the proxy egress IP.
- Use time-windowed pagination for high-volume fills.
#!/usr/bin/env python3
"""
Common OKX account analysis scenarios (read-only).
Generates structured JSON for tracking/reporting/alerts.
"""
import os, json, argparse
from datetime import datetime, timezone
from collections import defaultdict
from dotenv import load_dotenv
load_dotenv('/data/workspace/.env')
import okx.Account as Account
import okx.Trade as Trade
import okx.Funding as Funding
HK_PROXY = 'http://hk:x@sc-vpn.internal:8080'
def _creds():
return dict(
api_key=os.environ.get('OKX_RO_API_KEY', ''),
api_secret_key=os.environ.get('OKX_RO_SECRET', ''),
passphrase=os.environ.get('OKX_RO_PASSPHRASE', ''),
flag='0', proxy=HK_PROXY)
def print_json(d): print(json.dumps(d, ensure_ascii=False, indent=2))
def scenario_portfolio_snapshot(args):
"""Scenario 1: full portfolio snapshot (unified + funding + positions)"""
a = Account.AccountAPI(**_creds())
f = Funding.FundingAPI(**_creds())
bal = a.get_account_balance()
fb = f.get_balances()
pos = a.get_positions()
bdata = bal['data'][0] if bal.get('code') == '0' else {}
details = [d for d in bdata.get('details', []) if float(d.get('eq', 0) or 0) > 1e-9]
fb_rows = [x for x in fb.get('data', []) if float(x.get('bal', 0) or 0) > 1e-9]
open_pos = [p for p in pos.get('data', []) if float(p.get('pos', 0) or 0) != 0]
out = {
'scenario': 'portfolio_snapshot',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'unified': {
'totalEq': bdata.get('totalEq'),
'adjEq': bdata.get('adjEq'),
'mgnRatio': bdata.get('mgnRatio'),
'nonzero_assets': len(details),
'details': sorted(details, key=lambda x: -float(x.get('eqUsd', 0) or 0)),
},
'funding': {
'nonzero_assets': len(fb_rows),
'balances': fb_rows,
},
'open_positions_count': len(open_pos),
'open_positions': open_pos,
}
print_json(out)
def scenario_perp_risk(args):
"""Scenario 2: perpetual/futures risk monitoring"""
a = Account.AccountAPI(**_creds())
pos = a.get_positions(instType='SWAP')
risk = a.get_position_risk()
bal = a.get_account_balance()
bdata = bal['data'][0] if bal.get('code') == '0' else {}
mgn_ratio = float(bdata.get('mgnRatio', 0) or 0) if bdata.get('mgnRatio') else None
upl = sum(float(p.get('upl', 0) or 0) for p in pos.get('data', []))
out = {
'scenario': 'perp_risk',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'account_mgn_ratio': mgn_ratio,
'total_unrealized_pnl_usdt': upl,
'risk_alert': {
'mgn_ratio_below_3': (mgn_ratio is not None and 0 < mgn_ratio < 3),
'unrealized_loss_gt_threshold': upl < -abs(float(args.loss_threshold)),
},
'positions': [p for p in pos.get('data', []) if float(p.get('pos', 0) or 0) != 0],
'risk_detail': risk.get('data', []),
}
print_json(out)
def scenario_cashflow(args):
"""Scenario 3: deposits/withdrawals + recent bills (cashflow)"""
f = Funding.FundingAPI(**_creds())
a = Account.AccountAPI(**_creds())
dep = f.get_deposit_history()
wd = f.get_withdrawal_history()
bills = a.get_account_bills()
deps = dep.get('data', [])
wds = wd.get('data', [])
bs = bills.get('data', [])
by_subtype = defaultdict(lambda: {'count': 0, 'sum': 0.0})
for b in bs:
st = b.get('subType', 'UNKNOWN')
by_subtype[st]['count'] += 1
try:
by_subtype[st]['sum'] += float(b.get('balChg', 0) or 0)
except (TypeError, ValueError):
pass
out = {
'scenario': 'cashflow',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'deposit_count': len(deps),
'withdraw_count': len(wds),
'bills_count_7d': len(bs),
'bills_by_subtype': dict(by_subtype),
'deposits': deps[:args.limit],
'withdraws': wds[:args.limit],
}
print_json(out)
def scenario_trading_activity(args):
"""Scenario 4: recent fills activity by instrument type"""
t = Trade.TradeAPI(**_creds())
out_rows = []
for inst in [s.strip().upper() for s in (args.inst_types or 'SPOT,SWAP').split(',') if s.strip()]:
try:
r = t.get_fills_history(instType=inst)
fills = r.get('data', [])
except Exception as e:
out_rows.append({'instType': inst, 'error': str(e)[:120]})
continue
by_sym = defaultdict(lambda: {'count': 0, 'buy_qty': 0.0, 'sell_qty': 0.0, 'buy_quote': 0.0, 'sell_quote': 0.0})
for f in fills:
sym = f.get('instId')
qty = float(f.get('fillSz', 0) or 0)
px = float(f.get('fillPx', 0) or 0)
quote = qty * px
by_sym[sym]['count'] += 1
if f.get('side') == 'buy':
by_sym[sym]['buy_qty'] += qty
by_sym[sym]['buy_quote'] += quote
else:
by_sym[sym]['sell_qty'] += qty
by_sym[sym]['sell_quote'] += quote
out_rows.append({
'instType': inst,
'fills_total': len(fills),
'symbols': dict(by_sym),
})
out = {
'scenario': 'trading_activity',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'rows': out_rows,
}
print_json(out)
SCENARIOS = {
'portfolio_snapshot': scenario_portfolio_snapshot,
'perp_risk': scenario_perp_risk,
'cashflow': scenario_cashflow,
'trading_activity': scenario_trading_activity,
}
if __name__ == '__main__':
p = argparse.ArgumentParser(description='OKX account analysis scenarios (read-only)')
p.add_argument('scenario', choices=SCENARIOS.keys())
p.add_argument('--limit', type=int, default=100)
p.add_argument('--loss-threshold', type=float, default=5000.0)
p.add_argument('--inst-types', default='', help='comma-separated, e.g. SPOT,SWAP,FUTURES')
args = p.parse_args()
SCENARIOS[args.scenario](args)
#!/usr/bin/env python3
"""
OKX Read-Only Account Query Tool
Uses official python-okx library with HK VPN proxy.
Supports unified account: spot/margin/swap/futures/options.
"""
import os, sys, json, argparse
from dotenv import load_dotenv
load_dotenv("/data/workspace/.env")
import okx.Account as Account
import okx.Trade as Trade
import okx.Funding as Funding
import okx.PublicData as PublicData
HK_PROXY = "http://hk:x@sc-vpn.internal:8080"
def _creds():
return dict(
api_key=os.environ.get("OKX_RO_API_KEY", ""),
api_secret_key=os.environ.get("OKX_RO_SECRET", ""),
passphrase=os.environ.get("OKX_RO_PASSPHRASE", ""),
flag="0",
proxy=HK_PROXY,
)
def acct(): return Account.AccountAPI(**_creds())
def trade(): return Trade.TradeAPI(**_creds())
def fund(): return Funding.FundingAPI(**_creds())
def public(): return PublicData.PublicAPI(flag="0", proxy=HK_PROXY)
def fmt(d): print(json.dumps(d, ensure_ascii=False, indent=2))
# ── Actions ────────────────────────────────────────────────────────────────────
def account_balance(args):
"""统一账户余额(含权益/可用/已用保证金,所有币种)"""
r = acct().get_account_balance(ccy=(args.asset or '').upper())
fmt(r)
def account_config(args):
"""账户配置(账户模式、杠杆、是否多仓位等)"""
fmt(acct().get_account_config())
def positions(args):
"""合约/期权持仓"""
fmt(acct().get_positions(instType=(args.inst_type or '').upper()))
def position_risk(args):
"""持仓总风险(统一账户视角的风险率)"""
fmt(acct().get_position_risk())
def fee_rates(args):
"""当前手续费率(按 instType)"""
fmt(acct().get_fee_rates(instType=(args.inst_type or 'SPOT').upper()))
def bills(args):
"""近 7 天账单(资金变动流水)"""
fmt(acct().get_account_bills())
def open_orders(args):
"""当前挂单"""
fmt(trade().get_order_list(instType=(args.inst_type or '').upper()))
def order_history(args):
"""历史订单(默认 SPOT,最近 7 天)"""
fmt(trade().get_orders_history(instType=(args.inst_type or 'SPOT').upper()))
def fills_history(args):
"""成交明细(默认 SPOT,最近 3 个月)"""
fmt(trade().get_fills_history(instType=(args.inst_type or 'SPOT').upper()))
def funding_balance(args):
"""资金账户余额(与统一账户分开)"""
r = fund().get_balances(ccy=(args.asset or '').upper())
fmt(r)
def deposits(args):
"""充值记录"""
fmt(fund().get_deposit_history())
def withdrawals(args):
"""提币记录"""
fmt(fund().get_withdrawal_history())
def currencies(args):
"""所有支持币种 / 链信息"""
fmt(fund().get_currencies(ccy=(args.asset or '').upper()))
def funding_rate(args):
"""合约资金费率(默认 SWAP)"""
inst = (args.symbol or 'BTC-USDT-SWAP').upper()
fmt(public().get_funding_rate(instId=inst))
def summary(args):
"""一键汇总:统一账户 + 资金账户 + 当前持仓 + 当前挂单"""
a = acct()
f = fund()
t = trade()
bal = a.get_account_balance()
fb = f.get_balances()
pos = a.get_positions()
orders = t.get_order_list()
if bal.get('code') == '0':
bdata = bal['data'][0]
details = [d for d in bdata.get('details', []) if float(d.get('eq', 0) or 0) > 1e-9]
bsum = {
'totalEq': bdata.get('totalEq'),
'isoEq': bdata.get('isoEq'),
'adjEq': bdata.get('adjEq'),
'mgnRatio': bdata.get('mgnRatio'),
'details_nonzero': sorted(details, key=lambda x: -float(x.get('eqUsd', 0) or 0)),
}
else:
bsum = bal
if fb.get('code') == '0':
fb_nonzero = [x for x in fb['data'] if float(x.get('bal', 0) or 0) > 1e-9]
else:
fb_nonzero = []
out = {
'unified_account': bsum,
'funding_account_nonzero': fb_nonzero,
'open_positions': [p for p in pos.get('data', []) if float(p.get('pos', 0) or 0) != 0],
'open_orders': orders.get('data', []),
}
fmt(out)
ACTIONS = {
'summary': summary,
'account_balance': account_balance,
'account_config': account_config,
'positions': positions,
'position_risk': position_risk,
'fee_rates': fee_rates,
'bills': bills,
'open_orders': open_orders,
'order_history': order_history,
'fills_history': fills_history,
'funding_balance': funding_balance,
'deposits': deposits,
'withdrawals': withdrawals,
'currencies': currencies,
'funding_rate': funding_rate,
}
if __name__ == "__main__":
p = argparse.ArgumentParser(description='OKX Read-Only Account Tool')
p.add_argument('action', choices=ACTIONS.keys())
p.add_argument('--asset', default=None, help='Coin filter, e.g. USDT, BTC')
p.add_argument('--inst-type', default=None, dest='inst_type', help='SPOT/MARGIN/SWAP/FUTURES/OPTION')
p.add_argument('--symbol', default=None, help='Instrument id, e.g. BTC-USDT-SWAP')
args = p.parse_args()
try:
ACTIONS[args.action](args)
except Exception as e:
print(json.dumps({'error': str(e)}, ensure_ascii=False))
sys.exit(1)