特征工程:技术指标与基本面指标等
在这一章节,我会接着上一章节介绍的股票技术指标,介绍如何在特征工程中利用技术指标和基本面指标。我也会以这两类特征为例,介绍特征工程中涉及的数据预处理、数据变换、特征选取等内容。特征工程的目标是最大限度地从原始数据中提取特征以供算法和模型使用。对于股票预测,除了增加不同种类的原始数据(历史价量、基本面数据等等),从已有的数据中提取有用的信息也是非常重要的环节。
1. 技术指标特征
在这一部分,我们以上一次课中涉及到的如下技术指标作为特征:
- 动量
- 简单滑动平均
- 指数加权移动平均
- 布林带
我们使用的是之前已经下载好的平安银行的股票数据。
import pandas as pd df = pd.read_csv('1.csv', dtype={'trade_date': str}) df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d') df = df.set_index('trade_date', drop=False) # 指明drop=False保留trade_dt这一列 df = df.sort_index() # 按照时间顺序排序
然后通过TA-Lib计算我们介绍过的技术指标:
import talib # 计算动量 # 指定参数 timeperiod = 1 # 使用talib计算 df['mom'] = talib.MOM(df['close'], timeperiod=timeperiod) # 计算简单滑动平均 # 指定参数 timeperiod = 30 # 使用talib计算 df['sma'] = talib.SMA(df['close'], timeperiod=timeperiod) # 计算指数加权移动平均 # 指定参数 timeperiod = 30 # 使用talib计算 df['ema'] = talib.EMA(df['close'], timeperiod=timeperiod) # 计算布林带 # 指定参数 timeperiod = 5 nbdevup = 2 # 上下都是2倍标准差 nbdevdn = 2 # 使用talib计算 df['upperband_talib'], df['middleband_talib'], df['lowerband_talib'] = talib.BBANDS(df['close'], timeperiod=timeperiod, nbdevup=nbdevup, nbdevdn=nbdevdn) # 汇总技术指标特征 ta_features = ['mom', 'sma', 'ema', 'upperband_talib', 'middleband_talib', 'lowerband_talib']
2. 基本面指标特征
与基于技术指标的技术分析不同,基本面分析关注宏观经济、各种政策和企业的各方面财务情况等等因素对股票的影响。这些因素可以被大致分为宏观经济因素(如经济和行业状况)和微观经济因素(如财务状况和公司管理)。
这里我们以财务数据为例。财务数据的来源主要是上市公司发布的财务报表。按照境内监管的要求,上市公司每一会计年度都要公布两次审计过的财务报表,即年度财务报告和中期财务报告。另外还必须公布可不经审计的季度财务报表,即一季度和三季度报。公示时间年度报告是每年结束后4个月内,半年度是上半年结束后2个月内,季度报告是季度结束后1个月内。这里需要注意的是财务报表的发布日期会滞后于涵盖的财务周期,如果按照财务周期的最后一天使用财务数据的话会造成未来信息泄露的问题。
在境内上市的上市公司公布的财务报表主要是三张表:
- 资产负债表:根据资产、负债、所有者权益(或股东权益,下同)之间的勾稽关系,按照一定的分类标准和顺序,反映企业资产、负责、所有者权益的总体规模和结构;
- 利润表:包括企业的各项收入、费用以及构成利润的各个项目分类分项列示;
- 现金流量表:包括经营活动产生的现金流量、投资活动产生的现金流量、筹资活动产生的现金流量这三大项。
在这里,由于tushare获取财务数据对账户的积分有一定的要求,因此我们使用证券宝(baostock)获取财务数据。baostock可以使用pip命令进行安装(pip install baostock)。我们以季频盈利能力为例,其他的接口的使用方法是类似的。
import baostock as bs # 登陆系统 lg = bs.login() # 显示登陆返回信息 print('login respond error_code:'+lg.error_code) print('login respond error_msg:'+lg.error_msg) # 查询季频估值指标盈利能力 profit_list = [] # 设置时间范围,这里起点设为2009年是因为2009年的年报是在2010年发布的 year_list = range(2009, 2020) # 设置财报周期 quarter_list = range(1,5) for year in year_list: for quarter in quarter_list: rs_profit = bs.query_profit_data(code="sz.000001", year=year, quarter=quarter) while (rs_profit.error_code == '0') & rs_profit.next(): profit_list.append(rs_profit.get_row_data()) result_profit = pd.DataFrame(profit_list, columns=rs_profit.fields) result_profit['pubDate'] = pd.to_datetime(result_profit['pubDate'], format='%Y-%m-%d') result_profit = result_profit.set_index('pubDate', drop=False) # 打印输出 print(result_profit.head()) # 登出系统 bs.logout()
输出为:
login success! login respond error_code:0 login respond error_msg:success code pubDate statDate roeAvg npMargin gpMargin \ pubDate 2009-04-24 sz.000001 2009-04-24 2009-03-31 0.067044 0.298377 2009-08-21 sz.000001 2009-08-21 2009-06-30 0.134429 0.308562 2009-10-29 sz.000001 2009-10-29 2009-09-30 0.204987 0.327284 2010-03-12 sz.000001 2010-03-12 2009-12-31 0.272887 0.332843 2010-04-29 sz.000001 2010-04-29 2010-03-31 0.074126 0.386391 netProfit epsTTM MBRevenue totalShare \ pubDate 2009-04-24 1122077000.000000 0.235693 3105433762.00 2009-08-21 2311388000.000000 0.251684 7490850000.000000 3105433762.00 2009-10-29 3637419000.000000 0.300911 3105433762.00 2010-03-12 5030729000.000000 1.619976 15114440000.000000 3105433762.00 2010-04-29 1578118000.000000 1.766829 3105433762.00 liqaShare pubDate 2009-04-24 2784605731.00 2009-08-21 2923756824.00 2009-10-29 2923756824.00 2010-03-12 2924114263.00 2010-04-29 2924114263.00 logout success!
这里的输出的各列说明如下:
参数名称 | 参数描述 | 算法说明 |
---|---|---|
code | 证券代码 | |
pubDate | 公司发布财报的日期 | |
statDate | 财报统计的季度的最后一天, 比如2017-03-31, 2017-06-30 | |
roeAvg | 净资产收益率(平均)(%) | 归属母公司股东净利润/[(期初归属母公司股东的权益+期末归属母公司股东的权益)/2]*100% |
npMargin | 销售净利率(%) | 净利润/营业收入*100% |
gpMargin | 销售毛利率(%) | 毛利/营业收入100%=(营业收入-营业成本)/营业收入100% |
netProfit | 净利润(元) | |
epsTTM | 每股收益 | 归属母公司股东的净利润TTM/最新总股本 |
MBRevenue | 主营营业收入(元) | |
totalShare | 总股本 | |
liqaShare | 流通股本 |
接下来我们会以净资产收益率作为我们的基本面指标特征,并且将其加入我们上面定义的变量df中:
df['roeAvg'] = result_profit['roeAvg'] print(df.head()) # 汇总基本面指标特征 ba_list = ['roeAvg']
输出为:
ts_
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
<p> 在这个专刊中,我们会学习Python在金融中的应用: ·掌握Python进行数据分析和处理的方法; ·了解Python在量化投资中的应用; ·转行到金融数据分析和量化交易领域的基础等内容。 这个专刊适合: ·想要学习Python编程的在校学生; ·想要转行到金融领域的在职人士; ·想要利用业余时间进行量化投资的在职人士等。 本专刊购买后即可解锁所有章节,故不可以退换哦~ </p>