# 回测起始时间
# 策略比较参考标准,以沪深300为例
#benchmark = '000300.INDX'
#benchmark = '000016.INDX'
# 证券池 以贵州茅台为例
#instruments = ['000503.SZA']
# 起始资金
#capital_base = 1000000
# 2. 策略主体函数
# 初始化虚拟账户状态,只在第一个交易日运行
import requests
import json
import pandas as pd
import numpy as np
seed = 111
#os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
#import tensorflow as tf
from sklearn.preprocessing import scale
#tf.set_random_seed(seed)
#tf.random.set_seed(seed)
import warnings
warnings.filterwarnings("ignore")
数据截至时间(最新时间),你可以修改,例如 end_date = '2022-12-12',但是注意开始时间要与截至时间大于8个月时间差
start_date = '2022-03-01' #数据开始时间,你可以修改,例如 start_date = '2022-03-12'
# 回测结束时间
end_date =datetime.date.today().strftime("%Y-%m-%d") #数据截至时间(最新时间),你可以修改,例如 end_date = '2022-12-12',但是注意开始时间要与截至时间大于8个月时间差
下面代码是选择股票池代码,中证180(in_sse180) 沪深300(in_csi300) 上证50(in_sse50) in_szse100 in_csi800 中证500(in_csi500) in_csi100 in_csi1000 。 我选择的中证500(in_csi500)。
stocks = list(dNf[dNf['in_csi500']== 1]['instrument'])
你可以修改你喜欢的指数。当然也可以选择任意股票池,例如
stocks = ['000006.SZA', '000008.SZA','000009.SZA','000012.SZA','000021.SZA', '000025.SZA', '000027.SZA']
dNf = DataSource("index_constituent_CN_STOCK_A").read(start_date='2020-05-15', end_date='2020-05-15')#可以选择不同年份指数,修改时间start_date='2020-05-15',end_date='2020-05-15'
stocks = list(dNf[dNf['in_csi500']== 1]['instrument'])#在这里修改代码,例如改股票池为hs300 ;stocks = list(dNf[dNf['in_csi300']== 1]['instrument'])#
ts_df = DataSource("bar1d_CN_STOCK_A").read(instruments =stocks ,start_date=start_date, end_date=end_date).set_index(['instrument'])
def softmax(x):
x_row_max = x.max(axis=-1)
x_row_max = x_row_max.reshape(list(x.shape)[:-1] + [1])
x = x - x_row_max
x_exp = np.exp(x)
x_exp_row_sum = x_exp.sum(axis=-1).reshape(list(x.shape)[:-1] + [1])
softmax = x_exp / x_exp_row_sum
return softmax
#date = data.current_dt.strftime('%Y-%m-%d')
test_sate =end_date
#ts_df = DataSource("bar1d_CN_STOCK_A").read(instruments =stocks ,start_date="2021-06-01", end_date=date).set_index(['instrument'])
#ts_df['change'] = ts_df['close']/ts_df['pre_close'] -1
#ts_df = ts_df.set_index(['code'])
#date_label = ts_df.loc['000001.SZA'].set_index(['date']).sort_index()
date_label = ts_df.loc['000001.SZA'].set_index(['date']).sort_index()
test_input = []
test_output = []
length = 128
insts = []
test_cha = []
test_40 = []
for inst in stocks[0:298]:#[0:100]
fields = ['close', 'open', 'high', 'low', 'volume','amount']
field1 = ['close','open', 'high', 'low']
field2 = ['volume','amount' ]
#date_label = ts_df.loc[list(set(ts_df.index))[0]].set_index(['trade_date']).sort_index()
data = ts_df.loc[inst]#.dropna()
if len(data)<128:
continue
#data['time'] = data['time']#.apply(lambda x : datetime.datetime.strftime(x, "%Y-%m-%d"))
#data['date'] = data['date'].apply(lambda x : datetime.datetime.strftime(x, "%Y-%m-%d"))
data = data.set_index(['date']).sort_index()
data['return_-20'] = data['close']/data['close'].shift(20)-1
data = data.dropna()
s1 = date_label.loc[:test_sate].index[-1]
if len(data.loc[:test_sate])<128 :
continue
s2 = data.loc[:test_sate].index[-1]
if s1 > s2:
continue
test_input.append(scale(np.array(data.loc[:test_sate][fields][-length:].values)))
insts.append(inst)
#
url = 'https://www.heywhale.com/api/model/services/63b136ebcfd9524986b7b4a3?Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyT2lkIjoiNWFkOWU3NjA3MjM4NTE1ZDgwYjc4MDU5IiwiYXBwIjoibW9kZWwiLCJpYXQiOjE2NzI1NTgzNzd9.7O0CquLnwzkQ7c80y_UJkAh7hGVRS08t1LrwPebSNcc'
body = {
"content": {
"input": {
"data": np.array(test_input).tolist()
}
}
}
payload = json.dumps(body)
headers = {
'Content-Type': 'application/json'
}
for g in range(3):
response = requests.request("POST", url, headers=headers, data=payload)
if 'output' in json.loads(response.text).keys():
break
out = json.loads(response.text)['output']
hc=pd.DataFrame()
hc['out'] = softmax(np.array(out))[:,1]#tf.nn.softmax(out)[:,1]
hc['code'] = insts
下面提供两种处理方法 方法1,直接取分数排名前20名,这种具有适合高风险,高收益
sd = hc.sort_values('out')[-20:]
方法2,直接取分数小于0.82排名前20名,这种具有一定稳定性,推荐使用
sd = hc.sort_values('out').query('out <0.83')[20:]
sd = hc.sort_values('out').query('out <0.83')[-20:]
sd
import pandas as pd
import numpy as np
import random
import datetime
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
下面图用于监视所选择股票,因为有时趋势向下股票,也具有较高分数,所以需要认为判断下,选择趋势向上股票
for i in sd['code'].values:
print(i)
d1 = ts_df.loc[i]
#d1['date'] = d1['datw
d4 = d1.set_index('date').sort_index()[-40:]
fig = plt.figure(figsize=(30,10))
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot(d4['close'], color ="black",label='SZ50') ####黑线为收盘价
ax1.set_ylabel('close')
ax1.set_title('SZ50-Bond-Yield')
ax2 = ax1.twinx()
ax2.plot(d4['open'], color ="red",label='国债期限利差')####红线为开盘价
ax2.set_ylabel('open')
plt.legend(loc='best')
plt.show()