思路:通过学习近两年的每个季度报的基本面财务数据,建立模型,买入并持有预测三个月后会涨5%以上的股票,直到下一批季度报

数据采集:用到了大约10018行数据(已去除缺失值,不采用填充),其中采用了两个技术指标(趋势指标CYES,CYEL)

   circulating_market_cap  operating_revenue    net_profit           roe  \
count            10018.000000       1.001800e+04  1.001800e+04  10018.000000
mean               154.594481       3.588924e+09  4.234473e+08      3.140488
std                600.063348       2.005736e+10  3.071935e+09      3.247377
min                  3.120000       1.224100e+06  1.966154e+04      0.002400
25%                 33.570000       2.299639e+08  2.410783e+07      1.472500
50%                 58.854650       5.483732e+08  5.702822e+07      2.544550
75%                109.488325       1.511452e+09  1.540881e+08      3.915775
max              16176.732400       5.821850e+11  7.766000e+10     99.828000   inc_net_profit_year_on_year  inc_revenue_year_on_year       pe_ratio  \
count                 10018.000000              10018.000000   10018.000000
mean                    385.339754                 91.570442     216.210794
std                    4309.253887               1648.839653    6348.503816
min                       0.017300                -98.926300       1.920300
25%                      18.204850                  7.450175      33.834325
50%                      47.288100                 23.729200      54.822600
75%                     140.021300                 48.867150      96.220775
max                  308628.250000             122241.677300  594205.375000   CYEL1         CYES1           peg  price_increase_rate  \
count  10018.000000  10018.000000  10018.000000         10018.000000
mean       0.065483     -0.031435      9.038361            -1.866428
std        1.070460      0.626431    128.634609            13.427512
min       -7.415192     -3.243705      0.000165           -56.206703
25%       -0.511237     -0.325856      0.455366            -9.436908
50%       -0.028772      0.013026      1.163501            -3.026580
75%        0.554540      0.262382      3.137165             3.569913
max       10.001834      9.773301   8321.761237           247.121711   value
count  10018.000000
mean       0.214314
std        0.410366
min        0.000000
25%        0.000000
50%        0.000000
75%        0.000000
max        1.000000  

数据处理:

去除空白值、缺失值,对原始股价求出增长率*100,若增长率>5%,目标值value=1,反之为0

计算了PE/G,按照金融指标利润,PEG越小(负值滚出克),越能体现股票的价值和成长性

数据源来自聚宽,源码:

import numpy as np
#去除np默认省略
np.set_printoptions(suppress=True)
import pandas as pd
import re
import time
import jqdata
from jqlib.technical_analysis import *

np.set_printoptions(threshold=np.inf)  
def getdata(statdate):
    #字符处理
    year=statdate[0:4]
    date=statdate[-1]
    if date=='1':
        date_start='0430'
        date_end='0830'
    elif   date=='2':
        date_start='0831'
        date_end='1030'
    elif   date=='3':
        date_start='1031'
        date_end='1231'    
    elif   date=='4':
        year=str(int(year)+1)
        date_start='0429'
        date_end='0630'        
    date_start=year+date_start    
    date_end=year+date_end   
    print date_start,date_end
        
    q = query(
         valuation.code,  #代码
            valuation.circulating_market_cap,  #流通市值
            income.operating_revenue,  #营业收入
            income.net_profit,   #净利润
            indicator.roe ,   #净资产收益率
            indicator.inc_net_profit_year_on_year,   #同比净利润增长率
            indicator.inc_revenue_year_on_year,   #同比营业收入增长率
            valuation.pe_ratio

).order_by(

valuation.code.asc())
    df = get_fundamentals(q, statDate=statdate)
    
    df.index=df['code']
    
    #print df['code']
    #正则取code列表
    a=df['code'].values
    a=str(a)
    #print a
    pattern=r"'(.*?)'"
    list=re.findall(pattern,a)
    #print list
    print len(list)
    #改日期格式
    date_start = time.strptime(date_start, "%Y%m%d") 
    date_start=time.strftime("%Y-%m-%d",date_start)
    print date_start
        
    date_end = time.strptime(date_end, "%Y%m%d") 
    date_end=time.strftime("%Y-%m-%d",date_end)
    print date_end

#date_start = time.strftime("%Y/%m/%d %H:%M:%S", timeStruct) 
    
    #获取时间区间股价及股价变化
    df2 = get_price(list, start_date=date_start, end_date=date_end, frequency='daily', fields='close')
    df3=pd.DataFrame(df2['close'])
    
    #获取CYE(CYES,CYEL)
    #df['CYEL1','CYES1']= CYE(df['code'].values,check_date= date_start)

CYEL1,CYES1 = CYE(df['code'],check_date= date_start
    df['CYEL1']=pd.Series(CYEL1)
    df['CYES1']=pd.Series(CYES1)
   
        
    # 计算PE/G
    df['peg'] = df.apply(lambda x: x['pe_ratio'] / x['inc_net_profit_year_on_year'], axis=1)
    
    #df['price_increase_rate']
    
    df4= pd.DataFrame((df3.ix[-1]-df3.ix[0])/df3.ix[0]*100)
    
    df4.columns=['price_increase_rate']

df4['value']= df4['price_increase_rate'].where(df4['price_increase_rate']>5,0)
    df4['value']= df4['value'].where(df4['price_increase_rate']<=5,1)
    #print df
    #print df4
    #print df4.describe()
   
    #df['price_increase_rate']=
    df4=pd.concat([df,df4],axis=1)
    print df4['price_increase_rate']
    print df4.describe()

return df4

#list=['2016q2','2016q3','2016q4','2017q1','2017q2','2017q3']
list=['2016q1']
for statdate in list:
    data=getdata(statdate)
    #print data
    #print data.describe()
    string=str(statdate)+'.csv'
    data.to_csv(string)
    print'已储存%s'%(statdate)

#读取csv
from six import StringIO
csvlist=['2016q2.csv','2016q3.csv','2016q4.csv','2017q1.csv','2017q2.csv','2017q3.csv']
body=read_file(csvlist[0])
data=pd.read_csv(StringIO(body))
#data.index=data['code']
i=1
while i <= len(csvlist)-1:
    body=read_file(csvlist[i])
    data2=pd.read_csv(StringIO(body))
    #data2.index=data['code']
    #del data['code.1']
    #print data.head(20)
    data=pd.concat([data,data2],axis=0)
    i=i+1

del data['code.1']
print len(data)

#去除负值(没有成长性和目前经营不善的股票)
df=data[(data['net_profit'] >0) & (data['roe'] > 0)&(data['pe_ratio'] > 0)&(data['peg'] > 0)]
df.dropna(inplace=True)
print df.head(5)

print df.describe()

模型制作:

数据中去除了负值(没有成长性和目前经营不善的股票),保留了高成长性和基本面优异的股票下一步

70%训练,30%检验,数据进行了归一化。

from sklearn import preprocessing
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.svm import SVC

# 数据集0.3 0.7分集
X_train,X_test,y_train,y_test=train_test_split(df.ix[:,['circulating_market_cap','operating_revenue','net_profit','roe','inc_net_profit_year_on_year','inc_net_profit_year_on_year',  \
            'pe_ratio','CYEL1','CYES1','peg']],df['value'], test_size=0.3, random_state=40)

#model2 = MLPClassifier(activation='relu', solver='adam', alpha=0.0001)

#做了标准化归一化
X_scaled = preprocessing.scale(X_train)
X_test_scaled = preprocessing.scale(X_test)

model2 = SVC(C=1.0, kernel='rbf', gamma='auto')

model2.fit(X_scaled,y_train)

predict = model2.predict(X_test_scaled)

print model2.score(X_test_scaled, y_test)

#混淆矩阵

print confusion_matrix(y_true=y_test, y_pred=predict)

考虑到股票预测的特殊性,SCORE准确度虽然高达78%,但假阳性/阳性,真阳性/阳性的比率才是我所需要的

在本次测试中,测试集一共做出了18次判断,假阳7次,真阳11次。效果看似并不理想,其实63%准确度的三个月5%的预测结果足以让投资者获得超额收益。

***假阳并不意味着亏损,毕竟即使涨1%,虽然不符合value判断阀门,但也是盈利。

准确度:
0.787425149701

混淆矩阵:

            [[2356    7][ 632   11]]

sklearn svc模型的导入和使用

使用sklearn的joblib包保存模型

将新的季度财务数据导入模型源码:

# -*- coding: utf-8 -*-
from sklearn.externals import joblib
from sklearn import preprocessing
import numpy as np
np.set_printoptions(suppress=True)
import pandas as pd
model = joblib.load('SVC_STOCK.model')

#读取csv
from six import StringIO

body=read_file('2018q1.csv')
data=pd.read_csv(StringIO(body))
#data.index=data['code']

del data['code.1']
print len(data)

#去除负值(没有成长性和目前经营不善的股票)
df=data[(data['net_profit'] >0) & (data['roe'] > 0)&(data['pe_ratio'] > 0)&(data['peg'] > 0)]
del df['price_increase_rate']
df.dropna(axis = 0)
print df.head(5)
print df.describe()
print len(df)

X1=df.ix[:,['circulating_market_cap','operating_revenue','net_profit','roe','inc_net_profit_year_on_year','inc_net_profit_year_on_year','pe_ratio','CYEL1','CYES1','peg']]

X_scaled=preprocessing.scale(X1)
predict = model.predict(X_scaled)

count=0
for e in predict:
    if e == 1:
        count=count+1

print count

11

2018年一季报的财务结果并预测了11只股票会增长超过5%

#输出股票代码

df['predict']=predict

list=[]
list=df['code'][df['predict'] == 1].values

print list

['000333.XSHE' '000651.XSHE' '000858.XSHE' '002290.XSHE' '002415.XSHE''600019.XSHG' '600267.XSHG' '600276.XSHG' '600311.XSHG' '600519.XSHG''600747.XSHG']

对上述的结果进行回测检验

joinquant 回测代码:

# 导入函数库
import jqdata
    
from datetime import * 
import math
import numpy as np
import pandas as pd

# 初始化函数,设定基准等等
def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')        
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    #2015Q2
    #g.stock=['000554.XSHE' ,'000687.XSHE', '600321.XSHG' ,'600519.XSHG' ,'600533.XSHG','600629.XSHG']
    #2016Q1
    g.stock_2016q1=['000892.XSHE', '600519.XSHG', '601766.XSHG']
    #2016Q2
    g.stock_2016q2=['000609.XSHE' ,'600519.XSHG' ,'600984.XSHG', '601398.XSHG', '601766.XSHG','601800.XSHG']
    
    
    #2016Q3
    g.stock_2016q3=['000002.XSHE' ,'000333.XSHE' ,'600519.XSHG' ,'601318.XSHG', '601628.XSHG','601800.XSHG']
    
    
    #2016Q4
    g.stock_2016q4=['600519.XSHG', '601766.XSHG']
    
    #2017Q1
    g.stock_2017q1=['000333.XSHE', '000557.XSHE', '000651.XSHE', '002122.XSHE' ,'002141.XSHE',
    '002265.XSHE' ,'002346.XSHE', '300093.XSHE' ,'300338.XSHE' ,'300391.XSHE',
    '600019.XSHG', '600251.XSHG' ,'600519.XSHG', '600693.XSHG', '600817.XSHG',
    '600876.XSHG' ,'601628.XSHG']

#2017Q2
    g.stock_2017q2=['000002.XSHE', '000333.XSHE', '000651.XSHE' ,'000858.XSHE' ,'002415.XSHE',
    '300618.XSHE' ,'600519.XSHG', '601601.XSHG']
    
    #2017Q3
    g.stock_2017q3=['000002.XSHE' ,'000333.XSHE' ,'000651.XSHE' ,'002192.XSHE' ,'300354.XSHE',
    '600019.XSHG' ,'600238.XSHG', '600519.XSHG' ,'600769.XSHG' ,'601177.XSHG',
    '601318.XSHG', '601601.XSHG']
    
    #2018q1
    g.stock_2018q1=['000333.XSHE', '000651.XSHE' ,'000858.XSHE', '002290.XSHE' ,'002415.XSHE',
    '600019.XSHG', '600267.XSHG' ,'600276.XSHG' ,'600311.XSHG' ,'600519.XSHG',
    '600747.XSHG']
    
 
    #     0430-0830,0831-1030,1031-0430,0429-0629(年报不用,发布太慢)
    #2016q1-2018q1
    # 过滤掉order系列API产生的比error级别低的log
    # log.set_level('order', 'error')
    
    ### 股票相关设定 ###
    # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
      # 开盘前运行
    run_daily(before_market_open, time='before_open', reference_security='000300.XSHG') 
      # 开盘时或每分钟开始时运行
    run_daily(market_open, time='every_bar', reference_security='000300.XSHG')
      # 收盘后运行
    run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')
    
## 开盘前运行函数     
def before_market_open(context):
    #context.current_dt
    #引用股票列表
    if date(2016, 03, 31)<context.current_dt.date()<= date(2016, 8, 30):
        g.stock=g.stock_2016q1

elif  date(2016, 8, 31)<=context.current_dt.date()<= date(2016, 10, 30):
        g.stock=g.stock_2016q2

elif  date(2016, 10, 31)<=context.current_dt.date()<= date(2017, 04, 30):
        g.stock=g.stock_2016q3
    
    if date(2017, 05, 01)<=context.current_dt.date()<= date(2017, 8, 30):
        g.stock=g.stock_2017q1

elif  date(2017, 8, 31)<=context.current_dt.date()<= date(2017, 10, 30):
        g.stock=g.stock_2017q2

elif  date(2017, 10, 31)<=context.current_dt.date()<= date(2018, 04, 30):
        g.stock=g.stock_2017q3
    
    else:
        g.stock=g.stock_2018q1
        
        '''
        elif date(2017, 05, 01)<=context.previous_date<= date(2017, 8, 30):
        g.stock=g.stock_2018q1

elif  date(2016, 8, 31)<=context.previous_date<= date(2016, 10, 30):
        g.stock=g.stock_2016q2

elif  date(2016, 10, 31)<=context.previous_date<= date(2017, 04, 30):
        g.stock=g.stock_2016q3
        '''
    #过滤st和停牌
    remove_paused_and_st(g.stock)
  
    
## 开盘时运行函数
def market_open(context):
    cash = context.portfolio.available_cash
    
    if len( context.portfolio.positions)>0:
        for f in context.portfolio.positions:
            if f not in g.stock:
                order_target(f, 0)
                    
    
    for e in g.stock:
        if context.portfolio.available_cash>100000 :
             order_value(e, 100000)
    
   
 
## 收盘后运行函数  
def after_market_close(context):
    pass

def remove_paused_and_st(stock_list):
    current_data = get_current_data(stock_list)
    return [stock for stock in stock_list if not current_data[stock].paused 
        and not current_data[stock].is_st 
        and 'ST' not in current_data[stock].name 
        and '*' not in current_data[stock].name 
        and '退' not in current_data[stock].name]

这个策略只择股不择时,不止损和无风控,纯属毛坯房。未来将考虑使用技术指标的改进版进行择时交易,并进行止盈止损。

最大回测20%(时间区间为今年初A股受中美经济战崩盘),事实上201805月已明显反弹股价,并表现明显强于沪深300

机器学习SVC分类预测三个月后的股价相关推荐

  1. python机器学习之分类预测

    目录 逻辑回归 水位判断案例引入逻辑回归计算原理 逻辑回归 单次项逻辑回归代码示例 二阶项及以上项式的边界函数计算和绘制 二阶多项式逻辑回归案例 尝试用一阶函数画出边界 二阶项逻辑回归 K近邻分类模型 ...

  2. 【机器学习入门】(1) K近邻算法:原理、实例应用(红酒分类预测)附python完整代码及数据集

    各位同学好,今天我向大家介绍一下python机器学习中的K近邻算法.内容有:K近邻算法的原理解析:实战案例--红酒分类预测.红酒数据集.完整代码在文章最下面. 案例简介:有178个红酒样本,每一款红酒 ...

  3. 基于scikit-learn机器学习库的分类预测

    一旦你在scikit-learn中选择好机器学习模型,就可以用它来预测新的数据实例.初学者经常会有这样的疑问: 如何在scikit-learn中用我自己的模型进行预测? 在本教程中,你将会发现如何在P ...

  4. 基于Keras机器学习库的分类预测

    在前面的博文中,我们分享了<基于scikit-learn机器学习库的分类预测>,本文将分享Keras机器学习库的分类预测. 一旦你在Keras中选择好机器学习模型,就可以用它来预测新的数据 ...

  5. 泰坦尼克号沉船数据分析与可视化、数据建模与分类预测【Python | 机器学习-Sklearn】

    泰坦尼克号沉船数据之美--起于悲剧,止于浪漫 前言:泰坦尼克号,不只是卡梅隆导演的经典电影,它是一个真实存在的悲剧,也是电影的故事背景与题材.作为一个IT人,分析事实还得看数据,了解到泰坦尼克号沉船幸 ...

  6. 【活动打卡】【Datawhale】第16期 机器学习算法梳理(AI入门体验) Task02:基于决策树的分类预测

    1.决策树的介绍和应用 1.1 决策树的介绍 决策树是一种常见的分类模型,在金融风控.医疗辅助诊断等诸多行业具有较为广泛的应用.决策树的核心思想是基于树结构对数据进行划分,这种思想是人类处理问题时的本 ...

  7. 机器学习算法(七): 基于LightGBM的分类预测(基于英雄联盟10分钟数据判断红蓝方胜负)

    机器学习算法(七)基于LightGBM的分类预测 1. 实验室介绍 1.1 LightGBM的介绍 LightGBM是2017年由微软推出的可扩展机器学习系统,是微软旗下DMKT的一个开源项目,由20 ...

  8. 石油专业:一文入门机器学习,以测井岩性分类预测为例

    石油工程:一文入门机器学习,以测井岩性分类预测为例 1 前言 1.1 机器学习的相关背景 1.2 机器学习的八股文 2 模型实战 2.0 导入相关库 2.1 数据处理 2.1.1 数据读取 2.1.2 ...

  9. 机器学习算法------3.3 案例:癌症分类预测-良/恶性乳腺癌肿瘤预测

    文章目录 3.3 案例:癌症分类预测-良/恶性乳腺癌肿瘤预测 学习目标 1 背景介绍 2 案例分析 3 代码实现 4 小结 3.3 案例:癌症分类预测-良/恶性乳腺癌肿瘤预测 学习目标 通过肿瘤预测案 ...

最新文章

  1. 【Leafletjs】4.L.Map 中文API
  2. Keepalived简介
  3. django 用户管理相关的表
  4. 新浪微博 API 使用入门
  5. AngularJs自定义指令的详解
  6. 封装自己的DB类(PHP)
  7. BigDecimal的精度舍入模式详解
  8. Excel表格快速转PDF
  9. 关于二进制与十进制互转的方法(简单好学!)
  10. Code3 将文件转换到byte数组中
  11. android手机截图 视频,安卓Android手机相册视频如何隐藏
  12. SyntaxError报错成功解决
  13. 服务器raid5阵列硬盘故障的解决办法
  14. 机器人学与OROCOS-KDL(一)简介
  15. C++--数值的整数次方
  16. 饿死也别进外包公司!说好不加班才入职,结果连续工作10小时,提出辞职后,外包公司竟以时间短为理由拒绝给工资!...
  17. Gravity 介绍
  18. 为什么我的域名在某些地方不能访问,解析到127.0.0.1或者0.0.0.0?
  19. HCNP-RS培训视频课程[简讲版]-马青-专题视频课程
  20. 当前发布的sku信息中包含疑似与商品无关的字段,请核实修改后重新提交

热门文章

  1. 看,2021年,一个普通应届生的成长之旅
  2. zebradesginer zpl代码_老司机为您win7系统安装斑马GK888t打印机驱动的操作技巧
  3. 斗牛士的最后一刺,应准确命中牛肩胛骨间约几英寸宽的地方
  4. Python对列表去重的多种方法(四种方法)
  5. 谷歌浏览器那些有趣的隐藏功能
  6. android防拆机方案,拆机狂人必备 iFixit Android客户端试用
  7. 富士康计算机主板官网,富士康主板BIOS设置的进入方法
  8. iPhone与小米的体验对比(一)
  9. Web实现前后端分离,前后端解耦
  10. 用xcode编译c++代码