问题描述
坑爹的设计。 一个不留神,改了个参数,然后就点了一下重启策略。。。。
然后就心满意足的退出Ptrade。
然后想起来有个日志想要查一下的。再进去一看,里面的几个月的日志就被清除了。 OMG
这个清除日志的操作虽然说是软件设置的。但是产品经理应该也要评估一下,哪怕我只是改一个时间,比如我把策略从9:15分执行改成9:16执行,只要改动,策略就需要被重启,才能生效。
试问,哪个策略能够几年不出错,不修改,一直在上面运行的呢? 退一万步讲,其实如果我知道我即将修改后重启策略,面对这几百个按时间切割的日志,我用什么工具导出呢?
解决方案
为什么 ptrade 重启策略会清空日志?
在 ptrade 平台中,前端界面展示的日志通常是与当前策略进程绑定的。当你修改参数并点击“重启策略”时,系统会销毁旧的策略进程并启动一个新进程。为了节省服务器存储空间和保证界面加载速度,旧进程的控制台日志往往会被系统自动清理。这对于需要长期回溯实盘表现的量化交易者来说,确实是一个痛点。
解决方案:如何实现 ptrade 日志的持久化保存?
既然平台前端的日志不可靠,我们可以利用 Python 原生的文件操作能力,结合 ptrade 提供的 get_research_path() 接口,将关键日志直接写入到研究环境的磁盘中。这样,无论策略如何重启,日志文件都会安全地保存在你的个人目录下,随时可以下载导出。
方法一:自定义日志写入函数(推荐)
你可以编写一个自定义的日志函数,在调用 ptrade 自带的 log.info() 的同时,将内容追加写入到本地的 .txt 或 .csv 文件中。
import datetime
import os
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
# 获取研究路径,用于持久化保存文件
g.log_path = get_research_path() + 'my_strategy_log.txt'
write_custom_log("策略启动/重启,初始化完成")
def write_custom_log(content):
"""
自定义日志写入函数,同时输出到控制台和本地文件
"""
# 1. 调用系统日志在界面显示
log.info(content)
# 2. 写入本地文件持久化
try:
now_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_line = f"[{now_str}] {content}\n"
with open(g.log_path, 'a', encoding='utf-8') as f:
f.write(log_line)
except Exception as e:
log.error(f"写入本地日志失败: {e}")
def handle_data(context, data):
current_price = data[g.security]['close']
if current_price > 50:
order(g.security, 100)
write_custom_log(f"触发买入条件,买入 {g.security} 100股,当前价格 {current_price}")
方法二:使用 Python 标准库 logging 模块
ptrade 的 log 对象本身就是基于 Python 的 logging 模块封装的。你可以直接配置一个 FileHandler,让所有的日志自动输出到文件中。
import logging
import os
def setup_file_logger():
# 获取研究路径
log_dir = get_research_path()
log_file = os.path.join(log_dir, 'strategy_persistent.log')
# 获取 ptrade 的根 logger
logger = logging.getLogger()
# 检查是否已经添加过 FileHandler,避免重复添加
has_file_handler = any(isinstance(h, logging.FileHandler) for h in logger.handlers)
if not has_file_handler:
file_handler = logging.FileHandler(log_file, mode='a', encoding='utf-8')
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.setLevel(logging.INFO)
def initialize(context):
setup_file_logger()
log.info("策略初始化,日志已配置为持久化保存到研究目录。")
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
log.info("正常记录日志,这条信息不仅会在界面显示,还会保存在文件中。")
方法三:关键错误使用邮件报警
对于几个月才看一次的策略,除了保存日志,更重要的是在发生异常时能及时收到通知。ptrade 提供了 set_email_info 接口,可以在策略异常终止时发送邮件。
def initialize(context):
# 设置邮件信息 (需咨询券商当前环境是否支持)
set_email_info("[email protected]", "your_smtp_code", "【PTrade量化-策略异常提醒】")
log.info("邮件报警配置完成")
总结与建议
- 不要过度依赖前端 UI 日志:前端日志主要用于调试和短期监控。实盘策略的交易记录、核心变量状态必须通过文件持久化(如写入 CSV 或 TXT)。
- 定期导出:使用上述方法将日志写入
get_research_path()后,你可以随时进入 ptrade 的“研究”模块(Jupyter Notebook 环境),找到对应的日志文件并下载到本地电脑,再也不用担心重启策略导致数据丢失了。 - 按月切割日志:如果日志量很大,可以在自定义写入函数中,根据当前月份动态生成文件名(如
log_2023_10.txt),方便后续管理和导出。