Wealth-Lab Wiki

API ChartStyles Community Components Community Indicators IndexDefinitions Knowledge Base Misc Optimizers PosSizers Providers Standard Indicators TASC Traders Tips TASCIndicators Visualizers


Quick Search
Advanced Search »

TASC 2007-04 | Adjusted ROC (Luoma & Nikkinen)

Original text and WL4 code by Giorgio Beltrame
WL5 translation by Eugene.

Traders' Tip text

An exponential smoothing that adds information to an indicator, rather than just remove noise? Smoothing by adding? As strange as it may appear, it’s a simple yet effective idea. In order to compare this "adjusted ROC" against the standard Rate of Change indicator, we wrote a simple ChartScript that simulates “trading the spread” of two ROCs between a stock and a broad market index. (See code for actual rules.) The performance of the strategy improves markedly when just changing from the simple ROC implementation to the new adjusted version of Luoma and Nikkinen, without other modifications!

Figure 1. Results of a 10-years historical simulation using the original script (with UseAdjustedROC = false), trading all 30 stocks from the Dow Jones Industrial Average (Dow 30), allocating 10% of equity to each new position, starting with $100,000.

Figure 2. Results of a 10-years historical simulation after setting UseAdjustedROC to "true", settings as above.

Strategy Code

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

namespace WealthLab.Strategies { public class MyStrategy : WealthScript { protected override void Execute() { int Period = 40; bool UseAdjustedROC = true;

// get a broad market index (S&P500 is used here) and its ROC data DataSeries sIndex = GetExternalSymbol( "^GSPC", true ).Close; DataSeries sIndexROC = ROC.Series( sIndex, Period );

// get the ROC of selected stock DataSeries sROC = ROC.Series( Close, Period );

if( UseAdjustedROC ) { // change from standard ROCs to the "adjusted" version sROC = EMA.Series( ROC.Series( Close, 1 ), Period, EMACalculation.Modern ); sIndexROC = EMA.Series( ROC.Series( sIndex, 1), Period, EMACalculation.Modern ); }

// compute the spread between the two (adjusted) ROCs // that is, the difference: ROC(stock) - ROC(index) DataSeries sSpread = sROC - sIndexROC; sROC.Description = "sROC"; sIndexROC.Description = "sIndexROC"; sSpread.Description = "sSpread"; for(int bar = Period; bar < Bars.Count; bar++) { double R = sROC[bar]; if (IsLastPositionActive) { Position p = LastPosition; // exit all (long) positions when a profit target is reached, // or when the stock rises while the spread starts decreasing if( ( p.NetProfitAsOfBarPercent( bar ) > 4 ) || ( ( R > 0 ) & TurnDown( bar, sSpread ) ) ) SellAtMarket( bar + 1, Position.AllPositions ); }

// enter a new long position after the stock had a dip, // as soon as the spread shows an improvement if( ( R < 0 ) & TurnUp( bar, sSpread ) ) if( BuyAtMarket( bar + 1, (-R).ToString() ) != null ) // when trading multiple stocks, and not having enough cash to // enter all alerts, instruct WL’s $imulator to trade those with // the lowest (most negative) ROC value, hoping in a faster bounce LastPosition.Priority = - R;

} HideVolume(); ChartPane Pane = CreatePane( 50, false, true ); DrawHorzLine( Pane, 0, Color.Black, LineStyle.Solid, 2 ); PlotSeries( Pane, sROC, Color.Red, LineStyle.Solid, 1 ); PlotSeries( Pane, sIndexROC, Color.Blue, LineStyle.Dotted, 1 ); PlotSeries( Pane, sSpread, Color.Green, LineStyle.Solid, 2 ); } } }

Important Disclaimer: The information provided by Wealth-Lab is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.  The owner of Wealth-Lab.com assumes no liability resulting from the use of the material contained herein for investment purposes. By using this web site, you agree to the terms of this disclaimer and our Terms of Use.

ScrewTurn Wiki. Some of the icons created by FamFamFam.