fix(trade): LIMIT calculated quantity smaller than quoteAmountPrecision

This commit is contained in:
2025-07-30 09:28:42 +08:00
parent bda0eacfab
commit 49904b3822

90
main.py
View File

@@ -54,6 +54,7 @@ class MexcSpotMarket:
提供获取交易对价格等功能
方法:
- get_exchange_info(symbol): 获取交易对信息
- get_price(symbol): 获取指定交易对的当前价格
"""
@@ -61,6 +62,33 @@ class MexcSpotMarket:
"""初始化市场数据查询接口"""
self.market = mexc_spot_v3.mexc_market(config)
def get_exchange_info(self, symbol: str) -> Optional[Dict[str, Any]]:
"""
获取交易对信息
Args:
symbol: 交易对,如 "BTCUSDT"
Returns:
交易对信息字典或None(如果失败)
"""
params = {"symbol": symbol}
try:
logger.info("查询交易对信息: %s", symbol)
exchange_info = self.market.get_exchangeInfo(params)
if not exchange_info or "symbols" not in exchange_info:
logger.error("获取交易对信息失败: %s", exchange_info)
return None
logger.info("获取交易对信息成功")
return exchange_info
except Exception as e:
logger.error("查询交易所信息失败: %s", str(e))
return None
def get_price(self, symbol: str) -> Optional[float]:
"""
获取指定交易对的当前价格
@@ -274,6 +302,44 @@ class MexcSpotTrade:
logger.error("记录交易失败: %s", str(e))
return False
def _tool_calculate_quantity(
self,
quantity: float,
price: float,
base_asset_precision: int,
quote_amount_precision: float,
) -> float:
"""
调整下单数量以满足最小成交额要求。
策略说明:
- 计算出的quantity如果乘以price后小于交易对的最小成交额(quoteAmountPrecision)
则将quantity增加一个最小单位(10^(-base_asset_precision)),确保下单金额满足交易所要求。
Args:
quantity: 初步计算出的下单数量
price: 当前价格
base_asset_precision: 交易对基础资产的小数精度
quote_amount_precision: 交易对最小成交额
Returns:
满足最小成交额要求的下单数量
"""
processed_quantity = round(quantity, base_asset_precision)
if processed_quantity * price < quote_amount_precision:
logger.info(
"计算的quantity小于最低要求%f * %f = %f < %f,进行调整",
processed_quantity,
price,
processed_quantity * price,
quote_amount_precision,
)
processed_quantity = round(
quantity + 10 ** (-base_asset_precision), base_asset_precision
)
logger.info("调整后的quantity: %f", processed_quantity)
return processed_quantity
def trade(
self, symbol: str, order_type: str, side: str, **kwargs
) -> Optional[Dict[str, Any]]:
@@ -322,12 +388,26 @@ class MexcSpotTrade:
and "quantity" not in processed_kwargs
):
try:
exchange_info = self.market.get_exchange_info(symbol)
quote_amount = float(processed_kwargs["quoteOrderQty"])
price = float(processed_kwargs["price"])
price = (
float(current_price)
if not current_price is None
else float(processed_kwargs["price"])
)
quantity = quote_amount / price
processed_kwargs["quantity"] = str(quantity)
base_asset_precision = int(
exchange_info["symbols"][0]["baseAssetPrecision"]
)
quote_amount_precision = float(
exchange_info["symbols"][0]["quoteAmountPrecision"]
)
processed_quantity = self._tool_calculate_quantity(
quantity, price, base_asset_precision, quote_amount_precision
)
logger.info("根据quoteOrderQty计算quantity: %f", processed_quantity)
processed_kwargs["quantity"] = str(processed_quantity)
processed_kwargs.pop("quoteOrderQty")
logger.info("根据quoteOrderQty计算quantity: %f", quantity)
except (ValueError, KeyError) as e:
logger.error("计算quantity失败: %s", str(e))
return None
@@ -484,6 +564,7 @@ class TradingConfig:
return today_trades
def git_commit(repo_path: str = ".") -> str:
"""获取Git仓库版本"""
@@ -493,6 +574,7 @@ def git_commit(repo_path: str = ".") -> str:
except Exception as _:
return None
def main():
"""主函数"""
@@ -527,7 +609,7 @@ def main():
spot_trader = MexcSpotTrade(
config.config_data.get("api", {}),
config.config_data.get("symbol_mapping", {}),
os.path.basename(config_file).replace('.json', '')
os.path.basename(config_file).replace(".json", ""),
)
today_trades = config.get_today_trades()