问题描述
解决方案
在 QMT 量化交易平台中,将 13 位毫秒级时间戳转换为可读的日期格式,最直接且推荐的方法是使用平台内置的 API 函数 timetag_to_datetime。此外,也可以使用 Python 标准库 datetime 进行转换。
以下是具体的实现方法:
方法一:使用 QMT 内置函数 timetag_to_datetime(推荐)
QMT 提供了一个专门的全局函数用于处理时间戳转换,无需额外导入库,且针对平台内部的时间戳格式进行了优化。
函数原型:
timetag_to_datetime(timetag, format)
参数说明:
timetag:13 位毫秒级时间戳(例如:1640995200000)。format:目标格式字符串(例如:'%Y-%m-%d %H:%M:%S')。
代码示例:
# -*- coding: gbk -*-
def init(ContextInfo):
# 示例:假设有一个毫秒时间戳
timestamp = 1640995200000
# 转换为 "年-月-日 时:分:秒" 格式
date_str = timetag_to_datetime(timestamp, '%Y-%m-%d %H:%M:%S')
print(f"完整时间: {date_str}")
# 转换为 "年MM月DD日" 格式
date_str_short = timetag_to_datetime(timestamp, '%Y%m%d')
print(f"日期格式: {date_str_short}")
def handlebar(ContextInfo):
# 获取当前 K 线的时间戳
current_timetag = ContextInfo.get_bar_timetag(ContextInfo.barpos)
# 转换并打印
readable_time = timetag_to_datetime(current_timetag, '%Y-%m-%d %H:%M:%S')
print(f"当前K线时间: {readable_time}")
方法二:使用 Python 标准库 datetime
如果你需要生成 datetime 对象以便进行日期的加减运算(而不是仅仅输出字符串),可以使用 Python 标准库。
注意: Python 的 fromtimestamp 接收的是秒(10位),而 QMT 的时间戳是毫秒(13位),因此计算时必须除以 1000。
代码示例:
# -*- coding: gbk -*-
import datetime
def init(ContextInfo):
pass
def handlebar(ContextInfo):
# 获取毫秒时间戳
ms_timestamp = ContextInfo.get_bar_timetag(ContextInfo.barpos)
# 转换为 datetime 对象 (注意除以 1000)
dt_object = datetime.datetime.fromtimestamp(ms_timestamp / 1000)
# 格式化为字符串
date_str = dt_object.strftime('%Y-%m-%d %H:%M:%S')
print(f"datetime对象转换: {date_str}")
print(f"年份: {dt_object.year}, 月份: {dt_object.month}")
常见 QMT 时间戳来源
在编写策略时,你通常会从以下接口获取到这种 13 位时间戳:
ContextInfo.get_bar_timetag(index): 获取指定 K 线索引的时间戳。ContextInfo.get_tick_timetag(): 获取当前最新分笔(Tick)的时间戳。ContextInfo.get_market_data_ex(...): 返回的 DataFrame 索引通常也是时间格式,有时需要处理。
Q&A
Q: timetag_to_datetime 函数返回的数据类型是什么?
A: 该函数返回的是字符串 (string) 类型。如果需要进行日期计算(如计算两天前的时间),建议使用方法二中的 datetime 对象。
Q: 格式化字符串 %Y-%m-%d 代表什么意思?
A: 这是 Python 的标准时间格式化符号:
%Y: 4位数的年份 (如 2023)%m: 2位数的月份 (01-12)%d: 2位数的日期 (01-31)%H: 24小时制的小时 (00-23)%M: 分钟 (00-59)%S: 秒 (00-59)
Q: 为什么使用 datetime.fromtimestamp 转换出来的时间不对?
A: 最常见的原因是忘记将 QMT 的毫秒时间戳除以 1000。QMT 使用 13 位毫秒戳,而 Python 标准库默认处理 10 位秒戳。如果不除以 1000,年份会变成遥远的未来(如 50000 年以后)。