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:
|
def _calculate_position_size(self, symbol: str, margin: float, price: float, leverage: int) -> float:
|
||||||
"""计算仓位大小"""
|
"""计算仓位大小(按 Hyperliquid szDecimals 精度截断)"""
|
||||||
try:
|
try:
|
||||||
|
import math
|
||||||
|
|
||||||
# Hyperliquid 的仓位计算
|
# Hyperliquid 的仓位计算
|
||||||
position_value = margin * leverage
|
position_value = margin * leverage
|
||||||
position_size = position_value / price
|
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
|
return position_size
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,17 @@ class PaperTradingExecutor(BaseExecutor):
|
|||||||
# 调整保证金(模拟盘无手续费)
|
# 调整保证金(模拟盘无手续费)
|
||||||
adjusted_margin = margin
|
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 = {
|
signal = {
|
||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
@ -42,6 +53,10 @@ class PaperTradingExecutor(BaseExecutor):
|
|||||||
'entry_price': entry_price if order_type == 'limit' else current_price,
|
'entry_price': entry_price if order_type == 'limit' else current_price,
|
||||||
'stop_loss': stop_loss,
|
'stop_loss': stop_loss,
|
||||||
'take_profit': take_profit,
|
'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()
|
self.check_risk_limits()
|
||||||
|
|
||||||
|
# 精度保护:确保 size 符合 szDecimals 要求
|
||||||
|
size = self._sanitize_size(symbol, size)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if reduce_only:
|
if reduce_only:
|
||||||
# 平仓使用 market_close(不需要指定 is_buy,自动判断)
|
# 平仓使用 market_close(不需要指定 is_buy,自动判断)
|
||||||
@ -216,6 +219,10 @@ class HyperliquidTradingService:
|
|||||||
"""下限价单"""
|
"""下限价单"""
|
||||||
self.check_risk_limits()
|
self.check_risk_limits()
|
||||||
|
|
||||||
|
# 精度保护:确保 size 和 price 符合要求
|
||||||
|
size = self._sanitize_size(symbol, size)
|
||||||
|
price = round(float(price), 5) # Hyperliquid 价格最多 5 位小数
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = self.exchange.order(symbol, is_buy, size, price,
|
result = self.exchange.order(symbol, is_buy, size, price,
|
||||||
{"limit": {"tif": "Gtc"}},
|
{"limit": {"tif": "Gtc"}},
|
||||||
@ -582,6 +589,24 @@ class HyperliquidTradingService:
|
|||||||
logger.warning(f"获取 {symbol} szDecimals 失败,使用默认值 3")
|
logger.warning(f"获取 {symbol} szDecimals 失败,使用默认值 3")
|
||||||
return 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
|
_hyperliquid_service_instance = None
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user