pytdx
pytdx copied to clipboard
能否提供返回字段的含义
感谢您的贡献,能否提供返回字段的含义,比如行情返回的reversed_bytes,active2,查看了代码,也没找到注释。另外,是否可解析出换手率数据。
reversed_bytes 是和时间有关的信息,不过目前还无法正确还原为时间, active2 目前还无法解析..
至于具体的字段含义,暂时还没有精力一一整理,后续有时间的时候把主要接口的返回字段回加上一些说明
@leegb 感谢关注.
@rainx 期待你解析完成,不知是不是服务器不支持并发访问,我看了get_security_quotes()通过循环实现我通过它来获取即时行情费时太多,无法满足对市场的监控。
通达信的协议里面有一个类似tcp头中的seq_no的序列号, 一个请求和一个应答回包含相同的seq_no, 一般在请求头的第二个字节,这个我目前并没有利用,如果按照这个设计的话,理论上可以在一个连接里面发送多条请求之后再接收应答信息(目前还未实现), 理论上python对线程并发的支持并不好,如果想要提高吞吐量,可以创建多个进程,每个进程一个独立的连接,分别读取不同的代码,这样的方式来获取行情信息可以提升单个服务器的吞吐量,当然更好的方法是连接到不同的服务器,这样的话可以分散服务器访问压力..
@rainx 对通信协议不了解,之前用的是网易网页的API,获取一次全市场即时行情的时间也就几秒钟,但是最近不知道为什么变得非常慢,希望你能将一次发送多个代码,返回数据的功能开发出来,不胜感激。
对于抓取全市场行情,暂时还无法提供对应的代码,目前来看,基本上提供了此功能的库很快都会被数据源方屏蔽,比如新浪level2行情,不建议大范围使用
对于一次发送多个代码,我们的程序本来就是支持的,只不过对与每次调用时发送代码数量上限有一定的限制,您可以酌情使用。。
In [8]: api.to_df(api.get_security_quotes([(0, "000001"), (1, "600300")]))
Out[8]:
market code active1 price last_close open high low \
0 0 000001 0 0.0 10.44 0.0 0.0 0.0
1 1 600300 0 0.0 5.52 0.0 0.0 0.0
reversed_bytes0 reversed_bytes1 ... ask5 bid_vol5 ask_vol5 \
0 [184, 242, 223, 8] 0 ... 0.0 0 0
1 [164, 150, 222, 8] 0 ... 0.0 0 0
reversed_bytes4 reversed_bytes5 reversed_bytes6 reversed_bytes7 \
0 (0,) 0 1054 1075
1 (0,) 0 553 559
reversed_bytes8 reversed_bytes9 active2
0 1029 0 0
1 549 0 0
[2 rows x 44 columns]
全市场实时行情 是单指last_price吗
@rainx api.get_security_list(1, 0)这个api可以呀
@yutiansut 全市场api.get_security_quotes()的最新成交价
@leegb 只是获取最新价用 get_security_list 就可以了,一次获取的也比较多
@leegb api.get_security_quotes()如果只要最新成交价 这个的数据太多了 传输时间也是问题
:)
通达信的协议里面有一个类似tcp头中的seq_no的序列号, 一个请求和一个应答回包含相同的seq_no, 一般在请求头的第二个字节,这个我目前并没有利用,如果按照这个设计的话,理论上可以在一个连接里面发送多条请求之后再接收应答信息(目前还未实现)
能否保留seq_no,将请求/应答分离开来,使用asyncio,提高单一连接的吞吐量
seq_no..这个我后续再加吧...因为暂时用同步获取感觉速度也还可以,另外就是有点担心抓取的量太大被服务器block..
获取个数多的话,单机可以考虑用python的多进程map-reduce向多个服务器发起请求。用futures.ProcessPoolExecutor()的map方法。代码几乎不用修改,很简单。 目前这几天正在测试,用M个进程实时获取数据,每个进程随机从N(N>3M)个服务器中选取一个。 用了API后,数据获取模式会跟一般客户端有明显区别,如果对单个服务器扒太狠,当心TDX提出限制措施,那时就变成魔高一尺,道高一丈的游戏了。
用yutiansut 的代码 https://github.com/yutiansut/QUANTAXIS/blob/master/QUANTAXIS/QAFetch/QATdx.py#L53 修改了一个函数: tdx_get_servers(),用途是测试ip列表中的服务器速度,返回连接速度较快的n个列表。 使用的时候,,一般这样:
servers=tdx_get_servers(n=10)
api.connect(server[randint(1,10)],7709)
把servers=tdx_get_servers()放在程序头部 在程序内编写涉及到api.connect时,用随机函数从该列表中取得地址
应该可以部分缓解对单个服务器的压力。 更进一步的数据读取采取多线程或者进程的话,注意测试servers作为参数是否传递进线程或者进程。
from pytdx.hq import TdxHq_API
from datetime import datetime,timedelta
import pandas as pd
#import numpy as np
tdx_ip = [
'101.227.73.20',
'202.108.253.130',
......
]
def ping_tdx(ip):
t1 = datetime.now()
api = TdxHq_API()
try:
with api.connect(ip, 7709):
api.get_index_bars(9, 1, '000001', 0, 1)
return (datetime.now() - t1).total_seconds()
except:
return 9999
def tdx_get_servers( n=5, df=False):
lt = []
for t_ip,t_s in zip(tdx_ip,map(ping_tdx,tdx_ip)):
lt.append([t_ip,t_s])
server_list = pd.DataFrame(lt).sort_values(by=1)
if df:
return server_list
server_list = server_list[server_list[1] < 0.2]
return list(server_list.iloc[0:n,0].values)
参数 n:返回服务器数量,默认5个 df:测试开关,设为True时返回所有结果的DataFrame
我不是写了吗 @solensolen https://github.com/yutiansut/QUANTAXIS/blob/master/QUANTAXIS/QAFetch/QATdx.py#L53
def ping(ip):
api = TdxHq_API()
__time1 = datetime.datetime.now()
try:
with api.connect(ip, 7709):
api.get_security_bars(9, 0, '000001', 0, 1)
return datetime.datetime.now() - __time1
except:
return datetime.timedelta(9, 9, 0)
def select_best_ip():
QA_util_log_info('Selecting the Best Server IP of TDX')
listx = ['180.153.18.170', '180.153.18.171', '202.108.253.130', '202.108.253.131',
'60.191.117.167', '115.238.56.198', '218.75.126.9', '115.238.90.165',
'124.160.88.183', '60.12.136.250', '218.108.98.244', '218.108.47.69',
'14.17.75.71', '180.153.39.51']
data = [ping(x) for x in listx]
QA_util_log_info('===The BEST SERVER is : %s ===' %
(listx[data.index(min(data))]))
return listx[data.index(min(data))]
@solensolen 我这是找到最快的那个
嗯,就是参考您代码改的,因为需要一次获取多个列表。主要为了实现单线程或多线程运行中随机更换tdx服务器。
另外防止股票‘000001’休市可能导致异常,ping里面改成获取指数api.get_index_bars
不会的 他是start0 拿一条 所以今天停牌 也会有昨天的数据
如果你拿失败了(比如被封了) 重新运行这个代码 就能返回新的
不过有个烦躁的是 服务器多的话 验证最优的时候 如果timeout比较多 会阻塞比较久
确实,我单进程测试,30个服务器,都通的话4-5秒就结束。有2个TO,就要+4S左右了。如果更多TO,时间估计还要加。 如果TO服务器比例特别高,我这代码改两行,用多线程可以缓解。但你这面向公众的代码又不能随便采用多线程,到时不同的机器硬件出一堆其他问题。
是的 最好是生产者消费者模式 不过有点小题大做 除非你对行情低延迟性要求很高 如果是存数据 就没关系了
发现一个坑爹的情况,对于停牌股票,不同服务器的返回策略不一样: 有些是返回当前K线,但成交额为0或者一个很小的数。 有些返回停牌前的K线。
@solensolen 哦? 哪个服务器? 地址有吗 我测一下
没有记录.....比例很小,但可能会撞上。估计是某个券商的调整。加了一段代码进行判断才正常,把获取的最新记录的日期和当前日期比对,然后再根据成交量判断。
last_day = datetime.date(tt.iloc[-1,].name)
if last_day == date.today():
if tt.loc[last_day:,'amount'].sum() >1:
return (code,tt.loc[last_day:,])
else:
return ('stop_'+code,'有返回当天数据但实际无成交量,判断停牌')
else:
return ('stop_'+code,'未返回当天数据,判断停牌')
实际测试了一下,4s可以取完全部行情
理论上是700ms 不知道为啥这么慢
@rainx active这个字段之前稍微纠结过一下,应该时间和tick相关的一个字段,active相同的话,其他字段的值都是一样的
你说的是方向?