
Binance Account
- 41 installs
- 21 repo stars
- Updated August 3, 2026
- starchild-ai-agent/official-skills
Helps with ai & agent building tasks during AI-assisted development.
About
binance-account is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- binance-account
- AI & Agent Building
- AI-coding skill
Binance Account by the numbers
- 41 all-time installs (skills.sh)
- +5 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #8,142 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/starchild-ai-agent/official-skills --skill binance-accountAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 41 |
|---|---|
| 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
Binance Account (Read-Only)
Read-only Binance account tracker built on the widely used python-binance library. Use it for account tracking, daily/weekly reports, risk alerts, and cashflow attribution.
How to Get a Binance API Key (Read-Only)
1. Sign in at binance.com, top-right avatar → API Management
- Direct link: https://www.binance.com/en/my/settings/api-management
2. Create API → System generated 3. Complete 2FA verification (email + Authenticator / SMS) 4. Name the key → submit 5. Copy API Key + Secret Key immediately (Secret is shown only once) 6. Edit restrictions:
- ✅ Enable only
Enable Reading - ❌ Disable trading, withdrawal, and all write permissions
- Leave the IP whitelist empty (binding an IP causes cloud calls to be rejected)
7. Set the values into this skill's environment variables
Reference: Binance official tutorial
Prerequisites
1) API key permissions
In Binance API Management, create a read-only key. Enable only:
- ✅ Enable Reading
- ❌ Disable trading and withdrawal
2) Environment variables
BINANCE_RO_API_KEY=...
BINANCE_RO_SECRET=...3) Geo restriction (required)
Binance frequently returns 451 Restricted Location from server environments. This skill defaults to the SC internal HK proxy:
HK_PROXY = "http://hk:x@sc-vpn.internal:8080"Do not set a global HTTP_PROXY — it would break routing for other services.
Scripts
Base query script
python3 skills/binance-account/scripts/bn_account.py <action> [options]Scenario script
python3 skills/binance-account/scripts/account_scenarios.py <scenario> [options]Actions
summary: one-shot summaryspot_balance/futures_balance/futures_positionsspot_orders/futures_orders/spot_trades/futures_tradesdeposits/withdrawals/funding_income/account_snapshot
Scenarios
portfolio_snapshot: full account snapshotperp_risk: futures risk monitoring (margin ratio + unrealized loss)cashflow: deposits + withdrawals + funding income aggregationtrading_activity: recent trades by symbol
Common usage
python3 skills/binance-account/scripts/bn_account.py summary
python3 skills/binance-account/scripts/account_scenarios.py portfolio_snapshot
python3 skills/binance-account/scripts/account_scenarios.py perp_risk --loss-threshold 5000
python3 skills/binance-account/scripts/account_scenarios.py cashflow
python3 skills/binance-account/scripts/account_scenarios.py trading_activity --symbol BTCUSDTNotes
- IP whitelist is best left empty for cloud usage.
- Use time-windowed pagination for high-frequency trade pulls.
#!/usr/bin/env python3
"""
Common Binance 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
from binance.client import Client
load_dotenv('/data/workspace/.env')
HK_PROXY = 'http://hk:x@sc-vpn.internal:8080'
def get_client():
return Client(
api_key=os.environ.get('BINANCE_RO_API_KEY', ''),
api_secret=os.environ.get('BINANCE_RO_SECRET', ''),
requests_params={'proxies': {'https': HK_PROXY, 'http': HK_PROXY}}
)
def print_json(data):
print(json.dumps(data, ensure_ascii=False, indent=2))
def scenario_portfolio_snapshot(args):
"""Scenario 1: full portfolio snapshot (spot+futures)"""
c = get_client()
spot = c.get_account()
futures = c.futures_account()
balances = [b for b in spot['balances'] if float(b['free']) + float(b['locked']) > 1e-9]
positions = [p for p in futures.get('positions', []) if float(p['positionAmt']) != 0]
out = {
'scenario': 'portfolio_snapshot',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'spot_nonzero_assets': len(balances),
'spot_balances': balances,
'futures': {
'totalWalletBalance': futures.get('totalWalletBalance'),
'totalUnrealizedProfit': futures.get('totalUnrealizedProfit'),
'availableBalance': futures.get('availableBalance'),
'positions': positions,
}
}
print_json(out)
def scenario_futures_risk(args):
"""Scenario 2: futures risk monitoring"""
c = get_client()
f = c.futures_account()
positions = [p for p in f.get('positions', []) if float(p['positionAmt']) != 0]
# basic risk indicators from account-level fields
wallet = float(f.get('totalWalletBalance', 0) or 0)
unreal = float(f.get('totalUnrealizedProfit', 0) or 0)
margin = float(f.get('totalMarginBalance', 0) or 0)
maint = float(f.get('totalMaintMargin', 0) or 0)
ratio = (maint / margin) if margin > 0 else 0
out = {
'scenario': 'futures_risk',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'account': {
'totalWalletBalance': wallet,
'totalUnrealizedProfit': unreal,
'totalMarginBalance': margin,
'totalMaintMargin': maint,
'maint_margin_ratio': ratio,
},
'open_positions': positions,
'alerts': {
'maint_margin_ratio_gt_0_6': ratio > 0.6,
'unrealized_loss_gt_threshold': unreal < -abs(float(args.loss_threshold)),
}
}
print_json(out)
def scenario_cashflow(args):
"""Scenario 3: deposit/withdraw/transfer/funding cashflow"""
c = get_client()
def safe_call(fn, *a, **kw):
try:
return fn(*a, **kw), None
except Exception as e:
return None, str(e)
dep, dep_err = safe_call(c.get_deposit_history, limit=args.limit)
wd, wd_err = safe_call(c.get_withdraw_history, limit=args.limit)
inc, inc_err = safe_call(c.futures_income_history, limit=args.limit)
# transfer history: read-only keys often cannot call futures_account_transfer
# fallback to new_transfer_history (works with MAIN_UMFUTURE type on this account)
tr = []
transfer_errors = []
r, e = safe_call(c.futures_account_transfer, limit=args.limit)
if e:
transfer_errors.append({'endpoint': 'futures_account_transfer', 'error': e})
elif r:
tr.extend(r if isinstance(r, list) else [r])
for t in ['MAIN_UMFUTURE', 'MAIN_MARGIN', 'UMFUTURE_MAIN']:
r, e = safe_call(c.new_transfer_history, type=t, limit=args.limit)
if e:
transfer_errors.append({'endpoint': f'new_transfer_history({t})', 'error': e})
continue
if isinstance(r, dict) and 'rows' in r:
tr.extend(r.get('rows', []))
elif isinstance(r, list):
tr.extend(r)
# summarize income by type
by_type = defaultdict(float)
for x in (inc or []):
t = x.get('incomeType', 'UNKNOWN')
by_type[t] += float(x.get('income', 0) or 0)
out = {
'scenario': 'cashflow',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'deposit_count': len(dep or []),
'withdraw_count': len(wd or []),
'futures_transfer_count': len(tr),
'futures_income_count': len(inc or []),
'futures_income_by_type': dict(sorted(by_type.items(), key=lambda kv: -abs(kv[1]))),
'deposits': dep or [],
'withdraws': wd or [],
'transfers': tr,
'futures_income': inc or [],
'errors': {
'deposit_error': dep_err,
'withdraw_error': wd_err,
'income_error': inc_err,
'transfer_errors': transfer_errors,
}
}
print_json(out)
def scenario_trading_activity(args):
"""Scenario 4: spot trading activity by symbol in lookback window"""
c = get_client()
# user provides comma-separated symbols, default core symbols
symbols = [s.strip().upper() for s in (args.symbols or 'BTCUSDT,ETHUSDT,PAXGUSDT,DODOUSDT').split(',') if s.strip()]
start_ms = int((datetime.now(timezone.utc).timestamp() - args.days * 86400) * 1000)
rows = []
for sym in symbols:
try:
trades = c.get_my_trades(symbol=sym, startTime=start_ms, limit=1000)
except Exception as e:
rows.append({'symbol': sym, 'error': str(e)[:120]})
continue
buy_qty = sum(float(t['qty']) for t in trades if t['isBuyer'])
buy_quote = sum(float(t['quoteQty']) for t in trades if t['isBuyer'])
sell_qty = sum(float(t['qty']) for t in trades if not t['isBuyer'])
sell_quote = sum(float(t['quoteQty']) for t in trades if not t['isBuyer'])
rows.append({
'symbol': sym,
'trades': len(trades),
'buy_qty': buy_qty,
'buy_quote': buy_quote,
'sell_qty': sell_qty,
'sell_quote': sell_quote,
'net_qty': buy_qty - sell_qty,
})
out = {
'scenario': 'trading_activity',
'timestamp_utc': datetime.now(timezone.utc).isoformat(),
'days': args.days,
'rows': rows,
}
print_json(out)
SCENARIOS = {
'portfolio_snapshot': scenario_portfolio_snapshot,
'futures_risk': scenario_futures_risk,
'cashflow': scenario_cashflow,
'trading_activity': scenario_trading_activity,
}
if __name__ == '__main__':
p = argparse.ArgumentParser(description='Binance account analysis scenarios (read-only)')
p.add_argument('scenario', choices=SCENARIOS.keys())
p.add_argument('--limit', type=int, default=100, help='records per API for cashflow scenario')
p.add_argument('--days', type=int, default=30, help='lookback days for trading_activity scenario')
p.add_argument('--symbols', default='', help='comma-separated symbols for trading_activity')
p.add_argument('--loss-threshold', type=float, default=5000.0, help='loss threshold for futures_risk alert')
args = p.parse_args()
SCENARIOS[args.scenario](args)
#!/usr/bin/env python3
"""
Binance Read-Only Account Query Tool
Uses python-binance (official community library) with HK VPN proxy.
Supports Spot + USDM Futures.
"""
import os, sys, json, argparse
from dotenv import load_dotenv
load_dotenv("/data/workspace/.env")
from binance.client import Client
HK_PROXY = "http://hk:x@sc-vpn.internal:8080"
def get_client():
key = os.environ.get("BINANCE_RO_API_KEY", "")
secret = os.environ.get("BINANCE_RO_SECRET", "")
c = Client(api_key=key, api_secret=secret,
requests_params={"proxies": {"https": HK_PROXY, "http": HK_PROXY}})
return c
def fmt(data):
print(json.dumps(data, ensure_ascii=False, indent=2))
# ── Actions ────────────────────────────────────────────────────────────────────
def spot_balance(args):
"""现货账户余额(过滤零余额)"""
c = get_client()
info = c.get_account()
balances = [
b for b in info["balances"]
if float(b["free"]) + float(b["locked"]) > 0.000001
]
fmt({
"canTrade": info["canTrade"],
"canWithdraw": info["canWithdraw"],
"makerCommission": info["makerCommission"],
"takerCommission": info["takerCommission"],
"balances": sorted(balances, key=lambda x: -float(x["free"]))
})
def futures_balance(args):
"""U本位合约账户余额"""
c = get_client()
data = c.futures_account_balance()
data = [b for b in data if float(b.get("balance", 0)) != 0]
fmt(data)
def futures_account(args):
"""U本位合约完整账户(保证金、盈亏、持仓)"""
c = get_client()
info = c.futures_account()
positions = [p for p in info.get("positions", []) if float(p["positionAmt"]) != 0]
fmt({
"totalWalletBalance": info.get("totalWalletBalance"),
"totalUnrealizedProfit": info.get("totalUnrealizedProfit"),
"totalMarginBalance": info.get("totalMarginBalance"),
"availableBalance": info.get("availableBalance"),
"totalPositionInitialMargin": info.get("totalPositionInitialMargin"),
"canTrade": info.get("canTrade"),
"positions": positions,
})
def futures_positions(args):
"""当前合约持仓(仅持有中)"""
c = get_client()
data = c.futures_position_information()
open_pos = [p for p in data if float(p["positionAmt"]) != 0]
fmt(open_pos)
def spot_orders(args):
"""现货当前挂单"""
c = get_client()
sym = args.symbol.upper() if args.symbol else None
orders = c.get_open_orders(symbol=sym) if sym else c.get_open_orders()
fmt(orders)
def spot_order_history(args):
"""现货历史订单"""
c = get_client()
sym = (args.symbol or "BTCUSDT").upper()
kwargs = {"symbol": sym, "limit": args.limit or 50}
fmt(c.get_all_orders(**kwargs))
def futures_orders(args):
"""合约当前挂单"""
c = get_client()
sym = args.symbol.upper() if args.symbol else None
orders = c.futures_get_open_orders(symbol=sym) if sym else c.futures_get_open_orders()
fmt(orders)
def trade_history(args):
"""现货成交记录"""
c = get_client()
sym = (args.symbol or "BTCUSDT").upper()
fmt(c.get_my_trades(symbol=sym, limit=args.limit or 50))
def futures_trade_history(args):
"""合约成交记录"""
c = get_client()
sym = (args.symbol or "BTCUSDT").upper()
fmt(c.futures_account_trades(symbol=sym, limit=args.limit or 50))
def deposit_history(args):
"""充值记录"""
c = get_client()
kwargs = {}
if args.asset:
kwargs["coin"] = args.asset.upper()
fmt(c.get_deposit_history(**kwargs))
def withdraw_history(args):
"""提币记录"""
c = get_client()
kwargs = {}
if args.asset:
kwargs["coin"] = args.asset.upper()
fmt(c.get_withdraw_history(**kwargs))
def income_history(args):
"""合约收入流水(资金费、手续费返还等)"""
c = get_client()
kwargs = {"limit": args.limit or 100}
if args.symbol:
kwargs["symbol"] = args.symbol.upper()
if args.income_type:
kwargs["incomeType"] = args.income_type
fmt(c.futures_income_history(**kwargs))
def asset_snapshot(args):
"""账户快照(SPOT / MARGIN / FUTURES)"""
c = get_client()
account_type = (args.type or "SPOT").upper()
fmt(c.get_account_snapshot(type=account_type, limit=7))
def funding_rate(args):
"""当前资金费率"""
c = get_client()
kwargs = {}
if args.symbol:
kwargs["symbol"] = args.symbol.upper()
fmt(c.futures_mark_price(**kwargs))
def summary(args):
"""一键汇总:现货余额 + 合约账户概览 + 持仓"""
c = get_client()
# Spot
info = c.get_account()
spot_balances = [
b for b in info["balances"]
if float(b["free"]) + float(b["locked"]) > 0.000001
]
# Futures
fa = c.futures_account()
positions = [p for p in fa.get("positions", []) if float(p["positionAmt"]) != 0]
fmt({
"spot": {
"balances": sorted(spot_balances, key=lambda x: -float(x["free"])),
},
"futures": {
"totalWalletBalance": fa.get("totalWalletBalance"),
"totalUnrealizedProfit": fa.get("totalUnrealizedProfit"),
"availableBalance": fa.get("availableBalance"),
"openPositions": positions,
},
})
# ── CLI ────────────────────────────────────────────────────────────────────────
ACTIONS = {
"spot_balance": spot_balance,
"futures_balance": futures_balance,
"futures_account": futures_account,
"futures_positions": futures_positions,
"spot_orders": spot_orders,
"spot_order_history": spot_order_history,
"futures_orders": futures_orders,
"trade_history": trade_history,
"futures_trade_history": futures_trade_history,
"deposit_history": deposit_history,
"withdraw_history": withdraw_history,
"income_history": income_history,
"asset_snapshot": asset_snapshot,
"funding_rate": funding_rate,
"summary": summary,
}
if __name__ == "__main__":
p = argparse.ArgumentParser(description="Binance Read-Only Account Tool")
p.add_argument("action", choices=ACTIONS.keys())
p.add_argument("--symbol", default=None)
p.add_argument("--asset", default=None)
p.add_argument("--limit", type=int, default=None)
p.add_argument("--type", default=None, help="SPOT/MARGIN/FUTURES for snapshot")
p.add_argument("--income_type", default=None, help="e.g. FUNDING_FEE")
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)