Jack & Jill
TradeStation: December 2026
In the article “The Jack & Jill Indicator” in this issue, John Ehlers uses two adaptive SuperSmoother filters to identify the direction and strength of market trend. "Jack" responds quickly to price changes, while "Jill" filters out most cyclical fluctuations to provide a smoother representation of the underlying trend. When Jack is above Jill, the trend is considered bullish. When Jack is below Jill, the trend is considered bearish. The distance between the two lines reflects the strength of the trend.
Code: Select all
Function: $SuperSmoother
{
$SuperSmoother Function
(C) 2025 John F. Ehlers
}
inputs:
Price( numericseries ),
Period( numericsimple );
variables:
A0( 0 ),
Q( 0 ),
C1( 0 ),
C2( 0 );
Q = ExpValue( -1.414*3.14159 / Period );
C1 = 2 * Q * Cosine(1.414*180 / Period);
C2 = Q*Q;
A0 = (1 - c1 + c2) / 2;
if CurrentBar >= 4 Then $SuperSmoother = A0*( Price +
Price[1]) + C1 * $SuperSmoother[1] - C2 * $SuperSmoother[2];
if Currentbar < 4 then
$SuperSmoother = Price;
Function: $RMS
{
$RMS Function
(C) 2025 John F. Ehlers
}
inputs:
Price( numericseries ),
Length( numericsimple );
variable:
SumSq( 0 ),
Count( 0 );
SumSq = 0;
for Count = 0 to Length - 1
begin
SumSq = SumSq + Price[count]*Price[count];
end;
if SumSq <> 0 then
$RMS = SquareRoot(SumSq / Length);
Indicator: The Jack & Jill
{
Jack & Jill Indicator
(C) 2025 John F. Ehlers
}
inputs:
Period0( 20 );
variables:
Jack( 0 ),
Jill( 0 ),
JackPeriod( 20 ),
JillPeriod( 20 ),
JackRMS( 0 ),
JillRMS( 0 ),
JackROC( 0 ),
JillROC( 0 );
//adaptive SuperSmoother
Jack = $SuperSmoother( Close, JackPeriod );
//RMS for Jack ROC
JackRMS = $RMS( Jack - Jack[1], 81 );
//Normalize Jack ROC in Standard Deviations
if JackRMS <> 0 then
JackROC = AbsValue( (Jack - Jack[1]) / JackRMS );
if JackROC > 2 Then JackROC = 2;
//Period for adaptive SuperSmoother (Jack) on next bar
JackPeriod = Period0 * (1 - .5 * JackROC)
* (1 - .5 * JackROC);
if JackPeriod < 2 then
JackPeriod = 2;
//contra-adaptive SuperSmoother
Jill = $SuperSmoother( Close, JillPeriod );
//RMS for Jill ROC
JillRMS = $RMS( (Jill - Jill[1]), 81 );
//Normalize Jill ROC in Standard Deviations
if JillRMS <> 0 then
JillROC = AbsValue( (Jill - Jill[1]) / JillRMS );
if JillROC > 2 then
JillROC = 2;
//Period for contral-adaptive SuperSmoother (Jill)
//on next bar
JillPeriod = Period0
* (1 + .5 * JillROC) * (1 + .5 * JillROC);
//Plot results
Plot1( Jack, "Jack" );
Plot2( Jill, "Jill" );
Indicator: The Jack & Jill Oscillator
{
Jack & Jill Oscillator Indicator
(C) 2025 John F. Ehlers
}
inputs:
Period0( 20 );
variables:
Jack( 0 ),
Jill( 0 ),
JackPeriod( 20 ),
JillPeriod( 20 ),
JackRMS( 0 ),
JillRMS( 0 ),
JackROC( 0 ),
JillROC( 0 );
//adaptive SuperSmoother
Jack = $SuperSmoother( Close, JackPeriod );
//RMS for Jack ROC
JackRMS = $RMS( Jack - Jack[1], 81 );
//Normalize Jack ROC in Standard Deviations
if JackRMS <> 0 then
JackROC = AbsValue( (Jack - Jack[1]) / JackRMS );
if JackROC > 2 Then JackROC = 2;
//Period for adaptive SuperSmoother (Jack) on next bar
JackPeriod = Period0 * (1 - .5 * JackROC) * (1 - .5 * JackROC);
if JackPeriod < 2 then
JackPeriod = 2;
//contra-adaptive SuperSmoother
Jill = $SuperSmoother( Close, JillPeriod );
//RMS for Jill ROC
JillRMS = $RMS( (Jill - Jill[1]), 81 );
//Normalize Jill ROC in Standard Deviations
if JillRMS <> 0 then
JillROC = AbsValue( (Jill - Jill[1]) / JillRMS );
if JillROC > 2 then
JillROC = 2;
//Period for contral-adaptive SuperSmoother (Jill) on next bar
JillPeriod = Period0 * (1 + .5 * JillROC) * (1 + .5 * JillROC);
//Plot results
Plot1( 0, "Zero" );
Plot2( Jack - Jill, "Jack & Jill Osc" );
Sample Chart FIGURE 1: TRADESTATION. This shows a daily chart of the continuous emini S&P 500 futures contract (ES), showing a portion of 2026 with the Jack & Jill indicator and its oscillator version applied.
This article is for informational purposes. No type of trading or investment recommendation, advice, or strategy is being made, given, or in any manner provided by TradeStation Securities or its affiliates.