TRADERS’ TIPS

October 2014

Tips Article Thumbnail

For this month’s Traders’ Tips, the focus is mainly Sylvain Vervoort’s article from the September 2014 issue, “Exploring Charting Techniques: Creating A Trading Strategy, Part 3.” Here we present the October 2014 Traders’ Tips code with possible implementations in various software.

Code for NinjaTrader was already provided with Vervoort’s article by the author. S&C subscribers will find that code at the Subscriber Area of our website here. (Click on “S&C Article Code” from the homepage.) Presented here is an overview of some possible implementations for other software as well.

Traders’ Tips code is provided to help the reader implement a selected technique from an article in this issue or another recent issue. The entries here are contributed by various software developers or programmers for software that is capable of customization.


logo

TRADESTATION: OCTOBER 2014

In “Exploring Charting Techniques: Creating A Trading Strategy, Part 3,” which appeared last month in the September 2014 issue of STOCKS & COMMODITIES, author Sylvain Vervoort describes a process for creating indicators and strategies. Through his article series, the author takes us step by step, building up his trading idea with additional criteria along the way.

We are providing EasyLanguage code for both upper (moving averages) and lower (trading signal) indicators, as well as a strategy based on the author’s ideas (see Figure 1). As Vervoort points out, advanced chart types can be automated only when the limitations are fully understood.

Sample Chart

FIGURE 1: TRADESTATION. Here is an example implementation of the strategy and indicators based on author Sylvain Vervoort’s ideas applied to a chart of the S&P 500 index using a one-point renko bar.

More on strategy backtesting and automation of TradeStation’s range, renko, and other advanced chart types can be found in the advance chart type entry within platform help (from the TradeStation platform help menu, select platform help).

To download the EasyLanguage code for TradeStation, please visit our TradeStation and EasyLanguage support forum. The code from this article can be found here: https://www.tradestation.com/TASC-2014. The ELD filename is “_TASC_OCT2014_CREATINGSTRATEGY.ELD.”

TASC_Oct2014 (Strategy)

inputs:
TypicalPriceAvgLength( 8 ),
HeikinAshiAvgLength( 8 ),
TrendAvgLength( 21 ) ;

variables:
	haClose( 0 ),
	haOpen( 0 ),
	haHigh( 0 ),
	haLow( 0 ),
	HAAverage( 0 ),
	TPAverage( 0 ),
	TrendAverage( 0 ),
	TrendValue( 0 ),
	SignalCondition( false ),
	BarCondition( false ),
	TrendCondition( false ) ;

haClose = ( Open + High + Low + Close ) / 4 ;
haOpen = ( haOpen[1] + haClose[1] ) / 2 ;
haHigh = MaxList( High, haOpen, haClose ) ;
haLow = MinList( Low, haOpen, haClose ) ;

HAAverage = Average( ( haClose + haOpen + haHigh + haLow ) 
	/ 4, HeikinAshiAvgLength ) ;
TPAverage = Average( TypicalPrice, 
	TypicalPriceAvgLength ) ;
TrendAverage = Average( Close, TrendAvgLength ) ;

SignalCondition = TPAverage > HAAverage ;
BarCondition = Close > Open ;
TrendCondition = Close > TrendAverage ;

if SignalCondition and BarCondition 
	and TrendCondition then
	TrendValue = 1
else if not SignalCondition and 
	not BarCondition and not TrendCondition then
	TrendValue = -1
else 
	TrendValue = TrendValue[1] ;

if TrendValue = 1 then
	Buy ("LE") this bar on Close
else if TrendValue = -1 then
	SellShort ("SE") this bar on Close ;	
	
if TPAverage crosses under HAAverage then
	Sell ("LX")this bar on Close 
else if TPAverage crosses over HAAverage then
	BuyToCover ("SX") this bar on Close ;	
	
	

TASC_Oct2014 (Indicator)

inputs:
TypicalPriceAvgLength( 8 ),
HeikinAshiAvgLength( 8 ),
TrendAvgLength( 21 ) ;

variables:
	haClose( 0 ),
	haOpen( 0 ),
	haHigh( 0 ),
	haLow( 0 ),
	HAAverage( 0 ),
	TPAverage( 0 ),
	TrendAverage( 0 ),
	TrendValue( 0 ),
	PlotColor( 0 ) ;

haClose = ( Open + High + Low + Close ) / 4 ;
haOpen = ( haOpen[1] + haClose[1] ) / 2 ;
haHigh = MaxList( High, haOpen, haClose ) ;
haLow = MinList( Low, haOpen, haClose ) ;

HAAverage = Average( ( haClose + haOpen + haHigh + haLow ) 
	/ 4, HeikinAshiAvgLength ) ;
TPAverage = Average( TypicalPrice, 
	TypicalPriceAvgLength ) ;
TrendAverage = Average( Close, TrendAvgLength ) ;

Plot1( TPAverage, "TP Avg" ) ;
Plot2( HAAverage, "HA Avg" ) ;
Plot3( TrendAverage, "TrendAverage" ) ;


TASC_Oct2014_2 (Indicator)

inputs:
TypicalPriceAvgLength( 8 ),
HeikinAshiAvgLength( 8 ),
TrendAvgLength( 21 ) ;

variables:
	haClose( 0 ),
	haOpen( 0 ),
	haHigh( 0 ),
	haLow( 0 ),
	HAAverage( 0 ),
	TPAverage( 0 ),
	TrendAverage( 0 ),
	TrendValue( 0 ),
	PlotColor( 0 ),
	SignalCondition( false ),
	BarCondition( false ),
	TrendCondition( false ) ;
	
haClose = ( Open + High + Low + Close ) / 4 ;
haOpen = ( haOpen[1] + haClose[1] ) / 2 ;
haHigh = MaxList( High, haOpen, haClose ) ;
haLow = MinList( Low, haOpen, haClose ) ;

HAAverage = Average( ( haClose + haOpen + haHigh + haLow ) 
	/ 4, HeikinAshiAvgLength ) ;
TPAverage = Average( TypicalPrice, 
	TypicalPriceAvgLength ) ;
TrendAverage = Average( Close, TrendAvgLength ) ;

SignalCondition = TPAverage > HAAverage ;
BarCondition = Close > Open ;
TrendCondition = Close > TrendAverage ;

if SignalCondition and BarCondition 
	and TrendCondition then
	TrendValue = 1
else if not SignalCondition and 
	not BarCondition and not TrendCondition then
	TrendValue = -1
else 
	TrendValue = TrendValue[1] ;	

if TrendValue = 1 then
	PlotColor = Green
else if TrendValue = -1 then
	PlotColor = Red
else
	PlotColor = Transparent ;		

Plot1( TrendValue, "TrendValue", PlotColor ) ;

For more information about EasyLanguage in general, please see https://www.tradestation.com/EL-FAQ.

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.

—Doug McCrary
TradeStation Securities, Inc.
www.TradeStation.com

BACK TO LIST

logo

eSIGNAL: OCTOBER 2014

For this month’s Traders’ Tip, we’ve provided the formula SVEHaTypeCrossStrategy.efs based on the formula described in Sylvain Vervoort’s article in the September 2014 issue of STOCKS & COMMODITIES, “Exploring Charting Techniques: Creating a Trading Strategy, Part 3.”

The study contains formula parameters that may be configured through the edit chart window (right-click on the chart and select “edit chart”). A sample chart is shown in Figure 2.

Sample Chart

FIGURE 2: eSIGNAL. Here is an example of the SVEHaTypeCrossStrategy.efs shown on a chart of S&P 500 emini futures (ES).

To discuss this study or download a complete copy of the formula code, please visit the EFS Library Discussion Board forum under the forums link from the support menu at www.esignal.com or visit our EFS KnowledgeBase at https://www.esignal.com/support/kb/efs/. The eSignal formula script (EFS) is also available below for copying & pasting or for downloading here.

/*********************************
Provided By:  
    Interactive Data Corporation (Copyright © 2014) 
    All rights reserved. This sample eSignal Formula Script (EFS)
    is for educational purposes only. Interactive Data Corporation
    reserves the right to modify and overwrite this EFS file with 
    each new release. 

Description:        
    The Crossing Of Two Specific Moving Averages by Sylvain Vervoort

Formula Parameters:                     Default:
Typical Price Average                   8
Heikin-Ashi average                     8
Long Position Color                     lime
Short Position Color                    red

Version:            1.00  08/06/2014

Notes:
    The related article is copyrighted material. If you are not a subscriber
    of Stocks & Commodities, please visit www.traders.com.

**********************************/

var fpArray = new Array(); 

function preMain(){

    setStudyTitle("SVEHaTypeCrossStrategy");
    setPriceStudy(true);
      
    setCursorLabelName("Typical Price Average", 0);
    setCursorLabelName("Heikin-Ashi Average", 1);
    
    setDefaultBarFgColor(Color.RGB(0x00,0x94,0xFF), 0);
    setDefaultBarFgColor(Color.RGB(0xFF,0x9B,0x00), 1);

    var x = 0;

    fpArray[x] = new FunctionParameter("fpTypicalAverage", FunctionParameter.NUMBER);
    with(fpArray[x++]){

        setName("Typical Price Average");
        setLowerLimit(1); 
        setDefault(8);
    };

    fpArray[x] = new FunctionParameter("fpHaCAverage", FunctionParameter.NUMBER);
    with(fpArray[x++]){

        setName("Heikin-Ashi Average");
        setLowerLimit(1);
        setDefault(8);
    };

    fpArray[x] = new FunctionParameter("fpLongColor", FunctionParameter.COLOR);
    with(fpArray[x++]){

        setName("Long Position Color");    
        setDefault(Color.lime);
    };
    
    fpArray[x] = new FunctionParameter("fpShortColor", FunctionParameter.COLOR);
    with(fpArray[x++]){

        setName("Short Position Color");    
        setDefault(Color.red);
    };
}

var bInit = false;
var bVersion = null;

var xClose = null;
var xOpen = null;
var xOHLC4 = null;
var xHLC3 = null;
var xHaOpen = null;
var xHaC = null;
var xAVGTyp = null;
var xAVGHaC = null;
var xCross = null;

function main(fpHaCAverage, fpTypicalAverage, fpLongColor, fpShortColor){

    if (bVersion == null) bVersion = verify();
    if (bVersion == false) return;

    if (!bInit){

    	xClose = close();
    	xOpen = open();
    	xOHLC4 = ohlc4();
        xHLC3 = hlc3();
             
        xHaOpen = efsInternal("Calc_HaOpen", xOHLC4);
        xHaC = efsInternal("Calc_HaC", xOHLC4, xHaOpen);

        xAVGTyp = getSeries(sma(fpTypicalAverage, xHLC3));
        xAVGHaC = getSeries(sma(fpHaCAverage, xHaC));
        xCross = efsInternal("Calc_Cross", xAVGTyp, xAVGHaC, xClose, xOpen)
       
        bInit = true; 
    }; 

    var nCross_Last = xCross.getValue(-1);
    var nCross_Current = xCross.getValue(0);

    if (nCross_Last == null || nCross_Current == null)
        return;
    
    var bLong = false;
    var bShort = false;
    
    if (nCross_Current > 0 && nCross_Last < 1)
        bLong = true;
    if (nCross_Current < 1 && nCross_Last > 0)
        bShort = true;
    
    var nFillPrice = xClose.getValue(0);
       
    if (getCurrentBarIndex() != 0){       

        if (bLong){

            Strategy.doLong("Enter Long", Strategy.CLOSE, Strategy.THISBAR, Strategy.DEFAULT);
            drawShapeRelative(0, BelowBar1, Shape.UPTRIANGLE, null, fpLongColor, Text.PRESET, getCurrentBarIndex() + "Entry");
            drawTextRelative(0, BelowBar2, "Long", fpLongColor, null, Text.PRESET|Text.CENTER|Text.BOLD, null, null, getCurrentBarIndex() + "Entry");
            drawTextRelative(0, BelowBar3, Strategy.getDefaultLotSize() + " @ " + formatPriceNumber(nFillPrice), fpLongColor, null, Text.PRESET|Text.CENTER|Text.BOLD, null, null, getCurrentBarIndex() + "EntrySettings");
        };

        if (bShort){

            Strategy.doShort("Enter Short", Strategy.CLOSE, Strategy.THISBAR, Strategy.DEFAULT);
            drawShapeRelative(0, AboveBar1, Shape.DOWNTRIANGLE, null, fpShortColor, Text.PRESET, getCurrentBarIndex() + "Exit");
            drawTextRelative(0, AboveBar2, "Short", fpShortColor, null, Text.PRESET|Text.CENTER|Text.BOLD, null, null, getCurrentBarIndex() + "Exit");
            drawTextRelative(0, AboveBar3, Strategy.getDefaultLotSize() + " @ " + formatPriceNumber(nFillPrice), fpShortColor, null, Text.PRESET|Text.CENTER|Text.BOLD, null, null, getCurrentBarIndex() + "ExitSettings"); 
        };

    };

    return [xAVGTyp, xAVGHaC];
}

function Calc_HaOpen(xOHLC4){

    var nOHLC4 = xOHLC4.getValue(-1);
             
    if (nOHLC4 == null) 
        return null;
    
    var nHaOpen_Last = ref(-1);
    
    var nReturnValue = (nOHLC4 + nHaOpen_Last) / 2;

    return nReturnValue;
}

var xHigh = null;
var xLow = null;

function Calc_HaC(xOHLC4, xHaOpen){

    if (getBarState() == BARSTATE_ALLBARS)
    {
        xHigh = high();
        xLow = low();
    }

    var nOHLC4 = xOHLC4.getValue(0);
    var nHaOpen = xHaOpen.getValue(0);
    var nHigh = xHigh.getValue(0);
    var nLow = xLow.getValue(0);

    if (nOHLC4 == null || nHaOpen == null)
        return;

    var nReturnValue = (nOHLC4 + nHaOpen + Math.max(nHigh, nHaOpen) + Math.min(nLow, nHaOpen)) / 4;   
    
    return nReturnValue;
}

function Calc_Cross(xAVGTyp, xAVGHaC, xClose, xOpen){
  
    var nClose = xClose.getValue(0);
    var nOpen = xOpen.getValue(0);
    var nAVGTyp = xAVGTyp.getValue(0);
    var nAVGHaC = xAVGHaC.getValue(0);

    var nCross = null;
    var nCross_Last = ref(-1);
   
    if (nAVGTyp == null || nAVGHaC == null)
        return;
   
    if (nAVGTyp > nAVGHaC && nClose > nOpen)    
        nCross = 1
    else if (nAVGTyp < nAVGHaC && nClose < nOpen)
        nCross = 0;
    else 
        nCross = nCross_Last; 
        
    return nCross;
}

function verify(){
    
    var b = false;
    if (getBuildNumber() < 779){
        
        drawTextAbsolute(5, 35, "This study requires version 8.0 or later.", 
            Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
            null, 13, "error");
        drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=https://www.esignal.com/download/default.asp", 
            Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
            null, 13, "upgrade");
        return b;
    } 
    else
        b = true;
    
    return b;
}

—Eric Lippert
eSignal, an Interactive Data company
800 779-6555, www.eSignal.com

BACK TO LIST

logo

THINKORSWIM: OCTOBER 2014

In part 3 of his series on exploring charting techniques, which appeared in the September 2014 issue of STOCKS & COMMODITIES (“Creating A Trading Strategy”), author Sylvain Vervoort takes an in-depth look at defining, testing, and using a trading strategy. At thinkorswim, we have used our proprietary scripting language thinkScript to build a strategy for detecting trends using this method.

We have made the loading process extremely easy: Simply click on the link https://tos.mx/Hp8IeR and choose Backtest in thinkorswim, then choose to rename your study to “SyVerPart3.” You can adjust the parameters of these within the edit studies window to fine-tune your variables. In the article, Vervoort bases his strategy on a renko chart type. In thinkorswim charts, renko bars can be found under Style → Range for aggregation type. Then you can adjust the range type to “renko” under the style menu as well. A sample chart is shown in Figure 3.

Sample Chart

FIGURE 3: THINKORSWIM. Here’s an example of the SyVerPart3 study on the SPX.

For a detailed description of the strategy itself, see Vervoort’s article in the September 2014 issue of S&C. Happy swimming!

—thinkorswim, A division of TD Ameritrade, Inc.
www.thinkorswim.com

BACK TO LIST

logo

WEALTH-LAB: OCTOBER 2014

At first, it may seem that the idea presented in “Exploring Charting Techniques: Creating A Trading Strategy, Part 3” by Sylvain Vervoort, which appeared last month in the September 2014 issue of S&C, is trivial. After all, what don’t we know about the many variations of a moving average crossover? However, in his article, Vervoort takes the technique a step further, applying moving average crossovers on his modified renko chart with the added twist of heikin-ashi. The premise is to reduce the noise of a typical fixed-time-related chart and to produce fewer losing trades.

First, we’ll build two moving averages: The fast is the simple moving average (SMA) of the renko-based typical price, and the slow is an SMA of heikin-ashi (HA) recalculated prices. For simplicity of our example strategy, we take a standard renko chart and use daily prices. Despite using the same period, the HA-based average always lags due to added smoothing. The rules of the strategy are:

  1. When the eight-period “fast” average crosses above the “slower” counterpart of the same period, a long position is established.
  2. When the eight-period “fast” average crosses below the “slower” average of the same period, the long position is closed.

In Figure 4, the green and red renko bricks are superimposed on the open/high/low/close (OHLC) chart.

Sample Chart

FIGURE 4: WEALTH-LAB. This sample Wealth-Lab 6 chart illustrates application of the system’s rules on a daily chart of AXP (American Express).

To execute the trading system we’re providing, Wealth-Lab users can copy & paste the strategy’s C# code, or simply let Wealth-Lab do the job: in the open strategy dialog, simply click download to get the strategy code.

C# Strategy code:

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

namespace WealthLab.Strategies
{
	public class VervoortOct2014 : WealthScript
	{
		StrategyParameter paramRPU;
		StrategyParameter paramPeriod;
		
		public VervoortOct2014()
		{
			paramRPU = CreateParameter("Renko Units", 1, 1, 10, 1);
			paramPeriod = CreateParameter("MA Period", 8, 2, 20, 1);
		}
		
		protected override void Execute()
		{
			double rpu = paramRPU.Value;
			int period = paramPeriod.ValueInt;
			TRenko renko = new TRenko(Bars, rpu);
			DataSeries dsOpen = new DataSeries(Bars,"R-Open"), dsHigh = new DataSeries(Bars,"R-High"),
				dsLow = new DataSeries(Bars,"R-Low"), dsClose = new DataSeries(Bars,"R-Close");
			DataSeries haOpen = new DataSeries(Bars,"HA-Open"), haHigh = new DataSeries(Bars,"HA-High"),
				haLow = new DataSeries(Bars,"HA-Low"), haClose = new DataSeries(Bars,"HA-Close");
			
			for(int bar = 1; bar < Bars.Count; bar++)
			{
				Renko rko = renko.Columns[bar];
				
				// Create Renko-based OHLC and Heikin Ashi for averaging
				if( rko.Col > -1 )
				{
					if( rko.Col > renko.Columns[bar-1].Col )
					{
						Renko prev = renko.Columns[bar-1];

						double open = rko.DirectionUp ? rko.Low : rko.High;
						double close = !rko.DirectionUp ? rko.Low : rko.High;
						double high = rko.High;
						double low = rko.Low;
						
						double prevOpen = prev.DirectionUp ? prev.Low : prev.High;
						double prevClose = !prev.DirectionUp ? prev.Low : prev.High;
						double prevHigh = prev.High;
						double prevLow = prev.Low;
						
						double _haClose = (open + high + low + close) / 4;
						double _haOpen = (prevOpen + prevClose) / 2;
						double _haHigh = Math.Max( Math.Max(high, open), close );
						double _haLow = Math.Min( Math.Min(low, open), close );
						
						dsOpen[bar] = open;
						dsHigh[bar] = high;
						dsLow[bar] = low;
						dsClose[bar] = close;
						
						haOpen[bar] = _haOpen;
						haHigh[bar] = _haHigh;
						haLow[bar] = _haLow;
						haClose[bar] = _haClose;
					}
					else
					{
						dsOpen[bar] = dsOpen[bar-1];
						dsHigh[bar] = dsHigh[bar-1];
						dsLow[bar] = dsLow[bar-1];
						dsClose[bar] = dsClose[bar-1];
						
						haOpen[bar] = haOpen[bar-1];
						haHigh[bar] = haHigh[bar-1];
						haLow[bar] = haLow[bar-1];
						haClose[bar] = haClose[bar-1];
					}
				}				
			}
			
			//The first and faster average is the SMA of the typical price (HLC/3)
			//The second average is a SMA of heikin ashi re-calculated prices or haOpen + haHigh + haLow + haClose divided by four

			DataSeries maTypical = (SMA.Series( dsHigh, period ) + SMA.Series( dsLow, period ) + SMA.Series( dsClose, period )) / 3;
			DataSeries maHeikin = (SMA.Series( haOpen, period ) + SMA.Series( haHigh, period ) + SMA.Series( haLow, period ) + SMA.Series( haClose, period )) / 4;

			maTypical.Description = "SMA of Renko-based typical price";
			maHeikin.Description = "SMA of Renko-based Heikin Ashi";
			
			PlotSeries( PricePane, maTypical, Color.Blue, LineStyle.Solid, 1 );
			PlotSeries( PricePane, maHeikin, Color.Red, LineStyle.Solid, 1 );

			
			for(int bar = 1; bar < Bars.Count; bar++)
			{				
				// Detect crossover/crossunder and store state in a variable
				bool maXo = CrossOver(bar, maTypical, maHeikin);
				bool maXu = CrossUnder(bar, maTypical, maHeikin);
					
				Position p = LastPosition;				
				if ( IsLastPositionActive )
				{
					if ( maXu )
						SellAtMarket( bar + 1, p );
				}
				else
				{
					 if ( maXo )
						BuyAtMarket( bar + 1 );
				}

			}
		
		}
	}
}

—Eugene, Wealth-Lab team
MS123, LLC
www.wealth-lab.com

BACK TO LIST

logo

AMIBROKER: OCTOBER 2014

In “Exploring Charting Techniques: Creating A Trading Strategy, Part 3,” which appeared in the September 2014 issue of STOCKS & COMMODITIES, author Sylvain Vervoort continued his article series presenting a trading system based on modified renko charts and moving averages.

We are providing a ready-to-use formula for AmiBroker. It is based on the formula that Vervoort presented in his September 2014 article with the addition of trading rules, a colorized background, and moving averages for display in AmiBroker (see Figure 5).

Sample Chart

FIGURE 5: AMIBROKER. This modified renko chart of the S&P 500 index displays moving average crossovers and sample trading system entry/exit points.

// Modified Renko Chart with custom date axis 
// and high/low winks 
// Loosely based on Renko chart formula by G. Kavanagh 
// from AmiBroker on-line formula library (id=521) 
// Modifications & fixes TJ 2014 

function FillRun( dir, num, changedir ) 
{ 
       global i, j, modified, dt, RKC, RKO, RKD, RKH, RKL; 

       for ( x = 1; x <= num AND j < BarCount - 1; x++ ) 
       { 
           j++; 

           extra = ( changedir AND x == 1 ) * dir; 

           RKC[ j ] = RKC[ j - 1 ] + dir + extra; 
           RKO[ j ] = RKC[ j - 1 ] + IIf( modified, 0, extra ); 
           RKD[ j ] = dt[ i ]; 
           RKH[ j ] = High[ i - 1 ]; 
           RKL[ j ] = Low[ i - 1 ]; 
       } 
} 

SetBarsRequired( sbrAll, sbrAll ); 
Brick = Param( "Brick Size", 0.001, 0.0001, 1.00, 0.001 ); 
reverse = 2; 
intra = ParamToggle( "Intraday", "No|Yes", 0 ); 
modified = ParamToggle( "Modified", "No|Yes", 0 ); 

// Convert the closing price to rising and falling rounded bricks 
CF = ceil( C / Brick ); 
CR = floor( C / Brick ); 

// initialize first element 
j = 0; 
RKC[j] = CF[0]; 
RKO[j] = CF[0] + 1; 
RKD = 0; 
RKH = 0; 
RKL = 0; 
dt = IIf( intra, floor( TimeNum() / 100 ), DateNum() ); 

dir = -1; // 1 is up, -1 is down 

// Loop to produce the Renko values in number of bricks 

for ( i = 1; i < BarCount - 1; i++ ) 
{ 
   if ( j >= BarCount ) 
       break; // no more room -> finish 

   if ( CF[i] <= RKC[j] - 1 AND dir < 0 ) // Continue down 
   { 
       num = RKC[j] - CF[i]; 

       FillRun( dir, num, False ); 
   } 
   else 
   if ( CR[i] >= RKC[j] + Reverse AND dir < 0 ) // Change down to up 
   { 
       num = CR[i] - RKC[j]; 
       dir = 1; 

       FillRun( dir, num, True ); 
   } 
   else 
   if ( CR[i] >= RKC[j] + 1 AND dir > 0 ) // Continue Up 
   { 
       num = CR[i] - RKC[j]; 
       FillRun( dir, num, False ); 
   } 
   else 
   if ( CF[i] <= RKC[j] - Reverse AND dir > 0 ) // Change up to down 
   { 
       num = RKC[j] - CF[i]; 
       dir = -1; 

       FillRun( dir, num, True ); 
   } 
} 

// move the chart to right end of chart space, ie last brick on last bar position 
delta =  BarCount - 1 - j; 

RKC = Ref( RKC, -delta ); 
RKO = Ref( RKO, -delta ); 
RKD = Ref( RKD, -delta ); 
RKH = Ref( RKH, -delta ); 
RKL = Ref( RKL, -delta ); 

C = RKC * Brick; 
O = RKO * Brick; 
H = IIf( modified, RKH, Max( C, O ) ); 
L = IIf( modified, RKL, Min( C, O ) ); 

Plot( C, "", IIf( C > O, colorGreen, colorRed ), styleCandle ); 

m1 = MA( (C+H+L)/3, 8 ); 
m2 = MA( C, 8 ); 

Plot( m1, "SMA Typ", colorBlue ); 
Plot( m2, "SMA Renko", colorOrange ); 

Cover = Cross( m2, m1 ); 
Sell = Cross( m1, m2 ); 

Short = Sell AND C < O; 
Buy = Cover AND C > O; 

PlotShapes( shapeUpArrow * Buy, colorGreen, 0, m1); 
PlotShapes( shapeDownArrow * Sell, colorRed, 0, m1 );   
PlotShapes( shapeHollowUpArrow * Cover, colorGreen, 0, m1, -25); 
PlotShapes( shapeHollowDownArrow * Short, colorRed, 0, m1, -25 );   

color = IIf( Flip( Buy, Sell ), ColorRGB( 220, 255, 220 ), 
         IIf( Flip( Short, Cover ), ColorRGB( 255, 220, 220 ), colorWhite ) ); 
             
Plot( 1, "", color, styleArea | styleOwnScale, 0, 1, 0, -1 ); 

xnum = floor( RKD / 1000 ); 
XChange = IIf( xnum != Ref( xnum, -1 ), 1, Null ); 

Plot( XChange, "", colorGrey50, styleHistogram | styleOwnScale, 0, 1 ); 

// Draw renko-date axis 
MonthNames = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"; 
fvb = FirstVisibleValue( BarIndex() ); 
lvb = LastVisibleValue( BarIndex() ); 

for ( i = fvb; i < lvb; i++ ) 
{ 
 if ( XChange[ i ] ) 
 { 
   if ( intra ) 
      datetext = StrFormat( "%02gh", floor ( RKD[ i ] / 100 ) ); 
   else 
   if ( ( xnum[ i ] % 100 ) == 1 ) 
      datetext = StrFormat( "%04.0f", 1900 + ( xnum[ i ] / 100 ) ); 
   else 
      datetext = StrExtract( MonthNames, ( xnum[ i ] % 100 ) - 1 ); 

   PlotText( datetext  , i, LowestVisibleValue( Low ), colorGrey50, colorWhite, -20 ); 
 } 
} 

Title = Name() + StrFormat( " - 20%06.0f", RKD % 1000000 ) + " - Renko Chart : Last Value = " + RKC * Brick + " H: " + RKH + " L: " + RKL + ", Brick Size = " + Brick; 

GraphXSpace = 5;

—Tomasz Janeczko, AmiBroker.com
www.amibroker.com

BACK TO LIST

logo

NEUROSHELL TRADER: OCTOBER 2014

We have recreated the renko bar trading system described by Sylvain Vervoort in his September 2014 article “Exploring Charting Techniques: Creating A Trading Strategy, Part 3,” using NeuroShell Trader’s point-and-click indicator wizard without the need for programming.

We used the InterChart Tools Renko add-in to NeuroShell and the heikin-ashi close indicator from a previous Traders’ Tip to quickly set up the eight-period simple moving averages of the typical price and the heikin-ashi average closing price (see Vervoort’s article in the September 2014 issue for more details of his technique).

To produce a chart similar to the one we show in Figure 6 of the S&P 500 index, you can insert the indicators as follows:

  1. Select “New indicator” from the Insert menu
  2. Choose the averages category and select simple moving average, 8 periods
  3. Substitute the Ict Renko HLC3 (0.10, 1, 1, 10, High, Low, Volume) for the default value to recreate the typical price indicator described in Vervoort’s article
  4. Create another average indicator, and this time, substitute the HeikinAshiClose of the corresponding Ict Renko Bars to generate the heikin-ashi average closing price indicator.
Sample Chart

FIGURE 6: NEUROSHELL TRADER. This NeuroShell Trader chart displays the crossover of the eight-period SMA of the typical price and heikin-ashi average closing price. This strategy was created using the indicator wizard in NeuroShell Trader, so no programming is needed by the user.

The InterChart Tools Renko bars are virtual bars and perform their calculations using the same methods as traditional renko bars, but once a trading signal is generated by the renko bar, both the trade and fill are correctly displayed on the open of the next bar of the base chart.

The base chart is a 0.10 range bar of the S&P 500 index. The value of 0.10 virtual tick size in the Ict Renko Bars corresponds to the size of the base chart’s range bar. The next two parameters represent the number of ticks used to calculate the up part of the renko bar, followed by the number of ticks used to compute the down part. The “10” represents a multiplier that is applied to the described renko bar’s up/down ratio to realize its final size. This enables the indicators to use a different number of ticks for the up and down side of the renko bars. Since any bar’s function is to absorb noise, and rising price jitter is often different from falling price jitter, our renko bars permit an asymmetrical definition to accommodate this.

In the trading system described by Vervoort in his article, the trading signals occur when the average of the typical price crosses above or below the average of the heikin-ashi close of the renko bars. Rather than using a visual system, you could use NeuroShell Trader’s point-and-click wizard to build the crossover trading rules and allow NeuroShell Trader’s optimizer to identify the optimal bar size and noise absorption for a given algorithm or equity.

Users of NeuroShell Trader can go to the STOCKS & COMMODITIES section of the NeuroShell Trader free technical support website to download a copy of this or any previous Traders’ Tips.

—Marge Sherald, Ward Systems Group, Inc.
301 662-7950, sales@wardsystems.com
www.neuroshell.com

BACK TO LIST

logo

AIQ: OCTOBER 2014

The AIQ code for this month is based on Sylvain Vervoort’s article in the September 2014 issue of STOCKS & COMMODITIES, “Exploring Charting Techniques: Creating A Trading Strategy, Part 3.”

The code and EDS file can be downloaded from www.TradersEdgeSystems.com/traderstips.htm, and is also shown below.

I was not able to code the renko-based charts, so the two moving averages, the simple average of the typical price (typSMA), and the simple average of the heikin-ashi close (haSMA) are based on the closing values from a conventional chart, not the renko chart.

In Figure 7, I show a chart of Netflix (NFLX) with the typSMA and haSMA averages. The chart also shows a trade that was opened on 1/4/2013 and closed on 2/27/2013 for a 90% profit.

Sample Chart

FIGURE 7: AIQ. Here is a sample chart of Netflix (NFLX) with the typSMA and haSMA averages plus a sample trade marked with white up and down arrows.

!Exploring Charting Techniques: Creating A Trading Strategy
!Author: Sylvain Vervoort, TASC Oct 2014
!Coded by: Richard Denning 08/03/2014
!www.TradersEdgeSystems.com

!NOTE: Renko based charts are not available in AIQ. The following
!      code is conventional open, high, low , close charts.

! INPUTS:
H is [high].
L is [low].
C is [close].
O is [open].
OSD is offsettodate(month(),day(),year()).
typLen is 8.
haLen is 8.

!----------------HEIKIN-ASHI-----------------    
haC is (O + H +L + C) / 4.
DaysInto is ReportDate() - RuleDate().
end if DaysInto > 20.
endHAO is iff(end,O, haO).
haO is (valresult(endHAO,1)
	+valresult(haC,1))/2.
haH is Max(H,max(haO,haC)).
haL is Min(L,min(haO,haC)).
haCL is (haC + haO + haH + haL) / 4.
haSMA is simpleavg(haCL,haLen).  !PLOT
!---------------end HEIKIN-ASHI---------------

!---------------TYPICAL PRICE ----------------
TYP is (H+L+C)/3.
typSMA is simpleavg(TYP,typLen). !PLOT

!-----------------end TYPICAL-----------------

!--------------COLOR STUDY--------------------
GREEN if typSMA > haSMA.
RED if typSMA < haSMA.
!-------------end COLOR STUDY-----------------

!-------------TRADING SYSTEM------------------
Buy if GREEN.
ExitBuy if RED.
Sell if RED.
ExitSell if GREEN.
!-------------end TRADING SYSTEM--------------

—Richard Denning
info@TradersEdgeSystems.com
for AIQ Systems

BACK TO LIST

logo

TRADERSSTUDIO: OCTOBER 2014

The TradersStudio code I am providing for Sylvain Vervoort’s September 2014 article in S&C, “Exploring Charting Techniques: Creating A Trading Strategy, Part 3,” can be found at the following two websites:

The following code files are provided in the download:

I was not able to code the renko-based charts, so the two moving averages, the simple average of the typical price (typSMA), and the simple average of the heikin-ashi close (haSMA) are based on the closing values from a conventional chart, not the renko chart.

In Figure 8, I show a chart of the S&P 500 full-size futures contract (SP) using data from Pinnacle Data Corp. (www.pinnacledata.com) with the typSMA and haSMA averages. In addition, this chart shows a sample trade that was opened on 10/14/2013 and closed on 11/11/2013 for a $19,875 profit before commission & slippage.

Sample Chart

FIGURE 8: TRADERSSTUDIO. Here is an example crossover of the typSMA and haSMA averages on a chart of the S&P 500 full-size futures contract (SP). The trade shown here, which was opened on 10/14/2013 and closed on 11/11/2013, would have produced a profit of $19,875 before commission & slippage.

'Exploring Charting Techniques: Creating A Trading Strategy
'Author: Sylvain Vervoort, TASC Oct 2014
'Coded by: Richard Denning 08/03/2014
'www.TradersEdgeSystems.com

'NOTE: Renko based charts are not available in AIQ. The following
'      code is conventional open, high, low , close charts.

Function HA_SMA(haLen)
    Dim haC As BarArray
    Dim haO As BarArray
    Dim haH As BarArray
    Dim haL As BarArray
    Dim haCL As BarArray
    haC = (O+H+L+C)/4
    haO = IIF(BarNumber = FirstBar,O,(haO[1] + haC[1])/2) 
    haH = Max(H,haO)
    haL = Min(L,haO)
    haCL = (haC+haO+haH+haL)/4
    
HA_SMA = Average(haCL,haLen)
End Function
'------------------------------------------------------------------
Function TYP_SMA(typLen)
Dim TYP As BarArray
TYP = (H+L+C)/3
TYP_SMA = Average(TYP,typLen) 
End Function
'------------------------------------------------------------------
Sub TYP_HA_SMA(typLen,haLen)
plot1(typ_SMA(typLen))
plot2(ha_SMA(haLen))
End Sub
'------------------------------------------------------------------
Sub SVE_TYP_HA_SMA_SYS(typLen,haLen,LSB)
    'typLen = 8,haLen = 8
    'LSB = 1 (Longs only)
       ' = -1 (Shorts only) 
       ' = 0 (Both Longs and Shorts)
    Dim typSMA As BarArray
    Dim haSMA As BarArray
    Dim Green, Red
    typSMA = TYP_SMA(typLen)
    haSMA = HA_SMA(haLen)
    Green = typSMA > haSMA And C > O
    Red = typSMA < haSMA And C > O
    If Green And (LSB = 1 Or LSB = 0) Then Buy("LE",1,0,Market,Day)
    If Red Then ExitLong("LX","",1,0,Market,Day)
    If Red And (LSB = 0 Or LSB = -1) Then Sell("SE",1,0,Market,Day)
    If Green Then ExitShort("SX","",1,0,Market,Day)
End Sub
'-------------------------------------------------------------------

—Richard Denning
info@TradersEdgeSystems.com
for TradersStudio

BACK TO LIST

logo

NINJATRADER: OCTOBER 2014

The SveRenkoCross strategy, as introduced by Sylvain Vervoort in the September 2014 STOCKS & COMMODITIES article “Exploring Charting Techniques: Creating A Trading Strategy, Part 3,” has been made available for download at www.ninjatrader.com/SC/October2014SC.zip.

Once you have it downloaded, from within the NinjaTrader Control Center window, select the menu File → Utilities → Import NinjaScript and select the downloaded file. This file is for NinjaTrader version 7 or greater.

You can review the strategy source code by selecting the menu Tools → Edit NinjaScript → Strategy from within the NinjaTrader Control Center window and selecting the “SveRenkoCross” file. A sample chart implementing the strategy is shown in Figure 9.

Sample Chart

FIGURE 9: NINJATRADER. This screenshot shows the strategy applied to a 100-tick SveRenko S&P 500 chart in NinjaTrader.

—Raymond Deux & Cal Hueber
NinjaTrader, LLC
www.ninjatrader.com

BACK TO LIST

logo

UPDATA: OCTOBER 2014

Our Traders’ Tip this month is one that was developed in-house by our Updata team and is for a trading system we named the small-range bars system.

This system is a daily breakout system that identifies when the previous day’s absolute daily range (high to low) and normalized by the close is at least half a standard deviation below its cumulative period average. The system anticipates the next day will be of larger range. On that day, signals are generated upon breaking of the previous day’s high or low. All positions are flattened at the close.

The Updata code for this system is in the Updata Library and may be downloaded by clicking the custom menu and indicator library. Those who cannot access the library due to a firewall may paste the code shown below into the Updata custom editor and save it.


'Small Range Bars System 
DISPLAYSTYLE 3LINES
INDICATORTYPE CHART 
INDICATORTYPE2 TOOL
PLOTSTYLE2 LINE RGB(200,0,0) 
NAME "Abs Range With Cumulative Avg. - 0.5 Std.Deviations" ""
@PCTBAR=0 
@STDDEVBAR=0 
@AVGBAR=0  
#Inc=0  
@VOLUMEAVG=0   
@SUMBAR=0                           
@BARAVG=0 
@DIFFSq=0

FOR #CURDATE=1 TO #LASTDATE  
    IF ABS(HIGH-LOW)>0
       #Inc=#Inc+1
       @PCTBAR=(ABS(HIGH(1)-LOW(1)))/CLOSE(1) 
       @SUMBAR=@SUMBAR+@PCTBAR
       @BARAVG=@SUMBAR/#Inc
       @DIFFSq=@DIFFSq+((@PCTBAR-@BARAVG)*(@PCTBAR-@BARAVG))
       @STDDEVBAR=EXPBASE(@DIFFSq/(#Inc-1),0.5)
       'ENTRIES IF BAR IS 0.5 STD DEV BELOW AVG RANGE
       'LONGS UPON BREAK OF PREV HIGH
       'SHORTS UPON BREAK OF PREV LOW
       IF HIST(@PCTBAR<(@BARAVG-0.5*@STDDEVBAR),1)     
          IF HIGH>HIGH(1)
             BUY MAX(HIGH(1),OPEN)
          ENDIF
          IF LOW<LOW(1)
             SHORT MIN(LOW(1),OPEN)
          ENDIF
       ENDIF    
       'CLOSE POSITIONS ON SAME BAR
       SELL CLOSE 
       COVER CLOSE
       @PLOT=@PCTBAR
       @PLOT2=@BARAVG-0.5*@STDDEVBAR 
    ENDIF
NEXT


Sample Chart

FIGURE 10: UPDATA, SMALL-RANGE BARS SYSTEM. This chart shows an example of our small-range bars system as applied to NYMEX-listed WTI crude oil prices.

—Updata support team
support@updata.co.uk, www.updata.co.uk

BACK TO LIST

MICROSOFT EXCEL: OCTOBER 2014

In “Exploring Charting Techniques: Creating A Trading Strategy, Part 3” by Sylvain Vervoort, which appeared in the September 2014 issue of STOCKS & COMMODITIES, the author develops a simple trading strategy around the crossover of two moving averages constructed over the modified renko brick chart that he showed us earlier in his July 2014 S&C article of the same series (part 1).

I played around with the renko tick size (700), which translates to a brick size of $700. With the S&P 500 as the datastream (which is a big ticket compared to Ford at $17 a share), this allowed more dates on the renko chart for demonstration purposes. Adjust as you like for your trading instrument.

I also made one small change to his signal strategy. Rather than use a set 0.8 signal threshold, my spreadsheet calculates the maximum absolute delta between the moving averages and then takes a user-specified percentage of that delta as the threshold value. This allows the strategy to adapt to tradable instruments with large differences in pricing scales.

This strategy seems to work equally well with tick-level data or end-of-day data.

Unless we get a sharp signal crossover (as we see near 12/18/2013 in Figure 11), the delta between the two moving averages can be less than our signal threshold for one or more bars, and we get white space.

Sample Chart

FIGURE 11: EXCEL, CROSSOVER ON RENKO CHART. This shows a renko chart with the position durations per indicator. The crossover spread exceeds the signal threshold.

The chart in Figure 11 has a fixed number of bars to avoid some clutter. The right-most bar is for the same date as the right-most bar on the price chart in Figure 12. Because of the nature of the renko bar construct, the number of renko bars for a given time span will almost never be the same as the number of source data bars for the same time span.

To help get the charts to cover the same time span for the sake of visual comparison, the button to the right of the renko chart will reset the price chart of Figure 12 to the time span shown in the renko chart.

Sample Chart

FIGURE 12: EXCEL. Here’s a sample price chart for comparison to the renko chart in Figure 11.

Figure 13 details the backtest transactions that were summarized in the blue box at the bottom left of the chart in Figure 12.

Sample Chart

FIGURE 13: EXCEL, BACKTEST RESULTS. This shows the log of backtest transactions.

The spreadsheet file can be downloaded here: CreatingATradingStrategy.xlsm. To successfully download it, follow these steps:

—Ron McAllister
Excel and VBA programmer
rpmac_xltt@sprynet.com

BACK TO LIST

Originally published in the October 2014 issue of
Technical Analysis of Stocks & Commodities magazine.
All rights reserved. © Copyright 2014, Technical Analysis, Inc.