# `crypto_monitor_okx` 部署文档（Ubuntu）

**功能与页面操作** 见同目录 **[使用说明.md](./使用说明.md)**。Ubuntu 环境（Python / Node / PM2）见 **[docs/ubuntu-server.md](../docs/ubuntu-server.md)**。策略与 AI 见 **[策略交易说明.md](../策略交易说明.md)**、**[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**。

---

# 本地部署 + SSH SOCKS 转发 + PM2 启动指南（Ubuntu）

本文面向：**本地 Ubuntu 机器运行项目**，但 **本机直连 OKX 会被 TLS/SNI reset** 的场景。解决思路是：

- 本机启动 `ssh -D` 动态转发，把 **SOCKS5 出口**放到你可正常访问 OKX 的 VPS 上
- 项目通过环境变量 `OKX_SOCKS_PROXY=socks5h://127.0.0.1:1080` 让 `ccxt` 走 SOCKS
- **SSH 隧道**用 `ssh -D` 常驻（可用 tmux / autossh）；**Flask 应用** 仅用 **PM2** 托管（见 [docs/ubuntu-server.md](../docs/ubuntu-server.md)）

> 安全提醒：不要把 `.env`、私钥 `.pem`、OKX API Key 提交到 Git；文档里只用占位符。

---

## 0. 你需要准备的东西

- 一台 **Ubuntu** 本地机器（下文称“本机”）
- 一台可 SSH 登录、且 **能正常访问 OKX** 的 VPS（示例公网 IP：`47.76.87.111`，用户：`root`）
- VPS 登录方式：**SSH 私钥**（推荐）或密码（不推荐用于无人值守）
- 本机已安装：
  - `python3`、`python3-venv`、`pip`（或 `python3-pip`）
  - `git`（可选）
  - `curl`、`ssh`
  - `node` + `npm`（用于安装 `pm2`）

---

## 1. 从云服务器把项目同步到本地（推荐：打包下载）

在云服务器项目目录（包含 `app.py` 的目录）执行：

```bash
cd /opt/crypto_monitor/crypto_monitor_okx

# 可选：清理 Python 缓存，减少小文件传输
find . -type d -name __pycache__ -prune -exec rm -rf {} +
find . -type f -name "*.pyc" -delete

tar -czf crypto_monitor.tgz .
```

下载 `crypto_monitor.tgz` 到本机后解压：

```bash
mkdir -p /opt/crypto_monitor/crypto_monitor_okx
cd /opt/crypto_monitor
tar -xzf crypto_monitor.tgz -C crypto_monitor_okx
cd crypto_monitor_okx
cp -n .env.example .env    # 若尚无 .env
```

---

## 2. 配置 SSH 私钥与 `~/.ssh/config`（推荐）

把私钥放到本机（示例：`~/.ssh/vps1.pem`），并设置权限：

```bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
mv ~/Downloads/vps1.pem ~/.ssh/vps1.pem
chmod 600 ~/.ssh/vps1.pem
```

编辑 `~/.ssh/config`（没有就创建），添加：

```sshconfig
Host okx-vps
  HostName 47.76.87.111
  User root
  IdentityFile ~/.ssh/vps1.pem
  IdentitiesOnly yes
  ServerAliveInterval 30
  ServerAliveCountMax 3
  ExitOnForwardFailure yes
  BatchMode yes
```

测试：

```bash
ssh okx-vps true
```

> 如果你还没完全切到密钥登录（还会交互要密码），先把 `BatchMode yes` 注释掉，等密钥登录稳定后再打开。

---

## 3. 先手工验证：SSH SOCKS + OKX API

### 3.1 开一个本地 SOCKS（1080）

```bash
ssh -N -D 127.0.0.1:1080 okx-vps
```

保持该进程运行（另开终端继续下面步骤）。

### 3.2 验证 OKX 走 SOCKS 可用

```bash
curl -4 -Iv --max-time 15 --proxy socks5h://127.0.0.1:1080 https://www.okx.com/api/v5/public/time
```

看到 `HTTP/2 200`（或至少 TLS 握手成功且返回 JSON）即 OK。

---

## 4. Python 虚拟环境（venv）

在本机项目目录：

```bash
cd /opt/crypto_monitor/crypto_monitor_okx

python3 -m venv .venv
source .venv/bin/activate

python -m pip install -U pip
pip install flask requests ccxt werkzeug PySocks Pillow
```

> 说明：本仓库当前没有 `requirements.txt`。如果你希望“完全复刻云服务器依赖”，可以在云服务器项目环境里执行 `pip freeze > requirements.txt` 带回本机再 `pip install -r requirements.txt`（记得删掉明显无关/体积巨大的包）。

建议减少 `.pyc` 垃圾文件（可选）：

```bash
export PYTHONDONTWRITEBYTECODE=1
```

---

## 5. 配置环境变量（`.env.example` → `.env`）

| 文件 | 是否进 Git | 说明 |
|------|------------|------|
| **`.env.example`** | ✅ 是 | 变量模板与注释，可随 `git pull` 更新 |
| **`.env`** | ❌ 否 | 本机真实配置；`app.py` **只读此文件** |

### 5.1 首次配置

```bash
cd /opt/crypto_monitor/crypto_monitor_okx

cp -n .env.example .env    # 已存在 .env 时不覆盖
nano .env
```

### 5.2 备份与 `git pull`

- **`.env` 不在 Git 中**：`git pull` **不会**覆盖本地 `.env`。
- 远端若更新 **`.env.example`**，pull 后请**手动**把新增变量补进你的 `.env`。
- **升级前备份**：`cp .env .env.backup.$(date +%Y%m%d)`；恢复：`cp .env.backup.YYYYMMDD .env`。
- **换机**：`scp` 复制 `.env`，或新机 `cp .env.example .env` 后重填。

**AI 复盘**：四所共用根目录 **`ai_client.py`**。默认 **`AI_PROVIDER=openai`**，网关 `https://op.bz121.com/v1`，模型 `gemma4:e4b`；或改 **`ollama`** 走本机 Ollama。PM2 须 **`PYTHONPATH=..`**。详见 **[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**。

### 5.3 必填项检查（OKX + 代理）

至少确认/填写这些关键项（示例）：

```env
APP_HOST=127.0.0.1
APP_PORT=5000

# OKX（如需实盘）
LIVE_TRADING_ENABLED=false
OKX_API_KEY=...
OKX_API_SECRET=...
OKX_API_PASSPHRASE=...

# OKX 出口：走本机 SSH 动态转发 SOCKS
OKX_SOCKS_PROXY=socks5h://127.0.0.1:1080

# 开仓多周期K线图（可选）
# ORDER_CHART_ENABLED=true
# ORDER_CHART_TFS=4h,1h,15m,5m
# ORDER_CHART_LIMIT=100
# ORDER_CHART_DIR=static/images/order_charts
# DAILY_OPEN_ALERT_THRESHOLD=5
# DAILY_OPEN_HARD_LIMIT=0
# 说明见仓库 docs/daily-open-limit.md

# AI 复盘（默认 OpenAI 兼容网关；与 Ollama 二选一）
AI_PROVIDER=openai
AI_TIMEOUT_SECONDS=120
OPENAI_API_BASE=https://op.bz121.com/v1
OPENAI_API_KEY=你的密钥
OPENAI_MODEL=gemma4:e4b
# 本机 Ollama（仅 AI_PROVIDER=ollama）
OLLAMA_API=http://127.0.0.1:11434/api/generate
AI_MODEL=你的模型名
```

> 完整说明见仓库根 **[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**。`OPENAI_API_KEY` 在 [op.bz121.com](https://op.bz121.com/) 的 `gateway.json` 获取。

> `OKX_SOCKS_PROXY` 使用 `socks5h`：让 SOCKS 侧做域名解析（更贴近你 `curl --proxy socks5h://...` 的成功路径）。

---

## 6. 本机手工启动（验证 Flask）

确保：

1. SOCKS 隧道已运行（127.0.0.1:1080）
2. 虚拟环境已 `activate`
3. `.env` 已配置

启动：

```bash
cd /opt/crypto_monitor/crypto_monitor_okx
source .venv/bin/activate
python app.py
```

浏览器访问：`http://127.0.0.1:5000`（或你在 `.env` 配的端口）。

---

## 7. 安装 PM2（Node）

```bash
sudo npm i -g pm2
pm2 -v
```

---

## 8. 用 PM2 启动 SSH SOCKS 隧道（推荐：密钥免交互）

### 8.1 启动隧道进程

```bash
pm2 start "ssh" --name okx-socks-tunnel -- \
  -N -D 127.0.0.1:1080 okx-vps \
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
  -o ExitOnForwardFailure=yes -o BatchMode=yes
```

查看日志：

```bash
pm2 logs okx-socks-tunnel --lines 200
```

### 8.2 仍然验证 OKX

```bash
curl -4 -Iv --max-time 15 --proxy socks5h://127.0.0.1:1080 https://www.okx.com/api/v5/public/time
```

### 8.3 开机自启（可选）

```bash
pm2 save
pm2 startup
```

---

## 9. 用 PM2 启动 Flask（`app.py`）

`pm2` 管理 Python 的常用方式是直接启动解释器：

```bash
cd /opt/crypto_monitor/crypto_monitor_okx

pm2 start /opt/crypto_monitor/crypto_monitor_okx/.venv/bin/python --name crypto-monitor -- \
  /opt/crypto_monitor/crypto_monitor_okx/app.py
```

> 若项目目录与上文不一致，请替换为实际绝对路径；或用 `readlink -f app.py` 得到绝对路径。

查看日志：

```bash
pm2 logs crypto-monitor --lines 200
```

保存进程列表：

```bash
pm2 save
```

---

## 10. 常见问题排查（高频）

### 10.1 OKX 仍然失败：先看隧道是否在

```bash
ss -lntp | grep 1080 || true
pm2 status
```

### 10.2 `pm2` 里的 `ssh` 立刻退出

常见原因：

- 私钥权限不对（`chmod 600`）
- `~/.ssh/config` 写错 `HostName/User/IdentityFile`
- 开了 `BatchMode yes` 但仍需要密码（会失败）

### 10.3 `ccxt` SOCKS 报错 / 代理不生效

本机 Python 依赖通常需要：

```bash
source .venv/bin/activate
pip install PySocks
```

### 10.4 `.pyc` 很多导致同步慢

`.pyc` 是缓存，删除不影响功能：

```bash
find . -type d -name __pycache__ -prune -exec rm -rf {} +
find . -type f -name "*.pyc" -delete
```

---

## 11. 推荐的启动顺序（固定习惯）

1. `pm2` 启动 `okx-socks-tunnel`
2. `curl --proxy socks5h://127.0.0.1:1080 ...` 验证 OKX
3. `pm2` 启动 `crypto-monitor`

---

## 12. 免责声明

交易所有合规与地区政策要求。请确保你的使用方式符合当地法律法规与交易所条款。本文仅描述网络与工程部署技术路径。




写好了，脚本路径：

- `scripts/fix_breakeven_labels.py`

你在 Ubuntu 上这样用：

1) 先预览（不写库）：
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
```

2) 确认后执行：
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
```

默认修复条件就是你要的：
- `monitor_type='下单监控'`
- `result='止损'`
- `pnl_amount > 0`
- 改成 `result='保本止盈'`

如果你想，我还可以再给你一条“先自动备份 DB 再执行”的一键命令。