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' + 迁移说明
This commit is contained in:
2026-07-22 13:22:45 +08:00
parent e23f8d38c0
commit b660debd06
11 changed files with 907 additions and 244 deletions
+76 -2
View File
@@ -9,6 +9,16 @@ A specialized skill for interacting with the LongPort OpenAPI via the `longbridg
## ⚠️ 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`.
@@ -26,6 +36,8 @@ For Clash node-switching API recipe (used to set HK node for the bypass), see `r
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:
@@ -116,10 +128,12 @@ For token refresh automation, see `~/.hermes/scripts/update_longbridge_token.sh`
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 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方案+性价比评级。
@@ -197,6 +211,52 @@ User preference: cron job output to QQ must be **terse with tables**, NOT verbos
`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:
```bash
# 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 <SYMBOL>":**
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分钟检查持仓价格,接近支撑/阻力位时提醒。
```bash
@@ -331,4 +391,18 @@ resp = trade_ctx.submit_order(
- **已挂单管理**:定期检查是否还符合当前交易意图,如果只剩"接回"逻辑无法兑现,考虑撤单改用手机 App 手动
- **但用了三件套之后,这个不对称问题已解决**——卖单/买单都能下
- **🔴 [2026-07-05 做T方向] 做T=低吸高抛,不是低抛高吸。** 低吸=跌到支撑位买入,高抛=涨到阻力位卖出。不能随便市价卖出就叫"做T"。减仓和做T是两回事:减仓是降低风险敞口,做T是利用波动降低成本。
- **🔴 [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_order` 或 `submit_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 --json` 查 `status: "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 原话: "这个消息简洁点,可以是图表".