日志和只跑一次:日期戳 / C.done
这是工程记录。handlebar 每根 K 线都会进。不卡住,同一天会把接口打几十遍。不构成投资建议,不代操盘。
为什么要戳
| 场景 | 不戳会怎样 |
|---|---|
日线 handlebar | 回测每天一根还好;实盘同一分钟可能进多次 |
| 分钟线 | 一天几百根,选股、查持仓、写文件会重复 |
run_time 秒级 | 更容易连打 |
| 下单 / 申购 / 撤单 | 重复提交 |
长期状态不要只塞在 ContextInfo 上。盘中逐 K 可能回滚。日期戳放模块级变量或普通对象。
QMT:日期戳 + done
python
#coding:gbk
from datetime import datetime
_last_job_date = ''
def init(C):
C.done = False
def handlebar(C):
if not C.is_last_bar():
return
try:
tag = C.get_bar_timetag(C.barpos)
d = datetime.fromtimestamp(tag / 1000).strftime('%Y%m%d')
except Exception:
d = datetime.now().strftime('%Y%m%d')
global _last_job_date
if _last_job_date == d:
return
print('today once', d)
# 这里打一次接口 / 写一次日志
_last_job_date = d只要「进程里只跑一次」(回测整个区间一次),用 C.done:
python
def init(C):
C.done = False
def handlebar(C):
if C.done or not C.is_last_bar():
return
print('whole run once')
C.done = True实盘跨日要把 done 按日期清掉,否则第二天不再进。
PTrade:按 context.current_dt
python
def initialize(context):
g.last_job_date = None
def handle_data(context, data):
d = context.current_dt.strftime('%Y%m%d')
if g.last_job_date == d:
return
log.info('today once %s', d)
g.last_job_date = drun_daily 一天本来一次,仍建议打日期日志,方便和 handle_data 对账。
坑
- 只判断
is_last_bar(),实盘同一分钟仍可能进两次。日期戳和分钟戳叠一层。 - 把计数器写在
C.xxx上,定时器和handlebar不一定是同一个 C,对不上。用模块级变量。 - 日志不要每根 K 线
print整张表,先戳再打。QMT 日志在安装目录userdata/log。 - 写本地 json 做持久化时,路径要在客户端能写的目录,重启后先读再跑。
完整讨论和附件在 知识星球 Kimi量化研究所。
