{"description":"实验创建于2017/8/26","graph":{"edges":[{"to_node_id":"-41:sql","from_node_id":"-42:data"},{"to_node_id":"-72:data","from_node_id":"-41:data"}],"nodes":[{"node_id":"-42","module_id":"BigQuantSpace.input_features_dai.input_features_dai-v6","parameters":[{"name":"sql","value":"-- pragma enable_pushdown_window;\n-- 使用DAI SQL获取数据,构建因子等,如下是一个例子作为参考\n-- DAI SQL 语法: https://bigquant.com/wiki/doc/dai-PLSbc1SbZX#h-sql%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B\n\nSELECT\n -- 【在这里输入因子表达式】\n -- DAI SQL 算子/函数: https://bigquant.com/wiki/doc/dai-PLSbc1SbZX#h-%E5%87%BD%E6%95%B0\n -- 数据&字段: 数据文档 https://bigquant.com/data/home\n -- 使用在时间截面的total_market_cap排名、五日日均成交量m_avg(amount_0, 5)作为本模版的两个因子\n -- 这里使用了DAI提供的c_normalize函数对因子进行z-score标准化处理以在多因子线性合成时不被量纲影响\n -- 还可以增加系数调节因子权重,这里对两个因子简单地添加了0.4、0,6的系数,在这个示例中没有经济学意义\n -- 另外可以使用DAI提供的cut_outliers函数去极值,c_indneutralize、c_neutralize函数进行行业、行业市值中性化\n 0.4 * c_normalize(total_market_cap) + 0.6 * c_normalize(m_avg(amount_0, 5)) AS score,\n\n -- 日期,这是每个股票每天的数据\n date,\n -- 股票代码,代表每一支股票\n instrument\n-- 预计算因子和数据 cn_stock_factors https://bigquant.com/data/datasources/cn_stock_factors\nFROM cn_stock_factors\n\n-- where 数据过滤\nWHERE\n\t-- 剔除ST股票\n st_status = 0\n -- 上市天数 > 270, 过滤掉新股\n AND list_days > 270\n -- 要求 pe > 0,-- 表示注释\n -- AND pe_ttm > 0\n -- 非停牌股\n AND suspended = 0\n -- 不属于北交所\n AND list_sector < 4\n\n -- 阳线 放量\n AND close_1 > open_1\n AND amount_1 / amount_2 > 3\n \n-- QUALIFY 数据过滤,支持过滤窗口函数,在 WHERE 之后才执行窗口函数。这里简化了一下,都放到QUALIFY了。对于专业用户建议分开WHERE和QUALIFY,有更好的升性能和准确性\nQUALIFY\n \n -- 去掉有空值的行\n COLUMNS(*) IS NOT NULL\n \n -- 一线穿3线\n AND m_avg(close,5) BETWEEN open_1 AND close_1\n AND m_avg(close,10) BETWEEN open_1 AND close_1\n AND m_avg(close,20) BETWEEN open_1 AND close_1\n AND m_max(change_ratio, 10) > 0.97\n \n -- \n AND close_1 / m_min(low, 10) > 1.09\n\n\n\n-- 按因子值排名,从小到大\nORDER BY date, score\n","type":"Literal","bound_global_parameter":null}],"input_ports":[],"output_ports":[{"name":"data","node_id":"-42"}],"cacheable":true,"seq_num":1,"comment":"通过SQL调用数据、因子和表达式等构建策略逻辑","comment_collapsed":false,"x":-419,"y":-156},{"node_id":"-41","module_id":"BigQuantSpace.extract_data_dai.extract_data_dai-v7","parameters":[{"name":"start_date","value":"2023-01-01","type":"Literal","bound_global_parameter":null},{"name":"start_date_bound_to_trading_date","value":"True","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2023-12-31","type":"Literal","bound_global_parameter":null},{"name":"end_date_bound_to_trading_date","value":"True","type":"Literal","bound_global_parameter":null},{"name":"before_start_days","value":"90","type":"Literal","bound_global_parameter":null},{"name":"debug","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"sql","node_id":"-41"}],"output_ports":[{"name":"data","node_id":"-41"}],"cacheable":true,"seq_num":2,"comment":"抽取数据,设置数据开始时间和结束时间,并绑定模拟交易","comment_collapsed":false,"x":-371,"y":-25},{"node_id":"-72","module_id":"BigQuantSpace.bigtrader.bigtrader-v9","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 context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n\n # 持有期/调仓周期,1天,3天,5天等\n context.holding_days = 1\n # 设置买入股票数量\n context.target_hold_count = 10\n # 每只股票的目标权重\n context.target_percent_per_instrument = 1.0 / context.target_hold_count\n","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"# 交易引擎:每个单位时间开盘前调用一次。\ndef bigquant_run(context, data):\n # 盘前处理,订阅行情等\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"handle_tick","value":"# 交易引擎:tick数据处理函数,每个tick执行一次\ndef bigquant_run(context, tick):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"def bigquant_run(context, data):\n # 每 context.holding_days 个交易日调仓一次\n if context.trading_day_index % context.holding_days != 0:\n return\n\n # 获取当前日期\n current_date = data.current_dt.strftime(\"%Y-%m-%d\")\n # 获取当日数据\n current_day_data = context.data[context.data[\"date\"] == current_date]\n # 取前10只\n current_day_data = current_day_data.head(context.target_hold_count)\n # 获取当日目标持有股票\n target_hold_instruments = set(current_day_data[\"instrument\"])\n # 获取当前已持有股票\n current_hold_instruments = set(context.get_account_positions().keys())\n\n # 卖出不在目标持有列表中的股票\n for instrument in current_hold_instruments - target_hold_instruments:\n context.order_target_percent(instrument, 0)\n \n # 买入目标持有列表中的股票\n for instrument in target_hold_instruments - current_hold_instruments:\n context.order_target_percent(instrument, context.target_percent_per_instrument)\n","type":"Literal","bound_global_parameter":null},{"name":"handle_trade","value":"# 交易引擎:成交回报处理函数,每个成交发生时执行一次\ndef bigquant_run(context, trade):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"handle_order","value":"# 交易引擎:委托回报处理函数,每个委托变化时执行一次\ndef bigquant_run(context, order):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"after_trading","value":"# 交易引擎:盘后处理函数,每日盘后执行一次\ndef bigquant_run(context, data):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":1000000,"type":"Literal","bound_global_parameter":null},{"name":"frequency","value":"daily","type":"Literal","bound_global_parameter":null},{"name":"product_type","value":"股票","type":"Literal","bound_global_parameter":null},{"name":"before_start_days","value":0,"type":"Literal","bound_global_parameter":null},{"name":"volume_limit","value":1,"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":"benchmark","value":"000300.SH","type":"Literal","bound_global_parameter":null},{"name":"plot_charts","value":"True","type":"Literal","bound_global_parameter":null},{"name":"disable_cache","value":"False","type":"Literal","bound_global_parameter":null},{"name":"debug","value":"False","type":"Literal","bound_global_parameter":null},{"name":"backtest_only","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"data","node_id":"-72"},{"name":"options_data","node_id":"-72"},{"name":"history_ds","node_id":"-72"},{"name":"benchmark_ds","node_id":"-72"}],"output_ports":[{"name":"raw_perf","node_id":"-72"}],"cacheable":true,"seq_num":4,"comment":"交易,日线,设置初始化函数和K线处理函数,以及初始资金、基准等","comment_collapsed":false,"x":-251,"y":154}],"node_layout":"<node_postions><node_position Node='-42' Position='-419,-156,200,200'/><node_position Node='-41' Position='-371,-25,200,200'/><node_position Node='-72' Position='-251,154,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [5]:
    # 本代码由可视化策略环境自动生成 2024年2月19日 13:50
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
     
    # 显式导入 BigQuant 相关 SDK 模块
    from bigdatasource.api import DataSource
    from bigdata.api.datareader import D
    from biglearning.api import M
    from biglearning.api import tools as T
    from biglearning.module2.common.data import Outputs
     
    import pandas as pd
    import numpy as np
    import math
    import warnings
    import datetime
     
    from zipline.finance.commission import PerOrder
    from zipline.api import get_open_orders
    from zipline.api import symbol
     
    from bigtrader.sdk import *
    from bigtrader.utils.my_collections import NumPyDeque
    from bigtrader.constant import OrderType
    from bigtrader.constant import Direction
    
    # <aistudiograph>
    
    # @param(id="m4", name="initialize")
    # 交易引擎:初始化函数,只执行一次
    def m4_initialize_bigquant_run(context):
        # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    
        # 持有期/调仓周期,1天,3天,5天等
        context.holding_days = 1
        # 设置买入股票数量
        context.target_hold_count = 10
        # 每只股票的目标权重
        context.target_percent_per_instrument = 1.0 / context.target_hold_count
    
    # @param(id="m4", name="before_trading_start")
    # 交易引擎:每个单位时间开盘前调用一次。
    def m4_before_trading_start_bigquant_run(context, data):
        # 盘前处理,订阅行情等
        pass
    
    # @param(id="m4", name="handle_tick")
    # 交易引擎:tick数据处理函数,每个tick执行一次
    def m4_handle_tick_bigquant_run(context, tick):
        pass
    
    # @param(id="m4", name="handle_data")
    def m4_handle_data_bigquant_run(context, data):
        # 每 context.holding_days 个交易日调仓一次
        if context.trading_day_index % context.holding_days != 0:
            return
    
        # 获取当前日期
        current_date = data.current_dt.strftime("%Y-%m-%d")
        # 获取当日数据
        current_day_data = context.data[context.data["date"] == current_date]
        # 取前10只
        current_day_data = current_day_data.head(context.target_hold_count)
        # 获取当日目标持有股票
        target_hold_instruments = set(current_day_data["instrument"])
        # 获取当前已持有股票
        current_hold_instruments = set(context.get_account_positions().keys())
    
        # 卖出不在目标持有列表中的股票
        for instrument in current_hold_instruments - target_hold_instruments:
            context.order_target_percent(instrument, 0)
            
        # 买入目标持有列表中的股票
        for instrument in target_hold_instruments - current_hold_instruments:
            context.order_target_percent(instrument, context.target_percent_per_instrument)
    
    # @param(id="m4", name="handle_trade")
    # 交易引擎:成交回报处理函数,每个成交发生时执行一次
    def m4_handle_trade_bigquant_run(context, trade):
        pass
    
    # @param(id="m4", name="handle_order")
    # 交易引擎:委托回报处理函数,每个委托变化时执行一次
    def m4_handle_order_bigquant_run(context, order):
        pass
    
    # @param(id="m4", name="after_trading")
    # 交易引擎:盘后处理函数,每日盘后执行一次
    def m4_after_trading_bigquant_run(context, data):
        pass
    
    
    # @module(position="-419,-156", comment='通过SQL调用数据、因子和表达式等构建策略逻辑', comment_collapsed=False)
    m1 = M.input_features_dai.v6(
        sql="""-- pragma enable_pushdown_window;
    -- 使用DAI SQL获取数据,构建因子等,如下是一个例子作为参考
    -- DAI SQL 语法: https://bigquant.com/wiki/doc/dai-PLSbc1SbZX#h-sql%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B
    
    SELECT
        -- 【在这里输入因子表达式】
        -- DAI SQL 算子/函数: https://bigquant.com/wiki/doc/dai-PLSbc1SbZX#h-%E5%87%BD%E6%95%B0
        -- 数据&字段: 数据文档 https://bigquant.com/data/home
        -- 使用在时间截面的total_market_cap排名、五日日均成交量m_avg(amount_0, 5)作为本模版的两个因子
        -- 这里使用了DAI提供的c_normalize函数对因子进行z-score标准化处理以在多因子线性合成时不被量纲影响
        -- 还可以增加系数调节因子权重,这里对两个因子简单地添加了0.4、0,6的系数,在这个示例中没有经济学意义
        -- 另外可以使用DAI提供的cut_outliers函数去极值,c_indneutralize、c_neutralize函数进行行业、行业市值中性化
        0.4 * c_normalize(total_market_cap) + 0.6 * c_normalize(m_avg(amount_0, 5)) AS score,
    
        -- 日期,这是每个股票每天的数据
        date,
        -- 股票代码,代表每一支股票
        instrument
    -- 预计算因子和数据 cn_stock_factors https://bigquant.com/data/datasources/cn_stock_factors
    FROM cn_stock_factors
    
    -- where 数据过滤
    WHERE
    	-- 剔除ST股票
        st_status = 0
        -- 上市天数 > 270, 过滤掉新股
        AND list_days > 270
        -- 要求 pe > 0,-- 表示注释
        -- AND pe_ttm > 0
        -- 非停牌股
        AND suspended = 0
        -- 不属于北交所
        AND list_sector < 4
    
        -- 阳线 放量
        AND close_1 > open_1
        AND amount_1 / amount_2 > 3
       
    -- QUALIFY 数据过滤,支持过滤窗口函数,在 WHERE 之后才执行窗口函数。这里简化了一下,都放到QUALIFY了。对于专业用户建议分开WHERE和QUALIFY,有更好的升性能和准确性
    QUALIFY
        
        -- 去掉有空值的行
        COLUMNS(*) IS NOT NULL
        
        -- 一线穿3线
        AND m_avg(close,5) BETWEEN open_1 AND close_1
        AND m_avg(close,10) BETWEEN open_1 AND close_1
        AND m_avg(close,20) BETWEEN open_1 AND close_1
        AND m_max(change_ratio, 10) > 0.97
        
        -- 
        AND close_1 / m_min(low, 10) > 1.09
    
    
    
    -- 按因子值排名,从小到大
    ORDER BY date, score
    """
    )
    
    # @module(position="-371,-25", comment='抽取数据,设置数据开始时间和结束时间,并绑定模拟交易', comment_collapsed=False)
    m2 = M.extract_data_dai.v7(
        sql=m1.data,
        start_date='2023-01-01',
        start_date_bound_to_trading_date=True,
        end_date='2023-12-31',
        end_date_bound_to_trading_date=True,
        before_start_days=90,
        debug=False
    )
    
    # @module(position="-251,154", comment='交易,日线,设置初始化函数和K线处理函数,以及初始资金、基准等', comment_collapsed=False)
    m4 = M.bigtrader.v9(
        data=m2.data,
        start_date='',
        end_date='',
        initialize=m4_initialize_bigquant_run,
        before_trading_start=m4_before_trading_start_bigquant_run,
        handle_tick=m4_handle_tick_bigquant_run,
        handle_data=m4_handle_data_bigquant_run,
        handle_trade=m4_handle_trade_bigquant_run,
        handle_order=m4_handle_order_bigquant_run,
        after_trading=m4_after_trading_bigquant_run,
        capital_base=1000000,
        frequency='daily',
        product_type='股票',
        before_start_days=0,
        volume_limit=1,
        order_price_field_buy='open',
        order_price_field_sell='close',
        benchmark='000300.SH',
        plot_charts=True,
        disable_cache=False,
        debug=False,
        backtest_only=False
    )
    # </aistudiograph>
    
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    Cell In[5], line 167
        156 m2 = M.extract_data_dai.v7(
        157     sql=m1.data,
        158     start_date='2023-01-01',
       (...)
        163     debug=False
        164 )
        166 # @module(position="-251,154", comment='交易,日线,设置初始化函数和K线处理函数,以及初始资金、基准等', comment_collapsed=False)
    --> 167 m4 = M.bigtrader.v9(
        168     data=m2.data,
        169     start_date='',
        170     end_date='',
        171     initialize=m4_initialize_bigquant_run,
        172     before_trading_start=m4_before_trading_start_bigquant_run,
        173     handle_tick=m4_handle_tick_bigquant_run,
        174     handle_data=m4_handle_data_bigquant_run,
        175     handle_trade=m4_handle_trade_bigquant_run,
        176     handle_order=m4_handle_order_bigquant_run,
        177     after_trading=m4_after_trading_bigquant_run,
        178     capital_base=1000000,
        179     frequency='daily',
        180     product_type='股票',
        181     before_start_days=0,
        182     volume_limit=1,
        183     order_price_field_buy='open',
        184     order_price_field_sell='close',
        185     benchmark='000300.SH',
        186     plot_charts=True,
        187     disable_cache=False,
        188     debug=False,
        189     backtest_only=False
        190 )
        191 # </aistudiograph>
    
    File module2/common/modulemanagerv2.py:88, in biglearning.module2.common.modulemanagerv2.BigQuantModuleVersion.__call__()
    
    File module2/common/moduleinvoker.py:370, in biglearning.module2.common.moduleinvoker.module_invoke()
    
    File module2/common/moduleinvoker.py:292, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
    
    File module2/common/moduleinvoker.py:253, in biglearning.module2.common.moduleinvoker._invoke_with_cache()
    
    File module2/common/moduleinvoker.py:210, in biglearning.module2.common.moduleinvoker._module_run()
    
    File /var/app/data/custom_module/publicmodules/bigtrader/v9/__init__.py:301, in run(start_date, end_date, data, initialize, before_trading_start, handle_tick, handle_data, handle_trade, handle_order, after_trading, options_data, history_ds, benchmark_ds, capital_base, frequency, product_type, before_start_days, volume_limit, order_price_field_buy, order_price_field_sell, benchmark, plot_charts, disable_cache, debug, backtest_only, m_meta_kwargs)
        297     else:
        298         # use cppbacktest
        299         from .core.cppbacktest import BigQuantModule
    --> 301     outputs = BigQuantModule(
        302         start_date=start_date,
        303         end_date=end_date,
        304         **trading_params,
        305         plot_charts=plot_charts,
        306         disable_cache=disable_cache,
        307         **m_meta_kwargs,
        308     ).run()
        309 elif backtest_only:
        310     run_mode = None
    
    File /var/app/data/custom_module/publicmodules/bigtrader/v9/core/pybacktest/__init__.py:168, in BigQuantModule.__init__(self, start_date, end_date, data, prepare, initialize, after_trading, on_timer, on_message, before_trading_start, handle_data, handle_tick, handle_l2trade, handle_l2order, handle_trade, handle_order, capital_base, product_type, adjust_type, frequency, benchmark, plot_charts, options_data, debug, **kwargs)
        162     instruments = json.loads(data)
        163 elif isinstance(data, pd.DataFrame):
        164     instruments = {
        165         # "market": "CN_STOCK_A",
        166         "instruments": list(set(data["instrument"])),
        167         # TODO: to seconds?
    --> 168         "start_date": data["date"].min().strftime("%Y-%m-%d"),
        169         "end_date": data["date"].max().strftime("%Y-%m-%d"),
        170     }
        171 else:
        172     raise Exception(f"not supported instruments type: {type(data)}")
    
    File pandas/_libs/tslibs/nattype.pyx:72, in pandas._libs.tslibs.nattype._make_error_func.f()
    
    ValueError: NaTType does not support strftime