木木理财

量化金融笔记1-股票量化基础

2020-08-29  本文已影响0人  折桂狂人

1. 什么是股票

1.1 股票的定义及其诞生所解决的问题

股票的定义:股票是一种有价证券,是股份有限公司公开发行的用以证明投资者的股东身份和权益,并据以获得股息和红利的凭证。

首先回答一个问题:股票的诞生是为了解决什么问题?

企业所有权与经营权分离由此得到解决,经营者可以向社会募集资金发行股票筹钱,股票从而就能够成为对于拥有企业所有权的凭证,所有权即可按照投资者出资即所购买的股本数的多少来分配,从而达成一个双赢的局面。

1.2 股票的主体和流通

资本家(投资者):

企业经营者(专业团队):

企业经营者筹资的机制,即把企业的所有权像切披萨一样,分割成很多很多份(股本):

一级市场:企业经营者首次上市公开发行(IPO),按一定的价格去售卖给投资者。

二级市场:投资者之间相互转卖股票,所交易对象是已经发行过而正在流通的股票。

国内的量化投资和算法交易一般是针对于二级市场,因为二级市场信息比较透明,数据也更结构化,相比之下一级市场能够得到的信息就非常有限。

1.3 股票的常规分类

股票的最常规性的分类,是根据股东所享有的权利的不同,分为普通股优先股

普通股:

优先股(了解即可):

2. 股票价格收益率

2.1 什么是股票价格的收益率

一般比起股票价格的绝对大小,我们更关心的是股票价格的变化及波动情况。我们通常用收益率(Return Rate)来衡量股价的变化。

\color{red}{注}:当我们讨论一个金融资产(如股票)的收益率时,并不是说它给我们的账户带来多少比例的收入,而是指它的价格的涨跌幅(即变化率)。

衡量股票收益率的算法有两种:

  1. 简单收益率
    simple\ return\ rate\ _{t}=\frac{P_t-P_{t-1}}{P_{t-1}} = \frac{P_t}{P_{t-1}}-1

  2. 对数收益率
    log\ return\ rate\ _{t}=ln(\frac{P_t}{P_{t-1}})

其中P_tt时间点的股票价格。

在金融行情数据及软件上看到的涨跌幅,以及日常民间做股票投资所说的收益率,都是股票的简单收益率,但在金融投资方面做数学建模或者做学术研究就要特别关注对数收益率。

2.2 股票价格收益率计算在python中的实现

  1. 简单收益率

1)方法一:pandas.Series.pct_change()

simple_ret = data['close'].pct_change()

2)方法二:pandas.Series.shift()

simple_ret = data['close'] / data['close'].shift(1) - 1

3)方法三:按定义写循环计算

simple_ret = pd.Series(index = data['close'].index, dtype = float)
for i in range(len(simple_ret)):
    if i > 0:
        simple_ret[i] = data['close'][i] / data['close'][i-1] - 1

4)方法四:用Numpy数值向量化计算

close_array = data['close'].values
simple_ret = close_array[1:] / close_array[:-1] - 1
  1. 对数收益率

方法:直接用Numpy数值向量化计算

close_array = data['close'].values
log_ret = np.log(close_array[1:] / close_array[:-1])

一些关于收益率写程序计算的小结:

  1. 循环计算非常慢,在用python进行数值计算时能不用循环就不用循环,尽量用向量化运算

  2. pandas的数据结构为了便利性牺牲了性能,因此当要进行重度数值运算时,推荐优先用numpy,不用pandas直接内设的函数

运行效率快有什么用?仅仅就是省几毫秒的运行时间?
其一,当你要跑策略回测的时候,几乎每根K线都要跑同样的运算,假设我们只考虑一只股票,10年的日数据,那也得跑2250次(10*225=2250) ,如果我的策略要考虑上千只股票呢?如果我要做分钟数据呢?

其二,当你要做高频策略实盘时,比别人慢几微秒可能就抢不到单了。(注:不是人写程序写的快,而是程序运行的效率高)

2.3 两种收益率算法的特点及应用场合

简单收益率的特点:

(1) 简单直观

金融行情数据一般都是用简单收益率

(2) 截面可加性

即对于给定单期时间区间t-1到t,有n个金融资产(如股票)的简单收益率分别为r_{t}^{(1)},r_{t}^{(2)},...,r_{t}^{(n)}

对于这n个资产按\omega_1,\omega_2,...,\omega_n,(\sum_{i=1}^{n}\omega_{i}=1)的比例的投资组合W

其简单收益率就直接是n个资产简单收益率的线性加权之和:

r_{t}^{(W)}=\sum_{i=1}^{n}\omega_{i}r_{t}^{(i)}

\color{red}{注}:对数收益率就没有截面可加性的特征。

(3)时间序列不可加性

如资产组合第一天的简单收益率为1%,第二天的简单收益率为-1%,则不可将这两天每天的简单收益率去加总取平均,然后去得出这两天的简单收益率为0的结论,实际上这种情况是有亏损的。

对数收益率的特点

(1) 时间序列可加性

对于特定资产W,其0到T期各期的的对数收益率分别为

r_{1,0}=ln(\frac{P_1}{P_0}),

\cdots

r_{t,t-1}=ln(\frac{P_{t}}{P_{t-1}}),

\cdots

r_{T,T-1}=ln(\frac{P_{T}}{P_{T-1}})

则资产0到T期的对数收益率可为期间各期的对数收益率之和:

r_{0,T}=ln(\frac{P_{T}}{P_0})=\sum_{i=1}^{T}ln(\frac{P_t}{P_{t-1}})=\sum_{i=1}^{T}r_{t,t-1}

\color{red}{注:}简单收益率没有时间序列可加性。

(2) 截面不可加性

(3) 若资产价格服从对数正态分布(一般对金融资产会有这样的假定),则可以推出资产的对数收益率服从正态分布

综合以上特性:

  1. 在一般的金融投资建模、考虑多期收益率时,用对数收益率;

  2. 描述投资组合单期的区间收益率,用简单收益率。

3. 股票交易规则

3.1 场内交易与场外交易

场内交易

证券交易所:设有固定场地、北邮各种服务设施(如行情板、电视屏幕、电子计算机、电话、电传等等),配备了必要的管理和服务人员,集中进行股票和其他证券买卖的场所。

场外交易

3.2 A股、B股、H股

我国的上市公司的股票有A股,B股,H股等的区分,这一区分主要是依据股票的上市地点和所面对的投资者而定。

  1. A股:正式名称为人民币普通股股票。它是由我国境内的公司发行、供境内机构、组织或个人(不含港澳台投资者)以人民币认购和交易的普通股股票。

  2. B股:正式名称为人民币特种股票。它是以人民币标明面值,以外币认购和买卖,在境内(上海深圳)证券交易所上市交易额的股票。在2001年2月前,B股的投资人仅限于:外国的自然人、法人和其他组织,港澳台地区的自然人、法人和其他组织,定居在国外的中国居民,以及中国证监会规定的其他投资人。2001年2月19日之后,中国证监会宣布对内开放B股市场,准许持有合法外汇的境内居民自由开户买卖B股。

  3. H股:指注册地在内地、上市地在香港的中资企业股票。H股为实物股票,实行“T+0”交割制度、无涨跌幅限制。中国大陆地区机构投资者和个人投资者均可以投资H股,但大陆地区个人投资者证券账户和资金账户之和需超过50万元。

在大陆进行股票的量化交易,主要是针对在上海证券交易所和深圳证券交易所上市的A股

3.3 国内多层次的资本市场

资本市场的层次结构:指资本市场根据企业在不同发展阶段的融资需求和融资特点,针对各种市场主体不同的、特定需求,提供的具有不同内在逻辑次序、不同服务对象和不同内在特点的市场形式。一般来说是个比较中国化的概念。

我国资本市场体系结构表现为:

场内市场:(风险从上到下逐渐递增)

(1) 主板市场

(2) 中小板市场

(3) 创业板

(4) 科创板

(5) 新三板市场(全国股权转让系统)

场外市场:

3.4 股票交易指令和撮合机制

交易指令:

(1)买入:

支出现金,按成交价格\times股数,买入股票。

(2)卖出:

按成交价格\times股数,卖出股票换回现金。

订单类型:

(1)市价:

不考虑价格,直接按市场上存在的最优价买入/卖出股票。成交速度快,但往往交易成本高。

(2)限价:

指定期望成交的价格,不一定能很快成交,但能够保证成交的价格等于或优于指定价格。

撮合机制:

3.5 股票交易时间

Atrader库中的get_trading_days()函数可获得一个市场在一个时段内的交易日列表。

示例:

import atrader as at
# 获取上交所2018-01-01至2018-01-06的交易日期列表
trad_days = at.get_trading_days(market = 'sse', begin_date = '2018-01-01', end_date = '2018-01-06')
print(trad_days)

输出结果如下:

stock_base_1.png

3.6 股票交易成本

对于量化交易,股票的交易成本是一个重点需要纳入考虑的因素。

交易手续费:

交易手续费,是在股票交易时需要支付的款项,包括:

(1)券商交易佣金:

最高为成交金额的3‰,最低5元起,单笔交易佣金不满5元按5元收取。

(2)印花税:

成交金额的1‰,向卖方单边征收。

(3)过户费:

每1000股收取1元,不足1000股则按1元收取。(仅上交所收取)

(4)监管费:

约为成交金额的0.2‰

滑点-市场冲击成本:

短时间内在市场上进行大规模的交易,会把市场价格往对自己不利的一边推动,进而会增加交易成本。

3.7 股票复权

复权是个股票交易中,容易出错或者遗漏的地方。对于股票送转除权(配股、转增)、或者除息后,股价随之产生了变化,但股票的实际成本并没有发生变化。

如:某上市公司于某日进行预案公告日会进行分红,除权除息前股价为每股33.20元。在派息日每10股派现金分红6元,每10股送转10股,则派息日之后股票的价格变为:
配(新)股价格=(33.20-6÷10)×\frac{10}{10+10}=15.80
在分红之后,投资者账户中的股票数和账户金额也变化使得持有资产的总市值不变,所以在派息日股价从33.20元变到15.80元不意味着是使投资者巨额亏损的现象,所以不能以分红后的每股15.80元和分红前的33.20元跨分红期来计算这段时间的收益率,均线,MACD等指标。

跨分红期,不复权的股票价格行情图:

stock_base_2.png

因此在需要计算有跨分红期的时间段的收益率等指标时,需要对股票价格进行复权的操作。

复权:就是对股价和成交量进行权息修复,按照股票的实际涨跌绘制股价走势图,并把成交量调整为相同的股本口径。

股票复权的算法,有前复权后复权两种。

前复权:即向前复权,就是保持现有的价位不变,将以前的价格缩减,将除权除息之前的K线向下平移,时K线图形连贯吻合,保持股价走势的连续性。

前复权后价格=[(复权前股价-现金红利)+配(新)股价格×流通股份变动比例]÷(1+流通股份变动比例)

跨分红期,做前复权后的股票价格行情图:


stock_base_3.png

后复权:即后向复权,保持先前的价格不变,而将以后的价格增加向上平移。
后复权后价格=复权前股价×(1+流通股份变动比例)-配(新)股价格×流通股份变动比例+现金红利

跨分红期,做后复权后的股票价格行情图:

stock_base_3.png

前复权以当前股价为基数,后复权以上市价为基数。

小结:

4. 股票数据介绍与提取

4.1 行业分类和指数

行业分类

行业分类有两大类别,分别是申万行业分类以及证监会行业分类,其中申万行业分类涵盖3级分类,证监会行业分类涵盖2级分类。

通过Atrader软件可通过get_code_list函数接口获取行业代码及特定行业的成分股。

get_code_list - 获取指数行业成分股和权重

stock_base_14.png

案例:

1)获取申万行业和证监会行业分类的所有行业类别的代码:

import atrader as at
dfCode = at.get_code_list(‘plate_industry’)
dfCode.head()

运行结果如下:


stock_base_5.png

2)根据行业AT代码对照表的行业简称字段获取行业的成分股数据,如获取三级分类:申万白酒(’SWBJ3')行业的成分股有哪些:

import atrader as at
dfCode = at.get_code_list('SWBJ3')
print(dfCode)

运行结果如下,以下这些成分股就是当前被申万行业分类归类在三级分类白酒中:

stock_base_6.png

AT中提供的行业板块划分数据说明,详见:http://www.digquant.com.cn/document下的“行业”模块。

指数

股票价格指数:简称股指,是基于报告期的一组股票价格与基期的一组股票价格进行平均计算和动态对比后得出的。反映一个国家或地区、某一行业或主题的股票市场价格水平及其变动趋势的动态相对数。

同样,通过Atrader软件可通过get_code_list函数接口获取股票指数列表及特定股指的成分股信息。

案例:

1)获取Atrader库中所有股指的基本信息:

import atrader as at
dfIndex = at.get_code_list('index')
print(dfIndex)

运行结果如下:

stock_base_7.png

2)获取“沪深300(hs300)”股指的成分股信息及权重:

import atrader as at
hs300 = at.get_code_list('hs300')
print(hs300.head())

运行结果如下:

stock_base_8.png

AT中提供的股票指数数据说明,详见:http://www.digquant.com.cn/document下的“指数”模块。

4.2 行情数据

股票行情数据,包括K线Tick数据。

K线

K线:又称“蜡烛线”,是反映价格走势的一种图线,其特色在于一个线段内记录了多项讯息,一个完整的K线,包括一段个时间段内(可以是几分钟,一小时,一天,一周,一个月甚至一年)的最高价、最低价、开盘价和收盘价,相当易读易懂且实用有效,广泛用于股票、期货、贵金属、数字货币等行情的技术分析。

stock_base_9.png

Atrader中,提供get_kdata,get_kdata_n函数接口来获取历史K线行情数据。

get_kdata - 获取历史行情数据

stock_base_10.png

案例:

1)获取平安银行股票(szse.000001)2020年01月01日至2020年07月30日的日行情数据:

import atrader as at
dfData = at.get_kdata(target_list = ['szse.000001'], 
                      frequency = 'day', 
                      fre_num = 1, 
                      begin_date = '2020-01-01',
                      end_date = '2020-07-30',
                      fq = 1,
                      fill_up = False, 
                      df = True,
                      sort_by_date = False)
print(dfData.head())

运行结果如下:

stock_base_11.png

2)获取平安银行股票(szse.000001)和贵州茅台(sse.600519)的2020年07月01日至2020年07月31日的30min行情数据:

import atrader as at
targets = ['szse.000001','sse.600519']
dfData = at.get_kdata(target_list = targets, 
                      frequency = 'min', 
                      fre_num = 30, 
                      begin_date = '2020-07-01', 
                      end_date ='2020-07-31',
                      fq = 1,
                      fill_up = False,
                      df = True,
                      sort_by_date = False)
print(dfData.head())

运行结果如下:

stock_base_12.png

get_kdata_n - 获取n个历史行情数据

stock_base_13.png

案例:

1)获取平安银行股票(szse.000001)2019年08月20日往前算10个交易日的日行情数据:

import atrader as at
dfData = at.get_kdata_n(target_list = ['szse.000001'],
                      frequency = 'day', 
                      fre_num = 1, 
                      n = 10, 
                      end_date = '2020-08-20', 
                      fill_up = False, 
                      df = True, 
                      fq = 1)
print(dfData)

运行结果如下:

stock_base_15.png

Tick数据

维基百科中对Tick数据的描述:

Tick data is the most granular high-frequency data available, and so is the most useful in market microstructure analysis. Unfortunately, tick data is also the most susceptible to data corruption and so must be cleaned and conditioned prior to being used for any type of analysis.

Atrader中提供get_tick_data函数查询单个标的单天的tick数据。

get_tick_data - 查询tick数据

stock_base_16.png

\color{red}{注}:对于get_tick_data,只能选取一只股票,且只能选一天日期,频率固定为3秒。

案例:

1)获取平安银行股票(szse.000001)2020年07月30日的高频tick行情数据

import atrader as at
dfData = at.get_tick_data(code = 'szse.000001', 
                          date = '2020-07-30', 
                          fq = 0, 
                          df = True)
print(dfData.head())

运行结果如下:

stock_base_17.png

AT中提供的股票行情数据说明,详见:http://www.digquant.com.cn/document下的“股票”模块。

4.3 因子数据

多因子模型:资产的收益率由特定的多个因子所决定,是关于资产定价的模型。与资本资产定价模型和单指数模型不同,多因子模型认为证券价格并不仅仅取决于证券的风险,还取决于其他一些因素,如,投资者未来预期收入、未来消费品的相对价格及未来的投资机会等。

如:APT模型,描述股票的收益率跟多个因子有线性关系的影响:

r_i=\alpha_i+\sum_{k=1}^{K}\beta_{ik}F_k+\epsilon_i

在Atrade软件中,BP股票量化因子库是数字动能(Bitpower)量化研究部根据上市公司财务报表,交易行情计算而成。

股票因子包含了基础科目衍生类、质量类、收益风险类、情绪类、成长类、常用技术指标类、动量类、价值类、每股指标类、模式识别类、特色技术指标、行业与分析师类共十二大类共500多个因子。投资者可以直接通过这些因子进行单因子分析和研究,同样也可以在策略回测中使用。

因子分类介绍如下:

因子数据一般包括三个维度:股票、因子和日期。在Atrader库中,从股票、因子、日期中,控制好一个维度即在一个维度中取特定对象,可在另外两个维度延伸得到一个界面来获取因子数据。

stock_base_18.png

get_factor_by_code - 获取BP因子数据(单个股票)

对于选定一个股票,获取其在一段时间内多个因子的数据

stock_base_19.png

案例:

1)获取平安银行(‘szse.000001’)2018年1月1日至2019年8月30日的市盈率(‘PE’)和市净率(‘PB’)因子数据:

import atrader as at
dfData = at.get_factor_by_code(factor_list = ['PE','PB'], 
                               target = 'szse.000001', 
                               begin_date = '2018-01-01', 
                               end_date = '2019-08-30')
print(dfData.head(10)) 

运行结果如下:

stock_base_20.png

get_factor_by_day - 获取BP因子数据(单天)

给定特定单天日期,获取多个股票,多个因子的数值


stock_base_22.png

案例:

1)获取平安银行(‘szse.000001’)和浦发银行(‘sse.600000’)2019年8月30日的市盈率(‘PE’)和市净率(‘PB’)因子数据:

import atrader as at
dfData = at.get_factor_by_day(factor_list = ['PE', 'PB'], 
                              target_list = ['szse.000001','sse.600000'], 
                              date = '2019-08-30')
print(dfData)

运行结果如下:


stock_base_23.png

get_factor_by_factor - 获取BP因子数据(单个因子)

给定单个因子,获取一段时间,多标的的该因子数据

stock_base_24.png

案例:

1)获取平安银行(‘szse.000001’)和浦发银行(‘sse.600000’)2018年1月1日至2019年8月30日的市盈率(‘PE’)因子数据:

import atrader as at
dfData = at.get_factor_by_factor(factor = 'PE', 
                                 target_list = ['szse.000001','sse.600000'], 
                                 begin_date = '2018-01-01', 
                                 end_date='2019-08-30')
print(dfData.head(10))

运行结果如下:

stock_base_25.png

具体的因子库信息及获取详见:http://www.digquant.com.cn/document下的“因子”模块。

4.4 标的数据

在Atrader中,可以用get_stock_info函数接口获取一串股票标的的基本信息。

get_stock_info - 查询股票标的基本信息

查询股票类型标的基本信息

stock_base_26.png

案例:

1)获取平安银行('szse.000001')和浦发银行('sse.600000')标的的基本信息:

import atrader as at
target_list = ['szse.000001', 'sse.600000']
data = at.get_stock_info(target_list = target_list)
print(data)

运行结果如下:

stock_base_27.png

得到股票的标的信息包括:代码信息,一手对应多少股,上市时间,退市时间(未退市则没有),证券类型和所在交易所代码。

4.5 基本面数据

上市公司股票的基本面数据,包括财务报表数据行情衍生数据公司行为数据

财务报表数据

在Atrader软件中,可以通过调用对应库的函数接口,获取以下四类库的财务报表数据:

  1. bs-资产负债表

资产负债表:表示企业在一定日期(通常为各会计期末)的财务状况(即资产、负债和业主权益的状况)的主要会计报表。

  1. cs-现金流量表

现金流量表:是指反映企业在一定会计期间现金和现金等价物流入和流出的报表。现金,是指企业库存现金以及可以随时用于支付的存款。现金等价物,是指企业持有的期限短、流动性强、易于转换为已知金额现金、价值变动风险很小的投资。

  1. ins-利润表

利润表:是用以反映公司在一定期间利润实现(或发生亏损)的财务报表。它是一张动态报表。利润表可以为报表的阅读者提供作出合理的经济决策所需要的有关资料, 可用来分析利润增减变化的原因, 公司的经营成本, 作出投资价值评价等。

  1. indicator-财务指标

财务指标:指收集传达财务信息,说明资金活动,反映企业生产经营过程和成果的经济指标。是可以通过企业的财务报告中的数据计算的指标。

财务报表数据获取详见:http://www.digquant.com.cn/document下的“财务报表数据”模块。

行情衍生数据

在Atrader软件中,可以通过调用对应库的函数接口,获取以下六类库的股票行情衍生数据:

  1. 涨跌停幅度变动
  2. 个股日资金流向
  3. 股票_龙虎榜
  4. 新股上市连板天数
  5. 次新股日行情
  6. 沪深大宗交易

行情衍生数据获取详见:http://www.digquant.com.cn/document下的“行情衍生数据”模块。

公司行为数据

在Atrader软件中,可以通过调用对应库的函数接口,获取以下四类库的公司行为相关数据:

  1. 基本信息
  2. 人员信息
  3. 融资投资和分红
  4. 重大事项

公司行为数据获取详见:http://www.digquant.com.cn/document下的“公司行为数据”模块。

上一篇 下一篇

猜你喜欢

热点阅读