0% found this document useful (0 votes)
65 views18 pages

MetaStock Explorer Usage Tips

The document discusses common pitfalls when using the MetaStock Explorer tool, including issues related to structure, user settings, data loading, and code. It explains that the Explorer has 7 columns that function similarly to indicators and the filter acts as a 7th column. It also discusses ensuring the proper number of records are loaded to avoid inaccurate results from functions like EMAs.

Uploaded by

rarosil528
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
65 views18 pages

MetaStock Explorer Usage Tips

The document discusses common pitfalls when using the MetaStock Explorer tool, including issues related to structure, user settings, data loading, and code. It explains that the Explorer has 7 columns that function similarly to indicators and the filter acts as a 7th column. It also discusses ensuring the proper number of records are loaded to avoid inaccurate results from functions like EMAs.

Uploaded by

rarosil528
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

MetaStock Tips & Tricks IN THIS ISSUE

Explorer Pitfalls 1
Exponential Moving Averages 4
Questions and Answers 6
Developing Explorations – Part 2 7
Tip of the Month 12
Thanks For The Memory – Part 1 13
Coming Next Month 18
System Tester Part 2 – Held over until February

EXPLORER PITFALLS
I t’s been said before, probably more than once, that the Explorer is a
potentially very powerful tool. It can be used for everything from
quite mundane scans to very sophisticated data mining. Let’s take a
look at the various small traps that frustrate many MetaStock users. It’s
important that you know how to use this tool properly even if your
coding skills are not that hot.

Tools For Explorer problems fall into these four main areas; structure, user
settings, data and code.
MetaStock
Structure

The Explorer is merely a tool for extracting information from your


data. It works fine for rank beginners, but it can yield so much more
for those that understand the basic elements making up the complete
package. For example, did you know that an exploration reports results
MetaStock Tips & Tricks by up to seven different criteria? This is true. The filter is really just a
is published monthly by seventh column to which slightly different rules apply.
R A Larsen & Associates Processing Sequence. Explorer code is processed sequentially in the
Palmerston North 5301 same way as an indicator. Once the data for a particular security is
NEW ZEALAND
loaded, column A of bar one is processed first, then column B, and so
on through the remaining columns and filter. Bar two of the data is
Tel: +64 6 358 3723
processed next, also from column A through to the filter. The filter
roy@[Link]
[Link] result is only effective on the last bar of a security, but its code is
processed for every bar in the exploration.

Each security is processed one bar at a time. The securities in the


exploration list are also processed serially. However, the order in
Volume 1, Issue 5 which securities are processed is not always reflected by the order of
results in the final report.
January 2005
All illustrations in this newsletter are courtesy of MetaStock
Page 1 January 2005 Page 1
Columns A – F. With one exception, the Input() function, all columns
have the same essential qualities as an indicator. They also have the
same limitations. This gives you a tremendous amount of flexibility in
how you construct an exploration. You can report virtually any value
you choose in these columns. Results are reported at the last bar of
data, so it’s not obvious that information is available from all scanned The filter is
records. An indicator plots values for every bar, because that’s the
nature of an indicator. Think of an Explorer column as an indicator that
just a seventh
plots every bar but only reports on the last bar. A little mental agility column.
on your part may be needed to get at the information you want, but it’s
there for the taking all the same.

Filter. The filter is just a seventh column. It can’t use the Input()
function or report a visible value, but it can access the last-bar results
of other columns. It can also calculate a result from its own code and
use that with the results of other columns in performing its filtering
role. The filter is processed after columns A through F.

User Settings

There are two "Options" windows for the Explorer – global


Explorer settings and individual exploration settings.

Global Options. The first set of options provide global


settings; these are applied to all explorations. This
"Options" button is found at the bottom of "The Explorer"
window when the tool is first opened. The more important
option is "Data Loading". This allows you to select a set
number of records, or use the nominal assumed minimum.
Figure 1.
The "Load Minimum Records" option opens up a can of worms. It Global Explorer options.
should only be used with explorations that are known to return
accurate results with that setting. The method that MetaStock uses to
calculate the required number of records is simple, but basically
flawed. MetaStock looks for the highest "periods" parameter from all
column and filter code. Then it loads that number of records. PREV,
Cross() and other similar functions force at least one extra record to be
used. Most functions with no "periods" parameter have no influence on
the minimum-records calculation. BarsSince() and ValueWhen() are
typical examples of this type of function. Only functions that require
MetaStock to look at past data are considered, not functions that carry
values forward.

Expressions using exponential moving averages report incorrect values


unless they are fed by about five times the number of records set by the
"periods" parameter. The SAR() function needs sixteen or seventeen
records to return a result, but it won’t force that number of records to
be used by an exploration. Don’t assume that MetaStock can correctly
calculate the number of records needed to give an accurate result, and
don’t assume that N/A is the only possible wrong result.

Page 2 January 2005 Page 2


Individual Options. The second set of options are specific to each
exploration. Clicking the "Edit" button when exploration name is
highlighted enables access to this option set. Opening the Exploration
Editor reveals the second "Options" button. Notice that the three option
groups are date, periodicity and filter. All three are important and these
should normally not need changing.

Changing the exploration date allows you to test for a signal on any
given date, not just the most recent one. That effectively hides all
subsequent data from the exploration. If you change this setting for
some reason, remember to restore it to "Most Recent Date" afterwards.

The periodicity setting is self-explanatory. Use the appropriate setting.


If you need to run the exploration over both daily and weekly data then
you should make a copy of the exploration and change the periodicity
for the copy. Don’t forget to change the name of the copy too.
Figure 2.
Individual Exploration options.
It’s not a bad idea to have the filter always set to active. That way the
filter is enabled as soon as code is added into the filter window. Trying
to remember whether the filter is enabled on a particular exploration is
impossible, and it’s not the first place most people look for filter
problems either.

Data

Explorations use the same data as charts, but explorations usually load
fewer bars. This is to be expected since an exploration is usually just a
snapshot recording of current market activity. Unfortunately, reducing
the amount of data for explorations also increases the risk of inaccurate
results. The following article on exponential moving averages explains
the major reason why this happens.

Code

Quite a number of the problems that occur with the Explorer


are the result of function misuse or questionable code. The
Indicator Builder is the proper place for testing code, not the
Explorer Builder. The simple reason is that indicators are
"visual", while explorations are not. Code should only be
transferred to an exploration once you’re confident it does
what’s required on a chart. If it doesn’t work properly on a
chart there’s no way it’s going to fix itself and work in an
exploration. The Indicator Builder is the best
troubleshooting tool MetaStock has – use it. Remember that
you can reduce the amount of data loaded in a chart by
changing the charts X-Axis properties (right click in the
date area at the bottom of the chart). See Figure 3.
Figure 3.
X-Axis properties. In conclusion, let me stress again that the explorer is a very powerful
tool. Use that power to your advantage.
†

Page 3 January 2005 Page 3


EXPONENTIAL MOVING AVERAGES
I often hear the question "why don't the values from my
exploration agree with the values I see on a chart?". The answer has
been repeated many times, yet the most common cause is still not well
understood. The problem occurs if an exploration uses too few records
when calculating an exponential moving average.

To understand why this happens you must look at the structure of an


EMA. A simple moving average discards old data as soon as it falls Old data is
never completely
outside the specified data range. For example, a 10-period SMA only
uses data from 10 bars, and data from the 11th bar is completely
discarded. An EMA discards old data in a quite different manner. With
an EMA the "periods" value is used to calculate the proportion of data
purged from an
to retain, and by default, the corresponding proportion of data to EMA.
discard. If 90% of data is retained then it follows that 10% of data must
be discarded to make way for the 10% being added on each bar.

The crux of the matter is that old data is never completely purged. I
came across the following comment under Wilders Smoothing in the
user manual – "similar to the exponential method in that it retains a
decreasingly smaller percentage of all historical data in the series".
That comment encapsulates the essence of an EMA.

A proportion of the current bar’s data is added to an EMA on each new


bar. The same proportion is discarded from the previous bar’s EMA
value (PREV). If 20% of the CLOSE is added to the EMA on each
new bar, then it follows that 20% of the previous bar’s EMA must be
discarded, and 80% must be retained. The retained 80% holds some
fragments of all data from the very first bar. Larger fragments are kept
from each subsequent bar. Obviously the impact of old data diminishes
as new data is added, but that impact persists well beyond the nominal
"periods" value of the EMA.

The "periods" value is used to decide how much new data to add and
how much old data to drop out. An exponential moving average uses
the ratio expressed by "2/(1+n)", where "n" is the "periods" value of
the Mov() function. Look at the following expressions and see how a
"periods" value of 9 is converted into a percentage for a conventional
exponential moving average.

2/(1+n) = 2/(1+9) = 2/10 = 0.2 =20%

This tells us that a 9-period EMA adds 20% of each new bar’s data into
the EMA. That 20% is added to 80% of the previous bar’s EMA value
(PREV). Keeping 80% of the old data is the same as dropping out
20% – the two percentages are complimentary and add up to 100%.
The 20% of new data added replaces the 20% of old data dropped out. Figure 4.
9 period exponential
The term "new data" refers to the data array being smoothed. This is moving average.

Page 4 January 2005 Page 4


usually a price, but it could be anything. The term "old data" refers to
the EMA’s previous bar value (PREV). Note that an EMA cannot be
calculated in the MetaStock formula language without using the PREV
function (or a dll).

Wilders
{Exponential Moving Average}
Smoothing is Periods:=Input("Periods",1,99,9);

less responsive
Prcent:=2 / (1 + Periods);
If(Cum(1)=1, C, PREV * (1-Prcent) + C * Prcent);
than an EMA. Wilders Smoothing is another form of EMA, and it differs from a
conventional EMA in two ways. The biggest difference is the "ratio
calculation", and this is expressed as "(1/n)". Look at the following
expressions to see how a "periods" parameter of 9 is converted into a
percentage for Wilders Smoothing.

1/n = 1/9 = 0.1111 = 11.11%

It’s clear from this example that Wilders Smoothing adds less new data
than an EMA for any given "periods" parameter. This makes it less
responsive to data changes. You can use an EMA to replace Wilders
Smoothing by adjusting the "periods" parameter to suit. Let’s work
backwards to find out how many periods an EMA needs to match a 9-
periods Wilders Smoothing.

11.11% = 0.1111 = 1/9 = 2/18 = 2/(1+17)


Periods=17.

This can be formalized as "(n*2)-1", being one less than twice the
Wilders Smoothing periods. Try some of your own examples to check
this out. You can use MetaStock’s drop-down indicators to compare
the results of your experiments.

There’s another difference between an EMA and Wilders Smoothing –


the initial values are set using different methods. The initial value may
be referred to as the "seeding" value. An EMA is seeded on bar one
with 100% of the data value for that bar. If CLOSE is the data array
being smoothed, the seed value effective on bar one is the CLOSE for
bar one. You can’t plot this value (unless you set periods to 1), but
believe me, that’s the seed value it uses. Wilders Smoothing ignores all
invalid bars, and plots a simple moving average on the first valid bar.
A 9-period Wilders() is seeded with a 9-period simple moving average
on bar 9. See Figure 5.
Figure 5.
9 period Wilders {Wilders Smoothing}
Smoothing (red), and 9 Periods:=Input("Periods",1,99,9);
period simple moving Prcent:=1 / Periods;
average (black). Seed:=Mov(C,Periods,S);
If(Cum(1)=Periods, Seed, PREV * (1-Prcent) + C * Prcent);

Page 5 January 2005 Page 5


A number of technical indicators use Wilders() for internal smoothing. adx() oscp()
J Welles Wilder created several popular indicators, and most of these adxr() oscv()
are now built into MetaStock as part of the formula language. His most atr() pdi()
popular indicators are RSI, ATR and ADX, but don’t overlook the fact bbandbot() pfe()
that there are also a number of others. bbandtop() projosc()
dema() qstick()
{RSI Indicator} dx() rangeindicator()
A:=Input("RSI periods",2,50,14); emv() rmi()
U:=Wilders(If(C>Ref(C,-1),C-Ref(C,-1),0),A); forecastosc() rvi()
D:=Wilders(If(C<Ref(C,-1),Ref(C,-1)-C,0),A); imi() sar()
100-(100/(1+(U/D))); inertia() stoch()
macd() tema()
Let’s get back to answering the original question. The problem is not a mass() trix()
fault with the Explorer, nor is it a fault with the formula language. The mdi() wilders()
root cause is probably an EMA-smoothed value somewhere in the code mov()
that is using less data than the associated chart. Differences are most
Figure 6.
noticeable when the "Minimum Records" option is set. You should
These functions may not return
multiply the largest EMA-periods parameter in an exploration by 5 to accurate values if used with the
gauge an appropriate minimum number of records. See Figure 1 for “Minimum Records” setting.
pointers on setting the number of exploration records.

The functions listed in Figure 6 are among those needing extra care.
These may use exponential smoothing, or may display similar
symptoms when used with too few records. Don’t regard this list as
complete – it’s not. It’s provided here as a rough guide only, and you
should do your own research if you suspect your exploration reports
are inaccurate.
†
A number of
functions use
Wilders
QUESTIONS AND ANSWERS Smoothing
internally.
Q"period
When plotting the Q & B indicators I often get an error message
value out of range in Mov() function". This error often
necessitates closing MetaStock. What’s the minimum bar count, and
can the code be altered to use fewer bars and still remain relevant?

A I haven't heard of problems requiring an MS shutdown, but the


"out of range" problem is caused by the "n" variable default
setting. You could try cutting this back to 100-120 periods to see if that
improves the situation. The default of 250 means that MS needs at
least a full year of data to plot anything on daily charts, and more for
you to see a useful pattern. Weekly charts require 5+ years of data, so
the chance of this error occurring is quite high.

Adding the following code line just before the "noise" variable should
mean you don't get the problem, because the periods used by the Mov()
function is reduced automatically when there aren’t enough bars to

Page 6 January 2005 Page 6


work with. The Q indicator will plot at least "p2" valid bars with this
change, even on charts with less than 250 bars.

n:=LastValue(Min(Cum(1)-2*p2,n)); {extra line of code}


noise:=Sqrt(Mov(dt*dt,n,E)); {keep this existing line}

Qsecurity
Is it possible to include an indicator for an index in the normal
smart chart? If so, how do I do it?

A Yes, you can do this if you have access to the Security() function.
Remember that the Security() function requires the full path name
of the index when it’s in a different folder to any of your securities.
†

DEVELOPING EXPLORATIONS - 2
T he subject of explorations is complex. Most people see
explorations as a way to find stocks that meet some criteria that
they have decided defines a good entry. This is probably the most
popular use for explorations.

In addition, explorations are often used for defining trading rules and
testing systems. For example, a systems test might lead to the
conclusion that a specific signal has a good probability of being
profitable. However, the systems test is only one part of the total
process of determining the effectiveness and success probability of a
trading model. A system should be studied across a variety of dates to
determine the number, types and quality of trades it generates under
different market conditions. In my case, I know that I’m not going to
trade any system mechanically, so I want to establish the trading rules
I’m going to use with a specific signal. To do that, I have to look at a
lot of charts. I want to see charts having the signals when the market is
moving down and when the market is moving up.

I have a general rule that I use when developing and testing systems. I
look at a long only or short only system, not both combined together. I
evaluate each within the conditions it was designed to trade under. For
example, if the 5, 15 and 40 period SMA on a weekly chart is in an up-
trend, then my trading bias is to take long trades and only consider
short trades when the daily charts tell me the market is in a pull back
stage. I evaluate the short-term daily trends using a 4, 9, 18 period
EMA. On both charts, I use the DCF filter set to 27.

In an up-trend I expect my long trades to run for longer, and my short


trades to be of limited duration. The opposite holds true when the
market is in a downtrend.

Page 7 January 2005 Page 7


I look at my daily charts to pick specific exploration dates so I can
determine the number and type of trades the system finds when the
market is in-line with my bias and when it is not. Since I’m going to
filter each possible trade with my own trading rules, many of which are
not testable in the systems tester, I know I’m only going to take a
percentage of the signals any exploration yields, so to determine the
number of actual trades I can expect on a weekly basis, I have to track
them with paper and pencil.

As I study the charts, I can adjust my trading rules to maximize for the
best entries. Later I review the entry signals I would have taken against
their performance across time. This is a sophisticated system of paper
trading without the paper. I use another set of programs to track the
trades into the future, which helps me to establish the exit criteria and
the ratio of winning trades to losing trades. The systems tester makes
me use a set of fixed rules that often don’t allow me to easily do staged
entries and exits, timed holding periods or use mixed time frames to
make trading decisions. The historical explorations, with my electronic
paper trading methods, let me see how all of that works in a simulated
trading manner. It’s not perfect, but it’s pretty good. Often I can
increase the number of profitable trades a system generates in the tester
from 1 to 3, or 1 to 1, up to 3 to 1 and sometimes 4 to 1.

When I am exploring for stocks to trade, one trick I’ve learned is not to
explore using a specific entry criteria. For example, the John Clayburg
book, Four Steps to Trading Success, has been mentioned many times
on the MS boards. It’s an excellent book with an excellent indicator
system that combines extremely well with the B & Q indicators
discussed in previous MSTT articles. However, it is not a system that
was designed for mechanical trading, even though some people keep
trying to make it one.

Writing a specific exploration for the Clayburg system is likely to


create much more frustration than potential trades.

If I want to find trades for it, I write a surrogate exploration. As an


example, last month I mentioned some code using moving averages. If
you plot a couple of moving averages on a chart with the Clayburg
indicators you will notice that the Clayburg’s are often triggered within
a few bars of an MA crossover. Over the page is an example of MA
code designed to pick up all of the Clayburg signals, including the
inflection ones that are often missed by beginning users of the system.
I want to see them within a few bars of when they give the Clayburg
signal, and I want stocks likely to be in an up-trend. If you want to
check this, limit your search to the S&P 500 on November 4, 2004
because the S&P up-trend was underway and a lot of stocks were
giving off entry signals.

Page 8 January 2005 Page 8


Col A
BarsSince(C<Mov(C,18,E))>=
BarsSince(Cross(Mov(C,9,E),Mov(C,18,E)));

Col B
BarsSince(Cross(Mov(C,9,E),Mov(C,18,E)))<=3;

Filter
ColA and ColB;

If you don’t know what a Clayburg chart looks like, you can look
Clayburg settings in the files section of either MS board and find one. Here in the
side-bar are the settings to create your own. See Figure 7.
Will %R Green and Black on the chart.
If I write my exploration using the BarsSince function, I will find
%R 50 thresholds -10 & -90 green charts that have just recently triggered, or are close to triggering a
Clayburg buy signal. If the market is in a strong up-trend I prefer
%R 75 thresholds -20 & -80 black
to enter stocks that are already in an established up-trend
RSI Black and Red on the chart themselves. I don’t want to take a specific entry signal because
that is a lower probability trade than riding a stock that’s moving
RSI 7 and RSI 14 threshold up in an established pattern. To find those stocks, I’m going to
the same for both +30 & +70 increase my BarsSince width and use a statement or two to make
sure that during the BarsSince period, the stock has not dropped
Stoch Red and Green on the chart
below a specific moving average like the 10 bar EMA or 20 bar
Stoch (7,3) green threshold 10 and 90 EMA.

Stoch (45,5) red threshold 20 and 80 In addition, I would look at the Clayburg’s, the B & Q indicators
and the uRSC (URSC from Jose) to make sure the stock is strong
Figure 7. and that the up-trend I think I’m seeing is real.
Clayburg settings
One or two more things I might do include looking to see if the
particular stocks that are in an up-trend have traversed a short-term
pull back in the market. I like stocks strong enough to avoid downturns
that match the market. Those kind of up-trends usually run for long
periods of time. Additionally, I would look to see when the next
earnings announcement is scheduled. During earnings announcements,
I set very tight stops. You can find earnings announcement information
at Yahoo Finance.

All of this requires experimentation to find the correct mix of MA’s


and BarsSince count that will give you what you are looking for.

In general, I’ve found that the code to make a good expert or trading
system is not very good code for plugging into an exploration that will
find charts with stocks triggering the trade entry conditions that I’m
looking for. However, I have found code that yields groups of stocks
that are about to trigger almost any indicator signal you can think of.

One of those bits of code I happen to like is based on a May 2004


TASC article called the Inverse Fisher Transform. I had been using the
IFT for a few years before the publication of the article, but the article
generated a lot of interest in it.

Page 9 January 2005 Page 9


The IFT is a smoothing function that removes noise from many
common oscillators like the RSI or Stochastic indicators. When it is
applied to the RSI, for example, it removes a lot of the whipsaw
movement of the RSI that makes it difficult to use as an entry and exit
The IFT is a
indicator. smoothing
To fully understand it, you should read the TASC article. For our function that
purposes we’re only going to look at the code.
removes noise.
{Inverse Fisher Transform}
v1:= .1*(RSI(8)-50);
v2:=Mov(v1,9,W);
X:=(Exp(2*v2)-1)/(Exp(2*v2)+1);
-0.5;
0.5;
X;

Eight is the default value and the threshold for buy is –0.5, and for sell
it’s 0.5. When you plot it on a chart with your favorite system you will
see that, with a minor adjustment or two in the default value of the
RSI, it matches up closely with entries from your system. Explorations
are interested only in entries. However, if you desire, you can always
use two plots, one set to identify entries and one set to identify exits.
(Remember, this is if your system is based on indicators and not
patterns. I will discuss patterned entries later.)

Once you have adjusted the RSI period to match up to your desired
results, it’s easy to plug this code into an exploration with the uRSC

Adobe tools
code, or whatever else you might want to use as a value generator or
filtering criteria. For example, I only trade high volume, higher priced
stocks because I’m a big block trader. Some people want only low
priced stocks, so they might screen out all of the stocks over $10 a
allow text from
share. this document
If the exploration finds 50 potential trades, perhaps 10 of them will fit to be selected
and copied.
your desired entry signal with your trading rules. Yes, you may have to
look at 100 or more charts to find the best entries. (We’re talking about
your money here, so buckle up and do the work! )

The IFT of the RSI can be used as a crossover indicator, with the
BarsSince function, the alert function, or as a binary indicator. This
makes it versatile.

Here are a few more points to consider. The uRSC value is not in itself
a screening tool, unless you want to measure the strength of stocks
already in what looks like a trend. In general, just as many stocks move
up from a uRSC value above zero as do those below zero. In the next
article I will explain how to do explorations that use the uRSC very
effectively. The uRSC can be used to develop very profitable systems
for trading ETFs, mutual funds and stocks in general.

Page 10 January 2005 Page 10


Before doing an exploration you should have a defined strategy and
You should have a not simply search 7000 stocks a night. For example, I confine my
searches to the S&P 500, high volume dividend stocks or large caps –
defined strategy. all of which must be option-able stocks. You need a strategy that is
more specifically defined than simply trading tech stocks.

So how do you define that strategy? Well, you can use something like
the uRSC to find the best performing sectors, search those sectors for
tech stocks that are in an up-trend and that have had an entry signal
within X bars ago. Another alternative that I have tested and traded
successfully is finding stocks generating long or short entry signals
based on option pricing. You have to use a specialized program like
PowerStrike and combine it with a filtering system to identify which
trades are likely to be good trades. PowerStrike code provides the
explorations and chart information, but simply taking every possible
trade that PowerStrike identifies is a bad strategy. You have to build a
system around it because it’s not a system right out of the box.

I mentioned in my last article that trading from a prescreened list of


stocks like the Valueline T1 stocks or the S&P Neural Fair Value 25 is
a good strategy. It’s easy to make money trading this way, and the
stocks on those lists have two screens going for them – fundamentals
and TA charts. That’s powerful. In addition, you don’t have to screen
Fundamentals stocks every night, read a couple of hundred charts and trade
frequently. The Valueline not only has the Timeliness 1 stocks, it also
and T/A charts has the Technical 1 stocks, which are a group of stocks with good
technical characteristics like momentum. The Tech 1 and the Timely 1
are a powerful stocks often overlap by about 15%.
combination. When buying stocks from the prescreened lists, forget specific
indicator trigger points. Buy the trend and look for exits.

If you prefer to have a mechanical system, look at an ETF rotational


system, where you buy the top one to three performing ETFs based on
the uRSC values at the beginning of each month. You either hold them
until you get a suitable exit signal, or you sell them at the end of the
month and buy the next three. That system would have made about
30% this year buying at the beginning of the month and selling at the
end. However, forget testing that one with the systems tester. You’ll
have to do an exploration at the beginning of each month for the last 12
months and calculate what you would have made by hand. Why?
Because the systems tester can’t screen 30 stocks, pick the three with
the highest uRSC value, buy them and then sell them at the end of the
month. Roy is working on it, but he’s not quite there yet.

Several people have suggested alternatives to the uRSC, including


price averaging code and simple ROC code. These were suggested to
replace the uRSC in order to match the often-mentioned IBD ranking
system. The problem with all of these alternatives is they’re based only
on the value of the stock and not a comparison of a stock’s
performance to an index. Don’t be fooled. It’s the comparison to the

Page 11 January 2005 Page 11


index that gives the RSC its value. The IBD method is based on
comparison to an index.

If you’re a pattern trader forget writing exploration code for the


systems tester. The MS function language is not designed for finding
complex patterns like the cup and handle or the teakettle plus three, or
whatever. If you want those patterns use a service like Market Screen –
[Link]. Their ability to find patterns is much better
than an MS exploration. It’s costs $300 year for current pattern triggers
and hundreds of other TA indicators or situations.

So what’s my reward for all of this work? It’s hard to put numbers on
things because everyone is different and none of my systems are
mechanical. I know what you’re thinking – stop hedging and just tell
us!

Okay, I will, but remember, it’s hard to answer because there are
thousands of ways to trade, many thousands of risk profiles, and
varying degrees of laziness. Using what is comfortable for me, the type
of capital account I trade, what I trade and the market conditions I’ve
seen in my lifetime, I expect to make 20% to 60% a year. I caution you
not to pick the bigger number and assume you can average 60% a year.
You can’t. If you think you can, there’s nothing in these articles that
can help you. You are going to be toast, so I recommend buying a big
supply of burn cream before you run out of money.

Think about all the hedge funds, private money managers, mutual
funds and little guy traders out there. None of them average 60% a year
for more than a year or two. If you can average 20% a year for 10
years running, you’re at the top of the heap, and it’s a pretty lofty pile.

Jim

TIP OF THE MONTH


If you ever changed some code to shorten it or remove a redundant
section, then found that it no longer worked the way it should, what
would you do? Even those amongst us that are meticulous about
backups sometimes fall into little traps that cost us a lot of time. Well,
here are a few tips on code testing that might save you from some
embarrassment as well as wasted time.

Before changing any indicator, print out a hard copy. If the worst
comes to the worst you can at least get back to the point where you
started (not recommended, but better than no backup at all).

When you’re testing ideas for a particular variable it can be helpful to


paste a copy below the original. Put braces around the copy to turn it
(Continued on page 18)

Page 12 January 2005 Page 12


THANKS FOR THE MEMORY - 1
O ne of the first and most frustrating problems I encountered when I
was learning the MetaStock Formula Language was how to
remember the timing of an event. I knew about the PREV function of
course, but my old and slow computer didn’t handle PREV very well

A latch is a
at all. For my part I really didn’t need the number of tea-breaks that
PREV offered. I eventually stumbled onto the code structure that I now
memory device call a simple latch. Back then it was called a flag, and that confused
almost everyone. Eventually I settled on calling it a latch, and it works
in the same manner as a mechanical or electronic latch.

Definition

So what exactly is a latch? I think a good definition is that it’s a


memory device used to catch and hold a value or event.

The latch gives MetaStock an ability to remember events. It can also


remember a value related to an event. I often use a latch to monitor
trading system activity so I know if a system is in the market, or out.
As you work your way through the article you’ll discover different
ways to put latches together, and there’s several exercises for you to
try. The information given here is far from exhaustive on the subject,
but I think you’ll find it helpful.

My aim in writing the article is to walk you through the process of


coding and adapting a range of latches, and getting you to the point
where you have the knowledge and skill to code your own. Each
exercise can be copied directly into MetaStock where you can see its
logic on your own charts.

I’ve divided the subject of latches into two parts, Simple and PREV-
based. Except for exercise 1, this month’s article only looks at simple
latches. PREV-based latches feature next month in the second of this
two-part series.

A simple latch is binary in nature. This means that its result can only
have one of two states – usually zero or one. Other values can be
assigned, and I’ll show you how to do that with one of the exercises.
PREV-based latches are more flexible than their simple cousins. They
are not restricted to just two values and can store almost any value you
might wish. The disadvantage of PREV-based latches is large amount
the computer resources needed to drive the PREV function.

It’s important that you appreciate what the simple latch is a substitute
for, so I’m taking a moment to show you the code that first triggered
my search for a simple latch. The construction of a PREV-based latch
Figure 8. is examined in more detail next month. All you need to know for now
Exercise 1. Plotting a is that the code contains PREV, and it executes much more slowly for
PREV-based latch. that reason. An exploration that completes in 1 minute using the PREV

Page 13 January 2005 Page 13


latch in exercise 1 will run in 6 or 7 seconds once the PREV function is
eliminated. The actual latch is the unnamed PREV variable on the last
line of the exercise 1 code.

{Exercise 1} {PREV-based latch}


Set:=Cross(Mov(C,15,E),Mov(C,25,E));
Reset:=Cross(Mov(C,25,E),Mov(C,15,E));
If(Set,1,If(Reset,0,PREV));

Simple Latch Description

The basic form of a simple latch (binary flag) is shown in Exercise 2. It


requires two signals to function – a set and a reset signal. You could
think of these signals as the latch "on" and "off" buttons. I said last
month that ValueWhen() is about as close as MetaStock gets to a true
latch function. In ValueWhen() the "expression" parameter works as
both the set and reset signal. The stored value of ValueWhen() changes
each time the timing expression is true.

A simple latch operates by comparing the number of time periods that


have passed since the set and reset signals last occurred. From that Figure 9.
comparison using BarsSince() you can tell which of the two signals Bars since Set or Init (black), and
occurred last. The most recent signal determines the state of the latch. Bars since Reset or Init (red)
The number of bars that have passed since the signal is of no interest at
all. The only concern is whether the most recent signal was a set (latch
true) or a reset (latch false).

If the set signal occurred most recently the latch will be in the set (true)
state, and if the reset signal occurred most recently the latch will be in
the reset (false) state. MetaStock processes a chart from the first bar on
the left to the last bar on the right – from earliest to latest data. The
state of the latch is checked and updated as each new bar is processed,
moving from left to right across the chart or data series. The essence of
a simple latch is in deciding which of two events occurred most
recently. See Figure 9.

This article uses the crossover of two moving averages to create set
and reset signals for each exercise. These signals have no significance
other than that of creating generic set and reset signals.

{Exercise 2} {simple latch}


Set:=Cross(Mov(C,15,E),Mov(C,25,E));
Reset:=Cross(Mov(C,25,E),Mov(C,15,E));
{Did a set occur since a reset?}
BarsSince(Set)<BarsSince(Reset);
Figure 10.
The basic format of exercise 2 works fine up to a point, but it has one Exercise 2. Plotting the most
shortcoming. The output line (last line) may not plot a signal until basic form of a simple latch.
many bars after the start of a chart. The latch appears unable to plot a Note that the first cycle is
completely missing.
valid value when it would be reasonable to expect that it should. This
symptom is common with the ValueWhen() function too (among

Page 14 January 2005 Page 14


others). The reason in this case is that one of the BarsSince() functions
doesn’t get a trigger, and therefore it can’t plot a result either. An
invalid plot like this usually extends from the first bar of the chart until
the set signal goes active for the first time.

The set and reset signals both become valid on the same bar – the 26th.
The Cross() function adds another invalid bar to the 25 already forced
by the longer EMA. The total number may be much higher on some
charts. This latch won’t function until there has been a moving average
cross in both directions. One BarsSince() function will not be triggered
until the second cross takes place. The invalid plot for the latch extends
until that cross occurs.

This is where an "initializing" variable is so helpful. It tells us when


both set and reset signals are valid, and it generates a signal that’s used
to "kick-start" the latch. MetaStock 7.0 and later versions can make use
of the IsDefined() function to perform the same task, but this function
isn’t available to 6.52 users, and, quite frankly, it doesn’t provide any
advantage in this situation anyway.

The "Init" variable in exercise 3 is used to simulate initial set and reset
signals. These signals give a clear reference point from which the
BarsSince() functions in the latch can begin to operate. If you compare
plots between exercises 2 and 3 you’ll see that 3 has an N/A plot of
just 26 bars. Exercise 2, however, has an N/A plot that extends until
exercise 3 sets for the first time. An extended N/A plot may seem like
a minor detail, and sometimes that’s all it is. The real problem is that it
can make a sizable portion of data unavailable for testing, and thereby
fudge the data starting point and any test results. The use of an "Init"
variable in a simple latch has no downside that I’m aware of.

{Exercise 3} {simple latch with Init}


Set:=Cross(Mov(C,15,E),Mov(C,25,E));
Figure 11. Reset:=Cross(Mov(C,25,E),Mov(C,15,E));
Exercise 3. Plotting a simple
latch with an Init variable added.
Init:=Cum(Set+Reset>-1)=1;
Note where the plot starts Trade:=BarsSince(Init OR Set)<BarsSince(Init OR Reset);
relative to Figure 10. {Init simulates first set and reset}
Trade;

Notice that the OR logical operand in exercise 4 has been replaced by a


plus symbol (+). This is not a mistake. Any true (other than zero) is all
that’s needed for the logic to function exactly as required. "Init OR
Set" is logically the same as "Init+Set". The advantage of writing the
expression this way is a small space saving.

{Exercise 4} {Simple latch with Init}


Set:=Cross(Mov(C,15,E),Mov(C,25,E));
Reset:=Cross(Mov(C,25,E),Mov(C,15,E));
Init:=Cum(Set+Reset>-1)=1;
Trade:=BarsSince(Init+Set)<BarsSince(Init+Reset);
Trade;

Page 15 January 2005 Page 15


Review the
It’s always a good idea to name output variables, and this one is called
"Trade". The output variable is normally followed by code that needs
access to the state of the latch – to find out if it’s set or reset. Exercises
3 and 4 are examples of a binary latch, but they can only store one of examples and
two values. Typically those values are ONE and ZERO (true and
false). Other values can also be assigned, and the code showing you
grasp the
how to do that is given a little further on. underlying
The "Init" variable confuses many people, so don’t be alarmed if you principles.
don’t quite get it at first. It gives a TRUE spike on the bar when both
set and reset signals are first valid. It is only true for one bar, and false
for every subsequent bar. It does everything required it by being true
on that first valid bar. It remains invalid until both the set and reset
signals are valid. "Init" spikes true for one bar and simulates the initial
set and reset signals used to kick-start the latch. Each BarsSince()
function uses this simulated signal to start the bars-since count.

The construction of an "Init" signal is not about the actual values of the
signals it’s made from, but whether or not these signals are valid. The
sum of the two inputs, "Set" and "Reset", cannot be greater than –1
until both variables plot a valid value, i.e. "Set" and "Reset" are binary
signals. By definition, neither signal can ever be less than zero. The
test for a cumulative count of 1 ensures that this signal is only true for
the first valid bar, then false for every subsequent bar. That’s OK
because the whole purpose of "Init" is to generate a true only on the
initial bar. This signal being true for one bar tells us that the set and
reset signals are both now valid.

As I mentioned earlier, it’s possible to assign values other than one and
zero to a latch. The If() function can be used to alternate a latch output
between any two constant values.

{Exercise 5} {Simple latch with modified output}


Set:=Cross(Mov(C,15,E),Mov(C,25,E));
Reset:=Cross(Mov(C,25,E),Mov(C,15,E));
Init:=Cum(Set+Reset>-1)=1;
Trade:=If(BarsSince(Init+Set)<BarsSince(Init+Reset),3,-5);
Trade; {Swings between –3 and +5}

You also need to know that some ways of putting the "Trade" variable
together give bad results at the left side of a chart. Of the following
four latch constructions, only two are logically correct 100% of the
time. The first two are the correct versions.

{a} Trade:=If(BarsSince(Init+Set)<BarsSince(Init+Reset),1,0);
Is functionally identical to
{b} Trade:=If(BarsSince(Init+Set)>=BarsSince(Init+Reset),0,1); Figure 12.
An inverted initial plot caused by
Neither of the above examples are functionally the same as the use of "<="instead of "<"
{c} Trade:=If(BarsSince(Init+Set)> between the BarsSince() functions.
BarsSince(Init+Reset),0,1); {wrong}

Page 16 January 2005 Page 16


or
{d} Trade:=If(BarsSince(Init+Set)<=
BarsSince(Init+Reset),1,0); {wrong}

The difference is in the use of "=" with the ">" and "<" symbols. When
written incorrectly the polarity of the latch before the first set signal is
reversed (inverted). This may be only a small point, but for those
leading bars it is still wrong. Testing of historical data requires that
signals be as accurate as possible for all data in the test. Whatever you
use the simple latch for, take care to avoid these traps. The correct
construction when not using an If() function is demonstrated in {f} and
{g} as seen below.
Figure 13.
An inverted plot caused by the use {f} Trade:=BarsSince(Init+Set)<BarsSince(Init+Reset);
of ">="instead of "<" between the {g} Trade:=(BarsSince(Init+Set)>=BarsSince(Init+Reset))=0;
BarsSince() functions.
{h} Trade:=(BarsSince(Init+Set)>BarsSince(Init+Reset))=0; {wrong}
{i} Trade:=BarsSince(Init+Set)<=BarsSince(Init+Reset); {wrong}

Signal Timing for a Simple Latch

The timing charts, see below and Figure 14, are my attempt to show
the timing relationships between the different variables of a simple
latch. Exercise 6 can be used to show the same relationships on any
MetaStock chart. Obviously the signals are going to vary from chart to
chart, but the intrinsic relationships remain the same. A timing chart
like this is not unlike the stock or commodities chart that you are so
familiar with. Both plot a value in relation to time. Timing charts plot
binary values, and security charts plot prices.
__ _
_____/ \_____/\_______________/ \______ Set
__
N/A ___/\____________/ \________/\__ Reset

N/A \________________________________ Init


_________ ____
N/A _______/ \______/ \___ Trade

{Exercise 6} {signal timing for a simple latch}


Set:=Cross(Mov(C,15,E),Mov(C,25,E)); Set+3.75;
Reset:=Cross(Mov(C,25,E),Mov(C,15,E)); Reset+2.5;
Init:=Cum(Set+Reset>-1)=1; Init+1.25;
Figure 14. BarsSince(Init+Set)<BarsSince(Init+Reset);
A technique for troubleshooting
the relationships between binary In my opinion the simple latch is the most useful building block there
variables in a formula. is for MetaStock. Please take the time to become familiar with it. Next
month I’ll show you why a PREV-based latch is still an essential tool
in some circumstances.
†

Page 17 January 2005 Page 17


(Continued from page 12)

into a comment. You can then make changes to the original variable
and not worry about corrupting it. When you’re finished testing and
happy with the result you can restore the original code, or just delete it.

There’s no need to comment out the original variable, or the copy, as


long as it doesn’t refer to an earlier definition of the same variable
name. MetaStock regards the last definition of a variable as the only
valid one. This means that you can have several active definitions of
any variable, and know that only the final one is effective. Remove the
original definition only when you’re quite sure that the new version is
working correctly. The original variable may be redundant, but leaving
it in place for a while doesn’t do any harm.
†

PREMIUM DATA SERVICES


I f you are serious about getting the most from MetaStock, you will
need top quality data. Having bad data is worse than no data at all. I Bad data is worse
use Premium Data, available from Norgate Investor Services. than no data.
They provide premium quality end-of-day data suitable for MetaStock,
covering stock markets (ASX, SGX, Amex, NYSE, NASDAQ, OTC),
futures markets (80 contracts) and Forex (78 currency pairs). The data
is fully adjusted for all corporate actions such as consolidations, splits,
mergers, renames, code changes, and allows sophisticated groupings
such as industry, index participation and dividend-paying securities. A
free trial is available.

If you currently use another provider, let Norgate Investor Services


know and they'll give you a special offer. They really are worth your
consideration. [Link]
†

CUSTOM FORMULA SERVICES NEXT MONTH


Basics- Part 5
P ersonal trading system programming and testing, custom formula
writing for MetaStock and specialized data services are available
for AU$55/hr (US$40/hr, inc GST). Confidentiality and exclusivity
Latches - Part 2
guaranteed by Jose Silva. Explorations - Part 3
Questions & Answers
[Link] And More
†

Disclaimer: There are significant risks associated with securities trading. Nothing in this newsletter should be considered investment
advice, trading advice or recommendations as to investment management. I am not an investment advisor, and the information
provided in this newsletter is for educational purposes only. Each subscriber uses the information published in MetaStock Tips &
Tricks at their own discretion and bears all risk associated with the application of that information to their trading or investment
decisions. Nothing in this newsletter implies that any formula, method or strategy is in fact correct, or reliable in all circumstances.

Page 18 January 2005 Page 18

You might also like