摘要
ProjectionOscillator 是 Widner 投影振荡器的流式实现。它衡量收盘价在按斜率
投影得到的最高价/最低价包络带中的位置,并用短周期 SMA 生成信号线。
更新 API
result = rtta.ProjectionOscillator(
window=14, signal_window=3, fillna=True
).update(high, low, close)
# result.value, result.signal, result.upper, result.lower
advance(...) 只更新状态,不生成 Python 对象;多输出 batch(...) 为四个字段
分别返回数组。
工作原理
投影带并不是简单地取两条回归线在最新时点的拟合值。算法先求最高价与最低价 各自的回归斜率,再把窗口内的每一个历史最高价和最低价向前投影到当前 K 线。所有投影最高价中的最大者与所有投影最低价中的最小者构成包络通道; 它既随局部斜率变化,又保留窗口极值的包容性。
递推公式
在含 \(m\le n\) 个观测的窗口内,令 \(j=0\) 表示最早观测,\(j=m-1\) 表示当前观测。以普通最小二乘法得到最高价斜率 \(\beta_H\) 和最低价斜率 \(\beta_L\),再把每个点投影到当前索引:
\[\widehat H_j=H_j+\beta_H(m-1-j),\qquad
\widehat L_j=L_j+\beta_L(m-1-j).\]
投影包络带为:
\[U_t=\max_{0\le j<m}\widehat H_j,\qquad
L_t=\min_{0\le j<m}\widehat L_j.\]
振荡值与信号线为:
\[PO_t=100\frac{C_t-L_t}{U_t-L_t},\qquad
signal_t=SMA_{n_s}(PO_t).\]
带宽为零时使用安全除法。对合法 OHLC 输入,当前最高价和最低价本身也在候选 集合中,因此收盘价仍会落在这个包络通道内。
当 fillna=False 时,在取得 window 个观测之前,value、upper、
lower 均为 NaN;signal 还需要取得 signal_window 个振荡值。
当 fillna=True 时,回归和信号线都使用当时已有的历史立即计算。
实现说明
递推过程在 src/rtta/indicator.cpp 的 class ProjectionOscillator 中实现,
内部使用两个 LinearRegressionCore、最高价/最低价滚动缓冲区和一条信号
SMA。
