Files
mike b660debd06 v2026-07-21: 实战教训汇总 (push 11 文件)
新增 8 reference:
  - dividend-stability-score: A 股 5 维评分 (派息年数/CAGR/波动/最近/连续) → 0-100 分 + 5 星
  - dividend-yield-rate-sort: 按股息率% 倒序 (用户偏好 2026-07-13)
  - longport-http-module: longport_http.py 公共模块 (替代 SDK WSS)
  - leverage-pass-through-bug: process_signal.py 丢失 leverage 字段 (5x 实际 10x)
  - follow-trading-iron-laws: 跟单铁律 (用户原话 5+ 次 2026-07-21)
  - forced-skill-entry-okx-trade: okx_trade.sh 强制入口 (替代 ccxt 裸调)
  - mihomo-clash-node-supplier-dns: Clash 节点供应商 DNS 失败处理
  - mihomo-ssl-reconnect-pattern: mihomo 反复 SSL/Timeout 模式
  - v4.5.44-mu-add-to-75pct-cap: MU 加仓 75% 单币种 cap 标准流程

改 2 SKILL.md:
  - dividend-investing: 加 5 维评分 + 长桥 http 模块
  - longbridge-cli: 标注 '不要写 openapi.QuoteContext' + 迁移说明
2026-07-22 13:22:45 +08:00

40 KiB
Raw Permalink Blame History

name, description
name description
longbridge-cli LongPort OpenAPI CLI for market data, account management, orders, and trading/dividend analysis workflows.

LongBridge CLI (longbridge)

A specialized skill for interacting with the LongPort OpenAPI via the longbridge CLI. This skill handles market data (quotes, candlesticks), account info, and order management.

⚠️ Mainland China Access (602315) — PARTIAL workaround (CLI only)

2026-07-21 决策(实测): 所有 cron 跑的 stock 脚本都改用 longport_http.py 模块(CLI 走 proxychains 替代 Python SDK WSS)。详见 references/longport-http-module.md:

  • WSS 在国内 VPS + mihomo 代理下永远失败 (request timeout / Connect error)
  • CLI HTTP 走 mihomo 代理能通
  • ~/.hermes/scripts/longport_http.py 提供 get_quote / get_quotes / get_positions / submit_order 4 个函数
  • 5 次连续运行 4-5s 稳定
  • 已迁移: dividend_alert.py, dca_monitor.py
  • 待迁移: stock_t.py, daily_t_analysis.py, dca_scanner.py 等 14+ 脚本

不要写新的 openapi.QuoteContext 代码 — 必挂

LongPort API rejects trading requests from mainland China IPs with error 602315 — server-side IP check, not domain-routing. The 602315 block is enforced at the API gateway based on source IP, not based on which endpoint domain you connect to.

  • CLI orders (manual): three-piece recipe works as of 2026-07-09. Order ID 1259547163696824320 (RGTI 15@$15.50) succeeded via LONGBRIDGE_REGION=ap + proxychains4 + Clash HK node + --profile lb_real.
  • Python SDK orders (cron-driven): still get 602315 even with the full recipe. The Python SDK hardcodes openapi.longportapp.cn endpoints that resolve to CN-hosted Aliyun IPs; the *.com versions are unreachable from every Clash node we tested (AWS blocks egress from those ASNs).
  • Phone app (HK proxy): confirmed working by user.
  • WireGuard: BANNED for this account. Do not propose.

For automated trading today, disable auto-execution in the Python monitor scripts and place orders manually via the CLI recipe or phone app. Full diagnosis, what was tried, why it fails for SDK, and the cron-wrapper pattern in references/longbridge-602315-bypass.md (must read before any order operation from CN).

For token-refresh and account-level concerns separate from geo-block, see references/token-refresh.md.

For token credentials via --profile <name> env-file (bypasses terminal secret-masking), see references/longbridge-602315-bypass.md → Profile setup.

For Clash node-switching API recipe (used to set HK node for the bypass), see references/clash-node-switching.md.

For why the earlier /etc/hosts redirect was deprecated (SSL SNI mismatch, system-wide impact), see references/longbridge-cn-vs-com-endpoint.md.

For paper-trading / virtual portfolio using longbridge CLI for prices + simulated SL/TP checkpoints (zero-risk validation of a strategy before going live, no real money), see references/paper-trading-cli-based.md. Companion script at ~/.hermes/skills/trading/quant-factor-mining/scripts/intraday_entry_test.py --paper. Complements okx_t_monitor.py (which handles OKX real-money trades).

Transport Options

LongPort can be accessed three ways — choose the one that fits:

Transport When to use
CLI (longbridge) Quick terminal queries, simple scripts (this skill)
Python SDK (longport) Complex analysis, automated trading, batch workflows (see longbridge-python-sdk skill)
MCP (native Hermes) AI-agent-first access — tools auto-discover in Hermes (see references/longport-mcp-integration.md)

For the MCP transport, LongPort uses a two-endpoint architecture: an auth endpoint (/agent) to exchange an auth code for a Bearer token, then the main MCP service at https://mcp.longport.cn. Full flow documented in the reference below.

Usage

All commands should be run with the appropriate environment variables (LONGBRIDGE_APP_KEY, LONGBRIDGE_APP_SECRET, LONGBRIDGE_ACCESS_TOKEN) loaded.

Common Commands

  • Quotes: longbridge quote --json <SYMBOLS> (Get real-time quotes)
  • Candlesticks: longbridge candlesticks --json <SYMBOLS> (Get OHLC data)
  • Account: longbridge balance --json or longbridge positions --json
  • Orders: longbridge orders --json (Today's orders) or longbridge buy/sell --json <SYMBOLS> <QUANTITY>

Order Placement (做T / Active Trading)

CLI order commands require --price for limit orders and -y to skip interactive confirmation (essential for automation):

# Limit buy
longbridge buy RGTI.US --qty 30 --price 18.50 -y

# Limit sell
longbridge sell RGTI.US --qty 30 --price 20.50 -y

# Check pending orders
longbridge orders --json

# Cancel all orders (or specific ones)
longbridge cancel <ORDER_ID>

Pitfall: longbridge buy/sell without -y hangs in interactive mode. Always use -y in scripts/cron.

T-Trading (做T) Analysis Workflow

做T = buying/selling around an existing position to lower cost basis. Requires high-volatility stocks with 10%+ daily swings.

  1. Fetch multi-timeframe data via Python SDK (5min, 30min, daily candlesticks)
  2. Calculate technical indicators: SMA(5/10/20), ATR(14) for volatility, recent support/resistance from highs/lows
  3. Identify key levels: buy zone (support), sell zone (resistance), breakout/breakdown thresholds
  4. Deploy monitoring script as cron job (every 10-15 min during market hours)
  5. Auto-place limit orders when price hits key levels, notify user via chat

Technical analysis snippet (run via execute_code):

from longport import openapi
cfg = openapi.Config.from_env()
ctx = openapi.QuoteContext(config=cfg)

candles = ctx.candlesticks("SYMBOL.US", openapi.Period.Day, 20, openapi.AdjustType.NoAdjust)
closes = [float(c.close) for c in candles]
highs = [float(c.high) for c in candles]
lows = [float(c.low) for c in candles]

sma5 = sum(closes[-5:]) / 5
atr = sum(max(highs[i]-lows[i], abs(highs[i]-closes[i-1]), abs(lows[i]-closes[i-1])) for i in range(-14, 0)) / 14
support = min(lows[-5:])
resistance = max(highs[-5:])

Sell Order Workflow (做T卖出)

When user wants to place a sell order for an existing position:

  1. Query actual position firsttrade_ctx.stock_positions(), get quantity, cost_price, available_quantity. NEVER guess or use memory.
  2. Fetch candlesticks — 30-day daily for resistance levels, 5-min for intraday context.
  3. Calculate technical levels — SMA(5/10/20), support/resistance from high/low clusters, psychological round numbers ($20, $21, etc.).
  4. Present options table — conservative / recommended / aggressive, with projected P&L based on ACTUAL cost basis.
  5. Ask urgency — "这周要成交吗?" determines how aggressive the price should be. Patient = closer to resistance; urgent = closer to current price.
  6. Place order — Use execute_code + Python SDK, submit_order with TimeInForceType.GoodTilCanceled and OutsideRTH.AnyTime.
  7. Report order ID — Always return the order_id so user can track/cancel.

Price selection heuristic (not in a hurry):

  • Conservative: next psychological round number above current price
  • Recommended: SMA10 or recent consolidation zone midpoint
  • Aggressive: SMA20 or prior support-turned-resistance

For intraday margin trading with actionable entry/exit/position sizing, see references/intraday-margin-trading.md. For token refresh automation, see ~/.hermes/scripts/update_longbridge_token.sh — auto-updates all token locations and verifies. For semi-automatic order placement with price monitoring, see references/semi-auto-trading.md. For the verified-working 602315 bypass from CN (order ID 1259547163696824320), see references/longbridge-602315-bypass.md. WireGuard is explicitly NOT a valid alternative for this account — see the ban note in that reference. For Clash node-switching API recipe (used to set HK node for the bypass), see references/clash-node-switching.md. For the longport_http.py公共模块 (CLI 走 proxychains 替代 Python SDK WSS, 2026-07-21 新建, 实测 5 次连续 4-5s), see references/longport-http-module.md. 所有 cron 跑的 stock 脚本必须用它 (dividend_alert / dca_monitor 已迁移). Python SDK WSS 在国内 VPS + mihomo 代理下永远失败, 别再用 openapi.QuoteContext() / openapi.TradeContext(). For VWAP + multi-indicator T-trading panel (scoring system, cron-based auto-orders), see references/vwap-t-trading-panel.md. For stock T-trading analysis workflow (lot sizes, per-currency fees, cost-performance rating, cron job), see references/stock-t-trading-workflow.md. For DCA position filtering by dividend yield threshold, see references/dca-yield-filter.md. For diagnosing silent Rejected orders (CLI returns success, JSON has no reason, no 602315 — see phone app for actual reason), see references/order-rejection-diagnosis.md. For the 港股 9 档保护规则 (buying price must be ≤ ask1+9 ticks, selling price must be ≥ bid1-9 ticks, otherwise Rejected), see references/港股九档保护规则.md. For the fact that LongPort has NO algo-order support (no SL/TP/conditional endpoint, neither SDK nor CLI), see references/longbridge-algo-order-not-supported.md — this is the most important constraint to know before designing any longbridge stop-loss logic; the OKX advisor's private_post_trade_order_algo does not work for longbridge. For when you reorganize scripts and cron jobs fail silently with "Script not found" (the 4 cron-wrappers that moved from scripts/ to scripts/stocks/ on 2026-07-10), see references/cron-script-path-migration.md — short version: symlink at old path, never re-update all cron jobs at once.

T-Trading Daily Analysis (每日做T分析)

自动分析持仓股票,计算支撑/阻力/ATR,给出做T方案+性价比评级。

python3 ~/.hermes/skills/trading/longbridge-cli/scripts/daily_t_analysis.py
  • 输出:每只持仓的技术分析(SMA5/10/20、ATR、支撑/阻力)
  • 做T方案:低吸位(支撑+ATR缓冲)→ 高抛位(阻力-ATR缓冲)
  • 性价比评级:高(盈亏比≥3+收益率≥1.5%) / 中 / 低 / 不建议
  • 手续费:港股按真实费率(佣金min$3+印花税0.1%+征费+交收费),美股近$0
  • 每手股数:自动查询lot_size,做T数量取整到手
  • 已配置cron任务 daily-t-analysis:每周一~五北京时间9:00推QQ

通用持仓查询(任意股票,不限定)

~/.hermes/scripts/stock_t.py — 不依赖固定 ticker,用户传任意 SYMBOL.USSYMBOL.HK 即可查询/撤单(取代旧的 RGTI 专用脚本)。

# 列出全部持仓
proxychains4 -f ~/.proxychains/proxychains.conf python3 ~/.hermes/scripts/stock_t.py list

# 任意股票查状态(两种参数顺序都支持)
proxychains4 -f ~/.proxychains/proxychains.conf python3 ~/.hermes/scripts/stock_t.py status RGTI.US
proxychains4 -f ~/.proxychains/proxychains.conf python3 ~/.hermes/scripts/stock_t.py UNH.US status

# 撤某股票所有挂单
proxychains4 -f ~/.proxychains/proxychains.conf python3 ~/.hermes/scripts/stock_t.py cancel SOXS.US

脚本顶部已强制 os.environ['LONGBRIDGE_REGION'] = 'ap',但仍需外层包 proxychains + Clash HK 才能访问 longport API。脚本会按 <SYMBOL> 自动加载对应的 <symbol>_t_config.json(如果存在),让用户给不同股票配不同的做T级别。

WireGuard: BANNED for this account

User explicitly said "不要用wg了,会害死你的" after spending 1h recovering from a half-shutdown that left 0.0.0.0/1 + 128.0.0.0/1 residual routes and broke all network. Do NOT propose WG as a workaround for 602315 or any other longport issue. All WG scripts were deleted. The verified alternative is the three-piece recipe in references/longbridge-602315-bypass.md.

CLI Unicode Table Parsing (2026-07-09)

Longbridge CLI's table output uses two different vertical-bar characters:

  • Header row borders: (U+2503, BOX DRAWINGS DOUBLE VERTICAL)
  • Data row borders: (U+2502, BOX DRAWINGS LIGHT VERTICAL)

A naive line.split('┃') only parses headers; data rows come back empty. Use re.split('[┃│]', line) to handle both. Also: stock names with spaces ("Unitedhealth" / "Semicon Bear 3X") wrap to multiple data rows, so when parsing positions you MUST filter rows where 标的 is empty or 持仓 is non-numeric — otherwise you get Position("", 0, 0.0, 0) placeholders. See references/cli-unicode-table-parsing.md for the full implementation.

CLI balance has no buy_power field (2026-07-09)

CLI balance output only contains: 现金余额 / 净资产 / 最大融资额 / 剩余融资额 / 风险等级. No buy_power like the SDK. Compute it manually: buy_power = 现金余额 + 剩余融资额. The SDK's AccountBalance.buy_power equals this sum.

CLI cancel has no -y flag (2026-07-09)

longbridge buy / sell accept -y to skip interactive confirmation, but longbridge cancel does NOT (run longbridge cancel --help to verify). Workaround: echo 'y' | longbridge cancel <ORDER_ID>. This is essential for cron/automation.

Rejected orders: no rejection reason in --json (2026-07-09)

When longbridge buy returns 下单成功,订单号:<ID> but the order later shows OrderStatus.Rejected in orders --json, the JSON does NOT include a rejection reason — only order_id, symbol, side, quantity, executed_quantity: 0.0, price, executed_price: null, status: "OrderStatus.Rejected", timestamps. There is no message / reason / error field to inspect.

Diagnostic steps when an order is Rejected (in order of speed):

  1. Check phone app — Longport app shows the actual rejection reason under order history (insufficient margin, odd-lot violation, position concentration, account-level restriction, etc.). This is the fastest path.
  2. Test with minimum size — try --qty 1 at the price. If 1 share/lot is also Rejected, the issue is account-level (not size). If it fills, your original size violated a per-order limit.
  3. Try opposite side — if Buy Rejected, try Sell (same symbol, same size). Sell is sometimes more permissive (closing a position vs. opening). Verified 2026-07-09: ~/.local/bin/longbridge --profile lb_real sell RGTI.US --qty 1 --price 15.40 -y succeeded where equivalent buy would have rejected, so directional permissiveness does exist in some cases.
  4. Check static_info lot_size — for HK, lot_size is often 100, 200, 500, or 1000. If your qty is not a multiple, you get 602001 (lot size error) — different from a silent Reject. Always call longbridge info <SYMBOL> first for unfamiliar HK tickers.
  5. For HK boards specifically: SEHK Main Board has a minimum trade size of 50,000 HKD per board lot for some order types. A 200-share order at HK$112 = HK$22,400 may be below the broker's per-order minimum and get silently Rejected.

Workaround for HK minimum-size rejections: cluster multiple signals into one larger order, or add to existing position (e.g. 9988.HK is already a watched candidate, wait for stronger signal that justifies 500-share minimum).

Do not retry Rejected orders in a loop — they will keep getting Rejected for the same reason. Diagnose first, then adjust size/symbol/price.

Cron push notifications: terse, table-style only (2026-07-09)

User preference: cron job output to QQ must be terse with tables, NOT verbose. Bad: dumping full positions table every 15 min. Good: only push when an event happens (下单成功/失败, 触发止损/止盈, 持仓变化 ≥5%). Use push_to_qq.sh for the channel, but gate the push on grep matches like grep '下单成功' $LOG — empty output → no push. See references/cron-wrapper-multi-token-pitfall.md for the full wrapper template.

SDK-Compatibility Helper (2026-07-09)

scripts/longbridge_cli_helper.py provides Python SDK-shaped functions (account_balance, stock_positions, submit_order, cancel_order, OrderType / OrderSide / TimeInForceType enums) that internally shell out to the CLI. Use it when you want to write Python code (for control flow / data processing) but need the CLI's .com international domain path to bypass 602315. The helper does NOT use Python SDK at all — it just provides compatible names.

Cron Wrapper Multi-Token Pitfall (2026-07-09)

cronjob script field rejects multi-token commands like proxychains4 -f /path/conf python3 /path/script.py — it treats the whole string as one file path and reports Script not found: .... Always wrap in a .sh script and reference just the filename. Also: don't nest proxychains4 in shell variables (PROXY="proxychains4 -f ..."; $PROXY python3 ...can't load process....); always write proxychains4 literally in the command. See references/cron-wrapper-multi-token-pitfall.md for the wrapper template.

T-Trading Active Workflow: Low-吸-高-抛 (2026-07-10)

The user defines 做T (T-trade) as "低吸高抛" — buy at support, sell at resistance. The full manual CLI workflow for intraday positions is:

# Step 1: Enter (buy) — price must be ≤ ask1+9 ticks (港股 9 档 rule)
# Use the helper to auto-adjust to ask1, then submit limit order
LONGBRIDGE_REGION=ap LONGBRIDGE_TRADE_ENABLED=true \
  proxychains4 -f ~/.proxychains/proxychains.conf \
  ~/.local/bin/longbridge --profile lb_real buy 9988.HK --qty 200 --price <ask1> -y

# Step 2: When the buy FILLS, immediately place the exit (sell) at resistance / bid1 area
# Use helper to get bid1 (avoids the 9 档 Reject)
LONGBRIDGE_REGION=ap LONGBRIDGE_TRADE_ENABLED=true \
  proxychains4 -f ~/.proxychains/proxychains.conf \
  ~/.local/bin/longbridge --profile lb_real sell 9988.HK --qty 200 --price <bid1 or resistance> -y

Key behaviors that caused the user to lose ~700 RMB on 2026-07-10 when these were violated:

  1. Don't run cron auto-trading without the user explicitly asking for it — the existing cron monitor (hk_intraday_monitor_cron.sh / us_intraday_monitor_cron.sh) places orders when entry signal fires, and the user has to manually clean up if the cron signal is wrong. Net result on 2026-07-10: 9988.HK 200 shares + 1810.HK 1000 shares, both went below entry, and the user had to babysit them.

  2. Verify status before pushing any "下单成功" message — stdout has order_id, but orders --json shows Rejected for many orders. See okx-auto-position skill v4.5.1 for the strict status-check rules.

  3. For limit sell (出T), price must be ≥ bid1-9 ticks (not above ask1+9 like the buy rule) — the Reject rules are different for buy and sell. Use the helper's adjust_price_for_order(symbol, price, 'sell') to get bid1.

  4. Sell-side limit orders can also Reject — verified 2026-07-10: longbridge sell 1810.HK --qty 1000 --price 25.80 was Rejected because 25.80 was too far above the current bid1 (probably mid-spread). Always check current price with longbridge quote and use the helper's adjusted price.

  5. If you can't get a working exit limit, use Day order (time_in_force=Day) to let the broker auto-close at session end — better than being stuck with a position overnight.

  6. longbridge-cli does NOT support the adj_time option for orders, so to use "Day" TIF you must either:

    • Pass via env var: LONGBRIDGE_TIF=Day (NOT supported, see Option 5 below)
    • Use the Python helper, which uses SDK under the hood (will hit 602315)
    • Or just accept that default TIF is Day and orders auto-cancel at session close

Default workflow when user says "做T ":

  1. Run longbridge quote <SYMBOL> → get current price
  2. Run python3 ~/.hermes/scripts/stock_t.py status <SYMBOL> (via proxychains) → confirm no existing position
  3. Calculate entry at ask1 (use helper adjust_price_for_order(sym, current, 'buy'))
  4. longbridge buy --qty N --price <ask1> -y
  5. When filled, immediately calculate exit at bid1 (use helper adjust_price_for_order(sym, current, 'sell'))
  6. longbridge sell --qty N --price <bid1> -y
  7. If sell Rejected, accept the Day order auto-close at 16:00 HKT

This avoids the cron-driven losses because the user explicitly asks for each step. Cron monitor remains useful for signals (推 QQ), but order placement is manual.

T-Trading Price Monitor (做T价格监控)

每15分钟检查持仓价格,接近支撑/阻力位时提醒。

python3 ~/.hermes/skills/trading/longbridge-cli/scripts/t_monitor.py
  • 监控OKX持仓(ETH/BTC等)+ 长桥持仓(UNH/RGTI/3416.HK等)
  • 🟢 接近低吸位(支撑附近)→ 提醒买
  • 🔴 接近高抛位(阻力附近)→ 提醒卖
  • ⚠️ 跌破支撑 / 🚀 突破阻力 → 警告
  • 无提醒时静默输出(cron no_agent模式不推送)
  • 已配置cron任务 t-monitor:每15分钟检查,有提醒才推QQ

Market Analysis Workflows

Watchlist Query (via Python SDK)

The CLI does not support watchlist queries directly. Use longbridge-python-sdk skill instead, or use the execute_code pattern in references/execute-code-pattern.py which reliably loads LONGPORT_* env vars:

from longport import openapi
cfg = openapi.Config.from_env()
ctx = openapi.QuoteContext(config=cfg)
resp = ctx.watchlist()  # Returns all groups with securities

Dividend/Yield Analysis

When looking for income-generating assets:

  1. Identify Target: Determine if the user wants monthly, quarterly, or annual payouts.
  2. Filter by Stability: Prioritize assets with high stability scores (e.g., Dividend Aristocrats/Kings).
  3. Group and Sort: Group by frequency (Monthly vs Quarterly) and sort by stability, then yield.
  4. Contextualize: Provide a clear table or list with enough context (Ticker, Name, Yield, Stability).

Key dividend stocks by frequency:

  • Monthly: O (Realty Income), MAIN (Main Street Capital)
  • Quarterly: KO (Coca-Cola), PG (Procter & Gamble), and most S&P 500 dividend payers

Market Trend & Professional Analysis

  1. Identify Asset Class: Stocks or Crypto.
  2. Select Toolset:
    • Stocks: Use stock-analysis or stock-analysis-agent (Yahoo Finance data)
    • Crypto/professional trading: Use longbridge CLI (this skill) or longbridge-python-sdk
  3. Execute Analysis: Run the appropriate tool for real-time or historical data.
  4. Synthesize: Summarize into actionable insights.

Pitfalls (Analysis-Specific)

  • Yield vs. Growth: High yield alone doesn't guarantee returns; always check stability/growth potential.
  • Frequency Confusion: Distinguish between monthly and quarterly payouts to match user cash-flow needs.
  • Data Source Routing: Stocks → stock-analysis (Yahoo Finance). Professional trading → longbridge.

Pitfalls

  • NEVER fabricate trading data (critical): When asked about positions, costs, prices, or orders, you MUST query the actual data from LongBridge API FIRST before doing any calculations. Do NOT guess, assume, or use stale data from memory/user profile. The user will catch fabricated numbers and lose trust. Always: trade_ctx.stock_positions() → get real quantity, cost_price, available_quantity → then calculate. This applies to cost basis calculations, P&L projections, and sell order sizing. One extra API call is infinitely better than a wrong number.
  • Missing Symbols: Most quote/candlestick commands require one or more symbols.
  • JSON Output: Always use the --json flag for machine-readable data.
  • Environment Variables: Ensure .env or shell exports are active before running commands.
  • Command Syntax: Note that longbridge uses a sub-command structure (e.g., longbridge <command> [OPTIONS] <args>).
  • Token Expiration (401004): LONGBRIDGE_ACCESS_TOKEN is a dynamic, time-sensitive token stored in bashrc (or .env). It expires and causes 401004: token invalid errors. Fix (preferred): run bash ~/.hermes/scripts/update_longbridge_token.sh NEW_TOKEN — it auto-updates all locations (bashrc, .env, hermes envs) and verifies both CLI and Python SDK. See references/token-refresh.md for full workflow. Never rely on a stale cached token.
  • Freshly-generated token still gets 401004: If a new token (just copied from App) gets 401004, first decode the JWT to verify exp is in the future and ak matches the configured APP_KEY (see references/token-refresh.md → "JWT Verification"). If the JWT is valid but API rejects it, either: (a) wait 30s and retry (propagation delay), (b) re-generate from App (first generation sometimes doesn't register), or (c) try from Web console at https://open.longportapp.com/ (different token type). Do NOT assume the token is wrong — the JWT structure is verifiable independently of the API.
  • Command Name: The npm-installed CLI is longbridge (not lonbh, longport, etc.). Verify with npm list -g | grep longbridge.
  • Env Var Loading: Variables in bashrc are not visible to child processes via env | grep. Always source ~/.bashrc in the same shell session before running commands.
  • Validate Token Before Batch: Before running multi-ticker queries (especially dividend/quote batch calls), run a single-ticker sanity check first: longbridge quote --json AAPL. A 401004 on a 15-ticker batch wastes time diagnosing which tickers are the problem vs. the token being expired.
  • 401004 Diagnostic Protocol: When hitting 401004, first distinguish between these scenarios:
    • Terminal output shows ... → That's the tool's secret masking. Verify with python3 -c "open('/home/openclaw/.bashrc').read().split('LONGBRIDGE_ACCESS_TOKEN=')[1].split()[0]" | wc -c. If length ~1053, the token is intact.
    • Token was never saved → All files have literal ... placeholders. Ask user to re-generate.
    • Token expired → error 401003. Run bash ~/.hermes/scripts/update_longbridge_token.sh NEW_TOKEN.
    • Fresh token gets 401004 → See pitfall "Freshly-generated token still gets 401004" above. Do NOT iterate through config files one by one — run the script which handles all locations in one call.
  • CLI Installation Path: The longbridge CLI is installed via uv tool install at ~/.local/bin/longbridge. It is NOT in $PATH by default in all sessions. Use the full path ~/.local/bin/longbridge or add export PATH="$HOME/.local/bin:$PATH" to bashrc. Verify with which longbridge || ls ~/.local/bin/longbridge.
  • CLI Token Masking (Workaround via --profile): The terminal tool's secret-redaction layer masks/truncates env vars → CLI gets corrupted tokens → 401004/403201. Workaround: load credentials via --profile lb_real from ~/.lb_real.env (full 1053-char token, bypasses masking). See references/longbridge-602315-bypass.md → "Profile file". Rule: Always use --profile lb_real for longport CLI order/trade operations; quote/balance commands may work via direct env var but orders won't.
  • "..." in terminal output ≠ placeholder (critical trap): The terminal tool masks secrets in both display AND environment variables. When you run grep LONGBRIDGE_ACCESS_TOKEN ~/.bashrc, the output shows m_eyJh...jb-k even when the actual file has a complete 1053-char JWT. This is the tool's secret-redaction layer, NOT file corruption. Never conclude a token is truncated from terminal grep output alone. To verify the file truly has a complete token:
    python3 -c "
    with open('/home/openclaw/.bashrc') as f:
        for line in f:
            if 'LONGBRIDGE_ACCESS_TOKEN' in line and 'export' in line:
                tk = line.strip().split('=', 1)[1]
                print(f'Token length: {len(tk)}')  # Should be ~1053
    "
    
    Trust the user when they say "变量没有占位符" — they can see the file without masking.
  • Signature Invalid (403201): Distinct from 401004 (token expired). Error 403201: signature invalid means the LONGBRIDGE_APP_SECRET (or LONGPORT_APP_SECRET) value is wrong, corrupted, or truncated — NOT that the token expired. This commonly happens because of the terminal secret masking above. Fix: use --profile lb_real env-file path instead.
  • HK stock symbols: Use .HK suffix (e.g., 0823.HK, 0778.HK). The CLI accepts both 0823.HK and HK.0823 formats.
  • Python SDK Env Var Prefix Mismatch: The CLI uses LONGBRIDGE_* env vars, but the Python SDK (longport) reads LONGPORT_*. When using Python, you must manually map the bashrc vars: os.environ["LONGPORT_APP_KEY"] = config.get("LONGBRIDGE_APP_KEY", "") etc. See references/python-sdk.md.
  • buy/sell requires -y flag: Without -y, the CLI prompts for confirmation interactively and hangs in scripts/cron. Always longbridge buy SYM --qty N --price P -y.
  • Read-only mode by default (LONGBRIDGE_TRADE_ENABLED): The CLI defaults to read-only mode. buy, sell, and cancel commands fail with 当前为只读模式,下单/撤单操作已禁用 unless LONGBRIDGE_TRADE_ENABLED=true is set. Must be in ~/.lb_real.env profile OR bashrc. Without it, even valid tokens reject order commands.
  • Python SDK submit_order API quirks: The enum is openapi.TimeInForceType (NOT TimeInForce). The function signature is submit_order(symbol, order_type, side, submitted_quantity, time_in_force, submitted_price=None, ...) — note time_in_force is a required positional arg before the optional submitted_price. Correct call:
# Enums reference:
# openapi.OutsideRTH: .AnyTime (pre+regular+post), .Overnight, .RTHOnly, .Unknown
# openapi.TimeInForceType: .Day, .GoodTilCanceled, .GoodTilDate, .Unknown
# openapi.OrderType: .LO (limit), .MO (market), .ELO (enhanced limit), .ALO, .AO, .SLO, etc.
# openapi.OrderSide: .Buy, .Sell, .Unknown

resp = trade_ctx.submit_order(
    symbol="RGTI.US",
    order_type=openapi.OrderType.LO,
    side=openapi.OrderSide.Sell,
    submitted_quantity=15,
    time_in_force=openapi.TimeInForceType.GoodTilCanceled,  # GTC = persists until filled/canceled
    submitted_price=21.00,
    outside_rth=openapi.OutsideRTH.AnyTime,  # pre-market + regular + after-hours
)
  • SecurityQuote attributes vary: US quotes from Nasdaq Basic may lack turnover_rate, amplitude etc. that HK LV1 provides. Wrap attribute access in try/except or hasattr. No change_rate attribute: Calculate change manually: (float(q.last_done) - float(q.prev_close)) / float(q.prev_close) * 100. Available attributes: symbol, last_done, prev_close, open, high, low, timestamp.

  • Period enum uses underscores: Period.Min_5 not Period.Min5. Full list: Min_1, Min_2, Min_3, Min_5, Min_10, Min_15, Min_20, Min_30, Min_45, Min_60, Min_120, Min_180, Min_240, Day, Week, Month, Quarter, Year.

  • AccountBalance attributes: Has buy_power, total_cash, net_assets, max_finance_amount, remaining_finance_amount, risk_level, margin_call. NO available_cash or free — use buy_power for available buying power. Confirmed HK LV1 attributes (2026-06-25): high, last_done, low, open, overnight_quote, post_market_quote, pre_market_quote, prev_close, symbol, timestamp. NO change_rate — compute manually: (last_done - prev_close) / prev_close * 100.

  • Position fields: available_quantity (settled, sellable) vs quantity (total incl unsettled). For T-trading sell, check available_quantity first.

  • Prefer execute_code over terminal for Python SDK: The execute_code sandbox can access LONGPORT_* vars from the host environment, making Config.from_env() work reliably. In contrast, terminal + source ~/.bashrc frequently fails because env vars get masked/truncated by the terminal tool's secret-redaction layer, producing 403201 or 401004 errors. Workflow: for single-call quick data, use execute_code with inline Python + Config.from_env(). For CLI commands, use terminal with source ~/.bashrc && longbridge .... The ~/.lb_real.env profile file bypasses masking for both paths.

  • China Mainland Geo-Block (Error 602315): LongPort API blocks trading from mainland China IPs. The verified-working bypass is the three-piece recipe in the section "⚠️ Mainland China Access (602315) — verified working recipe" at the top of this skill. WireGuard is NOT an alternative for this account (user-banned). The earlier /etc/hosts redirect was deprecated (see references/longbridge-cn-vs-com-endpoint.md).

  • ONLY CLOSE YOUR OWN POSITIONS (critical): Automated trading systems MUST only close positions that were opened by the same system. Track opened positions in a JSON file (e.g., entries.json) with order_id, shares, entry_price. On close, verify order_id exists before executing. Never close user's manual positions. User explicitly stated: "只有你开仓的的你才能平,不是你开的你不能操作".

  • 🔴 [2026-07-05 — 不要把"信号源不推股票"误读成"长桥不能交易"] 用户的明确约束是两套资金/两套API严格分开:股票=LongPort(美股/港股持仓估值+做T),币圈=OKX(合约短线)。SKHYNIX/MU/SNDK等来自熬鹰资本的"股票名称",实际上是OKX上的美股代币永续合约(如 MUUSDTSNDKUSDT),走币圈 okx-auto-position 流程,不是长桥持仓。

    长桥账户本身可以做交易(正常买入/卖出/做T平仓),包括用户主动提到的 AMD、UNH、RGTI、3416.HK 等。当用户问"现在 XX 能下单吗/帮我看看 XX 持仓/做T卖出 XX"时,正常查持仓+评估即可。禁止替用户做"不能交易"的决定——除非用户明确说"今天不交易"、"别动长桥"。

    真正的硬约束只有两条:(1) cron 自动任务(daily_t_analysis.py / t_monitor.py)只输出报告/做T监控,不自动执行 buy/sell(2) 不许把熬鹰的"SKHYNIX/MU/SNDK"当成股票信号往长桥发——它们是 OKX 合约。

  • 🔴 [2026-07-09 PARTIAL — CLI only] The 602315 three-piece recipe is verified for CLI orders only, NOT for Python SDK cron scripts. Same LONGBRIDGE_REGION=ap + proxychains + Clash HK combo that succeeded for one-off CLI orders (order 1259547163696824320) still returns 602315 for the Python SDK running inside us_intraday_monitor.py / hk_intraday_monitor.py / *_intraday_close.py — because the Python SDK's is_cn() flow uses openapi.longportapp.cn (Aliyun Shenzhen/Shanghai), and the international *.com endpoints (AWS HK, e.g. 18.166.191.191) are unreachable from every Clash node we tested — curl https://18.166.191.191/ returns OpenSSL SSL_connect: SSL_ERROR_SYSCALL. The 602315 is a server-side IP/ASN check, not a domain-routing issue. As of 2026-07-09: CLI orders work with the three-piece recipe; cron-driven Python SDK orders do not — disable auto-execution in monitor scripts and place orders manually (CLI recipe or phone app) until this changes. Full diagnostic history in references/longbridge-602315-bypass.md.

  • 🔴 [2026-07-09 做T分析的 cron 模式]: 用户的 hard 约束(明确要求)是 cron 跑的 daily_t_analysis.py / t_monitor.py 只输出报告/做T监控,不自动 buy/sell。但用户手动通过对话触发的下单(问"AMD 现在能下吗"、问"RGTI 持仓")→正常评估 + 必要时下单。禁止替用户拒绝(把"信号源不推股票"误读成"长桥不能交易")。

    下单链路(优先级):

    1. LONGBRIDGE_REGION=ap + proxychains + Clash HKproxychains4 ... longbridge --profile lb_real ...(实测有效)
    2. 手机长桥 App 手动
    3. 不用 WG(关不干净的坑,用户明确禁用)
  • 🔴 [2026-07-08 价格触发做T挂单的实操案例]: 同一个股票(如 RGTI.US)的卖单/买单修改流程:

    • 撤旧单: longbridge cancel <OLD_ORDER_ID>trade_ctx.cancel_order(old_id)(注意:卖单 SDK 能下,但买单 SDK 报 602315 → 走 hosts 修复后下单)
    • 建新单: 撤完再建新,避免多OCO残留
    • OCO sz 取整到 lot_sz: 加仓后持仓可能是小数(如 14.77 张),但 OCO sz 必须整数张(14),剩余 0.77 张无保护
    • 港股 lot_size 可能 > 1(如 3416.HK 100股一手),下单前查 static_info(symbol).lot_size
  • 🔴 [2026-07-08 不对称挂单风险]: 实测发现同一 IP 下 LongPort 对卖单开放但买单 602315。场景:VPN 不稳时挂了一个卖单(RGTI 15股 @ $17),买单(@ $15.50)被 602315 拒。结果是只有单边暴露——价格跌不到 15.5 就没货接回,价格涨不到 17 就错过止盈。处理规则:

    • 要么成对下(卖+买一起)
    • 要么都不下
    • 已挂单管理:定期检查是否还符合当前交易意图,如果只剩"接回"逻辑无法兑现,考虑撤单改用手机 App 手动
    • 但用了三件套之后,这个不对称问题已解决——卖单/买单都能下
  • **🔴 [2026-07-05 做T方向] 做T=低吸高抛,不是低抛高吸。低吸=跌到支撑位买入,高抛=涨到阻力位卖出。不能随便市价卖出就叫"做T"。减仓和做T是两回事:减仓是降低风险敞口,做T是利用波动降低成本。

  • 🔴 [2026-07-09 LongPort 没有 SL/TP/conditional algo 端点] LongPort OpenAPI 不支持挂止损单 / 止盈单 / 条件单. longport.TradeContext 只暴露 submit_order / cancel_order / today_orders / history_orders / order_detail / replace_order / set_on_order_changed, 没有 submit_algo_ordersubmit_conditional_order. CLI 二进制同样: 所有 /v1/trade/order-algo / /v1/trade/orderAlgo / /v1/trade/algo 路径都是 404. 别照搬 OKX 的 private_post_trade_order_algo 逻辑到长桥 - 那是 OKX 专属. 长桥只能下普通限价/市价单, "止损"必须用 Day 单(time_in_force=Day)靠收盘自动取消, 或手动/CLI 下反向 limit 单. 详见 references/longbridge-algo-order-not-supported.md.

  • 🔴 [2026-07-10 假阳性成功推送] 任何订单推送前必须反查 status,不能信 stdout. 现象: cron 推送 📊 HK 1810.HK ✅ 下单成功: 1260056765857271808,实际 orders --jsonstatus: "OrderStatus.Rejected". 根因: submit_order / execute_order 返回 order_id 只代表"已发请求",不代表"已成交". 反查 status 规则:

    • closed / filled → 推 " 下单成功"
    • Rejected → 推 " 下单被拒: {id} (查长桥 App 或 orders --json 看 reason)"
    • NotReported → 推 " 已提交: {id} (等成交, 港股日内单收盘自动作废)"
    • Canceled → 推 "🚫 已撤: {id}"
    • 没反查前, 推送只能说"已提交 {id}, 待确认", 不能说"成功"

    实施: 在 hk_intraday_cli.py / us_intraday_cli.py submit_order 调用后,加 fetch_order(order_id) 反查. 详见 okx-auto-position skill v4.5.1 章节.

  • **🔴 [2026-07-09 改技能前先 trace 下游依赖] OKX advisor v4.5.0 改成 "只挂 SL 不挂 TP" 时, 假设长桥 SDK 也支持 conditional algo, 实际不支持, 导致长桥端下单后 step="sl_only" 永远是 "skipped" 状态. 教训: 改任何技能时, 先检查目标 SDK/CLI 是否支持新功能, 不要跨 broker 假设. 同样的 okx-only vs longbridge-only 概念适用于 fee 货币 (HKD vs USDT), endpoint 域名 (.com vs .cn), 持仓模式 (long_short_mode vs net_mode), 等.

  • **🔴 [2026-07-10 入场后立即挂出场单 (700RMB 教训)] 用户明确规则: 入场成功 (Filled) 后,必须立即挂出场限价单 (sell 在 bid1 价位). 不挂出场单 = 收盘自动作废 = 钱蒸发 (2026-07-10 1810.HK 1000 股 @ 25.64 当天挂卖单 25.80 被 9 档 Rejected 后没补救 → 收盘亏 100+ RMB). 操作流程: quote → bid1 → sell limit bid1 → orders --json 等 Filled. 卖单 Rejected 立即撤 + 重挂到更低 bid1 (不要挂同一个超 9 档价格). 如果连续 Rejected, 改用 time_in_force=Day 让系统自动平 (永远优于手动僵持).

  • 🔴 [2026-07-10 默认 dry-run] 用户规则: 任何交易类操作 (buy/sell/cancel), 用户没明确说"下单"前只算信号+输出分析, 不下真单. cron 自动 order monitor (hk_intraday_monitor_cron.sh / us_intraday_monitor_cron.sh) 仍运行监控+推送信号, 但下单前必须用户确认. 详见 references/做T完整链路.md.

  • 🔴 [2026-07-10 用户偏好 - cron 输出简洁表格] 用户的明确规则: cron 推送必须简洁 + 表格风格,禁止冗长啰嗦. 关键事件才推 (下单成功/失败, 触发止损/止盈, 持仓变化 ≥5%). 其他输出空时静默 (no_agent 模式不推 QQ). User 原话: "这个消息简洁点,可以是图表".