TASC 2018-10 | The Stiffness Indicator (Katsanos)

Modified on 2018/09/30 07:15 by Eugene — Categorized as: TASC Traders Tips

Traders' Tip text

The accompanying WealthScript C# code demonstrates how to implement a trading Strategy based on the rules by Mr. Katsanos. Here they are:

To change system’s behavior from “buy high” to “buy on pullback”, drag synonymous slider at the bottom of Wealth-Lab’s main workspace. In accordance with the article, entering when the short-term RSI turns up from a pullback in established trend is believed to be more efficient.


Figure 1 illustrates typical trades on a chart of GoodYear.

As the current abnormal bullish market has started 9 years ago, we weren’t convinced by author’s choice of 10 years of latest data. Our backtest with 5% equity per position on a sample of historic Dow 30 stocks as of 1/1/2000 spans the 10-year range up until 1/1/2010. In addition to a vibrant recovery, this includes two bear markets. The buy-on-pullback version finished with the net profit beating Buy&Hold’s (49% vs. ~17%, after commissions). More so, with significantly lower risk (maximum drawdown -13% vs. -59.3%) and market exposure (39.2% vs. 100%).


Figure 2 highlights system’s weakness: it can lose to Buy&Hold in strong bull markets.

On a closing note, make sure to load enough historical data to run this backtest. Indicators like EMA (used as the broad market direction condition) require a fair amount of seed data (here: three times the 100-bar EMA period) to stabilize their calculation before they can be used reliably in a trading system.


using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using TASCIndicators;

namespace WealthLab.Strategies { // Dow 30 Y2K stocks included AA AXP BA C CAT CVX DIS GE GM GT HD HWP IBM INTC IP JNJ JPM KO KODK MCD MRK MSFT PG PM SHLD T UTX WMT XOM public class TASCNov2018 : WealthScript { private StrategyParameter slider1; private StrategyParameter slider2; private StrategyParameter slider3; private StrategyParameter slider4; private StrategyParameter slider5; private StrategyParameter slider6;

public TASCNov2018() { slider6 = CreateParameter("Pullback?",1,0,1,1); slider1 = CreateParameter("Stiffness MA",100,2,100,10); slider2 = CreateParameter("Stiffness Period",60,2,100,10); slider3 = CreateParameter("Stiffness Devs",0.2,0.1,3,0.2); slider4 = CreateParameter("Bars since",84,10,200,2); slider5 = CreateParameter("RSI Period",3,3,6,1); } protected override void Execute() { int maPeriod = slider1.ValueInt, stiffPeriod = slider2.ValueInt, exitAfter = slider4.ValueInt, rsiPeriod = slider5.ValueInt; var devs = slider3.Value; var stiffness = Stiffness.Series(Close,maPeriod,stiffPeriod,devs); var rsi = RSI.Series(Close, rsiPeriod); bool useRsiTurnup = slider6.ValueInt == 1 ? true : false;

var spy = GetExternalSeries("SPY", Close); var spyEma = EMAModern.Series(spy, maPeriod);

for(int bar = GetTradingLoopStartBar( 100 ); bar < Bars.Count; bar++) { if (IsLastPositionActive) { Position p = LastPosition;

if ( bar+1 - p.EntryBar >= exitAfter ) //Bars since entry ? 84 (four months) SellAtMarket( bar+1, p, "Timed" ); if( CrossUnder( bar, stiffness, 50) ) //Stiffness(100,60) crosses under 50 SellAtMarket( bar+1, p, "Stiffness < 50" ); } else { if( !useRsiTurnup ) { if( CrossOver(bar, stiffness, 90) ) //Stiffness crosses over 90 if( spyEma[bar] > spyEma[bar - 1] ) //EMA (SPY,100) > EMA (SPY,100) BuyAtMarket( bar+1); } else { if( Close[bar] > SMA.Series(Close, maPeriod)[bar] ) if( stiffness[bar] >= 90 ) //Stiffness is bullish if( spyEma[bar] > spyEma[bar - 1] ) //EMA (SPY,100) > EMA (SPY,100) if( rsi[bar - 1] < 40 && TurnUp( bar, rsi) ) //RSI is oversold and turns up BuyAtMarket( bar+1, "RSI TurnUp"); } } }

ChartPane paneSpy = CreatePane(30,true,true); PlotSeries( paneSpy,spy,Color.Black,LineStyle.Solid,2); PlotSeries( paneSpy,spyEma,Color.Blue,LineStyle.Solid,1); ChartPane paneStiffness = CreatePane(30,false,true); PlotSeries( paneStiffness,stiffness,Color.Orange,LineStyle.Histogram,2); PlotSeries( PricePane, SMA.Series(Close, maPeriod),Color.Blue,LineStyle.Solid,1); PlotSeries( PricePane, SMA.Series(Close, maPeriod) - (devs * StdDev.Series(Close, maPeriod, StdDevCalculation.Sample)), Color.Red,LineStyle.Solid,1); ChartPane paneRsi = CreatePane(30,false,true); HideVolume(); PlotSeries( paneRsi,rsi,Color.Violet,LineStyle.Solid,2); } } }

Eugene (Gene Geren)
Wealth-Lab team