1. 量化交易简介
1.1 量化交易的历史
➢ 全球量化交易的发展历史:
- 量化投资的产生(60年代):1969年,爱德华·索普利用他发明的“科学股票市场系统”(实际上是一种股票权证定价模型),成立了第一个量化投资基金。索普也被称之为量化投资的鼻祖。
- 量化投资的兴起(70~80年代):1988年,詹姆斯·西蒙斯成立了大奖章基金,从事高频交易和多策略交易。基金成立20多年来收益率达到了年化70%左右,除去报酬后达到40%以上。西蒙斯也因此被称为"量化对冲之王"。[计算机、金融专业和数学等专业]
- 量化交易的繁荣(90年代):991年,彼得·穆勒发明了alpha系统策略等,开始用计算机+金融数据来设计模型,构建组合。
➢ 国内量化交易的发展历史:
- 量化投资元年:2010年,沪深300股指期货上市,此时的量化基金终于具备了可行的对冲工具,各种量化投资策略如alpha策略、股指期货套利策略才真正有了大展拳脚的空间,可以说2010年是中国量化投资元年。
- 量化投资高速发展、多元化发展:2013-2015年股指新政之前可以说是国内量化基金有史以来最风光的一段时期。国内量化投资机构成批涌现,国内量化投资高速发展。
2012年到2016年量化对冲策略管理的资金规模增长了20倍,管理期货策略更是增长了30倍,增长的速度是所有策略中最快的。相比美国量化基金发展历程,中国现在基本处于美国90年代至21世纪之间的阶段。
1.2 什么是量化交易
量化交易(量化投资)是借助现代统计学和数学(机器学习)的方法,利用计算机技术来进行交易的证券投资方式。学习量化交易,我们需要掌握:金融策略、挖掘技术和计算机技术。
量化交易从庞大的历史数据中海选能够带来超额收益的多种“大概率”事件以指定策略,用数量模型验证及固化这些规律和策略,然后严格执行已固化的策略来指导,以求获得可持续的、稳定且高于平均收益的超额回报。
1.3 量化交易分类
- 趋势性交易:适合一些主观交易的高手,用技术指标作为辅助工具在市场中如鱼得水的,但如果只用各种技术指标或指标组合作为核心算法构建模型,从未见过能长期盈利的。一般也会做一些量化分析操作,使用编程如 Python/matlab 。适合金融专业出生的,对财务、金融市场非常了解,如交易员、基金经理等。
- 市场中性: 在任何市场环境下风险更低,收益稳定性更高,资金容量更大。适合一些量化交易者,发现市场中的alpha因子赚取额外收益,例如股票与股指期货的对冲策略等。会做一些量化分析操作,使用编程如 Python/matlab。适合计算机出生,擅长编程、机器学习、数据挖掘技术(量化分析),真正的量化交易人员。
- 高频交易:在极短的时间内频繁买进卖出,完成多次大量的交易,此类交易方式对硬件系统以及市场环境的要求极高,所以只有在成熟市场中的专业机构才会得到应用。适合一些算法高手,使用C/C++ 编程语言去进行算法交易,对软硬件条件要求比较高。
1.4 金融产品及衍生品的投资策略
- 股票:市场中性投资占大多数、涉及少量的趋势性交易
- 期货:趋势性策略占大多数(期货不属于金融产品)
1.5 量化交易的优势
- 严格的纪律性
- 完备的系统性:首先表现在多层次,包括在大类资产配置、行业选择、精选个股三个层次上我们都有模型;其次是多角度,量化交易的核心投资思想包括宏观周期、市场结构、估值、成长、盈利质量、分析师盈利预测、市场情绪等多个角度;再者就是多数据,就是海量数据的处理。人脑处理信息的能力是有限的,当一个资本市场只有100只股票,这对定性投资基金经理是有优势的,他可以深刻分析这100家公司。但在一个很大的资本市场,比如有成千上万只股票的时候,强大的定量化交易的信息处理能力能反映它的优势,能捕捉更多的投资机会,拓展更大的投资机会。
- 数学模型取胜:股票实际操作过程中,运用概率分析,提高买卖成功的概率
- 股票的量化投资可以说是一种价值投资(价值投资是很多量化公司、基金公司所推崇的),我们所做的也是去挖掘市场中的价值股票,而并非去预测股票涨跌来进行投资等等(至少目前机构不会采取这种方式指导投资),这需要大家明确的一个问题。其实,由于中国散户太多,有些公司本身公司不怎么样,但股票也涨得很厉害。美国的量化投资稳定一些,主要是因为美国几乎没有什么个人投资者,他们都是找一些基金公司代理去做投资。
- 最终量化分析是众多投资机构的工具、分析手段而已。
1.6 如何做量化交易项目
量化投资涵盖整个交易流程,需要一个完整的作为研究的量化回测框架和实盘交易系统作为支撑。
➢ 量化交易研究流程
量化回测框架提供完整的数据,以及回测机制进行策略评估研究,并能够实时进行模拟交易,为实盘交易提供选择,我们的研究一般在回测平台中做。
- 获取数据:行情数据、基本面数据
- 数据挖掘:这部分很重要,大多数在公司会做这个部分。需要用到机器学习算法、特征工程等来分析结果,指导我们的策略。
- 构建策略
- 策略回测
- 策略分析:策略不是一直有效的,基金公司频繁去分析数据、挖掘数据,更新策略。
- 模拟交易
- 实盘交易
➢ 什么是量化策略
量化策略是指使用计算机作为工具,通过一套固定的逻辑来分析、判断和决策。 量化策略既可以自动执行,也可以人工执行。其实策略也可以理解为,分析数据之后,决策买什么以及交易时间。
➢ 流程包含的内容
- 获取数据:公司财务、新闻数据;基本行情数据。
- 数据分析与挖掘:传统分析方法、机器学习,数据挖掘方法;数据处理,标准化,去极值,中性化分组回测,行业分布。
- 构建策略:获取历史行情,历史持仓信息,调仓记录等;止盈止损单,限价单,市价单。
- 回测:股票涨跌停、停复牌处理;市场冲击,交易滑点,手续费。
- 策略分析:订单分析,成交分析,持仓分析。
- 模拟交易:接入实时行情,实时获取成交回报;实时监控,实时归因分析。
- 实盘交易:接入真实券商账户。
➢ 量化开发和研究岗位要求
- 基于交易市场数据,研究、开发交易策略,进行基础建模
- 负责对交易策略进行回测、跟踪、分析、优化
- 定期对交易策略的运行结果进行总结,给出分析报告,评估市场适用度
- 负责数据挖掘、处理,数据统计分析,从数据中发现规律,为量化分析提供支持,开发量化模型策略
- 与基金经理合作跟踪优化股票市场量化策略在实盘的表现
2. 量化回测框架介绍
2.1 回测框架介绍
➢ 基础回测框架
Zipline是一个Pythonic算法交易库,这是一个支持回测和现场交易的事件驱动系统。目前,Zipline被用于生产后测和实时交易引擎,为Quantopian提供动力。是一个免费的,以社区为中性的托管平台。Zipline本身只支持美国的证券,如果我们用需要改很多东西。
➢ 云端的框架
- 提供部分满足需求的数据(但是平台数据质量不行,指标不完整)
- 策略运行在远端服务器
➢ 不去实现一个回测框架的原因
- 没有完整的股票行情和基本面数据
- 回测平台是载体,重点在于快速验证策略
- 证券投资机构各自使用回测框架不同,没有通用的框架
➢ RiceQuant回测平台介绍
2.2 策略创建运行的流程
➢ 一个完整的策略需要做的事情
- 选择策略的运行信息:选择运行区间和初始资金,选择回测频率,选择股票池
- 编写策略的逻辑:获取股票行情、基本面数据
- 分析结果:策略指标分析
➢ 策略初始设置
- 基础设置:指定回测的起止日期、初始资金和回测频率。起止日期是策略运行的时间区间;初始资金是用于投资的总资金;回测的频率有两种选择,日回测和分钟回测(对于市场中性,判断周期可能更长,一个月等)。做股票量化选择日回测即可。
- 高级设置:略
➢ 策略主体运行流程分析
- 在init函数中实现策略初始化逻辑,策略的股票池:在哪些股票中进行交易判断(例如:HS300)
- 可以选择在before_trading函数进行一些每日开盘之前的操作,比如获取历史行情做一些数据预处理,获取当前账户资金等。
- 在handle_bar函数中实现策略具体逻辑,包括交易信号的产生、订单的创建。handle_bar内的逻辑会在每次bar数据更新的时候被触发。
运行顺序:在运行策略时首先运行init函数,但只运行一次。before_trading和handle_bar函数每日都会被调用,每日交易之前首先运行before_trading,然后再运行handle_bar函数进行每日的交易的判断。
2.3 数据获取接口
➢ 数据接口的种类
- 指定行业、板块股票列表
- 指定股票合约历史数据 [ history_bars ]
- 查询财务数据[ get_fundamentals ]
➢ 获取行业股票列表
以获取餐饮业的股票列表为例:
def init(context):
# 获取餐饮业股票列表
context.catering_stock_list = industry('H62')
def before_trading(context):
# 打印股票列表
print(context.catering_stock_list)
def handle_bar(context, bar_dict):
# 主要的算法逻辑
pass
打印出餐饮业股票列表:
2019-12-02 INFO ['000721.XSHE', '002306.XSHE', '002186.XSHE']
2019-12-03 INFO ['000721.XSHE', '002306.XSHE', '002186.XSHE']
2019-12-04 INFO ['000721.XSHE', '002306.XSHE', '002186.XSHE']
2019-12-05 INFO ['000721.XSHE', '002306.XSHE', '002186.XSHE']
2019-12-06 INFO ['000721.XSHE', '002306.XSHE', '002186.XSHE']
2019-12-09 INFO ['000721.XSHE', '002306.XSHE', '002186.XSHE']
2019-12-10 INFO ['000721.XSHE', '002306.XSHE', '002186.XSHE']
➢ 获取板块股票列表
以获取能源板块列表为例:
def init(context):
# 获取能源板块列表
context.energy_sector_list = sector("Energy")
def before_trading(context):
# 打印能源板块列表
print(context.energy_sector_list)
def handle_bar(context, bar_dict):
# 主要的算法逻辑
pass
打印能源板块列表:
2019-12-02 INFO ['600688.XSHG', '600397.XSHG', '600777.XSHG', '002353.XSHE', '000059.XSHE', '300309.XSHE',
'000937.XSHE', '600028.XSHG', '000159.XSHE', '600583.XSHG', '000968.XSHE', '600871.XSHG', '000552.XSHE',
'600792.XSHG', '603727.XSHG', '002554.XSHE', '601666.XSHG', '603113.XSHG', '002207.XSHE', '601101.XSHG',
'600508.XSHG', '600989.XSHG', '300164.XSHE', '002278.XSHE', '000780.XSHE', '600123.XSHG', '600725.XSHG',
'600759.XSHG', '300191.XSHE', '000406.XSHE', '600997.XSHG', '603800.XSHG', '600403.XSHG', '002018.XSHE',
'600971.XSHG', '600065.XSHG', '000763.XSHE', '600387.XSHG', '002629.XSHE', '300157.XSHE', '300471.XSHE',
'601898.XSHG', '601798.XSHG', '603036.XSHG', '000956.XSHE', '600740.XSHG', '600758.XSHG', '600188.XSHG',
'600968.XSHG', '603798.XSHG', '603619.XSHG', '002128.XSHE', '601808.XSHG', '000698.XSHE', '600002.XSHG',
'002828.XSHE', '300084.XSHE', '600395.XSHG', '000852.XSHE', '000983.XSHE', '000096.XSHE', '600772.XSHG',
'601015.XSHG', '600256.XSHG', '601857.XSHG', '601699.XSHG', '000817.XSHE', '000723.XSHE', '002259.XSHE',
'002221.XSHE', '002490.XSHE', '000866.XSHE', '000571.XSHE', '600348.XSHG', '601088.XSHG', '600121.XSHG',
'601918.XSHG', '000554.XSHE', '601001.XSHG', '300540.XSHE', '601011.XSHG', '000637.XSHE', '601225.XSHG']
➢ 获取指数成分股
一般很少选择使用某个行业或某个板块的股票,这些板块的股票很可能不是很好。我们要投的是一些前景比较好的公司,所以我们选择指数成份股票。股票成份股是实时更新的,
常见的指数成分股有:
"000001.XSHG" # 上证A股
"000300.XSHG" # HS300,沪深300
"000905.XSHG" # ZZ500,中正500
"000016.XSHG" # SZ50,深圳50
以中正500为例获取中正500的股票列表:
def init(context):
# 获取中正500股票列表
context.zz500_index_components_list = index_components("000905.XSHG")
def before_trading(context):
# 打印中正500股票列表
print(context.zz500_index_components_list)
def handle_bar(context, bar_dict):
# 主要的算法逻辑
pass
打印中正500的股票列表:
2019-12-03 INFO ['000587.XSHE', '600008.XSHG', '002157.XSHE', '601958.XSHG', '002589.XSHE', '600307.XSHG',
'601127.XSHG', '600416.XSHG', '600169.XSHG', '002500.XSHE', '600750.XSHG', '000488.XSHE', '603877.XSHG',
'002390.XSHE', '603556.XSHG', '600939.XSHG', '600642.XSHG', '002503.XSHE', '600037.XSHG', '601005.XSHG',
'601699.XSHG', '000552.XSHE', '600183.XSHG', '600694.XSHG', '002670.XSHE', '000559.XSHE', '600820.XSHG',
'601777.XSHG', '600280.XSHG', '002583.XSHE', '000686.XSHE', '002635.XSHE', '601866.XSHG', '000600.XSHE',
'300316.XSHE', '603868.XSHG', '600874.XSHG', '603501.XSHG', '000869.XSHE', '601615.XSHG', '600598.XSHG',
'002131.XSHE', '000727.XSHE', '600884.XSHG'