TRADERS’ TIPS

May 2012

Here is this month’s selection of Traders’ Tips, contributed by various developers of technical analysis software to help readers more easily implement some of the strategies presented in this and other issues.

Other code appearing in articles in this issue is posted in the Subscriber Area of our website at http://technical.traders.com/sub/sublogin.asp. Login requires your last name and subscription number (from mailing label). Once logged in, scroll down to beneath the “Optimized trading systems” area until you see “Code from articles.” From there, code can be copied and pasted into the appropriate technical analysis program so that no retyping of code is required for subscribers.

You can copy these formulas and programs for easy use in your spreadsheet or analysis software. Simply “select” the desired text by highlighting as you would in any word processing program, then use your standard key command for copy or choose “copy” from the browser menu. The copied text can then be “pasted” into any open spreadsheet or other software by selecting an insertion point and executing a paste command. By toggling back and forth between an application window and the open web page, data can be transferred with ease.

For this month’s Traders’ Tips, the focus is Walid Khalil’s article in this issue, “Sentiment Zone Oscillator.” Source code for AmiBroker is already provided in Khalil’s article in this issue, and subscribers will find this code in the Subscriber Area of our website, Traders.com. (Click on “Article Code” from our homepage.) Presented here is additional code and possible implementations for other software.


TRADESTATION: SENTIMENT ZONE OSCILLATOR

In “Sentiment Zone Oscillator” in this issue, author Walid Khalil describes the construction and use of the sentiment zone oscillator (SZO). The oscillator is designed to indicate overbought and oversold levels and potential entry/exit areas.

Shown below is the EasyLanguage code for the SZO indicator (_SZO); a strategy based on the author’s discussion (_SZO_Strategy); and an accompanying function (_TEMA) used in the indicator and strategy.

The buy and sell conditions used in the strategy are defined by Khalil in his article. Alerts were coded in the indicator to alert when the oscillator crosses below the overbought levels and above the oversold levels.

To download the EasyLanguage code for the indicators, first navigate to the EasyLanguage FAQs and Reference Posts Topic in the EasyLanguage support forum (https://www.tradestation.com/Discussions/Topic.aspx?Topic_ID=47452), scroll down and click on the link labeled “Traders' Tips, TASC.” Then select the appropriate link for the month and year. The ELD filename is “_SZO.ELD.” The code is also shown below.

_TEMA (Function - set Return Type to double)

{ TASC May 2012 }
{ Sentiment Zone Oscillator }

inputs:
	Price( numericseries ), { value to average }
	Length( numericsimple ) ; { length of average }

variables:
	EMA1( 0 ),
	EMA2( 0 ),
	EMA3( 0 ) ;

EMA1 = XAverage( Price, Length ) ;
EMA2 = XAverage( EMA1, Length ) ;
EMA3 = XAverage( EMA2, Length ) ;

_TEMA = 3 * EMA1 - 3 * EMA2 + EMA3 ;


_SZO (Indicator)

{ TASC May 2012 }
{ Sentiment Zone Oscillator }
{ Walid Khalil, MFTA, CFTe }
	
inputs:
	Period( 14 ),
	LongPeriod( 30 ),
	OverBought( 7 ),
	OverSold( -7 ),
	PlotZeroLine( true ),
	PlotDynamicOBandOS( true ) ;

variables:
	R( 0 ),
	SP( 0 ),
	SZO( 0 ),
	HighestSZO( 0 ),
	LowestSZO( 0 ),
	SZORange( 0 ),
	DynamicOB( 0 ),
	DynamicOS( 0 ) ;

if Close > Close[1] then
	R = 1
else
	R = -1 ;

SP = _TEMA( R, Period ) ;
SZO = 100 * SP / Period ;

HighestSZO = Highest( SZO, LongPeriod ) ;
LowestSZO = Lowest( SZO, LongPeriod ) ;
SZORange = HighestSZO - LowestSZO ;

DynamicOB = LowestSZO + SZORange * 0.95 ;
DynamicOS = HighestSZO - SZORange * 0.95 ;

Plot1( SZO, "SZO" ) ;
if PlotZeroLine then
	Plot2( 0, "Zero" ) ;
Plot3( OverBought, "OB" ) ;
Plot4( OverSold, "OS" ) ;
if PlotDynamicOBandOS then
	begin
	Plot5( DynamicOB, "DynOB" ) ;
	Plot6( DynamicOS, "DynOS" ) ;
	end ;

{ Alerts }
if AlertEnabled then
	begin
	if SZO crosses above OverSold then
		Alert( "SZO cross above OS" )
	else if SZO crosses above DynamicOS then
		Alert( "SZO cross above DynamicOS" )
	else if SZO crosses below OverBought then
		Alert( "SZO cross below OB" )
	else if SZO crosses below DynamicOB then
		Alert( "SZO cross below DynamicOB" ) ;
	end ;

_SZO_Strategy (Strategy)

{ TASC May 2012 }
{ Sentiment Zone Oscillator }
{ Walid Khalil, MFTA, CFTe }
	
inputs:
	SZOPeriod( 14 ), { length for SZO calculations }
	LongPeriod( 30 ), { used for dynamic OB and OS 
	 levels }
	SZOAvgLen( 30 ), { moving average length of SZO - 
	 for entry/exit }
	TrendEMALen( 60 ), { length for trend EMA }
	OverBought( 7 ),
	OverSold( -7 ) ;

variables:
	R( 0 ),
	SP( 0 ),
	SZO( 0 ),
	SZO_SMA( 0 ),
	TrendEMA( 0 ),
	HighestSZO( 0 ),
	LowestSZO( 0 ),
	SZORange( 0 ),
	DynamicOB( 0 ),
	DynamicOS( 0 ),
	BuyCondition1( false ),
	BuyCondition2( false ),
	BuyCondition3( false ),
	SellCondition1( false ),
	SellCondition2( false ) ;

if Close > Close[1] then
	R = 1
else
	R = -1 ;

SP = _TEMA( R, SZOPeriod ) ;
SZO = 100 * SP / SZOPeriod ;
TrendEMA = XAverage( Close, TrendEMALen ) ;
SZO_SMA = Average( SZO, SZOAvgLen ) ;

HighestSZO = Highest( SZO, LongPeriod ) ;
LowestSZO = Lowest( SZO, LongPeriod ) ;
SZORange = HighestSZO - LowestSZO ;

DynamicOB = LowestSZO + SZORange * 0.95 ;
DynamicOS = HighestSZO - SZORange * 0.95 ;

{ Buy Rules/Conditions }
BuyCondition1 = SZO_SMA crosses above 0 and 
 Close > TrendEMA ;
BuyCondition2 = Close > TrendEMA and 
 SZO_SMA > SZO_SMA[1] and SZO < DynamicOS ;
BuyCondition3 = SZO_SMA > 0 and SZO crosses above 
 DynamicOS and TrendEMA > TrendEMA[1] ;

{ Sell Rules/Conditions }
SellCondition1 = SZO_SMA crosses above 0 ;
SellCondition2 = SZO crosses below OverBought and 
 SZO_SMA < SZO_SMA[1] ;

{ Long Entry }
if BuyCondition1 or BuyCondition2 or BuyCondition3 then
	Buy ( "SZO LE" ) next bar market ;

{ Long Exit }
if SellCondition1 or SellCondition2 then
	Sell ( "SZO LX" ) next bar market ;

A sample chart is shown in Figure 1.

Image 1

FIGURE 1: TRADESTATION, SENTIMENT ZONE OSCILLATOR. Here is a daily bar chart of $INDU along with the _SZO indicator and _SZO_Strategy. In the indicator (lower panel), the magenta and cyan dotted lines plot the dynamic overbought and dynamic oversold levels, respectively.

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.

—Chris Imhof
TradeStation Securities, Inc.
A subsidiary of TradeStation Group, Inc.
www.TradeStation.com

BACK TO LIST

THINKORSWIM: SENTIMENT ZONE OSCILLATOR

April showers have brought us May flowers by way of Walid Khalil’s article in this issue, “Sentiment Zone Oscillator.” Through the creation of his volume and price zone oscillators, Khalil found a need to effectively track swings in market sentiment along with other factors, extreme swings in particular. His oscillator and the associated strategy utilize a back-counting method of rising versus falling periods tempered by a smoothed exponential moving average to avoid whipsaw signaling.

For thinkorswim users, we have created a pair of scripts, one study and one strategy, in our proprietary language, thinkScript. The study gives you access to the oscillator described in Khalil’s article. The associated strategy backtests the application of the oscillator in the method he recommends. With this study’s method of measuring antipodal sentiment, it can be used as a leading contrarian indicator. (See Figure 2.) Enjoy!

Image 1

FIGURE 2: THINKORSWIM, SENTIMENT ZONE OSCILLATOR. The SZO study can be used as a leading contrarian indicator.

The code is shown below along with instructions for applying it.

  1. From our TOS Charts, select Studies → Edit Studies
  2. Select the “Studies” tab in the upper left-hand corner
  3. Select “New” in the lower left-hand corner
  4. Name the oscillator study (that is, “SentimentZoneOscillator”)
  5. Click in the script editor window, remove “plot data = close,” and paste in the following:
    declare lower;
    
    input price = close;
    input length = 14;
    input longLength = 30;
    input percent = 95.0;
    
    def SP = TEMA(Sign(price - price[1]), length);
    plot SZO = 100 * SP / length;
    
    def HLP = Highest(SZO, longLength);
    def LLP = Lowest (SZO, longLength);
    def pRange = (HLP - LLP) * percent / 100;
    plot OverBought = LLP + pRange;
    plot OverSold = HLP - pRange;
    plot "+7" = 7;
    plot "-7" = -7;
    plot ZeroLine = 0;
    
    SZO.SetDefaultColor(GetColor(1));
    OverBought.SetDefaultColor(GetColor(5));
    OverSold.SetDefaultColor(GetColor(6));
    "+7".SetDefaultColor(GetColor(7));
    "-7".SetDefaultColor(GetColor(7));
    ZeroLine.SetDefaultColor(GetColor(4));Select OK.
    
    
  6. Click “OK”
  7. (Optional) If you wish to add the automated strategy as well, click Strategies at the upper left-hand corner of the “Edit studies and strategies” window
  8. Select “New” in the lower left-hand corner
  9. Name the oscillator strategy (that is, “SentimentZone”)
  10. Click in the script editor window, and paste in the following:
    script SentimentZoneOscillator {
    
        input price = close;
        input length = 14;
        input longLength = 30;
        input percent = 95.0;
    
        def SP = TEMA(Sign(price - price[1]), length);
        plot SZO = 100 * SP / length;
    
        def HLP = Highest(SZO, longLength);
        def LLP = Lowest (SZO, longLength);
        def pRange = (HLP - LLP) * percent / 100;
        plot OverBought = LLP + pRange;
        plot OverSold = HLP - pRange;
        plot "+7" = 7;
        plot "-7" = -7;
        plot ZeroLine = 0;
    }
    
    input price = close;
    input length = 14;
    input longLength = 30;
    input percent = 95.0;
    
    def SZO = reference SentimentZoneOscillator(price, length, longLength, percent).SZO;
    def OverSold = reference SentimentZoneOscillator(price, length, longLength, percent).OverSold;
    def SMA30 = Average(SZO, 30);
    def EMA60 = ExpAverage(price, 60);
    
    addOrder(OrderType.BUY_AUTO,
        SMA30 crosses above 0 and price > EMA60 or
        price > EMA60 and SZO < OverSold and SMA30 > SMA30[1] or
        SMA30 > 0 and SZO crosses above OverSold and EMA60 > EMA60[1],
        tickColor = GetColor(0), arrowColor = GetColor(0));
    addOrder(OrderType.SELL_AUTO,
        SMA30 crosses above 0 or
        SZO crosses below 7 and SMA30 < SMA30[1],
        tickColor = GetColor(1), arrowColor = GetColor(1));
  11. Select “OK” and you are good to go. Your new study and strategy will appear in your lists of studies and strategies.

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

BACK TO LIST

eSIGNAL: SENTIMENT ZONE OSCILLATOR

For this month’s Traders’ Tip, we’ve provided the formula SentimentZoneOsc.efs based on the formula code from Walid Khalil’s article in this issue, “Sentiment Zone Oscillator.”

The study contains formula parameters to set the number of periods, dynamic levels, dynamic levels period, and the dynamic levels percent range, which may be configured through the Edit Chart window.

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 http://www.esignal.com/support/kb/efs/. The eSignal formula script (EFS) is also available for copying & pasting below or downloading from here.

/*********************************
Provided By:  
    Interactive Data Corporation (Copyright © 2012) 
    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:        
    Sentiment Zone Oscillator
 
Version:            1.0  14/03/2012

Formula Parameters:                     Default:
    Period                              14
    Use Dynamic Levels                  true
    Dynamic Levels Period               30
    Dynamic Levels % Range              95
    
Notes:
    The related article is copyrighted material. If you are not
    a subscriber of Stocks & Commodities, please visit www.traders.com.

**********************************/
var OB_LEVEL = 7;
var OS_LEVEL = -7;

var fpArray = new Array();

function preMain()
{
    setCursorLabelName("Sentiment Zone Osc", 0);
    setCursorLabelName("OverBought Level", 1);
    setCursorLabelName("OverSold Level", 2);
    
    setDefaultBarFgColor(Color.aqua, 0);
    setDefaultBarFgColor(Color.red, 1);
    setDefaultBarFgColor(Color.green, 2);
    
    setDefaultBarThickness(2, 0);
    setDefaultBarThickness(2, 1);
    setDefaultBarThickness(2, 2);
    
    var x=0;
    fpArray[x] = new FunctionParameter("gPeriod", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
	setName("Period");
	setLowerLimit(2);
        setUpperLimit(200);
        setDefault(14);
    }

    fpArray[x] = new FunctionParameter("gIsDynamicLevels", FunctionParameter.BOOLEAN);
    with(fpArray[x++])
    {
	setName("Use Dynamic Levels");
        setDefault(true);
    }
    
    fpArray[x] = new FunctionParameter("gExtremesPeriod", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
	setName("Dynamic Levels Period");
	setLowerLimit(2);
        setUpperLimit(200);
        setDefault(30);
    }
    
    fpArray[x] = new FunctionParameter("gPercentageRange", FunctionParameter.NUMBER);
    with(fpArray[x++])
    {
	setName("Dynamic Levels % Range");
	setLowerLimit(1);
        setUpperLimit(100);
        setDefault(95);
    }
}

var bInit = false;
var bVersion = null;

var xSZO = null;

var xHLP = null;
var xLLP = null;

function main(gPeriod, gIsDynamicLevels, gExtremesPeriod, gPercentageRange)
{
    if (bVersion == null) bVersion = verify();
    if (bVersion == false) return;     
        
    if (!bInit)
    {
        xSZO = efsInternal("calc_SZO", gPeriod);
        
        if (gIsDynamicLevels)
        {
            xHLP = hhv(gExtremesPeriod, xSZO);
            xLLP = llv(gExtremesPeriod, xSZO);
        }
        
        bInit = true;
    }

    var nOB = null;
    var nOS = null;
    
    if (gIsDynamicLevels)
    {
        var vHLP = xHLP.getValue(0);
        var vLLP = xLLP.getValue(0);
        
        if (vHLP == null || vLLP == null)
            return;
        
        var nRange = vHLP - vLLP;
        var nPRange = nRange * (gPercentageRange / 100);
        
        nOB = vLLP + nPRange;
        nOS = vHLP - nPRange;
        
        addBand(OB_LEVEL, PS_DASH, 1, Color.maroon, "obLevel");
        addBand(OS_LEVEL, PS_DASH, 1, Color.darkgreen, "osLevel")
    }
    else
    {
        nOB = OB_LEVEL;
        nOS = OS_LEVEL;
    }
        
    var vSZO = xSZO.getValue(0);
        
    if (vSZO == null)
        return;
    
    return new Array(vSZO, nOB, nOS);
}


var bInitSZO = false;

var xR = null;
var xSP = null;

// Sentiment Zone Oscillator
function calc_SZO(period)
{
    if (!bInitSZO)
    {
        xR = efsInternal("calc_Range");
        xSP = efsInternal("TEMA", period, xR);
        
        bInitSZO = true;
    }
    
    var vSP = xSP.getValue(0);

    if (vSP == null)
        return;
    
    return 100 * (vSP / period);          
}


// to include both time and sentiment
function calc_Range()
{
    var vC = close(0);
    var vvC = close(-1);
    
    if (vvC == null)
        return;
    
    if (vC > vvC)
        return 1;
    else 
        return -1;
}


var bInitTEMA = false;
var xEma1 = null;
var xEma2 = null;
var xEma3 = null;

// Triple Exponential Moving Average
function TEMA(period, series)
{   
    if(!bInitTEMA)
    {
        xEma1 = ema(period, series);
        xEma2 = ema(period, xEma1);
        xEma3 = ema(period, xEma2);
        
        bInitTEMA = true;    
    }   
    
    var vEma1 = xEma1.getValue(0);
    var vEma2 = xEma2.getValue(0);
    var vEma3 = xEma3.getValue(0);
    
    if (vEma3 == null) 
        return null;
    
    return 3 * vEma1 - 3 * vEma2 + vEma3;
}

// verify version
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=http://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;
}

A sample chart is shown in Figure 3.

Image 1

FIGURE 3: eSIGNAL, SENTIMENT ZONE OSCILLATOR

—Jason Keck
eSignal, an Interactive Data company
800 779-6555, www.eSignal.com

BACK TO LIST

METASTOCK: SENTIMENT ZONE OSCILLATOR

Walid Khalil’s article in this issue, “Sentiment Zone Oscillator,” introduces an indicator of the same name. The article includes the MetaStock code for the indicator, but here, we’ll provide code for the dynamic overbought and oversold levels. Here are the steps to make one indicator that plots both the SZO and the OB/OS levels:

  1. In the Tools menu, select Indicator Builder
  2. Click New to open the Indicator Editor for a new indicator.
  3. Type the name “SZO with OB/OS levels”
  4. Click in the larger window and paste or type in the following formula:
    Period:= Input("Y",2,200,14);
    lperiod:= 30;
    pcent:= 95;
    R:= If(C>Ref(C,-1),1,-1);
    SP:= Tema(r,period);
    SZO:= 100*(SP/period);
    hlp:= HHV(szo, lperiod);
    llp:= LLV(szo, lperiod);
    prange:= (hlp-llp)*(pcent/100);
    ob:= llp+prange;
    OS:= hlp-prange;
    SZO;
    OB;
    OS
  5. Click OK to close the Indicator Editor
  6. Click OK to close the Indicator Editor
  7. Click OK to close the Indicator Builder

The system test for the SZO can be made as follows:

  1. Select Tools → Enhanced System Tester
  2. Click New
  3. Enter the name, “Sentiment Zone Oscillator”
  4. Select the Buy Order tab and enter the following formula:
    Period:= 14;
    lperiod:= 30;
    pcent:= 95;
    R:= If(C>Ref(C,-1),1,-1);
    SP:= Tema(r,period);
    SZO:= 100*(SP/period);
    hlp:= HHV(szo, lperiod);
    llp:= LLV(szo, lperiod);
    prange:= (hlp-llp)*(pcent/100);
    ob:= llp+prange;
    OS:= hlp-prange;
    
    con1:= C > Mov(C,60,E) AND
    Cross(Mov(szo,30,S),0);
    
    con2:= C > Mov(C,60,E) AND
    ROC(Mov(szo,30,S),1,$)>0 AND
    szo < os;
    
    con3:= Cross(SZO, os) AND
    Mov(szo,30,S)>0 AND
    ROC(Mov(C,60,E),1,$)>0;
    
    con1 OR con2 OR con3
    
    
  5. Select the Sell Order tab and enter the following formula.
    Period:= 14;
    R:= If(C>Ref(C,-1),1,-1);
    SP:= Tema(r,period);
    SZO:= 100*(SP/period);
    
    Cross(0,SZO) OR
    (Cross(7,SZO) AND
    Mov(szo,30,S)<0)
  6. Click OK to close the system editor.

—William Golson
MetaStock Support
www.MetaStock.com

BACK TO LIST

WEALTH-LAB: SENTIMENT ZONE OSCILLATOR

Although one of Wealth-Lab’s strongest points is the ability to express your ideas in C# language, no programming is required for certain tasks like prototyping a trading idea. The Strategy Builder allows you to combine building blocks known as rules into a trading system.

After updating our TASC magazine indicators library to its most recent version using the built-in extension manager, you will find the sentiment zone oscillator (SZO) organized under the TASC magazine indicators group. This allows you to quickly use it in rule-based strategies as an entry or exit condition without having to program a single line of code yourself.

Image 1

FIGURE 4: WEALTH-LAB, SENTIMENT ZONE OSCILLATOR. Here’s an example of building an SZO crossover/crossunder strategy from rules as indicated in “SZO trading tactics” in Wealth-Lab 6.3.

Figure 4 shows the Strategy Builder’s conditions tab with a group of rules for general indicators. To attach a rule for the SZO:

  1. Simply drag and drop one of the general conditions onto an entry or exit (specifically, “Indicator crosses above/below a value”), then
  2. Click where indicated to select the SZO from the indicators dialog.

In our example, the resulting system was a blend between the countertrend entry based on reacting to SZO extremes, as suggested by author Walid Khalil in his article in this issue (“Sentiment Zone Oscillator”), and a trend-following stop that trails a percentage below (or above, for shorts) the highest high (or lowest low for shorts) achieved since the position was opened. See Figure 5.

Image 1

FIGURE 5: WEALTH-LAB, SZO SYSTEM. Here is a sample short trade. The stock’s 14-period SZO crosses below the +7 threshold.

By extending the backtest range to the most recent 10 years, we examined how efficient SZO signals were on the same Dow 30 portfolio on a longer history. With 5% equity allocated to a position, some signals had to be skipped. Our preference is to err on the side of caution, so the trades with the most percentage gain were excluded, suggesting a conservative outcome. After subtracting trading costs (commissions and 0.05% slippage per trade), the system took 244 trades (and skipped 115), coming slightly short of buy & hold’s net profit (64% vs. 74%) with less downside risk (maximum drawdown -38% vs. -50%). See Figure 6.

Image 1

FIGURE 6: WEALTH-LAB, 6. The simplified rule-based strategy’s equity virtually mirrored the buy & hold, and the short side was a loser and was unable to support the long side during its weak times.

Overall, the SZO’s turning points seem to highlight extremes in market sentiment, and they do it without repeating too often. If you’re willing to experiment with the SZO trading system as presented by its author, the strategy code is also included:

Wealth-Lab 6 strategy code (C#):

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

namespace WealthLab.Strategies
{
	public class SZOStrategy : WealthScript
	{
		private StrategyParameter paramPeriod;
		private StrategyParameter paramLongPeriod;
		private StrategyParameter paramBuy1;
		private StrategyParameter paramBuy2;
		private StrategyParameter paramBuy3;
		
		public SZOStrategy()
		{
			paramPeriod = CreateParameter("SZO Period", 14, 2, 300, 1);
			paramLongPeriod = CreateParameter("Long Period", 30, 20, 300, 1);
			paramBuy1 = CreateParameter("Buy1 On/Off", 1, 0, 1, 1);
			paramBuy2 = CreateParameter("Buy2 On/Off", 1, 0, 1, 1);
			paramBuy3 = CreateParameter("Buy3 On/Off", 1, 0, 1, 1);
		}
		
		protected override void Execute()
		{
			int period = paramPeriod.ValueInt;
			int LongPeriod = paramLongPeriod.ValueInt;
			double Percent=95;
			LineStyle ls = LineStyle.Solid;
			bool buy1 = paramBuy1.ValueInt > 0;
			bool buy2 = paramBuy2.ValueInt > 0;
			bool buy3 = paramBuy1.ValueInt > 0;
			
			SZO szo = SZO.Series( Close,period );
			SMA ma = SMA.Series( szo,LongPeriod );
			Highest HLP = Highest.Series(szo, LongPeriod);
			Lowest LLP = Lowest.Series(szo, LongPeriod);
			DataSeries Range = HLP - LLP;
			DataSeries Prange = Range *(Percent/100d);
			DataSeries OB = LLP + Prange; OB.Description = "O/B";
			DataSeries OS = HLP - Prange; OS.Description = "O/S";
			EMA ema = EMA.Series( Close,60,EMACalculation.Modern );

			ChartPane szoPane = CreatePane( 30,true,true );
			PlotSeriesOscillator( szoPane, szo, 7, -7, Color.Red, Color.Green, Color.Black, ls, 2 );
			PlotSeries( szoPane, OB, Color.Red, ls, 1 );
			PlotSeries( szoPane, OS, Color.Green, ls, 1 );
			DrawHorzLine( szoPane, 7, Color.Red, LineStyle.Dashed, 2 );
			DrawHorzLine( szoPane, -7, Color.Green, LineStyle.Dashed, 2 );
			HideVolume();

			for(int bar = GetTradingLoopStartBar(LongPeriod); bar < Bars.Count; bar++)
			{
				bool buyRule1 = CrossOver( bar, szo, 0 ) && (Close[bar] > ema[bar]) && buy1;
				bool buyRule2 = (Close[bar] > ema[bar]) && (szo[bar] < OS[bar]) && (ma[bar] > ma[bar - 1]) && buy2;
				bool buyRule3 = ( ma[bar] > 0 ) && CrossOver( bar, szo, -7 ) && (ema[bar] > ema[bar - 1]) && buy3;
				
				bool sellRule = CrossUnder( bar, szo, 0 ) || (CrossUnder( bar, szo, 7 ) && (ma[bar] < ma[bar - 1]));
				
				if (IsLastPositionActive)
				{
					Position p = LastPosition;
					if( sellRule )
						SellAtMarket( bar+1,p );
				}
				else
				{
					if( buyRule1 || buyRule2 || buyRule3 )
						BuyAtMarket( bar+1 );
				}
			}
		}
	}
}

—Eugene
www.wealth-lab.com

BACK TO LIST

NEUROSHELL TRADER: SENTIMENT ZONE OSCILLATOR

The sentimental zone oscillator described by Walid Khalil in his article in this issue can be easily implemented with a few of NeuroShell Trader’s 800+ indicators. Simply select “New Indicator” from the Insert menu and use the Indicator Wizard to set up the following indicators:

SVO**
Multiply2( 100, Divide( Tema( IfThenElse( A>B( Close, Lag(Close,1)), 1, -1), 14, 14))

Overbought SVO zone
Add2 ( Min(SVO,30), Divide( Multiply2( Range(SVO,30), PERCENT), 100))

Oversold SVO zone
Subtract ( Max(SVO,30), Divide( Multiply2( Range(SVO,30), PERCENT), 100))

Note that the SVO is based on the TEMA custom indicator, which NeuroShell Trader users can download for free at www.ward.net.

To create a trading system based on the SZO, select “New Trading Strategy” from the Insert menu and enter the following formulas in the appropriate locations of the Trading Strategy Wizard:

Generate a buy long market order if one of the following is true:

And2(	CrossAbove( Avg( SVO, 30), 0 ),
	A>B( Close, ExpAvg( Close, 60 ))   )
And3(	A>B( Close, ExpAvg( Close, 60 )),
	A<B( SVO, SVO_OVERSOLD ),
	A>B( Momentum( Avg( SVO, 30), 1), 0)   )
And3(	A>B( Avg( SVO, 30), 0),
	CrossAbove( SVO, SVO_OVERSOLD ),
	A>B ( Momentum( ExpAvg( Close, 60 ), 1), 0)   )

Generate a sell long market order if one of the following is true:

CrossAbove ( Avg( SVO, 30), 0)
And2 ( CrossBelow( SVO, 7), A<B( Momentum( Avg(SVO,30), 1), 0))

If you have NeuroShell Trader Professional, you can also choose whether the parameters should be optimized. After backtesting the trading strategy, use the “Detailed Analysis” button to view the backtest and trade-by-trade statistics for the strategy.

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 past Traders’ Tips.

A sample chart is shown in Figure 7.

Image 1

FIGURE 7: NEUROSHELL TRADER, SENTIMENT ZONE OSCILLATOR. This NeuroShell Trader chart displays the sentimental zone oscillator trading system and corresponding SVO indicator with overbought and oversold zones.

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

BACK TO LIST

STRATASEARCH: SENTIMENT ZONE OSCILLATOR

The article “Sentiment Zone Oscillator” by Walid Khalil in this issue gives us several new ideas to play with.

First, a basic sentiment zone oscillator (SZO) can be run against static overbought and oversold lines. Second, the SZO can be run against dynamic overbought and oversold lines. And finally, the SZO can be run within the complete trading system provided by the author. In our tests, the first option provided the most benefits.

Using the SZO against static overbought and oversold lines, we used a wide variety of parameter sets and were able to generate some pretty impressive foundations. In many instances, large numbers of trades were produced with relatively short holding periods. In addition to returns significantly outperforming the S&P 500 index, we often saw percentage profitability exceeding 80%.

In our next test, we took the basic SZO trading rule and ran it through an AutoSearch where it was automatically tested alongside thousands of supporting trading rules. The results were exceptional, often outperforming the S&P 500 index by a wide margin with relatively short holding periods and a high percentage of profitable trades. While the SZO appears to be a good foundation on its own, its true value appears to shine when used alongside the proper sets of supporting trading rules.

StrataSearch users can explore the SZO further by importing the 12 new trading rules from the shared area of the StrataSearch user forum. After installing the trading rules, users can run an automated search alongside thousands of supporting indicators to see just how well the sentiment zone oscillator can perform.

A sample chart of the sentiment zone oscillator in Strata-Search is shown in Figure 8.

Image 1

FIGURE 8: STRATASEARCH, SENTIMENT ZONE OSCILLATOR. In the bottom panel, the sentiment zone oscillator periodically crosses the dynamic overbought and oversold lines for the S&P 500 index.

//*******************************************************
// Sentiment Zone Oscillator
//*********************************************************
PD = parameter("Period");
R =if(C > ref(C,-1), 1, -1 );
SP = tema(R, PD);
SZO = 100 * (SP/ PD);

//*********************************************************
// Sentiment Zone Oscillator - Overbought Line
//*********************************************************
Days = parameter("Days");
LongPeriod = parameter("LongPeriod");
Percent = parameter("Percent");
HLP = high(SZO(Days), LongPeriod);
LLP = low(SZO(Days), LongPeriod);
Range = HLP - LLP;
Prange = Range *(Percent/100);
OB = LLP + Prange;
OS = HLP - Prange;
SZO_OB = OB;

//*********************************************************
// Sentiment Zone Oscillator - Oversold Line
//*********************************************************
Days = parameter("Days");
LongPeriod = parameter("LongPeriod");
Percent = parameter("Percent");
HLP = high(SZO(Days), LongPeriod);
LLP = low(SZO(Days), LongPeriod);
Range = HLP - LLP;
Prange = Range *(Percent/100);
OB = LLP + Prange;
OS = HLP - Prange;
SZO_OS = OS;

—Pete Rast
Avarin Systems Inc
www.StrataSearch.com

BACK TO LIST

AIQ: SENTIMENT ZONE OSCILLATOR

The AIQ code for Walid Khalil’s sentiment zone oscillator and related system from his article in this issue, “Sentiment Zone Oscillator,” is provided at www.TradersEdgeSystems.com/traderstips.htm.

Using the author’s system that is described in the article, I ran a test on the NASDAQ 100 list of stocks using the Portfolio Manager module. The following capitalization settings were used:

In Figure 9, I show the equity curve for long-only trading on the NASDAQ 100 list of stocks for the period 12/31/1999 to 3/16/2012. The return averaged 10.3% per year with a maximum drawdown of 56.5% on 3/9/2009. The trend filters that are applied to each stock in the system did not prevent the large drawdown during the two bear markets in the test period. Applying an index-based trend filter might improve the results, but I did not try this due to time constraints.

Image 1

FIGURE 9: AIQ, SENTIMENT ZONE OSCILLATOR. Shown here is the equity curve for a trading simulation for the sentiment zone oscillator system on the NASDAQ 100 list of stocks for the period 12/31/99 to 3/16/12 (blue line) compared to the buy & hold on the NDX index (red line).

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

!SENTIMENT ZONE OSCILLATOR
!Author: Walid Khailil, TASC May 2012
!Coded by: Richard Denning 3/14/12
!www.TradersEdgeSystems.com

!ABBREVIATIONS:
C 	is [close].
C1	is valresult(C,1).
H 	is [high].
L 	is [low].
O 	is [open].
V	is [volume].
avgV	is expavg(V,50).
smaC	is simpleavg(C,10).

!INPUTS:
szoLen is 14.  	!SZO PARAMETER
trendEMAlen is 60.  !LENTH FOR TREND DETERMINATION
longLen is 30. 	!LONG PERIOD SMOOTHING FOR SZO
percent is 95.  !PERCENTAGE OF RANGE
sellLevel is 7.
filter is 0.24.

!SZO OSCILLATOR:
R is iff(C > C1,1,-1).

rEMA is expavg(R,szoLen).
rTEMA is (3*rEMA) - (3*expavg(rEMA,szoLen)) 
	+ (expavg(expavg(rEMA,szoLen),szoLen)).
SZO is 100*(rTEMA / szoLen). 
szoHLP is highresult(SZO,longLen).
szoLLP is lowresult(SZO,longLen).
szoRng is szoHLP - szoLLP.
szoPctRng is szoRng * (percent/100).
szoOB is szoLLP + szoPctRng.
szoOS is szoHLP - szoPctRng.
szoMA is simpleavg(szo,longLen).
EMAtrend is expavg(C,trendEMAlen).

!SZO TRADING SYSTEM RULES:

!BUYING CONDITION RULES:
SZOmaXOzero if szoMA > filter 
	and not valrule(szoMA > filter,1).
TrendUp if C > EMAtrend.
SZOovrSld if SZO < szoOS.
SZOmaUp if SZO > valresult(SZO,1).
SZOgtZero if SZO > 0.
SZOxoLLP if valrule(SZOovrSld,1) and not SZOovrSld.
EMAUp if EMAtrend > valresult(EMAtrend,1).

BuyCond1 if SZOmaXOzero and TrendUP.
BuyCond2 if TrendUp and SZOovrSld 
	and szoMA > valresult(szoMA,1).
BuyCond3 if SZOgtZero and SZOxoLLP and EMAUp.

Buy if BuyCond1 or BuyCond2 or BuyCond3.

!SELLING CONDITION RULES:
SellCond1 if szoMA < -filter 
	and not valrule(szoMA < -filter,1).
SellCond2 if szo < sellLevel 
	and not valrule(szo < sellLevel,1) 
	and szoMA < valresult(szoMA,1).

Sell if SellCond1 or SellCond2.

!RELATIVE STRENGTH UDF FOR SELECTING TRADES:
STL is 32.	!RELATIVE STRENGTH LENGTH
Price1 is C. Price2 is C.
aL	is STL * 0.25.
RC3	is (valresult(Price1,3*aL)/valresult(Price2,4*aL)-1)*100. 
RC2	is (valresult(Price1,2*aL)/valresult(Price2,3*aL)-1)*100. 
RC1	is (valresult(Price1,1*aL)/valresult(Price2,2*aL)-1)*100. 
RC0	is (valresult(Price1,0*aL)/valresult(Price2,1*aL)-1)*100. 
RS_AIQs	is 0.4*RC0 + 0.2*RC1 + 0.2*RC2 + 0.2*RC3.

ShowValues if C > 0.

—Richard Denning
info@TradersEdgeSystems.com
for AIQ Systems

BACK TO LIST

TRADERSSTUDIO: SENTIMENT ZONE OSCILLATOR

The TradersStudio code for Walid Khalil’s article in this issue, “Sentiment Zone Oscillator,” is provided at the following websites:

www.TradersEdgeSystems.com/traderstips.htm
www.TradersStudio.com → Traders Resources → Traders Tips

The code is also shown below.

The following files are provided in the download:

In Figure 10, I show the indicator on a chart of Apple Inc. for part of 2011. The chart also shows the buy arrows along with the exits for several trades from the system.

Image 1

FIGURE 10: TRADERSSTUDIO, SENTIMENT ZONE OSCILLATOR. Here is the SZO indicator with overbought/oversold levels and the moving average of the indicator on a chart of Apple Inc. together with buy arrows and exit Xs for several of the trades from author Walid Khalil’s system that uses the SZO indicator.

Code for TradersStudio:

'SENTIMENT ZONE OSCILLATOR
'Author: Walid Khailil, TASC May 2012
'Coded by: Richard Denning 3/17/12
'www.TradersEdgeSystems.com

function SZO(szoLen)
Dim R As BarArray
Dim SP As BarArray
R = IIF(C>C[1],1,-1)
SP = TEMA(R,szoLen)
SZO = 100 * (SP / szoLen)
	
End Function
'-------------------------------------
' TRIPPLE EXPONENTIAL MOVING AVERAGE:
Function TEMA(price,temaLen)
    Dim EMA As BarArray
    EMA = XAverage(price, temaLen, 0)
    TEMA = (3 * EMA) - (3 * XAverage(EMA,temaLen)) + (XAverage(XAverage(EMA,temaLen),temaLen))
End Function
'---------------------------------------------------------------------------------------------
Sub SZO_IND(szoLen,longLen,pctRange)
'defaults szoLen = 14,trendEMAlen = 60,longLen = 30,
'         pctRange = 95,sellLevel = 7,filter = 0.24
Dim theSZO As BarArray
Dim szoMA As BarArray
Dim emaTrend As BarArray
Dim szoHLP, szoLLP, szoRng, szoPctRng, szoOB, szoOS
Dim SZOmaXOzero, trendUp, SZOmaUp, SZOgtZero, SZOxoLLP, EMAup 
Dim SZOovrSld As BarArray
Dim BuyCond1, BuyCond2, BuyCond3, SellCond1, SellCond2
theSZO = SZO(szoLen)
szoHLP = Highest(theSZO,longLen)
szoLLP = Lowest(theSZO,longLen)
szoRng = szoHLP - szoLLP
szoPctRng = szoRng * pctRange/100
szoOB = szoLLP + szoPctRng
szoOS = szoHLP - szoPctRng
szoMA = Average(theSZO,longLen)

plot1 (theSZO)
plot2 (szoOB)
plot3 (szoOS)
plot4 (szoMA)

End Sub
'----------------------------------------------------------------
Sub SZO_Sys(szoLen,trendEMAlen,longLen,pctRange,sellLevel,filter)
'defaults szoLen = 14,trendEMAlen = 60,longLen = 30,
'         pctRange = 95,sellLevel = 7,filter = 0.24
Dim theSZO As BarArray
Dim szoMA As BarArray
Dim emaTrend As BarArray
Dim szoHLP, szoLLP, szoRng, szoPctRng, szoOB, szoOS
Dim SZOmaXOzero, trendUp, SZOmaUp, SZOgtZero, SZOxoLLP, EMAup 
Dim SZOovrSld As BarArray
Dim BuyCond1, BuyCond2, BuyCond3, SellCond1, SellCond2
theSZO = SZO(szoLen)
szoHLP = Highest(theSZO,longLen)
szoLLP = Lowest(theSZO,longLen)
szoRng = szoHLP - szoLLP
szoPctRng = szoRng * pctRange/100
szoOB = szoLLP + szoPctRng
szoOS = szoHLP - szoPctRng
szoMA = Average(theSZO,longLen)
emaTrend = XAverage(C,trendEMAlen)
SZOmaXOzero = CrossesOver(szoMA,filter)
trendUp = C > emaTrend
SZOovrSld = theSZO < szoOS
SZOmaUp = theSZO > theSZO[1]
SZOgtZero = theSZO > 0
SZOxoLLP = CrossesOver(theSZO,szoOS)
EMAup = emaTrend > emaTrend[1]

BuyCond1 = SZOmaXOzero And trendUp
BuyCond2= trendUp And SZOovrSld And szoMA > szoMA[1]
BuyCond3 = SZOgtZero And SZOxoLLP And EMAup
If BuyCond1 Or BuyCond2 Or BuyCond3 Then Buy("LE",1,0,Market,Day)

SellCond1 = CrossesUnder(szoMA,-filter)
SellCond2 = CrossesUnder(theSZO,sellLevel) And szoMA < szoMA[1]
If SellCond1 Or SellCond2 Then ExitLong("LX","",1,0,Market,Day)
End Sub
'----------------------------------------------------------------

—Richard Denning
info@TradersEdgeSystems.com
for TradersStudio

BACK TO LIST

NINJATRADER: SENTIMENT ZONE OSCILLATOR

The SZOATS and SZO indicators, as discussed by author Walid Khalil in “Sentiment Zone Oscillator” in this issue, have been implemented as an automated strategy and indicator available for download at www.ninjatrader.com/SC/May2012SC.zip.

Once 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’s source code by selecting the menu Tools → Edit NinjaScript → Strategy from within the NinjaTrader Control Center window and selecting “SZOATS.”

You can review the indicator’s source code by selecting the menu Tools → Edit NinjaScript → Indicator from within the NinjaTrader Control Center window and selecting the SZO.

A sample chart implementing the strategy is shown in Figure 11.

Image 1

FIGURE 11: NINJATRADER, SENTIMENT ZONE OSCILLATOR. The NinjaTrader screenshot shows the SZOATS and related indicator applied to a daily chart of Dow Jones Industrial Average (∧DJIA).

—Raymond Deux & Ryan Millard
NinjaTrader, LLC
www.ninjatrader.com

BACK TO LIST

TRADECISION: SENTIMENT ZONE OSCILLATOR

In his article “Sentiment Zone Oscillator” in this issue, author Walid Khalil presents an indicator that measures extreme bullishness and bearishness and helps identify a change in sentiment.

Using Tradecision’s Indicator Builder, create the following indicators:

SZO indicator:
inputs
Period: "Period", 14, 1, 100;
end_inputs
var

R:= iff (C> C\1\, 1,-1);
SP:= TEMA (R, Period);
SZO:=100 * (SP/ Period);
end_var

return SZO;

SZO top indicator:
inputs
Period: "Period", 14, 1, 100;
end_inputs
var

R:= iff (C> C\1\, 1,-1);
SP:= TEMA (R, Period);
SZO:=100 * (SP/ Period);
LongPeriod:=30;
Perc:=95;
HLP:= Highest(SZO, LongPeriod);
LLP:= Lowest(SZO, LongPeriod);
Range1:= HLP - LLP;
Prange:= Range1 *(Perc/100);
OB:= LLP + Prange;
end_var

return OB;

SZO bottom indicator:
inputs
Period: "Period", 14, 1, 100;

end_inputs
var

R:= iff (C> C\1\, 1,-1);
SP:= TEMA (R, Period);
SZO:=100 * (SP/ Period);
LongPeriod:=30;
Perc:=95;
HLP:= Highest(SZO, LongPeriod);
LLP:= Lowest(SZO, LongPeriod);
Range1:= HLP - LLP;
Prange:= Range1 *(Perc/100);
OS:= HLP - Prange;
end_var

return OS;

To import the strategy into Tradecision, visit the area “Traders' Tips from TASC Magazine” at www.tradecision.com/support/tasc_tips/tasc_traders_tips.htm or copy the code above.

Image 1

FIGURE 12: TRADECISION, S&P 500 WITH SENTIMENT ZONE OSCILLATOR (SZO). Here is the sentiment zone oscillator with overbought and oversold levels plotted on a ∧GSPC daily chart.

—Yana Timofeeva, Alyuda Research
(510) 931-7808, sales@tradecision.com
www.tradecision.com

BACK TO LIST

TRADESIGNAL: SENTIMENT ZONE OSCILLATOR

The indicators presented in Walid Khalil’s article in this issue, “Sentiment Zone Oscillator,” can easily be used with our online charting tool at www.tradesignalonline.com. Check the Infopedia section for our lexicon. There, you will find the indicator and functions, which you can make available for your personal account. Simply click on it and select “open script.” The indicator will be immediately available for application.

The code can also be downloaded here:

Sentiment Zone Osc Strategy.eqs
Sentiment Zone Oscillator.eqi
TEMA.eqf

Image 1

FIGURE 13: TRADESIGNAL ONLINE, SENTIMENT ZONE OSCILLATOR. Here is a sample TradeSignal Online chart showing the sentiment zone oscillator and sentiment zone oscillator strategy on an hourly chart of Adidas.

Source code for sentiment zone oscillator strategy.eqs

Meta:
	Synopsis("The Sentiment Zone Oscillator Strategy TAS&C 05/2012."),
	WebLink("http://www.tradesignalonline.com/lexicon/view.aspx?id=18091"),
	Subchart( True );

Inputs:
	Period( 14 , 2, 200 ),
	Trigger( 30 , 1 ),
	LongPeriod( 30 , 1 ),
	Percent( 95 , 1 );


Vars:
	r, sentPos, sentimentOscillator, hhLevel, llLevel, szoRange,
	pRange, upperBorder, lowerBorder, avgSZO,
	
	longCond1, longCond2, longCond3, shortCond1, shortCond2;

If Close > Close[1] Then
	r = 1
Else r =  - 1;

sentPos = TEMA( r, Period );
sentimentOscillator = 100 * ( sentPos / Period );
avgSZO = Average( sentimentOscillator, Trigger );

hhLevel = Highest( sentimentOscillator, LongPeriod );
llLevel = Lowest( sentimentOscillator, LongPeriod );
szoRange = hhLevel - llLevel;
pRange = szoRange * ( Percent / 100 );

upperBorder = llLevel + pRange;
lowerBorder = hhLevel - pRange;

longCond1 = avgSZO Crosses Over 0;

value1 = XAverage( Close, 60 );
longCond2 = Close > value1 And sentimentOscillator < lowerBorder And avgSZO > avgSZO[1];
longCond3 = sentimentOscillator > 0 And sentimentOscillator Crosses Over lowerBOrder;

If longCond1 Or longCond2 Or longCond3 Then
	BUy This Bar on CLose;

shortCond1 = avgSZO Crosses Under 0;
shortCond2 = sentimentOscillator Crosses Under 7 And avgSZO < avgSZO[1];

If shortCond1 Or shortCond2 Then
	Short This Bar on Close;

DrawLine( sentimentOscillator, "SZO", StyleSolid, 2, Red );
DrawLine( upperBorder, "SZO OB", StyleDash, 1, Black );
DrawLine( lowerBorder, "SZO OS", StyleDash, 1, Black );

// *** Copyright tradesignal GmbH ***
// *** www.tradesignal.com ***

Source code for sentiment zone oscillator.eqi

Meta:
	Synopsis("The Sentiment Zone Oscillator TAS&C 05/2012."),
	WebLink("http://www.tradesignalonline.com/lexicon/view.aspx?id=18091"),
	Subchart( True );

Inputs:
	Period( 14 , 2, 200 ),
	LongPeriod( 30 , 1 ),
	Percent( 95 , 1 );


Vars:
	r, sentPos, sentimentOscillator, hhLevel, llLevel, szoRange,
	pRange, upperBorder, lowerBorder;

If Close > Close[1] Then
	r = 1
Else r =  - 1;

sentPos = TEMA( r, Period );
sentimentOscillator = 100 * ( sentPos / Period );

hhLevel = Highest( sentimentOscillator, LongPeriod );
llLevel = Lowest( sentimentOscillator, LongPeriod );
szoRange = hhLevel - llLevel;
pRange = szoRange * ( Percent / 100 );

upperBorder = llLevel + pRange;
lowerBorder = hhLevel - pRange;

DrawLine( sentimentOscillator, "SZO", StyleSolid, 2, Red );
DrawLine( upperBorder, "SZO OB", StyleDash, 1, Black );
DrawLine( lowerBorder, "SZO OS", StyleDash, 1, Black );

// *** Copyright tradesignal GmbH ***
// *** www.tradesignal.com ***

Source code TEMA.eqf

Meta:
	Synopsis("The function calculates a zero lag moving average.");

Inputs:
	priceSeries( NumericSeries ),
	periodMA( NumericSimple );

TEMA = ( 3 * XAverage( priceSeries, periodMA ) ) - ( 3 * XAverage( XAverage( priceSeries, periodMA ), periodMA ) ) +
XAverage( XAverage( XAverage( priceSeries, periodMA ), periodMA ), periodMA  );

// *** Copyright tradesignal GmbH ***
// *** www.tradesignal.com ***

—Henning Blumenthal, Tradesignal GmbH
support@tradesignalonline.com
www.TradesignalOnline.com, www.Tradesignal.com

BACK TO LIST

UPDATA: SENTIMENT ZONE OSCILLATOR

This Traders’ Tip is based on the article in this issue by Walid Khalil, “Sentiment Zone Oscillator.” In the article, Khalil develops an oscillator to identify extremes in bullish and bearish sentiment, based on signed daily changes. As the indicator persists at extremes, a reversal becomes increasingly likely.

The Updata code for this technique has been entered in the Updata Library and you can download it by clicking the Custom menu and then Indicator Library. Those who cannot access the library due to a firewall may paste the code shown here into the Updata Custom editor and save it.

 
DISPLAYSTYLE 6LINES  
INDICATORTYPE TOOL
INDICATORTYPE2 CHART
PARAMETER "SZO Period" #Period=14 
PARAMETER "SZO Donchian Period" #DonchPeriod=30   
PARAMETER "SZO Sig. Period" #SZOSigPeriod=30 
PARAMETER "SZO Zero Line" @ZEROLine=0.24
PARAMETER "Range {%}" @PCT=95
PARAMETER "Close Sig. Period" #CLSigPeriod=60
NAME "Avg[" #CLSigPeriod "]" ""
NAME2 "SZO[" #Period "|" #SZOSigPeriod "]" ""
PLOTSTYLE THICK2 RGB(0,0,200)
COLOUR3 RGB(200,0,0) 
COLOUR4 RGB(150,150,150) 
PLOTSTYLE5 THICK2 RGB(0,0,200)   
PLOTSTYLE6 DASH RGB(0,200,0) 
@UpDown=0  
@UpDownSmooth=0  
@SZO=0  
@OB=0
@OS=0 
@Range=0
@PercentageRange=0
@DynamicUpper=0
@DynamicLower=0 
@CLSignalAvg=0 
@SZOSignalAvg=0
FOR #CURDATE=MAX(#Period+#SZOSigPeriod,#CLSigPeriod) TO #LASTDATE
   @UpDown=SIGN(CLOSE-CLOSE(1)) 
   @UpDownSmooth=SGNL(@UpDown,#Period,E) 
   @SZO=100*(@UpDownSmooth/#Period)
   @OB=HIST(PHIGH(@SZO,#DonchPeriod),1)
   @OS=HIST(PLOW(@SZO,#DonchPeriod),1) 
   @CLSignalAvg=SGNL(CLOSE,#CLSigPeriod,E) 
   @SZOSignalAvg=SGNL(@SZO,#SZOSigPeriod,E)
   @Range=@OB-@OS
   @PercentageRange=@Range*(@PCT/100)
   @DynamicUpper=@OS+@PercentageRange
   @DynamicLower=@OB-@PercentageRange
   'EXITS
   IF HASX(@SZO,@ZEROLine,UP) OR HASX(@SZO,(#Period/2),DOWN) AND @SZOSignalAvg<HIST(@SZOSignalAvg,1)
      SELL CLOSE
   ENDIF 
   'ENTRIES
   IF CLOSE>@CLSignalAvg AND HASX(@SZOSignalAvg,@ZEROLine,UP)
      BUY CLOSE
   ELSEIF CLOSE>@CLSignalAvg AND @SZO<@DynamicLower AND @SZOSignalAvg>HIST(@SZOSignalAvg,1)
      BUY CLOSE
   ELSEIF @SZOSignalAvg>@ZEROLine AND HASX(@SZO,@DynamicLower,UP) AND @CLSignalAvg>HIST(@CLSignalAvg,1) 
      BUY CLOSE
   ENDIF 
   @PLOT=@CLSignalAvg
   @PLOT2=@SZO 
   @PLOT3=@DynamicUpper
   @PLOT4=@DynamicLower
   @PLOT5=@SZOSignalAvg 
   @PLOT6=@ZEROLine  
NEXT

A sample chart is shown in Figure 14.

Image 1

FIGURE 14: UPDATA, SENTIMENT ZONE OSCILLATOR. Here is the sentiment zone oscillator (14-period) with system rules added to the daily S&P 500 index.

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

BACK TO LIST

SHARESCOPE: SENTIMENT ZONE OSCILLATOR

We’re providing a script that adds the sentiment zone oscillator (SZO) with overbought and oversold levels to a ShareScope chart (see Figure 15). We’re also offering a script that adds a configuration dialog.

The source code for the script is shown below, and users can also download both scripts from our website at www.sharescript.co.uk.

Image 1

FIGURE 15: SHARESCOPE, SENTIMENT ZONE OSCILLATOR. Here is the sentiment zone oscillator with overbought & oversold levels.

SZO_Ionic_May12.ss

//@Name:SZO
//@Description:Sentiment Zone Oscillator. As described on Stocks & Commodities magazine, May 2012 edition.
// Care has been taken in preparing this code but it is provided without guarantee.
// You are welcome to modify and extend it.  Please add your name as a modifier if you distribute it.
//Coded by: Richard Chiesa, ShareScript Support

var period = 14;
var longPeriod = 30;
var perc = 95;
function init(status)
{
	if (status == Loading || status == Editing)
	{
		period = storage.getAt(0);
		longPeriod = storage.getAt(1);
		perc = storage.getAt(2);
	}
	if (status == Adding || status == Editing)
	{
		dlg = new Dialog("SZO settings...", 145, 55);
		dlg.addOkButton();
		dlg.addCancelButton();
		dlg.addIntEdit("INT1",8,-1,-1,-1,"","SZO Period",period,2,1000);
		dlg.addIntEdit("INT2",8,-1,-1,-1,"","Long Period",longPeriod,2,1000);
		dlg.addIntEdit("INT3",8,-1,-1,-1,"","Percent",perc,1,100);
		if (dlg.show()==Dialog.Cancel)
			return false;
		period = dlg.getValue("INT1");
		longPeriod = dlg.getValue("INT2");
		perc = dlg.getValue("INT3");
		
		storage.setAt(0, period);
		storage.setAt(1, longPeriod);
		storage.setAt(2, perc);
	}
	setSeriesLineStyle(0,0,1);
	setSeriesColour(1, Colour.Red);
	setSeriesColour(2, Colour.Blue);
	setTitle(period+" SZO");
	setHorizontalLine(7);
	setHorizontalLine(0);
	setHorizontalLine(-7);
}
function getGraph(share, data)
{
	var SZO = [];
	var ma1 = new TEMA(period);
	var OB = [];
	var OS = [];
	for (var i=1; i<data.length; i++)
	{
		var tema1 = ma1.getNext(data[i].close>data[i-1].close?1:-1);
		SZO[i] = 100*tema1/period;
		var hh = 0;
		var ll = 1000;
		if (i>=longPeriod)
		{
			for (var j=0; j<longPeriod; j++)
			{
				hh=SZO[i-j]>hh?SZO[i-j]:hh;
				ll=SZO[i-j]<ll?SZO[i-j]:ll;
			}
			var range = (hh-ll)*perc/100;
			OB[i] = ll+range;
			OS[i] = hh-range;
		}
	}
	
	return [SZO,OB,OS];
}

function TEMA(p)
{
	this.period = p;
	this.emaVal1;
	this.emaVal2;
	this.emaVal3;
}

TEMA.prototype.getNext = function (price)
{
	var ma1 = new MA(this.period, MA.Exponential);
	var ma2 = new MA(this.period, MA.Exponential);
	var ma3 = new MA(this.period, MA.Exponential)	
	if (this.emaVal1 != undefined) this.emaVal1 = ma1.getNext(this.emaVal1);
	this.emaVal1 = ma1.getNext(price);
	if (this.emaVal2 != undefined) this.emaVal2 = ma2.getNext(this.emaVal2);
	this.emaVal2 = ma2.getNext(this.emaVal1);
	if (this.emaVal3 != undefined) this.emaVal3 = ma3.getNext(this.emaVal3);
	this.emaVal3 = ma3.getNext(this.emaVal2);
	var tema = 3*this.emaVal1-3*this.emaVal2+this.emaVal3;	
	return tema;
}

—Tim Clarke
www.sharescript.co.uk

BACK TO LIST

VT TRADER: SENTIMENT ZONE OSCILLATOR

Our Traders’ Tip is based on “Sentiment Zone Oscillator” by Walid Khalil in this issue. In the article, Kahlil introduces the sentiment zone oscillator (SZO). The SZO is a contrary oscillator that measures extreme bullishness (optimism) and bearishness (pessimism). It’s plotted on a vertical scale of +100 to -100. The SZO crossing above +7 (overbought) indicates a buy signal while crossing below -7 (oversold) indicates a sell signal. The zero level does not have any importance according to Khalil.

Image 1

FIGURE 16: VT TRADER, SENTIMENT ZONE OSCILLATOR. Here is the SZO indicator on a EUR/USD four-hour candlestick chart.

We’ll be offering the sentiment zone oscillator for download in our VT client forums at http://forum.vtsystems.com along with hundreds of other precoded and free indicators and trading systems. The VT Trader instructions for recreating the indicator are shown below.

  1. VT Trader’s Ribbon→Technical Analysis menu→Indicators group→Indicators Builder→[New] button
  2. In the General tab, type the following text into each corresponding text box:
    Name: TASC - 05/2012 - Sentiment Zone Oscillator (SZO)
    Function Name Alias: tasc_SZO
    Label Mask: TASC - 05/2012 - Sentiment Zone Oscillator (SZO) (%Periods%) = %SZO%
    Placement: New Frame
    Data Inspection Alias: Sentiment Zone. Osc.
  3. In the Input Variable(s) tab, create the following variables:
    [New] button...
    Name: Periods
    Display Name: Periods
    Type: integer
    Default: 14
  4. In the Output Variable(s) tab, create the following variables:
    [New] button...
    Var Name: SZO	
    Name: (SZO)
    Line Color: purple
    Line Width: 2
    Line Type: solid
  5. In the Horizontal Line tab, create the following horizontal lines:
    [New] button...
    Value: +7
    Line Color: red
    Line Width: thin
    Line Type: dashed
    
    [New] button...
    Value: 0
    Line Color: black
    Line Width: thin
    Line Type: dashed
    
    [New] button...
    Value: -7
    Line Color: red
    Line Width: thin
    Line Type: dashed
  6. In the Formula tab, copy and paste the following formula:
    {Provided By: Visual Trading Systems, LLC}
    {Copyright: 2012}
    {Description: TASC, May 2012 - "Exploiting Extremes" by Walid Khalil}
    {File: tasc_SZO.vtscr - Version 1.0}
    
    R:= If(C>Ref(C,-1),1,-1);
    SP:= vt_tema(R,Periods,E);
    SZO:= 100*(SP/Periods);
  7. Click the “Save” icon in the toolbar to finish building the Sentiment Zone Oscillator (SZO).

To attach the indicator to a chart click the right mouse button within the chart window and then select “Add Indicator” → “TASC - 05/2012 - Sentiment Zone Oscillator (SZO)” from the indicator list.

To learn more about VT Trader, visit www.vtsystems.com.

Risk disclaimer: Past performance is not indicative of future results. Forex trading involves a substantial risk of loss and may not be suitable for all investors.

—Chris Skidmore
Visual Trading Systems, LLC
vttrader@vtsystems.com
www.vtsystems.com

BACK TO LIST

TRADE NAVIGATOR: SENTIMENT ZONE OSCILLATOR

Here we will show you how to recreate the custom indicators and highlight zones featured in this issue’s article, “Sentiment Zone Oscillator” by Walid Khalil using TradeSense code in Trade Navigator. Some of the indicators needed come standard with Trade Navigator.

First, open the Trader’s Toolbox, click on the Functions tab and click the New button.

SZO: Type in the following code:

&R := IFF (Close > Close.1 , 1 , (-1)) 
&SP := TEMA (&R , Period , False) 
&SZO := 100 * (&SP / Period) 
&SZO
Image 1

Click the verify button. Click the Add button on the Add Inputs window. For the period input, make the default value 14. When you are finished, click the save button, type a name for your new function, and click OK.

Repeat these steps for the SZO above 7, SZO below -7, SZO OB, and SZO OS, as follows.

SZO above 7: Type in the following code:

SZO (Period) > 7

For the period input, make the default value 14.

SZO below -7: Type in the following code:

SZO (Period) < (-7)

For the period input, make the default value 14.

SZO OB: Type in the following code:

&hlp := Highest (SZO (Period) , LongPeriod) 
&llp := Lowest (SZO (Period) , LongPeriod) 
&Range := &hlp - &llp 
&Prange := &Range * (Percent / 100) 
&llp + &Prange

For the inputs:

Period: 	14
LongPeriod: 	30
Percent: 	95

SZO OS: Type in the following code:

&hlp := Highest (SZO (Period) , LongPeriod) 
&llp := Lowest (SZO (Period) , LongPeriod) 
&Range := &hlp - &llp 
&Prange := &Range * (Percent / 100) 
&hlp - &Prange

For the inputs:

Period: 	14
LongPeriod: 	30
Percent: 	95

Creating the chart
Now that we have the function created, go to a daily chart and go to the Add To Chart window by clicking on the chart and typing “A” on the keyboard.

Click on the Indicators tab, find the indicators in the list and either doubleclick on them or highlight the name and click the Add button.

Note you can add more than one indicator at a time: First, click the name of an indicator to highlight it. Then, holding the Ctrl key down on the keyboard, click the name of other indicators to add and click the Add button when you have all desired indicators highlighted.

Indicators to add to the chart are:

MovingAvgX
SZO
SZO OB
SZO OS

To add the highlight bars, go to a daily chart and go to the Add To Chart window by clicking on the chart and typing “A” on the keyboard.

Click on the HighlightBars tab, find the Highlight Bars in the list and either double click on them or highlight the name and click the Add button.

Highlight bars to add to this chart are:

SZO above 7
SZO below -7

On the chart, click & drag the labels for MovingAvgX into the same pane as the price bars. Click and drag the labels for SZO OB and SZO OS into the same pane as the SZO indicator. You will need to adjust the values for the MovingAvgX.

Click on the chart and type “E.” Highlight the desired indicator and change it to the desired values and color in the chart settings window. Change the MovingAvgX Bars used in the average to 60.

Image 1

Highlight “SZO above 7” in the chart settings window. Change the Type to “Highlight Zones” and select a fill color.

Repeat these steps for SZO below -7.

When you have the indicators the way you want to see them, click on the Templates button, and click <Manage chart templates>. Then click on the New button, type a name for the template and click OK. You now have a template that you can add to any chart by selecting it from the Templates button menu.

Genesis Financial Technologies has provided a library called “sentiment zone oscillator” that includes a template of the same name containing the custom indicators discussed here plus highlight zones from Khalil’s article. You can download a special file named “SC201205” from within Trade Navigator to get this library.

—Michael Herman
Genesis Financial Technologies
www.TradeNavigator.com

BACK TO LIST

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

Return to Contents