Compare commits

...

2 Commits

Author SHA1 Message Date
9011cc58a7 feat(csv): add account balance recording
Closes #5
2025-08-10 03:10:06 +08:00
82314a022b fix(trade): LIMIT calculated quantity algorithm
Closes #6
2025-08-10 03:01:45 +08:00

43
main.py
View File

@@ -160,6 +160,26 @@ class MexcSpotTrade:
self.csv_file = f"output/{config_file_name}.csv" self.csv_file = f"output/{config_file_name}.csv"
self.symbol_mapping = symbol_mapping self.symbol_mapping = symbol_mapping
def _api_get_balance(self) -> str:
"""
获取账户余额
Returns:
账户余额字典或None(如果失败)
"""
try:
logger.info("查询账户余额")
account_info = self.trader.get_account_info()
account_info_balance = account_info.get("balances", [])
balances = ""
for item in account_info_balance:
balances += f"{item['available']} {item['asset']} "
logger.info("获取账户余额成功")
return balances
except Exception as e:
logger.error("查询账户信息失败: %s", str(e))
return f"ERROR: {str(e)}"
def _api_get_order(self, symbol: str, order_id: str) -> Optional[Dict[str, Any]]: def _api_get_order(self, symbol: str, order_id: str) -> Optional[Dict[str, Any]]:
""" """
查询订单状态 查询订单状态
@@ -251,6 +271,7 @@ class MexcSpotTrade:
executed_qty = order_data["executedQty"] executed_qty = order_data["executedQty"]
cummulative_quote_qty = order_data["cummulativeQuoteQty"] cummulative_quote_qty = order_data["cummulativeQuoteQty"]
side = order_data["side"] side = order_data["side"]
balances = self._api_get_balance()
# 确定交易类型显示 # 确定交易类型显示
trade_type = "买入" if side == "BUY" else "卖出" trade_type = "买入" if side == "BUY" else "卖出"
@@ -268,6 +289,7 @@ class MexcSpotTrade:
"资金账户", "资金账户",
"CEX", "CEX",
f"MEXC API - Order ID: {order_id}", f"MEXC API - Order ID: {order_id}",
balances
] ]
# 检查文件是否存在 # 检查文件是否存在
@@ -292,6 +314,7 @@ class MexcSpotTrade:
"现金账户", "现金账户",
"目标账户", "目标账户",
"备注", "备注",
"balances"
] ]
) )
writer.writerow(row) writer.writerow(row)
@@ -368,18 +391,23 @@ class MexcSpotTrade:
order_type = order_type.upper() order_type = order_type.upper()
processed_kwargs = kwargs.copy() processed_kwargs = kwargs.copy()
# 记录未经过偏移的价格以供LIMIT订单只有quoteOrderQty没有quantity的情况使用
# 参数有price时直接使用否则就为实时价格
clean_price = processed_kwargs.get("price")
# 处理无price的情况获取实时价格 # 处理无price的情况获取实时价格
if order_type in ["LIMIT", "LIMIT_MAKER"] and "price" not in processed_kwargs: if order_type in ["LIMIT", "LIMIT_MAKER"] and "price" not in processed_kwargs:
current_price = self.market.get_price(symbol) current_price = self.market.get_price(symbol)
if current_price is None: if current_price is None:
logger.error("无法获取实时价格,交易取消") logger.error("无法获取实时价格,交易取消")
return None return None
clean_price = current_price
# 防止挂单不成交 # 防止挂单不成交
if side == "BUY": if side == "BUY":
processed_kwargs["price"] = current_price * 1.01 # 买入加价0.5% processed_kwargs["price"] = current_price * 1.01 # 买入加价1%
elif side == "SELL": elif side == "SELL":
processed_kwargs["price"] = current_price * 0.91 # 卖出减价0.5% processed_kwargs["price"] = current_price * 0.99 # 卖出减价1%
logger.info("使用调整0.5%%后价格作为限价: %f", processed_kwargs["price"]) logger.info("使用调整1%%后价格作为限价: %f", processed_kwargs["price"])
# 处理LIMIT订单只有quoteOrderQty没有quantity的情况 # 处理LIMIT订单只有quoteOrderQty没有quantity的情况
if ( if (
@@ -390,12 +418,7 @@ class MexcSpotTrade:
try: try:
exchange_info = self.market.get_exchange_info(symbol) exchange_info = self.market.get_exchange_info(symbol)
quote_amount = float(processed_kwargs["quoteOrderQty"]) quote_amount = float(processed_kwargs["quoteOrderQty"])
price = ( quantity = quote_amount / clean_price
float(current_price)
if not current_price is None
else float(processed_kwargs["price"])
)
quantity = quote_amount / price
base_asset_precision = int( base_asset_precision = int(
exchange_info["symbols"][0]["baseAssetPrecision"] exchange_info["symbols"][0]["baseAssetPrecision"]
) )
@@ -403,7 +426,7 @@ class MexcSpotTrade:
exchange_info["symbols"][0]["quoteAmountPrecision"] exchange_info["symbols"][0]["quoteAmountPrecision"]
) )
processed_quantity = self._tool_calculate_quantity( processed_quantity = self._tool_calculate_quantity(
quantity, price, base_asset_precision, quote_amount_precision quantity, clean_price, base_asset_precision, quote_amount_precision
) )
logger.info("根据quoteOrderQty计算quantity: %f", processed_quantity) logger.info("根据quoteOrderQty计算quantity: %f", processed_quantity)
processed_kwargs["quantity"] = str(processed_quantity) processed_kwargs["quantity"] = str(processed_quantity)