fix(account, binance_client, position_manager, risk_manager): 优化异常处理和代码风格
在多个模块中,增强了异常处理逻辑,确保在调用交易所API时能够正确捕获并记录错误信息。同时,调整了代码缩进和结构,提升了可读性和一致性。这一改动旨在提升系统的稳定性和风险控制能力,确保交易策略的有效性与安全性。
This commit is contained in:
parent
c53b67e294
commit
ff1d985859
|
|
@ -758,9 +758,9 @@ async def fetch_realtime_positions(account_id: int):
|
||||||
matched = None
|
matched = None
|
||||||
for db_trade in db_trades:
|
for db_trade in db_trades:
|
||||||
try:
|
try:
|
||||||
if abs(float(db_trade.get('entry_price', 0)) - entry_price) < 0.01:
|
if abs(float(db_trade.get('entry_price', 0)) - entry_price) < 0.01:
|
||||||
matched = db_trade
|
matched = db_trade
|
||||||
break
|
break
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
if matched is None:
|
if matched is None:
|
||||||
|
|
@ -938,8 +938,8 @@ async def close_position(symbol: str, account_id: int = Depends(get_account_id))
|
||||||
# 兼容旧逻辑:如果原始接口异常,回退到封装方法
|
# 兼容旧逻辑:如果原始接口异常,回退到封装方法
|
||||||
if not nonzero_positions:
|
if not nonzero_positions:
|
||||||
try:
|
try:
|
||||||
positions = await client.get_open_positions()
|
positions = await client.get_open_positions()
|
||||||
position = next((p for p in positions if p['symbol'] == symbol and float(p['positionAmt']) != 0), None)
|
position = next((p for p in positions if p['symbol'] == symbol and float(p['positionAmt']) != 0), None)
|
||||||
if position:
|
if position:
|
||||||
nonzero_positions = [(float(position["positionAmt"]), {"positionAmt": position["positionAmt"]})]
|
nonzero_positions = [(float(position["positionAmt"]), {"positionAmt": position["positionAmt"]})]
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
@ -1013,7 +1013,7 @@ async def close_position(symbol: str, account_id: int = Depends(get_account_id))
|
||||||
if dual_side is None:
|
if dual_side is None:
|
||||||
if any(isinstance(p, dict) and (p.get("positionSide") in ("LONG", "SHORT")) for _, p in nonzero_positions):
|
if any(isinstance(p, dict) and (p.get("positionSide") in ("LONG", "SHORT")) for _, p in nonzero_positions):
|
||||||
dual_side = True
|
dual_side = True
|
||||||
else:
|
else:
|
||||||
dual_side = False
|
dual_side = False
|
||||||
|
|
||||||
logger.info(f"{symbol} 持仓模式: {'HEDGE(对冲)' if dual_side else 'ONE-WAY(单向)'}")
|
logger.info(f"{symbol} 持仓模式: {'HEDGE(对冲)' if dual_side else 'ONE-WAY(单向)'}")
|
||||||
|
|
@ -1067,13 +1067,13 @@ async def close_position(symbol: str, account_id: int = Depends(get_account_id))
|
||||||
oid = order.get("orderId")
|
oid = order.get("orderId")
|
||||||
if oid:
|
if oid:
|
||||||
order_ids.append(oid)
|
order_ids.append(oid)
|
||||||
except Exception as order_error:
|
except Exception as order_error:
|
||||||
error_msg = f"{symbol} 平仓失败:下单异常 - {str(order_error)}"
|
error_msg = f"{symbol} 平仓失败:下单异常 - {str(order_error)}"
|
||||||
logger.error(error_msg)
|
logger.error(error_msg)
|
||||||
logger.error(f" 错误类型: {type(order_error).__name__}")
|
logger.error(f" 错误类型: {type(order_error).__name__}")
|
||||||
import traceback
|
import traceback
|
||||||
logger.error(f" 完整错误堆栈:\n{traceback.format_exc()}")
|
logger.error(f" 完整错误堆栈:\n{traceback.format_exc()}")
|
||||||
raise HTTPException(status_code=500, detail=error_msg)
|
raise HTTPException(status_code=500, detail=error_msg)
|
||||||
|
|
||||||
if not orders:
|
if not orders:
|
||||||
raise HTTPException(status_code=400, detail=f"{symbol} 无可平仓的有效仓位(数量调整后为0或无持仓)")
|
raise HTTPException(status_code=400, detail=f"{symbol} 无可平仓的有效仓位(数量调整后为0或无持仓)")
|
||||||
|
|
@ -1103,17 +1103,17 @@ async def close_position(symbol: str, account_id: int = Depends(get_account_id))
|
||||||
try:
|
try:
|
||||||
# 1. 获取价格
|
# 1. 获取价格
|
||||||
order_info = await client.client.futures_get_order(symbol=symbol, orderId=oid)
|
order_info = await client.client.futures_get_order(symbol=symbol, orderId=oid)
|
||||||
if order_info:
|
if order_info:
|
||||||
p = float(order_info.get('avgPrice', 0)) or float(order_info.get('price', 0))
|
p = float(order_info.get('avgPrice', 0)) or float(order_info.get('price', 0))
|
||||||
if p <= 0 and order_info.get('fills'):
|
if p <= 0 and order_info.get('fills'):
|
||||||
total_qty = 0
|
total_qty = 0
|
||||||
total_value = 0
|
total_value = 0
|
||||||
for fill in order_info.get('fills', []):
|
for fill in order_info.get('fills', []):
|
||||||
qty = float(fill.get('qty', 0))
|
qty = float(fill.get('qty', 0))
|
||||||
price = float(fill.get('price', 0))
|
price = float(fill.get('price', 0))
|
||||||
total_qty += qty
|
total_qty += qty
|
||||||
total_value += qty * price
|
total_value += qty * price
|
||||||
if total_qty > 0:
|
if total_qty > 0:
|
||||||
p = total_value / total_qty
|
p = total_value / total_qty
|
||||||
if p > 0:
|
if p > 0:
|
||||||
exit_prices[oid] = p
|
exit_prices[oid] = p
|
||||||
|
|
@ -1132,7 +1132,7 @@ async def close_position(symbol: str, account_id: int = Depends(get_account_id))
|
||||||
exit_realized_pnls[oid] = total_realized_pnl
|
exit_realized_pnls[oid] = total_realized_pnl
|
||||||
exit_commissions[oid] = total_commission
|
exit_commissions[oid] = total_commission
|
||||||
exit_commission_assets[oid] = "/".join(commission_assets) if commission_assets else None
|
exit_commission_assets[oid] = "/".join(commission_assets) if commission_assets else None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"获取订单详情失败 (orderId={oid}): {e}")
|
logger.warning(f"获取订单详情失败 (orderId={oid}): {e}")
|
||||||
|
|
||||||
# 兜底:如果无法获取订单价格,使用当前价格
|
# 兜底:如果无法获取订单价格,使用当前价格
|
||||||
|
|
@ -1150,8 +1150,8 @@ async def close_position(symbol: str, account_id: int = Depends(get_account_id))
|
||||||
used_order_ids = set()
|
used_order_ids = set()
|
||||||
for trade in open_trades:
|
for trade in open_trades:
|
||||||
try:
|
try:
|
||||||
entry_price = float(trade['entry_price'])
|
entry_price = float(trade['entry_price'])
|
||||||
trade_quantity = float(trade['quantity'])
|
trade_quantity = float(trade['quantity'])
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -1171,24 +1171,24 @@ async def close_position(symbol: str, account_id: int = Depends(get_account_id))
|
||||||
exit_price = fallback_exit_price or entry_price
|
exit_price = fallback_exit_price or entry_price
|
||||||
|
|
||||||
# 计算盈亏(数据库侧依旧按名义盈亏;收益率展示用保证金口径在前端/统计里另算)
|
# 计算盈亏(数据库侧依旧按名义盈亏;收益率展示用保证金口径在前端/统计里另算)
|
||||||
if trade['side'] == 'BUY':
|
if trade['side'] == 'BUY':
|
||||||
pnl = (exit_price - entry_price) * trade_quantity
|
pnl = (exit_price - entry_price) * trade_quantity
|
||||||
pnl_percent = ((exit_price - entry_price) / entry_price) * 100
|
pnl_percent = ((exit_price - entry_price) / entry_price) * 100
|
||||||
else:
|
else:
|
||||||
pnl = (entry_price - exit_price) * trade_quantity
|
pnl = (entry_price - exit_price) * trade_quantity
|
||||||
pnl_percent = ((entry_price - exit_price) / entry_price) * 100
|
pnl_percent = ((entry_price - exit_price) / entry_price) * 100
|
||||||
|
|
||||||
Trade.update_exit(
|
Trade.update_exit(
|
||||||
trade_id=trade['id'],
|
trade_id=trade['id'],
|
||||||
exit_price=exit_price,
|
exit_price=exit_price,
|
||||||
exit_reason='manual',
|
exit_reason='manual',
|
||||||
pnl=pnl,
|
pnl=pnl,
|
||||||
pnl_percent=pnl_percent,
|
pnl_percent=pnl_percent,
|
||||||
exit_order_id=chosen_oid,
|
exit_order_id=chosen_oid,
|
||||||
realized_pnl=exit_realized_pnls.get(chosen_oid),
|
realized_pnl=exit_realized_pnls.get(chosen_oid),
|
||||||
commission=exit_commissions.get(chosen_oid),
|
commission=exit_commissions.get(chosen_oid),
|
||||||
commission_asset=exit_commission_assets.get(chosen_oid)
|
commission_asset=exit_commission_assets.get(chosen_oid)
|
||||||
)
|
)
|
||||||
logger.info(f"✓ 已更新数据库记录 trade_id={trade['id']} order_id={chosen_oid} (盈亏: {pnl:.2f} USDT, {pnl_percent:.2f}%)")
|
logger.info(f"✓ 已更新数据库记录 trade_id={trade['id']} order_id={chosen_oid} (盈亏: {pnl:.2f} USDT, {pnl_percent:.2f}%)")
|
||||||
|
|
||||||
logger.info(f"✓ {symbol} 平仓成功")
|
logger.info(f"✓ {symbol} 平仓成功")
|
||||||
|
|
@ -1839,8 +1839,8 @@ async def sync_positions(
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not exit_price or exit_price <= 0:
|
if not exit_price or exit_price <= 0:
|
||||||
ticker = await client.get_ticker_24h(symbol)
|
ticker = await client.get_ticker_24h(symbol)
|
||||||
exit_price = float(ticker['price']) if ticker else entry_price
|
exit_price = float(ticker['price']) if ticker else entry_price
|
||||||
|
|
||||||
# 计算盈亏
|
# 计算盈亏
|
||||||
if trade['side'] == 'BUY':
|
if trade['side'] == 'BUY':
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ class BinanceClient:
|
||||||
# 连接前刷新API密钥(确保使用最新值,支持热更新)
|
# 连接前刷新API密钥(确保使用最新值,支持热更新)
|
||||||
# 但如果 API 密钥为空(只用于获取公开行情),则跳过
|
# 但如果 API 密钥为空(只用于获取公开行情),则跳过
|
||||||
if self.api_key and self.api_secret:
|
if self.api_key and self.api_secret:
|
||||||
self._refresh_api_credentials()
|
self._refresh_api_credentials()
|
||||||
else:
|
else:
|
||||||
logger.info("BinanceClient: 使用公开 API(无需认证),只能获取行情数据")
|
logger.info("BinanceClient: 使用公开 API(无需认证),只能获取行情数据")
|
||||||
|
|
||||||
|
|
@ -322,7 +322,7 @@ class BinanceClient:
|
||||||
|
|
||||||
# 验证API密钥权限(仅当提供了有效的 API key 时)
|
# 验证API密钥权限(仅当提供了有效的 API key 时)
|
||||||
if self.api_key and self.api_secret:
|
if self.api_key and self.api_secret:
|
||||||
await self._verify_api_permissions()
|
await self._verify_api_permissions()
|
||||||
else:
|
else:
|
||||||
logger.info("✓ 使用公开 API,跳过权限验证(只能获取行情数据)")
|
logger.info("✓ 使用公开 API,跳过权限验证(只能获取行情数据)")
|
||||||
|
|
||||||
|
|
@ -755,13 +755,13 @@ class BinanceClient:
|
||||||
self._display_to_api_symbol.update(display_to_api)
|
self._display_to_api_symbol.update(display_to_api)
|
||||||
if display_to_api:
|
if display_to_api:
|
||||||
logger.info(f"已映射 {len(display_to_api)} 个中文/非ASCII交易对到英文 symbol,均可正常下单")
|
logger.info(f"已映射 {len(display_to_api)} 个中文/非ASCII交易对到英文 symbol,均可正常下单")
|
||||||
logger.info(f"获取到 {len(usdt_pairs)} 个USDT永续合约交易对")
|
logger.info(f"获取到 {len(usdt_pairs)} 个USDT永续合约交易对")
|
||||||
# 回写 DB 供下次使用
|
# 回写 DB 供下次使用
|
||||||
try:
|
try:
|
||||||
await loop.run_in_executor(None, lambda: _save_exchange_info_to_db(exchange_info))
|
await loop.run_in_executor(None, lambda: _save_exchange_info_to_db(exchange_info))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug("exchange_info 写入 DB 失败: %s", e)
|
logger.debug("exchange_info 写入 DB 失败: %s", e)
|
||||||
return usdt_pairs
|
return usdt_pairs
|
||||||
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
if attempt < max_retries:
|
if attempt < max_retries:
|
||||||
|
|
@ -772,9 +772,9 @@ class BinanceClient:
|
||||||
logger.error(f"获取交易对失败:{max_retries}次重试后仍然超时")
|
logger.error(f"获取交易对失败:{max_retries}次重试后仍然超时")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
except BinanceAPIException as e:
|
except BinanceAPIException as e:
|
||||||
logger.error(f"获取交易对失败(API错误): {e}")
|
logger.error(f"获取交易对失败(API错误): {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if attempt < max_retries:
|
if attempt < max_retries:
|
||||||
|
|
@ -870,7 +870,7 @@ class BinanceClient:
|
||||||
from .market_ws_leader import KEY_KLINE_PREFIX
|
from .market_ws_leader import KEY_KLINE_PREFIX
|
||||||
shared_key = f"{KEY_KLINE_PREFIX}{symbol.upper()}:{interval.lower()}"
|
shared_key = f"{KEY_KLINE_PREFIX}{symbol.upper()}:{interval.lower()}"
|
||||||
# 使用较长的 TTL,因为这是共享缓存,多个账号都会使用
|
# 使用较长的 TTL,因为这是共享缓存,多个账号都会使用
|
||||||
ttl_map = {
|
ttl_map = {
|
||||||
'1m': 60, '3m': 120, '5m': 180, '15m': 300, '30m': 600,
|
'1m': 60, '3m': 120, '5m': 180, '15m': 300, '30m': 600,
|
||||||
'1h': 900, '2h': 1800, '4h': 3600, '6h': 5400, '8h': 7200, '12h': 10800, '1d': 21600
|
'1h': 900, '2h': 1800, '4h': 3600, '6h': 5400, '8h': 7200, '12h': 10800, '1d': 21600
|
||||||
}
|
}
|
||||||
|
|
@ -1292,7 +1292,7 @@ class BinanceClient:
|
||||||
f"获取持仓: 过滤掉 {len(skipped_low)} 个名义价值 < {min_notional} USDT 的仓位 {skipped_low},"
|
f"获取持仓: 过滤掉 {len(skipped_low)} 个名义价值 < {min_notional} USDT 的仓位 {skipped_low},"
|
||||||
"与仪表板不一致时可设 POSITION_MIN_NOTIONAL_USDT=0 或更小"
|
"与仪表板不一致时可设 POSITION_MIN_NOTIONAL_USDT=0 或更小"
|
||||||
)
|
)
|
||||||
return open_positions
|
return open_positions
|
||||||
except (asyncio.TimeoutError, BinanceAPIException) as e:
|
except (asyncio.TimeoutError, BinanceAPIException) as e:
|
||||||
last_error = e
|
last_error = e
|
||||||
# 如果是API异常,检查是否是网络相关或服务器错误
|
# 如果是API异常,检查是否是网络相关或服务器错误
|
||||||
|
|
@ -1389,7 +1389,7 @@ class BinanceClient:
|
||||||
if isinstance(cached, dict) and ("tickSize" not in cached or "pricePrecision" not in cached):
|
if isinstance(cached, dict) and ("tickSize" not in cached or "pricePrecision" not in cached):
|
||||||
logger.info(f"{symbol} symbol_info 缓存缺少 tickSize/pricePrecision,自动刷新一次")
|
logger.info(f"{symbol} symbol_info 缓存缺少 tickSize/pricePrecision,自动刷新一次")
|
||||||
else:
|
else:
|
||||||
return cached
|
return cached
|
||||||
# 2. 降级到进程内存(仅当 Redis 不可用时会有数据)
|
# 2. 降级到进程内存(仅当 Redis 不可用时会有数据)
|
||||||
if symbol in self._symbol_info_cache:
|
if symbol in self._symbol_info_cache:
|
||||||
cached_mem = self._symbol_info_cache[symbol]
|
cached_mem = self._symbol_info_cache[symbol]
|
||||||
|
|
@ -1873,8 +1873,8 @@ class BinanceClient:
|
||||||
position = positions[0]
|
position = positions[0]
|
||||||
# 优先使用 API 返回的 leverage,不再限制必须有持仓
|
# 优先使用 API 返回的 leverage,不再限制必须有持仓
|
||||||
leverage_bracket = position.get('leverage')
|
leverage_bracket = position.get('leverage')
|
||||||
if leverage_bracket:
|
if leverage_bracket:
|
||||||
current_leverage = int(leverage_bracket)
|
current_leverage = int(leverage_bracket)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(f"无法获取 {symbol} 的杠杆信息,使用默认值: {current_leverage}x ({e})")
|
logger.debug(f"无法获取 {symbol} 的杠杆信息,使用默认值: {current_leverage}x ({e})")
|
||||||
|
|
||||||
|
|
@ -2099,7 +2099,7 @@ class BinanceClient:
|
||||||
if reduce_only:
|
if reduce_only:
|
||||||
logger.warning(f"下单被拒绝 {symbol} {side}: ReduceOnly(-2022)(可能仓位已为0/方向腿不匹配),将由上层做幂等处理")
|
logger.warning(f"下单被拒绝 {symbol} {side}: ReduceOnly(-2022)(可能仓位已为0/方向腿不匹配),将由上层做幂等处理")
|
||||||
else:
|
else:
|
||||||
logger.error(f"下单失败 {symbol} {side}: ReduceOnly 订单被拒绝 - {e}")
|
logger.error(f"下单失败 {symbol} {side}: ReduceOnly 订单被拒绝 - {e}")
|
||||||
elif "reduceOnly" in error_msg.lower() or "reduce only" in error_msg.lower():
|
elif "reduceOnly" in error_msg.lower() or "reduce only" in error_msg.lower():
|
||||||
logger.error(f"下单失败 {symbol} {side}: ReduceOnly 相关错误 - {e}")
|
logger.error(f"下单失败 {symbol} {side}: ReduceOnly 相关错误 - {e}")
|
||||||
logger.error(f" 错误码: {error_code}")
|
logger.error(f" 错误码: {error_code}")
|
||||||
|
|
@ -2677,8 +2677,8 @@ class BinanceClient:
|
||||||
else:
|
else:
|
||||||
logger.error(f"设置杠杆请求超时 ({symbol} {target_leverage}x),已重试 2 次仍失败")
|
logger.error(f"设置杠杆请求超时 ({symbol} {target_leverage}x),已重试 2 次仍失败")
|
||||||
return 0
|
return 0
|
||||||
except BinanceAPIException as e:
|
except BinanceAPIException as e:
|
||||||
error_msg = str(e).lower()
|
error_msg = str(e).lower()
|
||||||
logger.warning(f"设置杠杆 {target_leverage}x 失败: {e},尝试降低杠杆...")
|
logger.warning(f"设置杠杆 {target_leverage}x 失败: {e},尝试降低杠杆...")
|
||||||
# 如果是 leverage 相关错误,尝试降级
|
# 如果是 leverage 相关错误,尝试降级
|
||||||
if 'leverage' in error_msg or 'invalid' in error_msg or 'max' in error_msg:
|
if 'leverage' in error_msg or 'invalid' in error_msg or 'max' in error_msg:
|
||||||
|
|
@ -2687,12 +2687,12 @@ class BinanceClient:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
await self.client.futures_change_leverage(symbol=symbol, leverage=fallback)
|
await self.client.futures_change_leverage(symbol=symbol, leverage=fallback)
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"{symbol} 杠杆降级成功: {target_leverage}x -> {fallback}x"
|
f"{symbol} 杠杆降级成功: {target_leverage}x -> {fallback}x"
|
||||||
)
|
)
|
||||||
return fallback
|
return fallback
|
||||||
except (TimeoutError, asyncio.TimeoutError, BinanceAPIException):
|
except (TimeoutError, asyncio.TimeoutError, BinanceAPIException):
|
||||||
continue
|
continue
|
||||||
logger.error(f"设置杠杆最终失败: {symbol} (目标: {target_leverage}x)")
|
logger.error(f"设置杠杆最终失败: {symbol} (目标: {target_leverage}x)")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3563,18 +3563,18 @@ class PositionManager:
|
||||||
)
|
)
|
||||||
logger.info(f" {symbol} [补建-手动] 使用交易所已有止损(保本/移动)sl={stop_loss_price},不覆盖为初始止损 {initial_stop_loss}")
|
logger.info(f" {symbol} [补建-手动] 使用交易所已有止损(保本/移动)sl={stop_loss_price},不覆盖为初始止损 {initial_stop_loss}")
|
||||||
else:
|
else:
|
||||||
stop_loss_price = self.risk_manager.get_stop_loss_price(
|
stop_loss_price = self.risk_manager.get_stop_loss_price(
|
||||||
entry_price, side, quantity, leverage,
|
entry_price, side, quantity, leverage,
|
||||||
stop_loss_pct=stop_loss_pct_margin
|
stop_loss_pct=stop_loss_pct_margin
|
||||||
)
|
)
|
||||||
initial_stop_loss = stop_loss_price
|
initial_stop_loss = stop_loss_price
|
||||||
if tp_from_ex is not None:
|
if tp_from_ex is not None:
|
||||||
take_profit_price = tp_from_ex
|
take_profit_price = tp_from_ex
|
||||||
else:
|
else:
|
||||||
take_profit_price = self.risk_manager.get_take_profit_price(
|
take_profit_price = self.risk_manager.get_take_profit_price(
|
||||||
entry_price, side, quantity, leverage,
|
entry_price, side, quantity, leverage,
|
||||||
take_profit_pct=take_profit_pct_margin
|
take_profit_pct=take_profit_pct_margin
|
||||||
)
|
)
|
||||||
|
|
||||||
position_info = {
|
position_info = {
|
||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ class RiskManager:
|
||||||
# 获取账户余额(优先 WS 缓存,Redis)
|
# 获取账户余额(优先 WS 缓存,Redis)
|
||||||
balance = await _get_balance_from_cache(self.client) if _get_stream_instance() else None
|
balance = await _get_balance_from_cache(self.client) if _get_stream_instance() else None
|
||||||
if balance is None:
|
if balance is None:
|
||||||
balance = await self.client.get_account_balance()
|
balance = await self.client.get_account_balance()
|
||||||
available_balance = balance.get('available', 0)
|
available_balance = balance.get('available', 0)
|
||||||
|
|
||||||
if available_balance <= 0:
|
if available_balance <= 0:
|
||||||
|
|
@ -170,7 +170,7 @@ class RiskManager:
|
||||||
# 获取当前持仓(优先 WS 缓存,Redis)
|
# 获取当前持仓(优先 WS 缓存,Redis)
|
||||||
positions = await _get_positions_from_cache(self.client) if _get_stream_instance() else None
|
positions = await _get_positions_from_cache(self.client) if _get_stream_instance() else None
|
||||||
if positions is None:
|
if positions is None:
|
||||||
positions = await self.client.get_open_positions()
|
positions = await self.client.get_open_positions()
|
||||||
|
|
||||||
# 计算当前总保证金占用
|
# 计算当前总保证金占用
|
||||||
current_position_values = []
|
current_position_values = []
|
||||||
|
|
@ -202,7 +202,7 @@ class RiskManager:
|
||||||
# 获取账户余额(优先 WS 缓存,Redis)
|
# 获取账户余额(优先 WS 缓存,Redis)
|
||||||
balance = await _get_balance_from_cache(self.client) if _get_stream_instance() else None
|
balance = await _get_balance_from_cache(self.client) if _get_stream_instance() else None
|
||||||
if balance is None:
|
if balance is None:
|
||||||
balance = await self.client.get_account_balance()
|
balance = await self.client.get_account_balance()
|
||||||
total_balance = balance.get('total', 0)
|
total_balance = balance.get('total', 0)
|
||||||
available_balance = balance.get('available', 0)
|
available_balance = balance.get('available', 0)
|
||||||
|
|
||||||
|
|
@ -453,7 +453,7 @@ class RiskManager:
|
||||||
# 获取账户余额(优先 WS 缓存,Redis)
|
# 获取账户余额(优先 WS 缓存,Redis)
|
||||||
balance = await _get_balance_from_cache(self.client) if _get_stream_instance() else None
|
balance = await _get_balance_from_cache(self.client) if _get_stream_instance() else None
|
||||||
if balance is None:
|
if balance is None:
|
||||||
balance = await self.client.get_account_balance()
|
balance = await self.client.get_account_balance()
|
||||||
available_balance = balance.get('available', 0)
|
available_balance = balance.get('available', 0)
|
||||||
total_balance = balance.get('total', 0)
|
total_balance = balance.get('total', 0)
|
||||||
|
|
||||||
|
|
@ -840,7 +840,7 @@ class RiskManager:
|
||||||
# 检查是否已有持仓 / 总持仓数量限制(优先 WS 缓存)
|
# 检查是否已有持仓 / 总持仓数量限制(优先 WS 缓存)
|
||||||
positions = await _get_positions_from_cache(self.client) if _get_stream_instance() else None
|
positions = await _get_positions_from_cache(self.client) if _get_stream_instance() else None
|
||||||
if positions is None:
|
if positions is None:
|
||||||
positions = await self.client.get_open_positions()
|
positions = await self.client.get_open_positions()
|
||||||
try:
|
try:
|
||||||
max_open = int(config.TRADING_CONFIG.get("MAX_OPEN_POSITIONS", 0) or 0)
|
max_open = int(config.TRADING_CONFIG.get("MAX_OPEN_POSITIONS", 0) or 0)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user