AI量化是未来趋势,金融机构对量化方向的人才求贤若渴,存在大量的人才缺失。对于金融知识一片空白的小白来说,难以听懂量化中专业的术语。因此,BigQuant整理了一套适合金融小白的培训课程,精心挑选量化中所需要具备的金融基础知识,为大家打开金融世界的一扇门。点击下方的视频来学习吧!(视频会持续更新!)
更多的知识需要个人不断地积累和沉淀,有什么不懂的就来问小Q吧!
AI量化是未来趋势,金融机构对量化方向的人才求贤若渴,存在大量的人才缺失。对于金融知识一片空白的小白来说,难以听懂量化中专业的术语。因此,BigQuant整理了一套适合金融小白的培训课程,精心挑选量化中所需要具备的金融基础知识,为大家打开金融世界的一扇门。点击下方的视频来学习吧!(视频会持续更新!)
更多的知识需要个人不断地积累和沉淀,有什么不懂的就来问小Q吧!
课程相关案例及源代码
1.1量化数据研究
# 本代码由可视化策略环境自动生成 2020年9月23日 14:39
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
m1 = M.instruments.v2(
start_date='2019-03-01',
end_date='2019-03-01',
market='CN_STOCK_A',
instrument_list='',
max_count=0
)
m3 = M.input_features.v1(
features="""# #号开始的表示注释
# 多个特征,每行一个,可以包含基础特征和衍生特征
pe_ttm_0
"""
)
m15 = M.general_feature_extractor.v7(
instruments=m1.data,
features=m3.data,
start_date='',
end_date='',
before_start_days=0
)
m4 = M.dropnan.v2(
input_data=m15.data
)
[2019-07-13 13:56:39.598088] INFO: bigquant: instruments.v2 开始运行..
[2019-07-13 13:56:39.724063] INFO: bigquant: 命中缓存
[2019-07-13 13:56:39.726585] INFO: bigquant: instruments.v2 运行完成[0.128489s].
[2019-07-13 13:56:39.731266] INFO: bigquant: input_features.v1 开始运行..
[2019-07-13 13:56:39.782459] INFO: bigquant: 命中缓存
[2019-07-13 13:56:39.788018] INFO: bigquant: input_features.v1 运行完成[0.056733s].
[2019-07-13 13:56:39.919480] INFO: bigquant: general_feature_extractor.v7 开始运行..
[2019-07-13 13:56:40.018003] INFO: bigquant: 命中缓存
[2019-07-13 13:56:40.020095] INFO: bigquant: general_feature_extractor.v7 运行完成[0.100616s].
[2019-07-13 13:56:40.023082] INFO: bigquant: dropnan.v1 开始运行..
[2019-07-13 13:56:40.075193] INFO: bigquant: 命中缓存
[2019-07-13 13:56:40.077928] INFO: bigquant: dropnan.v1 运行完成[0.054836s].
1.2因子构建
# 本代码由可视化策略环境自动生成 2019年7月13日 14:07
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
m1 = M.instruments.v2(
start_date='2016-01-01',
end_date='2016-03-01',
market='CN_STOCK_A',
instrument_list='',
max_count=0
)
m2 = M.advanced_auto_labeler.v2(
instruments=m1.data,
label_expr="""# #号开始的表示注释
# 0. 每行一个,顺序执行,从第二个开始,可以使用label字段
# 1. 可用数据字段见 https://bigquant.com/docs/develop/datasource/deprecated/history_data.html
# 添加benchmark_前缀,可使用对应的benchmark数据
# 2. 可用操作符和函数见 `表达式引擎 <https://bigquant.com/docs/develop/bigexpr/usage.html>`_
# 计算收益:5日收盘价(作为卖出价格)除以明日开盘价(作为买入价格)
shift(close, -5) / shift(open, -1)
""",
start_date='',
end_date='',
benchmark='000300.SHA',
drop_na_label=True,
cast_label_int=True
)
m3 = M.standardlize.v8(
input_1=m2.data,
columns_input=['label']
)
[2019-07-13 14:02:34.411943] INFO: bigquant: instruments.v2 开始运行..
[2019-07-13 14:02:34.558733] INFO: bigquant: instruments.v2 运行完成[0.146801s].
[2019-07-13 14:02:34.565602] INFO: bigquant: advanced_auto_labeler.v2 开始运行..
[2019-07-13 14:02:35.058736] INFO: 自动标注(股票): 加载历史数据: 94453 行
[2019-07-13 14:02:35.060750] INFO: 自动标注(股票): 开始标注 ..
[2019-07-13 14:02:35.653953] INFO: bigquant: advanced_auto_labeler.v2 运行完成[1.088338s].
[2019-07-13 14:02:35.661276] INFO: bigquant: standardlize.v8 开始运行..
[2019-07-13 14:02:35.958987] INFO: bigquant: standardlize.v8 运行完成[0.297696s].
2.1 固定买卖周期逻辑
# 本代码由可视化策略环境自动生成 2019年9月19日 16:25
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 回测引擎:初始化函数,只执行一次
def m19_initialize_bigquant_run(context):
# 加载预测数据
context.ranker_prediction = context.options['data'].read_df()
# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
# 预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)
# 设置买入的股票数量,这里买入预测股票列表排名靠前的5只
stock_count = 5
# 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])
# 设置每只股票占用的最大资金比例
context.max_cash_per_instrument = 0.2
context.options['hold_days'] = 3
# 回测引擎:每日数据处理函数,每天执行一次
def m19_handle_data_bigquant_run(context, data):
# 按日期过滤得到今日的预测数据
ranker_prediction = context.ranker_prediction[
context.ranker_prediction.date == data.current_dt.strftime('%Y-%m-%d')]
# 1. 资金分配
# 平均持仓时间是hold_days,每日都将买入股票,每日预期使用 1/hold_days 的资金
# 实际操作中,会存在一定的买入误差,所以在前hold_days天,等量使用资金;之后,尽量使用剩余资金(这里设置最多用等量的1.5倍)
is_staging = context.trading_day_index+1 < context.options['hold_days'] # 是否在建仓期间(前 hold_days 天)
cash_avg = context.portfolio.portfolio_value / (context.options['hold_days'])
cash_for_buy = min(context.portfolio.cash, cash_avg)
positions = {e.symbol: p.amount * p.last_sale_price
for e, p in context.portfolio.positions.items()}
# 2. 持有固定天数卖出
#----------------------------START:持有固定交易日天数卖出---------------------------
today = data.current_dt.strftime('%Y-%m-%d')
# 不是建仓期(在前hold_days属于建仓期)
if not is_staging:
equities = {e.symbol: p for e, p in context.portfolio.positions.items() if p.amount>0}
for instrument in equities:
sid = equities[instrument].sid # 交易标的
# 今天和上次交易的时间相隔hold_days就全部卖出
dt = pd.to_datetime(D.trading_days(end_date = today).iloc[-context.options['hold_days']+1].values[0])
if pd.to_datetime(equities[instrument].last_sale_date.strftime('%Y-%m-%d')) <= dt and data.can_trade(context.symbol(instrument)):
context.order_target_percent(sid, 0)
#--------------------------------END:持有固定天数卖出---------------------------
# 3. 生成买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票,这里要过滤掉已经持仓的股票否则last_sale_date会被再次买入覆盖
buy_cash_weights = context.stock_weights
buy_instruments = list(ranker_prediction[~ranker_prediction.instrument.isin(positions)].instrument[:len(buy_cash_weights)])
max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
for i, instrument in enumerate(buy_instruments):
cash = cash_for_buy * buy_cash_weights[i]
if cash > max_cash_per_instrument - positions.get(instrument, 0):
# 确保股票持仓量不会超过每次股票最大的占用资金量
cash = max_cash_per_instrument - positions.get(instrument, 0)
if cash > 0:
context.order_value(context.symbol(instrument), cash)
# 回测引擎:准备数据,只执行一次
def m19_prepare_bigquant_run(context):
pass
m1 = M.instruments.v2(
start_date='2010-01-01',
end_date='2015-01-01',
market='CN_STOCK_A',
instrument_list='',
max_count=0
)
m2 = M.advanced_auto_labeler.v2(
instruments=m1.data,
label_expr="""# #号开始的表示注释
# 0. 每行一个,顺序执行,从第二个开始,可以使用label字段
# 1. 可用数据字段见 https://bigquant.com/docs/develop/datasource/deprecated/history_data.html
# 添加benchmark_前缀,可使用对应的benchmark数据
# 2. 可用操作符和函数见 `表达式引擎 <https://bigquant.com/docs/develop/bigexpr/usage.html>`_
# 计算收益:5日收盘价(作为卖出价格)除以明日开盘价(作为买入价格)
shift(close, -5) / shift(open, -1)
# 极值处理:用1%和99%分位的值做clip
clip(label, all_quantile(label, 0.01), all_quantile(label, 0.99))
# 将分数映射到分类,这里使用20个分类
all_wbins(label, 20)
# 过滤掉一字涨停的情况 (设置label为NaN,在后续处理和训练中会忽略NaN的label)
where(shift(high, -1) == shift(low, -1), NaN, label)
""",
start_date='',
end_date='',
benchmark='000300.SHA',
drop_na_label=True,
cast_label_int=True
)
m3 = M.input_features.v1(
features="""# #号开始的表示注释
# 多个特征,每行一个,可以包含基础特征和衍生特征
return_5
return_10
return_20
avg_amount_0/avg_amount_5
avg_amount_5/avg_amount_20
rank_avg_amount_0/rank_avg_amount_5
rank_avg_amount_5/rank_avg_amount_10
rank_return_0
rank_return_5
rank_return_10
rank_return_0/rank_return_5
rank_return_5/rank_return_10
pe_ttm_0
"""
)
m15 = M.general_feature_extractor.v7(
instruments=m1.data,
features=m3.data,
start_date='',
end_date='',
before_start_days=0
)
m16 = M.derived_feature_extractor.v3(
input_data=m15.data,
features=m3.data,
date_col='date',
instrument_col='instrument',
drop_na=False,
remove_extra_columns=False
)
m7 = M.join.v3(
data1=m2.data,
data2=m16.data,
on='date,instrument',
how='inner',
sort=False
)
m13 = M.dropnan.v1(
input_data=m7.data
)
m6 = M.stock_ranker_train.v5(
training_ds=m13.data,
features=m3.data,
learning_algorithm='排序',
number_of_leaves=30,
minimum_docs_per_leaf=1000,
number_of_trees=20,
learning_rate=0.1,
max_bins=1023,
feature_fraction=1,
m_lazy_run=False
)
m9 = M.instruments.v2(
start_date=T.live_run_param('trading_date', '2015-01-01'),
end_date=T.live_run_param('trading_date', '2017-01-01'),
market='CN_STOCK_A',
instrument_list='',
max_count=0
)
m17 = M.general_feature_extractor.v7(
instruments=m9.data,
features=m3.data,
start_date='',
end_date='',
before_start_days=0
)
m18 = M.derived_feature_extractor.v3(
input_data=m17.data,
features=m3.data,
date_col='date',
instrument_col='instrument',
drop_na=False,
remove_extra_columns=False
)
m14 = M.dropnan.v1(
input_data=m18.data
)
m8 = M.stock_ranker_predict.v5(
model=m6.model,
data=m14.data,
m_lazy_run=False
)
m19 = M.trade.v4(
instruments=m9.data,
options_data=m8.predictions,
start_date='',
end_date='',
initialize=m19_initialize_bigquant_run,
handle_data=m19_handle_data_bigquant_run,
prepare=m19_prepare_bigquant_run,
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.SHA'
)
[2019-09-19 16:22:37.314384] INFO: bigquant: instruments.v2 开始运行..
[2019-09-19 16:22:37.467404] INFO: bigquant: 命中缓存
[2019-09-19 16:22:37.469960] INFO: bigquant: instruments.v2 运行完成[0.155594s].
[2019-09-19 16:22:37.473510] INFO: bigquant: advanced_auto_labeler.v2 开始运行..
[2019-09-19 16:22:37.598530] INFO: bigquant: 命中缓存
[2019-09-19 16:22:37.601114] INFO: bigquant: advanced_auto_labeler.v2 运行完成[0.127574s].
[2019-09-19 16:22:37.604060] INFO: bigquant: input_features.v1 开始运行..
[2019-09-19 16:22:37.790840] INFO: bigquant: 命中缓存
[2019-09-19 16:22:37.793394] INFO: bigquant: input_features.v1 运行完成[0.189287s].
[2019-09-19 16:22:37.868594] INFO: bigquant: general_feature_extractor.v7 开始运行..
[2019-09-19 16:22:37.998596] INFO: bigquant: 命中缓存
[2019-09-19 16:22:38.001394] INFO: bigquant: general_feature_extractor.v7 运行完成[0.132778s].
[2019-09-19 16:22:38.004921] INFO: bigquant: derived_feature_extractor.v3 开始运行..
[2019-09-19 16:22:38.121376] INFO: bigquant: 命中缓存
[2019-09-19 16:22:38.123756] INFO: bigquant: derived_feature_extractor.v3 运行完成[0.118816s].
[2019-09-19 16:22:38.127014] INFO: bigquant: join.v3 开始运行..
[2019-09-19 16:22:38.263526] INFO: bigquant: 命中缓存
[2019-09-19 16:22:38.267304] INFO: bigquant: join.v3 运行完成[0.140269s].
[2019-09-19 16:22:38.271402] INFO: bigquant: dropnan.v1 开始运行..
[2019-09-19 16:22:38.338102] INFO: bigquant: 命中缓存
[2019-09-19 16:22:38.340817] INFO: bigquant: dropnan.v1 运行完成[0.069399s].
[2019-09-19 16:22:38.344412] INFO: bigquant: stock_ranker_train.v5 开始运行..
[2019-09-19 16:22:38.581109] INFO: bigquant: 命中缓存
[2019-09-19 16:22:38.861015] INFO: bigquant: stock_ranker_train.v5 运行完成[0.516574s].
[2019-09-19 16:22:38.864610] INFO: bigquant: instruments.v2 开始运行..
[2019-09-19 16:22:38.973400] INFO: bigquant: 命中缓存
[2019-09-19 16:22:38.976130] INFO: bigquant: instruments.v2 运行完成[0.111477s].
[2019-09-19 16:22:39.140937] INFO: bigquant: general_feature_extractor.v7 开始运行..
[2019-09-19 16:22:39.241174] INFO: bigquant: 命中缓存
[2019-09-19 16:22:39.243482] INFO: bigquant: general_feature_extractor.v7 运行完成[0.102433s].
[2019-09-19 16:22:39.252239] INFO: bigquant: derived_feature_extractor.v3 开始运行..
[2019-09-19 16:22:39.411864] INFO: bigquant: 命中缓存
[2019-09-19 16:22:39.414129] INFO: bigquant: derived_feature_extractor.v3 运行完成[0.161888s].
[2019-09-19 16:22:39.418185] INFO: bigquant: dropnan.v1 开始运行..
[2019-09-19 16:22:39.539314] INFO: bigquant: 命中缓存
[2019-09-19 16:22:39.543370] INFO: bigquant: dropnan.v1 运行完成[0.125149s].
[2019-09-19 16:22:39.555560] INFO: bigquant: stock_ranker_predict.v5 开始运行..
[2019-09-19 16:22:39.759810] INFO: bigquant: 命中缓存
[2019-09-19 16:22:39.764539] INFO: bigquant: stock_ranker_predict.v5 运行完成[0.208961s].
[2019-09-19 16:22:39.895190] INFO: bigquant: backtest.v8 开始运行..
[2019-09-19 16:22:39.904613] INFO: bigquant: biglearning backtest:V8.2.12
[2019-09-19 16:22:39.907244] INFO: bigquant: product_type:stock by specified
[2019-09-19 16:22:40.270991] INFO: bigquant: cached.v2 开始运行..
[2019-09-19 16:22:40.362436] INFO: bigquant: 命中缓存
[2019-09-19 16:22:40.364843] INFO: bigquant: cached.v2 运行完成[0.093865s].
[2019-09-19 16:22:52.283166] INFO: algo: TradingAlgorithm V1.5.8
[2019-09-19 16:22:55.159307] INFO: algo: trading transform...
[2019-09-19 16:23:07.259762] INFO: algo: handle_splits get splits [dt:2015-04-16 00:00:00+00:00] [asset:Equity(683 [300390.SZA]), ratio:0.6630872981901985]
[2019-09-19 16:23:07.263554] INFO: Position: position stock handle split[sid:683, orig_amount:1100, new_amount:1658.0, orig_cost:39.020005629016886, new_cost:25.87, ratio:0.6630872981901985, last_sale_price:24.700001857584894]
[2019-09-19 16:23:07.268982] INFO: Position: after split: PositionStock(asset:Equity(683 [300390.SZA]), amount:1658.0, cost_basis:25.87, last_sale_price:37.25)
[2019-09-19 16:23:07.273662] INFO: Position: returning cash: 22.4
[2019-09-19 16:23:10.762021] INFO: algo: handle_splits get splits [dt:2015-05-15 00:00:00+00:00] [asset:Equity(2169 [000736.SZA]), ratio:0.9987076835878506]
[2019-09-19 16:23:10.768078] INFO: Position: position stock handle split[sid:2169, orig_amount:16900, new_amount:16921.0, orig_cost:15.350013840478981, new_cost:15.33, ratio:0.9987076835878506, last_sale_price:15.459995437209697]
[2019-09-19 16:23:10.773651] INFO: Position: after split: PositionStock(asset:Equity(2169 [000736.SZA]), amount:16921.0, cost_basis:15.33, last_sale_price:15.480000495910645)
[2019-09-19 16:23:10.775780] INFO: Position: returning cash: 13.43
[2019-09-19 16:23:11.696404] INFO: algo: handle_splits get splits [dt:2015-05-22 00:00:00+00:00] [asset:Equity(1892 [300119.SZA]), ratio:0.9944382925109119]
[2019-09-19 16:23:11.698545] INFO: Position: position stock handle split[sid:1892, orig_amount:6500, new_amount:6536.0, orig_cost:16.360001220667378, new_cost:16.27, ratio:0.9944382925109119, last_sale_price:17.88000194086899]
[2019-09-19 16:23:11.700719] INFO: Position: after split: PositionStock(asset:Equity(1892 [300119.SZA]), amount:6536.0, cost_basis:16.27, last_sale_price:17.98000144958496)
[2019-09-19 16:23:11.702665] INFO: Position: returning cash: 6.32
[2019-09-19 16:23:16.008936] INFO: algo: handle_splits get splits [dt:2015-06-23 00:00:00+00:00] [asset:Equity(2250 [300077.SZA]), ratio:0.9998031228727998]
[2019-09-19 16:23:16.011546] INFO: Position: position stock handle split[sid:2250, orig_amount:3600, new_amount:3600.0, orig_cost:51.989998192647114, new_cost:51.98, ratio:0.9998031228727998, last_sale_price:50.770001359017975]
[2019-09-19 16:23:16.014384] INFO: Position: after split: PositionStock(asset:Equity(2250 [300077.SZA]), amount:3600.0, cost_basis:51.98, last_sale_price:50.779998779296875)
[2019-09-19 16:23:16.016089] INFO: Position: returning cash: 35.99
[2019-09-19 16:23:16.913829] INFO: algo: handle_splits get splits [dt:2015-06-29 00:00:00+00:00] [asset:Equity(1560 [000716.SZA]), ratio:0.9974734355876671]
[2019-09-19 16:23:16.916250] INFO: Position: position stock handle split[sid:1560, orig_amount:4700, new_amount:4711.0, orig_cost:23.850001497022188, new_cost:23.79, ratio:0.9974734355876671, last_sale_price:23.689994095207094]
[2019-09-19 16:23:16.918203] INFO: Position: after split: PositionStock(asset:Equity(1560 [000716.SZA]), amount:4711.0, cost_basis:23.79, last_sale_price:23.75)
[2019-09-19 16:23:16.920206] INFO: Position: returning cash: 21.44
[2019-09-19 16:23:18.798835] INFO: algo: handle_splits get splits [dt:2015-07-08 00:00:00+00:00] [asset:Equity(2351 [002133.SZA]), ratio:0.9865547066162149]
[2019-09-19 16:23:20.869417] INFO: algo: handle_splits get splits [dt:2015-07-15 00:00:00+00:00] [asset:Equity(915 [300006.SZA]), ratio:0.9972134668014038]
[2019-09-19 16:23:20.872141] INFO: Position: position stock handle split[sid:915, orig_amount:3000, new_amount:3008.0, orig_cost:41.50000433930211, new_cost:41.38, ratio:0.9972134668014038, last_sale_price:35.789994518919066]
[2019-09-19 16:23:20.874222] INFO: Position: after split: PositionStock(asset:Equity(915 [300006.SZA]), amount:3008.0, cost_basis:41.38, last_sale_price:35.8900032043457)
[2019-09-19 16:23:20.876093] INFO: Position: returning cash: 13.71
[2019-09-19 16:23:30.611719] INFO: algo: handle_splits get splits [dt:2015-09-17 00:00:00+00:00] [asset:Equity(821 [600446.SHA]), ratio:0.33293942190663656]
[2019-09-19 16:23:30.615900] INFO: Position: position stock handle split[sid:821, orig_amount:1400, new_amount:4204.0, orig_cost:114.0000000482192, new_cost:37.96, ratio:0.33293942190663656, last_sale_price:33.80999677054322]
[2019-09-19 16:23:30.618103] INFO: Position: after split: PositionStock(asset:Equity(821 [600446.SHA]), amount:4204.0, cost_basis:37.96, last_sale_price:101.54999542236328)
[2019-09-19 16:23:30.620093] INFO: Position: returning cash: 32.77
[2019-09-19 16:23:59.022229] INFO: algo: handle_splits get splits [dt:2016-05-16 00:00:00+00:00] [asset:Equity(2340 [300081.SZA]), ratio:0.3987395579718062]
[2019-09-19 16:23:59.031922] INFO: Position: position stock handle split[sid:2340, orig_amount:5400, new_amount:13542.0, orig_cost:35.13000261128855, new_cost:14.01, ratio:0.3987395579718062, last_sale_price:13.919997907952927]
[2019-09-19 16:23:59.033981] INFO: Position: after split: PositionStock(asset:Equity(2340 [300081.SZA]), amount:13542.0, cost_basis:14.01, last_sale_price:34.90999984741211)
[2019-09-19 16:23:59.035735] INFO: Position: returning cash: 9.39
[2019-09-19 16:24:02.715411] INFO: algo: handle_splits get splits [dt:2016-06-20 00:00:00+00:00] [asset:Equity(2029 [600873.SHA]), ratio:0.9842022100472294]
[2019-09-19 16:24:02.726603] INFO: Position: position stock handle split[sid:2029, orig_amount:28000, new_amount:28449.0, orig_cost:6.260000416173964, new_cost:6.16, ratio:0.9842022100472294, last_sale_price:6.229999914510293]
[2019-09-19 16:24:02.732622] INFO: Position: after split: PositionStock(asset:Equity(2029 [600873.SHA]), amount:28449.0, cost_basis:6.16, last_sale_price:6.329999923706055)
[2019-09-19 16:24:02.738357] INFO: Position: returning cash: 2.73
[2019-09-19 16:24:06.366421] INFO: algo: handle_splits get splits [dt:2016-07-08 00:00:00+00:00] [asset:Equity(364 [603699.SHA]), ratio:0.9860337230776506]
[2019-09-19 16:24:06.372718] INFO: Position: position stock handle split[sid:364, orig_amount:13300, new_amount:13488.0, orig_cost:18.010052061145977, new_cost:17.76, ratio:0.9860337230776506, last_sale_price:17.65000326694793]
[2019-09-19 16:24:06.378282] INFO: Position: after split: PositionStock(asset:Equity(364 [603699.SHA]), amount:13488.0, cost_basis:17.76, last_sale_price:17.899999618530273)
[2019-09-19 16:24:06.383724] INFO: Position: returning cash: 6.75
[2019-09-19 16:24:11.138147] INFO: algo: handle_splits get splits [dt:2016-08-12 00:00:00+00:00] [asset:Equity(76 [600578.SHA]), ratio:0.95623635873562]
[2019-09-19 16:24:11.140197] INFO: Position: position stock handle split[sid:76, orig_amount:38700, new_amount:40471.0, orig_cost:4.560004052334111, new_cost:4.36, ratio:0.95623635873562, last_sale_price:4.3700003235706335]
[2019-09-19 16:24:11.141920] INFO: Position: after split: PositionStock(asset:Equity(76 [600578.SHA]), amount:40471.0, cost_basis:4.36, last_sale_price:4.570000171661377)
[2019-09-19 16:24:11.144057] INFO: Position: returning cash: 0.72
[2019-09-19 16:24:29.010979] INFO: Performance: Simulated 488 trading days out of 488.
[2019-09-19 16:24:29.017198] INFO: Performance: first open: 2015-01-05 09:30:00+00:00
[2019-09-19 16:24:29.022608] INFO: Performance: last close: 2016-12-30 15:00:00+00:00
[2019-09-19 16:24:49.609929] INFO: bigquant: backtest.v8 运行完成[129.714736s].
3.1 股票配对交易策略
# 本代码由可视化策略环境自动生成 2020年9月23日 14:42
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 回测引擎:初始化函数,只执行一次
def m3_initialize_bigquant_run(context):
# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
# 回测引擎:每日数据处理函数,每天执行一次
def m3_handle_data_bigquant_run(context, data):
today = data.current_dt.strftime('%Y-%m-%d')
zscore_today =context.zscore.ix[today]
#获取股票的列表
stocklist=context.instruments
# 转换成回测引擎所需要的symbol格式
symbol_1 = context.symbol(stocklist[0])
symbol_2 = context.symbol(stocklist[1])
# 持仓
cur_position_1 = context.portfolio.positions[symbol_1].amount
cur_position_2 = context.portfolio.positions[symbol_2].amount
# 交易逻辑
# 如果zscore大于上轨(>1),则价差会向下回归均值,因此需要买入股票x,卖出股票y
if zscore_today > 1 and cur_position_1 == 0 and data.can_trade(symbol_1) and data.can_trade(symbol_2):
context.order_target_percent(symbol_2, 0)
context.order_target_percent(symbol_1, 1)
print(today, '全仓买入:',stocklist[0])
# 如果zscore小于下轨(<-1),则价差会向上回归均值,因此需要买入股票y,卖出股票x
elif zscore_today < -1 and cur_position_2 == 0 and data.can_trade(symbol_1) and data.can_trade(symbol_2):
context.order_target_percent(symbol_1, 0)
context.order_target_percent(symbol_2, 1)
print(today, '全仓买入:',stocklist[1])
# 回测引擎:准备数据,只执行一次
def m3_prepare_bigquant_run(context):
pass
# 回测引擎:准备数据,只执行一次
def m3_before_trading_start_bigquant_run(context,data):
# 加载股票历史数据
df = context.options['data'].read_df()
df['date'] = df['date'].apply(lambda x:x.strftime('%Y-%m-%d'))
today = data.current_dt.strftime('%Y-%m-%d')
# 获取前240个自然日的数据
start_date = (pd.to_datetime(data.current_dt)-datetime.timedelta(days=240)).strftime('%Y-%m-%d')
stock_data = df[df.date <= today]
# 由于可能上市天数不同,对缺失值填充处理
prices_df=pd.pivot_table(stock_data, values='close_0', index=['date'], columns=['instrument'])
prices_df.fillna(method='ffill',inplace=True)
x = prices_df[context.instruments[0]] # 股票1
y = prices_df[context.instruments[1]] # 股票2
# 线性回归两个股票的股价 y=ax+b
from pyfinance import ols
model = ols.OLS(y=y, x=x)
def zscore(series):
return (series - series.mean()) / np.std(series)
# 计算 y-a*x 序列的zscore值序列
zscore_calcu = zscore(y-model.beta*x)
context.zscore=zscore_calcu
m1 = M.input_features.v1(
features="""# #号开始的表示注释
# 多个特征,每行一个,可以包含基础特征和衍生特征
close_0
"""
)
m2 = M.instruments.v2(
start_date=T.live_run_param('trading_date', '2015-01-01'),
end_date=T.live_run_param('trading_date', '2018-10-28'),
market='CN_STOCK_A',
instrument_list="""601328.SHA
601998.SHA""",
max_count=0
)
m7 = M.general_feature_extractor.v7(
instruments=m2.data,
features=m1.data,
start_date='',
end_date='',
before_start_days=300
)
m4 = M.derived_feature_extractor.v3(
input_data=m7.data,
features=m1.data,
date_col='date',
instrument_col='instrument',
drop_na=False,
remove_extra_columns=False,
user_functions={}
)
m5 = M.dropnan.v2(
input_data=m4.data
)
m3 = M.trade.v4(
instruments=m2.data,
options_data=m5.data,
start_date='',
end_date='',
initialize=m3_initialize_bigquant_run,
handle_data=m3_handle_data_bigquant_run,
prepare=m3_prepare_bigquant_run,
before_trading_start=m3_before_trading_start_bigquant_run,
volume_limit=0.025,
order_price_field_buy='open',
order_price_field_sell='open',
capital_base=1000000,
auto_cancel_non_tradable_orders=True,
data_frequency='daily',
price_type='真实价格',
product_type='股票',
plot_charts=True,
backtest_only=False,
benchmark=''
)
[2019-06-21 09:53:38.503017] INFO: bigquant: input_features.v1 开始运行..
[2019-06-21 09:53:38.545842] INFO: bigquant: 命中缓存
[2019-06-21 09:53:38.556901] INFO: bigquant: input_features.v1 运行完成[0.053881s].
[2019-06-21 09:53:38.560006] INFO: bigquant: instruments.v2 开始运行..
[2019-06-21 09:53:38.602468] INFO: bigquant: 命中缓存
[2019-06-21 09:53:38.604658] INFO: bigquant: instruments.v2 运行完成[0.044642s].
[2019-06-21 09:53:38.635206] INFO: bigquant: general_feature_extractor.v7 开始运行..
[2019-06-21 09:53:38.665744] INFO: bigquant: 命中缓存
[2019-06-21 09:53:38.667802] INFO: bigquant: general_feature_extractor.v7 运行完成[0.032597s].
[2019-06-21 09:53:38.670660] INFO: bigquant: derived_feature_extractor.v3 开始运行..
[2019-06-21 09:53:38.711715] INFO: bigquant: 命中缓存
[2019-06-21 09:53:38.713990] INFO: bigquant: derived_feature_extractor.v3 运行完成[0.04332s].
[2019-06-21 09:53:38.716530] INFO: bigquant: dropnan.v1 开始运行..
[2019-06-21 09:53:38.742758] INFO: bigquant: 命中缓存
[2019-06-21 09:53:38.744626] INFO: bigquant: dropnan.v1 运行完成[0.028085s].
[2019-06-21 09:53:38.791453] INFO: bigquant: backtest.v8 开始运行..
[2019-06-21 09:53:38.794461] INFO: bigquant: biglearning backtest:V8.2.2
[2019-06-21 09:53:38.795752] INFO: bigquant: product_type:stock by specified
[2019-06-21 09:53:39.084577] INFO: bigquant: cached.v2 开始运行..
[2019-06-21 09:53:39.128779] INFO: bigquant: 命中缓存
[2019-06-21 09:53:39.130639] INFO: bigquant: cached.v2 运行完成[0.046066s].
[2019-06-21 09:53:39.184503] INFO: algo: TradingAlgorithm V1.5.0
[2019-06-21 09:53:39.373587] INFO: algo: trading transform...
[2019-06-21 09:54:29.600489] INFO: algo: handle_splits get splits [dt:2016-07-25 00:00:00+00:00] [asset:Equity(0 [601998.SHA]), ratio:0.9657426445424234]
[2019-06-21 09:54:29.602455] INFO: Position: position stock handle split[sid:0, orig_amount:183300, new_amount:189802.0, orig_cost:5.690047724566808, new_cost:5.5, ratio:0.9657426445424234, last_sale_price:5.9200025215655305]
[2019-06-21 09:54:29.604078] INFO: Position: after split: asset: Equity(0 [601998.SHA]), amount: 189802.0, cost_basis: 5.5, last_sale_price: 6.130000114440918
[2019-06-21 09:54:29.605697] INFO: Position: returning cash: 0.7
[2019-06-21 09:55:01.107468] INFO: algo: handle_splits get splits [dt:2017-07-24 00:00:00+00:00] [asset:Equity(0 [601998.SHA]), ratio:0.9700427168666901]
[2019-06-21 09:55:01.110080] INFO: Position: position stock handle split[sid:0, orig_amount:218600, new_amount:225350.0, orig_cost:6.1500281882553605, new_cost:5.97, ratio:0.9700427168666901, last_sale_price:6.799999667260655]
[2019-06-21 09:55:01.112385] INFO: Position: after split: asset: Equity(0 [601998.SHA]), amount: 225350.0, cost_basis: 5.97, last_sale_price: 7.010000228881836
[2019-06-21 09:55:01.114301] INFO: Position: returning cash: 6.13
[2019-06-21 09:55:33.612472] INFO: algo: handle_splits get splits [dt:2018-07-16 00:00:00+00:00] [asset:Equity(1 [601328.SHA]), ratio:0.9517470390385913]
[2019-06-21 09:55:33.614314] INFO: Position: position stock handle split[sid:1, orig_amount:254600, new_amount:267508.0, orig_cost:7.0600000818200925, new_cost:6.72, ratio:0.9517470390385913, last_sale_price:5.7199994686311895]
[2019-06-21 09:55:33.615812] INFO: Position: after split: asset: Equity(1 [601328.SHA]), amount: 267508.0, cost_basis: 6.72, last_sale_price: 6.009999752044678
[2019-06-21 09:55:33.617095] INFO: Position: returning cash: 0.32
[2019-06-21 09:55:42.568981] INFO: Performance: Simulated 930 trading days out of 930.
[2019-06-21 09:55:42.571150] INFO: Performance: first open: 2015-01-05 09:30:00+00:00
[2019-06-21 09:55:42.573583] INFO: Performance: last close: 2018-10-26 15:00:00+00:00
[2019-06-21 09:55:44.571635] INFO: bigquant: backtest.v8 运行完成[125.780166s].
3.2 双均线策略+固定百分比止损
# 本代码由可视化策略环境自动生成 2020年9月23日 14:46
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 回测引擎:初始化函数,只执行一次
def m3_initialize_bigquant_run(context):
# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
# 回测引擎:每日数据处理函数,每天执行一次
def m3_handle_data_bigquant_run(context, data):
#------------------------------------------止损模块START------------------------------------------- #
date = data.current_dt.strftime('%Y-%m-%d')
positions = {e.symbol: p.cost_basis for e, p in context.portfolio.positions.items()}
# 新建当日止赢股票列表是为了handle_data 策略逻辑部分不再对该股票进行判断
current_stopwin_stock = []
if len(positions) > 0:
for i in positions.keys():
stock_cost = positions[i]
stock_market_price = data.current(context.symbol(i), 'price')
# 赚10%止盈
if stock_market_price / stock_cost -1 > 0.1:
context.order_target_percent(context.symbol(i),0)
current_stopwin_stock.append(i)
print('日期:',date,'股票:',i,'出现上涨10%,触发止盈')
#-------------------------------------------止损模块END---------------------------------------------#
# 1. 获取今日的日期
today = data.current_dt.strftime('%Y-%m-%d')
# 2. 获取目前持仓的股票和最新市值
stock_hold_now = {e.symbol: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()}
# 3. 获取当前账户可用现金
cash_for_buy = context.portfolio.cash
# 4. 获取当日的买卖信号股票列表
try:
buy_stock = context.daily_stock_buy[today]
except:
buy_stock=[] # 如果没有符合条件的股票,就设置为空
try:
sell_stock = context.daily_stock_sell[today]
except:
sell_stock=[] # 如果没有符合条件的股票,就设置为空
# 5. 确认需要卖出的股票:已有持仓中符合卖出条件的股票
stock_to_sell = [ i for i in stock_hold_now if i in sell_stock ]
# 6. 执行卖出操作
if len(stock_to_sell)>0:
for instrument in stock_to_sell:
# 如果股票已经在止盈列表中,则跳过卖出操作
if instrument in current_stopwin_stock:
continue
sid = context.symbol(instrument) # 将标的转化为equity格式
cur_position = context.portfolio.positions[sid].amount # 当前持仓
if cur_position > 0 and data.can_trade(sid):
context.order_target_percent(sid, 0) # 全部卖出
# 根据卖出的股票市值更新可用现金:
cash_for_buy += stock_hold_now[instrument]
# 7. 执行买入操作
if len(buy_stock)>0:
weight = 1/len(buy_stock) # 每只股票的比重为等资金比例持有
for instrument in buy_stock:
sid = context.symbol(instrument) # 将标的转化为equity格式
cur_position = context.portfolio.positions[sid].amount # 当前持仓
if data.can_trade(sid) and cur_position==0:
context.order_target_value(sid, weight*cash_for_buy) # 按可用现金等比例买入
# 回测引擎:准备数据,只执行一次
def m3_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_stock_buy= df.groupby('date').apply(open_pos_con)
# 每日卖出股票的数据框
context.daily_stock_sell= df.groupby('date').apply(close_pos_con)
m1 = M.input_features.v1(
features="""# #号开始的表示注释
# 多个特征,每行一个,可以包含基础特征和衍生特征
buy_condition=where(mean(close_0,5)>mean(close_0,20),1,0)
sell_condition=where(mean(close_0,5)<mean(close_0,20),1,0)""",
m_cached=False
)
m2 = M.instruments.v2(
start_date=T.live_run_param('trading_date', '2016-01-01'),
end_date=T.live_run_param('trading_date', '2017-01-01'),
market='CN_STOCK_A',
instrument_list='600519.SHA',
max_count=0
)
m7 = M.general_feature_extractor.v7(
instruments=m2.data,
features=m1.data,
start_date='',
end_date='',
before_start_days=200,
m_cached=False
)
m8 = M.derived_feature_extractor.v3(
input_data=m7.data,
features=m1.data,
date_col='date',
instrument_col='instrument',
drop_na=False,
remove_extra_columns=False
)
m4 = M.dropnan.v2(
input_data=m8.data
)
m3 = M.trade.v4(
instruments=m2.data,
options_data=m4.data,
start_date='',
end_date='',
initialize=m3_initialize_bigquant_run,
handle_data=m3_handle_data_bigquant_run,
prepare=m3_prepare_bigquant_run,
volume_limit=0.025,
order_price_field_buy='open',
order_price_field_sell='open',
capital_base=1000000,
auto_cancel_non_tradable_orders=True,
data_frequency='daily',
price_type='后复权',
product_type='股票',
plot_charts=True,
backtest_only=False,
benchmark=''
)
[2019-09-19 17:23:07.792873] INFO: bigquant: input_features.v1 开始运行..
[2019-09-19 17:23:08.186172] INFO: bigquant: input_features.v1 运行完成[0.393294s].
[2019-09-19 17:23:08.197696] INFO: bigquant: instruments.v2 开始运行..
[2019-09-19 17:23:08.701834] INFO: bigquant: 命中缓存
[2019-09-19 17:23:08.704262] INFO: bigquant: instruments.v2 运行完成[0.506546s].
[2019-09-19 17:23:09.307162] INFO: bigquant: general_feature_extractor.v7 开始运行..
[2019-09-19 17:23:09.853597] INFO: 基础特征抽取: 年份 2015, 特征行数=136
[2019-09-19 17:23:09.896071] INFO: 基础特征抽取: 年份 2016, 特征行数=244
[2019-09-19 17:23:09.918153] INFO: 基础特征抽取: 年份 2017, 特征行数=0
[2019-09-19 17:23:10.247284] INFO: 基础特征抽取: 总行数: 380
[2019-09-19 17:23:10.254148] INFO: bigquant: general_feature_extractor.v7 运行完成[0.946984s].
[2019-09-19 17:23:10.261087] INFO: bigquant: derived_feature_extractor.v3 开始运行..
[2019-09-19 17:23:10.718868] INFO: derived_feature_extractor: 提取完成 buy_condition=where(mean(close_0,5)>mean(close_0,20),1,0), 0.012s
[2019-09-19 17:23:10.743357] INFO: derived_feature_extractor: 提取完成 sell_condition=where(mean(close_0,5)[2019-09-19 17:23:11.037936] INFO: derived_feature_extractor: /y_2015, 136[2019-09-19 17:23:11.095965] INFO: derived_feature_extractor: /y_2016, 244[2019-09-19 17:23:11.450596] INFO: bigquant: derived_feature_extractor.v3 运行完成[1.189501s].[2019-09-19 17:23:11.458106] INFO: bigquant: dropnan.v1 开始运行..[2019-09-19 17:23:11.694375] INFO: dropnan: /y_2015, 136/136[2019-09-19 17:23:11.733158] INFO: dropnan: /y_2016, 244/244[2019-09-19 17:23:11.935565] INFO: dropnan: 行数: 380/380[2019-09-19 17:23:11.950387] INFO: bigquant: dropnan.v1 运行完成[0.492258s].[2019-09-19 17:23:12.028427] INFO: bigquant: backtest.v8 开始运行..[2019-09-19 17:23:12.117618] INFO: bigquant: biglearning backtest:V8.2.13[2019-09-19 17:23:13.218853] INFO: bigquant: product_type:stock by specified[2019-09-19 17:23:13.622276] INFO: bigquant: cached.v2 开始运行..[2019-09-19 17:23:13.739935] INFO: bigquant: 命中缓存[2019-09-19 17:23:13.745772] INFO: bigquant: cached.v2 运行完成[0.123481s].[2019-09-19 17:23:13.916656] INFO: algo: TradingAlgorithm V1.5.8[2019-09-19 17:23:14.001222] INFO: algo: trading transform...[2019-09-19 17:23:15.111988] INFO: Performance: Simulated 244 trading days out of 244.[2019-09-19 17:23:15.117268] INFO: Performance: first open: 2016-01-04 09:30:00+00:00[2019-09-19 17:23:15.124464] INFO: Performance: last close: 2016-12-30 15:00:00+00:00[2019-09-19 17:23:17.419454] INFO: bigquant: backtest.v8 运行完成[5.391029s].
3.3 多因子选股
# 本代码由可视化策略环境自动生成 2020年12月8日 14:15
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 回测引擎:初始化函数,只执行一次
def m2_initialize_bigquant_run(context):
# 设置交易费用,买入是万三,卖出是千分之1.3,如果不足5元按5元算
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
# 如果策略运行中,需要将数据(比如运行天数)进行保存,可以借用extension这个对象,类型为dict
if 'index' not in context.extension:
context.extension['index'] = 0
# 回测引擎:每日数据处理函数,每天执行一次
def m2_handle_data_bigquant_run(context, data):
# 1. 按每个K线递增,记录策略运行天数
context.extension['index'] += 1
# 2. 每隔22个交易日进行换仓
if context.extension['index'] % context.rebalance_days != 1:
return
# 3. 买入股票列表
stock_to_buy = context.daily_stock_buy.ix[data.current_dt.strftime('%Y-%m-%d')]
# 4. 当前持仓列表
stock_hold_now = [equity.symbol for equity in context.portfolio.positions]
no_need_to_sell = [i for i in stock_hold_now if (i in stock_to_buy) and (i in stock_hold_now)]
# 5. 卖出股票列表
stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]
# 6. 执行卖出
for stock in stock_to_sell:
if data.can_trade(context.symbol(stock)):
context.order_target_percent(context.symbol(stock), 0)
# 7. 执行买入
if len(stock_to_buy)>0:
weight = 1 / len(stock_to_buy) # 等权重
for instrument in stock_to_buy:
if data.can_trade(context.symbol(instrument)):
context.order_target_percent(context.symbol(instrument), weight)
# 回测引擎:准备数据,只执行一次
def m2_prepare_bigquant_run(context):
# 加载股票指标数据,数据继承自m4模块
context.indicator_data = context.options['data'].read_df()
# 设置股票数量
context.stock_num = 30
def open_pos_con(df):
return list(df.instrument)[:context.stock_num]
# 计算每日股票买入列表
context.daily_stock_buy = context.indicator_data.groupby('date').apply(open_pos_con)
# 调仓天数,22个交易日大概就是一个月。可以理解为一个月换仓一次
context.rebalance_days = 22
m3 = M.instruments.v2(
start_date='2015-01-01',
end_date='2019-04-23',
market='CN_STOCK_A',
instrument_list=''
)
m5 = M.input_features.v1(
features="""pb_lf_0
pe_ttm_0
amount_0"""
)
m1 = M.general_feature_extractor.v7(
instruments=m3.data,
features=m5.data,
start_date='',
end_date='',
before_start_days=90
)
m6 = M.sort.v4(
input_ds=m1.data,
sort_by='pe_ttm_0,pb_lf_0',
group_by='date',
keep_columns='--',
ascending=True
)
m4 = M.filter.v3(
input_data=m6.sorted_data,
expr='pb_lf_0 < 1.5 & pe_ttm_0 < 15 & amount_0 > 0 & pb_lf_0 > 0 & pe_ttm_0 > 0',
output_left_data=False
)
m2 = M.trade.v4(
instruments=m3.data,
options_data=m4.data,
start_date='',
end_date='',
initialize=m2_initialize_bigquant_run,
handle_data=m2_handle_data_bigquant_run,
prepare=m2_prepare_bigquant_run,
volume_limit=0.025,
order_price_field_buy='open',
order_price_field_sell='open',
capital_base=1000000,
auto_cancel_non_tradable_orders=True,
data_frequency='daily',
price_type='后复权',
product_type='股票',
plot_charts=True,
backtest_only=False,
benchmark=''
)
[2020-12-08 14:15:20.454254] INFO: moduleinvoker: instruments.v2 开始运行..
[2020-12-08 14:15:20.490386] INFO: moduleinvoker: 命中缓存
[2020-12-08 14:15:20.491638] INFO: moduleinvoker: instruments.v2 运行完成[0.037397s].
[2020-12-08 14:15:20.494466] INFO: moduleinvoker: input_features.v1 开始运行..
[2020-12-08 14:15:20.565296] INFO: moduleinvoker: 命中缓存
[2020-12-08 14:15:20.567009] INFO: moduleinvoker: input_features.v1 运行完成[0.072525s].
[2020-12-08 14:15:20.736726] INFO: moduleinvoker: general_feature_extractor.v7 开始运行..
[2020-12-08 14:15:20.813343] INFO: moduleinvoker: 命中缓存
[2020-12-08 14:15:20.814775] INFO: moduleinvoker: general_feature_extractor.v7 运行完成[0.078066s].
[2020-12-08 14:15:20.821709] INFO: moduleinvoker: sort.v4 开始运行..
[2020-12-08 14:15:20.899792] INFO: moduleinvoker: 命中缓存
[2020-12-08 14:15:20.901264] INFO: moduleinvoker: sort.v4 运行完成[0.079535s].
[2020-12-08 14:15:20.907554] INFO: moduleinvoker: filter.v3 开始运行..
[2020-12-08 14:15:20.951400] INFO: moduleinvoker: 命中缓存
[2020-12-08 14:15:20.953147] INFO: moduleinvoker: filter.v3 运行完成[0.045599s].
[2020-12-08 14:15:22.418218] INFO: moduleinvoker: backtest.v8 开始运行..
[2020-12-08 14:15:22.423311] INFO: backtest: biglearning backtest:V8.4.2
[2020-12-08 14:15:22.617669] INFO: backtest: product_type:stock by specified
[2020-12-08 14:15:22.858733] INFO: moduleinvoker: cached.v2 开始运行..
[2020-12-08 14:15:22.870786] INFO: moduleinvoker: 命中缓存
[2020-12-08 14:15:22.871936] INFO: moduleinvoker: cached.v2 运行完成[0.013229s].
[2020-12-08 14:15:25.985701] INFO: algo: TradingAlgorithm V1.6.10
[2020-12-08 14:15:28.225896] INFO: algo: trading transform...
[2020-12-08 14:15:35.552759] INFO: Performance: Simulated 1049 trading days out of 1049.
[2020-12-08 14:15:35.554640] INFO: Performance: first open: 2015-01-05 09:30:00+00:00
[2020-12-08 14:15:35.556695] INFO: Performance: last close: 2019-04-23 15:00:00+00:00
[2020-12-08 14:15:49.515487] INFO: moduleinvoker: backtest.v8 运行完成[27.097269s].
[2020-12-08 14:15:49.517069] INFO: moduleinvoker: trade.v4 运行完成[28.553024s].
3.4 双均线策略
# 本代码由可视化策略环境自动生成 2019年6月20日 15:59
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# 回测引擎:每日数据处理函数,每天执行一次
def m3_handle_data_bigquant_run(context, data):
# 1. 获取今日的日期
today = data.current_dt.strftime('%Y-%m-%d')
# 2. 获取目前持仓的股票和最新市值
stock_hold_now = {e.symbol: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()}
# 3. 获取当前账户可用现金
cash_for_buy = context.portfolio.cash
# 4. 获取当日的买卖信号股票列表
try:
buy_stock = context.daily_stock_buy[today]
except:
buy_stock=[] # 如果没有符合条件的股票,就设置为空
try:
sell_stock = context.daily_stock_sell[today]
except:
sell_stock=[] # 如果没有符合条件的股票,就设置为空
# 5. 确认需要卖出的股票:已有持仓中符合卖出条件的股票
stock_to_sell = [ i for i in stock_hold_now if i in sell_stock ]
# 6. 执行卖出操作
if len(stock_to_sell)>0:
for instrument in stock_to_sell:
sid = context.symbol(instrument) # 将标的转化为equity格式
cur_position = context.portfolio.positions[sid].amount # 当前持仓
if cur_position > 0 and data.can_trade(sid):
context.order_target_percent(sid, 0)
# 根据卖出的股票市值更新可用现金;
cash_for_buy += stock_hold_now[instrument]
# 7. 执行买入操作
if len(buy_stock)>0:
weight = 1/len(buy_stock) # 每只股票的比重为等资金比例持有
for instrument in buy_stock:
sid = context.symbol(instrument) # 将标的转化为equity格式
cur_position = context.portfolio.positions[sid].amount # 当前持仓
if data.can_trade(sid) and cur_position==0:
context.order_target_value(sid, weight*cash_for_buy) # 按可用现金等比例买入
# 回测引擎:准备数据,只执行一次
def m3_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_stock_buy= df.groupby('date').apply(open_pos_con)
# 每日卖出股票的数据框
context.daily_stock_sell= df.groupby('date').apply(close_pos_con)
# 回测引擎:初始化函数,只执行一次
def m3_initialize_bigquant_run(context):
# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
m1 = M.input_features.v1(
features="""# #号开始的表示注释
# 多个特征,每行一个,可以包含基础特征和衍生特征
buy_condition=where(mean(close_0,5)>mean(close_0,20),1,0)
sell_condition=where(mean(close_0,5)<mean(close_0,20),1,0)""",
m_cached=False
)
m2 = M.instruments.v2(
start_date=T.live_run_param('trading_date', '2016-01-01'),
end_date=T.live_run_param('trading_date', '2017-01-01'),
market='CN_STOCK_A',
instrument_list='600519.SHA',
max_count=0
)
m7 = M.general_feature_extractor.v7(
instruments=m2.data,
features=m1.data,
start_date='',
end_date='',
before_start_days=200,
m_cached=False
)
m8 = M.derived_feature_extractor.v3(
input_data=m7.data,
features=m1.data,
date_col='date',
instrument_col='instrument',
drop_na=False,
remove_extra_columns=False
)
m6 = M.dropnan.v1(
input_data=m8.data
)
m3 = M.trade.v4(
instruments=m2.data,
options_data=m6.data,
start_date='',
end_date='',
handle_data=m3_handle_data_bigquant_run,
prepare=m3_prepare_bigquant_run,
initialize=m3_initialize_bigquant_run,
volume_limit=0.025,
order_price_field_buy='close',
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=''
)
[2019-06-20 13:14:10.005262] INFO: bigquant: input_features.v1 开始运行..
[2019-06-20 13:14:10.063670] INFO: bigquant: input_features.v1 运行完成[0.058405s].
[2019-06-20 13:14:10.067459] INFO: bigquant: instruments.v2 开始运行..
[2019-06-20 13:14:10.094217] INFO: bigquant: 命中缓存
[2019-06-20 13:14:10.095947] INFO: bigquant: instruments.v2 运行完成[0.028497s].
[2019-06-20 13:14:10.128575] INFO: bigquant: general_feature_extractor.v7 开始运行..
[2019-06-20 13:14:10.246481] INFO: 基础特征抽取: 年份 2015, 特征行数=136
[2019-06-20 13:14:10.273475] INFO: 基础特征抽取: 年份 2016, 特征行数=244
[2019-06-20 13:14:10.285415] INFO: 基础特征抽取: 年份 2017, 特征行数=0
[2019-06-20 13:14:10.345540] INFO: 基础特征抽取: 总行数: 380
[2019-06-20 13:14:10.347480] INFO: bigquant: general_feature_extractor.v7 运行完成[0.218905s].
[2019-06-20 13:14:10.350536] INFO: bigquant: derived_feature_extractor.v3 开始运行..
[2019-06-20 13:14:10.436890] INFO: derived_feature_extractor: 提取完成 buy_condition=where(mean(close_0,5)>mean(close_0,20),1,0), 0.007s
[2019-06-20 13:14:10.446629] INFO: derived_feature_extractor: 提取完成 sell_condition=where(mean(close_0,5)[2019-06-20 13:14:10.486996] INFO: derived_feature_extractor: /y_2015, 136[2019-06-20 13:14:10.513525] INFO: derived_feature_extractor: /y_2016, 244[2019-06-20 13:14:10.613676] INFO: bigquant: derived_feature_extractor.v3 运行完成[0.263128s].[2019-06-20 13:14:10.616840] INFO: bigquant: dropnan.v1 开始运行..[2019-06-20 13:14:10.695606] INFO: dropnan: /y_2015, 136/136[2019-06-20 13:14:10.726307] INFO: dropnan: /y_2016, 244/244[2019-06-20 13:14:10.813265] INFO: dropnan: 行数: 380/380[2019-06-20 13:14:10.816473] INFO: bigquant: dropnan.v1 运行完成[0.199615s].[2019-06-20 13:14:10.860465] INFO: bigquant: backtest.v8 开始运行..[2019-06-20 13:14:10.864171] INFO: bigquant: biglearning backtest:V8.2.2[2019-06-20 13:14:11.500200] INFO: bigquant: product_type:stock by specified[2019-06-20 13:14:11.687216] INFO: bigquant: cached.v2 开始运行..[2019-06-20 13:14:11.726424] INFO: bigquant: 命中缓存[2019-06-20 13:14:11.729266] INFO: bigquant: cached.v2 运行完成[0.04205s].[2019-06-20 13:14:11.768565] INFO: algo: TradingAlgorithm V1.5.0[2019-06-20 13:14:11.812191] INFO: algo: trading transform...[2019-06-20 13:14:12.482313] INFO: Performance: Simulated 244 trading days out of 244.[2019-06-20 13:14:12.484003] INFO: Performance: first open: 2016-01-04 09:30:00+00:00[2019-06-20 13:14:12.485730] INFO: Performance: last close: 2016-12-30 15:00:00+00:00[2019-06-20 13:14:13.484915] INFO: bigquant: backtest.v8 运行完成[2.624447s].
这个克隆后不能运行,哪里的原因?
NameError Traceback (most recent call last)
in ()
114 plot_charts=True,
115 backtest_only=False,
–> 116 benchmark=’’
117 )
in m2_handle_data_bigquant_run(context, data)
29
30 # 5. 卖出股票列表
—> 31 stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]
32
33 # 6. 执行卖出
in (.0)
29
30 # 5. 卖出股票列表
—> 31 stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]
32
33 # 6. 执行卖出
NameError: name ‘no_need_to_sell’ is not defined