金融数据分析与挖掘具体实现方法 -1
有人让我写一下关于数据挖掘在金融方面的应用,再加上现在金融对数据方面的要求不断提高,准备用两篇随笔来做个入门总结。
首先,在看这篇随笔以前稍微补充一点金融方面的知识,因为我不是金融专业的,以下补充知识来自互联网与个人整理,欢迎批评指正并补充说明。
1 先来了解一下什么是金融市场呢?
通常狭义的金融市场特指有价证券(股票、债券)发行和流通的场所。
股票、债券是用来资本流通的金融产品,广义上的金融市场还包含货币市场,其中代表性的是期货市场等。
其实不管是资本市场,还是货币市场,都是可以提供给投资者投资的地方,其中货币市场以期货为代表的适合短期投资,而以股票代表的证券市场适合长期投资!
常见机构:银行、投资银行(证券公司)、保险公司、基金等
有价证券:是虚拟资本的一种形式,它本身没价值,但有价格。
2 狭义的金融市场划分
2.1 按交易程序划分
-
发行市场:又称为处理新发行证券的金融市场,筹集资金的公司、*或公共部门通过发行新的股票和债券来进行融资。
-
流通市场:又称二级市场,是指已经发行的证券进行转让、交易的市场。
我们通过一张图来理解一下:
关于投资的几个类别,一般我们将天使、vc、pe三个部分统称为私募(private equity),指的是没有在证券交易所公开上市交易的资产。
1、公司规模
天使投资主要投资早期创业公司;
vc投资中期高速发展型创业公司;
pe介入即将上市或被兼并收购的成熟企业。
2、资金规模
天使投资:500万以下 vc投资:千万 pe:千万级别以上
2.2 参与主体
- 证券交易所
- 买卖股票、公司债等有价证券的市场
证券公司:
- 可以承销发行、自营买卖或自营兼代理买卖证券
2.3 关于金融产品的区别
注:*、公司等发行股票、债券目的为了进行融资、发展等
3 什么是股票?
股票,是股份公司签发的证明股东所持股份的凭证,代表了股东对股份公司净资产的所有权。
- 特点:每股股票都代表股东对企业拥有单位的所有权,所拥有的份额取决于持有的股票数量总占比。本身没有价格,代表一种价值
3.1 股票按照股东权利的分类
- 按股东权利分类,股票可分为普通股、优先股等
普通股
普通股是指在公司的经营管理和盈利及财产的分配上享有普通权利的股份,代表满足所有债权偿付要求及优先股东的收益权与求偿权要求后对企业盈利和剩余财产的索取权。普通股构成公司资本的基础,是股票的一种基本形式。现上海和深圳证券交易所上进行交易的股票都是普通股。
普通股股东
(1)公司决策参与权。普通股股东有权参与股东大会,并有建议权、表决权和选举权,也可以委托他人代表其行使其股东权利。
(2)利润分配权。普通股股东有权从公司利润分配中得到股息。普通股的股息是不固定的,由公司赢利状况及其分配政策决定。普通股股东必须在优先股股东取得固定股息之后才有权享受股息分配权。
(3)优先认股权。如果公司需要扩张而增发普通股股票时,现有普通股股东有权按其持股比例,以低于市价的某一特定价格优先购买一定数量的新发行股票,从而保持其对企业所有权的原有比例。
(4)剩余资产分配权。当公司破产或清算时,若公司的资产在偿还欠债后还有剩余,其剩余部分按先优先股股东、后普通股股东的顺序进行分配。
优先股
优先股相对于普通股。优先股在利润分红及剩余财产分配的权利方面优先于普通股。
(1)优先分配权。在公司分配利润时,拥有优先股票的股东比持有普通股票的股东,分配在先,但是享受固定金额的股利,即优先股的股利是相对固定的。
(2)优先求偿权。若公司清算,分配剩余财产时,优先股在普通股之前分配。注:当公司决定连续几年不分配股利时,优先股股东可以进入股东大会来表达他们的意见,保护他们自己的权利。
3.2 股票按照上市地区的分类
- 根据上市地区可以分为,我国上市公司的股票有a股(在上海和深圳上市)、b股(上海和深圳上市,其中上海b股以美元结算,深圳b股以港元结算),h股(香港交易所上市,在大陆运作的公司)。并且还有一些n股和s股等的划分。这一区分主要依据股票的上市地点和所面对的投资者而定
3.3 股票按照股票业绩的分类
- 根据业绩也分为:st股、垃圾股、蓝筹股 等
- 蓝筹股:股票市场上,那些在其所属行业内占有重要支配性地位、业绩优良,成交活跃、红利优厚的大公司。
在进行股票投资的时候,我们会使用价值投资方式。选择公司前景好、业绩好的一些公司
知道了股票的基本分类,接下来我们去看看股票具体的一些机制。
3.4 人民币普通股票
a股
- a股即人民币普通股票。它是由我国境内的公司发行,供境内机构、组织或个人(不含港、澳、台投资者)以人民币认购和交易的普通股股票。
- 特点: a股不是实物股票,以无纸化电子记帐,实行t+1交易制度
t+1制度
自1995年1月1日起,为了保证股票市场的稳定,防止过度投机,股市实行“t+1”交易制度,当日买进的股票,要到下一个交易日才能卖出。同时,对资金仍然实行“t+0”,即当日回笼的资金马上可以使用。
t+1是一种股票交易制度,即当日买进的股票,要到下一个交易日才能卖出。
“t+1"中"t"指的是交易登记日,"t+1"指的是交易登记日的第二天。
3.5 股票的代码、开户、价格形成
我们可以看到这样的符号:
3.5.1 股票代码
股票代码用数字表示股票的不同含义。股票代码除了区分各种股票,也有其潜在的意义,比如600*是上交所上市的股票代码,6006是最早上市的股票,一个公司的股票代码跟车牌号差不多,能够显示出这个公司的实力以及知名度
1、沪市a股票买卖的代码是以600、601或603打头(在上海证券交易所上市的全是主板)
2、深市a股票买卖的代码是以000打头,其中中小板代码以002打头,创业板股票代码以300打头
问题:那么经常说的股票价格是什么?怎么形成的?
3.5.2 股票价格
股票价格(stock price)又叫股票行市,是指股票在证券市场上买卖的价格。股票在流通市场上的价格,才是完全意义上的股票的市场价格
股票初始发行价格=市盈率还原值×40%+股息还原率×20%+每股净值×20%+预计当年股息与一年期存款利率还原值×20%,影响股票价格的因素有很多,如企业因素、盈利情况、净资产、市场、行业等
3.5.3 股票的交易时间和过程
- 股票交易时间
- 休息日:周六、周日和上证所公告的休市日不交易。(一般为五一、十一国庆节、春节、元旦、清明节、端午节、中秋节等国家法定节假日)
- 股票交易过程
(一)、集合竞价阶段:9:15 — 9:25
1、9:15 — 9:19可以申报和撤单;9:20 — 9:25 可以申报,不可以撤单。
2、深圳交易所14:57 — 15:00实行集合竞价,可以申报,不可以撤单。
(二)、连续竞价阶段
1、上海交易所:9:30 — 11:30;13:00 — 15:00
2、深圳交易所:9:30 — 11:30;13:00 — 14:56:59
(三)成交原则
价格优先,时间优先
3.5.4 交易费用
1、印花税:1‰(卖的时候才收取,此为国家税收,全国统一)。 2、过户费:深圳交易所无此项费用,上海交易所收费标准(按成交金额的0.02‰人民币 [2] )。 3、交易佣金:最高收费为3‰,最低收费5元。各家劵商收费不一,开户前可咨询清楚。 例子: 假设你买入10000股,每股票价格为10元,以此为例,对其买入成本计算: 买入股票所用金额:10元/股×10000股=100000元; 过户费:0.02‰×100000=2元(沪市股票计算,深市为0); 交易佣金:100000×3‰=300元(按最高标准计算,正常情况下都小于这个值); 买入总成本:100000元+300元+2元=100302元(买入10000股,每股10元,所需总资金) 多少每股卖出才不赔钱? 可按如下公式计算:(买入总成本+卖出过户费)÷(1-印花税率-交易佣金率)÷股票数量=(100310元+10元)÷(1-0.001-0.003)÷10000=10.07228916元 =10.07元(四舍五入)。 若以10.08每股卖出价格计算: 股票金额:10.08元/股×10000股=100800元; 印花税:100800元×1‰=100.8元; 过户费:0.002%×100800元≈2元; 交易佣金:100800元×3‰=302.4元; 卖出后收入:100800元-100.8元-2元-302.4元=100394.8元; 最终实际盈利为:卖出后收入-买入总成本=100394.8-100302=92.8元;
3.6 股票的层次划分
即使在国内对于a股来说,目前总共有3000多只股票。并且数字可能随着时间会不断改变,如何更好的管理这些上市公司?实现怎样的制度去区分公司的规模大小?
3.6.1 中国股票市场的层次划分
- 主板:市场占有率高、规模较大、基础较好、高收益、低风险的大型优秀企业。
- 中小板:主要服务于即将或已进入成熟期、盈利能力强、但规模较主板小的中小企业。
- 创业板:是以自主创新企业及其他成长型创业企业为服务对象,主要为“两高”、“六新”企业,即高科技、高成长性、新经济、新服务、新农业、新能源、新材料、新商业模式企业。
- 新三板:主要为创新型、创业型、成长型中小微企业发展服务。
在选择购买股票的时候,有时候会根据划分依据去选择特定指数、行业、板块下的股票!!!
3.6.2 股票的不同性质划分
概念股概念股是与业绩股相对而言的。业绩股需要有良好的业绩支撑。概念股则是依靠某一种题材比如资产重组概念,三通概念等支撑价格。行业:
指数:
4 股票数据
4.1 交易数据
股票在流通市场上的价格,才是完全意义上的股票的市场价格,一般称为股票市价或股票行市。股票市价表现为开盘价、收盘价、最高价、最低价等形式。其中收盘价最重要,是分析股市行情时采用的基本数据。
4.2 股票k线图
k线图这种图表源处于日本德川幕府时代,被当时日本米市的商人用来记录米市的行情与价格波动,后因其细腻独到的标画方式而被引入到股市及期货市场。
4.2.1 k线图基本形态
4.2.2 k线图的计算周期
不同的时间间隔看待股票数据变化,会有不一样的发现!
k线的计算周期可将其分为日k线,周k线,月k线,年k线
很多网站提供了日线、周k线、月k线等周期数据,但是最原始的只有日k线的数据。我们需要自己去生成计算不同频率的数据
4.3 案例:股票k线数据重采样
股票方面的基础知识差不多了,接下来我们做个将日k线图转换成周k线图的案例吧!
- dataframe.resample(rule, how=none, axis=0, fill_method=none, closed=none,kind=none,)
- 频率转换和时间序列重采样,对象必须具有类似日期时间的索引(datetimeindex,periodindex或timedeltaindex)
- 日k周k对比:
那么日线、周线、月线等怎么切换标准??
周k线是指以周一的开盘价,周五的收盘价,全周最高价和全周最低价来画的k线图
大部分周线的指标是这个日线指标在这一周最后一个交易日的值。比如周线的’close’应该等于这一周最后一天日线数据的‘close’,但是有的指标是例外,比如周线的’high’应该等于这一周所有日线‘high’中的最大值
接下来我们还是使用之前stock_day当中的某个股票的行情数据
- 将索引转换成datetimeindex类型
- 对不同指标进行重采样
stock_day = pd.read_csv("./data/stock_day/stock_day.csv")
stock_day = stock_day.sort_index()
# 对每日交易数据进行重采样 (频率转换)
stock_day.index
# 1、必须将时间索引类型编程pandas默认的类型
stock_day.index = pd.to_datetime(stock_day.index)
# 2、进行频率转换日k---周k,首先让所有指标都为最后一天的价格
period_week_data = stock_day.resample('w').last()
# 分别对于开盘、收盘、最高价、最低价进行处理
period_week_data['open'] = stock_day['open'].resample('w').first()
# 处理最高价和最低价
period_week_data['high'] = stock_day['high'].resample('w').max()
# 最低价
period_week_data['low'] = stock_day['low'].resample('w').min()
# 成交量 这一周的每天成交量的和
period_week_data['volume'] = stock_day['volume'].resample('w').sum()
- 对于其中存在的缺失值
period_week_data.dropna(axis=0)
我们可以将计算出来的周k和原先的日k画图显示出来
- 画出k线图显示
金融数据绘制需要使用mpl_finance框架, 通过pip 安装即可
from mpl_finance import candlestick_ochl
import matplotlib.pyplot as plt
# 先画日k线
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(20, 8), dpi=80)
# 准备数据, array数组
stock_day['index'] = [i for i in range(stock_day.shape[0])]
day_k = stock_day[['index', 'open', 'close', 'high', 'low']]
candlestick_ochl(axes, day_k.values, width=0.2, colorup='r', colordown='g')
plt.show()
# 周k线图数据显示出来
period_week_data['index'] = [i for i in range(period_week_data.shape[0])]
week_k = period_week_data[['index', 'open', 'close', 'high', 'low']]
candlestick_ochl(axes, week_k.values, width=0.2, colorup='r', colordown='g')
plt.show()
4.4 什么是除权数据以及复权操作?
上市公司会时不时的发生现金分红、送股等一系列股本变动,这会造成股价的非正常变化,导致我们不能直接通过股价来计算股票的涨跌幅。这种数据我们也称之为除权数据。
所以我们要对这种数据做处理,也称之为复权数据。怎么进行复权呢?
简单的一种方式:
原始数据:
1号:100 2号:50 3号:53 4号:51
复权后:
100 / 50 = 2 比例
1号:100 2号:100 3号:106 4号:102
4.5 基本面数据
4.5.1 基本面数据的用处
主要用于基本面分析,主要侧重于从股票的基本面因素,如企业经营能力,财务状况,行业背景等对公司进行研究与分析,试图从公司角度找出股票的“内在价值”,从而与股票市场价值进行比较,挑选出最具投资价值的股票。
量化主要就属于这样的一个分析方式
5 股票时间序列数据处理
5.1 什么是时间序列?
时间序列是一组按照时间发生先后顺序进行排列的数据点序列。通常一组时间序列的时间间隔为一恒定值(如1秒,5分钟,12小时,7天,1年),因此时间序列可以作为离散时间数据进行分析处理。
例如:某监控系统的折线图表,显示了请求次数和响应时间随时间的变化趋势
5.2 pandas的时间类型
- pd.to_datetime():转换成pandas的时间类型 timestamp('2018-03-02 00:00:00')
# pd将时间数据转换成pandas时间类型
# 1、填入时间的字符串,格式有几种, "2018-01-01" ,”01/02/2018“
pd.to_datetime("01/02/2017")
5.3 pandas的时间序列类型
- 1、转换时间序列类型
# 传入时间的列表
pd.to_datetime(["2017-01-01", "2017-02-01", "2017-03-01"])
# 或者
date = [datetime(2018, 3, 1), datetime(2018, 3, 2), datetime(2018, 3, 3), datetime(2018, 3, 4), datetime(2018, 3, 5)]
date = pd.to_datetime(date)
# 如果其中有空值
date = [datetime(2018, 3, 1), datetime(2018, 3, 2), np.nan, datetime(2018, 3, 4), datetime(2018, 3, 5)]
date = pd.to_datetime(date)
# 结果会变成nat类型
datetimeindex(['2018-03-01', '2018-03-02', 'nat', '2018-03-04', '2018-03-05'], dtype='datetime64[ns]', freq=none)
- 2、pandas的时间序列类型:datetimeindex
# datetimeindex
pd.to_datetime(date)
datetimeindex(['2018-03-01', '2018-03-02', '2018-03-03', '2018-03-04',
'2018-03-05'],
dtype='datetime64[ns]', freq=none)
pd.to_datetime(date).values
array(['2018-03-01t00:00:00.000000000', '2018-03-02t00:00:00.000000000',
'2018-03-03t00:00:00.000000000', '2018-03-04t00:00:00.000000000',
'2018-03-05t00:00:00.000000000'], dtype='datetime64[ns]')
我们也可以通过datetimeindex来转换
- 3、通过pd.datetimeindex进行转换
pd.datetimeindex(date)
知道了时间序列类型,所以我们可以用这个当做索引,获取数据
5.4 pandas的基础时间序列结构
# 最基础的pandas的时间序列结构,以时间为索引的,series序列结构
# 以时间为索引的dataframe结构
series_date = pd.series(3.0, index=date)
pd.to_datetime(series_date)
pd.datetimeindex(series_date)
pandas时间序列series的index必须是datetimeindex
- datetimeindex的属性
- year,month,weekday,day,hour….
time.year
time.month
time.weekday
5.5 pandas生成指定频率的时间序列
- pandas.date_range(start=none, end=none, periods=none, freq='d', tz=none, normalize=false, name=none, closed=none, **kwargs)
- returna fixed frequency datetimeindex, with day (calendar) as the default frequency
- start:开始时间
- end:结束时间
- periods:产生多长的序列
- freq:频率 d,h,q等
- tz:时区
# 生成指定的时间序列
# 1、生成2017-01-02~2017-12-30,生成频率为1天, 不跳过周六周日
pd.date_range("2017-01-02", "2017-12-30", freq="d")
# 2、生成2017-01-02~2017-12-30,生成频率为1天, 跳过周六周日, 能够用在金融的数据,日线的数据
pd.date_range("2017-01-02", "2017-12-30", freq="b")
# 3、只知道开始时间日期,我也知道总共天数多少,生成序列, 从"2016-01-01", 共504天,跳过周末
pd.date_range("2016-01-01", periods=504, freq="b")
# 4、生成按照小时排列的时间序列数据
pd.date_range("2017-01-02", "2017-12-30", freq='h')
# 5、按照3h去进行生成
pd.date_range("2017-01-02", "2017-12-30", freq='3h')
# 6、按照1h30分钟去进行生成时间序列
pd.date_range("2017-01-02", "2017-12-30", freq='1h30min')
# 7、按照每月最后一天
pd.date_range("2017-01-02", "2017-12-30", freq='bm')
# 8、按照每个月的第几个星期几
pd.date_range("2017-01-02", "2017-12-30", freq='wom-3fri')
5.6什么是时间序列分析
对于时间序列类型,有特有的分析方法。同样股票本身也是一种时间序列类型,我们就以股票的数据来进行时间序列的分析
时间序列分析( time series analysis)方法,强调的是通过对一个区域进行一定时间段内的连续观察计算,提取相关特征,并分析其变化过程。
时间序列分析主要有确定性变化分析
- 确定性变化分析:移动平均法, 移动方差和标准差、移动相关系数
5.7 移动平均法
5.7.1 移动窗口
主要用在时间序列的数组变换, 不同作用的函数将它们统称为移动窗口函数
5.7.2 移动平均线
那么会有各种观察窗口的方法,其中最常用的就是移动平均法
- 移动平均线(moving average)简称均线, 将某一段时间的收盘价之和除以该周期
5.7.3 移动平均线的分类
- 移动平均线依计算周期分为短期(5天)、中期(20天)和长期(60天、120天),移动平均线没有固定的界限
- 移动平均线依据算法分为算数、加权法和指数移动平均线
不同的移动平均线方法不一样
1 简单移动平均线
简单移动平均线(sma),又称“算数移动平均线”,是指特定期间的收盘价进行平均化比如说,5日的均线sma=(c1+ c2 + c3 + c4 + c5) / 5
例子:
- 案例:对股票数据进行移动平均计算
拿到股票数据,画出k线图
# 拿到股票k线数据
stock_day = pd.read_csv("./data/stock_day/stock_day.csv")
stock_day = stock_day.sort_index()
stock_day["index"] = [i for i in range(stock_day.shape[0])]
arr = stock_day[['index', 'open', 'close', 'high', 'low']]
values = arr.values[:200]
# 画出k线图
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(20, 8), dpi=80)
candlestick_ochl(axes, values, width=0.2, colorup='r', colordown='g')
2 计算移动平均线
-
pandas.rolling_mean(arg, window, min_periods=none, freq=none, center=false, how=none, **kwargs) moving mean.
parameters:
- arg : series, dataframe
- window : 计算周期
# 直接对每天的收盘价进行求平均值, 简单移动平局线(sma)
# 分别加上短期、中期、长期局均线
pd.rolling_mean(stock_day["close"][:200], window=5).plot()
pd.rolling_mean(stock_day["close"][:200], window=10).plot()
pd.rolling_mean(stock_day["close"][:200], window=20).plot()
pd.rolling_mean(stock_day["close"][:200], window=30).plot()
pd.rolling_mean(stock_day["close"][:200], window=60).plot()
pd.rolling_mean(stock_day["close"][:200], window=120).plot()
3 加权移动平均线 (wma)
加权移动平均线 (wma)将过去某特定时间内的价格取其平均值,它的比重以平均线的长度设定,愈近期的收市价,对市况影响愈重要。
正因加权移动平均线强调将愈近期的价格比重提升,故此当市况倒退时,加权移动平均线比起其它平均线更容易预测价格波动。但是我们还是不会轻易使用加权,应为他的比重过大!!!!
4 指数平滑移动平均线(ewma)
是因应移动平均线被视为落后指标的缺失而发展出来的,为解决一旦价格已脱离均线差值扩大,而平均线未能立即反应,ewma可以减少类似缺点。
pd.ewma(com=none, span=one)
- 指数平均线
- span:时间间隔
# 画出指数平滑移动平均线
pd.ewma(stock_day['close'][:200], span=10).plot()
pd.ewma(stock_day['close'][:200], span=30).plot()
pd.ewma(stock_day['close'][:200], span=60).plot()
5.8 移动方差和标准差
- 方差和标准差:反应某一时期的序列的稳定性
# 求出指定窗口大小的收盘价标准差和方差
pd.rolling_var(stock_day['close'][:200], window=10).plot()
pd.rolling_std(stock_day['close'][:200], window=10).plot()
5.9 各项指标数据两两关联散点图
- pd.scatter_matrix(frame, figsize=none)
- frame:dataframe
frame = data[['open','volume', 'ma20', 'p_change', 'turnover']]
pd.scatter_matrix(frame, figsize=(20, 8))
从中我们可以简单看到成交量(volume)和换手率(turnover)有非常明显的线性关系,因为换手率的定义就是:成交量除以发行总股数。
通过一些图或者相关性分析可以找到强相关的一些指标,在机器学习、量化方向中会详细介绍
相关系数:后面会介绍,目前我们只需知道他是反应两个序列之间的关系即可
5.10 案例:移动平均线数据本地保存
ma_list = [5, 20 ,60]
for ma in ma_list:
data['ma' + str(ma)] = pd.rolling_mean(data.close, ma)
for ma in ma_list:
data['ema' + str(ma)] = pd.ewma(data.close, span=ma)
data.to_csv("ewma.csv")
5.11 移动平均线的作用
移动平均线经常会作为技术分析的基础理论,从中衍生出各种技术指标策略。后面将会介绍简单的基于均线的策略。