In his TASC article series about no-lag indicators, John Ehlers presented last month the Ultimate Oscillator. What’s so ultimate about it? Unlike other oscillators, it is supposed to indicate the current market direction with almost no lag.
The Ultimate Oscillator is built from the difference of two highpass filters. The highpass function below is a straightforward conversion of Ehlers’ EasyLanguage code to C:
var HighPass3(vars Data,int Period)
{
var a1 = exp(-1.414*PI / Period);
var c2 = 2*a1*cos(1.414*PI / Period);
var c3 = -a1*a1;
var c1 = (1.+c2-c3) / 4;
vars HP = series(0,3);
return HP[0] = c1*(Data[0]-2*Data[1]+Data[2])+c2*HP[1]+c3*HP[2];
}
The function is named HighPass3 because we have already 3 other highpass filters in the Zorro indicator library, all with different code. The Ultimate Oscillator is the difference of two highpass filters with different periods, and scaled by its root mean square for converting the output to standard deviations. Fortunately Zorro has already a sum of squares function, which makes the code shorter and simpler than Ehlers’ original:
var UltimateOsc(vars Data,int Edge,int Width)
{
vars Signals = series(HighPass3(Data,Width*Edge)-HighPass3(Data,Edge));
var RMS = sqrt(SumSq(Signals,100)/100);
return Signals[0]/fix0(RMS);
}
For checking its lag and smoothing power, we apply the Ultimate Oscillator to an S&P500 chart from 2024:
void run()
{
BarPeriod = 1440;
StartDate = 20240101;
EndDate = 20241231;
asset("SPX500");
plot("UltOsc", UltimateOsc(seriesC(),20,2),LINE,RED);
}
The resulting chart replicates Ehler’s chart in the article. The Oscillator output is the red line:

We can see that the ultimate oscillator reproduces the market trend remarkably well and with no visible lag. The code can be downloaded from the 2025 script repository.
My code conversion had a bug in a Highpass coefficient, it’s fixed now. The script in the repository contains the correct code.
Hi Petra, I found this article https://www.mesasoftware.com/papers/UltimateSmoother.pdf of the Ehlers Ultimate oscillator and I dont understand where this part of the function (EasyLanguage High Pass Filter Function) is gone in the Lite-C code conversion:
If CurrentBar >= 4 Then $HighPass = c1*(Price – 2*Price[1] + Price[2]) +
c2*$HighPass[1] + c3*$HighPass[2];
If Currentbar < 4 Then $HighPass = 0;
Furthermore what you call the "Ultimate oscillator" in Ehlers document call it is called "the Band Pass filter" but also here I dont understand the code conversion applied?
Thanks for your attention and understanding
My code is not from that paper, but a conversion from an article in TASC. I believe Ehlers has written many Ultimate smoothers or oscillators, all with different code.
Hi Petra, I understand. Can you share where I can find “TASC” and what is it ?
Thanks for your attention and understanding
https://traders.com/
Thanks for your response! Really interesting article to look for new ideas on that site!
I have zorro ver 2.70.0 but as I can see HighPass3 (4 HighPass filters) is already available . Is it the same as the one descripted in this article?
Thanks for your attention and understanding