为什么我的程序在我的交易”达到条件没有交易

策略分享
标签: #<Tag:0x00007fcf63651e38>

(chidaye) #1
克隆策略
In [ ]:
# 获取股票代码
instruments = D.instruments()
# 确定起始时间
start_date = '2013-01-01' 
# 确定结束时间
end_date = '2018-01-01' 
# 获取股票市净率数据,返回DataFrame数据格式
market_cap_data = D.history_data(instruments,start_date,end_date,
              fields=['pb_lf','amount'])
# 获取每日按市净率排序 (从低到高)的前三十只股票
daily_buy_stock = market_cap_data.groupby('date').apply(lambda df:df[(df['amount'] > 0)&((df['pb_lf'] > 0))].sort_values('pb_lf')[:10])
print (daily_buy_stock)


bm_price = D.history_data(['000300.SHA'], start_date , end_date, fields=['close'])
bm_price['sma'] = bm_price['close'].rolling(5).mean()
bm_price['lma'] = bm_price['close'].rolling(30).mean()
bm_price['gold_cross_status'] = bm_price['sma'] > bm_price['lma']
bm_price['pos_percent'] = np.where(bm_price['gold_cross_status'],1,0)
pos_df = bm_price[['date', 'pos_percent']].set_index('date')




# 2. 策略主体函数
# 回测参数设置,initialize函数只运行一次
def initialize(context):
    # 手续费设置
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) 
    # 调仓规则(每月的第一天调仓)
    context.schedule_function(rebalance, date_rule=date_rules.month_start(days_offset=0)) 
    # 传入 整理好的调仓股票数据
    context.daily_buy_stock = daily_buy_stock
    context.pos = pos_df

# handle_data函数会每天运行一次
def handle_data(context,data):
    date = data.current_dt.strftime('%Y-%m-%d')
    stock_hold_now = [equity.symbol for equity in context.portfolio.positions]
    # 满足空仓条件
    if context.pos.ix[date].pos_percent == 0:
        # 全部卖出
        for stock in stock_hold_now:
            if data.can_trade(context.symbol(stock)):
                context.order_target_percent(context.symbol(stock), 0)
# 换仓函数
def rebalance(context, data):
    # 当前的日期
    date = data.current_dt.strftime('%Y-%m-%d')
    # 根据日期获取调仓需要买入的股票的列表
    stock_to_buy = list(context.daily_buy_stock.ix[date].instrument)
    # 通过positions对象,使用列表生成式的方法获取目前持仓的股票列表
    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]
    # 需要卖出的股票
    stock_to_sell = [i for i in stock_hold_now if i not in no_need_to_sell]
  
    # 卖出
    for stock in stock_to_sell:
        # 如果该股票停牌,则没法成交。因此需要用can_trade方法检查下该股票的状态
        # 如果返回真值,则可以正常下单,否则会出错
        # 因为stock是字符串格式,我们用symbol方法将其转化成平台可以接受的形式:Equity格式

        if data.can_trade(context.symbol(stock)):
            # order_target_percent是平台的一个下单接口,表明下单使得该股票的权重为0,
            #   即卖出全部股票,可参考回测文档
            context.order_target_percent(context.symbol(stock), 0)
    
    # 如果当天没有买入的股票,就返回
    if len(stock_to_buy) == 0:
        return

    # 等权重买入 
    weight =  1 / len(stock_to_buy)
    
    # 买入
    for stock in stock_to_buy:
        if data.can_trade(context.symbol(stock)):
            # 下单使得某只股票的持仓权重达到weight,因为
            # weight大于0,因此是等权重买入
            context.order_target_percent(context.symbol(stock), weight)

# 3. 启动回测

m = M.trade.v2( 
    instruments=instruments,
    start_date=start_date, 
    end_date=end_date,
    # 必须传入initialize,只在第一天运行
    initialize=initialize,
    #  必须传入handle_data,每个交易日都会运行
    handle_data=handle_data,
    # 买入以开盘价成交
    order_price_field_buy='open',
    # 卖出也以开盘价成交
    order_price_field_sell='open',
    # 策略本金
    capital_base=60000,
    # 比较基准:沪深300
    benchmark='000300.INDX',
    price_type='real'
)

(iQuant) #2

您好,你的策略回测没有问题,对吧?
那么为什么模拟交易不行呢?你可以参考:小市值策略

原因就是:你需要在策略里面有prepare函数,这样策略模拟交易就会每天准备好相应的数据,就没问题啦!