feat(csv): record filled trade to csv

Closes #3
This commit is contained in:
2025-07-19 20:50:55 +08:00
parent 2ebf49a8d1
commit cef8945fe8

85
main.py
View File

@@ -1,6 +1,8 @@
import csv
from datetime import datetime
import time import time
import logging import logging
from typing import Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
from dataclasses import dataclass from dataclasses import dataclass
import mexc_spot_v3 import mexc_spot_v3
@@ -49,6 +51,8 @@ class GridTradingBot:
参数: 参数:
conf (Dict): 配置字典,包含: conf (Dict): 配置字典,包含:
- symbol: 交易对 (如 'BTCUSDC') - symbol: 交易对 (如 'BTCUSDC')
- csv_symbol: CSV中映射的交易对 (如 'BTCUSDT')
- csv_file: CSV记录文件 (如 'output/mexc-spot-grid-trades.csv')
- grid_percentage: 每格百分比 (如 0.005 表示 0.5%) - grid_percentage: 每格百分比 (如 0.005 表示 0.5%)
- grid_count: 单边网格数量 (如 3) - grid_count: 单边网格数量 (如 3)
- order_amount: 每单加密货币数量 (如 0.00001 BTC) - order_amount: 每单加密货币数量 (如 0.00001 BTC)
@@ -62,6 +66,8 @@ class GridTradingBot:
) )
self.config = conf self.config = conf
self.symbol = conf["symbol"] self.symbol = conf["symbol"]
self.csv_symbol = conf["csv_symbol"]
self.csv_file = conf["csv_file"]
self.grid_percentage = conf["grid_percentage"] self.grid_percentage = conf["grid_percentage"]
self.grid_count = conf["grid_count"] self.grid_count = conf["grid_count"]
self.order_amount = conf["order_amount"] self.order_amount = conf["order_amount"]
@@ -85,6 +91,78 @@ class GridTradingBot:
self.running = False self.running = False
logger.info("[GridTradingBot.__init__] GridTradingBot initialized successfully") logger.info("[GridTradingBot.__init__] GridTradingBot initialized successfully")
def record_transaction(self, order_response: Dict[str, Any]) -> bool:
"""
记录交易到CSV文件
Args:
order_data: 订单数据字典
Returns:
是否成功记录
"""
try:
csv_symbol = self.csv_symbol
order_id = order_response["orderId"]
executed_qty = order_response["executedQty"]
cummulative_quote_qty = order_response["cummulativeQuoteQty"]
side = order_response["side"]
trade_type = "买入" if side == "BUY" else "卖出"
timestamp = datetime.fromtimestamp(order_response["updateTime"] / 1000).strftime(
"%Y-%m-%dT%H:%M"
)
row = [
timestamp,
trade_type,
csv_symbol,
executed_qty,
cummulative_quote_qty,
"资金账户",
"CEX",
f"MEXC API - Order ID: {order_id}",
]
# 检查文件是否存在
file_exists = False
try:
with open(self.csv_file, "r", encoding="utf-8") as f:
file_exists = True
except FileNotFoundError:
pass
# 写入CSV
with open(self.csv_file, "a", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
if not file_exists:
writer.writerow(
[
"日期",
"类型",
"证券代码",
"份额",
"净额",
"现金账户",
"目标账户",
"备注",
]
)
writer.writerow(row)
logger.info(
"[GridTradingBot.record_transaction] Transaction recorded, order ID: %s",
order_id,
)
return True
except Exception as e:
logger.error(
"[GridTradingBot.record_transaction] Transaction recording failed: %s",
str(e),
)
return False
def api_get_price(self) -> float: def api_get_price(self) -> float:
"""获取当前市场价格""" """获取当前市场价格"""
logger.custom_debug( logger.custom_debug(
@@ -359,9 +437,8 @@ class GridTradingBot:
order_id, order_id,
self.active_orders[order_id].filled_time, self.active_orders[order_id].filled_time,
) )
self.record_transaction(order_info)
# 如果订单已完成或已取消,从活跃订单中移除
# if new_status in ["FILLED", "CANCELED"]:
if new_status in ["CANCELED"]: if new_status in ["CANCELED"]:
logger.custom_debug( logger.custom_debug(
"[GridTradingBot.api_update_order_statuses] Removing order %s from active orders (status: %s)", "[GridTradingBot.api_update_order_statuses] Removing order %s from active orders (status: %s)",
@@ -832,6 +909,8 @@ class GridTradingBot:
if __name__ == "__main__": if __name__ == "__main__":
config = { config = {
"symbol": "BTCUSDC", # 交易对 "symbol": "BTCUSDC", # 交易对
"csv_symbol": "BTCUSDT", # CSV记录映射交易对
"csv_file": "output/mexc_spot_grid_trades.csv", # CSV记录文件
"grid_percentage": 0.001, # 等比网格的公比 "grid_percentage": 0.001, # 等比网格的公比
"grid_count": 3, # 单侧的挂单数,实时平衡 "grid_count": 3, # 单侧的挂单数,实时平衡
"order_amount": 0.00001, # BTC数量 "order_amount": 0.00001, # BTC数量