当前位置: 首页 > news >正文

量化交易backtrader实践(一)_数据获取篇(4)_通达信数据应用

在第2节实践了从金融数据接口包例如tushare.pro或akshare获取数据,在第3节实践了直接从网页上爬取股票数据。其实,我们的电脑上怎么可能没有几个股票软件,在这些股票软件里,历史行情,实时行情都有,我们能否把这么数据提取出来?

那么这一节,我们就实践一下从股票软件通达信获取数据。

我们会分成3个部分来分别实践,

  1. 用python读取二进制.day文件
  2. 用pytdx库读取
  3. 通达信导出数据及处理

01_用python读取二进制.day文件

参考文档:

  • Python量化交易学习笔记(46)通达信日线数据获取_如何读取通达信日线数据-CSDN博客
  • 通达信行情数据获取--python_股票量化交易-获取数据的两种方法-CSDN博客 
  • python 通达信数据_Python读取通达信本地数据-CSDN博客 

001_通达信下载及文档路径

现在通达信免费版,盘后数据下载在右上角“选项”中,点击进入选择日期跨度开始下载,这个下载速度不会很快,8000多支股票/指数数据大概需要6~7分钟,下载要有点耐心。

数据下载后,根据上面参考文档1的说明,这些数据保存在"通达信安装路径\vipdoc\"下,于是我们可以直接问AI: 请帮我解析一下通达信vipdoc文件夹下的路径文件内容

通达信的vipdoc文件夹下存放的是股票市场的历史数据文件,这些文件通常按照市场、股票代码、文件类型等方式组织。例如,sh000001.day 文件就是上证指数的日线数据文件。

通达信的数据文件格式通常是二进制格式,而不是文本格式。

于是我们可以进入vipdoc文件夹,它里面有6个子夹,其中shsz就是上证和深证,再下一层的lday文件夹下就是xxx.day文件了,到这里我们下载了数据并知道数据保存的路径,下一步打开文件进行数据解析。

002_二进制文件打开与解析

A_python读取二进制文件基础

在Python中读取二进制文件(如图像、音频文件等)可以使用内置的open()函数,并指定模式为'rb'(读取二进制文件)。

with open('example.bin', 'rb') as f:data = f.read()  # 读取整个文件# 或者使用 f.read(n) 来读取 n 字节# 或者逐行读取: for line in f:

要解析几个字节并将其解释为数字,你需要根据这几个字节代表的数据类型以及它们的字节序(endianness)来处理。在Python中,你可以使用struct模块来帮助进行这种转换。

在Python的struct模块中,不同的字母代表不同的二进制格式。以下是常用的一些格式字符及其含义:

  • I: 无符号整型(unsigned integer),4个字节。
  • i: 带符号整型(signed integer),4个字节。
  • f: 单精度浮点数(single-precision float),4个字节。
  • h: 短整型(short),2个字节。
  • H: 无符号短整型(unsigned short),2个字节。
  • b: 字节(byte),1个字节。
  • B: 无符号字节(unsigned byte),1个字节。
  • l: 长整型(long),4个字节(在某些平台上可能是8个字节)。
  • L: 无符号长整型(unsigned long),4个字节(在某些平台上可能是8个字节)。
  • q: 长长整型(long long),8个字节。
  • Q: 无符号长长整型(unsigned long long),8个字节。
  • d: 双精度浮点数(double),8个字节。

示例代码:

import structbinary_data = b'\x00\x00\x00\x01\x00\x00\x80\x00\x00'  # 示例二进制数据# 解析一个4字节的无符号整数
unsigned_int = struct.unpack('>I', binary_data[:4])[0]   # >表示大端字节序
print(unsigned_int)  # 输出 1int2 = struct.unpack('II', binary_data[:8])  # 默认小端字节序
print(int2)int3 = struct.unpack('<II',binary_data[:8])   # <表示小端字节序
print(int3)----------------------
1
(16777216, 8388608)
(16777216, 8388608)

B_读取通达信.day文件

复习了python读取二进制文件基础后,我们就可以自己动手来解析一下.day文件了。首先,我们可以用文本编辑器查看一下sh000001.day的十六进制数据:

76 7A 33 01 B0 9E 04 00  D8 DF 04 00 55 9B 04 00
71 D2 04 00 CE 18 C5 52  29 F2 1D 1A 1C 01 10 03
7B 7A 33 01 3A CE 04 00  DE E8 04 00 C6 AD 04 00
4A B3 04 00 6D F3 8C 52  92 BE AB 11 EB 02 3F 01
7C 7A 33 01 24 A9 04 00  1F D8 04 00 38 98 04 00
75 D6 04 00 23 C9 75 52  A9 54 39 0F 00 04 38 00
7D 7A 33 01 2F DB 04 00  2A F8 04 00 9A D4 04 00
D5 F2 04 00 6A 50 C0 52  EA 0C 5F 16 0D 04 2F 00
7E 7A 33 01 4F DE 04 00  E8 F2 04 00 C2 D9 04 00
2D E1 04 00 D9 80 8B 52  BF A4 49 10 C0 00 78 03
7F 7A 33 01 E4 DD 04 00  48 EB 04 00 B9 D3 04 00
17 E2 04 00 F0 68 6B 52  FE 7A 62 0D BC 02 6E 01

将最前面的4个字节进行十六进制转十进制,按照默认的小端字节序则可以得到十进制数20150902,这个数除以1000得到年份2015,其他处理可以得到9月和2日。

d1 = 0x767A3301  # 大端字节序
d2 = 0x01337A76  # 小端字节序
d1,d2--------------------
(1987719937, 20150902)

由于这组数据取出来,后续也是要做成backtrader需要的datetime类型的index,所以这里就不去处理年,月,日,而是直接用转成datetime类型

from datetime import datetime
d2_str = str(d2)
date0 = datetime.strptime(d2_str, "%Y%m%d")
date0-----------------
datetime.datetime(2015, 9, 2, 0, 0)

按照参数文档1的说明:

day文件中,每32个字节存储了一根日线数据,各字节存储数据如下:

00 ~ 03 字节:年月日, 整型
04 ~ 07 字节:开盘价*100,整型
08 ~ 11 字节:最高价*100,整型
12 ~ 15 字节:最低价*100,整型
16 ~ 19 字节:收盘价*100,整型
20 ~ 23 字节:成交额(元),float型
24 ~ 27 字节:成交量(股),整型
28 ~ 31 字节:(保留)

每32个字节存储了一根日线数据,结构是("IIIIIfII"),于是可以用struct直接进行解析。日期我们还是直接转为datetime类型,开、高、收、低需要除以100,成交额换算成"亿元",成交量不动,保留字节直接去掉不用。

fname = 'TDX_data/sh000001.day'
with open(fname, 'rb') as f:buf = f.read()            # 读取全部字节buf_size = len(buf)           # 总字节数
icnt=int(buf_size/32)         # 数据组计数
list1 = []                    # 最终list保存解析后的数据for i in range(icnt):out1=[]a = struct.unpack('IIIIIfII',buf[i*32:(i+1)*32])date0 = dt.datetime.strptime(str(a[0]), "%Y%m%d")open1 = a[1]/100.0high2 = a[2]/100.0low3 = a[3]/100.0close4 = a[4]/100.0amount5 = a[5]/100000000.0volume6 = a[6]out1 = [date0,open1,high2,low3,close4,amount5,volume6]list1.append(out1)list1[:2]   # 显示前面2组数据---------------------------
[[datetime.datetime(2015, 9, 2, 0, 0),3027.68,3194.48,3019.09,3160.17,4232.62355456,438170153],[datetime.datetime(2015, 9, 7, 0, 0),3149.38,3217.58,3066.3,3080.42,3026.89714176,296468114]]

接着简单做成DataFrame类型的数据就可以了,下面的数据可以直接保存到.csv文件,也可以先做成backtrader接受的格式再保存,其中成交额并不是backtrader的FeedData的必须列,可以不要。

import pandas as pdcols = ['date','open','high','low','close','amount(亿)','volume']
df = pd.DataFrame(list1,columns=cols)
df--------------------------date	    open	high	low	    close	amount(亿)	volume
0	    2015-09-02	3027.68	3194.48	3019.09	3160.17	4232.623555	438170153
1	    2015-09-07	3149.38	3217.58	3066.30	3080.42	3026.897142	296468114
2	    2015-09-08	3054.44	3174.71	3011.12	3170.45	2639.103754	255415465
3	    2015-09-09	3182.55	3256.74	3165.70	3243.09	4129.914225	375327978
4	    2015-09-10	3190.55	3243.28	3178.90	3197.89	2995.810796	273261759
...	...	...	...	...	...	...	...
2174	2024-08-14	2866.24	2866.24	2850.40	2850.65	2074.575503	217885170
2175	2024-08-15	2844.20	2889.09	2839.39	2877.36	2549.871084	271900000
2176	2024-08-16	2877.94	2888.68	2873.06	2879.43	2436.082729	263653441
2177	2024-08-19	2877.95	2905.15	2877.77	2893.67	2429.948887	261687730
2178	2024-08-20	2895.55	2896.52	2855.33	2866.66	2373.078057	263658002
2179 rows × 7 columns

C_通达信数据的问题

由上步骤,我们从通达信的.day文件经过处理获取到股票的历史行情数据,可以送到backtrader中进行回测了。但是不要过于乐观了,我们得到的数据有一部分跟前面金融接口包得到的其实不一样。

我们先看上证指数,2015年9月2日的开盘价是3027.68,然后进入到通达信软件中去,找到这一根K线的数据,并截图出来,我们看到数据是一一对应的,没有问题。

fname = 'TDX_data/sh000001.day'with open(fname, 'rb') as f:buf = f.read(32)        # 只读取一根K线a = struct.unpack('IIIIIfII',buf)
a----------------------
(20150902, 302768, 319448, 301909, 316017, 423262355456.0, 438170153, 51380508)

然后,随机选择一支股票,顺口的代码 600600

fname2 = 'TDX_data/sh600600.day'
with open(fname2, 'rb') as f:buf = f.read(32)      a = struct.unpack('IIIIIfII',buf)
a-----------------------
(20150902, 3250, 3419, 3210, 3408, 342315360.0, 10166265, 65536)

我们在通达信软件里面打开K线图并找到它对应的那根K线(20150902),但是截图显示其开盘价为:24.66(不是32.50),包括高、低、收都与解析出来的数值不对应,但有趣的是成交额成交量又是对上了的。

这时候,我们在股票软件中点击右上第二行的"复权",再选择不复权,得到的开盘价就是32.50能对应上了。见下图,左边是前复权的数据,右边是不复权的数据。

这让我想起好多年前在某软件里玩的模拟盘,有一次我重仓模拟买了一支股票,然后它除权10送10,于是第二天我的模拟盘里面,股票数量没变,股票价格变成只有原来的一半,总金额也变成原来一半,我的账户瞬间亏损,本来模拟玩得开开心心的,这么一来就不想玩了。

话说回来,如果是不复权的数据,那么数据里就可能会有断层,把它放到backtrader里去回测,就会出现各种奇异的结果,这也是为什么前面我们用akshare获取数据的时候参数里要选择"qfq"前复权的原因了。

003_通达信.day数据读取小结

  • 我们用python读取二进制的方式读取.day文件
  • 使用struct库对数据进行解析
  • 通达信.day文件32字节一根K线,能解析出日期,开、高、低、收,成交量和成交额
  • 通过简单处理换算可以制作成DataFrame格式,以便于输出给backtrader
  • 但.day文件记录的是不复权的数据,直接用于backtrader会产生未知问题,不建议使用

02_使用pytdx库

参考文档:

  • python 读取 通达信 数据 pytdx_python读取通达信本地数据-CSDN博客
  • [Python]调用pytdx的代码示例_pytdx调用-CSDN博客
  •  扩展行情 pytdx.exhq · pytdx (gitbooks.io)

首先,惯例咨询AI: 请简要介绍一下pytdx库的功能

pytdx 是一个Python库,用于从通达信(Tdx)平台获取中国股市的数据。通达信是一家为中国证券市场提供交易软件和服务的公司,其提供的数据接口被广泛应用于证券公司的交易终端中。pytdx 库使得开发者能够绕过图形用户界面直接通过Python代码访问这些数据,从而进行自动化数据分析或交易策略开发等应用。

主要功能包括但不限于:

  • 获取股票的基本信息,如股票代码、名称等。
  • 获取实时行情数据,包括股票价格、成交量、涨跌幅等。
  • 查询历史交易数据,包括日线、周线、月线级别的K线图数据。
  • 获取指数信息以及相关指数成分股的信息。
  • 支持多种市场类型,包括A股、B股、基金、债券等。
  • 提供了对数据的解析功能,便于进一步处理和分析。

然后,到它的网页上看一下:  扩展行情 pytdx.exhq · pytdx (gitbooks.io)

从接口API的列表中,我们可以清楚了解pytdx库的主要功能,比如说还有交易相关的pytdx.trade等。而对我们目前而言,只需要实践标准行情以及数据文件读取二个部分就可以了。

001_pytdx.reader数据文件读取

学习一个库,还是要去看源码,我们可以在IDE里 From pytdx import reader,Ctrl+点击reader就能跳转到reader/__init__.py文件,这里的代码内容并不多:

from pytdx.reader.daily_bar_reader import TdxDailyBarReader, TdxFileNotFoundException, TdxNotAssignVipdocPathException
from pytdx.reader.min_bar_reader import TdxMinBarReader
from pytdx.reader.lc_min_bar_reader import TdxLCMinBarReader
from pytdx.reader.exhq_daily_bar_reader import TdxExHqDailyBarReader
from pytdx.reader.gbbq_reader import GbbqReader
from pytdx.reader.block_reader import BlockReader
from pytdx.reader.block_reader import CustomerBlockReader
from pytdx.reader.history_financial_reader import HistoryFinancialReader__all__ = ['TdxDailyBarReader','TdxFileNotFoundException','TdxNotAssignVipdocPathException','TdxMinBarReader','TdxLCMinBarReader','TdxExHqDailyBarReader','GbbqReader','BlockReader','CustomerBlockReader','HistoryFinancialReader'
]

我们把它们直接送到AI进行解析:

这段代码主要涉及从pytdx.reader模块导入多个类,用于处理和读取不同的股票市场数据pytdx是一个开源的Python库,用于从通达信(一个中国流行的股票交易平台)获取历史和实时的股票数据。以下是每个导入类的简要解析:

  1. TdxDailyBarReader: 用于读取每日股票数据(开盘价、最高价、最低价、收盘价、成交量等)。
  2. TdxFileNotFoundException: 当试图读取的文件不存在时抛出的异常。
  3. TdxNotAssignVipdocPathException: 当未指定VIP文件路径时抛出的异常,通常与数据文件的路径配置相关。
  4. TdxMinBarReader: 用于读取分钟级别的股票数据。
  5. TdxLCMinBarReader: 用于读取分钟级别的股票数据,可能与TdxMinBarReader有细微的差别,具体取决于数据格式或来源。
  6. TdxExHqDailyBarReader: 用于读取扩展的每日股票数据,可能包括更详细的市场信息。
  7. GbbqReader: 用于读取股票的分时数据,如分笔成交数据。
  8. BlockReader: 用于读取股票板块数据,即一组相关股票的集合。
  9. CustomerBlockReader: 可能用于读取自定义的股票板块数据,允许用户定义自己的股票集合。
  10. HistoryFinancialReader: 用于读取股票的财务历史数据,如收入、利润等。

根据解析的内容,我们把重点放在1和8上面,即读取每日股票数据和读取板块数据。前面使用python读取二进制.day文件,我们实践了自己通过编写代码将.day的二进制文件转成DataFrame格式的数据,而在pytdx里,封装了TdxDailyBarReader类可以更方便直接的使用:

from pytdx.reader import TdxDailyBarReader, TdxFileNotFoundExceptionfname = 'TDX_data/sh000001.day'
reader = TdxDailyBarReader()
df = reader.get_df(fname)
df--------------------------------open	high	low	    close	amount	    volume
date						
2015-09-02	3027.68	3194.48	3019.09	3160.17	4.232624e+11	438170153.0
2015-09-07	3149.38	3217.58	3066.30	3080.42	3.026897e+11	296468114.0
2015-09-08	3054.44	3174.71	3011.12	3170.45	2.639104e+11	255415465.0
2015-09-09	3182.55	3256.74	3165.70	3243.09	4.129914e+11	375327978.0
2015-09-10	3190.55	3243.28	3178.90	3197.89	2.995811e+11	273261759.0
...	...	...	...	...	...	...
2024-08-14	2866.24	2866.24	2850.40	2850.65	2.074576e+11	217885170.0
2024-08-15	2844.20	2889.09	2839.39	2877.36	2.549871e+11	271900000.0
2024-08-16	2877.94	2888.68	2873.06	2879.43	2.436083e+11	263653441.0
2024-08-19	2877.95	2905.15	2877.77	2893.67	2.429949e+11	261687730.0
2024-08-20	2895.55	2896.52	2855.33	2866.66	2.373078e+11	263658002.0
2179 rows × 6 columns

我们看到它与前面自己写的代码读取二进制.day文件的结果几乎没有什么不同。不过可以到源码中去对比一下以发现自己的不足和别人代码的优点。

接着,我们继续实践8-板块文件读取,那么这些文件在/T002/hq_cache/下面,其实板块的文件并不多,主要就是3个,我们从源码的测试代码上只看到block_zs.dat这一个。这个文件夹下面还有很多的.dat文件,但注意是不能用blockReader来读取的,它们的格式并不相同。

fname3 = 'TDX_data/block_zs.dat'  # 综合指数
fname4 = 'TDX_data/block_fg.dat'  # 风格
fname5 = 'TDX_data/block_gn.dat'  # 概念
from pytdx.reader import BlockReaderdf = BlockReader().get_df(fname5)
df--------------------------------blockname	block_type	code_index	code
0	    通达信88    	2	0	000100
1	    通达信88	    2	1	000568
2	    通达信88	    2	2	000625
3	    通达信88	    2	3	000631
4	    通达信88	    2	4	000708
...	...	...	...	...
29711	AI眼镜	    2	72	688521
29712	AI眼镜	    2	73	688525
29713	AI眼镜	    2	74	688601
29714	AI眼镜	    2	75	688608
29715	AI眼镜	    2	76	873001
29716 rows × 4 columns

002_pytdx.hq行情

hq- 即行情的拼音首字母缩写。先看官方文档:

标准行情 pytdx.hq · pytdx (gitbooks.io)

我们需要先引入,再创建对象,然后在with语句里面,使用to_df()获取DataFrame的数据......另外参数的说明也列在了代码下面对应的位置,比如第1个参数是K线的周期是分钟还是日K等,有趣的是值为4的说明是日K线,而9的说明也是日K线,试了一下还的确都是,那为啥要2次日K线?

from pytdx.hq import TdxHq_API
api = TdxHq_API()
with api.connect('119.147.212.81', 7709):data = api.to_df(api.get_security_bars(9, 0, '000001', 2, 10)) # 返回DataFrame# K线:1 15分钟 2 30分钟 3 1小时 4 日K线 5 周K线 6 月K线  9 日K线 10 季K线 11 年K线# 市场:0深圳,1上海# 指定开始位置 0-今天, 1-昨天, 2-前天开始# 几条记录 10-10条记录,最多800data-----------------------------open	close	high	low	vol	amount	year	month	day	hour	minute	datetime
0	10.31	10.13	10.38	10.11	1197676.0	1.221351e+09	2024	8	29	15	0	2024-08-29 15:00
1	10.11	10.16	10.26	10.11	1294059.0	1.318859e+09	2024	8	30	15	0	2024-08-30 15:00
2	10.12	10.11	10.21	10.09	968835.0	9.838988e+08	2024	9	2	15	0	2024-09-02 15:00
3	10.11	10.08	10.13	10.00	916581.0	9.208847e+08	2024	9	3	15	0	2024-09-03 15:00
4	10.05	10.02	10.15	10.00	847992.0	8.522246e+08	2024	9	4	15	0	2024-09-04 15:00
5	10.03	10.07	10.08	9.98	594208.0	5.958458e+08	2024	9	5	15	0	2024-09-05 15:00
6	10.06	10.08	10.21	10.05	878865.0	8.915078e+08	2024	9	6	15	0	2024-09-06 15:00
7	10.05	9.85	10.07	9.84	1639174.0	1.624858e+09	2024	9	9	15	0	2024-09-09 15:00
8	9.86	9.90	9.92	9.78	767901.0	7.561247e+08	2024	9	10	15	0	2024-09-10 15:00
9	9.88	9.65	9.88	9.63	1108727.0	1.078602e+09	2024	9	11	15	0	2024-09-11 15:00

在这里,有必要使用with api.conect()来建立连接,然后数据的获取需要在建立连接的基础上进行。除些之外,其他的看起来和使用akshare获取也没有太多的差别。

还是要着重说一下,关于前复权和不复权的问题,pytdx官网上有通过同花顺的爬虫获取前后复权的数据,这么看的话,本身可能还是存在这个问题的,在这样的情况下,我们还是不建议读取.day文件以及用pytdx请求历史行情数据,在第2节的tushare.pro或akshare就已经能够实现了。

003_Mootdx

参考:批量下载 - MOOTDX

这个也是从pytdx的参考文档1中无意间发现的,跳到它的官网看说明:

Mootdx 是一款纯 Python 语言开发的类似 TDX 的行情数据接口的实现。

  • 在线文档: https://www.mootdx.com
  • 国内镜像: mootdx: 通达信数据读取 pytdx 的一个简便使用封装

项目特点

  • 基于 pytdx 二次封装。

简单看了一下,这个是基于pytdx的二次封装,好像是会把读取.day文件等变得更简单一些,以及行情数据请求更清晰,如果有兴趣,不妨实践一下,这里我们就跳过了。

03_通达信导出数据的处理

终于来到通达信导出数据这一部分。

001_TDX数据导出

我在网上搜索了很多次,没有看到有文章写这方面的内容,大概是用通达信的高手往往精于通达信的指标都是十几年以上的老股民,而做量化交易的往往直接在量化交易的软件上做,两者搭配起来的比较少的缘故吧,不过这只是自己的瞎猜而已。

通达信软件在选项菜单里有个“数据导出”项,这条指令在不同的页面上会导出不同的数据,比如

  • 在自选股页面上导出的就是自选股,
  • 在股票日K线页面上导出的就是日K线数据,
  • 如果在15分钟页面上导出的就是15分钟的K线数据。

002_导出数据示例

我们来看一下数据导出的一些示例,之前的章节里讲过做自选股列表,那个时候还需要制作全股票列表,以及把中文名称制作成拼音的首字母缩写等等,这样才能用不同方式获取到需要的股票。而这些做法其实都是在借鉴股票软件的已有功能,我们在股票软件里可以非常轻松的做很多个自选股页(自定义板块),比如用某个选股指标(假设KDJ)选出的50支股票,马上可以放进自定义板块中,然后数据导出来进行简单处理,就变成了backtrader的需要回测的自选股列表,我们就可以非常有针对的进行回测,也能够大大提高数据分析的效率。

自选股列表

以一个简洁自选股(自定义板块)为例,在通达信里显示是这样的:

导出成xls文件显示:

我们在用pandas读取excel文件遇到了连续的问题,包括没有设置engine,以及格式不正确等:

ValueError: Excel file format cannot be determined, you must specify an engine manually.
XLRDError: Unsupported format, or corrupt file: Expected BOF record; found b'\xb4\xfa\xc2\xeb\t\xc3\xfb\xb3'

在这里我们先投个降,改数据导出为.txt文件,以便于进行数据的读取和处理。然后一上来会读取报错:UnicodeDecodeError 。

fname_list2 = "C:/new_tdx/T0002/export/简洁自选股20240913.txt"import pandas as pd
df_s_list = pd.read_table(fname_list2)df_s_list---------------------
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb4 in position 0: invalid start byte

这是一个典型的错误,中文版的WIN11默认编码是GBK,这个.txt文件中含有大量的中文字符,而python的默认编码是UTF-8,因此出现了 ''utf-8' codec can't decode的问题,针对这个问题,加上encoding='GBK‘ 就能解决了。

import pandas as pd
df_s_list = pd.read_table(fname_list2,encoding='GBK')df_s_list.iloc[:,:6]------------------------------代码	名称(15)	涨幅%	现价	涨跌	买价
0	601168	西部矿业	0.21	14.300	0.030	14.300
1	300058	蓝色光标	-1.87	5.250	-0.100	5.250
2	000921	海信家电	-2.43	24.450	-0.610	24.450
3	601086	国芳集团	-2.19	3.570	-0.080	3.570
4	600794	保税科技	1.03	2.930	0.030	2.910
5	002516	旷达科技	0.52	3.860	0.020	3.860
6	300697	电工合金	-1.49	9.270	-0.140	9.270
7	159633	中证1000指数ETF	-1.15	1.809	-0.021	1.809
8	515220	煤炭ETF	-0.88	1.017	-0.009	1.017
9	560080	中药ETF	-0.97	0.916	-0.009	0.915
10	159967	创业板成长ETF	1.13	0.358	0.004	0.357
11	513660	恒生ETF	0.63	2.083	0.013	2.082
12	601058	赛轮轮胎	-1.45	13.610	-0.200	13.610
13	512880	证券ETF	0.25	0.805	0.002	0.804
14	512690	酒ETF	-2.39	0.490	-0.012	0.489
15	数据来源:通达信	NaN	NaN	NaN	NaN	NaN

这里是索引15出现了问题,看上面的xls文件输出,因为最后一行是“数据来源:通达信”而不是有效数据,因此这个数据还要去除最后一行。而如果我们在一个UI程序里(比如wxPython),只需要少添加一行数据就可以了。


name_list = list(df_s_list.iloc[:,1])
for item in name_list[:-1]:self.m_checkList1.Append(item)

这样,我们就能在backtrader回测窗口程序里,得到自选股列表,还可以用fileopenbox点击更换另外一个从通达信里导出的自定义板块文件,实现多个自选股列表的切换,而在对需要的股票进行回测,只需要勾选上就行。

于是我们就让通达信和backtrader回测进行了第一次比较深度的结合运用,不用为回测哪些股票,以及这些股票我当时为什么挑它们而发愁了,默认自选股就是我关注的股票/ETF,而自定义板块出来的,就是当时根据某指标/策略选到的,如果我再把导出时的文件名以某指标/策略命名加上日期,这就是比较不错的资料管理系统的雏形。

日K线数据处理

日K线需要进入K线图,如下图,窗口上所有的曲线都会以数据的形式导出,

比如这张图上添加了主图指标TDXWAVE,副图上只有一个CCI指标,导出的数据就会成为这样:0-时间,1-开,2-高,3-低,4-收,5-成交量(默认数据没有在图上显示),以及自己在通达信页面上添加的6-TDXWAVE指标和7-CCI指标。

简单说明一下,这里把窗口设成了2个,左下角"窗口"可以选择显示1-12个窗口,那么显示出来的窗口里的指标,是会都导出到文件里的。

这个文件我们也可以很轻松处理为backtrader接受的格式,甚至在excel里手动制作成.csv的文件就能让backtrader程序成功读取并完成回测,以下是函数的代码需求:

  • pandas读取时需要跳过第一行,且第二行是标题
  • 仍要注意最后一行是“数据来源:通达信”的说明,需要去除
  • index是日期,需要转为datetime类型
  • 标题是中文,需要改为英文
  • 成交量是股数,一般都会除以100得到交易的“手”数
fname_kline = 'C:/new_tdx/T0002/export/515220.txt'
dfout = TDX_data_to_feed(fname_kline)
dfout---------------------------------open	high	low    	close	volume	openinterest
trade_date						
2022-12-23	1.035	1.044	1.026	1.043	78252704.0	0
2022-12-26	1.038	1.049	1.036	1.049	64240300.0	0
2022-12-27	1.056	1.070	1.053	1.070	79422496.0	0
2022-12-28	1.063	1.072	1.057	1.062	67954600.0	0
2022-12-29	1.057	1.057	1.035	1.038	88724304.0	0
...	...	...	...	...	...	...
2024-09-09	1.054	1.054	1.023	1.031	106600896.0	0
2024-09-10	1.028	1.043	1.022	1.031	98271800.0	0
2024-09-11	1.013	1.025	1.004	1.016	116725800.0	0
2024-09-12	1.018	1.033	1.017	1.026	120319984.0	0
2024-09-13	1.027	1.034	1.016	1.017	109814400.0	0
420 rows × 6 columns

这里补充一下关于复权的问题,用“数据导出”得到的数据可以是不复权的,也可以是前复权甚至后复权的,这完全取决于你的通达信当前页面上"复权"选择的选项,而不会像.day文件那样一定是不复权的数据。所以这种方式会让你得到更有自由度的数据。

另外,通达信的一些特有指标是加密的,你要在backtrader里做出这些指标是非常有挑战的,但通过"数据导出",这些指标的值都是能获取的(例如上面的TDXWAVE和CCI),这样我们就不需要在backtrader里再编写那些通达信里已有的指标公式。在后续的章节里我们再来详细的进行实践。

04_小结

backtrader进行回测的数据也可以从通达信这类股票软件中获取,本节先实践了在通达信里完成"盘后数据下载"后,用python读取二进制的方式得到日K线数据;然后使用pytdx库的reader类对通达信下载的各种数据文件进行读取。最后介绍了一种非常容易完成的操作即"数据导出"来获得backtrader回测所需要的日K线数据的方法,使backtrader能与通达信深度结合运用。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【吉利汽车安全应急响应中心-登录/注册安全分析报告-无验证方式导致安全隐患】
  • 探索端智能,加速大模型应用,火山引擎边缘智能 x 扣子技术沙龙等你来
  • MYSQL数据库——InnoDB存储引擎
  • Typescript 的类型断言
  • git编译安装报错
  • 设计模式篇--抽象工厂模式
  • 基于云计算的虚拟电厂负荷预测
  • Vscode python无法转到函数定义
  • 23种设计模式详解
  • [vue] vue-seamless-scroll 滚动到第二遍的时候不能进行点击的问题
  • 如何删除git提交记录
  • js读取文件,生成随机题目,多项选择题则提供随机答案供选择
  • 两段有趣的代码(C语言函数指针)
  • 在C++中,如何避免出现Bug?
  • Mini-Omni 语言模型在流式传输中边思考边听说应用
  • [LeetCode] Wiggle Sort
  • 【笔记】你不知道的JS读书笔记——Promise
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • CentOS从零开始部署Nodejs项目
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • download使用浅析
  • js算法-归并排序(merge_sort)
  • nodejs实现webservice问题总结
  • sessionStorage和localStorage
  • v-if和v-for连用出现的问题
  • 百度小程序遇到的问题
  • 编写符合Python风格的对象
  • 前端存储 - localStorage
  • 一道面试题引发的“血案”
  • 用 Swift 编写面向协议的视图
  • 再次简单明了总结flex布局,一看就懂...
  • 最近的计划
  • ionic入门之数据绑定显示-1
  • Java总结 - String - 这篇请使劲喷我
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​Spring Boot 分片上传文件
  • ​如何在iOS手机上查看应用日志
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • (09)Hive——CTE 公共表达式
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (回溯) LeetCode 40. 组合总和II
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (一)Dubbo快速入门、介绍、使用
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .NET 分布式技术比较
  • .NET 回调、接口回调、 委托