免责声明:本文基于个人使用体验,与任何厂商无商业关系。内容仅供技术交流参考,不构成投资建议。
一、前言
量化交易日志系统是策略运行的重要保障。好的日志系统能帮助快速定位问题、分析策略表现、优化交易行为。
2026年了,如何搭建一个完善的日志系统?如何分析日志数据?今天分享一下我的实践经验。
二、日志系统的重要性
1. 问题定位
场景:
- 策略突然停止运行
- 订单执行异常
- 数据获取失败
日志作用:
# 没有日志:不知道哪里出问题defbad_strategy():api.insert_order(...)# 出错了,但不知道原因# 有日志:可以快速定位defgood_strategy():logger.info("准备下单")try:order=api.insert_order(...)logger.info(f"下单成功:{order.order_id}")exceptExceptionase:logger.error(f"下单失败:{e}",exc_info=True)2. 策略分析
用途:
- 分析交易行为
- 评估策略表现
- 优化交易逻辑
三、日志系统设计
1. 日志级别
importlogging# 配置日志级别logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')logger=logging.getLogger('trading')# 使用不同级别logger.debug("调试信息")# 详细调试logger.info("一般信息")# 正常运行信息logger.warning("警告信息")# 警告但不影响运行logger.error("错误信息")# 错误但可恢复logger.critical("严重错误")# 严重错误,可能崩溃2. 日志分类
classTradingLogger:"""交易日志器"""def__init__(self):# 创建不同的loggerself.signal_logger=logging.getLogger('trading.signal')self.order_logger=logging.getLogger('trading.order')self.position_logger=logging.getLogger('trading.position')self.error_logger=logging.getLogger('trading.error')deflog_signal(self,signal):"""记录信号"""self.signal_logger.info(f"信号生成:{signal['type']}{signal['symbol']}"f"价格={signal['price']}强度={signal['strength']}")deflog_order(self,order,action):"""记录订单"""self.order_logger.info(f"订单{action}:{order.order_id}{order.symbol}"f"{order.direction}{order.volume}手 @{order.price}")deflog_position(self,position):"""记录持仓"""self.position_logger.info(f"持仓更新:{position.symbol}"f"多头={position.pos_long}空头={position.pos_short}"f"盈亏={position.float_profit}")deflog_error(self,error,context):"""记录错误"""self.error_logger.error(f"错误发生:{error}上下文:{context}",exc_info=True)# 使用logger=TradingLogger()logger.log_signal(signal)logger.log_order(order,"提交")3. 日志存储
importlogging.handlersimportosfromdatetimeimportdatetimedefsetup_logging(log_dir="logs"):"""设置日志"""os.makedirs(log_dir,exist_ok=True)# 按日期分割日志log_file=os.path.join(log_dir,f"trading_{datetime.now().strftime('%Y%m%d')}.log")# 文件处理器file_handler=logging.handlers.RotatingFileHandler(log_file,maxBytes=10*1024*1024,# 10MBbackupCount=30# 保留30天)file_handler.setLevel(logging.INFO)file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))# 控制台处理器console_handler=logging.StreamHandler()console_handler.setLevel(logging.WARNING)console_handler.setFormatter(logging.Formatter('%(levelname)s - %(message)s'))# 配置根loggerroot_logger=logging.getLogger()root_logger.setLevel(logging.INFO)root_logger.addHandler(file_handler)root_logger.addHandler(console_handler)setup_logging()四、关键信息记录
1. 交易记录
importjsonfromdatetimeimportdatetimeclassTradeLogger:"""交易记录器"""def__init__(self,log_file="trades.json"):self.log_file=log_file self.trades=[]deflog_trade(self,trade):"""记录交易"""trade_record={'timestamp':datetime.now().isoformat(),'symbol':trade['symbol'],'direction':trade['direction'],'volume':trade['volume'],'price':trade['price'],'order_id':trade.get('order_id'),'signal':trade.get('signal'),'pnl':trade.get('pnl',0),}self.trades.append(trade_record)# 实时写入withopen(self.log_file,'a',encoding='utf-8')asf:f.write(json.dumps(trade_record,ensure_ascii=False)+'\n')defget_trades(self,start_date=None,end_date=None):"""获取交易记录"""trades=self.tradesifstart_date:trades=[tfortintradesift['timestamp']>=start_date]ifend_date:trades=[tfortintradesift['timestamp']<=end_date]returntrades# 使用trade_logger=TradeLogger()trade_logger.log_trade({'symbol':'SHFE.rb2505','direction':'BUY','volume':1,'price':3500,'signal':'ma_cross'})2. 策略状态记录
classStrategyLogger:"""策略状态记录器"""def__init__(self):self.states=[]deflog_state(self,strategy_name,state):"""记录策略状态"""state_record={'timestamp':datetime.now().isoformat(),'strategy':strategy_name,'equity':state.get('equity'),'position':state.get('position'),'signals':state.get('signals',[]),'errors':state.get('errors',[]),}self.states.append(state_record)# 写入数据库或文件self.save_state(state_record)defsave_state(self,state):"""保存状态"""# 可以保存到数据库# 或写入文件pass3. 性能监控
importtimefromfunctoolsimportwrapsdefperformance_logger(func):"""性能日志装饰器"""@wraps(func)defwrapper(*args,**kwargs):start_time=time.time()try:result=func(*args,**kwargs)elapsed=time.time()-start_time logger.info(f"{func.__name__}执行时间:{elapsed:.3f}秒")returnresultexceptExceptionase:elapsed=time.time()-start_time logger.error(f"{func.__name__}执行失败:{e}耗时:{elapsed:.3f}秒")raisereturnwrapper# 使用@performance_loggerdefgenerate_signal(klines):"""生成信号"""# 策略逻辑returnsignal五、日志分析
1. 交易分析
importpandasaspddefanalyze_trades(log_file):"""分析交易日志"""# 读取交易记录trades=[]withopen(log_file,'r',encoding='utf-8')asf:forlineinf:trades.append(json.loads(line))df=pd.DataFrame(trades)# 分析analysis={'total_trades':len(df),'win_rate':(df['pnl']>0).sum()/len(df),'avg_profit':df[df['pnl']>0]['pnl'].mean(),'avg_loss':df[df['pnl']<0]['pnl'].mean(),'total_pnl':df['pnl'].sum(),}returnanalysis# 使用analysis=analyze_trades("trades.json")print(analysis)2. 错误分析
importredefanalyze_errors(log_file):"""分析错误日志"""errors=[]withopen(log_file,'r',encoding='utf-8')asf:forlineinf:if'ERROR'inlineor'CRITICAL'inline:errors.append(line)# 统计错误类型error_types={}forerrorinerrors:# 提取错误类型match=re.search(r'(\w+Error|\w+Exception)',error)ifmatch:error_type=match.group(1)error_types[error_type]=error_types.get(error_type,0)+1returnerror_types# 使用error_stats=analyze_errors("trading_20250101.log")print(error_stats)3. 性能分析
defanalyze_performance(log_file):"""分析性能日志"""performance_data=[]withopen(log_file,'r',encoding='utf-8')asf:forlineinf:if'执行时间'inline:# 提取函数名和执行时间match=re.search(r'(\w+) 执行时间: ([\d.]+)秒',line)ifmatch:func_name=match.group(1)elapsed=float(match.group(2))performance_data.append({'function':func_name,'elapsed':elapsed})df=pd.DataFrame(performance_data)# 统计stats=df.groupby('function')['elapsed'].agg(['mean','max','count'])returnstats# 使用perf_stats=analyze_performance("trading_20250101.log")print(perf_stats)六、不同工具的日志支持
| 工具 | 日志支持 | 特点 |
|---|---|---|
| TqSdk | 需自己实现 | 灵活,可自定义 |
| VnPy | 内置日志 | 有日志模块 |
| 掘金量化 | 平台日志 | 在线查看 |
七、我的日志系统经验
作为一个从业二十年的期货量化交易者,分享几点日志系统经验:
1. 日志设计
我的日志系统包括:
- 交易日志:记录所有交易
- 信号日志:记录信号生成
- 错误日志:记录所有错误
- 性能日志:记录关键函数执行时间
2. 日志存储
我使用文件存储,按日期分割:
- 每天一个日志文件
- 保留最近30天
- 重要日志单独备份
3. 日志分析
我定期分析日志:
- 每周分析交易记录
- 每月分析错误统计
- 定期优化慢函数
我目前使用TqSdk做交易,自己实现日志系统。虽然多写一些代码,但更灵活,可以完全控制日志格式和内容。
这只是我个人的经验,每个人需求不同,建议根据自己的情况设计。
八、总结
2026年期货量化交易日志系统要点:
- 日志设计:分类记录,不同级别
- 关键信息:交易、信号、错误、性能
- 日志存储:按日期分割,定期清理
- 日志分析:定期分析,优化策略
好的日志系统是量化交易的重要保障,能帮助快速定位问题、分析策略表现。
本文仅作为技术介绍,不代表对任何工具的推荐。实际使用请自行评估。
声明:本文基于个人学习经验整理,仅供技术交流参考,不构成任何投资建议。