问题描述
获取当日最新分钟数据为空,部分股票获取分钟数据为空,国金客户端,绍兴行情服务器,获取代码如下
def get_minute_bars(date, code):
start_date = date.strftime('%Y%m%d') + '000000'
end_date = date.strftime('%Y%m%d') + '235959'
seq = xtdata.subscribe_quote(code, period='1m', count=-1)
stock = xtdata.get_market_data_ex(
field_list=['time', 'open', 'high', 'low', 'close', 'volume', 'amount'],
stock_list=[code],
period='1m',
start_time=start_date,
end_time=end_date,
count=-1,
dividend_type='none'
)
xtdata.unsubscribe_quote(seq)
df = stock[code]
if len(df) == 0:
return None
tuples_array = []
for row in df.itertuples(index=False):
tuples_array.append((code,
row[0],
row[1],
row[2],
row[3],
row[4],
row[5],
row[6]
))
return tuples_array
def get_minute_bars(date, code):
start_date = date.strftime('%Y%m%d') + '000000'
end_date = date.strftime('%Y%m%d') + '235959'
seq = xtdata.subscribe_quote(code, period='1m', count=-1)
stock = xtdata.get_market_data_ex(
field_list=['time', 'open', 'high', 'low', 'close', 'volume', 'amount'],
stock_list=[code],
period='1m',
start_time=start_date,
end_time=end_date,
count=-1,
dividend_type='none'
)
xtdata.unsubscribe_quote(seq)
df = stock[code]
if len(df) == 0:
return None
tuples_array = []
for row in df.itertuples(index=False):
tuples_array.append((code,
row[0],
row[1],
row[2],
row[3],
row[4],
row[5],
row[6]
))
return tuples_array
解决方案
在QMT中获取分钟数据时,如果遇到部分股票返回空DataFrame的情况,通常是因为数据订阅和获取的机制导致的。以下是可能的原因及解决方法:
问题原因分析
- 异步订阅机制:
xtdata.subscribe_quote是异步执行的。当你调用订阅函数后,立即调用get_market_data_ex获取数据,此时数据可能还没有从服务器推送到本地端,导致获取到的数据为空。 - 本地数据缺失:
get_market_data_ex默认会从本地读取数据。如果本地没有该股票的分钟数据,且订阅数据还未到达,就会返回空。 - 停牌或无交易:部分股票可能处于停牌状态,或者在指定时间段内没有交易数据。
解决方法
为了确保在获取数据前,数据已经成功推送到本地,可以采用以下几种方法:
方法一:增加等待时间
在订阅数据后,增加一个短暂的等待时间,让数据有足够的时间推送到本地。
import time
from xtquant import xtdata
def get_minute_bars(date, code):
start_date = date.strftime('%Y%m%d') + '000000'
end_date = date.strftime('%Y%m%d') + '235959'
# 订阅数据
seq = xtdata.subscribe_quote(code, period='1m', count=-1)
# 增加等待时间,确保数据推送到本地
time.sleep(1) # 根据网络情况调整等待时间
# 获取数据
stock = xtdata.get_market_data_ex(
field_list=['time', 'open', 'high', 'low', 'close', 'volume', 'amount'],
stock_list=[code],
period='1m',
start_time=start_date,
end_time=end_date,
count=-1,
dividend_type='none'
)
# 取消订阅
xtdata.unsubscribe_quote(seq)
df = stock.get(code)
if df is None or len(df) == 0:
return None
tuples_array = []
for row in df.itertuples(index=False):
tuples_array.append((code,
row[0],
row[1],
row[2],
row[3],
row[4],
row[5],
row[6]
))
return tuples_array
方法二:使用回调函数处理数据
更稳妥的方法是使用 subscribe_quote 的回调函数,在数据到达时进行处理。
from xtquant import xtdata
import pandas as pd
def on_quote(datas):
for code, df in datas.items():
if not df.empty:
print(f"Received data for {code}:")
print(df)
# 在这里处理你的数据逻辑
def get_minute_bars_async(code):
# 订阅数据并设置回调函数
seq = xtdata.subscribe_quote(code, period='1m', count=-1, callback=on_quote)
return seq
# 使用示例
# seq = get_minute_bars_async('000001.SZ')
# ... 运行一段时间后 ...
# xtdata.unsubscribe_quote(seq)
方法三:提前下载历史数据
如果你需要的是历史分钟数据,建议提前使用 xtdata.download_history_data 下载好数据,然后再使用 get_market_data_ex 读取本地数据。
from xtquant import xtdata
def download_and_get_data(code, start_date, end_date):
# 提前下载数据
xtdata.download_history_data(code, period='1m', start_time=start_date, end_time=end_date)
# 获取本地数据
stock = xtdata.get_market_data_ex(
field_list=['time', 'open', 'high', 'low', 'close', 'volume', 'amount'],
stock_list=[code],
period='1m',
start_time=start_date,
end_time=end_date,
count=-1,
dividend_type='none'
)
return stock.get(code)
总结
在QMT中,subscribe_quote 是异步的,直接调用 get_market_data_ex 可能会因为数据未到达而返回空。通过增加等待时间、使用回调函数或提前下载历史数据,可以有效解决这个问题。