解决方案

残血收割1日线周期,过去每个交易日信号数量的统计

用Python统计了过去历史上,1日线周期下,每个交易日有多少个残血收割信号

目的是为了验证,当一个交易日密集出现多个残血收割信号时,是否可以确认市场已跌至底部

测试结果还算比较满意,基本都能抄到底,

但也有翻车的时候,比如2011/12/16和2001/10/12,

但大部分时候还是赚钱的,下跌了及时止损,亏损应该可以限制在10%以内,但抄到底部,可以赚百分之几十,盈亏比还是挺高的,胜率也高

xM4qNd.png

话说为了把这数据弄出来,可真的不容易啊§34§

我不知道如何导出通达信数据,只能用最傻瓜的方法,在个股的K线图页面,用键盘上的快捷键【3-4-回车-回车-ESC-PAGE DOWN】,当然,导出数千次股票,就得重复数千次,然后我用的是键盘模拟软件

然后遇到了第一个问题,就是导出的股票文件不完整,最后发现,如果焦点在K线图,按PAGE DOWN,就会跳到下一只股票,要是焦点在左侧的股票列表,那么按page down,就会跳到下一屏股票,这导致我漏了许多股票没导出。

好在导出的文件是以股票代码命名的,比如000001.xls,我就先把文件夹里的所有文件的文件里列表导出成TXT,用的命令是DIR /S/B >FILESLIST.TXT,导出来之后,放入EXCEL,然后分列,取得股票代码列表,再把股票代码放入TXT文件,然后在同花顺中导入TXT文件的股票,再在同花顺旗下的问财搜索【沪深上市,不包含自选股】,取得所有缺失的股票的列表,在通达信里加自选板块再导出一遍

然后尝试用Python读取excel文件,但是通达信导出的xls格式的文件Python竟然识别读取不了,又找了方法将xls文件批量转换成xlsx

我的思路是:
先创建一个空的DataFrame数据表,用Python依次读取每份股票文件的内容,然后把读取出来的内容存入前面的DataFrame数据表上,把几千只股票的数据合并成一张数据表,最后用pandas的groupby()计算每个交易日有多少残血收割信号

我先用几份文件试了一下,合并没问题,但是用goupby()进行统计时却出了问题,因为导出的excel文件存在空值或NaN值,用NaN值进行计算时就会报错,然后程序终止,

我自己也是个初学Python的新手,于是在网上找到代码,将pandas数据表中的空值与NaN值全部替换成0,但是不知道什么原因,我在网上找到的代码,会把交易日期那一列也全都替换成0,导致日期数据全部丢失,这样就不能知道每个交易日有多少信号了

我想出的办法是,每次读取Excel文件时,先复制一个备份,等我用网上的代码用0填充所有的空值和NaN值后,再用备份中的日期这一列替换掉需要用来合并的数据表

最后,我认为所有问题都已经解决可以开始搞了,结果发现又出了问题,我之前尝试将几只股票的历史数据合并成一张表时一切正常,但我要将几千只股票合并成一张表,电脑内存完全不够用,因为一个交易日期就是一行数据,一只股票会有几百几千行数据,几千只股票可能得有上千万行数据,电脑内存直接爆了,最后想到的办法是,每次读取Excel文件时,只保留有信号的行,没出信号的行全都忽略

最后一个问题解决后,程序终于顺利运行,导出了我想要的统计信息

使用的代码如下:

import os
import pandas as pd
file_location='C:/py/xlsx'   #读取的文件夹

# file location存储我们要读取的数据的文件夹绝对路径



# for root, dirs, files in os.walk(file_location):
#     # root输出文件夹,dirs输出root下所有的文件夹,files输出root下的所有的文件
#     print('当前文件夹:', root)
#     print('包含的文件夹:', dirs)
#     print('包含的文件:', files)
#     print()

pd.set_option('expand_frame_repr', False)  # 当列太多时显示完整



#批量读取文件名称
file_list=[]



for root,dir,files in os.walk(file_location):
   for filename in files:
        if filename.endswith('.xlsx'):
            file_path=os.path.join(root,filename)   #通过os.path.join()函数,连接当前文件夹路径与文件名,返回给file_path
            #file_path=os.path.abspath(file_path)
            file_list.append(file_path)

print(file_list)



print('------------------遍历文件名,批量导入数据--------------------')
all_data=pd.DataFrame()
#for fp in sorted(file_list):    #sorted()函数可以对包括列表、元组、字符串、字典、集合这些序列进行排序
for fp in sorted(file_list):   #加入切片操作,只读取文件夹中前11个文件
    print(fp)  #打印文件路径与文件名
    #导入数据
    df=pd.read_excel(fp,skiprows=2,parse_dates=['      时间'])

    df = df.drop(labels=0)  #删除索引值为1的行

    df2=df

    # 移除数据表内的空格
    df.replace('\s+', '', regex=True, inplace=True)
    df.fillna(0, inplace=True)
    #
    # # 将空值替换为0
    df = df.replace(r'\s*', 0, regex=True).fillna(0)
    #
    df.replace('\s+', '', regex=True, inplace=True)
    df.fillna(0, inplace=True)

    rename_dict = {'残血收割.DCD   ': '抢人头', '残血收割.CD    ': '发现残血', '      时间':'日期','魔王出击.MWGZ  ': '魔王出击','残血收割.ZCD   ': '复活再杀'}   #

    #   '魔王出击.MWGZ  ': '魔王出击',
   # '残血收割.ZCD   ': '复活再杀',

    df.rename(columns=rename_dict, inplace=True)
    #时间这一列莫名其妙会被删除,于是提前复制一个备份,在最后放回来
    df['交易日期']=df2['      时间']
    df['抢人头与复活再杀']=df['抢人头']+df['复活再杀'] #只要等于1那就说明今天有残血收割信号
    df['信号数量']=df['发现残血']+df['魔王出击']



    #df.fillna(value=0, inplace = True)
    #df=df.fillna(0)

    #df['全残血收割'] = df['抢人头'] + df['复活再杀']

    df = df[df['信号数量'] > 0] #仅保留有信号的行



    #print(df)
    #exit()  #不加上这一一行,会连续读取,加上这一行,读取一个文件就结束for循环
    all_data=all_data.append(df,ignore_index=True)  #合并过多文件会响应过慢

print(all_data)


'''每次导入几千个文件耗时太长,可以将所有的文件合并成一个csv文件'''
#all_data.to_csv('all_data.csv',index=False,encoding='gbk')


'''导出数据为hdf文件格式'''
#all_data.to_hdf('全量通达信数据.hdf',key='all_data',mode='w') #key是数据表的名字,类似于Excel工作簿中的工作表,W模式为覆盖
all_data.to_csv('全量通达信数据.csv',encoding='gbk')

all_data.groupby('交易日期' ,as_index=False)['发现残血','抢人头','复活再杀','魔王出击','抢人头与复活再杀'].sum().to_csv('统计结果.csv',encoding='gbk')
#all_data.groupby('日期' ,as_index=False)['复活再杀'].sum().to_csv('统计结果2.csv',encoding='gbk')

代码VBA,将XLS文件批量转换成XLSX文件

右键Sheet1查看代码,插入模块,在模块中修改xls文件路径,文件路径需要保留最后的/号,然后运行

Sub ConvertToXlsx()
    Dim strPath As String
    Dim strFile As String
    Dim wbk As Workbook
    ' Path must end in trailing backslash
    strPath = "C:\py\xls/"
    strFile = Dir(strPath & "*.xls")
    Do While strFile <> ""
        If Right(strFile, 3) = "xls" Then
            Set wbk = Workbooks.Open(Filename:=strPath & strFile)
            wbk.SaveAs Filename:=strPath & strFile & "x", _
                FileFormat:=xlOpenXMLWorkbook
            wbk.Close SaveChanges:=False
        End If
        strFile = Dir
    Loop
End Sub

发表回复