From d75527a9ca59a27d8b185752fef1970f3d2a0ee7 Mon Sep 17 00:00:00 2001 From: dekun Date: Thu, 4 Jun 2026 07:47:18 +0800 Subject: [PATCH] docs(env): unify auto-transfer config across four exchanges Align .env.example blocks and add sync script to merge AUTO_TRANSFER_* into existing instance .env files without touching API secrets. Co-authored-by: Cursor --- crypto_monitor_binance/.env.example | 8 +- crypto_monitor_gate/.env.example | 8 +- crypto_monitor_gate_bot/.env.example | 8 +- crypto_monitor_okx/.env.example | 8 +- deploy/README.md | 10 ++ scripts/sync_four_exchange_transfer_env.py | 115 +++++++++++++++++++++ 6 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 scripts/sync_four_exchange_transfer_env.py diff --git a/crypto_monitor_binance/.env.example b/crypto_monitor_binance/.env.example index 74f0652..886cbae 100644 --- a/crypto_monitor_binance/.env.example +++ b/crypto_monitor_binance/.env.example @@ -130,12 +130,17 @@ MONITOR_POLL_SECONDS=3 # 使用可用资金时的缓冲比例(如0.98代表用98%) FULL_MARGIN_BUFFER_RATIO=0.98 -# 自动划转:将目标账户补足到 AUTO_TRANSFER_AMOUNT(ccxt:funding↔swap 等) +# ============================================================================= +# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值) +# ============================================================================= AUTO_TRANSFER_ENABLED=false +# 合约/交易账户(AUTO_TRANSFER_TO)补足到的 USDT 总额,非每日开仓基数 AUTO_TRANSFER_AMOUNT=30 AUTO_TRANSFER_FROM=funding AUTO_TRANSFER_TO=swap TRANSFER_CCY=USDT +# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重 +AUTO_TRANSFER_BJ_HOUR=8 # 强制清仓整点(北京时间,默认 0=凌晨00点) FORCE_CLOSE_BJ_HOUR=0 # 是否启用强制清仓(默认关闭,true 才会在整点执行) @@ -182,5 +187,4 @@ AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest # DEFAULT_TRADE_STYLE=trend APP_TIMEZONE=Asia/Shanghai -AUTO_TRANSFER_BJ_HOUR=8 # TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点,默认 8 点起算新交易日;开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED diff --git a/crypto_monitor_gate/.env.example b/crypto_monitor_gate/.env.example index f2aa45f..e75689c 100644 --- a/crypto_monitor_gate/.env.example +++ b/crypto_monitor_gate/.env.example @@ -136,12 +136,17 @@ RECONCILE_FLAT_CONFIRM_POLLS=3 # 使用可用资金时的缓冲比例(如0.98代表用98%) FULL_MARGIN_BUFFER_RATIO=0.98 -# 自动划转:将目标账户补足到 AUTO_TRANSFER_AMOUNT +# ============================================================================= +# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值) +# ============================================================================= AUTO_TRANSFER_ENABLED=false +# 交易账户(AUTO_TRANSFER_TO)补足到的 USDT 总额,非每日开仓基数 AUTO_TRANSFER_AMOUNT=30 AUTO_TRANSFER_FROM=funding AUTO_TRANSFER_TO=swap TRANSFER_CCY=USDT +# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重 +AUTO_TRANSFER_BJ_HOUR=8 # 强制清仓整点(北京时间,默认 0=凌晨00点) FORCE_CLOSE_BJ_HOUR=0 # 是否启用强制清仓(默认关闭,true 才会在整点执行) @@ -186,5 +191,4 @@ AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest # DEFAULT_TRADE_STYLE=trend APP_TIMEZONE=Asia/Shanghai -AUTO_TRANSFER_BJ_HOUR=8 # TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点,默认 8 点起算新交易日;开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED diff --git a/crypto_monitor_gate_bot/.env.example b/crypto_monitor_gate_bot/.env.example index cf64475..b6f7f1c 100644 --- a/crypto_monitor_gate_bot/.env.example +++ b/crypto_monitor_gate_bot/.env.example @@ -104,12 +104,17 @@ MONITOR_POLL_SECONDS=3 # 使用可用资金时的缓冲比例(如0.98代表用98%) FULL_MARGIN_BUFFER_RATIO=0.98 -# 自动划转:将目标账户补足到 AUTO_TRANSFER_AMOUNT +# ============================================================================= +# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值) +# ============================================================================= AUTO_TRANSFER_ENABLED=false +# 交易账户(AUTO_TRANSFER_TO)补足到的 USDT 总额,非每日开仓基数 AUTO_TRANSFER_AMOUNT=30 AUTO_TRANSFER_FROM=funding AUTO_TRANSFER_TO=swap TRANSFER_CCY=USDT +# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重 +AUTO_TRANSFER_BJ_HOUR=8 # 强制清仓整点(北京时间,默认 0=凌晨00点) FORCE_CLOSE_BJ_HOUR=0 # 是否启用强制清仓(默认关闭,true 才会在整点执行) @@ -160,5 +165,4 @@ AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest # TREND_PREVIEW_MAX_BALANCE_DRIFT_PCT=5 APP_TIMEZONE=Asia/Shanghai -AUTO_TRANSFER_BJ_HOUR=8 # TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点,默认 8 点起算新交易日;开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED diff --git a/crypto_monitor_okx/.env.example b/crypto_monitor_okx/.env.example index fc66edf..a9f6697 100644 --- a/crypto_monitor_okx/.env.example +++ b/crypto_monitor_okx/.env.example @@ -95,12 +95,17 @@ BREAKEVEN_EXCHANGE_MIN_INTERVAL_SEC=60 # 使用可用资金时的缓冲比例(如0.98代表用98%) FULL_MARGIN_BUFFER_RATIO=0.98 -# 自动划转:将目标账户补足到 AUTO_TRANSFER_AMOUNT +# ============================================================================= +# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值) +# ============================================================================= AUTO_TRANSFER_ENABLED=false +# 交易账户(AUTO_TRANSFER_TO)补足到的 USDT 总额,非每日开仓基数 AUTO_TRANSFER_AMOUNT=30 AUTO_TRANSFER_FROM=funding AUTO_TRANSFER_TO=swap TRANSFER_CCY=USDT +# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重 +AUTO_TRANSFER_BJ_HOUR=8 # 强制清仓整点(北京时间,默认 0=凌晨00点) FORCE_CLOSE_BJ_HOUR=0 # 是否启用强制清仓(默认关闭,true 才会在整点执行) @@ -148,7 +153,6 @@ AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest # DEFAULT_TRADE_STYLE=trend APP_TIMEZONE=Asia/Shanghai -AUTO_TRANSFER_BJ_HOUR=8 # TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点,默认 8 点起算新交易日/可开仓等 # 默认启用「北京时间 TRADING_DAY_RESET_HOUR 前禁止新开仓」;网页顶栏可运行时切换(写入 DB) diff --git a/deploy/README.md b/deploy/README.md index ed35eec..1099041 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -85,6 +85,16 @@ bash deploy/setup_env.sh 3. 服务器长期运行见各目录 **《部署文档.md》**(SSH SOCKS、PM2)。 4. **多账户中控**(`manual_trading_hub`):编辑 `manual_trading_hub/.env`(`HUB_PASSWORD`、`HUB_BRIDGE_TOKEN` 等与四实例一致),再 `pm2 start ecosystem.config.cjs`;验收 `bash manual_trading_hub/scripts/verify_hub_deploy.sh`。详见 [manual_trading_hub/部署文档.md](../manual_trading_hub/部署文档.md)、[常见问题.md](../manual_trading_hub/常见问题.md)。 +## 四所 `.env` 自动划转项(已有 .env 时) + +`AUTO_TRANSFER_AMOUNT` 等与 `DAILY_START_CAPITAL` **独立**;四所 `.env.example` 已统一注释。若服务器上已有 `.env`,可合并写入(不覆盖 API 密钥): + +```bash +python scripts/sync_four_exchange_transfer_env.py +# 缺 AUTO_TRANSFER_AMOUNT 时会沿用该文件中的 DAILY_START_CAPITAL +pm2 restart crypto-monitor-binance crypto-monitor-okx crypto-monitor-gate crypto-monitor-gate-bot +``` + ## 依赖说明 - 四个监控子项目共用仓库根目录 **[requirements.txt](../requirements.txt)**。 diff --git a/scripts/sync_four_exchange_transfer_env.py b/scripts/sync_four_exchange_transfer_env.py new file mode 100644 index 0000000..98ede86 --- /dev/null +++ b/scripts/sync_four_exchange_transfer_env.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +""" +将自动划转 / 币安资金账户相关项写入四所实例 .env(已存在则更新,缺失则追加)。 + +用法(仓库根目录): + python scripts/sync_four_exchange_transfer_env.py + python scripts/sync_four_exchange_transfer_env.py --dry-run + +不修改 API 密钥与其它自定义项;若 .env 不存在则跳过(请先从 .env.example 复制)。 +""" +from __future__ import annotations + +import argparse +import os +import re + +REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +INSTANCES = ( + "crypto_monitor_binance", + "crypto_monitor_okx", + "crypto_monitor_gate", + "crypto_monitor_gate_bot", +) + +# 四所统一(页顶「将 swap 补足到 XU」= AUTO_TRANSFER_AMOUNT,与 DAILY_START_CAPITAL 独立) +COMMON_KEYS = { + "AUTO_TRANSFER_ENABLED": "false", + "AUTO_TRANSFER_FROM": "funding", + "AUTO_TRANSFER_TO": "swap", + "TRANSFER_CCY": "USDT", + "AUTO_TRANSFER_BJ_HOUR": "8", +} + +BINANCE_ONLY = { + "BINANCE_FUNDING_INCLUDE_SPOT": "false", +} + + +def _parse_env(path: str) -> list[str]: + if not os.path.isfile(path): + return [] + with open(path, "r", encoding="utf-8", errors="ignore") as f: + return f.read().replace("\r\n", "\n").replace("\r", "\n").splitlines() + + +def _env_get(lines: list[str], key: str) -> str | None: + pat = re.compile(r"^\s*" + re.escape(key) + r"\s*=\s*(.*)\s*$") + for line in lines: + m = pat.match(line) + if m: + return m.group(1).strip().strip('"').strip("'") + return None + + +def _upsert(lines: list[str], key: str, value: str) -> list[str]: + pat = re.compile(r"^\s*" + re.escape(key) + r"\s*=") + out = [] + replaced = False + for line in lines: + if pat.match(line): + if not replaced: + out.append(f"{key}={value}") + replaced = True + continue + out.append(line) + if not replaced: + if out and out[-1].strip(): + out.append("") + out.append(f"{key}={value}") + return out + + +def _ensure_transfer_block(lines: list[str], extra: dict[str, str]) -> list[str]: + daily = _env_get(lines, "DAILY_START_CAPITAL") + amount = _env_get(lines, "AUTO_TRANSFER_AMOUNT") + if amount is None: + amount = daily if daily else "30" + keys = dict(COMMON_KEYS) + keys["AUTO_TRANSFER_AMOUNT"] = amount + keys.update(extra) + for k, v in keys.items(): + lines = _upsert(lines, k, v) + return lines + + +def sync_one(dir_name: str, dry_run: bool) -> str: + env_path = os.path.join(REPO, dir_name, ".env") + if not os.path.isfile(env_path): + return f"SKIP {dir_name}: 无 .env(请 cp .env.example .env)" + lines = _parse_env(env_path) + extra = dict(BINANCE_ONLY) if dir_name == "crypto_monitor_binance" else {} + new_lines = _ensure_transfer_block(lines, extra) + if new_lines == lines: + return f"OK {dir_name}: 已是最新" + if dry_run: + return f"DRY {dir_name}: 将更新 {len([1 for a,b in zip(lines,new_lines) if a!=b])}+ 行" + with open(env_path, "w", encoding="utf-8", newline="\n") as f: + f.write("\n".join(new_lines)) + if new_lines and new_lines[-1].strip(): + f.write("\n") + amt = _env_get(new_lines, "AUTO_TRANSFER_AMOUNT") + return f"DONE {dir_name}: AUTO_TRANSFER_AMOUNT={amt}" + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--dry-run", action="store_true") + args = ap.parse_args() + for name in INSTANCES: + print(sync_one(name, args.dry_run)) + + +if __name__ == "__main__": + main()