feat(factors): 添加时间序列函数及智能路由

- 新增 8 个国泰君安 191 兼容的时间序列函数:ts_sma, ts_wma, ts_decay_linear, ts_argmax, ts_argmin, ts_count, ts_prod, ts_sumac
- max_/min_ 函数智能路由:正整数参数自动调用 ts_max/ts_min 实现滚动窗口逻辑
This commit is contained in:
2026-03-15 13:05:55 +08:00
parent 0e9ea5d533
commit c6ebab0e58
3 changed files with 467 additions and 2 deletions

View File

@@ -510,26 +510,40 @@ def abs(x: Union[Node, str]) -> FunctionNode:
def max_(x: Union[Node, str], y: Union[Node, str, int, float]) -> FunctionNode:
"""逐元素最大值。
智能分发逻辑:
- 如果 y 是正整数 (y > 0),调用 ts_max(x, y) 滚动窗口最大值
- 否则,调用逐元素 max(x, y)
注意:避免 MAX(CLOSE - DELAY(CLOSE, 1), 0) 这类场景被错误路由到 ts_max
Args:
x: 第一个因子表达式或字段名字符串
y: 第二个因子表达式、字段名字符串或数值
y: 第二个因子表达式、字段名字符串或正整数(窗口大小)
Returns:
FunctionNode: 函数调用节点
"""
if isinstance(y, int) and y > 0:
return ts_max(x, y)
return FunctionNode("max", x, _ensure_node(y))
def min_(x: Union[Node, str], y: Union[Node, str, int, float]) -> FunctionNode:
"""逐元素最小值。
智能分发逻辑:
- 如果 y 是正整数 (y > 0),调用 ts_min(x, y) 滚动窗口最小值
- 否则,调用逐元素 min(x, y)
Args:
x: 第一个因子表达式或字段名字符串
y: 第二个因子表达式、字段名字符串或数值
y: 第二个因子表达式、字段名字符串或正整数(窗口大小)
Returns:
FunctionNode: 函数调用节点
"""
if isinstance(y, int) and y > 0:
return ts_min(x, y)
return FunctionNode("min", x, _ensure_node(y))
@@ -622,3 +636,129 @@ def where(
FunctionNode: 函数调用节点
"""
return if_(condition, true_val, false_val)
# ==================== 补充的时间序列函数 ====================
def ts_sma(x: Union[Node, str], n: int, m: int) -> FunctionNode:
"""国内平滑移动平均 (Simple Moving Average)。
使用 N*M 平滑,公式: SMA = (M*CLOSE + (N-M)*REF(CLOSE,1)) / N
对应国泰君安 191 因子的 SMA 函数。
Args:
x: 输入因子表达式或字段名字符串
n: 第一个参数,对应公式中的 N
m: 第二个参数,对应公式中的 M
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_sma", x, n, m)
def ts_wma(x: Union[Node, str], window: int) -> FunctionNode:
"""线性加权移动平均 (Weighted Moving Average)。
权重按线性递增,最近一天权重最大。
Args:
x: 输入因子表达式或字段名字符串
window: 滚动窗口大小
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_wma", x, window)
def ts_decay_linear(x: Union[Node, str], window: int) -> FunctionNode:
"""线性衰减移动平均 (Decay Linear)。
与 WMA 等价,权重按线性递增(近期权重最大)。
Args:
x: 输入因子表达式或字段名字符串
window: 滚动窗口大小
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_decay_linear", x, window)
def ts_argmax(x: Union[Node, str], window: int) -> FunctionNode:
"""时间序列最大值位置 (HIGHDAY)。
返回距离过去 window 期内最大值的交易日数。
例如:今天是最高点返回 0昨天是最高点返回 1。
Args:
x: 输入因子表达式或字段名字符串
window: 滚动窗口大小
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_argmax", x, window)
def ts_argmin(x: Union[Node, str], window: int) -> FunctionNode:
"""时间序列最小值位置 (LOWDAY)。
返回距离过去 window 期内最小值的交易日数。
例如:今天是最低点返回 0昨天是最低点返回 1。
Args:
x: 输入因子表达式或字段名字符串
window: 滚动窗口大小
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_argmin", x, window)
def ts_count(condition: Union[Node, str], window: int) -> FunctionNode:
"""窗口内条件为真的天数。
统计过去 window 内满足条件的交易日数量。
Args:
condition: 条件表达式或字段名字符串(布尔型)
window: 滚动窗口大小
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_count", condition, window)
def ts_prod(x: Union[Node, str], window: int) -> FunctionNode:
"""窗口期内的连乘积。
计算过去 window 期因子值的乘积。
Args:
x: 输入因子表达式或字段名字符串
window: 滚动窗口大小
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_prod", x, window)
def ts_sumac(x: Union[Node, str]) -> FunctionNode:
"""累计求和。
从序列开始到当前位置的累计求和。
Args:
x: 输入因子表达式或字段名字符串
Returns:
FunctionNode: 函数调用节点
"""
return FunctionNode("ts_sumac", x)