表达式引擎

bigexpr是 BigQuant 开发的表达式计算引擎,通过编写简单的表达式,就可以对数据做任何运算,而无需编写代码。

bigexpr在平台上被广泛使用,M.advanced_auto_labelerM.derived_feature_extractor 都已经由bigexpr驱动,您可以用表达式就可以定义标注目标和完成后特征抽取。

文档

通过表达式,实现数据处理和计算。

e.g. rank(rank(close_0 / close_1) / rank(close_0 / close_10))

在表达式中可以使用

  1. 常量
    • NaN: np.NaN
    • Inf: np.Inf
    • None: None
  2. 支持的运算符
    • 逻辑运算符: & (与), | (或), ~ (非)
    • 比较运算符: <, <=, ==, !=, >=, >
    • 一元算术运算符: - (负)
    • 二元算术运算符: +, -, , /, * (次方), % (取余), << (位运算:左移), >> (位运算:后移)
  3. 简单函数
    • where(cond, x, y):
      如果cond为True,则为 x, 否则 y * 示例:where(a > b, c, d) * 示例:where(a > b, where(a > c, c, d), e)
    • iif
      where的别名
    • {sin,cos,tan}(x)
      三角函数正弦,余弦和正切
    • {arcsin,arccos,arctan}(x)
      反三角函数
    • arctan2(x, y)
      反三角函数,=arctan(x/y)
    • {sinh,cosh,tanh}(x)
      双曲正弦,余弦和正切
    • {arcsinh,arccosh,arctanh}(x)
      反双曲正弦,余弦和正切
    • {log,log10,log1p}(x)
      自然对数, 10为底的对数和log(1+x)
    • {exp,expm1}(x)
      指数和exp(x)-1
    • sqrt(x)
      平方根
    • abs(x)
      绝对值
    • ceil(x)
      向上取整
    • floor(x)
      向下取整
    • sign(x)
      取 x 的符号,如果 x > 0, 为1; x == 0,为0; 否则为-1
    • signedpower(x, a)
      等价于 sign(x) * (abs(x)**a)
    • min(numer1, number2, number3, ..): number
      求最小值,2个或者更多个参数
    • max(numer1, number2, number3, ..): number
      求最大值,2个或者更多个参数
    • isnan(number): bool
      判断是否为NaN, e.g. where(isnan(a), 0, a)
    • clip(s, lower, upper)
      对s做裁剪,如果<lower,则设置为lower,如果>upper,则设置为upper
    • all_quantile(s, q)
      计算s的第q个百分位数, q属于[0, 1]。则 all_quantile(s, 0)得到s的最小值,all_quantile(s, 1)对应s的最大值。注意,这里计算的是全部s数据的百分位(而不是按天或者按股票处理的)
    • all_wbins(s, bins)
      按等宽做离散化,映射从0开始。bins可以是正整数,表示bins的数量;list,表示splits,e.g. [-2, 0, 2],小于-2的数据将被映射为0,大于2的被映射为3,中间的分别为1和2
    • all_cbins(s, bins)
      按等频做离散化,映射从0开始。bins可以是正整数,表示bins的数量;list,表示每个bin里的数据比例
  4. 按股票分组后的数据处理函数
    • shift(x, d)
      • d天以前的x值。如果d为负数,则表示 abs(d)天以后的值
      • 一般在特征抽取时,用到的d都为正数,否则将可能引入未来数据
      • 在数据标注时,可能用到d为负数的情况
    • delay
      shift的别名
    • delta(x, d)
      今天的 x 值减去 d 天以前的 x 值
    • correlation(x, y, d)
      在过去长度为 d 天, x 和 y 的相关性
    • covariance(x,y,d)
      在过去长度为 d 天, x 和 y 的协方差
    • sum(x,d)
      过去 d 天 x 的和
    • product(x,d)
      过去 d 天 x 的乘积
    • std(x,d)
      过去 d 天 x 的标准差
    • mean(x,d)
      过去 d 天x的均值
    • decay_linear(x, d)
      过去 d 天的加权平均,权重是1,…,d-1,d
    • stddev
      std的别名
    • ts_min(x,d)
      时间序列函数, d 天内的最小值
    • ts_max(x,d)
      时间序列函数, d 天内的最大值
    • ts_argmax(x, d)
      时间序列函数, d 天内的最大值发生在哪一天
    • ts_argmin(x, d)
      时间序列函数, d 天内的最小值发生在哪一天
    • ts_rank(x, d)
      时间序列函数, 当天的值在d天的内的排名百分比
  5. 按日期分组后的数据处理函数
    • rank(x)
      x在当天的百分比排名, e.g. rank(close_0/close_1)
    • scale(x, a=1)
      重新缩放x,使得 sum(abs(x)) = a (a的默认值为1)
  6. 按日期和自定义key分组的处理函数
    • group_mean(key, x)
      同时按日期和key做分组,求平均。 eg. 各行业的简单平均pe值: group_mean(industry_sw_level1_0, pe_ttm_0)
    • group_sum(key, x)
      同时按日期和key做分组,求和。 eg. 各行业的交易量: group_sum(industry_sw_level1_0, amount_0)
    • group_rank(key, x)
      同时按日期和key做分组,求当前值在分组内的排名百分比。 eg. pe值在对应行业的排名: group_rank(industry_sw_level1_0, pe_ttm_0)
  7. TA-LIB部分技术指标
    • ta_sma(x, timeperiod)
      timeperiod周期的简单移动平均值
    • ta_ema(x, timeperiod)
      timeperiod周期的指数移动平均值
    • ta_wma(x, timeperiod)
      timeperiod周期的加权移动平均值
    • ta_mom(x, timeperiod)
      timeperiod周期的动量指标
    • ta_roc(x, timeperiod)
      timeperiod周期的变动率指标
    • ta_rsi(x, timeperiod)
      timeperiod周期的相对强弱指标
    • ta_trix(x, timeperiod)
      timeperiod周期的三重指数平滑平均线
    • ta_willr(x, timeperiod)
      timeperiod周期的威廉指标
    • ta_atr(high, low, close, timeperiod)
      timeperiod周期的均幅指标
    • ta_adx(high, low, close, timeperiod)
      timeperiod周期的平均趋向指数
    • ta_adxr(high, low, close, timeperiod)
      timeperiod周期的平均趋向指数
    • ta_cci(high, low, close, timeperiod)
      timeperiod周期的顺势指标
    • ta_beta(x, y, timeperiod)
      timeperiod周期的回归斜率
  8. 自定义函数
    • 用户可以自定义函数,用于添加新函数或者覆盖原函数
    • 函数接口:func(df, arg, ..)
    • func为函数名称
    • df为预定义参数,包括了DataFrame数据
    • arg,函数参数,可以有多个,或者使用 *args 实现任意个数参数

示例代码

数据标注:

conf.label_expr = [
    # 计算收益:5日收盘价(作为卖出价格)除以明日开盘价(作为买入价格)
    'shift(close, -5) / shift(open, -1)',
    # 极值处理:用1%和99%分位的值做clip
    'clip(label, all_quantile(label, 0.01), all_quantile(label, 0.99))',
    # 将分数映射到分类,这里使用20个分类
    'all_wbins(label, 20)',
    # 过滤掉一字涨停的情况 (设置label为NaN,在后续处理和训练中会忽略NaN的label)
    'where(shift(high, -1) == shift(low, -1), NaN, label)'
]

m1 = M.advanced_auto_labeler.v2(
    instruments=conf.instruments, start_date=conf.start_date, end_date=conf.split_date,
    label_expr=conf.label_expr, benchmark='000300.SHA')

衍生特征抽取:

conf.features = [
    'return_5',  # 5日收益
    'return_10',  # 10日收益
    'return_20',  # 20日收益
    'avg_amount_0/avg_amount_5',  # 当日/5日平均交易额
    'avg_amount_5/avg_amount_20',  # 5日/20日平均交易额
]

# 抽取基础特征,比如 return_5, return_10, ..
m2 = M.general_feature_extractor.v5(
    instruments=conf.instruments,
    start_date=conf.start_date, end_date=conf.split_date,
    features=conf.features)
# 计算衍生特征,比如 avg_amount_0/avg_amount_5 ..
m2_1 = M.derived_feature_extractor.v2(input_data=m2.data, features=conf.features)
# 再计算一个衍生特征,比如 rank(return_10 / return_20)
m2_2 = M.derived_feature_extractor.v2(
    input_data=m2.data,
    features=['rank(return_10 / return_20)'])

用户自定义函数衍生特征抽取:

# 抽取基础特征,比如 return_5, return_10, ..
m2 = M.general_feature_extractor.v5(
    instruments=conf.instruments,
    start_date=conf.start_date, end_date=conf.split_date,
    features=conf.features)
# 计算衍生特征,比如 avg_amount_0/avg_amount_5 ..
m2_1 = M.derived_feature_extractor.v2(input_data=m2.data, features=conf.features)

# 自定义函数
def timex(df, s, x):
    return s * x

m2_2 = M.derived_feature_extractor.v2(
    input_data=m2.data,
    features=['timex(close_1 / close_0, 100)'])