复制链接
克隆策略
In [21]:
# 回测起始时间
# 策略比较参考标准,以沪深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")

数据开始时间,你可以修改,例如 start_date = '2022-03-12'

数据截至时间(最新时间),你可以修改,例如 end_date = '2022-12-12',但是注意开始时间要与截至时间大于8个月时间差

In [11]:
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']
In [23]:
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'])#
In [14]:
ts_df = DataSource("bar1d_CN_STOCK_A").read(instruments =stocks ,start_date=start_date, end_date=end_date).set_index(['instrument']) 
In [24]:
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
In [26]:
    #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:]
In [36]:
sd = hc.sort_values('out').query('out <0.83')[-20:]
In [37]:
sd
Out[37]:
out code
21 0.768791 000400.SZA
291 0.769087 600282.SHA
250 0.769096 600008.SHA
81 0.771301 000988.SZA
7 0.771923 000028.SZA
111 0.772239 002152.SZA
11 0.777058 000060.SZA
144 0.779593 002373.SZA
58 0.780040 000778.SZA
110 0.787308 002131.SZA
241 0.791649 300315.SZA
85 0.800638 000999.SZA
24 0.801362 000426.SZA
135 0.804082 002302.SZA
200 0.806438 002867.SZA
224 0.807856 300159.SZA
56 0.824991 000761.SZA
83 0.827293 000997.SZA
14 0.828209 000066.SZA
283 0.828595 600201.SHA
In [38]:
import pandas as pd
import numpy as np
import random
import datetime
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

下面图用于监视所选择股票,因为有时趋势向下股票,也具有较高分数,所以需要认为判断下,选择趋势向上股票

In [55]:
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()
000400.SZA
600282.SHA
600008.SHA
000988.SZA
000028.SZA
002152.SZA
000060.SZA
002373.SZA
000778.SZA
002131.SZA
300315.SZA
000999.SZA
000426.SZA
002302.SZA
002867.SZA
300159.SZA
000761.SZA
000997.SZA
000066.SZA
600201.SHA
In [ ]: