ProjectionOscillator

Incremental, causal technical analysis documentation

Summary

ProjectionOscillator is RTTA's streaming Widner projection oscillator. It places close inside slope-projected enclosing high/low bands and smooths the oscillator with a short SMA signal line.

Update API

result = rtta.ProjectionOscillator(
    window=14, signal_window=3, fillna=True
).update(high, low, close)
# result.value, result.signal, result.upper, result.lower

advance(...) updates state without returning a Python object. Multi-output batch(...) returns arrays for all four fields.

Theory Of Operation

Projection bands are not merely the latest fitted values of two regressions. The high and low regression slopes are used to project each historical high and low forward to the current bar. Taking the greatest projected high and least projected low produces an enclosing channel that follows local slope while retaining the protection of window extremes.

Recurrence

Within a window of \(m\le n\) observations, index \(j=0\) is oldest and \(j=m-1\) is current. Let \(\beta_H\) and \(\beta_L\) be ordinary least-squares slopes fitted to the high and low series. Project each point to the current index:

\[\widehat H_j=H_j+\beta_H(m-1-j),\qquad \widehat L_j=L_j+\beta_L(m-1-j).\]

The enclosing projection bands are

\[U_t=\max_{0\le j<m}\widehat H_j,\qquad L_t=\min_{0\le j<m}\widehat L_j.\]

Then

\[PO_t=100\frac{C_t-L_t}{U_t-L_t},\qquad signal_t=SMA_{n_s}(PO_t),\]

with safe division when band width is zero. For valid OHLC input, the current high and low themselves are members of the candidate set, so close remains inside the enclosing channel.

With fillna=False, value, upper, and lower are NaN until window observations are available; signal additionally needs signal_window oscillator values. With fillna=True, both regressions and the signal use the history available so far.

Implementation Notes

The recurrence is implemented in src/rtta/indicator.cpp in class ProjectionOscillator, using two LinearRegressionCore instances, rolling high/low buffers, and an SMA signal.

Reference