update
This commit is contained in:
parent
eb5edf919c
commit
e48911d502
@ -281,13 +281,20 @@ class HyperliquidExecutor(BaseExecutor):
|
||||
# ==================== 辅助方法 ====================
|
||||
|
||||
def _calculate_position_size(self, symbol: str, margin: float, price: float, leverage: int) -> float:
|
||||
"""计算仓位大小"""
|
||||
"""计算仓位大小(按 Hyperliquid szDecimals 精度截断)"""
|
||||
try:
|
||||
import math
|
||||
|
||||
# Hyperliquid 的仓位计算
|
||||
position_value = margin * leverage
|
||||
position_size = position_value / price
|
||||
|
||||
logger.info(f" 仓位计算: ${margin:.2f} × {leverage}x = ${position_value:.2f} → {position_size:.6f} {symbol}")
|
||||
# 按 Hyperliquid 要求的精度截断(szDecimals)
|
||||
sz_decimals = self.hyperliquid.get_sz_decimals(symbol)
|
||||
factor = 10 ** sz_decimals
|
||||
position_size = math.floor(position_size * factor) / factor
|
||||
|
||||
logger.info(f" 仓位计算: ${margin:.2f} × {leverage}x = ${position_value:.2f} → {position_size:.6f} {symbol} (精度: {sz_decimals}位)")
|
||||
|
||||
return position_size
|
||||
|
||||
|
||||
@ -34,6 +34,17 @@ class PaperTradingExecutor(BaseExecutor):
|
||||
# 调整保证金(模拟盘无手续费)
|
||||
adjusted_margin = margin
|
||||
|
||||
# 根据 confidence 推算信号等级
|
||||
confidence = decision.get('confidence', 0)
|
||||
if confidence >= 80:
|
||||
signal_grade = 'A'
|
||||
elif confidence >= 60:
|
||||
signal_grade = 'B'
|
||||
elif confidence >= 40:
|
||||
signal_grade = 'C'
|
||||
else:
|
||||
signal_grade = 'D'
|
||||
|
||||
# 构建信号字典
|
||||
signal = {
|
||||
'symbol': symbol,
|
||||
@ -42,6 +53,10 @@ class PaperTradingExecutor(BaseExecutor):
|
||||
'entry_price': entry_price if order_type == 'limit' else current_price,
|
||||
'stop_loss': stop_loss,
|
||||
'take_profit': take_profit,
|
||||
'signal_grade': signal_grade,
|
||||
'confidence': confidence,
|
||||
'quantity': adjusted_margin,
|
||||
'position_size': decision.get('position_size', 'light'),
|
||||
}
|
||||
|
||||
# 执行下单(统一调用方式)
|
||||
|
||||
@ -160,6 +160,9 @@ class HyperliquidTradingService:
|
||||
# 风险检查
|
||||
self.check_risk_limits()
|
||||
|
||||
# 精度保护:确保 size 符合 szDecimals 要求
|
||||
size = self._sanitize_size(symbol, size)
|
||||
|
||||
try:
|
||||
if reduce_only:
|
||||
# 平仓使用 market_close(不需要指定 is_buy,自动判断)
|
||||
@ -216,6 +219,10 @@ class HyperliquidTradingService:
|
||||
"""下限价单"""
|
||||
self.check_risk_limits()
|
||||
|
||||
# 精度保护:确保 size 和 price 符合要求
|
||||
size = self._sanitize_size(symbol, size)
|
||||
price = round(float(price), 5) # Hyperliquid 价格最多 5 位小数
|
||||
|
||||
try:
|
||||
result = self.exchange.order(symbol, is_buy, size, price,
|
||||
{"limit": {"tif": "Gtc"}},
|
||||
@ -582,6 +589,24 @@ class HyperliquidTradingService:
|
||||
logger.warning(f"获取 {symbol} szDecimals 失败,使用默认值 3")
|
||||
return 3
|
||||
|
||||
def _sanitize_size(self, symbol: str, size: float) -> float:
|
||||
"""
|
||||
精度保护:确保 size 符合 Hyperliquid szDecimals 要求
|
||||
|
||||
这是防止 float_to_wire causes rounding 错误的最后防线。
|
||||
"""
|
||||
import math
|
||||
try:
|
||||
sz_decimals = self.get_sz_decimals(symbol)
|
||||
factor = 10 ** sz_decimals
|
||||
sanitized = math.floor(float(size) * factor) / factor
|
||||
if sanitized != size:
|
||||
logger.info(f" 精度截断: {size} → {sanitized} ({symbol} szDecimals={sz_decimals})")
|
||||
return sanitized
|
||||
except Exception as e:
|
||||
logger.warning(f" 精度截断失败: {e},使用原值 {size}")
|
||||
return size
|
||||
|
||||
|
||||
# 单例
|
||||
_hyperliquid_service_instance = None
|
||||
|
||||
Loading…
Reference in New Issue
Block a user