版本 v1.0
选出某因子排名前10的基金; 买入基金持仓60日开始换仓。
因子定义:
close/shift(close, 5):收盘价5日动量
1、确定基金池和回测时间
通过证券代码列表输入回测的起止日期
2、确定买卖原则
在输入特征列表中通过表达式引擎定义close/shift(close, 5)这个因子 。选出该因子值排名前10的基金。选出的10支基金为买入基金列表,以60个交易日开始换仓。
3、回测
通过 trade 模块中的初始化函数定义交易手续费和滑点; 通过 trade 模块中的主函数(handle函数)查看每日的买卖交易信号,按照买卖原则执行相应的买入/卖出/调仓操作。
可视化策略实现如下:
# 本代码由可视化策略环境自动生成 2022年4月9日 14:59
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
def m3_run_bigquant_run(input_1, input_2, input_3):
df = input_1.read()
df.rename(columns={'nav':'close'}, inplace=True)
df['open'] = df['close'] - 1
df['high'] = df['close'] + 2
df['low'] = df['close'] - 2
df['volume'] = 100000
df['amount'] = df['volume'] * df['close']
# df = df.groupby('date').apply(lambda x: x[x['close']>x['close'].mean()*3]).reset_index(drop=True)
# from datetime import time
# trading_date = df['date'].tolist() #.apply(lambda x: x.date()).unique().tolist() # 自定义的交易日历的日期
# trading_sections = [(time(9,0,0), time(11,30,0)), (time(13,30,0), time(15,0,0)), (time(21,0,0), time(23,0,0))] # 自定义的交易开、收盘时间
# trading_calendar = get_extend_calendar_with_tradingdays('MyFutCalendar', tradingdays=trading_date, trading_sections=trading_sections) # 生成自定义交易日历
data_1 = DataSource.write_df(df)
# data_2 = DataSource.write_pickle(trading_calendar)
return Outputs(data_1=data_1)#,data_2=data_2)
# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
def m3_post_run_bigquant_run(outputs):
return outputs
# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
def m6_run_bigquant_run(input_1, input_2, input_3):
# 示例代码如下。在这里编写您的代码
df = input_1.read()
df = df.groupby('date').apply(mom_factor).reset_index(drop=True)
data_1 = DataSource.write_df(df)
return Outputs(data_1=data_1, data_2=None, data_3=None)
def mom_factor(df):
x = df.sort_values(by='close/shift(close, 5)', ascending=False)
x = x[0:10]
return x
# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
def m6_post_run_bigquant_run(outputs):
return outputs
# 回测引擎:初始化函数,只执行一次
def m2_initialize_bigquant_run(context):
# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
context.test_data = context.options['data'].read()
# 回测引擎:每日数据处理函数,每天执行一次
def m2_handle_data_bigquant_run(context, data):
if (context.trading_day_index-6) % 60 ==0:
today = data.current_dt.strftime('%Y-%m-%d')
instruments = context.test_data[context.test_data['date']==today].instrument.tolist()
stock_hold_now = {e.symbol: p.amount * p.last_sale_price
for e, p in context.perf_tracker.position_tracker.positions.items()}
buy_stock = [i for i in instruments if i not in stock_hold_now ]
sell_stock = [i for i in stock_hold_now if i not in instruments]
cash_for_buy = context.portfolio.cash
#买入并持有
#每标的购买资金
for instrument in buy_stock :
# print("current price=", data.current(context.symbol(instrument), "close"), context.symbol(instrument))
context.order_target_value(context.symbol(instrument), cash_for_buy/len(buy_stock),order_type=OrderType.MARKET)
for instrument in sell_stock :
context.order_target_percent(context.symbol(instrument), 0)
# 回测引擎:准备数据,只执行一次
def m2_prepare_bigquant_run(context):
pass
# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
def m2_before_trading_start_bigquant_run(context, data):
pass
m7 = M.instruments.v2(
start_date='2020-03-01',
end_date='2021-09-13',
market='CN_MUTFUND',
instrument_list="""
""",
max_count=0
)
m1 = M.use_datasource.v1(
instruments=m7.data,
datasource_id='history_nav_CN_MUTFUND',
start_date='',
end_date=''
)
m3 = M.cached.v3(
input_1=m1.data,
run=m3_run_bigquant_run,
post_run=m3_post_run_bigquant_run,
input_ports='',
params='{}',
output_ports=''
)
m4 = M.input_features.v1(
features="""close/shift(close, 5)
"""
)
m5 = M.derived_feature_extractor.v3(
input_data=m3.data_1,
features=m4.data,
date_col='date',
instrument_col='instrument',
drop_na=False,
remove_extra_columns=False,
user_functions={}
)
m8 = M.dropnan.v2(
input_data=m5.data
)
m6 = M.cached.v3(
input_1=m8.data,
run=m6_run_bigquant_run,
post_run=m6_post_run_bigquant_run,
input_ports='',
params='{}',
output_ports=''
)
m2 = M.trade.v4(
instruments=m7.data,
options_data=m6.data_1,
history_ds=m8.data,
start_date='',
end_date='',
initialize=m2_initialize_bigquant_run,
handle_data=m2_handle_data_bigquant_run,
prepare=m2_prepare_bigquant_run,
before_trading_start=m2_before_trading_start_bigquant_run,
volume_limit=0,
order_price_field_buy='close',
order_price_field_sell='close',
capital_base=300000,
auto_cancel_non_tradable_orders=True,
data_frequency='daily',
price_type='真实价格',
product_type='股票',
plot_charts=True,
backtest_only=False,
benchmark=''
)
[2022-04-09 14:59:29.777806] INFO: moduleinvoker: instruments.v2 开始运行..
[2022-04-09 14:59:29.785292] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:29.787033] INFO: moduleinvoker: instruments.v2 运行完成[0.009232s].
[2022-04-09 14:59:29.792823] INFO: moduleinvoker: use_datasource.v1 开始运行..
[2022-04-09 14:59:29.821994] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:29.823903] INFO: moduleinvoker: use_datasource.v1 运行完成[0.031097s].
[2022-04-09 14:59:29.835164] INFO: moduleinvoker: cached.v3 开始运行..
[2022-04-09 14:59:29.841131] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:29.842441] INFO: moduleinvoker: cached.v3 运行完成[0.007284s].
[2022-04-09 14:59:29.846027] INFO: moduleinvoker: input_features.v1 开始运行..
[2022-04-09 14:59:29.853269] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:29.855353] INFO: moduleinvoker: input_features.v1 运行完成[0.009331s].
[2022-04-09 14:59:29.862868] INFO: moduleinvoker: derived_feature_extractor.v3 开始运行..
[2022-04-09 14:59:29.899953] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:29.901866] INFO: moduleinvoker: derived_feature_extractor.v3 运行完成[0.038994s].
[2022-04-09 14:59:29.911145] INFO: moduleinvoker: dropnan.v2 开始运行..
[2022-04-09 14:59:29.918021] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:29.919627] INFO: moduleinvoker: dropnan.v2 运行完成[0.008487s].
[2022-04-09 14:59:29.931530] INFO: moduleinvoker: cached.v3 开始运行..
[2022-04-09 14:59:29.946466] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:29.948738] INFO: moduleinvoker: cached.v3 运行完成[0.017215s].
[2022-04-09 14:59:30.024973] INFO: moduleinvoker: backtest.v8 开始运行..
[2022-04-09 14:59:30.034181] INFO: moduleinvoker: 命中缓存
[2022-04-09 14:59:30.913416] INFO: moduleinvoker: backtest.v8 运行完成[0.888466s].
[2022-04-09 14:59:30.915751] INFO: moduleinvoker: trade.v4 运行完成[0.960879s].