BigQuant使用文档

134-自定义买入卖出逻辑

由qxiao创建,最终由qxiao 被浏览 133 用户

本文是关于交易引擎BigTrader使用的一些小技巧。虽然在之前的旧文档也介绍过,见文末附录链接。但本文有一些不一样的地方。

设置股票为等权

以前我们习惯于在初始化函数中定义股票权重,为简化交易引擎模块的代码,我们最近新增了一个仓位分配的模块,用于设置股票权重,当前提供了三种权重分配的使用示例,排序倒数、对数下降和等权重,小伙伴也可自行使用DAI算子灵活设置权重。 下图以等权重为例


运行完后,我们可以看到每天要建仓的票就是等权重了,因为我们设置了持仓股票数量为10,因此单票权重为0.1.

每隔几天运行一次

在之前的代码里,我们是通过记录一个索引,如果索引值能够整除调仓天数那么就是调仓期,目前可以通过context.rebalance_period.is_signal_date这个方法来实现。

#下一个交易日不是调仓日,则不生成信号
if not context.rebalance_period.is_signal_date(data.current_dt.date()):
   return


这里调仓周期类型 选择 交易日。

我们通过日志可以看出,交易引擎会通过is_signal_date判断当前日期是否是调仓日,如果是的话,就返回True,否则为False。

这里,可以看出每5天是一个True.

指定时间运行

我们在之前的文章里,介绍了在初始化函数中通过schedule_function方法设置定时运行rebalance函数,因为交易引擎的核心没有改变,因此现在依然可以使用这种方式。 但本文更多是介绍另外一种方法来实现按指定时间运行。

在BigTrader模块,我们可以修改调仓周期类型,支持按周、月、季、年度进行指定时间运行。


如果我们勾选的是周度交易日,那么会在每周第一个交易日进行调仓。其他也是同理,如果设置的是月度交易日,那交易引擎会在每月第一个交易日进行调仓。可以发现和每隔几天固定运行有一定差异。之前我们按月调仓是每隔22个交易日运行,但无法实现每月第一个交易日调仓。如果我们设置了调仓周期类型这个参数,那我们调仓周期日期默认设置为1.


持有固定天数卖出

持有固定自然日天数

def bigquant_run(context, data):
    import pandas as pd
    from datetime import datetime 
     
     
    if not context.rebalance_period.is_signal_date(data.current_dt.date()):
        return
     
  
    # 从传入的数据 context.data 中读取今天的信号数据
    today_df = context.data[context.data["date"] == data.current_dt.strftime("%Y-%m-%d")]
    target_instruments = set(today_df["instrument"])
 
    # 获取当前已持有股票
    holding_instruments = set(context.get_account_positions().keys())
     
    # 账户持仓
    account_pos = context.get_account_positions() 
     
 
    # 卖出不在目标持有列表中的股票
    for instrument in holding_instruments:
        open_date = account_pos[instrument].open_date 
          
        # 持仓天数(自然日)
        delta_days = (data.current_dt - datetime.strptime(open_date, "%Y%m%d")).days
         
        # 超过10个交易日 就卖出
        if delta_days > 10:
            context.order_target_percent(instrument, 0)
            print('====持仓达到某自然日卖出====',data.current_dt, instrument)
         
         
    # 买入目标持有列表中的股票
    for i, x in today_df.iterrows():
        # 处理 null 或者 decimal.Decimal 类型等
        position = 0.0 if pd.isnull(x.position) else float(x.position)
        context.order_target_percent(x.instrument, position)

持有固定交易日天数卖出


先传入一个外部数据,交易日历数据,我们用数据抽取模块得到。



然后,我们在BigTrader模块的初始化函数里用context.options['data'].read() 将交易日历读出来。


接着,我们就可以计算持仓的交易天数了,代码如下:

def bigquant_run(context, data):
    import pandas as pd
    from datetime import datetime 
     
    # 该函数用于计算两个字符串日期间隔的交易天数
    def get_hold_days(sd,ed,trading_days_df):
        # 计算两个字符串日期之间间隔的交易天数
        df = trading_days_df
        return df[(df['date'] >=sd) & (df['date']<=ed)].shape[0] - 1
     
     
    if not context.rebalance_period.is_signal_date(data.current_dt.date()):
        return
     
  
    # 从传入的数据 context.data 中读取今天的信号数据
    today_df = context.data[context.data["date"] == data.current_dt.strftime("%Y-%m-%d")]
    target_instruments = set(today_df["instrument"])
 
    # 获取当前已持有股票
    holding_instruments = set(context.get_account_positions().keys())
     
    # 账户持仓
    account_pos = context.get_account_positions() 
     
 
    # 卖出不在目标持有列表中的股票
    for instrument in holding_instruments:
        open_date = account_pos[instrument].open_date
          
        # 持仓天数(交易日)
        delta_days = get_hold_days(datetime.strptime(open_date, "%Y%m%d"), data.current_dt.strftime("%Y-%m-%d"),  context.trading_days_df)
          
        # 超过10个交易日 就卖出
        if delta_days > 10:
            context.order_target_percent(instrument, 0)
            print('====持仓达到某交易日卖出====',data.current_dt, instrument)
         
         
    # 买入目标持有列表中的股票
    for i, x in today_df.iterrows():
        # 处理 null 或者 decimal.Decimal 类型等
        position = 0.0 if pd.isnull(x.position) else float(x.position)
        context.order_target_percent(x.instrument, position)

\

止盈止损 、大盘风控

请移步:https://bigquant.com/wiki/doc/114-YCE9b0Z1h3

旧版文档: https://bigquant.com/wiki/doc/6ieq5a6a5lmj5lmw5ywl5y2w5ye66yc76l6r-OCkaNT91EC

标签

交易引擎
{link}