# 本代码由可视化策略环境自动生成 2022年3月19日 20:06
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 回测引擎:初始化函数,只执行一次
def m8_initialize_bigquant_run(context):
# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
#context.set_commission(PerOrder(buy_cost=0.00001, sell_cost=0.0001, min_cost=1))
# 设置买入的股票数量,这里买入预测股票列表排名靠前的5只
context.stock_count = 1
# 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
#context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])
# 每只股票的权重平均分配
context.stock_weights = 1/context.stock_count
# 设置每只股票占用的最大资金比例
context.max_cash_per_instrument = 1
context.options['hold_days'] = 0
# 回测引擎:每日数据处理函数,每天执行一次
def m8_handle_data_bigquant_run(context, data):
today = data.current_dt.strftime('%Y-%m-%d')
equities = {e.symbol: p for e, p in context.portfolio.positions.items() if p.amount>0}
stock_now = len(equities); #获取当前持仓股票数量
stock_count = context.stock_count
# 按日期过滤得到今日的预测数据
# 加载预测数据
df = context.options['data'].read_df()
df_today = df[df.date == data.current_dt.strftime('%Y-%m-%d')]
df_today.set_index('instrument')
now_stock = []
sell_stock = []
try:
buy_list = context.daily_buy_stock[today]
except:
buy_list = []
# 1. 资金分配
#is_staging = context.trading_day_index < context.options['hold_days'] # 是否在建仓期间(前 hold_days 天)
#stock_cash = context.portfolio.portfolio_value/stock_count
#cash_avg = context.portfolio.portfolio_value
#cash_for_buy = min(context.portfolio.cash, stock_cash)
#cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)
positions = {e.symbol: p.amount * p.last_sale_price
for e, p in context.perf_tracker.position_tracker.positions.items()}
#if not is_staging :
if 1==1 :
if len(equities) > 0:
for i in equities.keys():
last_sale_date = equities[i].last_sale_date # 上次交易日期
delta_days = data.current_dt - last_sale_date
hold_days = delta_days.days # 持仓天数
if hold_days >= context.options['hold_days'] and i not in buy_list :
print('日期:',today,'卖出2:',i)
context.order_target(context.symbol(i), 0)
sell_stock.append(i)
stock_now = stock_now -1
#print('日期:', today, '股票:', i, ' 卖出')
# 3. 生成买入订单
buy_num = stock_count - stock_now
#if is_staging :
# buy_num = 1
if len(buy_list)>0:
print('日期:', today, '选出股票数量:', len(buy_list))
if buy_num>0 and len(buy_list)>0 :
# 不再买入已经轮仓卖出和移动止损的股票,以防止出现空头持仓
buy_instruments = [i for i in buy_list if i not in now_stock][:buy_num]
print(buy_list)
cash_for_buy = context.portfolio.cash/len(buy_instruments)
for i, instrument in enumerate(buy_instruments):
current_price = data.current(context.symbol(instrument), 'price')
if cash_for_buy>0 and data.can_trade(context.symbol(instrument)):
amount = math.floor(cash_for_buy / current_price / 100) * 100
context.order(context.symbol(instrument), amount)
#if(instrument=='002735.SZA'):
print('日期:',today,'买入:',instrument)
else :
print('日期:',today,'无资金或不能交易未买入:',instrument)
# 回测引擎:准备数据,只执行一次
def m8_prepare_bigquant_run(context):
# 加载预测数据
df = context.options['data'].read_df()
# 函数:求满足开仓条件的股票列表
def open_pos_con(df):
return list(df[df['buy_condition']>0].instrument)
# 函数:求满足平仓条件的股票列表
def close_pos_con(df):
return list(df[df['sell_condition']>0].instrument)
# 每日卖出股票的数据框
context.daily_sell_stock= df.groupby('date').apply(close_pos_con)
# 每日买入股票的数据框
context.daily_buy_stock= df.groupby('date').apply(open_pos_con)
# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
def m8_before_trading_start_bigquant_run(context, data):
pass
m1 = M.instruments.v2(
start_date='2021-01-01',
end_date=T.live_run_param('trading_date', '2021-01-06'),
market='CN_STOCK_A',
instrument_list='',
max_count=0
)
m2 = M.input_features.v1(
features="""
#昨日MACD.dea-dif在 0到-0.1之间,调整幅度不大
ta_macd_dea(close_1/adjust_factor_1)
ta_macd_dif(close_1/adjust_factor_1)
#死叉前后两天(昨天,前天)收盘价必须一跌一涨
close_2
close_1
#昨天ma5死叉ma10
con1=ta_ma(close_1, 5)-ta_ma(close_1, 10)<0
#前天ma5在ma10之上
con2=ta_ma(close_2, 5)-ta_ma(close_2, 10)>0
#ma20上升
con3=ta_ma(close_1, 20)-ta_ma(close_2, 20)>0
#ma30上升
con4=ta_ma(close_1, 30)-ta_ma(close_2, 30)>0
#前天成交量ma5大于ma10
con5=ta_ma(volume_2, 5)-ta_ma(volume_2, 10)>0
#昨天成交量ma5*1.2大于ma10
con6=1.2*ta_ma(volume_1, 5)-ta_ma(volume_1, 10)>0
con7=ta_macd_dif(close_1)>0#昨天macd.dif大于0
con8=ta_macd_dea(close_1)>0#昨天macd.dea大于0
#昨日MACD.dea-dif在 0到-0.1之间,调整幅度不大
con9=ta_macd_dea(close_1)-ta_macd_dif(close_1)<0
con10=ta_macd_dea(close_1)-ta_macd_dif(close_1)>-0.1
#死叉前后两天(昨天,前天)收盘价必须一跌一涨
con11=(close_2>close_1)| (close_1>close_2)
con12=((open_0)<(close_1))
#
my1=where((con1)&(con2)&(con3)&(con4)&(con5)&(con6),1,0)
#
my2=where((con7)&(con8)&(con9)&(con10),1,0)
#
my3=where((con11),1,0)
#
my4=where((con12),1,0)
#按策略优质度排序
yzd1=where(my1==1,8,0)
yzd2=where(my2==1,6,0)
yzd3=where(my3==1,4,0)
yzd4=where(my4==1,2,0)
yzd=yzd1+yzd2+yzd3+yzd4
my=min(my1,my2,my3,my4)
buy_condition=where(my==1,1,0)
sell_condition=where(my<1,1,0)
# yzd=yzd1+yzd2+yzd3
# my=my1+my2+my3
# buy_condition=where(my==3,1,0)
# sell_condition=where(my<3,1,0)
"""
)
m5 = M.general_feature_extractor.v7(
instruments=m1.data,
features=m2.data,
start_date='',
end_date='',
before_start_days=60,
m_cached=False
)
m7 = M.derived_feature_extractor.v3(
input_data=m5.data,
features=m2.data,
date_col='date',
instrument_col='instrument',
drop_na=False,
remove_extra_columns=False,
user_functions={}
)
m6 = M.chinaa_stock_filter.v1(
input_data=m7.data,
index_constituent_cond=['全部'],
board_cond=['上证主板', '深证主板'],
industry_cond=['全部'],
st_cond=['正常'],
delist_cond=['非退市'],
output_left_data=False
)
m11 = M.dropnan.v2(
input_data=m6.data
)
m9 = M.sort.v4(
input_ds=m11.data,
sort_by='yzd',
group_by='date',
keep_columns='--',
ascending=False
)
m3 = M.filter.v3(
input_data=m9.sorted_data,
expr='my==1',
output_left_data=False
)
m8 = M.trade.v4(
instruments=m1.data,
options_data=m3.data,
start_date='',
end_date='',
initialize=m8_initialize_bigquant_run,
handle_data=m8_handle_data_bigquant_run,
prepare=m8_prepare_bigquant_run,
before_trading_start=m8_before_trading_start_bigquant_run,
volume_limit=0,
order_price_field_buy='open',
order_price_field_sell='open',
capital_base=100000,
auto_cancel_non_tradable_orders=True,
data_frequency='daily',
price_type='真实价格',
product_type='股票',
plot_charts=True,
backtest_only=False,
benchmark=''
)
m10 = M.filter.v3(
input_data=m11.data,
expr='(con1==1) & (con2==1) & (con3==1) & (con4==1) & (con5==1) & (con6==1 ) &(date==\'2021-01-05\')',
output_left_data=False
)
m4 = M.filter.v3(
input_data=m10.data,
expr='(con7==1) & (con8==1) & (con9==1) & (con10==1)',
output_left_data=False
)
m12 = M.filter.v3(
input_data=m4.data,
expr='con11==1',
output_left_data=False
)
[2022-03-19 19:59:37.769425] INFO: moduleinvoker: instruments.v2 开始运行..
[2022-03-19 19:59:37.776823] INFO: moduleinvoker: 命中缓存
[2022-03-19 19:59:37.778195] INFO: moduleinvoker: instruments.v2 运行完成[0.008775s].
[2022-03-19 19:59:37.781698] INFO: moduleinvoker: input_features.v1 开始运行..
[2022-03-19 19:59:37.790539] INFO: moduleinvoker: 命中缓存
[2022-03-19 19:59:37.791841] INFO: moduleinvoker: input_features.v1 运行完成[0.010135s].
[2022-03-19 19:59:37.804799] INFO: moduleinvoker: general_feature_extractor.v7 开始运行..
[2022-03-19 19:59:39.734612] INFO: 基础特征抽取: 年份 2020, 特征行数=179288
[2022-03-19 19:59:41.703059] INFO: 基础特征抽取: 年份 2021, 特征行数=12364
[2022-03-19 19:59:41.758646] INFO: 基础特征抽取: 总行数: 191652
[2022-03-19 19:59:41.760714] INFO: moduleinvoker: general_feature_extractor.v7 运行完成[3.955923s].
[2022-03-19 19:59:41.768348] INFO: moduleinvoker: derived_feature_extractor.v3 开始运行..
[2022-03-19 19:59:45.726082] INFO: derived_feature_extractor: 提取完成 ta_macd_dea(close_1/adjust_factor_1), 3.527s
[2022-03-19 19:59:49.828085] INFO: derived_feature_extractor: 提取完成 ta_macd_dif(close_1/adjust_factor_1), 4.100s
[2022-03-19 19:59:57.087216] INFO: derived_feature_extractor: 提取完成 con1=ta_ma(close_1, 5)-ta_ma(close_1, 10)<0, 7.258s
[2022-03-19 20:00:04.984641] INFO: derived_feature_extractor: 提取完成 con2=ta_ma(close_2, 5)-ta_ma(close_2, 10)>0, 7.896s
[2022-03-19 20:00:13.094198] INFO: derived_feature_extractor: 提取完成 con3=ta_ma(close_1, 20)-ta_ma(close_2, 20)>0, 8.108s
[2022-03-19 20:00:20.760883] INFO: derived_feature_extractor: 提取完成 con4=ta_ma(close_1, 30)-ta_ma(close_2, 30)>0, 7.665s
[2022-03-19 20:00:28.218443] INFO: derived_feature_extractor: 提取完成 con5=ta_ma(volume_2, 5)-ta_ma(volume_2, 10)>0, 7.456s
[2022-03-19 20:00:35.996791] INFO: derived_feature_extractor: 提取完成 con6=1.2*ta_ma(volume_1, 5)-ta_ma(volume_1, 10)>0, 7.777s
[2022-03-19 20:00:40.178145] INFO: derived_feature_extractor: 提取完成 con7=ta_macd_dif(close_1)>0#昨天macd.dif大于0, 4.179s
[2022-03-19 20:00:43.813720] INFO: derived_feature_extractor: 提取完成 con8=ta_macd_dea(close_1)>0#昨天macd.dea大于0, 3.634s
[2022-03-19 20:00:51.579050] INFO: derived_feature_extractor: 提取完成 con9=ta_macd_dea(close_1)-ta_macd_dif(close_1)<0, 7.764s
[2022-03-19 20:00:59.029948] INFO: derived_feature_extractor: 提取完成 con10=ta_macd_dea(close_1)-ta_macd_dif(close_1)>-0.1, 7.449s
[2022-03-19 20:00:59.032979] INFO: derived_feature_extractor: 提取完成 con11=(close_2>close_1)| (close_1>close_2), 0.001s
[2022-03-19 20:00:59.035179] INFO: derived_feature_extractor: 提取完成 con12=((open_0)[2022-03-19 20:00:59.038212] INFO: derived_feature_extractor: 提取完成 my1=where((con1)&(con2)&(con3)&(con4)&(con5)&(con6),1,0), 0.002s[2022-03-19 20:00:59.040941] INFO: derived_feature_extractor: 提取完成 my2=where((con7)&(con8)&(con9)&(con10),1,0), 0.002s[2022-03-19 20:00:59.062778] INFO: derived_feature_extractor: 提取完成 my3=where((con11),1,0), 0.002s[2022-03-19 20:00:59.065723] INFO: derived_feature_extractor: 提取完成 my4=where((con12),1,0), 0.002s[2022-03-19 20:00:59.068090] INFO: derived_feature_extractor: 提取完成 yzd1=where(my1==1,8,0), 0.001s[2022-03-19 20:00:59.070306] INFO: derived_feature_extractor: 提取完成 yzd2=where(my2==1,6,0), 0.001s[2022-03-19 20:00:59.073326] INFO: derived_feature_extractor: 提取完成 yzd3=where(my3==1,4,0), 0.002s[2022-03-19 20:00:59.076342] INFO: derived_feature_extractor: 提取完成 yzd4=where(my4==1,2,0), 0.002s[2022-03-19 20:00:59.079351] INFO: derived_feature_extractor: 提取完成 yzd=yzd1+yzd2+yzd3+yzd4, 0.002s[2022-03-19 20:00:59.083988] INFO: derived_feature_extractor: 提取完成 my=min(my1,my2,my3,my4), 0.003s[2022-03-19 20:00:59.087037] INFO: derived_feature_extractor: 提取完成 buy_condition=where(my==1,1,0), 0.002s[2022-03-19 20:00:59.089815] INFO: derived_feature_extractor: 提取完成 sell_condition=where(my<1,1,0), 0.001s[2022-03-19 20:00:59.570291] INFO: derived_feature_extractor: /y_2020, 179288[2022-03-19 20:00:59.733086] INFO: derived_feature_extractor: /y_2021, 12364[2022-03-19 20:00:59.873859] INFO: moduleinvoker: derived_feature_extractor.v3 运行完成[78.105499s].[2022-03-19 20:00:59.882431] INFO: moduleinvoker: chinaa_stock_filter.v1 开始运行..[2022-03-19 20:01:00.905414] INFO: A股股票过滤: 过滤 /y_2020, 123161/0/179288[2022-03-19 20:01:01.231017] INFO: A股股票过滤: 过滤 /y_2021, 8464/0/12364[2022-03-19 20:01:01.328825] INFO: A股股票过滤: 过滤完成, 131625 + 0[2022-03-19 20:01:01.360158] INFO: moduleinvoker: chinaa_stock_filter.v1 运行完成[1.47772s].[2022-03-19 20:01:01.368311] INFO: moduleinvoker: dropnan.v2 开始运行..[2022-03-19 20:01:01.629308] INFO: dropnan: /y_2020, 30562/123161[2022-03-19 20:01:01.711451] INFO: dropnan: /y_2021, 8380/8464[2022-03-19 20:01:01.766997] INFO: dropnan: 行数: 38942/131625[2022-03-19 20:01:01.772651] INFO: moduleinvoker: dropnan.v2 运行完成[0.404337s].[2022-03-19 20:01:01.778700] INFO: moduleinvoker: sort.v4 开始运行..[2022-03-19 20:01:02.147050] INFO: moduleinvoker: sort.v4 运行完成[0.368354s].[2022-03-19 20:01:02.155977] INFO: moduleinvoker: filter.v3 开始运行..[2022-03-19 20:01:02.187718] INFO: filter: 使用表达式 my==1 过滤[2022-03-19 20:01:02.394582] INFO: filter: 过滤 /data, 11/0/38942[2022-03-19 20:01:02.417804] INFO: moduleinvoker: filter.v3 运行完成[0.261821s].[2022-03-19 20:01:02.484376] INFO: moduleinvoker: backtest.v8 开始运行..[2022-03-19 20:01:02.488995] INFO: backtest: biglearning backtest:V8.6.2[2022-03-19 20:01:02.541152] INFO: backtest: product_type:stock by specified[2022-03-19 20:01:02.668398] INFO: moduleinvoker: cached.v2 开始运行..[2022-03-19 20:01:02.677652] INFO: moduleinvoker: 命中缓存[2022-03-19 20:01:02.679533] INFO: moduleinvoker: cached.v2 运行完成[0.011161s].[2022-03-19 20:01:03.503631] INFO: algo: TradingAlgorithm V1.8.7[2022-03-19 20:01:03.662321] INFO: algo: trading transform...[2022-03-19 20:01:03.956550] INFO: Performance: Simulated 3 trading days out of 3.[2022-03-19 20:01:03.958333] INFO: Performance: first open: 2021-01-04 09:30:00+00:00[2022-03-19 20:01:03.959300] INFO: Performance: last close: 2021-01-06 15:00:00+00:00[2022-03-19 20:01:21.664508] INFO: moduleinvoker: backtest.v8 运行完成[19.180128s].[2022-03-19 20:01:21.666371] INFO: moduleinvoker: trade.v4 运行完成[19.241462s].[2022-03-19 20:01:21.692690] INFO: moduleinvoker: filter.v3 开始运行..[2022-03-19 20:01:21.735031] INFO: filter: 使用表达式 (con1==1) & (con2==1) & (con3==1) & (con4==1) & (con5==1) & (con6==1 ) &(date=='2021-01-05') 过滤[2022-03-19 20:01:21.969331] INFO: filter: 过滤 /y_2020, 0/0/30562[2022-03-19 20:01:22.106000] INFO: filter: 过滤 /y_2021, 6/0/8380[2022-03-19 20:01:22.187813] INFO: moduleinvoker: filter.v3 运行完成[0.495114s].[2022-03-19 20:01:22.214261] INFO: moduleinvoker: filter.v3 开始运行..[2022-03-19 20:01:22.266254] INFO: filter: 使用表达式 (con7==1) & (con8==1) & (con9==1) & (con10==1) 过滤[2022-03-19 20:01:22.461858] INFO: filter: 过滤 /y_2021, 3/0/6[2022-03-19 20:01:22.504905] INFO: moduleinvoker: filter.v3 运行完成[0.290654s].[2022-03-19 20:01:22.516499] INFO: moduleinvoker: filter.v3 开始运行..[2022-03-19 20:01:22.538425] INFO: filter: 使用表达式 con11==1 过滤[2022-03-19 20:01:22.717852] INFO: filter: 过滤 /y_2021, 3/0/3[2022-03-19 20:01:22.788911] INFO: moduleinvoker: filter.v3 运行完成[0.272388s].
m10.data.read()
其中2021-01-04的000723的ta_macd指标与通达信指标计算结果不一致,最离谱的是dea与dif的值的高低也有差别