Rank: Advanced Member
Groups: Registered, Registered Users, Subscribers, Unverified Users Joined: 10/28/2004(UTC) Posts: 3,111 Location: Perth, Western Australia
Was thanked: 16 time(s) in 16 post(s)
|
From Roys Latches article that used to posted around here somewhere?.......
Roy wrote:Latches
Using latches in MetaStock (or flags as I prefer to call them) is a simple and convenient way of remembering code conditions or events. This document is an attempt to explain the various constructions and uses of latches as they relate to ‘Trade equity’ and ‘Trade Stop’, but it by no means covers all there is to write on the subject.
A ‘latch’ is a device that stores and holds, or remembers, a particular event or condition. A ‘binary latch’ can be set to one of two values (normally zero and one but not necessarily so), while a ‘price latch’ can be set to virtually any value one could think of. Each type has both advantages and disadvantages that will be mentioned as appropriate.
In the following discussion please note that ‘one’ is interchangeable with ‘true’ or ‘on’, and ‘zero’ with ‘false’ or ‘off’. You may wonder why I do not write a line such as -
“ N:=Fml("set signal"); ” as
“ N:=Fml("set signal")=1; ”.
The reason is that MS “assumes” that I am referring to the “true” condition of that binary variable, and so adding “=1” is redundant. Only if I am looking for a “false” condition do I need to specify the state by adding “=0”. I should also need to point out that MetaStock does not know the difference between a ‘price’ variable and a ‘binary’ variable. For example it will treat a ‘price’ variable of 0.99c as a binary zero unless your coding makes it clear as to how the variable should be treated. In the same manner a ‘price’ variable of $1.00 or higher will be treated as a binary one unless your coding clarifies the intended usage.
Binary Latch Description
Example 1 presents the simplest form of a latch. It requires two signals to operate – a ‘set’ signal, and a ‘reset’ signal. You could think of these signals as the latch ‘on’ switch and the ‘off’ switch. By using the BarsSince() function we are able to decide which signal occurred most recently, and therefore whether the current state of the latch should be ‘on’ or ‘off’. MetaStock processes a chart from the first bar on the left to the last bar on the right. This means that the latch condition is checked and updated as each new bar is processed from left to right.
{Example 1}
N:=Fml("set signal");
X:=Fml("reset signal");
BarsSince(N)<BarsSince(X);
One problem to be addressed with this simple code is that the output line (using BarsSince) can have an extended invalid signal period. In other words it will return a value of N/A instead of a legitimate value. This N/A period will extend from the first bar on the chart until the ‘set’ signal is true and the ‘reset’ signal is valid. This extended N/A can be addressed by adding an ‘initialized’ variable into the output line. I normally name this variable ‘I’, and its purpose is to inform any code following ‘N’ and ‘X’ that the set and reset signals are valid – i.e. are not returning N/A. In this latch configuration it also serves to create ‘fake’ set and reset signals that provide a specific starting point (bar) for the latch.
It is also convenient to name the output line variable because additional code usually follows. Example 2 is a complete binary latch and as such it can store only two values – zero and one.
{Example 2}
N:=Fml("set signal");
X:=Fml("reset signal");
I:=Cum(N+X>-1)=1;
Tr:=BarsSince(I OR N)<BarsSince(I OR X);
Tr;
The ‘I’ variable confuses many people. It will be ‘true’ (or one) for the first bar when both set and reset signals are valid, and ‘false’ (zero) for every bar thereafter. Until both set and reset signals are valid it also will be invalid and return a value of N/A. ‘I’ being true for one bar provides the ‘fake’ set and reset signals used to kick the latch into action.
Notice that the construction if ‘I’ is not concerned with actual values, but whether or not ‘N’ and ‘X’ are VALID. The sum of the two inputs (‘N’ and ‘X’) cannot be tested as being greater than –1 until both return a value of at least zero once both are valid. Since ‘N’ and ‘X’ are binary signals (zero or one), by definition they will never be less than zero. The Cum() count equal to one ensures that this signal is true for the first valid bar only, and false for every bar after that. That’s OK because its whole purpose is generate a ‘true’ for just the one initial bar.
It is possible to assign values other than zero and one to the latch output, but be aware that this latch can’t be used to store prices. The reason is that multiple set signals will allow the stored price to change. However the If() function can be used to select the two values that that latch can swing between.
{Example 3}
N:=Fml("set signal");
X:=Fml("reset signal");
I:=Cum(N+X>-1)=1;
Tr:=If(BarsSince(I OR N)<BarsSince(I OR X),1,0);
Tr;
Now that we are able to assign different values to the ‘Tr’ variable one needs to be aware that not all methods of making ‘Tr’ are equal.
Tr:=If(BarsSince(I OR N)<BarsSince(I OR X),1,0);
Is functionally identical to
Tr:=If(BarsSince(I OR N)>=BarsSince(I OR X),0,1);
But neither is the same as
Tr:=If(BarsSince(I OR N)>BarsSince(I OR X),0,1);
The difference is in the use of “=” with “>” or “<” symbols. Written the wrong way the section of the flag prior to the first ‘set’ signal will be the inverse of its proper state. This may be only a small point but to my mind it is still the difference between right and wrong. The testing of historical data demands that our test signals are accurate for ALL data under test so please take care with this potential trap.
Typical Signal Timing for Binary Latch.
High is ‘one’, low is ‘zero’,
__ _
__/ \\_____/\\_______________/ \\__ set (N)
__
N/A ___/\\____________/ \\________ reset (X)
N/A \\____________________________ Initialization (I)
_________ ____
N/A _______/ \\______/ latch state (Tr)
Price Latch Description
A PREV version of the humble latch offers more options for MS coding because it can “remember” a user determined value. This value can then be accessed from within the latch (by using the PREV function) to manage a number of resets that can be related to the ‘set’ signal or timing. The one major down side to using PREV is that it is resource hungry and it will significantly slow the execution time of any code using it. Each additional PREV further increases the resource burden.
{Example 4}
N:=Fml("set signal");
X:=Fml("reset signal");
Tr:=If(N,1,If(X,0,PREV));
Tr;
Example 4 is the simplest form of a PREV based latch, and here it is still being used to give a binary result because it has no way of discriminating between the first and subsequent ‘set’ signals. By checking the previous state of ‘Tr’ (using PREV) we can ensure that only the FIRST bar of the entry signal is used to decide what value to store in the latch. Notice that the ‘I’ variable is not used in this latch. It is not needed to provide a starting point once PREV is introduced, and neither is there any problem, other than a lack of skill, in setting the correct polarity of the output signal ‘Tr’.
I suggest that all PREV variables be named, and this is particularly important when is used in what is effectively the output line – I have had some unpredictable results when using PREV as an unnamed output line.
{Example 5}
N:=Fml("set signal");
X:=Fml("reset signal");
Tr:=If(PREV=0,If(N,CLOSE,0),If(X,0,PREV));
Tr;
... to be continue
|