问答交流

日频交易cash不更新吗?

由lookit创建,最终由lookit 被浏览 71 用户

在进行编写日频策略时,发现一个奇怪的问题

{w:100}当日9:30卖出股票,当日15:00买入股票时仅买了一个零头,这让我百思不得其解,猜测bigquant的cash更新逻辑是隔天更新。如果要使得策略正常运行,是否需要将其改为分钟测试呢?

附上所用的回测函数

回测引擎:初始化函数,只执行一次

def m8_initialize_bigquant_run(context):

# 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
#context.set_commission(PerOrder(buy_cost=0.00001, sell_cost=0.0001, min_cost=1))

# 设置买入的股票数量,这里买入预测股票列表排名靠前的5只
context.stock_count = 1
# 每只的股票的权重,如下的权重分配会使得靠前的股票分配多一点的资金,[0.339160, 0.213986, 0.169580, ..]
#context.stock_weights = T.norm([1 / math.log(i + 2) for i in range(0, stock_count)])
# 每只股票的权重平均分配
context.stock_weights = 1/context.stock_count
# 设置每只股票占用的最大资金比例
context.max_cash_per_instrument = 1
context.options['hold_days'] = 0

回测引擎:每日数据处理函数,每天执行一次

def m8_handle_data_bigquant_run(context, data): today = data.current_dt.strftime('%Y-%m-%d') equities = {e.symbol: p for e, p in context.portfolio.positions.items() if p.amount>0} stock_now = len(equities); #获取当前持仓股票数量 stock_count = context.stock_count

# 按日期过滤得到今日的预测数据
# 加载预测数据
df = context.options['data'].read_df()
df_today = df[df.date == data.current_dt.strftime('%Y-%m-%d')]
df_today.set_index('instrument')


now_stock = []
sell_stock = []
   
try:
    buy_list = context.daily_buy_stock[today]
except:
    buy_list = []


# 1. 资金分配
#is_staging = context.trading_day_index < context.options['hold_days'] # 是否在建仓期间(前 hold_days 天) 
#stock_cash = context.portfolio.portfolio_value/stock_count
#cash_avg = context.portfolio.portfolio_value
#cash_for_buy = min(context.portfolio.cash,  stock_cash)
#cash_for_sell = cash_avg - (context.portfolio.cash - cash_for_buy)

positions = {e.symbol: p.amount * p.last_sale_price
             for e, p in context.perf_tracker.position_tracker.positions.items()}

        
#if not is_staging :
if 1==1 :    
    if len(equities) > 0:
        for i in equities.keys():
            last_sale_date = equities[i].last_sale_date	# 上次交易日期
            delta_days = data.current_dt - last_sale_date  
            hold_days = delta_days.days # 持仓天数
            if hold_days >= context.options['hold_days'] and i not in buy_list :
                print('日期:',today,'卖出2:',i)
                context.order_target(context.symbol(i), 0)
                sell_stock.append(i)
                stock_now = stock_now -1
                #print('日期:', today, '股票:', i, ' 卖出')

3. 生成买入订单

buy_num = stock_count - stock_now
#if is_staging :
#    buy_num = 1
if len(buy_list)>0:
    print('日期:', today, '选出股票数量:', len(buy_list))
if buy_num>0 and len(buy_list)>0 :
    # 不再买入已经轮仓卖出和移动止损的股票,以防止出现空头持仓
    buy_instruments = [i for i in buy_list if i not in now_stock][:buy_num]
    print(buy_list)
    cash_for_buy = context.portfolio.cash/len(buy_instruments)
    for i, instrument in enumerate(buy_instruments):
        current_price = data.current(context.symbol(instrument), 'price')
        
        if cash_for_buy>0 and data.can_trade(context.symbol(instrument)):           
            amount = math.floor(cash_for_buy / current_price / 100) * 100
            context.order(context.symbol(instrument), amount)
            #if(instrument=='002735.SZA'):
            print('日期:',today,'买入:',instrument)
        else :
            print('日期:',today,'无资金或不能交易未买入:',instrument)

回测引擎:准备数据,只执行一次

def m8_prepare_bigquant_run(context): # 加载预测数据 df = context.options['data'].read_df() # 函数:求满足开仓条件的股票列表 def open_pos_con(df): return list(df[df['buy_condition']>0].instrument) # 函数:求满足平仓条件的股票列表 def close_pos_con(df): return list(df[df['sell_condition']>0].instrument)

# 每日卖出股票的数据框
context.daily_sell_stock= df.groupby('date').apply(close_pos_con)  
# 每日买入股票的数据框
context.daily_buy_stock= df.groupby('date').apply(open_pos_con)  

回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。

def m8_before_trading_start_bigquant_run(context, data): pass

\

评论
  • 能分享下策略吗?看下具体是什么原因。
  • [https://bigquant.com/experimentshare/7ded062427cc484d801d79d24a5bbe23](https://bigquant.com/experimentshare/7ded062427cc484d801d79d24a5bbe23) \
{link}