策略想法:选择期货锌和期货铜2016年主力合约小时数据,如果买入 前一小时涨幅较大合约,假设A,买入前一小时涨幅较小合约,假设B,买入时实时保持两者价值相等(价格不相等,则买入份数不一样),如果A涨幅小于B涨幅,则平仓。
策略代码如下:
import pandas as pdimport pyodbcfrom sqlalchemy import create_engineimport numpy as npfrom statistics import medianimport crash_on_ipyimport pdbimport matplotlib.pyplot as pltfrom numpy import nandata_cu=pd.read_csv(‘SQCU13.csv‘)data_zn=pd.read_csv(‘SQZN13.csv‘)data_zn.columns=[‘date‘,‘time‘,‘open‘,‘high‘,‘low‘,‘close‘,‘volumn‘,‘hold‘]data_cu.columns=[‘date‘,‘time‘,‘open‘,‘high‘,‘low‘,‘close‘,‘volumn‘,‘hold‘]data_zn[‘date_time‘]=data_zn[‘date‘]+data_zn[‘time‘]data_cu[‘date_time‘]=data_cu[‘date‘]+data_cu[‘time‘]del data_zn[‘date‘],data_zn[‘time‘],data_cu[‘date‘],data_cu[‘time‘]data_zn=data_zn.set_index(‘date_time‘)data_cu=data_cu.set_index(‘date_time‘)data_zn.rename(index=lambda x:str(x)[:12],inplace=True)data_cu.rename(index=lambda x:str(x)[:12],inplace=True)#取收盘价data_zn=data_zn.loc[:,[‘close‘]]data_cu=data_cu.loc[:,[‘close‘]]new_data_zn=data_zn.groupby(data_zn.index).last()new_data_cu=data_cu.groupby(data_cu.index).last()data=pd.concat([new_data_zn,new_data_cu],axis=1)data.columns=[‘zn_close‘,‘cu_close‘]data_zn_array=np.array(new_data_zn[‘close‘])data_cu_array=np.array(new_data_cu[‘close‘])T=len(data_zn_array)zn_return=[0]cu_return=[0]mark_enter=[0]*(T)mark_leave=[0]*(T)for i in range(1,T): if new_data_zn.index[i]==new_data_cu.index[i]: zn_return.append((data_zn_array[i]-data_zn_array[i-1])/data_zn_array[i]) cu_return.append((data_cu_array[i]-data_cu_array[i-1])/data_cu_array[i])data[‘zn_return‘]=zn_return;data[‘cu_return‘]=cu_returnprofit=[]position=Falselong_zn_positon=False for i in range(1,T): if data[‘zn_return‘][i]<data[‘cu_return‘][i] and not position: position=True long_zn_positon=True mark_enter[i]=1 shares=data[‘cu_close‘][i]/data[‘zn_close‘][i] long_price=data[‘zn_close‘][i] short_price=data[‘cu_close‘][i] elif data[‘zn_return‘][i]>data[‘cu_return‘][i] and not position: position=True long_zn_positon=False shares = data[‘cu_close‘][i]/ data[‘zn_close‘][i] mark_enter[i]=1 long_price = data[‘cu_close‘][i] short_price = data[‘zn_close‘][i] elif data[‘zn_return‘][i]>data[‘cu_return‘][i] and position and long_zn_positon: position=False long_zn_positon = False mark_leave[i]=1 return_zn=(data[‘zn_close‘][i]-long_price)*shares return_cu=short_price-data[‘cu_close‘][i] profit.append((return_zn+return_cu)/(2*short_price)) elif data[‘zn_return‘][i]<data[‘cu_return‘][i] and position and not long_zn_positon: position=False long_zn_positon=False mark_leave[i]=1 return_zn=(short_price-data[‘zn_close‘][i])*shares return_cu=long_price-data[‘cu_close‘][i] profit.append((return_zn + return_cu) / (2 * long_price)) #计算sharpe#计算总回报total_return=np.expm1(np.log1p(profit).sum())#计算年化回报annual_return=(1+total_return)**(365/365)-1risk_free_rate=0.015profit_std=np.array(profit).std()volatility=profit_std*(len(profit)**0.5)annual_factor=1annual_volatility=volatility*((annual_factor)**0.5)sharpe=(annual_return-risk_free_rate)/annual_volatility# print(total_return,annual_return,std,volatility,annual_volatility,sharpe)print(‘夏普比率:{}‘.format(sharpe)) #计算最大回撤#计算df_cum=np.exp(np.log1p(profit).cumsum())max_return=np.maximum.accumulate(df_cum)max_drawdown=((max_return-df_cum)/max_return).max()print(‘-----------------‘)print(‘最大回撤: {}‘.format(max_drawdown)) #计算盈亏比plrwin_times=sum(x>0 for x in profit)loss_times=sum(x<0 for x in profit)plr=win_times/loss_timesprint(‘----------------------------‘)print(‘盈利次数:{}‘.format(win_times))print(‘亏损次数:{}‘.format(loss_times))print(‘盈亏比:{}‘.format(plr)) # #画出净值走势图fig=plt.figure()ax1=fig.add_subplot(2,1,1)cum_net_worth,=plt.plot(df_cum,label=‘cum_net_worth‘)plt.legend([cum_net_worth],[‘cum_net_worth‘])ax2=fig.add_subplot(2,1,2)zn,=plt.plot(zn_return)cu,=plt.plot(cu_return)plt.legend([zn,cu],[‘zn_return‘,‘cu_return‘])for i in range(0,T): if mark_enter[i]==0: cu_return[i]=nanplt.plot(cu_return,‘*‘)for i in range(0,T): if mark_leave[i]==0: zn_return[i]=nanplt.plot(zn_return,‘+‘) plt.show()pdb.set_trace() 策略运行结果如下图:
时间: 2024-11-08 08:04:33