表达式引擎¶
bigexpr是 BigQuant 开发的表达式计算引擎,通过编写简单的表达式,就可以对数据做任何运算,而无需编写代码。
bigexpr在平台上被广泛使用,M.advanced_auto_labeler 和 M.derived_feature_extractor 都已经由bigexpr驱动,您可以用表达式就可以定义标注目标和完成后特征抽取。
文档¶
通过表达式,实现数据处理和计算。
e.g. rank(rank(close_0 / close_1) / rank(close_0 / close_10))
在表达式中可以使用
- 常量
- NaN: np.NaN
- Inf: np.Inf
- None: None
- 支持的运算符
- 逻辑运算符: & (与), | (或), ~ (非)
- 比较运算符: <, <=, ==, !=, >=, >
- 一元算术运算符: - (负)
- 二元算术运算符: +, -, , /, * (次方), % (取余), << (位运算:左移), >> (位运算:后移)
- 简单函数
- 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里的数据比例
- 按股票分组后的数据处理函数
- 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天的内的排名百分比
- 按日期分组后的数据处理函数
- rank(x)
- x在当天的百分比排名, e.g. rank(close_0/close_1)
- scale(x, a=1)
- 重新缩放x,使得 sum(abs(x)) = a (a的默认值为1)
- 按日期和自定义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)
- 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周期的回归斜率
- 自定义函数
- 用户可以自定义函数,用于添加新函数或者覆盖原函数
- 函数接口: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)'])