auto_trade_sys/trading_system/binance_order_event_logger.py
薇薇安 fc6c31dd5d feat(user_data_stream): 增强订单和算法更新事件的日志记录
在 `user_data_stream.py` 中为 `ORDER_TRADE_UPDATE` 和 `ALGO_UPDATE` 事件添加了日志记录功能,确保在接收到相关推送时能够记录事件信息。这一改进提升了系统的可追踪性和调试能力。
2026-02-21 17:09:41 +08:00

85 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
币安订单推送事件日志:将 ORDER_TRADE_UPDATE / ALGO_UPDATE 等写入日志文件,便于与 DB 对账。
每行一条 JSON含 event_type、account_id、时间、关键字段方便 grep / 脚本分析。
"""
import json
import logging
import os
import time
from pathlib import Path
from typing import Any, Dict, Optional
logger = logging.getLogger(__name__)
_LOG_DIR: Optional[Path] = None
_LOG_PATH: Optional[Path] = None
def _get_log_path() -> Optional[Path]:
global _LOG_DIR, _LOG_PATH
if _LOG_PATH is not None:
return _LOG_PATH
try:
root = Path(__file__).resolve().parent.parent
_LOG_DIR = root / "logs"
_LOG_DIR.mkdir(parents=True, exist_ok=True)
_LOG_PATH = _LOG_DIR / "binance_order_events.log"
return _LOG_PATH
except Exception as e:
logger.debug(f"binance_order_event_logger 无法创建日志路径: {e}")
return None
def _default_serializer(obj):
if hasattr(obj, "isoformat"):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")
def log_order_event(account_id: int, event_type: str, event_time_ms: Optional[int], data: Dict[str, Any]) -> None:
"""
将币安订单推送事件写入日志文件(每行一条 JSON
Args:
account_id: 账号 ID
event_type: ORDER_TRADE_UPDATE / ALGO_UPDATE 等
event_time_ms: 事件时间(毫秒)
data: 原始 payload如 o 或 a 部分),会提取关键字段
"""
path = _get_log_path()
if not path:
return
try:
# 提取关键字段便于对账
row = {
"ts": int(time.time() * 1000),
"event_type": event_type,
"account_id": account_id,
"E": event_time_ms,
}
if event_type == "ORDER_TRADE_UPDATE" and data:
o = data
row["symbol"] = (o.get("s") or "").strip()
row["orderId"] = o.get("i")
row["clientOrderId"] = (o.get("c") or "").strip() or None
row["event"] = (o.get("x") or "").strip() # NEW/TRADE/CANCELED
row["status"] = (o.get("X") or "").strip() # NEW/FILLED/CANCELED
row["reduceOnly"] = o.get("R") is True
if row["status"] == "FILLED":
row["avgPrice"] = o.get("ap")
row["executedQty"] = o.get("z")
row["realizedPnl"] = o.get("rp")
elif event_type == "ALGO_UPDATE" and data:
o = data
row["symbol"] = (o.get("s") or "").strip()
row["algoId"] = o.get("i")
row["algoStatus"] = (o.get("X") or "").strip() # TRIGGERED/FINISHED
row["triggeredOrderId"] = o.get("ai") # 触发后的普通订单 id
else:
row["raw"] = data
line = json.dumps(row, ensure_ascii=False, default=_default_serializer) + "\n"
with open(path, "a", encoding="utf-8") as f:
f.write(line)
except Exception as e:
logger.debug(f"binance_order_event_logger 写入失败: {e}")