本方案由 EasyQuant AI量化助手 提供。如有更多问题,直接用 EasyQuant AI量化助手 帮您快速解决量化交易编程难题。
问题背景
QMT 中的历史行情通常需要先下载到 MiniQMT 本地,再通过 xtdata 接口读取。很多用户直接调用数据读取函数后发现返回为空,常见原因就是本地尚未下载对应股票、周期或日期范围的数据。
实现思路
完整流程分为四步:
-
导入
xtquant.xtdata; -
调用
download_history_data()下载指定标的和周期; -
调用
get_market_data_ex()读取本地历史 K 线; -
对 DataFrame 数据进行均线计算和信号判断。
QMT 的基础行情周期包括 tick、1m、5m、1d 等;合成周期通常依赖基础周期数据。例如需要历史 15 分钟线时,应先确保 5 分钟基础数据可用。(迅投行情函数说明)
完整代码示例
from xtquant import xtdata
import pandas as pd
# 股票代码:平安银行
STOCK_CODE = "000001.SZ"
# 读取日线数据
PERIOD = "1d"
# 历史区间
START_TIME = "20240101"
END_TIME = "20241231"
def download_kline_data():
"""
下载历史K线至MiniQMT本地缓存。
首次运行或本地数据不足时执行。
"""
xtdata.download_history_data(
stock_code=STOCK_CODE,
period=PERIOD,
start_time=START_TIME,
end_time=END_TIME
)
print("历史数据下载请求已提交:", STOCK_CODE, PERIOD)
def get_kline_data():
"""
从本地缓存读取历史K线。
返回结果通常是:{股票代码: DataFrame}。
"""
market_data = xtdata.get_market_data_ex(
field_list=[
"time",
"open",
"high",
"low",
"close",
"volume",
"amount"
],
stock_list=[STOCK_CODE],
period=PERIOD,
start_time=START_TIME,
end_time=END_TIME,
count=-1,
dividend_type="front",
fill_data=False
)
if STOCK_CODE not in market_data:
print("未读取到数据,请检查代码、周期和本地下载状态")
return None
kline_df = market_data[STOCK_CODE]
if kline_df is None or kline_df.empty:
print("K线数据为空")
return None
return kline_df
def calculate_ma_signal(kline_df):
"""
计算5日、20日均线,并识别最近一次金叉或死叉。
"""
df = kline_df.copy()
# 确保close列为数值类型
df["close"] = pd.to_numeric(df["close"])
# 计算均线
df["ma5"] = df["close"].rolling(window=5).mean()
df["ma20"] = df["close"].rolling(window=20).mean()
# 删除均线尚未形成的行
df = df.dropna().reset_index(drop=True)
if len(df) < 2:
print("有效数据不足,无法判断均线交叉")
return df
last_row = df.iloc[-1]
prev_row = df.iloc[-2]
buy_signal = (
last_row["ma5"] > last_row["ma20"]
and prev_row["ma5"] <= prev_row["ma20"]
)
sell_signal = (
last_row["ma5"] < last_row["ma20"]
and prev_row["ma5"] >= prev_row["ma20"]
)
print("最新收盘价:", round(last_row["close"], 2))
print("MA5:", round(last_row["ma5"], 2))
print("MA20:", round(last_row["ma20"], 2))
if buy_signal:
print("信号结果:MA5 上穿 MA20,出现均线金叉")
elif sell_signal:
print("信号结果:MA5 下穿 MA20,出现均线死叉")
else:
print("信号结果:当前无新的均线交叉")
return df
if __name__ == "__main__":
# 第一步:下载历史数据
download_kline_data()
# 第二步:读取本地历史数据
kline_data = get_kline_data()
# 第三步:计算指标与交易信号
if kline_data is not None:
result_df = calculate_ma_signal(kline_data)
# 查看最近10根K线及均线结果
print(result_df.tail(10))
注意事项
-
QMT 股票代码格式为
代码.市场,例如000001.SZ、600000.SH。 -
download_history_data()负责补充本地数据;读取前应确认 MiniQMT 已连接且行情权限正常。 -
count=-1表示读取满足条件的全部本地数据,数据量较大时应限制时间范围。 -
前复权、后复权或不复权会影响价格序列,策略回测和实盘计算应保持一致。
-
下载历史数据与订阅实时数据是两套流程:历史部分通常先下载,实时部分可通过订阅接口获取。(迅投 XtData 文档)
总结
QMT 获取历史 K 线的关键是“先下载、再读取”。掌握 download_history_data() 和 get_market_data_ex() 后,就可以继续扩展到多股票数据、分钟线指标计算、回测数据准备和实时策略开发。
本方案由 EasyQuant AI量化助手 提供。

2126

被折叠的 条评论
为什么被折叠?



