@@ -36,6 +36,50 @@ IBKRClient = None
|
||||
MT5Client = None
|
||||
|
||||
|
||||
def _normalize_symbol_for_order(symbol: str, market_type: str = "swap") -> str:
|
||||
"""
|
||||
规范化符号格式,确保符号符合交易所要求。
|
||||
|
||||
处理各种输入格式:
|
||||
- BTC/USDT -> BTC/USDT
|
||||
- BTCUSDT -> BTC/USDT
|
||||
- BTC/USDT:USDT -> BTC/USDT
|
||||
- PI, TRX -> PI/USDT, TRX/USDT (默认添加 /USDT)
|
||||
|
||||
Args:
|
||||
symbol: 原始符号
|
||||
market_type: 市场类型 (spot/swap)
|
||||
|
||||
Returns:
|
||||
规范化后的符号
|
||||
"""
|
||||
if not symbol:
|
||||
return symbol
|
||||
|
||||
sym = symbol.strip()
|
||||
|
||||
# 移除 swap/futures 后缀
|
||||
if ':' in sym:
|
||||
sym = sym.split(':', 1)[0]
|
||||
|
||||
sym = sym.upper()
|
||||
|
||||
# 如果已经有分隔符,直接返回(假设格式正确)
|
||||
if '/' in sym:
|
||||
return sym
|
||||
|
||||
# 尝试从常见报价货币中识别
|
||||
common_quotes = ['USDT', 'USD', 'BTC', 'ETH', 'BUSD', 'USDC']
|
||||
for quote in common_quotes:
|
||||
if sym.endswith(quote) and len(sym) > len(quote):
|
||||
base = sym[:-len(quote)]
|
||||
if base:
|
||||
return f"{base}/{quote}"
|
||||
|
||||
# 如果无法识别,默认使用 USDT
|
||||
return f"{sym}/USDT"
|
||||
|
||||
|
||||
def _signal_to_sides(signal_type: str) -> Tuple[str, str, bool]:
|
||||
"""
|
||||
Returns (side, pos_side, reduce_only)
|
||||
@@ -80,6 +124,9 @@ def place_order_from_signal(
|
||||
# Spot does not support short signals in this system.
|
||||
if mt == "spot" and ("short" in (signal_type or "").lower()):
|
||||
raise LiveTradingError("spot market does not support short signals")
|
||||
|
||||
# 规范化符号格式(统一处理裸符号如 PI, TRX 等)
|
||||
symbol = _normalize_symbol_for_order(symbol, market_type=mt)
|
||||
|
||||
if isinstance(client, BinanceFuturesClient):
|
||||
return client.place_market_order(
|
||||
|
||||
Reference in New Issue
Block a user