- position_closer: 去掉 Redis 依赖,平仓条件仅名义+未实现盈亏 - requirements: 移除 redis - settings.toml: 仅保留实际使用的配置项 - 新增 Dockerfile(仅安装依赖)、docker-compose(挂载代码与配置) - 新增 .dockerignore、.gitignore(含 nohup.log) Co-authored-by: Cursor <cursoragent@cursor.com>
5.3 KiB
5.3 KiB
币安永续合约定时平仓
定时从币安获取永续合约持仓,当满足条件时对该合约的多空进行限价平仓。
技术栈:币安合约使用 python-binance 的 AsyncClient(aio 异步接口),Redis 使用 redis.asyncio(与 aioredis 用法兼容的异步接口)。
逻辑
- 平仓前置条件(不满足则直接退出,不执行后续平仓):
- 获取当前账户总未实现盈亏,写入 Redis Sorted Set(历史记录);
- 取近 N 分钟(默认 5 分钟)内历史中的最小总未实现盈亏;
- 仅当 当前总未实现盈亏 - 该最小 > 配置阈值(默认 2 USDT)时,才继续执行平仓逻辑;否则退出。
- 定时拉取持仓:按配置间隔调用币安
GET /fapi/v2/positionRisk获取 USDT 永续持仓。 - 触发条件(满足其一即对该合约平仓):
- Redis 中指定 key 的 Set 里包含该合约 symbol(如
BTCUSDT)时强制平仓; - 该合约多空名义价值总和 <
notional_small_close_threshold(默认 30 USDT)且未实现盈亏 >small_close_min_profit(默认 0.03 USDT)。
- Redis 中指定 key 的 Set 里包含该合约 symbol(如
- 平仓方式:
- 多头:限价卖出,价格 = 当前价 × 1.003;
- 空头:限价买入,价格 = 当前价 × 0.997。
- 若因 Redis 触发平仓,平仓后会从该 Set 中移除该 symbol。
配置(Dynaconf)
配置通过 Dynaconf 加载,按优先级:环境变量 > .secrets.toml > settings.toml。环境变量需加前缀 BINANCE_POSITION_(如 BINANCE_POSITION_BINANCE_API_KEY)。
- settings.toml:所有非敏感配置均在此文件,可直接修改。
- .secrets.toml:仅放敏感信息(复制
.secrets.toml.example为.secrets.toml后填写),勿提交。
| 配置项 | 说明 | 所在文件 |
|---|---|---|
binance_api_key |
币安 API Key(需合约权限) | .secrets.toml |
binance_api_secret |
币安 API Secret | .secrets.toml |
binance_base_url |
合约 API 地址 | settings.toml |
redis_url |
Redis 连接 | settings.toml |
redis_close_key |
强制平仓合约的 Redis Set key | settings.toml |
redis_unrealized_profit_history_key |
总未实现盈亏历史的 Sorted Set key,用于平仓前置条件,默认 close_position:unrealized_profit_history |
settings.toml |
unrealized_profit_window_seconds |
平仓前置条件:近 N 秒内最小总未实现盈亏作为基准,默认 300(5 分钟) | settings.toml |
unrealized_profit_min_rise |
平仓前置条件:当前总未实现盈亏 - 近 N 秒最小 须大于此值(USDT)才执行平仓,默认 2 | settings.toml |
notional_threshold |
大仓位阈值(USDT):多空价值总和大于此值且盈利大于 notional_large_close_min_profit 时平仓,默认 50 | settings.toml |
notional_large_close_min_profit |
大仓位平仓最低盈利(USDT):大仓位未实现盈亏须大于此值,默认 0.3 | settings.toml |
notional_small_close_threshold |
小仓位平仓阈值(USDT):多空价值总和小于此值且盈利大于 small_close_min_profit 时平仓,默认 30 | settings.toml |
small_close_min_profit |
小仓位平仓最低盈利(USDT):小仓位未实现盈亏须大于此值,默认 0.03 | settings.toml |
interval_seconds |
轮询间隔(秒),当前流程备用 | settings.toml |
dry_run |
默认 true(dry-run,不真实下单);设为 false 或 DRY_RUN=0 时真实下单 |
settings.toml |
默认 dry-run:脚本默认只跑全流程并打印将下的单,不真实下单、不从 Redis 移除。要真实平仓时,在 settings.toml 中设置 dry_run = false,或运行前设置环境变量 DRY_RUN=0。
安装与运行
使用项目内 venv 初始化环境并运行:
# 创建虚拟环境(若尚未创建)
python3 -m venv .venv
# 激活虚拟环境并安装依赖
.venv/bin/pip install -r requirements.txt
# 运行
.venv/bin/python position_closer.py
或先激活 venv 再执行:
source .venv/bin/activate # Linux/macOS
pip install -r requirements.txt
python position_closer.py
每小时定时运行
项目内提供 run_position_closer.sh:
# 运行一次
./run_position_closer.sh
# 前台每 1 小时运行一次(循环,Ctrl+C 停止)
./run_position_closer.sh loop
用 crontab 每小时整点执行一次(将路径换成你的项目目录):
crontab -e
# 添加一行(整点执行):
0 * * * * /home/yanhaoyang/Projects/bn-pc/run_position_closer.sh
通过 Redis 指定平仓合约
向 Redis Set 添加需要平仓的合约 symbol 即可,下一轮轮询会对其多空进行平仓,并在平仓后从 Set 中移除:
redis-cli SADD close_position:contracts BTCUSDT ETHUSDT
(若修改了 redis_close_key,请使用你配置的 key。)
注意事项
- 支持单向持仓(positionSide=BOTH)与双向持仓(LONG/SHORT)。
- 平仓使用限价单,若市价偏离较多可能不会立刻成交,需自行在交易所查看或撤单改市价。
- API Key 需有 USDT 永续合约的读取与交易权限;建议先用测试网验证。