问答交流

3.0平台的历史数据问题,运行代码就发现history只能看2个记录,不能看11个记录

由csowen创建,最终由csowen 被浏览 3 用户

from bigmodule import M

# <aistudiograph>

# @param(id="m9", name="run")
def m9_run_bigquant_run(input_1, input_2, input_3):
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    # 示例代码如下。在这里编写您的代码
    import dai
    df = input_1.read()    
    drop_cols =['st_status', 'low', 'low_1', 'price_limit_status']    
    df = df.drop(columns=drop_cols)   
    ds = dai.DataSource.write_bdb(df)
    return dict(data_1=ds, data_2={"hello": "world"}, data_3=None)

# @param(id="m14", name="initialize")
# 交易引擎:初始化函数, 只执行一次
def m14_initialize_bigquant_run(context):
    import math
    import numpy as np
    from bigtrader.finance.commission import PerOrder
    #系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0003, min_cost=5))#Owen set
    #预测数据,通过options传入进来,使用 read_df 函数,加载到内存 (DataFrame)
    #设置买入的股票数量,这里买入预测股票列表排名靠前的5只
    context.stock_count=3
    context.filter_flag=[0,0] ##disable filter3,filter2
    #每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
    ##context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, context.stock_count)])#disabe
    #设置每只股票占用的最大资金比例
    context.max_cash_per_instrument = 1.0 ##disable limit
    context.options['hold_days'] = 1
    context.track_stock = {}
    print ("owen-view", context.portfolio.positions.items())
    print ("owen-view-cash","portfolio_value", context.portfolio.portfolio_value,"cash ", context.portfolio.cash)


# @param(id="m14", name="before_trading_start")
# 交易引擎:每个单位时间开盘前调用一次。
def m14_before_trading_start_bigquant_run(context, data):
    # 盘前处理,订阅行情等
    pass

def price_cut(context, data):
    today = data.current_dt.strftime('%Y-%m-%d')  
    #------------------------------------------止损模块START------------------------------------------------
    equities = {e.symbol: p for e, p in context.portfolio.positions.items() if p.amount>0}
    #新建当日止损股票列表是为了handle_data 策略逻辑部分不再对该股票进行判断
    stoploss_stock = []
    if len(equities) > 0:
        ##price_cut
        for i in equities.keys():
            stock_market_price = data.current(context.symbol(i), 'price')  # 最新市场价格
            last_sale_date = equities[i].last_sale_date   # 上次交易日期
            price_open = data.history(context.symbol(i), 'open',bar_count=2,frequency='1d')
            price_close = data.history(context.symbol(i), 'close',bar_count=2,frequency='1d')
            ##1.09 2019.1.1~2024.2.5  331%-HUI 19.1%.
            ##1.095 2019.1.1 ~ 2024.2.5 359.72%-HUI 19.71%
            ## 2023.2.7~2024.2.7  -1.54% ~HUI 19.61%
            ##2016.6.5~2024.2.7 846.63%-HUI 19.8% 年化35.4%
            ##disable 2019.1.1 ~ 2024.2.5 383.84%-HUI 18.22%
            #enable 2015.1.1~2024.2.9 911%,disable 1460%
            if False:#price_close[-1] > price_close[-2] * 1.095:
                continue
            context.order_target_percent(context.symbol(i), 0)##高频卖出     
            stoploss_stock.append(i)
        if len(stoploss_stock)>0:
            print('日期:', today, '股票:', stoploss_stock, ' sell ',(stock_market_price - equities[i].cost_basis)/(equities[i].cost_basis))
        return stoploss_stock
    #-------------------------------------------止损模块END---------------------------------------------
    return stoploss_stock

# @param(id="m14", name="handle_data")
# 回测引擎:每日数据处理函数, 每天执行一次
def m14_handle_data_bigquant_run(context, data):
    print ('start ')
    stoploss_stock = price_cut(context,data)#止损模块检查
    #stoploss_stock += big_change(context,  data) ##止损检查
    today = data.current_dt.strftime('%Y-%m-%d')
    print ('ranker data')
    # 按日期过滤得到今日的预测数据
    ranker_prediction = context.data[context.data.date == data.current_dt.strftime("%Y-%m-%d")]    
    #ranker_prediction = ranker_prediction.sort_values('score', ascending=False)
    
    cash_for_buy = context.portfolio.cash#owen set
    if cash_for_buy>1000*100*100:
        print (today,'cash ',cash_for_buy,' more than 1000w')
    ##print (context.portfolio.cash, cash_avg, cash_for_buy,"owen-debug")
    positions = {e.symbol: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()}
    ###sell_stock = generate_sell(context,data,ranker_prediction,stoploss_stock) ##disable
    sell_stock=[]
    equities = {e.symbol: p for e, p in context.portfolio.positions.items() if p.amount>0}    
    stock_hold = len(equities)
    print ('current stock hold',stock_hold)

    # 3. 生成买入订单:按机器学习算法预测的排序,买入前面的stock_count只股票
    ##buy_cash_weights = context.stock_weights #disable
    buy_list = list(ranker_prediction.instrument)
    buy_stock_num = context.stock_count - stock_hold ##owen-debug
    if buy_stock_num == 0:
        return ## has stock in track
    ##不再买入已经轮仓卖出和移动止损的股票,以防止出现空头持仓
    buy_instruments = [i for i in buy_list if i not in sell_stock + stoploss_stock]
    print ('buy_instruments',len(buy_instruments)) 
    buy_stock = []
    for i in buy_instruments[0:16]:##best 16
        print (i, context.symbol(i),'debug ')
        vol_h = data.history(context.symbol(i), 'volume', bar_count=11, frequency='1d')     
        print (type(vol_h),' lsit ',len(vol_h))   
        
        price_open = data.history(context.symbol(i), 'open',bar_count=11,frequency='1d')
        price_close = data.history(context.symbol(i), 'close',bar_count=11,frequency='1d')
        avg5=sum(price_close[-5:])/5
        avg10=sum(price_close[-10:])/10
        _avg5 = (price_close[-11] + sum(price_close[-4:]))/5
        _avg10 = (price_close[-11] + sum(price_close[-9:]))/10        
        print ('start filer ')
        if vol_h[-1] > vol_h[-2]*3 and vol_h[-1] < vol_h[2]*7 and (price_close[-1] > price_open[-1]*0.93 or price_close[-2] < price_open[-2]*0.93):
            buy_stock.append(i)
            continue      
        if avg5 *0.95 > avg10:
            buy_stock.append(i)
            continue
    
            
    max_cash_per_instrument = context.portfolio.portfolio_value * context.max_cash_per_instrument
    count = 0
    for i in buy_stock[0:3]:##top-3
        if count +1 > buy_stock_num:
            return
        count = count +1
        cash = cash_for_buy/buy_stock_num #only buy one         
        price = data.current(context.symbol(i), 'price')
        stock_num = np.floor(cash/price/100)*100  # 向下取整
        print (today, ' buy ',i, stock_num,' using ',(price*stock_num)/100/100,'w')
        context.order_value(context.symbol(i), stock_num)
    return ##dsiable
    # 1. 资金分配
    # 平均持仓时间是hold_days, 每日都将买入股票, 每日预期使用 1/hold_days 的资金
    # 实际操作中, 会存在一定的买入误差, 所以在前hold_days天, 等量使用资金;之后, 尽量使用剩余资金(这里设置最多用等量的1.5倍)
    is_staging = (
        context.trading_day_index < context.options["hold_days"]
    )  # 是否在建仓期间(前 hold_days 天)
    cash_avg = context.portfolio.portfolio_value / context.options["hold_days"]
    cash_for_buy = min(context.portfolio.cash, (1 if is_staging else 1.5) * cash_avg)
    cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)
    positions = {
        e: p.amount * p.last_sale_price for e, p in context.portfolio.positions.items()
    }

    # 2. 生成卖出订单:hold_days天之后才开始卖出;对持仓的股票, 按机器学习算法预测的排序末位淘汰
    if not is_staging and cash_for_sell > 0:
        equities = {e: e for e, p in context.portfolio.positions.items()}
        instruments = list(
            reversed(
                list(
                    ranker_prediction.instrument[
                        ranker_prediction.instrument.apply(lambda x: x in equities)
                    ]
                )
            )
        )

        for instrument in instruments:
            context.order_target(instrument, 0)
            cash_for_sell -= positions[instrument]
            if cash_for_sell <= 0:
                break

    # 3. 生成买入订单:按机器学习算法预测的排序, 买入前面的stock_count只股票
    buy_cash_weights = context.stock_weights
    buy_instruments = list(ranker_prediction.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(instrument, cash)

# @param(id="m14", name="handle_trade")
# 交易引擎:成交回报处理函数,每个成交发生时执行一次
def m14_handle_trade_bigquant_run(context, trade):
    pass

# @param(id="m14", name="handle_order")
# 交易引擎:委托回报处理函数,每个委托变化时执行一次
def m14_handle_order_bigquant_run(context, order):
    pass

# @module(position="-845,-1266", comment="""训练集""")
m1 = M.instruments_dai.v3(
    start_date="""2010-01-01""",
    start_date_bound_to_trading_date=False,
    end_date="""2015-01-01""",
    end_date_bound_to_trading_date=False,
    market="""中国A股""",
    custom_market="""""",
    m_name="""m1"""
)

# @module(position="-395,-1377", comment="""""", comment_collapsed=True)
m2 = M.input_features_expr.v1(
    features="""
m_avg(turn,5)
m_avg(turn,10)
total_market_cap
mf_net_amount_5 
mf_net_amount_10 
m_avg(volume,5) as avg_volume_5
m_avg(volume,10) as avg_volume_10


#return_5
#return_20
#daily_return_0
#daily_return_1
#adjust_factor_0/adjust_factor_10#415%
#volatility_5_0
#amount_0/avg_amount_30#remove -27%
#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

#过滤因子,这四个因子不参与模型学习
st_status 
low   
price_limit_status
m_lag(low,1) as low_1
""",
    m_name="""m2"""
)

# @module(position="-514,-1040", comment="""""", comment_collapsed=True)
m3 = M.extract_data_expr.v1(
    instruments=m1.data,
    features=m2.data,
    start_date="""""",
    end_date="""""",
    before_start_days=90,
    m_name="""m3"""
)

# @module(position="-977,-1102", comment="""""", comment_collapsed=True)
m4 = M.input_features_expr.v1(
    features="""m_lead(close,-2) / m_lead(open, -1) AS _future_return
all_quantile_cont(_future_return, 0.01) AS _future_return_1pct
all_quantile_cont(_future_return, 0.99) AS _future_return_99pct
clip(_future_return, _future_return_1pct, _future_return_99pct) AS _clipped_return
all_cbins(_clipped_return, 20) AS _binned_return
_binned_return AS _label
if( m_lead(high, 1) = m_lead(low, 1), NULL, _label) as label 
""",
    m_name="""m4"""
)

# @module(position="-979,-1037", comment="""""", comment_collapsed=True)
m5 = M.extract_data_expr.v1(
    instruments=m1.data,
    features=m4.data,
    start_date="""""",
    end_date="""""",
    before_start_days=90,
    m_name="""m5"""
)

# @module(position="-726,-916", comment="""""", comment_collapsed=True)
m8 = M.data_join.v4(
    data1=m5.data,
    data2=m3.data,
    on="""date,instrument""",
    how="""inner""",
    sort=True,
    m_name="""m8"""
)

# @module(position="-727,-839", comment="""""", comment_collapsed=True)
m6 = M.data_filter.v5(
    input_data=m8.data,
    expr="""st_status==0 & price_limit_status==2 | price_limit_status ==3 & low>low_1""",
    output_left_data=False,
    m_name="""m6"""
)

# @module(position="-730,-764", comment="""""", comment_collapsed=True)
m12 = M.data_dropnan.v6(
    input_data=m6.data,
    m_name="""m12"""
)

# @module(position="-726,-677", comment="""""", comment_collapsed=True)
m9 = M.python.v2(
    input_1=m12.data,
    run=m9_run_bigquant_run,
    do_run=True,
    m_name="""m9"""
)

# @module(position="-315,-563", comment="""""", comment_collapsed=True)
m7 = M.stock_ranker_dai_train.v9(
    data=m9.data_1,
    learning_algorithm="""排序""",
    number_of_leaves=32,
    min_docs_per_leaf=1000,
    number_of_trees=20,
    learning_rate=0.1,
    max_bins=1072,
    feature_fraction=1,
    data_row_fraction=1,
    plot_charts=True,
    ndcg_discount_base=1,
    m_name="""m7"""
)

# @module(position="70,-1263", comment="""测试集""")
m15 = M.instruments_dai.v3(
    start_date="""2015-01-01""",
    start_date_bound_to_trading_date=False,
    end_date="""2016-01-01""",
    end_date_bound_to_trading_date=True,
    market="""中国A股""",
    custom_market="""""",
    m_cached=False,
    m_name="""m15"""
)

# @module(position="76,-937", comment="""""", comment_collapsed=True)
m16 = M.extract_data_expr.v1(
    instruments=m15.data,
    features=m2.data,
    start_date="""""",
    end_date="""""",
    before_start_days=90,
    m_name="""m16"""
)

# @module(position="76,-861", comment="""""", comment_collapsed=True)
m10 = M.data_filter.v5(
    input_data=m16.data,
    expr="""st_status==0 & price_limit_status==2 | price_limit_status ==3 & low>low_1""",
    output_left_data=False,
    m_name="""m10"""
)

# @module(position="78,-778", comment="""""", comment_collapsed=True)
m17 = M.data_dropnan.v6(
    input_data=m10.data,
    m_name="""m17"""
)

# @module(position="-317,-490", comment="""""", comment_collapsed=True)
m13 = M.stock_ranker_dai_predict.v13(
    model=m7.model,
    data=m17.data,
    m_name="""m13"""
)

# @module(position="-334,-396", comment="""""", comment_collapsed=True)
m14 = M.bigtrader.v34(
    data=m13.predictions,
    start_date="""""",
    end_date="""""",
    initialize=m14_initialize_bigquant_run,
    before_trading_start=m14_before_trading_start_bigquant_run,
    handle_data=m14_handle_data_bigquant_run,
    handle_trade=m14_handle_trade_bigquant_run,
    handle_order=m14_handle_order_bigquant_run,
    capital_base=3000000.1,
    frequency="""daily""",
    product_type="""股票""",
    rebalance_period_type="""交易日""",
    rebalance_period_days="""5""",
    rebalance_period_roll_forward=True,
    backtest_engine_mode="""标准模式""",
    before_start_days=0,
    volume_limit=1,
    order_price_field_buy="""open""",
    order_price_field_sell="""close""",
    benchmark="""沪深300指数""",
    plot_charts=True,
    debug=False,
    backtest_only=False,
    m_name="""m14"""
)
# </aistudiograph>

\

标签

数据处理
{link}