fix(trade): LIMIT
calculated quantity smaller than quoteAmountPrecision
This commit is contained in:
90
main.py
90
main.py
@@ -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()
|
||||
|
||||
|
Reference in New Issue
Block a user