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
TSM Moving Average
Image


In TASC magazine, January 2026, "Smoothing The Data", by Perry Kaufman

Of the various smoothing methods commonly available to traders and technical analysts,
which are best at finding the trend in price data?

Code: Select all

{ TSM Moving Average : Moving average system
 Copyright 2025 P J Kaufman. All rights reserved. }
{ strategy (1 - 10) as follows:
1. Moving average
2. Average-off
3. Weighted moving average
4. Triangular moving average
5. Pivot point moving average
6. Standard deviation moving average
7. Moving median
8. Geometric moving average
9. Exponential moving average
10. Linear regression
}
 input: strategy(1), period(20), SDvalue(0.05), 
usefutures(false), longonly(false);
 vars: signal(0), psignal(0), trend(0), size(1), ix(0), INT 
middle(0), 
 value(0), SD(0), SDpercent(0), prod(0), root(0), 
 smooth(0), newprice(0), sumofprices(0), sumofweights(0), 
 INT start(0), stockinvestment(10000), futuresinvestment(25000),
 ATRper(20), equity(0), adate(" "), totalPL(0), 
NAV(100), 
 returns(0), cumreturn(0), todayPL(0), totalLong(0), totalShort(0);
array: pricearray[150](0), sortprices[150](0), sortedarray[150](0);
 
if usefutures then
 size = futuresinvestment/(Avgtruerange(ATRper
)*bigpointvalue)
 else
 size = stockinvestment/close;
// 1. Moving Average
if strategy = 1 then begin
 trend = average(close,period);
 end;
// 2. Average off
if strategy = 2 then begin
 If Currentbar = 1 then
 trend = average(close,period)
 else
 trend = ((period - 1)*trend[1] + close)/period;
 end;
// 3. Weighted moving average
if strategy = 3 then begin
 sumofprices = 0;
 sumofweights = 0;
 for ix = 0 to period - 1 begin
 sumofweights = sumofweights + ix + 1;
 sumofprices = sumofprices + (ix+1)*close[ix];
 end;
 trend = sumofprices/sumofweights;
 end;
// 4. Triangulation
if strategy = 4 then begin
 middle = period/2;
// increase weights towards middle
 sumofprices = 0;
 sumofweights = 0;
// prices increase towards middle
 for ix = 0 to middle begin
 sumofweights = sumofweights + ix + 1;
 sumofprices = sumofprices + (ix+1)*close[ix];
 end;
 value = 0;
 for ix = period to middle - 1 begin
 value = value + 1;
 sumofweights = sumofweights + value;
 sumofprices = sumofprices + value*close[ix];
 end;
 trend = sumofprices/sumofweights;
 end;
// 5. Pivot-Point moving average
if strategy = 5 then begin
 start = period - period/3;
 sumofprices = 0;
 sumofweights = 0;
 value = start + 1;
 for ix = 0 to period - 1 begin
 value = value - 1;
 sumofweights = sumofweights + value;
 sumofprices = sumofprices + value*close[ix];
 end;
 trend = sumofprices/sumofweights;
 end;
// 6. Standard deviation moving average
if strategy = 6 then begin
 SD = stddev(close,period);
 SDpercent = (SD - SD[1])/SD;
 trend = average(close,period) + 
SDvalue*SDpercent;
 end;
// 7. Moving median
if strategy = 7 then begin
// move prices to array
 for ix = 0 to period - 1 begin
 pricearray[ix + 1] = close[ix];
 end;
 value1 = sortarray(pricearray,period,1);
 trend = pricearray[period/2];
 end;
 // 8. Geometric moving average
if strategy = 8 then begin
 prod = 1;
 for ix = 0 to period - 1 begin
 prod = prod*close[ix];
 end;
 root = 1/period;
 trend = power(prod,root);
 end;
// 9. Exponential smoothing
if strategy = 9 then begin
 smooth = 2/(period + 1);
 trend = trend[1] + smooth*(close - trend[1]);
 end;
// 10. Linear regression, slope increasing or decreasing
if strategy = 10 then begin
 trend = linearregslope(close,period);
 if trend > 0 then begin
 buy to cover all shares next bar on open;
 buy size share next bar on open;
 signal = 1;
 end
 else if trend < 0 then begin
 sell all shares next bar on open;
 if longonly = false then begin
 sell short size share next bar on open;
 end;
 signal = -1;
 end;
 end;
// common entry code
if strategy <> 10 then begin
 if trend > trend[1] then signal = 1
 else if trend < trend[1] then signal = -1;
// new long position
 if psignal <= 0 and signal > 0 then begin
 buy to cover all shares next bar on open;
 buy size shares next bar on open;
 end
 else if psignal > 0 and signal < 0 then begin
 sell all shares next bar on open;
 if longonly = false then begin
 sell short size shares next bar on 
open; 
 end;
 end;
 end;
psignal = signal;
 equity = netprofit + openpositionprofit;
todayPL = equity - equity[1];
if psignal > 0 then
 totalLong = totalLong + todayPL
 else if psignal < 0 then
 totalShort = totalShort + todayPL;
totalPL = totalPL + equity - equity[1];
returns = (equity - equity[1])/stockinvestment;
cumreturn = cumreturn + returns;
if usefutures = false then
 NAV = 100
 else
 NAV = NAV[1]*(1 + returns);
 
adate = ELdatetostring(date);
 If Currentbar = 1 then print(file("c:\TradeStation\
Smoothing.csv"), 
 "Date,Close,Signal,Size,TotalShort,TotalLong,To
talPL,Returns,CumReturn,NAV");
 print(file("c:\TradeStation\Smoothing.csv"),adate, ",", 
close:8:6, ",", 
 signal:5:0, ",", size:8:3, ",", totalShort:8:0, ",", totalLong:8:0, ",", 
 totalPL:8:0, ",", returns:6:4, ",", cumreturn:8:4, ",", 
NAV:9:4);

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