用 Python 做股市数据分析(2)

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

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

交易策略

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

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

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

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

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

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

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

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

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

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

 

OpenHighLowCloseVolumeAdj Close20d50d200d20d-50d
Date
2016-08-26107.410004107.949997106.309998106.94000227766300106.940002107.87101.51102.736.36
2016-08-29106.620003107.440002106.290001106.82000024970300106.820000107.91101.74102.686.17
2016-08-30105.800003106.500000105.500000106.00000024863900106.000000107.98101.96102.636.02
2016-08-31105.660004106.570000105.639999106.09999829662400106.099998108.00102.16102.605.84
2016-09-01106.139999106.800003105.620003106.73000326643600106.730003108.04102.39102.565.65

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

 

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

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

 

OpenHighLowCloseVolumeAdj Close20d50d200d20d-50dRegimeSignal
Date
2016-08-26107.410004107.949997106.309998106.94000227766300106.940002107.87101.51102.736.361.00.0
2016-08-29106.620003107.440002106.290001106.82000024970300106.820000107.91101.74102.686.171.00.0
2016-08-30105.800003106.500000105.500000106.00000024863900106.000000107.98101.96102.636.021.00.0
2016-08-31105.660004106.570000105.639999106.09999829662400106.099998108.00102.16102.605.841.00.0
2016-09-01106.139999106.800003105.620003106.73000326643600106.730003108.04102.39102.565.651.0-1.0

 

我们会买入苹果公司的股票20次,抛出21次 (原文数字跟代码结果不符,译文根据代码结果更正)。如果我们只选了苹果公司的股票,六年内只有21次交易发生。如果每次多头转空头的时候我们都采取行动,我们将会参与21次交易。(请记住交易次数不是越多越好,毕竟交易不是免费的)

你也许注意到了这个系统不是很稳定。快速平均线在慢速平均线之上就激发交易,即使这个状态只是短短一瞬,这样会导致交易马上终止(这样并不好因为现实中每次交易都要付费,这个费用会很快消耗掉收益)。同时所有的牛市瞬间转为熊市,如果你允许同时押熊市和牛市,那就会出现每次交易结束就自动激发另一场押相反方向交易的诡异情况。更好的系统会要求有更多的证据来证明市场的发展方向,但是这里我们不去追究那个细节。

下面我们来看看每次买入卖出时候的股票价格。

 

 

 

 

PriceRegimeSignal
Date
2010-03-16224.4499971.0Buy
2010-06-11253.509995-1.0Sell
2010-06-18274.0700111.0Buy
2010-07-22259.020000-1.0Sell
2010-09-20283.2300071.0Buy
2011-03-30348.6300090.0Sell
2011-03-31348.510006-1.0Sell
2011-05-12346.5699881.0Buy
2011-05-27337.409992-1.0Sell
2011-07-14357.7700041.0Buy
2011-11-17377.410000-1.0Sell
2011-12-28402.6400031.0Buy
2012-05-09569.180023-1.0Sell
2012-06-25570.7700201.0Buy
2012-10-17644.610001-1.0Sell
2013-05-17433.2600101.0Buy
2013-06-26398.069992-1.0Sell
2013-07-31452.5299841.0Buy
2013-10-03483.409996-1.0Sell
2013-10-16501.1100011.0Buy
2014-01-28506.499977-1.0Sell
2014-03-26539.7799911.0Buy
2014-04-22531.700020-1.0Sell
2014-04-25571.9399801.0Buy
2014-06-1193.860001-1.0Sell
2014-08-1899.1600041.0Buy
2014-10-1797.669998-1.0Sell
2014-10-28106.7399981.0Buy
2015-01-05106.250000-1.0Sell
2015-02-05119.9400021.0Buy
2015-04-16126.169998-1.0Sell
2015-04-28130.5599981.0Buy
2015-06-25127.500000-1.0Sell
2015-10-27114.5500031.0Buy
2015-12-18106.029999-1.0Sell
2016-03-11102.2600021.0Buy
2016-05-0593.239998-1.0Sell
2016-07-0195.8899991.0Buy
2016-07-0896.680000-1.0Sell
2016-07-2597.3399961.0Buy
2016-09-01106.7300031.0Sell
End DatePriceProfit
Date
2010-03-162010-06-11224.44999729.059998
2010-06-182010-07-22274.070011-15.050011
2010-09-202011-03-30283.23000765.400002
2011-05-122011-05-27346.569988-9.159996
2011-07-142011-11-17357.77000419.639996
2011-12-282012-05-09402.640003166.540020
2012-06-252012-10-17570.77002073.839981
2013-05-172013-06-26433.260010-35.190018
2013-07-312013-10-03452.52998430.880012
2013-10-162014-01-28501.1100015.389976
2014-03-262014-04-22539.779991-8.079971
2014-04-252014-06-11571.939980-478.079979
2014-08-182014-10-1799.160004-1.490006
2014-10-282015-01-05106.739998-0.489998
2015-02-052015-04-16119.9400026.229996
2015-04-282015-06-25130.559998-3.059998
2015-10-272015-12-18114.550003-8.520004
2016-03-112016-05-05102.260002-9.020004
2016-07-012016-07-0895.8899990.790001
2016-07-252016-09-0197.3399969.390007

从上表可以看出2013年5月17日那天苹果公司股票价格大跌,我们的系统会表现很差。但是那个价格下降不是因为苹果遇到了什么大危机,而仅仅是一次分股。由于分红不如分股那么显著,这也许会影响系统行为。

我们不希望我们的交易系统的表现受到分红和分股的影响。一个解决方案是利用历史的分红分股数据来设计交易系统,这些数据可以真实地反映股市的行为从而帮助我们找到最佳解决方案,但是这个方法要更复杂一些。另一个方案就是根据分红和分股来调整股票的价格。

雅虎财经只提供调整之后的股票闭市价格,不过这些对于我们调整开市,高价和低价已经足够了。调整闭市股价是这样实现的:

让我们回到开始,先调整股票价格,然后再来评价我们的交易系统。

 

 

 

 

End DatePriceProfit
Date
2010-03-162010-06-1029.3556673.408371
2010-06-182010-07-2235.845436-1.968381
2010-09-202011-03-3037.0434668.553623
2011-05-122011-05-2745.327660-1.198030
2011-07-142011-11-1746.7925032.568702
2011-12-282012-05-0952.66102021.781659
2012-06-252012-10-1774.65063410.019459
2013-05-172013-06-2657.882798-4.701326
2013-07-312013-10-0460.4572344.500835
2013-10-162014-01-2867.3894731.122523
2014-03-112014-03-1772.948554-1.272298
2014-03-242014-04-2273.370393-1.019203
2014-04-252014-10-1777.82685116.191371
2014-10-282015-01-05102.749105-0.028185
2015-02-052015-04-16116.4138466.046838
2015-04-282015-06-26126.721620-3.184117
2015-10-272015-12-18112.152083-7.897288
2016-03-102016-05-05100.015950-7.278331
2016-06-232016-06-2795.582210-4.038123
2016-06-302016-07-1195.0849041.372569
2016-07-252016-09-0196.8155269.914477

可以看到根据分红和分股调整之后的价格图变得很不一样了。之后的分析我们都会用到这个调整之后的数据。

假设我们在股市有一百万,让我们来看看根据下面的条件,我们的系统会如何反应:

  • 每次用总额的10%来进行交易
  • 退出头寸如果亏损达到了交易额的20%

模拟的时候要记住:

  • 每次交易有100支股票
  • 我们的避损规则是当股票价格下降到一定数值时就抛出。我们需要检查这段时间内的低价是否低到可以出发避损规则。现实中除非我们买入看空期权,我们无法保证我们能以设定低值价格卖出股票。这里为了简洁我们将设定值作为卖出值。
  • 每次交易都会付给中介一定的佣金。这里我们没有考虑这个。

下面的代码演示了如何实现回溯测试:

 

End DatePriceProfitLow
Date
2010-03-162010-06-1029.3556673.40837126.059775
2010-06-182010-07-2235.845436-1.96838131.337127
2010-09-202011-03-3037.0434668.55362335.967068
2011-05-122011-05-2745.327660-1.19803043.084626
2011-07-142011-11-1746.7925032.56870246.171251
2011-12-282012-05-0952.66102021.78165952.382438
2012-06-252012-10-1774.65063410.01945973.975759
2013-05-172013-06-2657.882798-4.70132652.859502
2013-07-312013-10-0460.4572344.50083560.043080
2013-10-162014-01-2867.3894731.12252367.136651
2014-03-112014-03-1772.948554-1.27229871.167335
2014-03-242014-04-2273.370393-1.01920369.579335
2014-04-252014-10-1777.82685116.19137176.740971
2014-10-282015-01-05102.749105-0.028185101.411076
2015-02-052015-04-16116.4138466.046838114.948237
2015-04-282015-06-26126.721620-3.184117119.733299
2015-10-272015-12-18112.152083-7.897288104.038477
2016-03-102016-05-05100.015950-7.27833191.345994
2016-06-232016-06-2795.582210-4.03812391.006996
2016-06-302016-07-1195.0849041.37256993.791913
2016-07-252016-09-0196.8155269.91447795.900485

 

 

End DateEnd Port. ValueProfit per ShareShare PriceSharesStart Port. ValueStop-Loss TriggeredTotal ProfitTrade Value
2010-03-162010-06-101.011588e+063.40837129.3556673400.01.000000e+060.011588.461499809.2678
2010-06-182010-07-221.006077e+06-1.96838135.8454362800.01.011588e+060.0-5511.4668100367.2208
2010-09-202011-03-301.029172e+068.55362337.0434662700.01.006077e+060.023094.7821100017.3582
2011-05-122011-05-271.026536e+06-1.19803045.3276602200.01.029172e+060.0-2635.666099720.8520
2011-07-142011-11-171.031930e+062.56870246.7925032100.01.026536e+060.05394.274298264.2563
2011-12-282012-05-091.073316e+0621.78165952.6610201900.01.031930e+060.041385.1521100055.9380
2012-06-252012-10-171.087343e+0610.01945974.6506341400.01.073316e+060.014027.2426104510.8876
2013-05-172013-06-261.078880e+06-4.70132657.8827981800.01.087343e+060.0-8462.3868104189.0364
2013-07-312013-10-041.086532e+064.50083560.4572341700.01.078880e+060.07651.4195102777.2978
2013-10-162014-01-281.088328e+061.12252367.3894731600.01.086532e+060.01796.0368107823.1568
2014-03-112014-03-171.086547e+06-1.27229872.9485541400.01.088328e+060.0-1781.2172102127.9756
2014-03-242014-04-221.085120e+06-1.01920373.3703931400.01.086547e+060.0-1426.8842102718.5502
2014-04-252014-10-171.106169e+0616.19137177.8268511300.01.085120e+060.021048.7823101174.9063
2014-10-282015-01-051.106140e+06-0.028185102.7491051000.01.106169e+060.0-28.1850102749.1050
2015-02-052015-04-161.111582e+066.046838116.413846900.01.106140e+060.05442.1542104772.4614
2015-04-282015-06-261.109035e+06-3.184117126.721620800.01.111582e+060.0-2547.2936101377.2960
2015-10-272015-12-181.101928e+06-7.897288112.152083900.01.109035e+060.0-7107.5592100936.8747
2016-03-102016-05-051.093921e+06-7.278331100.0159501100.01.101928e+060.0-8006.1641110017.5450
2016-06-232016-06-271.089480e+06-4.03812395.5822101100.01.093921e+060.0-4441.9353105140.4310
2016-06-302016-07-111.090989e+061.37256995.0849041100.01.089480e+060.01509.8259104593.3944
2016-07-252016-09-011.101895e+069.91447796.8155261100.01.090989e+060.010905.9247106497.0786

 

 

 

我们的财产总额六年增加了10%。考虑到每次交易额只有总额的10%,这个成绩不算差。

同时我们也注意到这个策略并没有引发停止损失委托。这意味着我们可以不需要它么?这个难说。毕竟这个激发事件完全取决于我们的设定值。

停止损失委托是被自动激活的,它并不会考虑股市整体走势。也就是说不论是股市真正的走低还是暂时的波动都会激发停止损失委托。而后者是我们需要注意的因为在现实中,由价格波动激发停止损失委托不仅让你支出一笔交易费用,同时还无法保证最终的卖出价格是你设定的价格。

下面的链接分别支持反对使用停止损失委托,但是之后的内容我不会要求我们的回溯测试系统使用它。这样可以简化系统,但不是很符合实际(我相信工业系统应该有停止损失委托)。

现实中我们不会只用总额的10%去押一支股票而是投资多种股票。在给定的时间可以跟不同公司同时交易,而且大部分财产应该在股票上,而不是现金。现在我们开始投资多支股票 (原文是stops,感觉是typo,译文按照stocks翻译),并且在两条移动平均线交叉的时候退市(不使用止损)。我们需要改变回溯测试的代码。我们会用一个pandas的DataFrame来存储所有股票的买卖,上一层的循环也需要记录更多的信息。

下面的函数用于产生买卖订单,以及另一回溯测试函数。

 

 

PriceRegimeSignal
DateSymbol
2010-03-16AAPL29.3556671.0Buy
AMZN131.7899931.0Buy
GOOG282.318173-1.0Sell
HPQ20.7223161.0Buy
IBM110.5632401.0Buy
MSFT24.677580-1.0Sell
NFLX10.0900001.0Buy
NTDOY37.0999981.0Buy
SNY16.360001-1.0Sell
YHOO16.360001-1.0Sell
2010-03-17SNY16.5000001.0Buy
YHOO16.5000001.0Buy
2010-03-22GOOG278.4720041.0Buy
2010-03-23MSFT25.1060961.0Buy
2010-05-03GOOG265.035411-1.0Sell
2010-05-10HPQ19.435830-1.0Sell
2010-05-14NTDOY35.799999-1.0Sell
2010-05-17SNY16.270000-1.0Sell
YHOO16.270000-1.0Sell
2010-05-19AMZN124.589996-1.0Sell
MSFT23.835187-1.0Sell
2010-05-21IBM108.322991-1.0Sell
2010-06-10AAPL32.7640380.0Sell
2010-06-11AAPL33.156405-1.0Sell
2010-06-18AAPL35.8454361.0Buy
2010-06-28IBM111.3976971.0Buy
2010-07-01IBM105.861499-1.0Sell
2010-07-06IBM106.6301751.0Buy
2010-07-09NTDOY36.9500011.0Buy
2010-07-20IBM109.298956-1.0Sell
2016-06-23AAPL95.5822101.0Buy
TWTR17.0400011.0Buy
2016-06-27AAPL91.544087-1.0Sell
FB108.970001-1.0Sell
2016-06-28SNY36.040001-1.0Sell
YHOO36.040001-1.0Sell
2016-06-30AAPL95.0849041.0Buy
NFLX91.4800030.0Sell
2016-07-01NFLX96.669998-1.0Sell
SNY37.9900021.0Buy
YHOO37.9900021.0Buy
2016-07-11AAPL96.457473-1.0Sell
NTDOY27.7000011.0Buy
2016-07-14MSFT53.4071331.0Buy
2016-07-25AAPL96.8155261.0Buy
FB121.6299971.0Buy
2016-07-26GOOG738.4199831.0Buy
2016-08-18NFLX96.1600041.0Buy
2016-09-01AAPL106.7300031.0Sell
2016-09-02AMZN772.4400021.0Sell
FB126.5100021.0Sell
GOOG771.4600221.0Sell
HPQ14.4900001.0Sell
IBM159.5500031.0Sell
MSFT57.6699981.0Sell
NFLX97.3799971.0Sell
NTDOY28.8400001.0Sell
SNY43.2799991.0Sell
TWTR19.5499991.0Sell
YHOO43.2799991.0Sell

475 rows × 3 columns

 

End CashPortfolio ValueProfit per ShareShare PriceSharesStart CashTotal ProfitTrade ValueType
DateSymbol
2010-03-16AAPL9.001907e+051.000000e+060.00000029.3556673400.01.000000e+060.099809.2678Buy
AMZN8.079377e+051.000000e+060.000000131.789993700.09.001907e+050.092252.9951Buy
GOOG8.079377e+051.000000e+060.000000282.3181730.08.079377e+050.00.0000Sell
HPQ7.084706e+051.000000e+060.00000020.7223164800.08.079377e+050.099467.1168Buy
IBM6.089637e+051.000000e+060.000000110.563240900.07.084706e+050.099506.9160Buy
MSFT6.089637e+051.000000e+060.00000024.6775800.06.089637e+050.00.0000Sell
NFLX5.090727e+051.000000e+060.00000010.0900009900.06.089637e+050.099891.0000Buy
NTDOY4.126127e+051.000000e+060.00000037.0999982600.05.090727e+050.096459.9948Buy
SNY4.126127e+051.000000e+060.00000016.3600010.04.126127e+050.00.0000Sell
YHOO4.126127e+051.000000e+060.00000016.3600010.04.126127e+050.00.0000Sell
2010-03-17SNY3.136127e+051.000000e+060.00000016.5000006000.04.126127e+050.099000.0000Buy
YHOO2.146127e+051.000000e+060.00000016.5000006000.03.136127e+050.099000.0000Buy
2010-03-22GOOG1.310711e+051.000000e+060.000000278.472004300.02.146127e+050.083541.6012Buy
2010-03-23MSFT3.315733e+041.000000e+060.00000025.1060963900.01.310711e+050.097913.7744Buy
2010-05-03GOOG1.126680e+059.959690e+05-13.436593265.0354110.03.315733e+04-0.079510.6233Sell
2010-05-10HPQ2.059599e+059.897939e+05-1.28648619.4358300.01.126680e+05-0.093291.9840Sell
2010-05-14NTDOY2.990399e+059.864139e+05-1.29999935.7999990.02.059599e+05-0.093079.9974Sell
2010-05-17SNY3.966599e+059.850339e+05-0.23000016.2700000.02.990399e+05-0.097620.0000Sell
YHOO4.942799e+059.836539e+05-0.23000016.2700000.03.966599e+05-0.097620.0000Sell
2010-05-19AMZN5.814929e+059.786139e+05-7.199997124.5899960.04.942799e+05-0.087212.9972Sell
MSFT6.744502e+059.736573e+05-1.27090923.8351870.05.814929e+05-0.092957.2293Sell
2010-05-21IBM7.719409e+059.716411e+05-2.240249108.3229910.06.744502e+05-0.097490.6919Sell
2010-06-10AAPL8.833386e+059.832296e+053.40837132.7640380.07.719409e+050.0111397.7292Sell
2010-06-11AAPL8.833386e+059.832296e+053.80073833.1564050.08.833386e+050.00.0000Sell
2010-06-18AAPL7.865559e+059.832296e+050.00000035.8454362700.08.833386e+050.096782.6772Buy
2010-06-28IBM6.974378e+059.832296e+050.000000111.397697800.07.865559e+050.089118.1576Buy
2010-07-01IBM7.821270e+059.788006e+05-5.536198105.8614990.06.974378e+05-0.084689.1992Sell
2010-07-06IBM6.861598e+059.788006e+050.000000106.630175900.07.821270e+050.095967.1575Buy
2010-07-09NTDOY5.900898e+059.788006e+050.00000036.9500012600.06.861598e+050.096070.0026Buy
2010-07-20IBM6.884589e+059.812025e+052.668781109.2989560.05.900898e+050.098369.0604Sell
2016-06-23AAPL3.951693e+051.863808e+060.00000095.5822101900.05.767755e+050.0181606.1990Buy
TWTR2.094333e+051.863808e+060.00000017.04000110900.03.951693e+050.0185736.0109Buy
2016-06-27AAPL3.833670e+051.856135e+06-4.03812391.5440870.02.094333e+05-0.0173933.7653Sell
FB5.795130e+051.862921e+063.770004108.9700010.03.833670e+050.0196146.0018Sell
2016-06-28SNY7.885450e+051.880959e+063.11000136.0400010.05.795130e+050.0209032.0058Sell
YHOO9.975770e+051.898997e+063.11000136.0400010.07.885450e+050.0209032.0058Sell
2016-06-30AAPL8.169157e+051.898997e+060.00000095.0849041900.09.975770e+050.0180661.3176Buy
NFLX9.907277e+051.893981e+06-2.64000091.4800030.08.169157e+05-0.0173812.0057Sell
2016-07-01NFLX9.907277e+051.893981e+062.54999596.6699980.09.907277e+050.00.0000Sell
SNY8.045767e+051.893981e+060.00000037.9900024900.09.907277e+050.0186151.0098Buy
YHOO6.184257e+051.893981e+060.00000037.9900024900.08.045767e+050.0186151.0098Buy
2016-07-11AAPL8.016949e+051.896589e+061.37256996.4574730.06.184257e+050.0183269.1987Sell
NTDOY6.133349e+051.896589e+060.00000027.7000016800.08.016949e+050.0188360.0068Buy
2016-07-14MSFT4.264099e+051.896589e+060.00000053.4071333500.06.133349e+050.0186924.9655Buy
2016-07-25AAPL2.424604e+051.896589e+060.00000096.8155261900.04.264099e+050.0183949.4994Buy
FB6.001543e+041.896589e+060.000000121.6299971500.02.424604e+050.0182444.9955Buy
2016-07-26GOOG-8.766857e+041.896589e+060.000000738.419983200.06.001543e+040.0147683.9966Buy
2016-08-18NFLX-2.703726e+051.896589e+060.00000096.1600041900.0-8.766857e+040.0182704.0076Buy
2016-09-01AAPL-6.758557e+041.915427e+069.914477106.7300030.0-2.703726e+050.0202787.0057Sell
2016-09-02AMZN1.641464e+051.979327e+06213.000000772.4400020.0-6.758557e+040.0231732.0006Sell
FB3.539114e+051.986647e+064.880005126.5100020.01.641464e+050.0189765.0030Sell
GOOG5.082034e+051.993255e+0633.040039771.4600220.03.539114e+050.0154292.0044Sell
HPQ7.081654e+052.006030e+060.92574614.4900000.05.082034e+050.0199962.0000Sell
IBM8.996254e+052.015652e+068.018727159.5500030.07.081654e+050.0191460.0036Sell
MSFT1.101470e+062.030572e+064.26286557.6699980.08.996254e+050.0201844.9930Sell
NFLX1.286492e+062.032890e+061.21999397.3799970.01.101470e+060.0185021.9943Sell
NTDOY1.482604e+062.040642e+061.13999928.8400000.01.286492e+060.0196112.0000Sell
SNY1.694676e+062.066563e+065.28999743.2799990.01.482604e+060.0212071.9951Sell
TWTR1.907771e+062.093922e+062.50999819.5499990.01.694676e+060.0213094.9891Sell
YHOO2.119843e+062.119843e+065.28999743.2799990.01.907771e+060.0212071.9951Sell

475 rows × 9 columns

 

更为现实的投资组合可以投资任何12支股票而达到100%的收益。这个看上去不错,但是我们可以做得更好。

基准分析法

基准分析法可以分析交易策略效率的好坏。所谓基准分析,就是将策略和其他(著名)策略进行比较从而评价该策略的表现好坏。

每次你评价交易系统的时候,都要跟买入持有策略(SPY)进行比较。除了一些信托基金和少数投资经理没有使用它,该策略在大多时候都是无敌的。有效市场假说强调没有人能战胜股票市场,所以每个人都应该购入指数基金,因为它能反应整个市场的构成。SPY是一个交易型开放式指数基金(一种可以像股票一样交易的信托基金),它的价格有效反映了S&P 500中的股票价格。买入并持有SPY,说明你可以有效地匹配市场回报率而不是战胜它。

下面是SPY的数据,让我们看看简单买入持有SPY能得到的回报:

 

OpenHighLowCloseVolumeAdj Close
Date
2010-01-04112.370003113.389999111.510002113.33000211894460099.292299
2016-09-01217.369995217.729996216.029999217.38999993859000217.389999

 

 

买入持有SPY比我们当前的交易系统好——我们的系统还没有考虑不菲的交易费用。考虑到机会成本和该策略的消耗,我们不应该用它。

怎样才能改进我们的系统呢?对于初学者来尽量多样化是一个选择。目前我们所有的股票都来自技术公司,这意味着技术型公司的不景气会反映在我们的投资组合上。我们应该设计一个可以利用空头头寸和熊市的系统,这样不管市场如何变动,我们都可以盈利。我们也可以寻求更好的方法预测股票的最高期望价格。但是不论如何我们都需要做得比SPY更好,不然由于我们的系统会自带机会成本,是没用的。

其他的基准策略也是存在的。如果我们的系统比“买入持有SPY”更好,我们可以进一步跟其他的系统比较,例如:

(我最初在这里接触到这些策略)基本准则仍然是:不要使用一个复杂的,包含大量交易的系统如果它赢不了一个简单的交易不频繁的指数基金模型。(事实上这个标准挺难实现的

最后要强调的是,假设你的交易系统在回溯测试中打败了所有的基准系统,也不意味着它能够准确地预测未来。因为回溯测试容易过拟合,它不能用于预测未来。

结论

虽然讲座最后的结论不是那么乐观,但记住有效市场理论也有缺陷。我个人的观点是当交易更多依赖于算法的时候,就更难战胜市场。有一个说法是:信托基金都不太可能战胜市场,你的系统能战胜市场仅仅是一个可能性而已。(当然信托基金表现很差的原因是收费太高,而指数基金不存在这个问题。)

本讲座只简单地说明了一种基于移动平均的交易策略。还有许多别的交易策略这里并没有提到。而且我们也没有深入探讨空头股票和货币交易。特别是股票期权有很多东西可以讲,它也提供了不同的方法来预测股票的走向。你可以在Derivatives Analytics with Python: Data Analysis, Models, Simulation, Calibration and Hedging书中读到更多的相关内容。(犹他大学的图书馆有这本书)

另一个资源是O’Reilly出的Python for Finance,犹他大学的图书馆里也有

记住在股票里面亏钱是很正常的,同样股市也能提供其他方法无法提供的高回报,每一个投资策略都应该是经过深思熟虑的。这个讲座旨在抛砖引玉,希望同学们自己进一步探讨这个话题。

作业

问题1

建立一个基于移动平均的交易系统(不需要止损条件)。选择15支2010年1月1日之前上市的股票,利用回溯测试检验你的 系统,并且SPY基准作比较,你的系统能战胜市场吗?

问题2

在现实中每一笔交易都要支付一笔佣金。弄明白如何计算佣金,然后修改你的backtes()函数,使之能够计算不同的佣金模式(固定费用,按比例收费等等)。

 

我们现在的移动平均交汇点分析系统在两条平均线交叉的时候触发交易。修改系统令其更准确:

当你完成修改之后,重复问题1,使用一个真实的佣金策略(从交易所查)来模拟你的系统,同时要求移动平均差异达到一定的移动标准差再激发交易。

问题3

我们的交易系统无法处理空头股票。空头买卖的复杂性在于损失是没有下限的(多头头寸的最大损失等于购入股票的总价格)。学习如何处理空头头寸,然后修改backtest()使其能够处理空头交易。思考要如何实现空头交易,包括允许多少空头交易?在进行其他交易的时候如何处理空头交易?提示:空头交易的量在函数中可以用一个负数来表示。

完成之后重复问题1,也可以同时考虑问题2中提到的因素。

转载于:https://www.cnblogs.com/anenyang/articles/8776572.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值