Files

337 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Crypto ATR Signal
Version: `v1.3.1`
扫描 Binance Futures 交易对,在 4 小时周期识别已收盘 K 线的大阳 / 大阴信号,并通过 FastAPI 网页展示。
## 核心逻辑
- 数据源:Binance Futures
- 市场:
- CryptoUSDT Perpetual crypto 合约
- TradFiBinance Futures 传统金融类合约
- 周期:4H
- ATRTradingView 默认 `ATR(14, RMA)`
- 默认过滤:`High - Low >= ATR * 1.5`
- 方向:
- `Close > Open`:大阳
- `Close < Open`:大阴
- 已收盘判定:只接受 `close_time <= 当前 UTC 时间` 的 K 线
- 页面时间:按 `Europe/Madrid` 显示
## v1.2 变化
- 增加 TradFi 市场模块。
- 首页增加 Crypto / TradFi 市场切换。
- Crypto 和 TradFi 使用独立参数,不共用 ATR 长度、过滤倍数、实体过滤设置。
- 数据库增加 `market_type`,旧 Crypto 数据会自动迁移为 `CRYPTO`
- 扫描命令增加 `--market crypto` / `--market tradfi`
## v1.2.1 变化
- TradFi 使用休市友好逻辑:按 Binance 实际返回的已收盘 K 线处理,不把休市时间段强行当作漏档。
- Crypto 保持严格 4H 时间轴检查。
- 新增 `scan_runs` 扫描记录表。
## v1.3.0 变化
- 增加 `--market all`,一次完成 Crypto 与 TradFi 扫描。
- 增加 Discord 聚合推送,一个总开关、每轮一条消息。
- 页面增加“全部”视图,支持按市场分组或合并排序。
- 页面默认视图、市场入口、分组和版本信息可通过 `.env` 控制。
## v1.3.1 变化
- Discord 汇总使用当前最新 K 线信号总数,重复扫描不会误报为 0。
- 增加扫描进程锁,避免 Cron 任务重叠。
- 增加 `/health` 健康检查接口。
- TradFi 新部署默认启用实体占比 `0.5` 过滤。
## 项目结构
```text
crypto-atr-signal
├── scanner.py # 定时扫描:拉 K 线、补缺口、算 ATR、写 signals
├── webapp.py # FastAPI 网页展示
├── templates/
│ └── index.html
├── data/app.db # SQLite 数据库,运行后生成
├── .env.example
├── requirements.txt
├── VERSION
├── CHANGELOG.md
├── ROADMAP.md
└── README.md
```
## 升级路线
后续版本规划与指标口径见 [ROADMAP.md](ROADMAP.md)。当前下一目标为 `v1.4.0`“市场温度”,当前运行版本仍为 `v1.3.1`
## 获取与更新项目
推荐使用 SSH 克隆。Gitea 的 SSH 服务使用 `2222` 端口:
```bash
git clone ssh://git@git.polarisx.net:2222/mikemoi/crypto-atr-signal.git
cd crypto-atr-signal
```
也可以使用 HTTPS
```bash
git clone https://git.polarisx.net/mikemoi/crypto-atr-signal.git
cd crypto-atr-signal
```
私有仓库通过 HTTPS 克隆时,请使用 Gitea 用户名和访问令牌,不要把账户密码写进命令或脚本。
服务器已经部署过项目时,使用以下命令获取最新版本:
```bash
cd /www/wwwroot/crypto-atr-signal
git pull --ff-only origin main
.venv/bin/pip install -r requirements.txt
sudo systemctl restart crypto-atr-signal
```
`.env``data/app.db`、日志和虚拟环境已被 `.gitignore` 排除,执行 `git pull` 不会覆盖这些本地运行数据。更新前不要删除 `data` 目录或 `.env` 文件。
## 安装
```bash
cd /www/wwwroot/crypto-atr-signal
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env
chmod 600 .env
```
## 配置
```env
CRYPTO_ATR_LENGTH=14
CRYPTO_ATR_MULTIPLE=1.5
CRYPTO_BODY_RATIO_FILTER_ENABLED=false
CRYPTO_MIN_BODY_RATIO=0.5
TRADFI_ATR_LENGTH=14
TRADFI_ATR_MULTIPLE=1.5
TRADFI_BODY_RATIO_FILTER_ENABLED=true
TRADFI_MIN_BODY_RATIO=0.5
DISCORD_ENABLED=false
DISCORD_WEBHOOK_URL=
PAGE_DEFAULT_VIEW=all
PAGE_SHOW_ALL=true
PAGE_SHOW_CRYPTO=true
PAGE_SHOW_TRADFI=true
PAGE_GROUP_BY_MARKET=true
PAGE_SHOW_VERSION=true
SCAN_LOCK_PATH=data/scanner.lock
HEALTH_MAX_SCAN_AGE_HOURS=8
INIT_KLINES_LIMIT=40
CONCURRENCY=10
MAX_RETRIES=3
RATE_LIMIT_BACKOFF=30
KLINES_RETENTION_PER_SYMBOL=500
SIGNAL_RETENTION_DAYS=90
DB_PATH=data/app.db
```
## 扫描
首次运行会为对应市场的每个品种下载最近 `INIT_KLINES_LIMIT` 根 4H 已收盘 K 线,用于初始化 ATR。
之后再次运行时:
- 没有历史数据:初始化最近 40 根 K 线
- 有历史数据且无缺口:只拉最新 2 根
- 有缺口:只补中间缺失的 K 线
- 单个品种失败:记录错误并跳过,不阻塞整轮扫描
手动扫描:
```bash
.venv/bin/python scanner.py --market all
.venv/bin/python scanner.py --market crypto
.venv/bin/python scanner.py --market tradfi
```
Discord 聚合推送只由 `--market all` 触发。单独扫描某个市场不会发送汇总消息。
## Cron
建议服务器使用 UTC 时区。Binance 4H K 线按 UTC 收盘:
```text
00:00 / 04:00 / 08:00 / 12:00 / 16:00 / 20:00 UTC
```
推荐使用一条聚合 cron
```cron
# Binance 4H close + 1 min, UTC;扫描两个市场后发送一条 Discord 汇总
1 0,4,8,12,16,20 * * * cd /www/wwwroot/crypto-atr-signal && .venv/bin/python scanner.py --market all >> scanner.log 2>&1
```
对应马德里时间:
- 夏令时:02:01 / 06:01 / 10:01 / 14:01 / 18:01 / 22:01
- 冬令时:01:01 / 05:01 / 09:01 / 13:01 / 17:01 / 21:01
## 启动网页
```bash
.venv/bin/python -m uvicorn webapp:app --host 127.0.0.1 --port 8000
```
访问:
- 全部:`http://127.0.0.1:8000/?market=all&sort=desc`
- Crypto`http://127.0.0.1:8000/?market=crypto&sort=desc`
- TradFi`http://127.0.0.1:8000/?market=tradfi&sort=desc`
## systemd 常驻网页
```ini
[Unit]
Description=Crypto ATR Signal Web
After=network.target
[Service]
WorkingDirectory=/www/wwwroot/crypto-atr-signal
ExecStart=/www/wwwroot/crypto-atr-signal/.venv/bin/python -m uvicorn webapp:app --host 127.0.0.1 --port 8000
Restart=always
RestartSec=3
User=www
Group=www
[Install]
WantedBy=multi-user.target
```
启用:
```bash
sudo systemctl daemon-reload
sudo systemctl enable crypto-atr-signal
sudo systemctl start crypto-atr-signal
sudo systemctl status crypto-atr-signal
```
## Nginx 反向代理
FastAPI 只监听 `127.0.0.1:8000`,公网访问交给 Nginx
```nginx
server {
listen 80;
server_name signal.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
修改域名后执行:
```bash
sudo nginx -t
sudo systemctl reload nginx
```
生产环境建议为域名配置 HTTPS;如果页面只供客户使用,可在 Nginx 增加访问认证。
## 健康检查
```bash
curl http://127.0.0.1:8000/health
```
数据库正常、Crypto 与 TradFi 最近一次扫描成功且未超过 `HEALTH_MAX_SCAN_AGE_HOURS` 时返回 HTTP `200`。数据库异常、扫描失败或超时未运行时返回 HTTP `503`,可直接接入宝塔或 Uptime Kuma。
## 数据库备份与恢复
使用 SQLite 自带的在线备份命令,不需要停止网页服务:
```bash
cd /www/wwwroot/crypto-atr-signal
mkdir -p backups
sqlite3 data/app.db ".backup 'backups/app-$(date +%F-%H%M).db'"
```
恢复前先停止网页服务,并确保扫描任务没有运行:
```bash
sudo systemctl stop crypto-atr-signal
cp backups/app-YYYY-MM-DD-HHMM.db data/app.db
sudo systemctl start crypto-atr-signal
```
## 常见故障排查
```bash
# 查看网页服务状态和最近日志
sudo systemctl status crypto-atr-signal
sudo journalctl -u crypto-atr-signal -n 100 --no-pager
# 手动执行一轮聚合扫描
cd /www/wwwroot/crypto-atr-signal
.venv/bin/python scanner.py --market all
# 检查网页和数据库健康状态
curl -i http://127.0.0.1:8000/health
```
如果日志出现 `another scanner process is already running`,说明上一轮尚未结束,本轮已被进程锁安全跳过,无需手动删除锁文件。
## 页面功能
- Crypto / TradFi 市场切换
- 交易对列表校对时间
- 最新已收盘 K 线时间
- 当前信号统计
- 大阳 / 大阴数量
- 扫描品种数量
- ATR 倍数点击切换正序 / 倒序
- 点击品种跳转 TradingView
## 数据库
使用 SQLite,并开启 WAL
```sql
PRAGMA journal_mode = WAL;
```
主要表:
- `symbols`:交易对列表,按 `market_type + symbol` 区分市场
- `klines`4H K 线和 ATR,按 `market_type + symbol + open_time` 存储
- `signals`:大阳 / 大阴信号,按 `market_type + symbol + open_time` 存储
## 资源建议
独立 `2C2G` VPS 足够运行:
- FastAPI 常驻
- SQLite
- cron 每 4 小时聚合扫描 Crypto 和 TradFi
- Nginx 反向代理
建议:
- `CONCURRENCY=8~10`
- 服务器时区用 UTC
- 页面显示马德里时间
- 不需要 MySQL / PostgreSQL