上海做网站的哪家好,济南公司网站开发,我做的电影网站为什么百度搜索不到,logo在线设计软件免费版第一阶段、一个简单策略入门量化投资
1-2 移动均线交叉策略1 第一阶段一个简单策略入门量化投资1-2 移动均线交叉策略1前言获取数据移动均线交叉策略数据可视化绘制折线图绘制K线图绘制移动均线 移动均线交叉策略回测什么是回测回溯买卖信号计算收益 未完待续完整代码 前言
…第一阶段、一个简单策略入门量化投资
1-2 移动均线交叉策略1 第一阶段一个简单策略入门量化投资1-2 移动均线交叉策略1前言获取数据移动均线交叉策略数据可视化绘制折线图绘制K线图绘制移动均线 移动均线交叉策略回测什么是回测回溯买卖信号计算收益 未完待续完整代码 前言
本学期订了两个目标探索量化投资与熟练掌握python 以量化投资为切入点以python为工具在研究策略过程中又可以练习python两个目标相辅相成想法很美好于是就有了此文。 作为一个初学者我定下了第一阶段的目标 通过一个简单策略梳理研究并编写一个交易策略的整个流程从而入门量化投资。 我在网上找到了一篇不错的入门教程 Python股市数据分析教程——学会它或可以实现半“智能”炒股 (Part 1) 这也是我的主要参考资料本文是在此基础上梳理出来的也可以说是学习过程的记录。下面开始正文 获取数据
在1-1股票数据预处理练习中我们已经介绍了如何获取一只股票的数据并且进行一定的修改以满足我们的需要 使用如下代码获取苹果公司2010年至今的股票数据
import numpy as np
import pandas as pd
import pandas_datareader.data as web
import datetime
import time##### get historical data of a stock
# the first time we get the stock data from the interface of yahoo
# but we may not want to do this step all the time, so we try to save it in .csv
#start datetime.datetime(2016, 1, 1)
#end datetime.date.today()
#apple web.DataReader(AAPL, yahoo, start, end)
#print(apple.head())
#apple.to_csv(path_or_bufdata_AAPL.csv)##### read the data from csv
applepd.read_csv(filepath_or_bufferdata_AAPL.csv)
print(apple.head())
# note that some format(data type) of data we read from .csv has changed
# for example the attribute Date should be the index of the dataframe, and the date type changed from datetime to string
# this changes would made some methods got trouble
# So we need to make the following changes
date_list []
for i in range(len(apple)):date_str apple[Date][i]t time.strptime(date_str, %Y-%m-%d)temp_date datetime.datetime(t[0], t[1], t[2])date_list.append(temp_date)
apple[DateTime] pd.Series(date_list,apple.index)
del apple[Date]
apple apple.set_index(DateTime)
这样数据准备工作就完成了
移动均线交叉策略
许多交易策略都试图去找到股票价格的趋势移动均线交叉策略就是其中最简单的一种。我们来讨论下它是如何工作的。 什么是移动均线 对于序列xt以及时刻tq天均线表示过去q天股价的均值也就是说如果MAtq表示t时刻的q天均线那么 显然移动均线平滑了数据序列并有助于识别股市的发展趋势。q值越大移动均线就越难反映序列xt中的短期波动但也更好的把握了整体的趋势。 什么是均线交叉策略 均线交叉策略的想法是利用一长一短两条移动均线能够从”噪声”中识别股市的发展趋势。短期均线具有较小的q值比较紧密地跟随股票的趋势发展更能代表短期内的股价变动而长期均线的q值较大进而使得均线对股票波动的响应较小而且更加平稳。 因此移动均线交叉策略描述如下 当短期均线超越长期均线时说明股票价格短期内程上涨的趋势我们将这时作为买入时机。当短期均线跌落到长期均线以下时认为牛市结束将股票卖出。 下面我们通过可视化的方法绘制出股票的历史数据图以及两条长短均线来直观的感受下这个策略。
数据可视化
绘制折线图
我们利用获取的数据中的股票收盘价绘制出相应的折线图。
apple[Adj Close].plot(gridTrue) 绘制K线图
很显然这种表达过于单调而且我们获取的数据还包含开盘价、最高价、最低价这些信息没有使用。 众所周知金融数据通常以日本蜡烛图即K线图的形式绘制这种图表最早在18世纪由日本米市商人命名。matplotlib可以绘制这样的图表但操作起来比较复杂。于是此文的作者实现了一个函数可以更容易地在pandas数据框架中创建蜡烛图并使用它绘制我们的股票数据。你还可以参考matplotlib提供的示例 戳这里. 我们调用这个函数来可视化股票数据代码可在文末查看。
draw_candle.pandas_candlestick_ohlc(applestick month)
其中stick参数用于指明绘制每个“小蜡烛”的时间间隔效果如下
绘制移动均线
首先为苹果股票创建了三条移动均线滑动平均的范围分别是20天、50天、200天。随后将其与股票数据一同绘制在图表中。 pandas提供了轻松计算移动均线的功能下面的代码展示了这部分功能。
apple[20d] np.round(apple[Close].rolling(window 20, center False).mean(), 2)
apple[50d] np.round(apple[Close].rolling(window 50, center False).mean(), 2)
apple[100d] np.round(apple[Close].rolling(window 200, center False).mean(), 2)
draw_candle.pandas_candlestick_ohlc(apple.loc[2016-01-04:2017-09-01,:],stickweek,otherseries [20d, 50d, 100d]) 多多观察不同滑动长度的移动均线组合而成的交叉策略以及均线交叉策略作用在不同股票上的图表能够对该策略有一些更好的认识。
移动均线交叉策略回测
什么是回测
股票回测是指设定了某些股票策略后基于历史已经发生过的真实行情数据在历史上某一个时间点开始严格按照设定的组合进行选股并模拟真实金融市场交易的规则进行模型买入、模型卖出得出一个时间段内的盈利率、最大回撤率等数据。 回测是股票模型创建中必不可少的环境虽然回测效果非常好的策略实盘也不一定表现好但连回测效果都不好的策略就无法立足了。
回溯买卖信号
我们现在依照移动均线交叉策略的规则回溯出在苹果股票上利用该策略产生的买卖信号进而方便后面计算策略收益。 依照已经制定的策略定义买卖点如下 买点短期均线长期均线 卖点短期均线长期均线 这个过程可通过下面代码完成
##### compute the sub of the long time span moving average and the short one
# use regime to represent it
apple[20d-50d] apple[20d] - apple[50d]
apple[Regime] np.where(apple[20d-50d] 0, 1, 0)
apple[Regime] np.where(apple[20d-50d] 0, -1, apple[Regime])
regime_count apple[Regime].value_counts()##### use Regime to compute the trading signal
regime_orig apple.ix[-1, Regime]
apple.ix[-1, Regime] 0
apple[Signal] np.sign(apple[Regime] - apple[Regime].shift(1))
apple.ix[-1, Regime] regime_orig##### build the trading signal dataframe ( it is a list shows the buy and sell operations of the strategy )
apple_signals pd.concat([pd.DataFrame({Price: apple.loc[apple[Signal] 1, Close],Regime: apple.loc[apple[Signal] 1, Regime],Signal: Buy}),pd.DataFrame({Price: apple.loc[apple[Signal] -1, Close],Regime: apple.loc[apple[Signal] -1, Regime],Signal: Sell}),])
apple_signals.sort_index(inplace True)
print(apple_signals.head())
回溯的买卖信号表单如下所示
DateTimePriceRegimeSignal2010-03-1531.9771421.0Buy2010-06-1136.215714-1.0Sell2010-06-1839.1528591.0Buy2010-07-2237.002857-1.0Sell2010-08-1635.3771440.0Buy…………
计算收益
我们称买入-卖出为一次完整的交易那么利用回溯的买卖点表单我们可以回测出均线交叉策略在历史数据上进行的每笔交易以及每笔交易产生的收益。代码如下
##### use the trading signal dataframe apple_signals to compute the profit
apple_long_profits pd.DataFrame({Price: apple_signals.loc[(apple_signals[Signal] Buy) apple_signals[Regime] 1, Price],Profit: pd.Series(apple_signals[Price] - apple_signals[Price].shift(1)).loc[apple_signals.loc[(apple_signals[Signal].shift(1) Buy) (apple_signals[Regime].shift(1) 1)].index].tolist(),End Date: apple_signals[Price].loc[apple_signals.loc[(apple_signals[Signal].shift(1) Buy) (apple_signals[Regime].shift(1) 1)].index].index})
print(apple_long_profits.head())
draw_candle.pandas_candlestick_ohlc(apple, stick 45, otherseries [20d, 50d])
得到的交易清单如下
DateTimeEnd DatePriceProfit2010-03-152010-06-1131.9771424.2385722010-06-182010-07-2239.152859-2.1500022010-09-202011-03-3040.4614309.3428572011-05-122011-05-2749.509998-1.3085712011-07-142011-11-1751.1100012.805713………… 进行简单统计可以看到 苹果股票在2010年1月1日至今这段时间内 如果我们从第一天买入股票一直持有股票最后一天卖出获得的收益是每股124.02美元收益率为412% 如果按照我们的策略进行买卖总共完成了21笔交易收益为美股82.35美元收益率为273%
未完待续…
我们可以很直观的看到得到的结果有点让人哭笑不得显然按照移动均线交叉策略得到的结果还不如不使用任何策略来的靠谱。事实真的是这样吗 此外我们的策略还有很多漏洞回测的过程也有许多问题这些都将会在后面的工作中进行完善。
完整代码
import numpy as np
import pandas as pd
import pandas_datareader.data as web
import datetime
import time
import matplotlib.pyplot as plt
import pylab
import draw_candle##### get historical data of a stock
# the first time we get the stock data from the interface of yahoo
# but we may not want to do this step all the time, so we try to save it in .csv
#start datetime.datetime(2016, 1, 1)
#end datetime.date.today()
#apple web.DataReader(AAPL, yahoo, start, end)
#print(apple.head())
#apple.to_csv(path_or_bufdata_AAPL.csv)##### read the data from csv
applepd.read_csv(filepath_or_bufferdata_AAPL.csv)
#print(apple.head())
# note that some format(data type) of data we read from .csv has changed
# for example the attribute Date should be the index of the dataframe, and the date type changed from datetime to string
# this changes would made our methods in draw_candle.py got trouble
# So we need to make the following changes
date_list []
for i in range(len(apple)):date_str apple[Date][i]t time.strptime(date_str, %Y-%m-%d)temp_date datetime.datetime(t[0], t[1], t[2])date_list.append(temp_date)
apple[DateTime] pd.Series(date_list,apple.index)
del apple[Date]
apple apple.set_index(DateTime)##### we can visualize the data roughly
pylab.rcParams[figure.figsize] (10, 6)
#apple[Adj Close].plot(gridTrue)
#draw_candle.pandas_candlestick_ohlc(apple,stick month)##### compute the moving average of the history data for different time span
# use np.round to cut data to a certain accuracy
apple[20d] np.round(apple[Close].rolling(window 20, center False).mean(), 2)
apple[50d] np.round(apple[Close].rolling(window 50, center False).mean(), 2)
apple[100d] np.round(apple[Close].rolling(window 200, center False).mean(), 2)
#draw_candle.pandas_candlestick_ohlc(apple.loc[2016-01-04:2017-09-01,:],stickweek,otherseries [20d, 50d, 100d])##### compute the sub of the long time span moving average and the short one
# use regime to represent it
apple[20d-50d] apple[20d] - apple[50d]
apple[Regime] np.where(apple[20d-50d] 0, 1, 0)
apple[Regime] np.where(apple[20d-50d] 0, -1, apple[Regime])
regime_count apple[Regime].value_counts()
#print(regime_count)
#apple.loc[2017-01-01:2017-09-01,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)##### use Regime to compute the trading signal
regime_orig apple.ix[-1, Regime]
apple.ix[-1, Regime] 0
apple[Signal] np.sign(apple[Regime] - apple[Regime].shift(1))
apple.ix[-1, Regime] regime_orig##### build the trading signal dataframe ( it is a list shows the buy and sell operations of the strategy )
# the apple_signals looks like:
# Price Regime Signal
# Date
# 2010-03-15 31.977142 1.0 Buy
# 2010-06-11 36.215714 -1.0 Sell
# 2010-06-18 39.152859 1.0 Buy
# 2010-07-22 37.002857 -1.0 Sell#print(apple.loc[apple[Signal] 1, Close])
#print(apple.loc[apple[Signal] -1, Close])
apple_signals pd.concat([pd.DataFrame({Price: apple.loc[apple[Signal] 1, Close],Regime: apple.loc[apple[Signal] 1, Regime],Signal: Buy}),pd.DataFrame({Price: apple.loc[apple[Signal] -1, Close],Regime: apple.loc[apple[Signal] -1, Regime],Signal: Sell}),])
apple_signals.sort_index(inplace True)##### use the trading signal dataframe apple_signals to compute the profit
# the apple_long_profits looks like:
# End Date Price Profit
# Date
# 2010-03-15 2010-06-11 31.977142 4.238572
# 2010-06-18 2010-07-22 39.152859 -2.150002
# 2010-09-20 2011-03-30 40.461430 9.342857
apple_long_profits pd.DataFrame({Price: apple_signals.loc[(apple_signals[Signal] Buy) apple_signals[Regime] 1, Price],Profit: pd.Series(apple_signals[Price] - apple_signals[Price].shift(1)).loc[apple_signals.loc[(apple_signals[Signal].shift(1) Buy) (apple_signals[Regime].shift(1) 1)].index].tolist(),End Date: apple_signals[Price].loc[apple_signals.loc[(apple_signals[Signal].shift(1) Buy) (apple_signals[Regime].shift(1) 1)].index].index})
#print(apple_long_profits)
#draw_candle.pandas_candlestick_ohlc(apple, stick 45, otherseries [20d, 50d])##### take a simple analysis
# compute a rough profit (dont consider fee of the deal)
rough_profit apple_long_profits[Profit].sum()
print(rough_profit)# compute the profit if we dont take any operation
# (take long position at the first day and sale it on the last day of the date)
no_operation_profit apple[Close][-1]-apple[Close][0]
print(no_operation_profit)plt.show()