请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  数理科学 帖子:3365999 新帖:0

宏观择时多空组合——十年收益12倍,最大回撤6.7%

耶伦发表于:5 月 20 日 11:01回复(1)

之前做了系列宏观择时研究,但都是单方向做多,缺少做空,这会错过一些盈利时机。本文在原来基础上进行了进一步探索,从多空两个方向研究宏观择时策略。

使用数据
择时周期为每月,采用的数据为聚宽提供的月度宏观数据,不同的数据延时不同,本文采用的有效宏观数据延时如下:

  1. MAC_MANUFACTURING_PMI 延时1个月

  2. MAC_FIXED_INVESTMENT 延时2个月

  3. MAC_INDUSTRY_GROWTH 延时2个月

  4. MAC_NONMANUFACTURING_PMI 延时1个月

  5. MAC_MANUFACTURING_PMI 延时1个月

研究方法
选择多空因子,采用三种方法筛选
1.长短均线,多期均线穿越长期均线判断趋势
2.移动平均
3.连续变化趋势,例如连续两个月上涨认为上涨趋势形成,预测下月仍然上涨
对不同延时周期不同的均线参数进行调整,选择出有效的预测因子。
例如选择出的有效因子:
pmi 延时3个月 移动平均窗口长度为2 下降趋势时下个月做多,认为是反转信号
本文共选出有效多空因子24个,其中做多因子16个,做空因子8个。
对多空因子进行组合,采用简单的线性相加,即可得到较好的效果。
只采用做多因子的效果:
收益率4.5倍,基准收益的3.6倍,正确率69%,最大回撤11.8%
Img

只采用做空因子的效果:
收益率2.5倍,基准收益的2.3倍,正确率64%
Img

多空因子合并效果:
收益率12.2倍,基准收益的9.5倍,正确率82%,最大回撤4.3%
Img

从效果来看,即实现了高收益,同时最大回撤低,控制了风险。足以证明宏观数据具备择时能力。

但是本文的研究方法仍有问题,基于过去的数据挑选,又基于过去的数据预测,有过度调参的嫌疑,但是通过收益曲线可以看出,整体处于上升趋势,单个因子在周期内效果一般,但组合因子在不同时期都有向上表现,侧面反应出稳定性。另外,选择的预测因子在经济学原理上有较强的解释性,提高了可信度。
在因子组合方式上仍有探索空间,本文只是简单的等比例组合,有兴趣的小伙伴可以继续研究,效果会更好。

from jqdata import *import numpy as npimport pandas as pdimport datetime as dtfrom six import StringIOfrom dateutil.parser import parseimport pickleimport seaborn as snsimport matplotlib as mplimport matplotlib.pyplot as pltimport osimport statsmodels.api as smimport scipyimport talib as tlfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import GridSearchCVimport matplotlib.pyplot as pltimport warningswarnings.filterwarnings('ignore')
mpl.rcParams['font.family']='serif'mpl.rcParams['axes.unicode_minus']=False # 处理负号def get_profit(data,start_date,end_date,rate_riskfree=0):'''    data:计算好的带有position的数据,决定每月的买入卖出决策    '''df_pct=pd.DataFrame()prices = get_price('000300.XSHG',start_date=start_date,end_date=end_date,fields='close')['close']df_pct['pct']=prices.pct_change()rate_riskfree = 0df_pct = pd.concat([df_pct,data],axis=1)[start_date:end_date].dropna()df_pct['net_value'] =(df_pct['pct']+1).cumprod()df_pct['net_value_timing'] = (df_pct['pct']*df_pct['position']+rate_riskfree*(1-df_pct['position'])+1).cumprod()df_pct[['net_value','net_value_timing']].plot(figsize=(15,6))return df_pct
def get_month_list(start_date, end_date):sy = int(start_date[:4])ey = int(end_date[:4])sm = int(start_date[5:7])em = int(end_date[5:7])l = []for y in range(sy, ey + 1):if y == sy:for i in range(sm, 13):if i < 10:s = str(y) + '-' + '0' + str(i)l.append(s)else:s = str(y) + '-' + str(i)l.append(s)elif y == ey:for i in range(1, em + 1):if i < 10:s = str(y) + '-' + '0' + str(i)l.append(s)else:s = str(y) + '-' + str(i)l.append(s)else:for i in range(1, 13):if i < 10:s = str(y) + '-' + '0' + str(i)l.append(s)else:s = str(y) + '-' + str(i)l.append(s)return l#获取label值def get_profit_monthly(start_date,end_date,cut_list=[-0.00,0.00],label=True,rate_riskfree=0):'''    data:position数据,1列,前期计算出择时position    start_date:datetime or str, 开始时间,此时间要和data时间有交集,通常是对应    end_date:结束时间    rate_riskfree:无风险利率    cut_list:分类切点,注意二分类和多分类时后续算法的区别    label:决定输出的是分类结果还是连续结果    '''df_pct=pd.DataFrame()prices = get_price('000300.XSHG',start_date=start_date,end_date=end_date,fields='close')['close']prices_M = prices.resample('M',how='last')month_list = get_month_list(start_date,end_date)prices_M.index = month_listdf_pct['pct']=prices_M.pct_change().dropna()def fun(x):if x > cut_list[-1]:y = 1elif x < cut_list[0]:y = -1else:y = 0return yif label:df_pct = df_pct.applymap(lambda x: fun(x))return df_pct#计算最大回撤def find_max_drawdown(returns):# 定义最大回撤的变量result = 0# 记录最高的回报率点historical_return = 0# 遍历所有日期for i in range(len(returns)):# 最高回报率记录historical_return = max(historical_return, returns[i])# 最大回撤记录drawdown = 1 - (returns[i]) / (historical_return)# 记录最大回撤result = max(drawdown, result)# 返回最大回撤值return resultdef get_profit_res(data,start_date,end_date,rate_riskfree=0,plot=True):'''    data:position数据,1列,前期计算出择时position,index必须是日期    start_date:datetime or str, 开始时间,此时间要和data时间有交集,通常是对应    end_date:结束时间    rate_riskfree:无风险利率    '''df_pct=pd.DataFrame()prices = get_price('000300.XSHG',start_date=start_date,end_date=end_date,fields='close')['close']prices_M = prices.resample('M',how='last')month_list = get_month_list(start_date,end_date)prices_M.index = month_listdf_pct['pct']=prices_M.pct_change()df_pct['pct_position'] = df_pct['pct']df_pct['pct_position'][df_pct['pct_position']>0] = 1df_pct['pct_position'][df_pct['pct_position']<0] = 0rate_riskfree = 0df_pct = pd.concat([df_pct,data],axis=1).loc[month_list].dropna()#计算胜率win_rate = df_pct['position'] * df_pct['pct_position']win_rate = win_rate.sum()/df_pct['position'].sum()df_pct['net_value'] =(df_pct['pct']+1).cumprod()df_pct['net_value_timing'] = (df_pct['pct']*df_pct['position']+rate_riskfree*(1-df_pct['position'])+1).cumprod()if plot == True:f = plt.figure(figsize=(15,6))ax = f.add_subplot(1,1,1)ax.plot(df_pct[['net_value','net_value_timing']])ax.set_xticks(month_list[::12])profit_res = df_pct.ix[-1,['net_value','net_value_timing']].to_frame().stack().unstack(0)profit_res['win_rate'] = win_rateprofit_res['profit_ratio'] = profit_res['net_value_timing'] / profit_res['net_value']return profit_resdef get_profit_res_for_sell(data,start_date,end_date,rate_riskfree=0,plot=True):'''    data:position数据,1列,前期计算出择时position    start_date:datetime or str, 开始时间,此时间要和data时间有交集,通常是对应    end_date:结束时间    rate_riskfree:无风险利率    '''df_pct=pd.DataFrame()prices = get_price('000300.XSHG',start_date=start_date,end_date=end_date,fields='close')['close']prices_M = prices.resample('M',how='last')month_list = get_month_list(start_date,end_date)prices_M.index = month_listdf_pct['pct']=prices_M.pct_change()df_pct['pct_position'] = df_pct['pct']df_pct['pct_position'][df_pct['pct_position']>0]= 0df_pct['pct_position'][df_pct['pct_position']<0] = 1 #空头rate_riskfree = 0df_pct = pd.concat([df_pct,data],axis=1).loc[month_list].dropna()#计算胜率win_rate = df_pct['position'] * df_pct['pct_position']win_rate = win_rate.sum()/df_pct['position'].sum()df_pct['net_value'] =(df_pct['pct']+1).cumprod()df_pct['timing_for_sell'] = (-df_pct['pct']*df_pct['position']+rate_riskfree*(1-df_pct['position'])+1).cumprod()df_pct['net_value_timing'] = (df_pct['pct']*df_pct['position']+rate_riskfree*(1-df_pct['position'])+1).cumprod()if plot == True:f = plt.figure(figsize=(15,6))ax = f.add_subplot(1,1,1)ax.plot(df_pct[['net_value','timing_for_sell']])ax.set_xticks(month_list[::12])profit_res = df_pct.ix[-1,['net_value','timing_for_sell']].to_frame().stack().unstack(0)profit_res['win_rate'] = win_rateprofit_res['profit_ratio'] = profit_res['timing_for_sell'] / profit_res['net_value']return profit_res
def get_rolling_positon(data,n,delay=2,how='up'):'''    data:dataframe or series,输入数据,必须是一列    n:移动平均窗口大小    delay:取决于宏观数据发布时间,一般宏观数据都是本月中旬发布上月数据,每月初能拿到的最近数据为2月前    '''if how == 'up':position = (data.rolling(n).mean() > data.rolling(n).mean().shift(1))*1.0else:position = (data.rolling(n).mean() < data.rolling(n).mean().shift(1))*1.0if isinstance(position,pd.Series):position = position.to_frame()position.columns = ['position']position = position.shift(delay).dropna()return positiondef get_position_from_continus_increase(data,n,delay=2,how='up'):'''    data:dataframe or series,输入数据,必须是一列    n:连续n次上涨或下跌    how:默认up,连续上涨n天position标记为1    delay:取决于宏观数据发布时间,一般宏观数据都是本月中旬发布上月数据,每月初能拿到的最近数据为2月前    '''index = list(data.index)length = len(index)l = []for i in range(n,length):if how == 'up':counter = 0for j in range(i-n,i):if data.loc[index[j]]< data.loc[index[j+1]]:counter += 1if counter == n:position = 1l.append(position)else:position = 0l.append(position)else:counter = 0for j in range(i-n,i):if data.loc[index[j]] > data.loc[index[j+1]]:counter += 1if counter == n:position = 1l.append(position)else:position = 0l.append(position)res = pd.DataFrame(l,columns=['position'],index=index[n:])res = res.shift(delay).dropna()return resdef get_position_from_long_short_monving_*erage(data,long_n=12,short_n=3,delay=2,how='up'):'''    data:dataframe or series,输入数据,必须是一列    long_n:移动平均长期线计算窗口    short_n:移动平均短期线窗口    n:连续n次上涨或下跌    how:默认up,连续上涨n天position标记为1    delay:取决于宏观数据发布时间,一般宏观数据都是本月中旬发布上月数据,每月初能拿到的最近数据为2月前    '''    long_ma = data.rolling(long_n).mean()short_ma = data.rolling(short_n).mean()diff = short_ma -  long_maif how == 'up':diff[diff>0] = 1diff[diff<=0] = 0else:diff[diff>=0] = 0diff[diff<0] = 1if isinstance(diff,pd.Series):diff = diff.to_frame()diff.columns = ['position']res = diff.shift(delay).dropna()return res
start_date = '2009-01-01'end_date = '2019-03-29'month_list = get_month_list(start_date,end_date)

做多因子¶

'''macro.MAC_MANUFACTURING_PMI, 数据本身延迟1个月delay=3,how=down1.pmi rolling=22.produce_idx rolling=33.import_idx rolling=34.delivery_time_idx rolling=25.finished_produce_idx rolling=16.purchase_quantity_idx rolling=1delay =11.delivery_time_idx (14,4)'''def get_mac_economic_idx(month_list):mei = macro.MAC_MANUFACTURING_PMIq = query(mei).filter(mei.stat_month.in_(month_list))mac_economic = macro.run_query(q)mac_economic = mac_economic.set_index('stat_month')return mac_economicmac_manufacturing = get_mac_economic_idx(month_list)mac_manufacturing = mac_manufacturing.sort_index()pmi = mac_manufacturing['pmi'].sort_index()pmi = get_rolling_positon(pmi,n=2,delay=3,how='down')produce_idx = mac_manufacturing['produce_idx'].sort_index()produce_idx = get_rolling_positon(produce_idx,n=3,delay=3,how='down')import_idx = mac_manufacturing['import_idx'].sort_index()import_idx = get_rolling_positon(import_idx,n=3,delay=3,how='down')delivery_time_idx = mac_manufacturing['delivery_time_idx'].sort_index()delivery_time_idx = get_rolling_positon(delivery_time_idx,n=2,delay=3,how='down')finished_produce_idx = mac_manufacturing['finished_produce_idx'].sort_index()finished_produce_idx = get_rolling_positon(finished_produce_idx,n=1,delay=3,how='down')purchase_quantity_idx = mac_manufacturing['purchase_quantity_idx'].sort_index()purchase_quantity_idx = get_rolling_positon(purchase_quantity_idx,n=1,delay=3,how='down')delivery_time_idx_lsma = mac_manufacturing['delivery_time_idx'].sort_index()delivery_time_idx_lsma = get_position_from_long_short_monving_*erage(delivery_time_idx_lsma,long_n=14,short_n=4,delay=1,how='down')mac_manufacturing_position = pd.concat([pmi,produce_idx,import_idx,delivery_time_idx,finished_produce_idx,purchase_quantity_idx,delivery_time_idx_lsma],axis=1)mac_manufacturing_position = mac_manufacturing_position.dropna()mac_manufacturing_position.columns = ['pmi','produce_idx','import_idx','delivery_time_idx','finished_produce_idx','purchase_quantity_idx','delivery_time_idx_lsma']get_profit_res(delivery_time_idx_lsma,start_date,end_date)

.dataframe tbody tr th:only-of-type {        vertical-align: middle;    }    .dataframe tbody tr th {        vertical-align: top;    }    .dataframe thead th {        text-align: right;    }


net_valuenet_value_timingwin_rateprofit_ratio
2019-031.1799911.943870.573771.647361
'''macro.MAC_FIXED_INVESTMENT, 数据本身延迟2个月delay=2,how=down1.expand_yoy (10,4)2.secondary_yoy rolling=2delay=3how=up1.primary_yoy rolling=2 低频高效delay=3how=down1.expand_yoy (8,4)  continue = 2 低频高效    '''def get_mac_economic_idx(month_list):mei = macro.MAC_FIXED_INVESTMENTq = query(mei).filter(mei.stat_month.in_(month_list))mac_economic = macro.run_query(q)mac_economic = mac_economic.set_index('stat_month')return mac_economicmac_fixed = get_mac_economic_idx(month_list)mac_fixed = mac_fixed.sort_index()expand_yoy = mac_fixed['expand_yoy'].sort_index()expand_yoy = get_position_from_long_short_monving_*erage(expand_yoy,long_n=10,short_n=4,delay=2,how='down')secondary_yoy = mac_fixed['secondary_yoy'].sort_index()secondary_yoy = get_rolling_positon(secondary_yoy,n=2,delay=2,how='down')primary_yoy = mac_fixed['primary_yoy'].sort_index()primary_yoy = get_rolling_positon(primary_yoy,n=2,delay=3,how='up')expand_yoy_lsma = mac_fixed['expand_yoy'].sort_index()expand_yoy_lsma = get_position_from_long_short_monving_*erage(expand_yoy_lsma,long_n=8,short_n=4,delay=3,how='down')expand_yoy_continue = mac_fixed['expand_yoy'].sort_index()expand_yoy_continue = get_position_from_continus_increase(expand_yoy_continue,n=2,delay=3,how='down')mac_fixed_position = pd.concat([expand_yoy,secondary_yoy,primary_yoy,expand_yoy_lsma,expand_yoy_continue],axis=1).dropna()mac_fixed_position.columns = ['expand_yoy','secondary_yoy','primary_yoy','expand_yoy_lsma','expand_yoy_continue']
'''macro.MAC_INDUSTRY_GROWTH, 数据本身延迟2个月delay=2,how=up1.collective_acc rolling=32.foreign_yoy (8,2)delay=2how=down1.growth_yoy rolling=12.private_yoy rolling=13.joint_stock_yoy rolling=1'''def get_mac_economic_idx(month_list):mei = macro.MAC_INDUSTRY_GROWTHq = query(mei).filter(mei.stat_month.in_(month_list))mac_economic = macro.run_query(q)mac_economic = mac_economic.set_index('stat_month')return mac_economicmac_industry = get_mac_economic_idx(month_list) #无一月份数据mac_industry = mac_industry.sort_index()collective_acc = mac_industry['collective_acc'].sort_index()collective_acc = get_rolling_positon(collective_acc,n=3,delay=2,how='up')#foreign_yoy = mac_industry['foreign_yoy'].sort_index()#foreign_yoy = get_position_from_long_short_monving_*erage(foreign_yoy,long_n=8,short_n=2,delay=2,how='up')growth_yoy = mac_industry['growth_yoy'].sort_index()growth_yoy = get_rolling_positon(growth_yoy,n=1,delay=2,how='down')private_yoy = mac_industry['private_yoy'].sort_index()private_yoy = get_rolling_positon(private_yoy,n=1,delay=2,how='down')joint_stock_yoy = mac_industry['joint_stock_yoy'].sort_index()joint_stock_yoy = get_rolling_positon(joint_stock_yoy,n=1,delay=2,how='down')mac_industry_position = pd.concat([collective_acc,growth_yoy,private_yoy,joint_stock_yoy],axis=1).dropna()mac_industry_position.columns = ['collective_acc','growth_yoy','private_yoy','joint_stock_yoy']

做空因子¶

'''macro.MAC_MANUFACTURING_PMI 数据本身延迟1个月delay=1,how=down1.new_export_orders_idx  coninue=2delay=3how=up1.new_orders_idx (10,2)2.inve*ry_idx (10,3)3.input_idx (10,3)4.employ_idx (8,4) 低频高效5.delivery_time_idx (14,2)6.new_orders_idx continue=2 低频高效7.order_in_hand_idx rolling=3 delay=2,how=up1.inve*ry_idx (10,4)'''def get_mac_economic_idx(month_list):mei = macro.MAC_MANUFACTURING_PMIq = query(mei).filter(mei.stat_month.in_(month_list))mac_economic = macro.run_query(q)mac_economic = mac_economic.set_index('stat_month')return mac_economicmac_manufacturing_sell = get_mac_economic_idx(month_list) #无一月份数据mac_manufacturing_sell = mac_manufacturing_sell.sort_index()new_export_orders_idx = mac_manufacturing_sell['new_export_orders_idx'].sort_index()new_export_orders_idx = get_position_from_continus_increase(new_export_orders_idx,n=2,delay=1,how='down')'''macro.MAC_NONMANUFACTURING_PMIdelay=3,how = up1.new_orders_idx (10,2)2.inve*ry_idx (10,3)3.input_idx (10,3)4.employ_idx  (8,4)5.inve*ry_idx delay=2 (10,4)'''def get_mac_economic_idx(month_list):mei = macro.MAC_NONMANUFACTURING_PMIq = query(mei).filter(mei.stat_month.in_(month_list))mac_economic = macro.run_query(q)mac_economic = mac_economic.set_index('stat_month')return mac_economicmac_monmanufacturing_sell = get_mac_economic_idx(month_list)mac_monmanufacturing_sell = mac_monmanufacturing_sell.sort_index().fillna(method='ffill')new_orders_idx = mac_monmanufacturing_sell['new_orders_idx'].sort_index()new_orders_idx = get_position_from_long_short_monving_*erage(new_orders_idx,long_n=10,short_n=2,delay=3,how='up')inve*ry_idx = mac_monmanufacturing_sell['inve*ry_idx'].sort_index()inve*ry_idx = get_position_from_long_short_monving_*erage(inve*ry_idx,long_n=10,short_n=3,delay=3,how='up')input_idx = mac_monmanufacturing_sell['input_idx'].sort_index()input_idx = get_position_from_long_short_monving_*erage(input_idx,long_n=10,short_n=3,delay=3,how='up')employ_idx = mac_monmanufacturing_sell['employ_idx'].sort_index()employ_idx = get_position_from_long_short_monving_*erage(employ_idx,long_n=8,short_n=4,delay=3,how='up')inve*ry_idx = mac_monmanufacturing_sell['inve*ry_idx'].sort_index()inve*ry_idx = get_position_from_long_short_monving_*erage(inve*ry_idx,long_n=10,short_n=4,delay=2,how='up')'''macro.MAC_FIXED_INVESTMENTdelay=2,how = up1.secondary_yoy rolling=2delay=3construct_install_yoy rolling=2'''def get_mac_economic_idx(month_list):mei = macro.MAC_FIXED_INVESTMENTq = query(mei).filter(mei.stat_month.in_(month_list))mac_economic = macro.run_query(q)mac_economic = mac_economic.set_index('stat_month')return mac_economicmax_fixed_investment = get_mac_economic_idx(month_list)max_fixed_investment = max_fixed_investment.sort_index().fillna(method='ffill')secondary_yoy = max_fixed_investment['secondary_yoy'].sort_index()secondary_yoy = get_rolling_positon(secondary_yoy,2,delay=2,how='up')construct_install_yoy = max_fixed_investment['construct_install_yoy'].sort_index()construct_install_yoy = get_rolling_positon(construct_install_yoy,2,delay=2,how='up')all_position_for_sell = pd.concat([new_export_orders_idx,new_orders_idx,inve*ry_idx,input_idx,employ_idx,inve*ry_idx,secondary_yoy,construct_install_yoy],axis=1)all_position_for_sell.columns = ['new_export_orders_idx','new_orders_idx','inve*ry_idx','input_idx','employ_idx','inve*ry_idx','secondary_yoy','construct_install_yoy']all_position_for_sell = all_position_for_sell.fillna(method='ffill').dropna()
all_position = pd.concat([mac_manufacturing_position,mac_fixed_position,mac_industry_position],axis=1).dropna()profit = get_profit_monthly(start_date=start_date,end_date=end_date)profit_continue = get_profit_monthly(start_date=start_date,end_date=end_date,label=False)sel_index = all_position.indexprofit = profit.ix[sel_index]profit_continue = profit_continue.ix[sel_index]
#做多len_col = len(all_position.columns)sum_position = all_position.sum(axis=1)thre = 0.45predict_position = sum_position/len_col#print(predict_position)predict_position[predict_position >= thre] = 1predict_position[predict_position < thre] = 0#做空predict_position_for_sell = all_position_for_sell.sum(axis=1) / len(all_position_for_sell.columns)thre_sell = 0.5predict_position_for_sell[predict_position_for_sell >= thre_sell] = 1predict_position_for_sell[predict_position_for_sell < thre_sell] = 0predict_position_for_sell = predict_position_for_sell.to_frame()predict_position_for_sell.columns = ['position']get_profit_res_for_sell(predict_position_for_sell,start_date,end_date)predict_position_for_sell[predict_position_for_sell==1] = -1
combine_position = pd.concat([predict_position,predict_position_for_sell],axis=1).dropna()combine_position.columns = ['buy','sell']combine_position['combine'] = combine_position['buy'] + combine_position['sell']combine_position = combine_position['combine']
#做多def get_cumprod_profit(profit,profit_continue,predict):profit_continue['profit'] = profitprofit_continue['predict'] = predictprofit_continue['profit_multiply_predict'] = (profit_continue['pct'] * profit_continue['predict'])profit_continue['profit_cumprod'] = (profit_continue['profit_multiply_predict'] + 1).cumprod()profit_continue['original_profit'] = (profit_continue['pct'] + 1).cumprod()profit_continue['correct'] = profit_continue['predict'] * profit_continue['profit']profit_continue['correct'][profit_continue['correct']==-1] = 0correct_ratio = profit_continue['correct'].sum() / profit_continue['predict'].sum()max_drawdown = find_max_drawdown(profit_continue['profit_cumprod'])base_profit = (profit_continue['pct'] +1 ).cumprod().iloc[-1]celve_profit =  profit_continue['profit_cumprod'].iloc[-1]fig = plt.figure(figsize=(15,8))plt.plot(profit_continue['profit_cumprod'],label='stratage profit')plt.plot(profit_continue['original_profit'],label='base profit')plt.legend()ind = profit_continue.indexplt.xticks(ind[::6])print('stratage profit: ',celve_profit)print('stratage / base profit: ',celve_profit/base_profit)print('correct ratio: ',correct_ratio)print('max drawdown: ',max_drawdown)
   # print(profit_continue)#print(profit_continue)get_cumprod_profit(profit,profit_continue,predict_position)
stratage profit:  4.555235896697446
stratage / base profit:  3.5576211734745407
correct ratio:  0.6935483870967742
max drawdown:  0.2339005442953601
#多空结合def get_cumprod_profit_for_buy_and_sell(profit,profit_continue,predict):profit_continue['profit'] = profitprofit_continue['predict'] = predictprofit_continue['profit_multiply_predict'] = (profit_continue['pct'] * profit_continue['predict'])profit_continue['profit_cumprod'] = (profit_continue['profit_multiply_predict'] + 1).cumprod()profit_continue['original_profit'] = (profit_continue['pct'] + 1).cumprod()profit_continue['correct'] = profit_continue['predict'] * profit_continue['profit']profit_continue['correct'][profit_continue['correct']==-1] = 0profit_continue['predict_num'] = profit_continue['predict']profit_continue['predict_num'][profit_continue['predict_num']==-1] = 1correct_ratio = profit_continue['correct'].sum() / profit_continue['predict_num'].sum()max_drawdown = find_max_drawdown(profit_continue['profit_cumprod'])base_profit = (profit_continue['pct'] +1 ).cumprod().iloc[-1]celve_profit =  profit_continue['profit_cumprod'].iloc[-1]fig = plt.figure(figsize=(15,8))plt.plot(profit_continue['profit_cumprod'],label='stratage profit')plt.plot(profit_continue['original_profit'],label='base profit')plt.legend()ind = profit_continue.indexplt.xticks(ind[::6])print('stratage profit: ',celve_profit)print('stratage / base profit: ',celve_profit/base_profit)print('correct ratio: ',correct_ratio)print('max drawdown: ',max_drawdown)#print(profit_continue)#print(profit_continue)get_cumprod_profit_for_buy_and_sell(profit,profit_continue,combine_position)
stratage profit:  12.191638501783478
stratage / base profit:  9.521621329147411
correct ratio:  0.8166666666666667
max drawdown:  0.06691785391891358

全部回复

0/140

达人推荐

量化课程

    移动端课程