fix: CTP 需 zh_CN.GB18030 中文 locale 而非仅 UTF-8

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-24 11:42:15 +08:00
parent d368317c1b
commit 36e26973fb
6 changed files with 56 additions and 24 deletions
+6 -3
View File
@@ -27,10 +27,13 @@ need_install python3-venv python3-venv
need_install git git
# vnpy_ctp 在 Linux 上需本地编译(Meson + pkg-config 查找 python3-dev
echo "==> 安装 vnpy_ctp 编译依赖..."
echo "==> 安装 vnpy_ctp 编译依赖与 CTP 中文 locale..."
apt-get install -y build-essential python3-dev pkg-config locales
locale-gen en_US.UTF-8 C.UTF-8 2>/dev/null || true
update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 2>/dev/null || true
# CTP C++ API 登录回调需要 zh_CN.GB18030vnpy/vnpy_ctp#24
sed -i '/^# zh_CN.GB18030/s/^# //' /etc/locale.gen 2>/dev/null || true
sed -i '/^# zh_CN.UTF-8/s/^# //' /etc/locale.gen 2>/dev/null || true
locale-gen zh_CN.GB18030 zh_CN.UTF-8 en_US.UTF-8 2>/dev/null || locale-gen
update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 2>/dev/null || true
if ! command -v pm2 &>/dev/null; then
echo "==> 安装 PM2..."
+1 -1
View File
@@ -346,7 +346,7 @@ pm2 restart qihuo
|-----------|------|
| `pip install vnpy_ctp` 编译失败 / `Python dependency not found` | 安装 `build-essential python3-dev pkg-config` 后重试 |
| CTP 连接超时 | 检查前置 IP、端口、SimNow 是否维护、是否在允许连接时段 |
| 连接后立即崩溃 `locale::facet::_S_create_c_locale` | 安装 locale`apt install -y locales && locale-gen en_US.UTF-8``git pull` `pm2 restart qihuo --update-env` |
| 连接后立即崩溃 `locale::facet::_S_create_c_locale` | CTP 需 **zh_CN.GB18030**`sed -i '/^# zh_CN.GB18030/s/^# //' /etc/locale.gen && locale-gen zh_CN.GB18030`,再 `pm2 restart qihuo --update-env` |
| 服务器 `180.168.146.187` 超时 | 换 SimNow 备用前置 `182.254.243.31:30001/30011`(见 [SIMNOW.md](./SIMNOW.md) |
| 已连接但下单拒单 | 检查合约代码、价格精度、是否有足够保证金 |
+1 -1
View File
@@ -183,7 +183,7 @@ python scripts/test_simnow.py
| 报错 **4097** / 握手失败 | `pip install -U vnpy vnpy_ctp``.env``SIMNOW_ENV=实盘` |
| **不合法的登录** | 投资者代码/密码错,或未在快期改过一次密码 |
| 快期能登、脚本不能 | 多为网络或前置地址,换 SimNow 官网其他组前置试 |
| 连上后进程崩溃 `locale::facet::_S_create_c_locale` | `apt install -y locales && locale-gen en_US.UTF-8``git pull``pm2 restart qihuo --update-env` |
| 连上后进程崩溃 `locale::facet::_S_create_c_locale` | **必须**安装 `zh_CN.GB18030``sed -i '/^# zh_CN.GB18030/s/^# //' /etc/locale.gen && locale-gen zh_CN.GB18030` |
### 提示「未安装 vnpy / vnpy_ctp」
+3 -3
View File
@@ -11,9 +11,9 @@ module.exports = {
max_memory_restart: "300M",
env: {
NODE_ENV: "production",
LANG: "en_US.UTF-8",
LC_ALL: "en_US.UTF-8",
LC_CTYPE: "en_US.UTF-8",
LANG: "zh_CN.UTF-8",
LC_ALL: "zh_CN.UTF-8",
LC_CTYPE: "zh_CN.UTF-8",
},
error_file: "/opt/qihuo/logs/pm2-error.log",
out_file: "/opt/qihuo/logs/pm2-out.log",
+39 -13
View File
@@ -11,29 +11,48 @@ logger = logging.getLogger(__name__)
_LOCALE_DONE = False
_LOCALE_NAME = ""
# CTP C++ API 登录回调依赖中文 locale(见 vnpy/vnpy_ctp#24
_CTP_REQUIRED_LOCALES = ("zh_CN.GB18030", "zh_CN.gb18030")
def _available_locales() -> set[str]:
try:
out = subprocess.check_output(["locale", "-a"], text=True, stderr=subprocess.DEVNULL)
return {line.strip() for line in out.splitlines() if line.strip()}
except (OSError, subprocess.SubprocessError):
return set()
def missing_ctp_locales() -> list[str]:
"""CTP 所需的 zh_CN.GB18030 是否已安装。"""
avail = {x.lower() for x in _available_locales()}
if any(x.lower() in avail for x in _CTP_REQUIRED_LOCALES):
return []
return ["zh_CN.GB18030"]
def _list_locale_candidates() -> list[str]:
avail = _available_locales()
names: list[str] = []
# CTP 回调优先尝试中文 locale
for item in (
"C.UTF-8",
"zh_CN.GB18030",
"zh_CN.gb18030",
"zh_CN.UTF-8",
"zh_CN.utf8",
"en_US.UTF-8",
"en_US.utf8",
"C.UTF-8",
"C.utf8",
"POSIX",
"C",
):
if item not in names:
if item in avail and item not in names:
names.append(item)
try:
out = subprocess.check_output(["locale", "-a"], text=True, stderr=subprocess.DEVNULL)
for line in out.splitlines():
loc = line.strip()
if not loc:
continue
for loc in sorted(avail):
low = loc.lower()
if "utf" in low and loc not in names:
names.insert(0, loc)
except (OSError, subprocess.SubprocessError):
pass
names.append(loc)
return names
@@ -43,6 +62,14 @@ def ensure_process_locale() -> str:
if _LOCALE_DONE:
return _LOCALE_NAME
missing = missing_ctp_locales()
if missing:
raise RuntimeError(
"CTP 需要中文 locale zh_CN.GB18030,当前系统未安装。"
"请执行: sed -i '/^# zh_CN.GB18030/s/^# //' /etc/locale.gen && "
"locale-gen zh_CN.GB18030"
)
last_err: locale.Error | None = None
for name in _list_locale_candidates():
try:
@@ -60,6 +87,5 @@ def ensure_process_locale() -> str:
raise RuntimeError(
"未找到可用 localevnpy_ctp 会在 CTP 登录后崩溃。"
"请执行: apt install -y locales && locale-gen en_US.UTF-8 && "
"update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8"
"请执行: apt install -y locales && locale-gen zh_CN.GB18030 en_US.UTF-8"
) from last_err
+4 -1
View File
@@ -9,7 +9,7 @@ import sys
BASE = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BASE)
from locale_fix import ensure_process_locale
from locale_fix import ensure_process_locale, missing_ctp_locales
ensure_process_locale()
@@ -40,6 +40,9 @@ def main() -> int:
print("=== SimNow 配置 ===")
print(f"locale = {ensure_process_locale()}")
missing = missing_ctp_locales()
if missing:
print(f"警告: 缺少 CTP 所需 locale: {', '.join(missing)}")
print(f"SIMNOW_USER = {user or '(未设置)'}")
print(f"SIMNOW_PASSWORD = {'*' * 8 if os.getenv('SIMNOW_PASSWORD') else '(未设置)'}")
print(f"SIMNOW_TD = {td}")