Python自学第5周反馈:python做多元回归分析,预测某支股票未来的最高最低价

python做多元回归分析,预测某支股票未来的最高最低价

上一次简单的做了大盘股指的移动平滑预测,但在实际中,变化时受到多种因素影响的
所以这次基于上次的基础,用python来进行股票价格的多元线性预测

那么先明确一下预测的目的,得到某支股票的拟合模型,用来预测它在第二天或者未来的最低价(抄底),最高价(脱手)。
不专业的简单分析下多元有那些元
1.大概会跟昨天的振幅和涨跌幅有关,毕竟如果看到昨天在跌可能就会犹豫买入
2.跟昨天的价格有关,可能资金有限,操作的时候股票的价格会影响买入态度
3.跟昨天的成交量有关,可能昨天成交了特别多导致今天有人跟风
4.跟节假日休市时间有关,可能之前放假回来后出现上扬,或者接下来准备休市三天小长假很多人开始割肉收回款项
5.另外,肯定也跟大盘的变化公司的市值行业的景气情况等等有关,但是考虑到数据的来源复杂性,就不纳入本次学习的研究范围。

下面的内容代码部分可以跳过阅读,在最后附上所有的代码

一、 获取下数据:

#1.get请求
shuju = requests.get(URL)                                                  #用requests模块请求网页
#整理得到的数据
liebiao_1= re.split(r'\[',shuju.content.decode('utf-8'))[-1]               #把字符串按方括号[切割取后面部分
liebiao_2 = re.split(r']',liebiao_1)[0]                                    #把字符串按方括号]切割取前面部分
liebiao_3 = re.split(r'","|"',liebiao_2)                                   #把字符串按引号和逗号切割
liebiao = []                                                               #建立一个空列表
for x in liebiao_3:                                                        #遍历原先切割字符串等得到的列表
    if x != '':                                                            #剔除空集
        liebiao.append(x)                                                  #放回空列表

Shuangxiang = {}
#"日期,开盘,收盘,最高,最低,成交量,成交额,振幅,不知道是啥"
#有:T_1(前面有没有放假),T_2(后面有没有放假),Zkai,Zshou,Zmax,Zmin,Zdeal,ZE,Zfu,ZX,Zcha=(Zshou-Zkai)/Zkai,,F容错
for i in range(0,len(liebiao)):                                            #遍历数据的行数
    Shuangxiang['第'+str(i+1)+'行'] = {}                                         #生成行字典
    i_biao = re.split(r',',liebiao[i])                                     #对数据按逗号再切割
    for k in range(0,len(i_biao)):                                         #遍历切割好的数据到行列表下的列键
        if k+1 ==1:
            Shuangxiang['第' + str(i + 1) + '行']['第' + str(k + 1) + '列'] = day_num(i_biao[k])
        else:
            if '%' in i_biao[k]:
                m = float(re.split(r'%', i_biao[k])[0])/100
                Shuangxiang['第' + str(i + 1) + '行']['第' + str(k + 1) + '列'] = m
            else:
                if i_biao[k] == '-':
                    m = float(0)
                    Shuangxiang['第' + str(i + 1) + '行']['第' + str(k + 1) + '列'] = m
                else:
                    Shuangxiang['第' + str(i + 1) + '行']['第' + str(k + 1) + '列'] = float(i_biao[k])

通过类似上一次的操作,我们能够得到N组这样的数据:

日期 开盘 收盘 最高 最低 成交量 成交额 振幅 不知道是啥
2019-09-20 23.05 23.44 23.67 22.73 8795 20393557 4.1% 0.49

当然,实际上在代码中已经处理了几个数据:
1. 振幅是带有百分号的字符串所以重新去掉百分号转换成浮点数据
2. 有时存在数据缺失,比如刚刚上市的时候,系统获取的数据时-号,用0替换掉
3. 日期的显示通过一个day_num()函数转化为了日序数,便于计算上一次交易和下一次交易的时间间隔,day_num()函数:

#用于识别2019-09-20类型日期,便于计算两组数据之间的时间间隔
def day_num(y_m_d):
    import time
    daynum = time.mktime(time.strptime(y_m_d,"%Y-%m-%d"))/int(86400)
    return daynum

二、 对数据进行处理
我们需要用于多元分析的数据应为:

第1列 第2列 第3列 第4列 第5列 第6列 第7列 第8列 第9列 第10列 第11列 第12列 第13列 第14列
日期 开盘 收盘 最高 最低 成交量 成交额 振幅 不知是啥 已休市 预备休市 涨跌幅 次日最低价 次日最高价
日期 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 Y1 Y2

得到的两个模型应该为:
AX1+BX2+CX3+DX4+EX5+FX6+GX7+HX8+IX9+JX10+KX11+F容错=Y1次日最低价
aX1+ bX2+ cX3+dX4+ eX5+fX6+ gX7+ hX8+ iX9+jX10+ kX11+ f容错=Y2次日最高价

# 第10列为向前减天数(已放假)
for i in list(range(1,len(Shuangxiang)+1)):
    if i == 1:
        Shuangxiang['第' + str(i) + '行']['第' + str(10) + '列'] = 0
    else:
        Shuangxiang['第'+str(i)+'行']['第'+str(10)+'列'] = Shuangxiang['第'+str(i)+'行']['第'+str(1)+'列']-Shuangxiang['第'+str(i-1)+'行']['第'+str(1)+'列']-1
# 第11列为向后减天数(预备放假)
for i in list(range(1,len(Shuangxiang)+1)):
    if i == len(Shuangxiang):
        day_last = Shuangxiang['第'+str(i)+'行']['第'+str(1)+'列']*86400
        import time
        Week = int(time.strftime("%w", time.localtime(day_last)))
        if Week == 5:
            Shuangxiang['第' + str(i) + '行']['第' + str(11) + '列'] = float(2)
        else:
            Shuangxiang['第' + str(i) + '行']['第' + str(11) + '列'] = float(0)
    else:
        Shuangxiang['第'+str(i)+'行']['第'+str(11)+'列'] = Shuangxiang['第'+str(i+1)+'行']['第'+str(1)+'列']-Shuangxiang['第'+str(i)+'行']['第'+str(1)+'列']-1
# 第12列为涨跌幅(Zshou-Zkai)/Zkai,收在第三列,开在第二列
for i in list(range(1,len(Shuangxiang)+1)):
    Shuangxiang['第'+str(i)+'行']['第'+str(12)+'列'] = (Shuangxiang['第'+str(i)+'行']['第'+str(3)+'列']-Shuangxiang['第'+str(i)+'行']['第'+str(2)+'列'])/Shuangxiang['第'+str(i)+'行']['第'+str(2)+'列']
# 第13列为后一天的最低价,第14列为后一天的最高价,及用前一天的所有数据求出与后一天这两个值的系数关系
for i in list(range(1,len(Shuangxiang)+1)):
    if i == len(Shuangxiang):
        Shuangxiang['第' + str(i) + '行']['第' + str(13) + '列'] = 0
        Shuangxiang['第' + str(i) + '行']['第' + str(14) + '列'] = 0
    else:
        Shuangxiang['第'+str(i)+'行']['第'+str(13)+'列'] = Shuangxiang['第'+str(i+1)+'行']['第'+str(5)+'列']
        Shuangxiang['第'+str(i)+'行']['第'+str(14)+'列'] = Shuangxiang['第'+str(i+1)+'行']['第'+str(4)+'列']

三、 对数据进行计算
这里主要用了一个第三方库
介绍一下这个第三方库,当然,也能百度到

import numpy as np
X_zu = [[X11,X12,X13]
        [X21,X22,X23]
        [X31,X32,X33] ]
Y_zu = [y1,y2,y3]
xishu = np.linalg.solve(X_zu,Y_zu)
#可以得到aX11+bX12+cX13=y1
        aX21+bX22+cX23=y2
        aX31+bX32+cX33=y3方程组的系数解
的系数,结果为[a,b,c]

得到K1,K2分别为两个模型的系数列表
把两个表复制到另外两个列表上写到Excel里面看下系数的变化

KK1 = []
KK2 = []
for m in K1:
    KK1.append(m)
for n in K2:
    KK2.append(n)
for m in range(0,len(KK1)):
    for m_i in range(0,len(KK1[m])):
         KK1[m][m_i]= str(KK1[m][m_i])
for n in range(0,len(KK2)):
    for n_i in range(0,len(KK2[n])):
         KK2[n][n_i]= str(KK2[n][n_i])
for m in range(0,len(KK1)):
    KK1[m] = '\t'.join(KK1[m])
for n in range(0,len(KK2)):
    KK2[n] = '\t'.join(KK2[n])
kk1 = '\n'.join(KK1)
kk2 = '\n'.join(KK2)
lujing = input('路径:')
save_excel(kk1,lujing,'k1','xls')
save_excel(kk2,lujing,'k2','xls')

导出后在EXCEL里用折线图看下变化
Python自学第5周反馈:python做多元回归分析,预测某支股票未来的最高最低价_第1张图片
选了K1中11个数据的前两个来看,在某些时候,所有的系数都会出现同时性的异常变化,然后又恢复到稳定平缓的区间内
所以这个时候,如果剔除掉这些极值的变化,是否就意味着得到了误差较小的模型系数
那么简单剔除这些极值后求下平均

#复制一下列表,不改变原始列表数据
KK1 = []
KK2 = []
for m in K1:
    KK1.append(m)
for n in K2:
    KK2.append(n)

Min_xishu = []                       #次日最低价模型系数
for m in KK1:
    m_jizhi = sum(Maxbox(m))+sum(Minbox(m))
    m_pingjun = (sum(m)-m_jizhi)/(len(m)-len(Maxbox(m))-len(Minbox(m)))
    Min_xishu.append(m_pingjun)
Max_xishu = []                       #次日最低价模型系数
for n in KK2:
    n_jizhi = sum(Maxbox(n))+sum(Minbox(n))
    n_pingjun = (sum(n)-n_jizhi)/(len(n)-len(Maxbox(n))-len(Minbox(n)))
    Max_xishu.append(n_pingjun)

得到两个模型的较为平缓的系数列表

[-9.87415007673367, 14.446784122123194, 1.010947292700218, -0.6713494282167548, 0.004399760010864537, 3.3945343773612057e-09, -21.086355791490657, -7.300150600152714, -0.059418146292691564, -0.023176762967006607, -187.71050254233998]
[-11.61087869160444, 12.975152480636996, 5.314732749838108, -4.383161888273938, 0.006608535250453917, -5.837076664947736e-07, -105.80464849744256, -10.279447137600293, -0.009796891546675993, 0.030801842614598465, -194.7853503579903]

如果实际使用的时候,不删减小数点后面的数值自然更为精准,但是在这里我们删减一下得到两个模型方程;

日期 开盘 收盘 最高 最低 成交量 成交额 振幅 不知是啥 已休市 预备休市 涨跌幅 次日最低价 次日最高价
日期 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 Y1 Y2
次日最低价=-9.87×开盘价+14.45×收盘价+1.01×最高价-0.67×最低价+0.004×成交量+0.0000000003×成交额-21.09×振幅-7.30×未知参数-0.059×已休市天数-0.023×预备休市天数-187.7×涨跌幅+容错

可以看到,成交量和额的影响微乎其微
这里的容错是通过公式回测后,得到预测值和实际值之间的偏差数值的平均常数或误差函数
实际上,股票价格上升和下降时的变化应该是不一样的,因素的影响也是不一样的,所以实际操作中,最好将上涨和下跌做两个模型来进行分析

本次学习的代码:

URL = "http://pdfm.eastmoney.com/EM_UBG_PDTI_Fast/api/js?rtntype=5&token=4f1862fc3b5e77c150a2b985b12db0fd&cb=jQuery18302552622653333736_1569140962147&id=0023952&type=k&authorityType=&_=1569140965266"
import re
import requests
import numpy as np
#在单独表字典中单独读取某行某列的一段数据为列表
def quhang(zidian,hang,lie1,lie2):
    liebiao = []
    for i in list(range(lie1,lie2+1)):
        x = zidian['第'+str(hang)+'行']['第'+str(i)+'列']
        liebiao.append(x)
    return liebiao
def qulie (zidian,lie,hang1,hang2):
    liebiao = []
    for i in list(range(hang1,hang2+1)):
        x = zidian['第'+str(i)+'行']['第'+str(lie)+'列']
        liebiao.append(x)
    return liebiao

#用于识别2019-09-20类型日期,便于计算两组数据之间的时间间隔
def day_num(y_m_d):
    import time
    daynum = time.mktime(time.strptime(y_m_d,"%Y-%m-%d"))/int(86400)
    return daynum
#把特定的字符串写入特定路径按特定名和格式保存
def save_excel(baocunduixiang,wenjianjialujing,baocunming,geshihouzhui):
    baocunming = str(baocunming)                                                         #指定保存名
    LUJING_NEW = wenjianjialujing + '\\' + baocunming + '.'+ geshihouzhui                #拼装最终路径
    f = open(LUJING_NEW, 'w')                                                            # 在目的路径声明一个文件及格式并打开
    f.write(baocunduixiang)                                                              # 把处理好的信息写入这个文件
    f.close()                                                                            # 关闭写入操作
#极大值极小值
def Maxbox(liebiao):
    Maxbox_num = []
    for i in range(0,len(liebiao)):
        if i == 0 :
            if liebiao[i]>liebiao[i+1]:
                Maxbox_num.append(i+1)
        else:
            if i == len(liebiao)-1:
                if liebiao[i]>liebiao[i-1]:
                    Maxbox_num.append(i+1)
            else:
                if liebiao[i]>liebiao[i-1]:
                    if liebiao[i]>liebiao[i+1]:
                        Maxbox_num.append(i+1)
    jieguo = []
    for a in Maxbox_num:
        jieguo.append(liebiao[a-1])
    return jieguo
def Minbox(liebiao):
    Minbox_num = []
    for i in range(0,len(liebiao)):
        if i == 0 :
            if liebiao[i]

你可能感兴趣的:(爬虫入门)