做量化没有实时数据怎么行?一个超级好用的Python库,速度贼快!

360影视 动漫周边 2025-03-13 13:43 3

摘要:import psutilimport subprocessdef get_tdx_pid: """通过进程名或路径特征获取通达信进程的PID""" for proc in psutil.process_iter(['pid', 'name', 'exe'])

作为一个量化交易的“苦逼”搬砖人,你有没有遇到过这样的窘境:

想写个量化策略,数据卡到起飞?找了半天数据接口,收费的贼贵,免费的贼慢?本来准备大展拳脚,结果光是爬数据就累得半死?

pytdx 是一款纯Python语言开发的类似TradeX的行情数据接口的实现。最重要的是,它速度快,还不用花钱!

安装过程相当简单,直接用 pip 一把梭:

pip install pytdx

如果下载速度感人,可以试试国内源:

pip install pytdx -i https://pypi.tuna.tsinghua.edu.cn/simple

要获取数据,咱们得先连上 TDX 的行情服务器,代码如下:

from pytdx.hq import TdxHq_API# 创建 API 对象api = TdxHq_API# 连接服务器if api.connect('119.147.212.81', 7709): print("连接成功!") # 做一些操作 api.disconnect #关闭连接else: print("连接失败!")

这里花姐推荐使用 with 语法,可以省略disconnect语句

with api.connect('119.147.212.81', 7709): # 做一些操作

这里的 119.147.212.81:7709 是一个 TDX 行情服务器,你可以换成其他可用的服务器。

提示: 估计99%的人到这里就被卡住了,disconnect直接连接失败,主要是 119.147.212.81:7709 这个 TDX 行情服务器不可用了。

查看pytdx源码,我们看到里面已经写好了许多ip池,但是许多已经不能用了

通过以下代码可以找到可用的行情服务器ip

from pytdx.util.best_ip import select_best_ipbest_ip = select_best_ipprint(f"最优服务器:IP={best_ip['ip']}, 端口={best_ip['port']}")

花姐独家获取方式先安装 通达信 软件,然后打开 接下来运行该代码就可以获得通达信的行情ip了

import psutilimport subprocessdef get_tdx_pid: """通过进程名或路径特征获取通达信进程的PID""" for proc in psutil.process_iter(['pid', 'name', 'exe']): try: # 匹配条件1:精确匹配进程名(考虑Windows大小写不敏感特性) if proc.info['name'] and 'tdxw.exe' == proc.info['name'].lower: return proc.pid # 匹配条件2:路径特征匹配(适配不同安装位置的通达信客户端) exe_path = proc.info['exe'] or '' if 'new_tdx' in exe_path and 'tdxw.exe' in exe_path: return proc.pid except (psutil.NoSuchProcess, psutil.AccessDenied): # 处理进程已结束或权限不足的情况,继续遍历其他进程 continue return Nonedef find_ip_by_pid(pid, port): """通过PID和端口号查找对应的网络连接信息""" # 构建命令:查找指定PID和端口的网络连接 cmd = f'netstat -ano | findstr "{pid}" | findstr "{port}"' try: # 执行命令并捕获输出 result = subprocess.check_output(cmd, shell=True, text=True) # 按行分割并解析每部分信息 lines = [line.split for line in result.strip.split('\n')] return [{ 'proto': parts[0], # 协议类型(TCP/UDP) 'local': parts[1], # 本地地址:端口 'remote': parts[2], # 远端地址:端口(即行情服务器地址) 'state': parts[3], # 连接状态(ESTABLISHED等) 'pid': parts[4] # 进程ID(用于二次验证) } for parts in lines] except subprocess.CalledProcessError: # 未找到匹配结果时返回空列表 return # 主执行流程if __name__ == "__main__": # 步骤1:获取通达信客户端PID pid = get_tdx_pid # 步骤2:查找该PID与7709端口(通达信默认行情端口)的连接信息 ip_port = find_ip_by_pid(pid, 7709) # 步骤3:处理查询结果 if len(ip_port): for part in ip_port: print("通达信行情服务器为:", part['remote']) else: print("未找到通达信行情服务器")

运行结果如下:

连接上服务器后,我们就可以拉取实时行情数据了,比如查询 贵州茅台 的数据:

# 获取单只股票的实时行情stock_data = api.get_security_quotes(1, '600519')print(stock_data)

重要知识点:

1 代表上海证券交易所 (6开头的股票,688、689 也填1)0 代表深证证券交易交所 (3、0 开头的股票)2 代表北京证券交易所 (4、8、9 开头的股票)

如果要获取多个股票的代码使用如下格式数据:[ (市场代码1, 股票代码1),(市场代码2, 股票代码2) ... (市场代码n, 股票代码n) ]

返回值解析

返回值是一个数组,数组里是OrderedDict格式的数据,OrderedDict 是 Python 中 collections 模块提供的一种字典子类,它 保持键值对的插入顺序。与普通字典(dict)不同,OrderedDict 在遍历时会按照键值对插入的顺序返回数据,而不是随机顺序。 可以通过stock_data[0]['open'] 的形式获取具体的值

开盘、最高、最低、收盘、成交量、成交额、买盘报价、卖盘报价都有非常不错。

[OrderedDict([ ('market', 1), ('code', '600519'), ('active1', 2999), ('price', 1518.98), ('last_close', 1505.98), ('open', 1503.0), ('high', 1528.36), ('low', 1503.0), ('servertime', '13:30:00.018'), ('reversed_bytes0', 13300003), ('reversed_bytes1', -151898), ('vol', 27472), ('cur_vol', 38), ('amount', 4162208768.0), ('s_vol', 12340), ('b_vol', 15132), ('reversed_bytes2', 18), ('reversed_bytes3', 379117), ('bid1', 1518.93), ('ask1', 1518.99), ('bid_vol1', 2), ('ask_vol1', 1), ('bid2', 1518.91), ('ask2', 1519.0), ('bid_vol2', 8), ('ask_vol2', 17), ('bid3', 1518.84), ('ask3', 1519.03), ('bid_vol3', 7), ('ask_vol3', 2), ('bid4', 1518.82), ('ask4', 1519.91), ('bid_vol4', 8), ('ask_vol4', 1), ('bid5', 1518.8), ('ask5', 1520.0), ('bid_vol5', 9), ('ask_vol5', 18), ('reversed_bytes4', (1356,)), ('reversed_bytes5', 0), ('reversed_bytes6', 0), ('reversed_bytes7', 0), ('reversed_bytes8', 0), ('reversed_bytes9', -0.13), ('active2', 2999)] )]

量化交易少不了 K 线数据,看看 pytdx 怎么搞定它:

# 获取日 K 线数据k_data = api.get_security_bars(9, 1, '600519', 0, 10)print(k_data)

这里的 9 表示日 K 线,1 代表上交所,'600519' 是股票代码,0, 10 代表从 0 开始获取 10 条数据,最多可获取800根K线。

想获取不同周期的 K 线数据?直接改第一个参数就行:

K线种类0 5分钟K线 1 15分钟K线 2 30分钟K线 3 1小时K线 4 日K线5 周K线6 月K线7 1分钟8 1分钟K线 9 日K线10 季K线11 年K线

返回值解析返回值是一个数组,数组里是OrderedDict格式的数据 为了方便数据计算,可以通过以下方法转换成Dataframe格式

df = api.to_df(k_data)print(df)

返回值如下,这样数据就看的清晰多了注意: 获取的行情数据是不复权的

open close high low vol amount year month day hour minute datetime0 1488.00 1479.07 1499.52 1474.00 34743.0 5.157907e+09 2025 2 24 15 0 2025-02-24 15:001 1470.01 1454.00 1473.39 1452.00 28387.0 4.142814e+09 2025 2 25 15 0 2025-02-25 15:002 1455.45 1460.01 1464.96 1445.00 26366.0 3.835949e+09 2025 2 26 15 0 2025-02-26 15:003 1460.02 1485.56 1489.90 1454.00 49762.0 7.368003e+09 2025 2 27 15 0 2025-02-27 15:004 1485.50 1500.79 1528.38 1482.00 56128.0 8.475738e+09 2025 2 28 15 0 2025-02-28 15:005 1502.60 1487.02 1520.99 1481.50 31595.0 4.736680e+09 2025 3 3 15 0 2025-03-03 15:006 1485.00 1470.11 1486.00 1465.21 25211.0 3.710676e+09 2025 3 4 15 0 2025-03-04 15:007 1472.00 1466.37 1474.00 1460.10 24605.0 3.606932e+09 2025 3 5 15 0 2025-03-05 15:008 1474.00 1505.98 1510.20 1472.08 42167.0 6.297117e+09 2025 3 6 15 0 2025-03-06 15:009 1503.00 1520.36 1528.36 1503.00 31216.0 4.730871e+09 2025 3 7 15 0 2025-03-07 15:00

如果你的策略依赖盘口数据,分笔成交数据是个不错的选择:

# 获取最近 10 条分笔成交数据transaction_data = api.get_transaction_data(1, '600519', 0, 10)print(api.to_df(transaction_data)) time price vol num buyorsell0 14:53 1520.92 9 8 01 14:53 1520.90 5 4 12 14:53 1520.98 6 5 13 14:53 1520.98 9 9 14 14:53 1521.00 4 4 05 14:53 1520.97 8 8 16 14:54 1520.97 19 18 07 14:54 1520.82 29 29 18 14:54 1520.90 18 18 29 14:54 1520.83 19 14 1

用完 API 记得断开连接,不然连接数太多可能会被服务器“拉黑”

api.disconnect

来源:散文随风想

相关推荐