# LongPort 602315 Mainland-China Geo-Block: What ACTUALLY Works (2026-07-09) **Status**: PARTIAL WORKAROUND — CLI orders work, Python SDK orders are still blocked. **Order ID `1259547163696824320` (RGTI 15@$15.50)** was placed via the **CLI** path only. The Python SDK (used by all cron jobs) **still gets `602315`** even with the full three-piece recipe. This document supersedes the original "verified working" framing in the SKILL.md header. ## The fundamental problem LongPort's geo-block `602315: Due to Mainland China regulatory requirements` is **enforced server-side based on source IP**. It is NOT a domain-routing problem. No amount of `LONGBRIDGE_REGION` setting, `/etc/hosts` redirect, or "international endpoint" trick bypasses the server-side check — the API gateway sees your connection's egress IP and rejects if it's a CN IP (or a CN ASN, or any IP that LongPort's geo-feed marks as CN). The whole "use `.com` instead of `.cn`" framing is wrong. Both endpoints talk to the same gateway infrastructure; the gateway checks the source IP regardless of which domain resolved the connection. ## Two domain families (important for diagnosis, not for bypass) LongPort has two parallel domain trees that get geo-blocked differently depending on which client you use: | Domain tree | Used by | Endpoint hosts | |---|---|---| | `*.longbridge.cn` | CLI (`longbridge` binary) | Aliyun Shenzhen (`47.106.x.x`, `120.77.x.x`) | | `*.longportapp.cn` | Python SDK (`longport` package) | Aliyun Shenzhen (api) + Shanghai (quote) | - CLI hits `openapi.longbridge.cn` - Python SDK hits `openapi.longportapp.cn`, `openapi-quote.longportapp.cn`, `openapi-trade.longportapp.cn` Both are CN-hosted and both return 602315 from a CN egress IP. The international versions `*.longbridge.com` and `*.longportapp.com` exist (AWS HK/global), but: - `LONGBRIDGE_REGION=ap` only changes the **CLI's** endpoint selection. The Python SDK's `Config.from_env()` reads `LONGBRIDGE_REGION` for some endpoints, but `is_cn()` in the Rust geo crate probes `geotest.lbkrs.com` anyway, and even when overridden, the SDK still hits `openapi.longportapp.cn` (the hardcoded default) because the env-var override only takes effect for fields explicitly wired through it (HTTP URL, WS URLs — see `config.rs` `env_var()` helper). Verified empirically 2026-07-09: `LONGBRIDGE_REGION=ap` set in Python process, `proxychains` wrapping the call, `geotest` was reachable through Clash HK — but every API call to `openapi.longportapp.cn` still returned 602315. - The `*.com` IPs (e.g. `18.166.191.191`, `18.163.160.163`) are **unreachable from every Clash HK node we tested** (HK 01/02/03, US 01/02/03, Taiwan 01/02/03) — `curl https://18.166.191.191/` returns `OpenSSL SSL_connect: SSL_ERROR_SYSCALL`. The TCP connection opens but TLS handshake fails. This is consistent with AWS blocking egress from consumer VPN/proxy ASNs. ## What the three-piece recipe ACTUALLY does ```bash LONGBRIDGE_REGION=ap \ LONGBRIDGE_TRADE_ENABLED=true \ proxychains4 -f ~/.proxychains/proxychains.conf \ ~/.local/bin/longbridge --profile lb_real buy RGTI.US --qty 15 --price 15.50 -y ``` For the **CLI** path: 1. `LONGBRIDGE_REGION=ap` → CLI picks `openapi.longbridge.com` endpoint (per `config.rs` `env_var("HTTP_URL")` etc.) 2. `proxychains4` → forces Rust binary's HTTPS through Clash 7890 3. Clash on HK node → egress IP is HK 4. CLI connects to `openapi.longbridge.com` from a HK IP → **succeeds** (only CLI is verified working) For the **Python SDK** path (the 4 cron scripts): 1. `os.environ['LONGBRIDGE_REGION'] = 'ap'` set in script → does **not** override the hardcoded `openapi.longportapp.cn` endpoint that Python SDK uses 2. `proxychains4` → forces Rust binary's HTTPS through Clash 7890 ✓ 3. Clash on HK node → egress IP is HK ✓ 4. Python SDK still connects to `openapi.longportapp.cn` from HK IP → server still returns 602315 ✗ **So cron-based automated trading is NOT working as of 2026-07-09.** The "verified working" framing in the skill header and the 602315-bypass reference is misleading — it works for one-off manual CLI orders, not for the automated pipeline the cron jobs represent. ## What you should do TODAY (ranked) 1. **For one-off manual orders**: use the CLI three-piece recipe. It works. ```bash LONGBRIDGE_REGION=ap LONGBRIDGE_TRADE_ENABLED=true \ proxychains4 -f ~/.proxychains/proxychains.conf \ ~/.local/bin/longbridge --profile lb_real buy RGTI.US --qty 15 --price 15.50 -y ``` 2. **For cron-driven trading**: disable auto-execution in the monitor scripts and have them push signals to QQ; you place the order manually from the phone app or via the CLI recipe above. The signals and risk checks still work; just don't let the script call `submit_order`. 3. **For phone-app trading**: confirmed working by user with HK proxy (no API needed). The LongPort app on a phone with HK network egress does not trigger 602315 because (a) the device IP is HK or (b) the app uses a different auth path that doesn't run the same geo-check as the OpenAPI. 4. **Stop trying `/etc/hosts` redirects**. We added `18.166.191.191 openapi.longportapp.cn` etc. and the API server still returned 602315 because the source IP is the problem, not the domain. We also tried the AWS `.com` IPs directly and they fail SSL handshake from Clash. The hosts file is back to default (only localhost entries). 5. **Do NOT propose WireGuard** for this account. User banned it after a 1-hour recovery from a half-shutdown. All WG scripts were deleted. ## Failure-mode table (expanded from original reference) | Symptom | Cause | Fix | |---|---|---| | `error sending request: client error (Connect)` | `.com` endpoint unreachable from CN (TLS fails from every Clash node) | Cannot fix with current setup. Use phone app, or accept that automated trading from this server is blocked | | `602315 Mainland China regulatory` (CLI) | CLI still using `.cn` (env var not passed) | Verify `LONGBRIDGE_REGION=ap` is in the env; check no quoting/space issue | | `602315 Mainland China regulatory` (Python SDK) | **Server-side IP check, not domain-routing** | Cannot bypass with proxychains + HK node alone. SDK hardcoded endpoint doesn't matter — gateway still sees CN/Clash IP as blocked | | `4001: token empty` | Token not loaded into CLI | Use `--profile lb_real`; verify `~/.lb_real.env` has full 1053-char token | | `401004 token invalid` | Token truncated by terminal masking | Same as above — `--profile` bypasses the masking | | HK exit suddenly returns CN IP | Clash node selector fell back to auto | Re-pin `GLOBAL` to `🇭🇰 香港 01` via API; verify with `curl -x http://127.0.0.1:7890 https://api.ipify.org` | | Cron order succeeds but no QQ push | Script ran `print()` only; didn't call `push_to_qq.sh` | `no_agent` scripts must `subprocess.run(['bash', '~/.hermes/scripts/push_to_qq.sh', msg])` | | Cron "Script not found" | script field has spaces (e.g. `proxychains4 -f ... python3 ...`) | Cron script field is one path. Use a **bash wrapper**: `hk_intraday_monitor_cron.sh` that `exec proxychains4 -f ... python3 ...` | ## The cron wrapper pattern (4 scripts updated 2026-07-09) The cron job's `script` field must be a single executable path — multi-token commands like `proxychains4 -f X python3 Y` are misinterpreted as `Script not found: /path/to/proxychains4 -f X python3 Y`. Fix: create a `*_cron.sh` wrapper. ```bash #!/bin/bash # ~/.hermes/scripts/hk_intraday_monitor_cron.sh exec proxychains4 -f ~/.proxychains/proxychains.conf \ python3 ~/.hermes/scripts/hk_intraday_monitor.py ``` Then point the cron job's script field at the wrapper: ```bash cronjob update --job_id e3667cb07aff --script hk_intraday_monitor_cron.sh ``` The 4 affected cron jobs (wrappers created 2026-07-09): - `hk_intraday_monitor_cron.sh` → `hk_intraday_monitor.py` - `us_intraday_monitor_cron.sh` → `us_intraday_monitor.py` - `hk_intraday_close_cron.sh` → `hk_intraday_close.py` - `us_intraday_close_cron.sh` → `us_intraday_close.py` Even with the wrapper, the underlying 602315 problem remains for Python SDK calls. The wrappers get the script to RUN; they don't fix the geo-block. ## Diagnostic script (paste to verify your environment) ```bash # 1. Check Clash HK exit curl -s -x http://127.0.0.1:7890 --max-time 8 https://api.ipify.org # Expected: 154.83.x.x (HK) or similar non-CN IP # 2. Check if AWS HK endpoints are reachable from Clash proxychains4 -f ~/.proxychains/proxychains.conf \ curl -s --max-time 10 -o /dev/null -w "%{http_code}\n" https://18.166.191.191/ # Expected today: 000 (TLS fails) — proves the AWS IP path doesn't work # 3. Check if longportapp.cn is geo-blocked from current egress proxychains4 -f ~/.proxychains/proxychains.conf \ python3 -c " import os; os.environ['LONGBRIDGE_REGION']='ap' bashrc = open('/home/openclaw/.bashrc').read() for k in ['LONGPORT_APP_KEY','LONGPORT_APP_SECRET','LONGPORT_ACCESS_TOKEN']: os.environ[k] = next(l for l in bashrc.splitlines() if l.startswith(f'export {k}')).split('=',1)[1].strip() from longport import openapi try: ctx = openapi.QuoteContext(config=openapi.Config.from_env()) print(ctx.quote(['RGTI.US'])[0].last_done) except Exception as e: print(f'ERR: {e}') " # Expected: 602315 error even with full three-piece setup ``` ## History / what we tried in order 1. Direct LongPort API from CN → 602315 2. `LONGBRIDGE_REGION=ap` only → still 602315 3. `LONGBRIDGE_REGION=ap` + proxychains4 + Clash HK → CLI works (order `1259547163696824320` placed) 4. Same combo for Python SDK cron scripts → still 602315 5. Added `openapi.longportapp.cn` → `18.166.191.191` in `/etc/hosts` → still 602315 6. Added all 3 longportapp.cn + 2 longbridge.cn domains → still 602315 7. Tested `https://18.166.191.191/` directly via proxychains → `OpenSSL SSL_connect: SSL_ERROR_SYSCALL` 8. Tested US 01/02/03, HK 01/02/03, Taiwan 01/02/03 Clash nodes → all fail AWS HK SSL handshake 9. Conclusion: AWS blocks egress from these proxy ASNs; the `.com` path is not reachable 10. Reverted `/etc/hosts` changes; restored to default (localhost only) The geo-block `602315` is therefore **not bypassable from this server with the current network setup** for the Python SDK path. The CLI recipe still works for manual one-off orders.