July 2001
TRADERS' TIPS

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 issue.

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.

This month's tips include formulas and programs for:
 

TRADESTATION EASYLANGUAGE: THREE LINE-BREAK CHART
TRADESTATION EASYLANGUAGE: MIDAS SUPPORT AND RESISTANCE
TRADESTATION EASYLANGUAGE: VIMA
WEALTH-LAB.COM
TECHNIFILTER PLUS


or return to July 2001 Contents


TRADESTATION EASYLANGUAGE: Three-Line Break Chart

The 2001 Bonus Issue of STOCKS & COMMODITIES contained an article titled "Three-Line Break Reversal Signals." No EasyLanguage code was included with the article, and TradeStation doesn't provide an option to create a three-line break chart. Thus, I'd like to share the following EasyLanguage code for a PaintBar study that simulates a three-line break chart.

But first, let me provide a refresher on three-line break charts. To draw line break blocks, today's close is compared to the high and low of the previous block. A block is drawn only when today's close exceeds the high or low of the previous block. If today's close is higher than the top of the previous block, a new up block is drawn in the next column from the prior high to the new high price (today's close). If today's close is lower than the bottom of the previous block, a new down block is drawn in the next column from the prior low to the new low price (today's close). If the close fails to move outside the range of the previous block's high or low, then nothing is drawn.

In a three-line break chart, if rallies are strong enough to display three consecutive blocks in the same direction, then prices must reverse by the extreme price of the last three blocks in order to create a new block.

If a rally is powerful enough to form three consecutive up blocks, then prices must fall below the lowest point of the last three up blocks before a new down block is drawn. If a selloff is powerful enough to form three consecutive down blocks, then prices must rise above the highest point of the last three down blocks before a new up block is drawn.

I have written this PaintBar study in which up block colors rotate between white and yellow, and down block colors rotate between red and magenta. Each time the rules call for a new block to be drawn, the PaintBar colors change, indicating the new block. The chart is best viewed when setting the bar type to "line on close."

Variables: FUBarHigh(0), FUBarLow(0), SUBarHigh(0), SUBarLow(0),
TUBarHigh(0), TUBarLow(0), FLBarHigh(0), FLBarLow(0), SLBarHigh(0),
SLBarLow(0), TLBarHigh(0), TLBarLow(0), UpCount(0), DownCount(0),
UpNew(0), DnNew(0), UpRev(0), DnRev(0), PlotHigh(0), PlotLow(0), 
Color(0);
If Close > UpNew Then Begin
  If DownCount < 3 Then Begin
    If UpCount = 0 Then Begin
      UpCount = UpCount + 1;
      DownCount = 0;
      FUBarHigh = Close;
      FUBarLow = UpNew;
      SUBarHigh = 0;
      SUBarLow = 0;
      TUBarHigh = 0;
      TUBarLow = 0;
      FLBarHigh = 0;
      FLBarLow = 0;
      SLBarHigh = 0;
      SLBarLow = 0;
      TLBarHigh = 0;
      TLBarLow = 0;
      UpNew = FUBarHigh;
      DnNew = FUBarLow;
      PlotHigh = FUBarHigh;
      PlotLow = FUBarLow;    
      Color = 7;
    End;
    If UpCount = 1 Then
      If Close > UpNew Then Begin
        UpCount = UpCount + 1;
        SUBarHigh = Close;
        SUBarLow = FUBarHigh;
        UpNew = SUBarHigh;
        DnNew = SUBarLow;
        PlotHigh = SUBarHigh;
        PlotLow = SUBarLow;
        Color = 8;
      End;
    If UpCount = 2 Then
      If Close > UpNew Then Begin
        UpCount = UpCount +  1;
        TUBarHigh = Close;
        TUBarLow = SUBarHigh;
        UpNew = TUBarHigh;
        DnNew = TUBarLow;
        PlotHigh = TUBarHigh;
        PlotLow = TUBarLow;
        Color = 7;
      End;
    If UpCount = 3 Then
      If Close > UpNew Then Begin
        FUBarHigh = SUBarHigh;
        FUBarLow = SUBarLow;
        SUBarHigh = TUBarHigh;
        SUBarLow = TUBarLow;
        TUBarHigh = Close;
        TUBarLow = SUBarHigh;
        UpNew = TUBarHigh;
        DnNew = TUBarLow;
        PlotHigh = TUBarHigh;
        PlotLow = TUBarLow;
        If Color = 7 Then
          Color = 8
        Else
          Color = 7;
      End;
  End;
  If DownCount = 3 Then Begin
    UpRev = FLBarHigh;   
    If Close > UpRev Then Begin   
      UpCount = UpCount + 1;
      DownCount = 0;
      FUBarHigh = Close;   
      FUBarLow = TLBarHigh;   
      SUBarHigh = 0;
      SUBarLow = 0;
      TUBarHigh = 0;
      TUBarLow = 0;
      FLBarHigh = 0;
      FLBarLow = 0;
      SLBarHigh = 0;
      SLBarLow = 0;
      TLBarHigh = 0;
      TLBarLow = 0;
      UpNew = FUBarHigh;
      DnNew = FUBarLow;
      PlotHigh = FUBarHigh;
      PlotLow = FUBarLow; 
      Color = 7;
    End;
  End;
End;
If Close < DnNew Then Begin
  If UpCount < 3 Then Begin
    If DownCount = 0 Then Begin
      DownCount = DownCount + 1;
      UpCount = 0;   
      FLBarHigh = DnNew;
      FLBarLow = Close;
      SLBarHigh = 0;
      SLBarLow = 0;
      TLBarHigh = 0;
      TLBarLow = 0;
      FUBarHigh = 0;
      FUBarLow = 0;
      SUBarHigh = 0;
      SUBarLow = 0;
      TUBarHigh = 0;
      TUBarLow = 0;
      UpNew = FLBarHigh;
      DnNew = FLBarLow;
      PlotHigh = FLBarHigh;
      PlotLow = FLBarLow;
      Color = 6;   
    End;
    If DownCount = 1 Then
      If Close < DnNew Then Begin
        DownCount = DownCount + 1;
        SLBarHigh = FLBarLow;
        SLBarLow = Close;
        UpNew = SLBarHigh;
        DnNew = SLBarLow;
        PlotHigh = SLBarHigh;
        PlotLow = SLbarLow;
        Color = 5;
      End;
    If DownCount = 2 Then
      If Close < DnNew Then Begin
        DownCount = DownCount +  1;
        TLBarHigh = SLBarLow;
        TLBarLow = Close;
        UpNew = TLBarHigh;
        DnNew = TLBarLow;
        PlotHigh = TLBarHigh;
        PlotLow = TLBarLow;
        Color = 6;
      End;
    If DownCount = 3 Then
      If Close < DnNew Then Begin
        FLBarHigh = SLBarHigh;
        FLBarLow = SLBarLow;
        SLBarHigh = TLBarHigh;
        SLBarLow = TLBarLow;
        TLBarHigh = SLBarLow;
        TLBarLow = Close;
        UpNew = TLBarHigh;
        DnNew = TLBarLow;
        PlotHigh = TLBarHigh;
        PlotLow = TLBarLow;
        If Color = 6 Then
          Color = 5
        Else
          Color = 6;
      End;
  End;
  If UpCount = 3 Then Begin
    DnRev = FUBarLow; 
    If Close < DnRev Then Begin   
      DownCount = DownCount + 1;
      UpCount = 0;
      FLBarHigh = TUBarLow;
      FLBarLow = Close;   
      SLBarHigh = 0;
      SLBarLow = 0;
      TLBarHigh = 0;
      TLBarLow = 0;
      FUBarHigh = 0;
      FUBarLow = 0;
      SUBarHigh = 0;
      SUBarLow = 0;
      TUBarHigh = 0;
      TUBarLow = 0;
      UpNew = FLBarHigh;
      DnNew = FLBarLow;
      PlotHigh = FLBarHigh;
      PlotLow = FLBarLow;
      Color = 6;
    End;
  End;
End;   Plot1(PlotHigh,"High Bar",Color);
Plot2(PlotLow,"Low Bar",Color);
--John M. Snyder
Editor: This was ingenious and a generous gesture. Thanks for sending it in, John! Note: This code is also available as a downloadable .Ela file from the STOCKS & COMMODITIES website, Traders.com.
Click here to download the .ELA file.


GO BACK


TRADESTATION EASYLANGUAGE: MIDAS SUPPORT AND RESISTANCE

Editor: Here is a second tip from reader John Snyder.

The following EasyLanguage code displays the Midas support and resistance indicator presented in "Volume-Weighted Average Price" by George Reyna in the May 2001 STOCKS & COMMODITIES.
 

Input: Price((High + Low)/2), Mo(01), Da(03), Yr(2001);
Variable: Date1(0), StartBar(0), StartBarNum(0), BarsAgo(0),
BegVol(0), BegPV(0), Counter(0), CumVol(0), CumPV(0), SRLevel(0);
Date1 = ELDate(Mo,Da,Yr);
If DayofWeekFix(Date1) = 6 Then {If DOW = Saturday}
 Date1 = Date1 - 1;
If DayofWeekFix(Date1) = 0 Then {If DOW = Sunday}
 Date1 = Date1 - 2;
StartBar = FindBar(Date1,1600);
If StartBar < 0 Then  {If this date is a Holiday}
 StartBar = FindBar(Date1 + 1,1600);
If StartBar = 0 Then Begin
 StartBarNum = BarNumber;
 BegVol = Volume;
 BegPV = Volume * Price;
End;
BarsAgo = (CurrentBar - StartBarNum);
If StartBar >= 0 Then
 For Counter = 0 To BarsAgo Begin
  CumVol = Volume[Counter] + CumVol;
  CumPV = (Price[Counter] * Volume[Counter]) + CumPV;
 End;
SRLevel = IFF((CumPV - BegPV) = 0, 0, (CumPV - BegPV) / (CumVol - BegVol));
If StartBar > 0 Then
 Plot1(SRLevel,"SRLevel");


--John M. Snyder
 
 

GO BACK


TRADESTATION EASYLANGUAGE: VIMA


R.G. BoomersÕ variable-interval moving average, or VIMA, described elsewhere in this issue, can be implemented as a function-cum-indicator pair in TradeStationÕs EasyLanguage as shown here. The function VimaLength returns the recommended length for the simple average at the current bar, given the set of difference intervals to use, the amount of history to consider, and the lengths of the pair of bracketing averages.

The indicator VIMA provides the actual values of the inputs for the VimaLength function and plots the variable interval moving average based on the dynamically changing average length, or interval, from bar to bar.  Default values for the inputs are included in the indicator and can be edited by the user at the time the indicator is applied to a chart.

Instead of an indicator, the VimaLength function could also be called by a user-created trading strategy with similar inputs.  TradeStationÕs backtesting engine could then be used to not only quickly find the best pair of averages to use, but to optimize the other two inputs as well.

The code for both the function and the indicator will be available for download at www.tradestation.com. Look for the file VIMA.ELS.
 

Function: VIMALength
inputs:
MaxLength1(numericsimple), {"interval" will vary from 2 days to
 (MaxLength1 + 1) days; equivalently, Length1 below will vary
 from 1 day to MaxLength1 days}

Length2(numericsimple), {number of historical RESULTS to consider
 for each max/min calculation; actual number of historical data
 points used may be more than this}
ShortestVIMALength(numericsimple),
LongestVIMALength(numericsimple);
variables:
 VIMAOsc( 0 ),
 Length1( 0 ),
 MaxDiff( 0 ),
 MinDiff( 0 ),
 NormDiff( 0 ),
 VIMAOscMax( 0 ),
 VIMAOscMin( 0 ),
 VIMAOscNorm( 0 ),
 VIMALengthRange(LongestVIMALength - ShortestVIMALength);
VIMAOsc = 0;
for Length1 = 1 to MaxLength1
 begin
 MaxDiff = Highest(Close - Close[Length1], Length2);
 MinDiff = Lowest(Close - Close[Length1], Length2);
 NormDiff = (Close - Close[Length1] - MinDiff) / (MaxDiff - MinDiff);
 VIMAOsc = VIMAOsc + NormDiff;
 end;
VIMAOscMax = Highest(VIMAOsc, Length2);
VIMAOscMin = Lowest(VIMAOsc, Length2);
VIMAOscNorm = (VIMAOsc - VIMAOscMin) / (VIMAOscMax - VIMAOscMin);
VIMALength = ShortestVIMALength + Round(VIMAOscNorm * VIMALengthRange, 0);
Indicator: VIMA
inputs:
 MaxLength1( 3 ),
 Length2( 20 ),
 ShortestVIMALength( 3 ),
 LongestVIMALength( 6 );
variables:
 CurrentVIMALength( 0 );
CurrentVIMALength = VIMALength( MaxLength1, Length2,
 ShortestVIMALength, LongestVIMALength);
Plot1(Average(Close, CurrentVIMALength));


--Ramesh Dhingra, Product Manager, EasyLanguage
TradeStation Technologies, Inc.
(formerly Omega Research, Inc.)
A wholly owned subsidiary of TradeStation Group, Inc.
http://www.TradeStation.com

GO BACK


  WEALTH-LAB.COM


R.G. Boomers' variable-interval moving average (VIMA) is a bit more complex than your typical technical indicator. Composing the indicator requires you to compare differences in price over a series of intervals to determine the period of a simple moving average to use. Wealth-Lab's scripting language, WealthScript, is equipped for the challenge. Here, we use some of WealthScript's advanced features, such as user-defined arrays, to implement the VIMA indicator. All that's left is determining the best-performing values for the high and low moving averages. The Wealth-Lab Desktop Optimization tool can be used to gather this piece of the puzzle.
 

{Create PriceSeries corresponding to differences 2 to 35}
SetArray(Diffs, 36);
for Interval := 2 to 35 do
begin
 Diffs[Interval] := CreateSeries;
 for Bar := 35 to BarCount - 1 do
  SetSeriesValue(Bar, Diffs[Interval],
    PriceClose(Bar) - riceClose(Bar - Interval));
end;
{Create VIMA Series}
VIMA := CreateSeries;
for Bar := ( 250 + 35 ) to BarCount - 1 do
begin
 XSum := 0.0;
 for Interval := 2 to 35 do
 begin
  H := Highest( Bar, Diffs[Interval], 250 );
  L := Lowest( Bar, Diffs[Interval], 250 );
  if H <> L then
  begin
   X := ( PriceClose( Bar ) - L ) / ( H - L );
   XSum := XSum + X;
  end;
 end;
 SetSeriesValue( Bar, VIMA, XSum );
end;
{ Plot VIMA }
VIMAPane := CreatePane( 50, true, true );
PlotSeries( VIMA, VIMAPane, #Navy, #Histogram );
DrawLabel( 'VIMA', VIMAPane );
{ Create VIMA MA }
VIMAMA := CreateSeries();
HVIMA := Highest( BarCount - 1, VIMA, BarCount );
LVIMA := Lowest( BarCount - 1, VIMA, BarCount );
for Bar := ( 250 + 25 ) to BarCount - 1 do
begin
 V := GetSeriesValue( Bar, VIMA );
 M := ( V - LVIMA ) / ( HVIMA - LVIMA );
 N := Trunc( 34 * M );
 N := N + 2;
 SetSeriesValue( Bar, VIMAMA, SMA( Bar, #Close, N ));
end;
{ Plot VIMA MA }
PlotSeries( VIMAMA, 0, #Blue, 2 );
DrawLabel( 'VIMA MA', 0 );


--Dion Kurczek, Wealth-Lab.com
773 883-9047, dionkk@ix.netcom.com
http://www.wealth-lab.com
 

GO BACK



 

TECHNIFILTER PLUS


Here is a TechniFilter Plus formula that computes the VIMA calculation discussed in R.G. Boomers' article in this issue, "Variable-Interval Moving Averages."

Lines 1 through 12 compute where each day's price is located within the maximum and minimum price ranges for a specific lookback period. Each line uses a different lookback period in the range of 2 to 35 by increments of 3. Line 13 just sums the previous 12 lines to obtain the VIMA oscillator. Line 14 computes average length in the range from 10 to 50, depending on where the VIMA oscillator is in its 250-day range. Finally, line 15 uses this length in its calculation of a simple average.
 

NAME: VIMA
SWITCHES: multiline
FORMULA:
[1]: (C-(C-CY2)M250)/((C-CY2)M250-(C-CY2)N250)
[2]: (C-(C-CY5)M250)/((C-CY5)M250-(C-CY5)N250)
[3]: (C-(C-CY8)M250)/((C-CY8)M250-(C-CY8)N250)
[4]: (C-(C-CY11)M250)/((C-CY11)M250-(C-CY11)N250)
[5]: (C-(C-CY14)M250)/((C-CY14)M250-(C-CY14)N250)
[6]: (C-(C-CY17)M250)/((C-CY17)M250-(C-CY17)N250)
[7]: (C-(C-CY20)M250)/((C-CY20)M250-(C-CY20)N250)
[8]: (C-(C-CY23)M250)/((C-CY23)M250-(C-CY23)N250)
[9]: (C-(C-CY26)M250)/((C-CY26)M250-(C-CY26)N250)
[10]: (C-(C-CY29)M250)/((C-CY29)M250-(C-CY29)N250)
[11]: (C-(C-CY32)M250)/((C-CY32)M250-(C-CY32)N250)
[12]: (C-(C-CY35)M250)/((C-CY35)M250-(C-CY35)N250)
[13]: [1]+[2]+[3]+[4]+[5]+[6]+[7]+[8]+[9]+[10]+[11]+[12]  {oscillator}
[14]: (10 + 40*([13]-[13]N250)/([13]M250-[13]N250)) \ 1   {average len varying 10 to 50}
[15]: CA[14] {v}
 Visit RTR's website to download this formula as well as program updates.
--Clay Burch, RTR Software
919 510-0608, rtrsoft@aol.com
http://www.rtrsoftware.com
 

GO BACK



All rights reserved. © Copyright 2001, Technical Analysis, Inc.

Return to July 2001 Contents