问题描述
有一个策略要用到月线数据,在使用 get_market_data_ex 时候,没法获取到数据,已经下载了 1 分钟和日线数据。代码如下:
BY_DAIMA=["000059.SZ"]
MON_Positions_data = ContextInfo.get_market_data_ex([],BY_DAIMA,'1mon','','',50,'front',False,False)
MON_df=MON_Positions_data[BY_DAIMA[0]].index
MON_Close_list = MON_Positions_data[BY_DAIMA[0]].loc[:,'close']
print(MON_Positions_data)
print(len(MON_CLOSE_list))
print(now_date)
运行上述代码获取不到数据,仅仅修改周期字段为 1d 和 1w 均能取到数据。
是什么原因呢?还是说没有实现月线等,还是字段有误?
解决方案
在 QMT 平台中使用 get_market_data_ex 接口获取长周期(如月线 1mon、季线 1q、半年线 1hy)数据失败,通常是由以下两个原因导致的:
1. 原因分析
- 本地数据未下载:QMT 的数据接口依赖于本地数据。如果您只在“数据管理”中下载了 1 分钟和日线数据,而没有专门下载月线或季线数据,接口将无法直接返回这些周期的数据。虽然平台有时会自动合成周线(
1w),但对更长周期的自动合成支持可能不完善。 - 接口参数支持限制:根据 QMT 官方 API 文档,
get_market_data_ex的period参数主要明确支持'tick'、分钟线(如'1m','5m')、日线('1d')等。对于'1mon'等长周期,建议通过日线数据自行合成,这样既准确又灵活。
2. 解决方案:使用 Pandas 将日线重采样为月线
既然您已经下载了日线数据,最稳妥且高效的方法是:获取日线数据(1d),然后使用 Python 的 pandas 库将其重采样(Resample)为月线、季线等任意周期数据。
以下是具体的代码示例:
#coding:gbk
import pandas as pd
def init(ContextInfo):
pass
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
return
BY_DAIMA = ["000059.SZ"]
# 1. 获取足够数量的日线数据(例如获取过去500个交易日的日线)
daily_data = ContextInfo.get_market_data_ex([], BY_DAIMA, '1d', '', '', 500, 'front', False, False)
if BY_DAIMA[0] in daily_data and not daily_data[BY_DAIMA[0]].empty:
df = daily_data[BY_DAIMA[0]]
# 2. 将索引(字符串格式的日期)转换为 datetime 格式
df.index = pd.to_datetime(df.index)
# 3. 使用 pandas 的 resample 方法重采样为月线 ('M' 代表月末)
# 定义各字段的合成规则:开盘价取月初,最高价取当月最高,最低价取当月最低,收盘价取月末,成交量/额求和
mon_df = df.resample('M').agg({
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum',
'amount': 'sum'
})
# 4. 剔除没有交易的月份(例如停牌导致全月无数据)
mon_df = mon_df.dropna()
# 打印合成后的月线数据
print("合成的月线数据:")
print(mon_df.tail())
# 获取月线收盘价列表
MON_Close_list = mon_df['close'].tolist()
print("月线收盘价列表长度:", len(MON_Close_list))
else:
print("未获取到日线数据,请检查数据下载情况。")
3. 扩展:如何合成季线和半年线?
使用上述 resample 方法,您只需修改重采样的频率字符串即可轻松获得其他周期数据:
- 季线 (1q):将
resample('M')改为resample('Q') - 半年线 (1hy):将
resample('M')改为resample('6M') - 年线 (1y):将
resample('M')改为resample('Y')
这种方法不仅解决了接口直接获取不到数据的问题,还能确保复权方式(如前复权)在长周期上的计算完全符合您的策略逻辑。