TASC magazine indicators

1
VAcc

TASC = Technical Analysis of Stocks & Commodities

TradeStation: November 2023
In his article in the September 2023 issue titled “VAcc: A Momentum Indicator Based On Velocity And Acceleration,” author Scott Cong has introduced a new momentum indicator based on the simple physics principles of velocity and acceleration. The indicator is said to be responsive, precise, and easy to use. In addition, the indicator is said to be less susceptible to overbought/oversold saturation. The TradeStation implementation in EasyLangauge uses a VAcc function.

Code: Select all


Function: VAcc

// TASC NOVEMBER 2023
// VAcc Function
// Scott Cong

inputs:
	iLength( numericsimple ),
	iSmooth( numericsimple ),
	iReturnType( numericsimple );

Variables:
	Length( iLength ),
	Avg_acc( 0 ),
	Avg_vel( 0 ),
	Sum_acc( 0 ),
	Sum_vel( 0 ),
	Idx( 0 ),
	Result( 0 );

Sum_vel = 0;

for Idx = 1 to Length
begin
    Sum_vel += (Close - Close[Idx]) / Idx;
end;

Avg_vel = XAverage(Sum_vel / Length, iSmooth);

Sum_acc = 0;

for Idx = 1 to Length
begin
    Sum_acc += (Avg_vel - Avg_vel[Idx]) / Idx;
end;

Avg_acc = Sum_acc / Length;

if iReturnType = 0 then
    Result = Avg_vel
else
    Result = Sum_acc;

VAcc = Result;


Indicator: VAcc 

// TASC NOVEMBER 2023
// VAcc - Velocity (V) and Acceleration (Acc) 	
// Scott Cong

inputs:
	Period( 21 ),
	Smooth( 5 );

variables:
	AvgVel( 0 ),
	AvgAcc( 0 );

AvgVel = 100 * VAcc(Period, Smooth, 0);
AvgAcc = 100 * VAcc(Period, Smooth, 1);

Plot1( AvgVel / Period * 2, "VAcc" );
Plot2( 0, "Zero" );


Re: TASC magazine indicators

2
Laguerre Filters

TradeStation: July 2025
In “Laguerre Filters” in this issue, John Ehlers presents a trend-trading technique using the Laguerre filter. Since Laguerre filters excel at smoothing long-wavelength components in a data set, this makes them particularly well-suited for identifying trading trends.

Code: Select all

Function: Laguerre Filter
{
	TASC JUL 2025
	Laguerre Filter
	(C) 2002-2025 John F. Ehlers
}

inputs:
	Gama( .8 ),
	Length( 40 );

variables:
	L0( 0 ),
	L1( 0 ),
	L2( 0 ),
	L3( 0 ),
	L4( 0 ),
	Laguerre( 0 );
	
L0 = $UltimateSmoother(Close, Length);
L1 = -Gama * L0[1] + L0[1] + Gama * L1[1];
L2 = -Gama * L1[1] + L1[1] + Gama * L2[1];
L3 = -Gama * L2[1] + L2[1] + Gama * L3[1];
L4 = -Gama * L3[1] + L3[1] + Gama * L4[1];

Laguerre = (L0 + 4*L1 + 6*L2 + 4*L3 + L4) / 16;


Plot1( Laguerre );
Plot2( L0 );


Indicator: Laguerre Oscillator
{
	TASC JUL 2025
	Laguerre Oscillator
	(C) 2002-2025 John F. Ehlers
}

inputs:
	Gama( .5 ),
	Length( 30 );

variables:
	L0( 0 ),
	L1( 0 ),
	RMS( 0 ),
	LaguerreOsc( 0 );

L0 = $UltimateSmoother(Close, Length);
L1 = -Gama * L0 + L0[1] + Gama * L1[1];
RMS = $RMS(L0 - L1, 100);

if RMS <> 0 then 
	LaguerreOsc = (L0 - L1) / RMS;
	
Plot1( LaguerreOsc, "Laguerre Osc" );
Plot2( 0, "Zero Line" );

Function: $RMS
{
	RMS Function
	(C) 2015-2025 John F. Ehlers
}

inputs:
	Price( numericseries ),
	Length( numericsimple );

variables:
	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);

Function: $SuperSmoother
{
	UltimateSmoother Function
	(C) 2004-2025 John F. Ehlers
}

inputs:
	Price( numericseries ),
	Period( numericsimple );
	
variables:
	a1( 0 ),
	b1( 0 ),
	c1( 0 ),
	c2( 0 ),
	c3( 0 ),
	US( 0 );
	
a1 = ExpValue(-1.414*3.14159 / Period);
b1 = 2 * a1 * Cosine(1.414*180 / Period);
c2 = b1;
c3 = -a1 * a1;
c1 = (1 + c2 - c3) / 4;

if CurrentBar >= 4 then 
 US = (1 - c1)*Price + (2 * c1 - c2) * Price[1] 
 - (c1 + c3) * Price[2] + c2*US[1] + c3 * US[2];
 
if CurrentBar < 4 then 
	US = Price;

$UltimateSmoother = US;

Re: TASC magazine indicators

3
PMA: projected moving average

TradeStation: March 2025
In “Removing Moving Average Lag” in this issue, John Ehlers introduces a projected moving average (PMA) designed to remove the lag inherent in moving averages. He does this by adding the slope times half the length of the average to the average itself. A function labeled $PMA is provided for the calculations. A sample chart displaying the PMA, the PMA slope, and its prediction, as discussed in Ehlers’ article.

Code: Select all

Function: $PMA
{
	TASC MAR 2025
	Projected Moving Average ($PMA) Function
	(C) 2024 John F. Ehlers
}

inputs:
	Price( numericseries ),
	Length( numericsimple ),
	PMA( numericref ),
	Slope( numericref ),
	SMA( numericref );

variables:
	Count( 0 ),
	Sx( 0 ),
	Sy( 0 ),
	Sxx( 0 ),
	Syy( 0 ),
	Sxy( 0 );

Sx = 0;
Sy = 0;
Sxx = 0;
Syy = 0;
Sxy = 0;

for Count = 1 to Length
begin
	Sx = Sx + Count;
	Sy = Sy + Price[Count - 1];
	Sxx = Sxx + Count * Count;
	Syy = Syy + Price[Count - 1] * Price[Count - 1];
	Sxy = Sxy + count*Price[Count - 1];
end;

Slope = -(Length * Sxy - Sx * Sy) / (Length * Sxx - Sx * Sx);
SMA = Sy / Length;
PMA = SMA + Slope * Length / 2;

//Function Return Value
$PMA = 1;


Indicator: Projected Moving Average (PMA)
{
	TASC MAR 2025
	Projected Moving Average (PMA)
	(C) 2024 John F. Ehlers
}

inputs:
	Length( 20 );

variables:
	ReturnValue( 0 ),
	PMA( 0 ),
	Slope( 0 ),
	SMA( 0 ),
	Predict( 0 );
	
ReturnValue = $PMA(Close, Length, PMA, Slope, SMA);
Predict = PMA + .5 * (Slope - Slope[2])*Length;

Plot1( PMA, "PMA" );
Plot2( Predict, "Predict" );
//Plot3( SMA, "SMA" )


Indicator: PMA Slope and Prediction
{
	TASC MAR 2025
	PMA Slope and Its Prediction
	(C) 2024 John F. Ehlers
}

inputs:
	Length( 20 );

variables:
	ReturnValue( 0 ),
	PMA( 0 ),
	Slope( 0 ),
	SMA( 0 ),
	Predict( 0 );

ReturnValue = $PMA(Close, Length, PMA, Slope, SMA);
Predict = 1.5 * Slope - .5 * Slope[4];

Plot1( Slope, "Slope" );
Plot2( 0, "Zero Line" );
Plot3( Predict, "Predict" );
These users thanked the author Banzai for the post:
macd & rsi

Re: TASC magazine indicators

4
Banzai wrote: Fri Dec 05, 2025 6:54 pm Laguerre Filters

TradeStation: July 2025
In “Laguerre Filters” in this issue, John Ehlers presents a trend-trading technique using the Laguerre filter. Since Laguerre filters excel at smoothing long-wavelength components in a data set, this makes them particularly well-suited for identifying trading trends.

Code: Select all

Function: Laguerre Filter
{
	TASC JUL 2025
	Laguerre Filter
	(C) 2002-2025 John F. Ehlers
}

inputs:
	Gama( .8 ),
	Length( 40 );

variables:
	L0( 0 ),
	L1( 0 ),
	L2( 0 ),
	L3( 0 ),
	L4( 0 ),
	Laguerre( 0 );
	
L0 = $UltimateSmoother(Close, Length);
L1 = -Gama * L0[1] + L0[1] + Gama * L1[1];
L2 = -Gama * L1[1] + L1[1] + Gama * L2[1];
L3 = -Gama * L2[1] + L2[1] + Gama * L3[1];
L4 = -Gama * L3[1] + L3[1] + Gama * L4[1];

Laguerre = (L0 + 4*L1 + 6*L2 + 4*L3 + L4) / 16;


Plot1( Laguerre );
Plot2( L0 );


Indicator: Laguerre Oscillator
{
	TASC JUL 2025
	Laguerre Oscillator
	(C) 2002-2025 John F. Ehlers
}

inputs:
	Gama( .5 ),
	Length( 30 );

variables:
	L0( 0 ),
	L1( 0 ),
	RMS( 0 ),
	LaguerreOsc( 0 );

L0 = $UltimateSmoother(Close, Length);
L1 = -Gama * L0 + L0[1] + Gama * L1[1];
RMS = $RMS(L0 - L1, 100);

if RMS <> 0 then 
	LaguerreOsc = (L0 - L1) / RMS;
	
Plot1( LaguerreOsc, "Laguerre Osc" );
Plot2( 0, "Zero Line" );

Function: $RMS
{
	RMS Function
	(C) 2015-2025 John F. Ehlers
}

inputs:
	Price( numericseries ),
	Length( numericsimple );

variables:
	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);

Function: $SuperSmoother
{
	UltimateSmoother Function
	(C) 2004-2025 John F. Ehlers
}

inputs:
	Price( numericseries ),
	Period( numericsimple );
	
variables:
	a1( 0 ),
	b1( 0 ),
	c1( 0 ),
	c2( 0 ),
	c3( 0 ),
	US( 0 );
	
a1 = ExpValue(-1.414*3.14159 / Period);
b1 = 2 * a1 * Cosine(1.414*180 / Period);
c2 = b1;
c3 = -a1 * a1;
c1 = (1 + c2 - c3) / 4;

if CurrentBar >= 4 then 
 US = (1 - c1)*Price + (2 * c1 - c2) * Price[1] 
 - (c1 + c3) * Price[2] + c2*US[1] + c3 * US[2];
 
if CurrentBar < 4 then 
	US = Price;

$UltimateSmoother = US;
Posted a mt4 version here.
These users thanked the author mrtools for the post:
Banzai