feat(binance_client, config): 添加单向持仓模式配置以优化交易逻辑

在 `binance_client.py` 中引入了 `ONE_WAY_POSITION_ONLY` 配置,确保在单向持仓模式下不传递 `positionSide`,避免对冲模式检测。同时,更新了 `config.py`,新增该配置项以支持该功能,提升了交易策略的灵活性与风险控制能力。
This commit is contained in:
薇薇安 2026-02-20 00:40:23 +08:00
parent bfe3d8ec75
commit 2c5524bdcf
2 changed files with 23 additions and 53 deletions

View File

@ -600,7 +600,13 @@ class BinanceClient:
获取币安合约持仓模式
- True: 对冲模式Hedge Mode需要下单时传 positionSide=LONG/SHORT
- False: 单向模式One-way Mode不应传 positionSide=LONG/SHORT
若配置 ONE_WAY_POSITION_ONLY=True直接返回 False不请求 API
"""
one_way_only = bool(config.TRADING_CONFIG.get("ONE_WAY_POSITION_ONLY", True))
if one_way_only:
self._dual_side_position = False
return False
if not self.client:
return None
@ -2372,11 +2378,13 @@ class BinanceClient:
"""
try:
symbol_info = await self.get_symbol_info(symbol)
one_way_only = bool(config.TRADING_CONFIG.get("ONE_WAY_POSITION_ONLY", True))
dual = None
try:
dual = await self._get_dual_side_position()
except Exception:
dual = None
if not one_way_only:
try:
dual = await self._get_dual_side_position()
except Exception:
dual = None
pd = (position_direction or "").upper()
if pd not in {"BUY", "SELL"}:
@ -2471,70 +2479,31 @@ class BinanceClient:
"closePosition": True,
}
# 对冲模式:必须指定 positionSide
# ⚠️ 优化如果对冲模式检测失败dual is None先尝试不传 positionSide单向模式失败再尝试传 positionSide
if dual is True:
# 单向持仓模式ONE_WAY_POSITION_ONLY不传 positionSide否则按检测结果处理
if not one_way_only and dual is True:
params["positionSide"] = "LONG" if pd == "BUY" else "SHORT"
elif dual is None:
# 对冲模式检测失败:先尝试单向模式(不传 positionSide如果失败再尝试对冲模式
logger.debug(f"{symbol} 对冲模式检测失败dual=None先尝试单向模式不传 positionSide")
# 走 Algo Order 接口(避免 -4120
order = await self.futures_create_algo_order(params)
if order:
return order
# 兜底:对冲/单向模式可能导致 positionSide 误判,尝试切换一次
logger.warning(f"{symbol} 首次挂保护单失败,尝试切换 positionSide 重试...")
if dual is True:
# 仅在对冲模式且未配置 ONE_WAY_POSITION_ONLY 时,尝试移除 positionSide 重试一次
if not one_way_only and dual is True:
logger.warning(f"{symbol} 首次挂保护单失败,尝试移除 positionSide 重试...")
retry = dict(params)
retry.pop("positionSide", None)
# 关键修复:重试时必须清除之前的 timestamp 和 signature
retry.pop("timestamp", None)
retry.pop("signature", None)
logger.debug(f"{symbol} 重试1: 移除 positionSide对冲模式 -> 单向模式)")
retry_order = await self.futures_create_algo_order(retry)
if retry_order:
logger.info(f"{symbol} ✓ 重试成功(移除 positionSide")
return retry_order
elif dual is False:
# 单向模式首次失败:尝试添加 positionSide可能是对冲模式但检测失败
retry = dict(params)
retry["positionSide"] = "LONG" if pd == "BUY" else "SHORT"
# 关键修复:重试时必须清除之前的 timestamp 和 signature
retry.pop("timestamp", None)
retry.pop("signature", None)
logger.debug(f"{symbol} 重试1: 添加 positionSide={retry['positionSide']}(单向模式 -> 对冲模式)")
retry_order = await self.futures_create_algo_order(retry)
if retry_order:
logger.info(f"{symbol} ✓ 重试成功(添加 positionSide")
return retry_order
elif dual is None:
# 对冲模式检测失败:先尝试单向模式失败后,再尝试对冲模式
retry = dict(params)
if "positionSide" in retry:
retry.pop("positionSide", None)
retry.pop("timestamp", None)
retry.pop("signature", None)
logger.debug(f"{symbol} 重试1: 移除 positionSide对冲模式检测失败 -> 单向模式)")
retry_order = await self.futures_create_algo_order(retry)
if retry_order:
logger.info(f"{symbol} ✓ 重试成功(移除 positionSide")
return retry_order
else:
retry["positionSide"] = "LONG" if pd == "BUY" else "SHORT"
retry.pop("timestamp", None)
retry.pop("signature", None)
logger.debug(f"{symbol} 重试2: 添加 positionSide={retry['positionSide']}(单向模式失败 -> 对冲模式)")
retry_order = await self.futures_create_algo_order(retry)
if retry_order:
logger.info(f"{symbol} ✓ 重试成功(添加 positionSide")
return retry_order
# 如果还是失败,记录详细参数用于调试
logger.error(f"{symbol} ❌ 所有重试都失败,保护单挂单失败")
logger.error(f"{symbol} ❌ 保护单挂单失败")
logger.error(f" 参数: {params}")
logger.error(f" 对冲模式: {dual}None 表示无法读取持仓模式,请检查网络或 API 权限)")
if not one_way_only:
logger.error(f" 对冲模式: {dual}None 表示无法读取持仓模式,请检查网络或 API 权限)")
return None
except BinanceAPIException as e:

View File

@ -186,6 +186,7 @@ DEFAULT_TRADING_CONFIG = {
'AUTO_TRADE_ENABLED': True, # 自动交易总开关
'MAX_OPEN_POSITIONS': 4, # 同时持仓数量上限总仓位12% / 单笔1.5% = 最多4个
'MAX_DAILY_ENTRIES': 15, # 每日最多15笔快速验证模式提高上限以快速验证策略
'ONE_WAY_POSITION_ONLY': True, # 账号固定为单向持仓模式,不传 positionSide不检测对冲模式避免 -4061
'MAX_POSITION_PERCENT': 0.20, # 单笔仓位上限20%(作为风控熔断,实际仓位由固定风险模型决定)
'MAX_TOTAL_POSITION_PERCENT': 0.80, # 总仓位80%(避免满仓,留有余地)