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:
The enclosing projection bands are
Then
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.
