利用研究模块进行参数调整和股票池选择,将优化后的参数保存,后在策略模块中使用,进行更精准回测。
利用研究模块可以方便的进行参数调整和股票池选择,将优化后的参数保存,后在策略模块中使用,进行更精准回测。
导入必备的程序包
#导入需要的程序包
from research_api import *
import pandas as pd
import seaborn as sns
import numpy as np
import math
import matplotlib.pyplot as plt
定义策略函数,返回策略表,应包括买入点,卖出点,买卖价格。
def Strategy(df,parameter):
df[df['volume']==0]=np.nan
#计算策略指标,标记出买卖点
shortday = parameter[0]
longday = parameter[1]
close = df['close']
ewma5 = pd.ewma(close,shortday)
ewma10 = pd.ewma(close,longday)
Strategy_table = pd.concat([ewma5,ewma10],keys=['ewma5','ewma10'],axis=1)
Strategy_table['open']=df['open']
Strategy_table['yesterday']=(Strategy_table['ewma5']<Strategy_table['ewma10']).shift(1)#计算昨天的
Strategy_table['today']=(Strategy_table['ewma5']>Strategy_table['ewma10'])#计算今天
Strategy_table['buypoint'] = Strategy_table['yesterday'] & Strategy_table['today']
Strategy_table['sellpoint'] = Strategy_table['yesterday'].apply(lambda x:not x)&Strategy_table['today'].apply(lambda x:not x)
Strategy_table = Strategy_table.dropna()
return Strategy_table
定义买卖函数,返回策略的风险指标。
def Buysellstrategy(init_money,buy_cost,sell_cost,Strategy_table):
cash = [init_money]
holdstocknum =[0]
buysellpoint=[0]
for i in range(1,len(Strategy_table)-1):
cash.append(cash[i-1])
holdstocknum.append(holdstocknum[i-1])
buysellpoint.append('0')
if Strategy_table['buypoint'][i]==True: #定义买入策略,根据标记出的买点以第二天开盘价买入,包括买入手续费
current_cash = cash[i]
buyprice = Strategy_table['open'][i+1]#明日开盘价
number_of_shares = int((current_cash-buy_cost)/buyprice)
if number_of_shares > 0:
buysellpoint[i]=1
cash[i] = cash[i]-buyprice*number_of_shares
holdstocknum[i] = number_of_shares
elif Strategy_table['sellpoint'][i]==True:#定义卖出策略,根据标记出的卖点以第二天开盘价卖出,包括卖出手续费
if holdstocknum[i]>0:
buysellpoint[i]=-1
curret_cash = cash[i]
sellprice = Strategy_table['open'][i+1]#明日开盘价
cash[i] = cash[i] + sellprice*holdstocknum[i]-sell_cost
holdstocknum[i] = 0
cash.insert(0,np.nan)
holdstocknum.insert(0,np.nan)
buysellpoint.append(np.nan)
Strategy_table['cash']=cash
Strategy_table['holdstocknum']=holdstocknum
Strategy_table['buysellpoint']=buysellpoint#标记出实际买卖点
Strategy_table['portfolio_value']=Strategy_table['cash']+Strategy_table['open']*Strategy_table['holdstocknum']
#returns = 100*(Strategy_table['portfolio_value'][-1]/Strategy_table['portfolio_value'][1]-1)#计算收益
returns = 100*Strategy_table['portfolio_value'].pct_change().cumsum()[-1]
#计算最大回撤
maxdrawdown = 100*((max(Strategy_table['portfolio_value'].dropna())-min(Strategy_table['portfolio_value'].dropna()))/max(Strategy_table['portfolio_value'].dropna()))
return returns,maxdrawdown,Strategy_table
初始化:初始化资金,回测时间,策略参数设置,股票池,手续费设置。 输出回测表。
init_money = 10000
start_date='2013-01-01'
end_date='2015-10-18'
#days = [5,10,20,30,60,120]
parameter = [5,10]
#选择股票池,这里选择沪深300股票数据
stocklist = get_index_stocks('000300.XSHG')
buy_cost=5#0.0008
sell_cost=7#0.0013
#min_cost=5
Returns = []
Maxdrawdown = []
for j in range(0,len(stocklist)):
stock = stocklist[j]#获取股票代码
df = get_price(stock, start_date, end_date, frequency='daily')
Strategy_table = Strategy(df,parameter)
returns,maxdrawdown,Strategy_table = Buysellstrategy(init_money,buy_cost,sell_cost,Strategy_table)
Returns.append(returns)
Maxdrawdown.append(maxdrawdown)
Backtest = pd.DataFrame(index=stocklist)
Backtest['returns']=Returns
Backtest['maxdrawdown']=Maxdrawdown
Backtest
returns | maxdrawdown | |
---|---|---|
000630.XSHE | 9.386720 | 45.057869 |
000750.XSHE | -2.288905 | 48.982188 |
002344.XSHE | 73.798666 | 59.036096 |
600546.XSHG | 23.863817 | 54.549422 |
601216.XSHG | 143.961823 | 79.607509 |
600648.XSHG | 52.519214 | 78.766299 |
601857.XSHG | 6.501930 | 46.452784 |
601238.XSHG | 34.764662 | 56.968047 |
000061.XSHE | 83.667657 | 63.794346 |
601299.XSHG | 194.479005 | 88.676711 |
002400.XSHE | 139.828517 | 73.581805 |
600111.XSHG | -17.520880 | 45.856616 |
601118.XSHG | 47.580474 | 63.811278 |
600340.XSHG | 60.115114 | 57.842807 |
600741.XSHG | 64.636473 | 58.951221 |
600100.XSHG | 112.222547 | 77.587748 |
000876.XSHE | 43.519710 | 51.855115 |
000729.XSHE | 29.669523 | 44.867846 |
002353.XSHE | -15.407872 | 25.259612 |
000024.XSHE | 59.798341 | 61.926411 |
600252.XSHG | 28.988900 | 61.189862 |
600718.XSHG | 94.554420 | 70.069507 |
002450.XSHE | 34.526367 | 69.392712 |
002065.XSHE | 65.788842 | 55.952598 |
002500.XSHE | 101.250916 | 74.237603 |
600011.XSHG | 41.925265 | 61.059232 |
601866.XSHG | 173.625540 | 84.368702 |
000783.XSHE | 109.012492 | 72.652122 |
601666.XSHG | -22.629281 | 43.387569 |
002202.XSHE | 64.675218 | 66.760760 |
... | ... | ... |
600216.XSHG | -12.112415 | 35.786509 |
002024.XSHE | 83.349534 | 73.237875 |
600015.XSHG | 31.842439 | 49.711260 |
002236.XSHE | 61.528686 | 51.114396 |
600219.XSHG | 56.256268 | 57.168663 |
000333.XSHE | 66.918795 | 56.439872 |
002603.XSHE | 33.199800 | 50.797383 |
600875.XSHG | 57.217173 | 62.599771 |
600688.XSHG | 78.797955 | 70.960959 |
600060.XSHG | 82.983774 | 68.433350 |
000063.XSHE | 61.309015 | 59.995349 |
002465.XSHE | 85.512078 | 65.929012 |
000156.XSHE | 67.395133 | 65.381458 |
601933.XSHG | -1.900869 | 46.187173 |
601989.XSHG | 91.139216 | 73.952479 |
600383.XSHG | 61.943386 | 60.941186 |
000009.XSHE | 57.932932 | 43.344811 |
000970.XSHE | 8.402291 | 54.714539 |
601958.XSHG | -11.926875 | 46.728112 |
601766.XSHG | 175.960292 | 88.025514 |
600795.XSHG | 91.321017 | 71.343870 |
002241.XSHE | 39.336077 | 49.362460 |
000778.XSHE | 57.224334 | 61.990110 |
002106.XSHE | 54.373195 | 37.824324 |
600030.XSHG | 110.632233 | 70.305966 |
601669.XSHG | 120.088144 | 78.763295 |
600832.XSHG | 102.327164 | 64.420341 |
601186.XSHG | 109.529348 | 80.239404 |
000792.XSHE | -23.985170 | 40.805934 |
600739.XSHG | 76.174093 | 59.960965 |
300 rows × 2 columns
统计分析回测表。
Backtest.describe()
returns | maxdrawdown | |
---|---|---|
count | 300.000000 | 300.000000 |
mean | 52.538589 | 59.368586 |
std | 46.426823 | 12.944235 |
min | -50.855440 | 25.259612 |
25% | 17.944032 | 49.714769 |
50% | 52.789305 | 58.924462 |
75% | 81.236871 | 69.246476 |
max | 204.949800 | 88.676711 |
打印出回测收益大于150%的股票
Backtest[Backtest['returns']>150]
returns | maxdrawdown | |
---|---|---|
601299.XSHG | 194.479005 | 88.676711 |
601866.XSHG | 173.625540 | 84.368702 |
600352.XSHG | 151.593050 | 78.629862 |
600588.XSHG | 166.279243 | 82.841259 |
601390.XSHG | 177.476808 | 88.507478 |
002252.XSHE | 153.306544 | 82.636461 |
600271.XSHG | 150.496579 | 84.052788 |
600415.XSHG | 204.949800 | 88.463770 |
000503.XSHE | 164.579280 | 80.267105 |
601766.XSHG | 175.960292 | 88.025514 |
df = get_price('600415.XSHG', start_date, end_date, frequency='daily')
Strategy_table = Strategy(df,parameter)
returns,maxdrawdown,Strategy_table = Buysellstrategy(init_money,buy_cost,sell_cost,Strategy_table)
Strategy_table['open'].plot(figsize=[18,8],label='open price')
plt.plot(Strategy_table.index[Strategy_table['buysellpoint']==1],Strategy_table['open'][Strategy_table['buysellpoint']==1],'r^',label='buypoint')
plt.plot(Strategy_table.index[Strategy_table['buysellpoint']==-1],Strategy_table['open'][Strategy_table['buysellpoint']==-1],'gv',label='sellpoint')
plt.legend(loc='best')
<matplotlib.legend.Legend at 0x7f365c5c5250>
df = get_price('000300.XSHG', start_date, end_date, frequency='daily')
(100*df['close'].pct_change().cumsum()).plot(figsize=[18,8],label='Benchmark Returns')
df = get_price('600415.XSHG', start_date, end_date, frequency='daily')
Strategy_table = Strategy(df,parameter)
returns,maxdrawdown,Strategy_table = Buysellstrategy(init_money,buy_cost,sell_cost,Strategy_table)
(100*Strategy_table['portfolio_value'].pct_change().cumsum()).plot(label='Total Returns')
plt.legend(loc='best')
<matplotlib.legend.Legend at 0x7f365c530d10>
对比表和图中,可以实际看出股票的买入卖出点的实际参数
Strategy_table[400:]
ewma5 | ewma10 | open | yesterday | today | buypoint | sellpoint | cash | holdstocknum | buysellpoint | portfolio_value | |
---|---|---|---|---|---|---|---|---|---|---|---|
2014-09-01 | 2.759515 | 2.724396 | 2.79 | False | True | False | False | 5.10 | 4025 | 0 | 11234.85 |
2014-09-02 | 2.769596 | 2.733087 | 2.81 | False | True | False | False | 5.10 | 4025 | 0 | 11315.35 |
2014-09-03 | 2.787997 | 2.746443 | 2.82 | False | True | False | False | 5.10 | 4025 | 0 | 11355.60 |
2014-09-04 | 2.803331 | 2.758585 | 2.88 | False | True | False | False | 5.10 | 4025 | 0 | 11597.10 |
2014-09-05 | 2.824442 | 2.774168 | 2.90 | False | True | False | False | 5.10 | 4025 | 0 | 11677.60 |
2014-09-09 | 2.880368 | 2.809243 | 2.92 | False | True | False | False | 5.10 | 4025 | 0 | 11758.10 |
2014-09-10 | 2.921974 | 2.838403 | 3.14 | False | True | False | False | 5.10 | 4025 | 0 | 12643.60 |
2014-09-11 | 2.971645 | 2.873094 | 3.13 | False | True | False | False | 5.10 | 4025 | 0 | 12603.35 |
2014-09-12 | 3.016371 | 2.906449 | 3.20 | False | True | False | False | 5.10 | 4025 | 0 | 12885.10 |
2014-09-15 | 3.070309 | 2.945863 | 3.24 | False | True | False | False | 5.10 | 4025 | 0 | 13046.10 |
2014-09-16 | 3.098591 | 2.972602 | 3.37 | False | True | False | False | 5.10 | 4025 | 0 | 13569.35 |
2014-09-17 | 3.122159 | 2.996911 | 3.24 | False | True | False | False | 5.10 | 4025 | 0 | 13046.10 |
2014-09-18 | 3.156799 | 3.027192 | 3.23 | False | True | False | False | 5.10 | 4025 | 0 | 13005.85 |
2014-09-19 | 3.188999 | 3.056538 | 3.36 | False | True | False | False | 5.10 | 4025 | 0 | 13529.10 |
2014-09-22 | 3.204166 | 3.076853 | 3.33 | False | True | False | False | 5.10 | 4025 | 0 | 13408.35 |
2014-09-23 | 3.213472 | 3.093503 | 3.27 | False | True | False | False | 5.10 | 4025 | 0 | 13166.85 |
2014-09-24 | 3.224560 | 3.110457 | 3.24 | False | True | False | False | 5.10 | 4025 | 0 | 13046.10 |
2014-09-25 | 3.228800 | 3.123143 | 3.30 | False | True | False | False | 5.10 | 4025 | 0 | 13287.60 |
2014-09-26 | 3.229000 | 3.132857 | 3.24 | False | True | False | False | 5.10 | 4025 | 0 | 13046.10 |
2014-09-29 | 3.242500 | 3.148961 | 3.23 | False | True | False | False | 5.10 | 4025 | 0 | 13005.85 |
2014-09-30 | 3.255417 | 3.164510 | 3.35 | False | True | False | False | 5.10 | 4025 | 0 | 13488.85 |
2014-10-08 | 3.286180 | 3.189554 | 3.37 | False | True | False | False | 5.10 | 4025 | 0 | 13569.35 |
2014-10-09 | 3.320150 | 3.216868 | 3.45 | False | True | False | False | 5.10 | 4025 | 0 | 13891.35 |
2014-10-10 | 3.343459 | 3.238971 | 3.46 | False | True | False | False | 5.10 | 4025 | 0 | 13931.60 |
2014-10-13 | 3.366216 | 3.260882 | 3.43 | False | True | False | False | 5.10 | 4025 | 0 | 13810.85 |
2014-10-14 | 3.385180 | 3.280802 | 3.47 | False | True | False | False | 5.10 | 4025 | 0 | 13971.85 |
2014-10-15 | 3.400983 | 3.298911 | 3.49 | False | True | False | False | 5.10 | 4025 | 0 | 14052.35 |
2014-10-16 | 3.400819 | 3.308101 | 3.46 | False | True | False | False | 5.10 | 4025 | 0 | 13931.60 |
2014-10-17 | 3.377349 | 3.303728 | 3.40 | False | True | False | False | 5.10 | 4025 | 0 | 13690.10 |
2014-10-20 | 3.369458 | 3.306117 | 3.26 | False | True | False | False | 5.10 | 4025 | 0 | 13126.60 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2015-08-27 | 10.103665 | 10.868906 | 8.24 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-08-28 | 9.907915 | 10.691036 | 8.36 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-08-31 | 9.716482 | 10.514034 | 8.86 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-01 | 9.501962 | 10.323152 | 8.45 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-02 | 9.188172 | 10.075732 | 7.95 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-07 | 8.943392 | 9.860246 | 7.86 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-08 | 8.787782 | 9.691093 | 7.60 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-09 | 8.723137 | 9.573120 | 8.10 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-10 | 8.615926 | 9.436750 | 8.21 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-11 | 8.558262 | 9.330233 | 8.02 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-14 | 8.461872 | 9.207013 | 8.30 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-15 | 8.248202 | 9.022095 | 7.75 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-16 | 8.171827 | 8.909731 | 7.25 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-17 | 8.044846 | 8.772998 | 7.68 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-18 | 7.950699 | 8.655144 | 7.47 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-21 | 7.903913 | 8.565372 | 7.41 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-22 | 7.993265 | 8.553950 | 7.70 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-23 | 8.012722 | 8.513512 | 8.18 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-24 | 8.033935 | 8.479495 | 8.07 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-25 | 7.983278 | 8.411249 | 8.10 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-28 | 7.952731 | 8.355598 | 7.74 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-29 | 7.878941 | 8.278622 | 7.61 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-09-30 | 7.822450 | 8.211393 | 7.52 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-10-08 | 7.828708 | 8.179413 | 7.80 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-10-09 | 7.872258 | 8.171276 | 7.87 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-10-12 | 8.020216 | 8.224845 | 8.23 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-10-13 | 8.145181 | 8.274446 | 8.61 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-10-14 | 8.299318 | 8.346824 | 8.74 | True | False | False | False | 61178.10 | 0 | 0 | 61178.10 |
2015-10-15 | 8.479433 | 8.440814 | 9.05 | True | True | True | False | 61178.10 | 0 | 1 | 61178.10 |
2015-10-16 | 8.616195 | 8.518971 | 9.39 | False | True | False | False | 11.64 | 6514 | NaN | 61178.10 |
264 rows × 11 columns
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...