复制链接
克隆策略
In [1]:
# 本代码由可视化策略环境自动生成 2019年3月1日 14:18


# 回测起始时间
start_date = '2022-10-01'
# 回测结束时间
end_date = '2022-12-12'
# 策略比较参考标准,以沪深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")
#print(pd.read_csv(BytesIO(read_file('hc.csv'))))
#numpy.random.seed(111)
#instruments = np.random.choice(INS, size=200, replace=False)
dNf = DataSource("index_constituent_CN_STOCK_A").read(start_date='2020-05-15', end_date='2020-05-15')
stocks = list(dNf[dNf['in_csi300']== 1]['instrument'])#in_csi500 in_csi300

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

def initialize(context):
    # 设置手续费,买入时万3,卖出是千分之1.3,不足5元以5元计
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

# 策略交易逻辑,每个交易日运行一次
def handle_data(context, data):
    # 在这里添加策略代码
    date = data.current_dt.strftime('%Y-%m-%d') 
    test_sate = date
    ts_df = DataSource("bar1d_CN_STOCK_A").read(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()
    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'
    }

    response = requests.request("POST", url, headers=headers, data=payload)

    out = json.loads(response.text)['output']
    hc=pd.DataFrame()
    hc['out'] = softmax(np.array(out))[:,1]#tf.nn.softmax(out)[:,1]
    hc['code'] = insts
    sd = hc.sort_values('out')[-20:]
    bo =[]
    for b in sd['code']:
        ddd= ts_df.loc[b]
        ddd['change'] = ddd['close']/ddd['close'].shift(1) -1
        ddd = ddd.dropna()
        bo.append(ddd['change'].rolling(5).std().apply(lambda x : abs(x)).mean())
    sd['bo'] = bo
    sd= sd.sort_values('bo')
    # 给微信发送消息(添加模拟交易,并绑定微信生效)
    # send_message('美好的一天~')
    #g.security = sd['code'].iloc[0]
    # 要操作的股票:平安银行(g.为全局变量)
    #sid =list(ddk.values())[0]
    sid =sd['code'].iloc[0]
    instruments = {e.symbol: e for e, p in context.portfolio.positions.items()}
    if len(instruments)>0:
        for instrument in instruments:
            if instrument!= sid:
                context.order_target_percent(context.symbol(instrument),0)
    else:
        context.order_target_percent(context.symbol(sid),1)  
    
    
# 3. 启动回测

# 策略回测接口: https://bigquant.com/docs/module_trade.html
m = M.trade.v4(
    instruments=stocks,
    start_date=start_date,
    end_date=end_date,
    initialize=initialize,
    handle_data=handle_data,
    # 买入订单以开盘价成交
    volume_limit=0.025,
    order_price_field_buy='open',
    order_price_field_sell='close',
    capital_base=1000000,
    auto_cancel_non_tradable_orders=True,
    data_frequency='daily',
    price_type='真实价格',
    product_type='股票',
    plot_charts=True,
    backtest_only=False,
    benchmark='000300.HIX'

)
  • 收益率42.95%
  • 年化收益率608.18%
  • 基准收益率3.9%
  • 阿尔法5.9
  • 贝塔0.53
  • 夏普比率4.21
  • 胜率0.64
  • 盈亏比2.35
  • 收益波动率48.68%
  • 信息比率0.24
  • 最大回撤7.99%
bigcharts-data-start/{"__type":"tabs","__id":"bigchart-ae59508fea744c54867ea9e11c3d697e"}/bigcharts-data-end
In [ ]: