{"description":"实验创建于2019/4/24","graph":{"edges":[{"to_node_id":"-93:input_1","from_node_id":"-578:data"},{"to_node_id":"-40:input_data","from_node_id":"-632:data_1"},{"to_node_id":"-47:input_1","from_node_id":"-40:data"},{"to_node_id":"-199:input_1","from_node_id":"-47:data_1"},{"to_node_id":"-43:options_data","from_node_id":"-47:data_1"},{"to_node_id":"-43:history_ds","from_node_id":"-47:data_1"},{"to_node_id":"-43:benchmark_ds","from_node_id":"-47:data_1"},{"to_node_id":"-1128:input_1","from_node_id":"-47:data_1"},{"to_node_id":"-43:instruments","from_node_id":"-199:data_1"},{"to_node_id":"-43:trading_calendar","from_node_id":"-1128:data_1"},{"to_node_id":"-93:input_2","from_node_id":"-81:data"},{"to_node_id":"-100:input_1","from_node_id":"-93:data_1"},{"to_node_id":"-632:input_1","from_node_id":"-103:data"}],"nodes":[{"node_id":"-43","module_id":"BigQuantSpace.trade.trade-v4","parameters":[{"name":"start_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"initialize","value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n \n # 加载股票指标数据,数据继承自m4模块\n context.indicator_data = context.options['data'].read_df().set_index('date')\n print('indicator_data:', context.indicator_data.head()) \n # 设置交易费用,买入是万三,卖出是千分之1.3,如果不足5元按5元算\n context.set_commission(PerOrder(buy_cost=0.002, sell_cost=0.002, min_cost=5))\n # 设置股票数量\n context.stock_num = 1\n \n # 调仓天数,1个交易日换仓一次\n context.rebalance_days = 1\n \n # 如果策略运行中,需要将数据进行保存,可以借用extension这个对象,类型为dict\n # 比如当前运行的k线的索引,比如个股持仓天数、买入均价\n if 'index' not in context.extension:\n context.extension['index'] = 0\n \n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \n # 按每个K线递增\n context.extension['index'] += 1\n \n # 每隔1个交易日进行换仓\n if context.extension['index'] % context.rebalance_days != 0:\n return \n \n # 日期\n date = data.current_dt.strftime('%Y-%m-%d')\n \n print('debug:', date)\n # 买入股票列表\n \n stock_to_buy = context.indicator_data.loc[date]['instrument'][- context.stock_num:]\n print('stock_to_buy:', stock_to_buy)\n \n # 目前持仓列表 \n stock_hold_now = [equity.symbol for equity in context.portfolio.positions]\n print('stock_hold_now:', stock_hold_now)\n \n # 继续持有股票列表\n no_need_to_sell = [i for i in stock_hold_now if i in stock_to_buy]\n print('no_need_to_sell:', no_need_to_sell)\n\n # 卖出股票列表 \n stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]\n print('stock_to_sell:', stock_to_sell)\n\n # 执行卖出\n for stock in stock_to_sell:\n if data.can_trade(context.symbol(stock)):\n context.order_target_percent(context.symbol(stock), 0)\n \n # 如果当天没有买入就返回\n if len(stock_to_buy) == 0:\n return\n \n # 等权重\n weight = 1 / len(stock_to_buy)\n # 执行买入\n for cp in stock_to_buy:\n if data.can_trade(context.symbol(cp)):\n context.order_target_percent(context.symbol(cp), weight)","type":"Literal","bound_global_parameter":null},{"name":"prepare","value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"volume_limit","value":0.025,"type":"Literal","bound_global_parameter":null},{"name":"order_price_field_buy","value":"open","type":"Literal","bound_global_parameter":null},{"name":"order_price_field_sell","value":"close","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":"1000000","type":"Literal","bound_global_parameter":null},{"name":"auto_cancel_non_tradable_orders","value":"True","type":"Literal","bound_global_parameter":null},{"name":"data_frequency","value":"daily","type":"Literal","bound_global_parameter":null},{"name":"price_type","value":"后复权","type":"Literal","bound_global_parameter":null},{"name":"product_type","value":"期货","type":"Literal","bound_global_parameter":null},{"name":"plot_charts","value":"True","type":"Literal","bound_global_parameter":null},{"name":"backtest_only","value":"False","type":"Literal","bound_global_parameter":null},{"name":"benchmark","value":"btcusdt","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-43"},{"name":"options_data","node_id":"-43"},{"name":"history_ds","node_id":"-43"},{"name":"benchmark_ds","node_id":"-43"},{"name":"trading_calendar","node_id":"-43"}],"output_ports":[{"name":"raw_perf","node_id":"-43"}],"cacheable":false,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"-578","module_id":"BigQuantSpace.input_csv.input_csv-v5","parameters":[{"name":"file","value":"price_symbol_full.csv","type":"Literal","bound_global_parameter":null},{"name":"coding","value":"GBK","type":"Literal","bound_global_parameter":null},{"name":"dtypes","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"date_type","value":"%Y-%m-%d %H:%M:%S","type":"Literal","bound_global_parameter":null},{"name":"date_cols","value":"['datetime']","type":"Literal","bound_global_parameter":null}],"input_ports":[],"output_ports":[{"name":"data","node_id":"-578"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"-632","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\nimport datetime\ndef bigquant_run(input_1, input_2, input_3):\n df = input_1.read_df()\n df.rename(columns={'datetime': 'date'}, inplace = True)\n df = df.sort_values(by = ['instrument', 'date'],ascending=True)\n df['high_low_diff'] = df['high'] - df['low']\n df['swing'] = df['high_low_diff'] / df['open']\n for name, group in df.groupby('instrument'):\n group['swing_volatility_2'] = group['swing'].rolling(2).std()\n if name == '1.HBI':\n group_all = group\n else:\n group_all = pd.concat([group_all, group])\n group_all = group_all.sort_values(by = ['date', 'instrument'], ascending=True)\n \n return Outputs(data_1=DataSource.write_df(group_all),data_2=None,data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-632"},{"name":"input_2","node_id":"-632"},{"name":"input_3","node_id":"-632"}],"output_ports":[{"name":"data_1","node_id":"-632"},{"name":"data_2","node_id":"-632"},{"name":"data_3","node_id":"-632"}],"cacheable":true,"seq_num":4,"comment":"计算振幅、振幅的2日波动率","comment_collapsed":false},{"node_id":"-40","module_id":"BigQuantSpace.dropnan.dropnan-v2","parameters":[],"input_ports":[{"name":"input_data","node_id":"-40"},{"name":"features","node_id":"-40"}],"output_ports":[{"name":"data","node_id":"-40"}],"cacheable":true,"seq_num":6,"comment":"","comment_collapsed":true},{"node_id":"-47","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\nimport datetime\ndef bigquant_run(input_1, input_2, input_3):\n df = input_1.read_df()\n for name, group in df.groupby('date'): \n group['rank_swing_volatility_2'] = group['swing_volatility_2'].rank()\n group = group.sort_values('swing_volatility_2') \n if datetime.datetime.strftime(name, '%Y-%m-%d') == '2017-10-27':\n group_all = group\n else:\n group_all = pd.concat([group_all, group])\n #group_all = group_all.rename({'instrument_full': 'instrument'}, axis = 1)\n group_all = group_all.reset_index(drop = True)\n return Outputs(data_1=DataSource.write_df(group_all),data_2=None,data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-47"},{"name":"input_2","node_id":"-47"},{"name":"input_3","node_id":"-47"}],"output_ports":[{"name":"data_1","node_id":"-47"},{"name":"data_2","node_id":"-47"},{"name":"data_3","node_id":"-47"}],"cacheable":true,"seq_num":7,"comment":"计算振幅的2日波动率的排名","comment_collapsed":false},{"node_id":"-199","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3, start_date, end_date, market):\n # 示例代码如下。在这里编写您的代码\n df = input_1.read_df()\n instrument = df['instrument']\n instrument = instrument.drop_duplicates()\n list_1 = instrument.to_list()\n \n dict_1 = {'instruments': list_1, 'start_date': start_date, 'end_date': end_date, 'market': market}\n data_1 = DataSource.write_pickle(dict_1)\n return Outputs(data_1=data_1, data_2=None, data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{'start_date':'2017-10-27', 'end_date':'2021-07-18', 'market':'DCC'}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"data_1","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-199"},{"name":"input_2","node_id":"-199"},{"name":"input_3","node_id":"-199"}],"output_ports":[{"name":"data_1","node_id":"-199"},{"name":"data_2","node_id":"-199"},{"name":"data_3","node_id":"-199"}],"cacheable":true,"seq_num":8,"comment":"将insturment转为列表","comment_collapsed":false},{"node_id":"-1128","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n #df = pd.DataFrame({'data': [1, 2, 3]})\n #data_1 = DataSource.write_df(df)\n from datetime import time\n df = input_1.read()\n # 直接根据回测数据的DataFrame的date来生成交易日历对象\n trading_date =df['date'] # 交易日历的日期\n trading_date = trading_date.drop_duplicates()\n trading_date = trading_date.reset_index(drop = True)\n trading_sections = [(time(00,00), time(00,00))]#23,59 # 交易日历的开、收盘时间\n # 生成交易日历\n trading_calendar = get_extend_calendar_with_tradingdays('CryptoCurrencyCalendar', tradingdays=trading_date, trading_sections=trading_sections)\n data_1 = DataSource.write_pickle(trading_calendar)\n return Outputs(data_1=data_1)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-1128"},{"name":"input_2","node_id":"-1128"},{"name":"input_3","node_id":"-1128"}],"output_ports":[{"name":"data_1","node_id":"-1128"},{"name":"data_2","node_id":"-1128"},{"name":"data_3","node_id":"-1128"}],"cacheable":true,"seq_num":3,"comment":"定义数字货币交易日历","comment_collapsed":false},{"node_id":"-81","module_id":"BigQuantSpace.input_csv.input_csv-v5","parameters":[{"name":"file","value":"instruments1.csv","type":"Literal","bound_global_parameter":null},{"name":"coding","value":"GBK","type":"Literal","bound_global_parameter":null},{"name":"dtypes","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"date_type","value":"False","type":"Literal","bound_global_parameter":null},{"name":"date_cols","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[],"output_ports":[{"name":"data","node_id":"-81"}],"cacheable":false,"seq_num":5,"comment":"","comment_collapsed":true},{"node_id":"-93","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n global df2\n df1 = input_1.read_df()\n df2 = input_2.read_df()\n def transform_instrument(instrument_full):\n print('instrument_full: ', instrument_full)\n for index, row in df2.iterrows():\n #print('row[instrument_full]: ', row['instrument_full'])\n if instrument_full == row['instrument_full']:\n result = row['instrument_simple']\n #print('result: ', result)\n break\n return result\n df1['instrument'] = df1['symbol'].apply(lambda x: transform_instrument(x))\n data_1 = DataSource.write_df(df1)\n #data_2 = DataSource.write_pickle(df)\n return Outputs(data_1=data_1, data_2=None, data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-93"},{"name":"input_2","node_id":"-93"},{"name":"input_3","node_id":"-93"}],"output_ports":[{"name":"data_1","node_id":"-93"},{"name":"data_2","node_id":"-93"},{"name":"data_3","node_id":"-93"}],"cacheable":true,"seq_num":9,"comment":"转换数字货币代码为数字代码","comment_collapsed":false},{"node_id":"-100","module_id":"BigQuantSpace.df_to_csv.df_to_csv-v2","parameters":[{"name":"name","value":"instrument2.csv","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-100"}],"output_ports":[],"cacheable":true,"seq_num":10,"comment":"","comment_collapsed":true},{"node_id":"-103","module_id":"BigQuantSpace.input_csv.input_csv-v5","parameters":[{"name":"file","value":"instrument2.csv","type":"Literal","bound_global_parameter":null},{"name":"coding","value":"GBK","type":"Literal","bound_global_parameter":null},{"name":"dtypes","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"date_type","value":"%Y-%m-%d","type":"Literal","bound_global_parameter":null},{"name":"date_cols","value":"['datetime']","type":"Literal","bound_global_parameter":null}],"input_ports":[],"output_ports":[{"name":"data","node_id":"-103"}],"cacheable":true,"seq_num":11,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-43' Position='197,571,200,200'/><node_position Node='-578' Position='256.79559326171875,-132.41354322433472,200,200'/><node_position Node='-632' Position='220.07101440429688,177.87129974365234,200,200'/><node_position Node='-40' Position='197.39541625976562,273.87129974365234,200,200'/><node_position Node='-47' Position='263.91552734375,352.44905853271484,200,200'/><node_position Node='-199' Position='20,469,200,200'/><node_position Node='-1128' Position='466.45782470703125,460.457763671875,200,200'/><node_position Node='-81' Position='591.3733520507812,-131.18299865722656,200,200'/><node_position Node='-93' Position='436.39141845703125,-57.485239028930664,200,200'/><node_position Node='-100' Position='365.3261413574219,33.71915054321289,200,200'/><node_position Node='-103' Position='152.4041290283203,102.32907915115356,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
[2021-08-09 19:39:35.287352] INFO: moduleinvoker: input_csv.v5 开始运行..
[2021-08-09 19:39:35.311304] INFO: moduleinvoker: 命中缓存
[2021-08-09 19:39:35.314016] INFO: moduleinvoker: input_csv.v5 运行完成[0.026694s].
[2021-08-09 19:39:35.326509] INFO: moduleinvoker: cached.v3 开始运行..
[2021-08-09 19:39:35.339228] INFO: moduleinvoker: 命中缓存
[2021-08-09 19:39:35.341810] INFO: moduleinvoker: cached.v3 运行完成[0.015318s].
[2021-08-09 19:39:35.347938] INFO: moduleinvoker: dropnan.v2 开始运行..
[2021-08-09 19:39:35.355470] INFO: moduleinvoker: 命中缓存
[2021-08-09 19:39:35.358063] INFO: moduleinvoker: dropnan.v2 运行完成[0.010136s].
[2021-08-09 19:39:35.365288] INFO: moduleinvoker: cached.v3 开始运行..
[2021-08-09 19:39:35.373680] INFO: moduleinvoker: 命中缓存
[2021-08-09 19:39:35.376377] INFO: moduleinvoker: cached.v3 运行完成[0.0111s].
[2021-08-09 19:39:35.384636] INFO: moduleinvoker: cached.v3 开始运行..
[2021-08-09 19:39:35.637580] INFO: moduleinvoker: cached.v3 运行完成[0.252958s].
[2021-08-09 19:39:35.645032] INFO: moduleinvoker: cached.v3 开始运行..
[2021-08-09 19:39:35.654495] INFO: moduleinvoker: 命中缓存
[2021-08-09 19:39:35.657016] INFO: moduleinvoker: cached.v3 运行完成[0.011981s].
[2021-08-09 19:39:35.698509] INFO: moduleinvoker: backtest.v8 开始运行..
[2021-08-09 19:39:35.705570] INFO: backtest: biglearning backtest:V8.5.0
[2021-08-09 19:39:35.708096] INFO: backtest: product_type:future by specified
[2021-08-09 19:39:36.288549] INFO: algo: TradingAlgorithm V1.8.3
[2021-08-09 19:39:36.639873] ERROR: moduleinvoker: module name: backtest, module version: v8, trackeback: ValueError: month must be in 1..12
The above exception was the direct cause of the following exception:
dateutil.parser._parser.ParserError: month must be in 1..12: 2021-62-15
During handling of the above exception, another exception occurred:
ValueError: could not convert string to Timestamp
[2021-08-09 19:39:36.683587] ERROR: moduleinvoker: module name: trade, module version: v4, trackeback: ValueError: month must be in 1..12
The above exception was the direct cause of the following exception:
dateutil.parser._parser.ParserError: month must be in 1..12: 2021-62-15
During handling of the above exception, another exception occurred:
ValueError: could not convert string to Timestamp
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: month must be in 1..12
The above exception was the direct cause of the following exception:
ParserError Traceback (most recent call last)
ParserError: month must be in 1..12: 2021-62-15
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
<ipython-input-2-8d46e512a221> in <module>
204 )
205
--> 206 m2 = M.trade.v4(
207 instruments=m8.data_1,
208 options_data=m7.data_1,
ValueError: could not convert string to Timestamp