目录
3.1 source_api_0_0_1.proto文件编码
2.1 import_api_OptionService_0_0_1.proto
👉编码历史数据查询服务接口👈
一、单节点期货数据查询接口
1、数据说明
1.1 工程命名
- 本地IP及端口号设定为:127.0.0.1:8091
- QdService:工程文件夹名称
- FuturesData:数据接口名
1.2 查询变量
- category:数据类别(包括日线查询"daybar"和分钟线查询"minbar")
- target:标的名称
- start_time:开始时间
- end_time:结束时间
- limit_price:限定价格(例如限定开盘价范围)
1.3 数据字段
- 'date': 日期时间
- 'open_price': 开盘价
- 'high_price': 最高价
- 'low_price': 最低价
- 'close_price': 收盘价
- 'volume': 成交量
- 'amount': 成交额
2、数据查询代码
2.1 优化源代码
经过优化,实现数据查询代码能够同时满足两种不同存储路径的日线和分钟线数据查询功能。具体代码如下:
import pandas as pd
import h5py
import os
import numpy as np
from datetime import datetime
day_path="F:/daybar/future_daybar.h5"
min_path="F:/minbar/future"
def query_data(category, target, start_time, end_time, limit_price):
data_list = []
column_mapping = {
'date': 0,
'open_price': 1,
'high_price': 2,
'low_price': 3,
'close_price': 4,
'volume': 5, #成交量
'amount': 6, #成交额
}
if category == 'daybar':
file_path = day_path
date_format = "%Y%m%d"
with h5py.File(file_path, mode="r") as h5:
if target in h5:
dataset = h5[target]
data_list = [] # 在每次循环之前清空 data_list
filtered_data = [] # 初始化为一个空列表
for data in dataset:
if pd.to_datetime(data[0], format=date_format) < pd.to_datetime(start_time, format="%Y%m%d"):
continue
if pd.to_datetime(data[0], format=date_format) > pd.to_datetime(end_time, format="%Y%m%d") :
break
selected_data = {column_name: data[column_index] for column_name, column_index in column_mapping.items()}
data_list.append(selected_data)
filtered_data = [row for row in data_list if row['close_price'] >= limit_price]
elif category == 'minbar':
file_path = min_path
date_format = "%Y%m%d%H%M%S"
for filename in os.listdir(file_path):
if filename.endswith(".h5") and target in filename:
h5_path = os.path.join(file_path, filename)
with h5py.File(h5_path, mode="r") as h5_file:
if 'data' in h5_file:
dataset = h5_file['data']
data_list = [] # 在每次循环之前清空 data_list
filtered_data = [] # 初始化为一个空列表
for data in dataset:
if pd.to_datetime(data[0], format=date_format) < pd.to_datetime(start_time, format=date_format):
continue
if pd.to_datetime(data[0], format=date_format) > pd.to_datetime(end_time, format=date_format):
break
selected_data = {column_name: data[column_index] for column_name, column_index in column_mapping.items()}
data_list.append(selected_data)
filtered_data = [row for row in data_list if row['close_price'] >= limit_price]
else:
raise ValueError("Invalid category. Use 'daybar' or 'minbar'.")
result = pd.DataFrame(filtered_data)
return result
2.2 代码测试及结果
如下所示,分别尝试日线数据和分钟线数据的查询。
#测试代码1
category='daybar'
target='A0303'
start_time="20020401"
end_time="20020410"
limit_price=2105
darbar = query_data(category, target, start_time, end_time, limit_price)
darbar
#测试代码2
category='minbar'
target='A88'
start_time="20100104090100"
end_time="20100104091000"
limit_price=8400
minbar = query_data(category, target, start_time, end_time, limit_price)
minbar
3、数据查询接口编码
具体工程文件创建、初始化、打包、安装等步骤详见上一篇文章,此处不作赘述。
3.1 source_api_0_0_1.proto文件编码
syntax = "proto3";
import "google/protobuf/empty.proto";
message Request {
string category = 1;
string target = 2;
string start_time = 3;
string end_time = 4;
float limit_price = 5;
}
message Data {
string date = 1;
float open_price = 2;
float high_price = 3;
float low_price = 4;
float close_price = 5;
float volume = 6;
double amount = 7;
}
message Response {
repeated Data datas = 1;
}
service QdService {
rpc FuturesData(Request) returns (Response);
}
3.2 service.py文件
from x_com import xport_core
from x_com import source_api
import pandas as pd
import h5py
import os
logger = xport_core.getLogger()
class QdService:
day_path = "F:/daybar/future_daybar.h5"
min_path = "F:/minbar/future"
async def on_init(self):
logger.info("on_init...")
async def on_finalize(self):
logger.info("on_finalize...")
# FuturesData
async def futures_data(self, ctx: xport_core.Context, param: source_api.Request) -> source_api.Response:
response = source_api.Response()
response.datas = []
if param.category == 'daybar':
filtered_data = self.query_day_data(param.target, param.start_time, param.end_time, param.limit_price)
for row in filtered_data:
result = source_api.Data()
result.date = str( row["date"])
result.open_price =row["open_price"]
result.high_price = row["high_price"]
result.low_price = row["low_price"]
result.close_price =row["close_price"]
result.volume = row["volume"]
result.amount = row["amount"]
response.datas.append(result)
elif param.category == 'minbar':
filtered_data = self.query_min_data(param.target, param.start_time, param.end_time, param.limit_price)
for row in filtered_data:
result = source_api.Data()
result.date = str( row["date"])
result.open_price =row["open_price"]
result.high_price = row["high_price"]
result.low_price = row["low_price"]
result.close_price =row["close_price"]
result.volume = row["volume"]
result.amount = row["amount"]
#response.datas.append(result)
response.datas.append(result)
logger.info(filtered_data)
return response
# 数据查询函数(日线)
def query_day_data(self, target, start_time, end_time, limit_price):
file_path = self.day_path
date_format = "%Y%m%d"
data_list = []
with h5py.File(file_path, mode="r") as h5:
if target in h5:
dataset = h5[target]
for data in dataset:
if pd.to_datetime(data[0], format=date_format) < pd.to_datetime(start_time, format="%Y%m%d"):
continue
if pd.to_datetime(data[0], format=date_format) > pd.to_datetime(end_time, format="%Y%m%d"):
break
selected_data = {'date': data[0], 'open_price': data[1], 'high_price': data[2],
'low_price': data[3], 'close_price': data[4], 'volume': data[5],
'amount': data[6]}
data_list.append(selected_data)
filtered_data = [row for row in data_list if row['close_price'] >= limit_price]
#data_list.append(selected_data)
#filtered_data = [row for row in data_list if row['close_price'] >= limit_price]
#result = pd.DataFrame(filtered_data).reset_index(drop=True)
return filtered_data
# 数据查询函数(分钟线)
def query_min_data(self, target, start_time, end_time, limit_price):
file_path = self.min_path
date_format = "%Y%m%d%H%M%S"
data_list = []
for filename in os.listdir(file_path):
if filename.endswith(".h5") and target in filename:
h5_path = os.path.join(file_path, filename)
with h5py.File(h5_path, mode="r") as h5_file:
if 'data' in h5_file:
dataset = h5_file['data']
for data in dataset:
if pd.to_datetime(data[0], format=date_format) < pd.to_datetime(start_time, format=date_format):
continue
if pd.to_datetime(data[0], format=date_format) > pd.to_datetime(end_time, format=date_format):
break
selected_data = {'date': data[0], 'open_price': data[1], 'high_price': data[2],
'low_price': data[3], 'close_price': data[4], 'volume': data[5],
'amount': data[6]}
data_list.append(selected_data)
filtered_data = [row for row in data_list if row['close_price'] >= limit_price]
#result = pd.DataFrame(filtered_data).reset_index(drop=True)
return filtered_data
4、Postman接口测试
4.1 日线数据查询
4.2 分钟线数据查询
二、跨节点查询期权数据接口
1、数据说明
1.1 工程命名
- 请求数据网络IP及端口号设定为:10.86.8.16:8091
- 发送数据网络IP及端口号设定为:10.86.8.102:8080
- Test1Service:工程文件夹名称
- TDayK:日线数据接口名
- TyMinK:分钟线数据接口名
1.2 查询变量
-
"order_book_id":标的名称
-
"start_date":开始日期
-
"end_date":结束日期
-
"high_price_limit":最高价限定
1.3 数据字段
- 'date': 日期时间
- 'open_price': 开盘价
- 'high_price': 最高价
- 'low_price': 最低价
- 'close_price': 收盘价
- 'volume': 成交量
- 'total_turnover': 成交额
2、工程文件
2.1 import_api_OptionService_0_0_1.proto
2.2 source_api_0_0_1.proto
2.3 service.py
关键文件编码逻辑同上方类似,详细代码内容请下载文章顶部源码资源。
3、接口测试
3.1 跨节点请求
- Postman窗口:
- 终端显示:
3.2 日线数据查询
- Postman窗口:
- 终端显示:
3.3 分钟线数据查询
- Postman窗口:
- 终端显示:
三、总结心得
完成这篇文章的编辑只用了一个下午的时间,但要完成文章中涉及到的知识内容,我利用课余时间,总历时7周时间。
人生没有白走的路,每一步都算数,发表博客的目标即是对个人学习经历的记录,也是希望他人学习时能够少走弯路。
Nothing comes from nothing.