【转】用Python做股市量化策略投资数据分析

金融量化分析介绍

 


金融量化分析介绍

  • 1、什么是金融量化分析

  • 2、金融量化分析可以干什么

  • 3、为什么将python运用于金融

  • 4、常用库简介

1、什么是金融量化分析

  从标题中我们可以简单的分析一下这个题目中的关键词,金融、量化、分析,接下来一个一个分析:

 

金融:金融是什么相信在大多数人心中都是比较神秘、高大上的,需要大量的资金与丰富的经验才可以在股市叱咤风云,也确实金融行业的风险非常大,任何人都不敢保证某一只股票的走向或者说是收益与否。金融其实与赌博很类似,但是为什么政府会禁止赌博而不禁止金融呢?这是因为金融行业的发展对国家经济是有好处的,而赌博单纯只是满足个人欲望,对经济发展一点好处都没有,就比如说:现在有个非常有想法的创业者,但是他没有资金,这个时候一个亿万富翁给他投资,经过一段时间的发展公司上市了,那创业者是不是就有钱了,而投资者的资产是不是也提升了,这就是通过金融的方式让资产进行流通。就算一个国家的人再有钱,但是他们都把钱存在地窖里,不生产不流通,那这个国家的整体经济一定不景气,所以说国家一定会大力发展经济。但是一定要记住一点,金融行业的风险很大。

量化:在这里量化也可以说是量化投资或是量化交易。刚才有介绍金融,金融行业最注重的就是投资和交易了,但是在之前都是通过人的一个主观判断和针对市场方面的一些分析做出的投资,但是有时候人的判断并不一定就是对的,有时候还会被自己的个人情绪所影响,所以说这个时候量化投资横空出世,通过数字化以及计算机技术通过相应的策略实现一种相对稳定的交易方式。

分析:结合本章所有内容来看,分析就是指的数据分析,只不过我们这个数据分析针对的金融方面的数据。当然只要我们学会这些数据分析的手段到时候无论是金融方面的数据还是其他任何行业的数据都可以手到擒来。

数据分析:

 数据分析

专业点来说金融量化分析主要是指以先进的数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据当中选出能够带来超额收益的多种“大概率”事件以此来指定策略。主要就是以下几步:

1、发现的一种能够赚钱的规律

2、将规律分解成可操作的步骤(策略)

3、编写程序,让机器去执行这个策略

4、机器返回结果,或者说是让机器直接实现自动化交易

2、金融量化分析可以干什么

  相信大家都经常会使用百度、谷歌等之类的搜索引擎搜索我们想了解的问题,它就会从庞大的数据库当中找到你想要了解的问题,但是你要是直接去问它,我该怎么投资?我到底该买哪一支股票?什么股票可以挣钱?这样的问题会有答案吗,肯定是不会的,所以说金融量化的任务就是类似于这些搜索引擎的功能,它会通知你今天应该买什么,今天应该卖什么,当然如果有需求完全可以进行自动化交易。

那具体能干什么简单总结了几点:

1、可以帮你在几千只A股当中选择符合要求条件的股票

2、选择买进、卖出、以及平仓的时机

3、管理仓位风险

4、不会受到个人情绪影响

 

 

 

本文由 伯乐在线 - 小米云豆粥 翻译。未经许可,禁止转载!
英文出处:Curtis Miller。欢迎加入翻译组

这篇博文是用Python分析股市数据系列两部中的第一部,内容基于我犹他大学 数学3900 (数据科学)的课程。在这些博文中,我会讨论一些基础知识。比如如何用pandas从雅虎财经获得数据, 可视化股市数据,平局数指标的定义,设计移动平均交汇点分析移动平均线的方法,回溯测试, 基准分析法。最后一篇博文会包含问题以供练习。第一篇博文会包含平局数指标以及之前的内容。

注意:本文仅代表作者本人的观点。文中的内容不应该被当做经济建议。我不对文中代码负责,取用者自己负责。

引言

金融业使用高等数学和统计已经有段时日。早在八十年代以前,银行业和金融业被认为是“枯燥”的;投资银行跟商业银行是分开的,业界主要的任务是处理“简单的”(跟当今相比)的金融职能,例如贷款。里根政府的减少调控和数学的应用,使该行业从枯燥的银行业变为今天的模样。在那之后,金融跻身科学,成为推动数学研究和发展的力量。例如数学上一个重大进展是布莱克-舒尔斯公式的推导。它被用来股票定价 (一份赋予股票持有者以一定的价格从股票发行者手中买入和卖出的合同)。但是, 不好的统计模型,包括布莱克-舒尔斯模型, 背负了部分导致2008金融危机的骂名。

近年来,计算机科学加入了高等数学的阵营,为金融和证券交易(为了盈利而进行的金融产品买入卖出行为)带来了革命性的变化。如今交易主要由计算机来完成:算法能以人类难以达到的速度做出交易决策(参看光速的限制已经成为系统设计中的瓶颈)。机器学习和数据挖掘也被越来越广泛的用到金融领域中,目测这个势头会保持下去。事实上很大一部分的算法交易都是高频交易(HFT)。虽然算法比人工快,但这些技术还是很新,而且被应用在一个以不稳定,高风险著称的领域。据一条被黑客曝光的白宫相关媒体推特表明HFT应该对2010 闪电式崩盘 and a 2013 闪电式崩盘 负责。

不过这节课不是关于如何利用不好的数学模型来摧毁证券市场。相反的,我将提供一些基本的Python工具来处理和分析股市数据。我会讲到移动平均值,如何利用移动平均值来制定交易策略,如何制定进入和撤出股市的决策,记忆如何利用回溯测试来评估一个决策。

免责申明:这不是投资建议。同时我私人完全没有交易经验(文中相关的知识大部分来自我在盐湖城社区大学参加的一个学期关于股市交易的课程)!这里仅仅是基本概念知识,不足以用于实际交易的股票。股票交易可以让你受到损失(已有太多案例),你要为自己的行为负责。

获取并可视化股市数据

从雅虎金融获取数据

在分析数据之前得先得到数据。股市数据可以从Yahoo! Finance、 Google Finance以及其他的地方拿到。同时,pandas包提供了轻松从以上网站获取数据的方法。这节课我们使用雅虎金融的数据。

下面的代码展示了如何直接创建一个含有股市数据的DataFrame。(更多关于远程获取数据的信息,点击这里

OpenHighLowCloseVolumeAdj Close
Date      
2016-01-04 102.610001 105.370003 102.000000 105.349998 67649400 103.586180
2016-01-05 105.750000 105.849998 102.410004 102.709999 55791000 100.990380
2016-01-06 100.559998 102.370003 99.870003 100.699997 68457400 99.014030
2016-01-07 98.680000 100.129997 96.430000 96.449997 81094400 94.835186
2016-01-08 98.550003 99.110001 96.760002 96.959999 70798000 95.336649

让我们简单说一下数据内容。Open是当天的开始价格(不是前一天闭市的价格);high是股票当天的最高价;low是股票当天的最低价;close是闭市时间的股票价格。Volume指交易数量。Adjust close是根据法人行为调整之后的闭市价格。虽然股票价格基本上是由交易者决定的,stock splits (拆股。指上市公司将现有股票一拆为二,新股价格为原股的一半的行为)以及dividends(分红。每一股的分红)同样也会影响股票价格,也应该在模型中被考虑到。

可视化股市数据

获得数据之后让我们考虑将其可视化。下面我会演示如何使用matplotlib包。值得注意的是appleDataFrame对象有一个plot()方法让画图变得更简单。

Alt

线段图是可行的,但是每一天的数据至少有四个变量(开市,股票最高价,股票最低价和闭市),我们希望找到一种不需要我们画四条不同的线就能看到这四个变量走势的可视化方法。一般来说我们使用烛柱图(也称为日本阴阳烛图表)来可视化金融数据,烛柱图最早在18世纪被日本的稻米商人所使用。可以用matplotlib来作图,但是需要费些功夫。

你们可以使用我实现的一个函数更容易地画烛柱图,它接受pandas的data frame作为数据来源。(程序基于这个例子, 你可以从这里找到相关函数的文档。)

烛状图中黑色线条代表该交易日闭市价格高于开市价格(盈利),红色线条代表该交易日开市价格高于闭市价格(亏损)。刻度线代表当天交易的最高价和最低价(影线用来指明烛身的哪端是开市,哪端是闭市)。烛状图在金融和技术分析中被广泛使用在交易决策上,利用烛身的形状,颜色和位置。我今天不会涉及到策略。

我们也许想要把不同的金融商品呈现在一张图上:这样我们可以比较不同的股票,比较股票跟市场的关系,或者可以看其他证券,例如交易所交易基金(ETFs)。在后面的内容中,我们将会学到如何画金融证券跟一些指数(移动平均)的关系。届时你需要使用线段图而不是烛状图。(试想你如何重叠不同的烛状图而让图表保持整洁?)

下面我展示了不同技术公司股票的数据,以及如何调整数据让数据线聚在一起。

AAPLGOOGMSFT
Date
2016-01-04 103.586180 741.840027 53.696756
2016-01-05 100.990380 742.580017 53.941723
2016-01-06 99.014030 743.619995 52.961855
2016-01-07 94.835186 726.390015 51.119702
2016-01-08 95.336649 714.469971 51.276485

 

png

这张图表的问题在哪里呢?虽然价格的绝对值很重要(昂贵的股票很难购得,这不仅会影响它们的波动性,也会影响你交易它们的难易度),但是在交易中,我们更关注每支股票价格的变化而不是它的价格。Google的股票价格比苹果微软的都高,这个差别让苹果和微软的股票显得波动性很低,而事实并不是那样。

一个解决办法就是用两个不同的标度来作图。一个标度用于苹果和微软的数据;另一个标度用来表示Google的数据。

png

 

一个“更好”的解决方法是可视化我们实际关心的信息:股票的收益。这需要我们进行必要的数据转化。数据转化的方法很多。其中一个转化方法是将每个交易日的股票交个跟比较我们所关心的时间段开始的股票价格相比较。也就是:

text{return}_{t,0} = frac{text{price}_t}{text{price}_0}

这需要转化stock对象中的数据,操作如下:

 
AAPLGOOGMSFT
Date
2016-01-04 1.000000 1.000000 1.000000
2016-01-05 0.974941 1.000998 1.004562
2016-01-06 0.955861 1.002399 0.986314
2016-01-07 0.915520 0.979173 0.952007
2016-01-08 0.920361 0.963105 0.954927

 

png

这个图就有用多了。现在我们可以看到从我们所关心的日期算起,每支股票的收益有多高。而且我们可以看到这些股票之间的相关性很高。它们基本上朝同一个方向移动,在其他类型的图表中很难观察到这一现象。

 

我们还可以用每天的股值变化作图。一个可行的方法是我们使用后一天$t + 1$和当天$t$的股值变化占当天股价的比例:

text{growth}_t = frac{text{price}_{t + 1} - text{price}_t}{text{price}_t}

我们也可以比较当天跟前一天的价格:

text{increase}_t = frac{text{price}_{t} - text{price}_{t-1}}{text{price}_t}

以上的公式并不相同,可能会让我们得到不同的结论,但是我们可以使用对数差异来表示股票价格变化:

text{change}_t = log(text{price}_{t}) - log(text{price}_{t - 1})

(这里的log是自然对数,我们的定义不完全取决于使用log(text{price}_{t}) - log(text{price}_{t - 1})还是log(text{price}_{t+1}) - log(text{price}_{t}).) 使用对数差异的好处是该差异值可以被解释为股票的百分比差异,但是不受分母的影响。

下面的代码演示了如何计算和可视化股票的对数差异:

 

AAPLGOOGMSFT
Date
2016-01-04 NaN NaN NaN
2016-01-05 -0.025379 0.000997 0.004552
2016-01-06 -0.019764 0.001400 -0.018332
2016-01-07 -0.043121 -0.023443 -0.035402
2016-01-08 0.005274 -0.016546 0.003062
stock_change.plot(grid = True).axhline(y = 0, color = "black", lw = 2)

  

png

你更倾向于哪种转换方法呢?从相对时间段开始日的收益差距可以明显看出不同证券的总体走势。不同交易日之间的差距被用于更多预测股市行情的方法中,它们是不容被忽视的。

移动平均值

图表非常有用。在现实生活中,有些交易人在做决策的时候几乎完全基于图表(这些人是“技术人员”,从图表中找到规律并制定交易策略被称作技术分析,它是交易的基本教义之一。)下面让我们来看看如何找到股票价格的变化趋势。

一个q天的移动平均值(用MA^q_t来表示)定义为:对于某一个时间点t,它之前q天的平均值。

MA^q_t = frac{1}{q} sum_{i = 0}^{q-1} x_{t - i}

移动平均值可以让一个系列的数据变得更平滑,有助于我们找到趋势。q值越大,移动平均对短期的波动越不敏感。移动平均的基本目的就是从噪音中识别趋势。快速的移动平均有偏小的q,它们更接近股票价格;而慢速的移动平均有较大的q值,这使得它们对波动不敏感从而更加稳定。

pandas提供了计算移动平均的函数。下面我将演示使用这个函数来计算苹果公司股票价格的20天(一个月)移动平均值,并将它跟股票价格画在一起。

png

注意到平均值的起始点时间是很迟的。我们必须等到20天之后才能开始计算该值。这个问题对于更长时间段的移动平均来说是个更加严重的问题。因为我希望我可以计算200天的移动平均,我将扩展我们所得到的苹果公司股票的数据,但我们主要还是只关注2016。

png

你会发现移动平均比真实的股票价格数据平滑很多。而且这个指数是非常难改变的:一支股票的价格需要变到平局值之上或之下才能改变移动平均线的方向。因此平均线的交叉点代表了潜在的趋势变化,需要加以注意。

交易者往往对不同的移动平均感兴趣,例如20天,50天和200天。要同时生成多条移动平均线也不难:

png

20天的移动平均线对小的变化非常敏感,而200天的移动平均线波动最小。这里的200天平均线显示出来总体的熊市趋势:股值总体来说一直在下降。20天移动平均线所代表的信息是熊市牛市交替,接下来有可能是牛市。这些平均线的交叉点就是交易信息点,它们代表股票价格的趋势会有所改变因而你需要作出能盈利的相应决策。

请移动下节内容。你将读到如何使用移动平局线来设计和测试交易策略。

更新:该文章早期版本提到算法交易跟高频交易是一个意思。但是网友评论指出这并不一定:算法可以用来进行交易但不一定就是高频。高频交易是算法交易中间很大的一部分,但是两者不等价。

 

这篇博文是用Python分析股市数据系列两部中的第二部,内容基于我在犹他大学 数学3900 (数据科学)的课程 (阅读第一部分)。在这两篇博文中,我会讨论一些基础知识,包括比如如何用pandas从雅虎财经获得数据, 可视化股市数据,平均数指标的定义,设计移动平均交汇点分析移动平均线的方法,回溯测试和 基准分析法。这篇文章会讨论如何设计用移动平均交汇点分析移动平均线的系统,如何做回溯测试和基准分析,最后留有一些练习题以飨读者。

注意:本文仅代表作者本人的观点。文中的内容不应该被当做经济建议。我不对文中代码负责,取用者自己负责

交易策略

在特定的预期条件达成时一个开放头寸会被关闭。多头头寸表示交易中需要金融商品价格上升才能产生盈利,空头头寸表示交易中需要金融商品价格下降才能产生盈利。在股票交易中,多头头寸是牛市,空头头寸是熊市,反之则不成立。(股票期权交易中这个非常典型)

例如你在预计股价上涨的情况下购入股票,并计划在股票价格上涨高于购入价时抛出,这就是多头头寸。就是说你持有一定的金融产品,如果它们价格上涨,你将会获利,并且没有上限;如果它们价格下降,你会亏损。由于股票价格不会为负,亏损是有限度的。相反的,如果你预计股价会下跌,就从交易公司借贷股票然后卖出,同时期待未来股票价格下降后再低价买入还贷来赚取差额,这就是空头股票。如果股价下跌你会获利。空头头寸的获利额度受股价所限(最佳情况就是股票变得一文不值,你不用花钱就能将它们买回来),而损失却没有下限,因为你有可能需要花很多钱才能买回股票。所以交换所只会在确定投资者有很好的经济基础的情况下才会让他们空头借贷股票。

所有股民都应该决定他在每一股上可以冒多大的风险。比如有人决定无论什么情况他都不会在某一次交易中投入总额的10%去冒险。同时在交易中,股民要有一个撤出策略,这是让股民退出头寸的各种条件。股民也可以设置一个目标,这是导致股民退出头寸的最小盈利额。同样的,股民也需要有一个他能承受的最大损失额度。当预计损失大于可承受额度时,股民应该退出头寸以避免更大损失(这可以通过设置停止损失委托来避免未来的损失)。

我们要设计一个交易策略,它包含用于快速交易的交易激发信号、决定交易额度的规则和完整的退出策略。我们的目标是设计并评估该交易策略。

假设每次交易金额占总额的比例是固定的(10%)。同时设定在每一次交易中,如果损失超过了20%的交易值,我们就退出头寸。现在我们要决定什么时候进入头寸,什么时候退出以保证盈利。

这里我要演示移动平均交汇点分析移动平均线的方法。我会使用两条移动平均线,一条快速的,另一条是慢速的。我们的策略是:

  • 当快速移动平均线和慢速移动线交汇时开始交易
  • 当快速移动平均线和慢速移动线再次交汇时停止交易

做多是指在快速平均线上升到慢速平均线之上时开始交易,当快速平均线下降到慢速平均线之下时停止交易。卖空正好相反,它是指在快速平均线下降到慢速平均线之下时开始交易,快速平均线上升到慢速平均线之上时停止交易。

现在我们有一整套策略了。在使用它之前我们需要先做一下测试。回溯测试是一个常用的测试方法,它使用历史数据来看策略是否会盈利。例如这张苹果公司的股票价值图,如果20天的移动平均是快速线,50天的移动平均是慢速线,那么我们这个策略不是很挣钱,至少在你一直做多头头寸的时候。

下面让我们来自动化回溯测试的过程。首先我们要识别什么时候20天平均线在50天之下,以及之上。

apple['20d-50d'] =apple['20d'] -apple['50d']
apple.tail()
OpenHighLowCloseVolumeAdj Close20d50d200d20d-50d
Date
2016-08-26 107.410004 107.949997 106.309998 106.940002 27766300 106.940002 107.87 101.51 102.73 6.36
2016-08-29 106.620003 107.440002 106.290001 106.820000 24970300 106.820000 107.91 101.74 102.68 6.17
2016-08-30 105.800003 106.500000 105.500000 106.000000 24863900 106.000000 107.98 101.96 102.63 6.02
2016-08-31 105.660004 106.570000 105.639999 106.099998 29662400 106.099998 108.00 102.16 102.60 5.84
2016-09-01 106.139999 106.800003 105.620003 106.730003 26643600 106.730003 108.04 102.39 102.56 5.65

我们将差异的符号称为状态转换。快速移动平均线在慢速移动平均线之上代表牛市状态;相反则为熊市。以下的代码用于识别状态转换。

复制代码
# np.where() is a vectorized if-else function, where a condition is checked for each component of a vector, and the first argument passed is used when the condition holds, and the other passed if it does not
apple["Regime"] = np.where(apple['20d-50d'] > 0, 1, 0)
# We have 1's for bullish regimes and 0's for everything else. Below I replace bearish regimes's values with -1, and to maintain the rest of the vector, the second argument is apple["Regime"]
apple["Regime"] = np.where(apple['20d-50d'] < 0, -1, apple["Regime"])
apple.loc['2016-01-01':'2016-08-07',"Regime"].plot(ylim = (-2,2)).axhline(y = 0, color = "black", lw = 2)
复制代码

apple["Regime"].plot(ylim =(-2,2)).axhline(y =0, color ="black", lw =2)

apple["Regime"].value_counts()
 1    966
-1    663
 0     50
Name: Regime, dtype: int64

从上面的曲线可以看到有966天苹果公司的股票是牛市,663天是熊市,有54天没有倾向性。(原文中牛市和熊市说反了,译文中更正;原文数字跟代码结果对不上,译文按照代码结果更正)

交易信号出现在状态转换之时。牛市出现时,买入信号被激活;牛市完结时,卖出信号被激活。同样的,熊市出现时卖出信号被激活,熊市结束时,买入信号被激活。(只有在你空头股票,或者使用一些其他的方法例如用股票期权赌市场的时候这种情况才对你有利)

复制代码
# To ensure that all trades close out, I temporarily change the regime of the last row to 0
regime_orig = apple.ix[-1, "Regime"]
apple.ix[-1, "Regime"] = 0
apple["Signal"] = np.sign(apple["Regime"] - apple["Regime"].shift(1))
# Restore original regime data
apple.ix[-1, "Regime"] = regime_orig
apple.tail()
复制代码
OpenHighLowCloseVolumeAdj Close20d50d200d20d-50dRegimeSignal
Date
2016-08-26 107.410004 107.949997 106.309998 106.940002 27766300 106.940002 107.87 101.51 102.73 6.36 1.0 0.0
2016-08-29 106.620003 107.440002 106.290001 106.820000 24970300 106.820000 107.91 101.74 102.68 6.17 1.0 0.0
2016-08-30 105.800003 106.500000 105.500000 106.000000 24863900 106.000000 107.98 101.96 102.63 6.02 1.0 0.0
2016-08-31 105.660004 106.570000 105.639999 106.099998 29662400 106.099998 108.00 102.16 102.60 5.84 1.0 0.0
2016-09-01 106.139999 106.800003 105.620003 106.730003 26643600 106.730003 108.04 102.39 102.56 5.65 1.0 -1.0
posted @ 2019-12-12 18:24  Slashout  阅读(4091)  评论(0编辑  收藏  举报