PureBytes Links
Trading Reference Links
|
At 7:53 PM -0500 12/19/98, David Wieringa wrote:
<SNIP>
>...that is why I asked about whether functions were executed on every bar,
>regardless of whether they were called.
<SNIP>
>I can't find any documentation to warn about these gotcha's.
------
You have indeed discovered one of the poorly documented "features" of
EasyLanguage. Every few months this question comes up. Below is a couple of
my previous posts on the subject.
If you look in the "Open" dialog box in the PowerEditor, you will see that
the "CloseD" function is a "Simple" function so that it need to be called
once per bar to work properly.
Bob Fulks
--------
Resent-Date: Sat, 8 Aug 1998 04:22:54 -0700
X-Sender: bfulks@xxxxxxx
Mime-Version: 1.0
Date: Sat, 8 Aug 1998 07:22:56 -0400
To: Peter Ryan <pryan@xxxxxxxxxxxxxx>
From: Bob Fulks <bfulks@xxxxxxxxxxxx>
Subject: Re: problems with EL function calls
Cc: "'omega-list@xxxxxxxxxx'" <omega-list@xxxxxxxxxx>
Resent-From: omega-list@xxxxxxxxxx
X-Mailing-List: <omega-list@xxxxxxxxxx> archive/latest/21628
X-Loop: omega-list@xxxxxxxxxx
Precedence: list
Resent-Sender: omega-list-request@xxxxxxxxxx
At 5:51 AM -0400 8/8/98, Peter Ryan wrote:
>On many occasions while calling functions i have written myself, I get an
>error message
> "arrays and variables are not allowed here".
>
>Typically this happens when I do something like:
>val = FastK(length)
>funcval = myfunc(val)
>
>I have to correct it to:
>funcval = myfunc(FastK(length))
>
>Can someone explain to me why this is, and what options I have to avoid it.
>It drives me mad.
You have discovered one of the hidden mysteries of EasyLanguage.
There are two kinds of functions, "series" functions and "simple"
functions. Look at the "Properties" dialog when you are writing a function
and it allows you to specify which you want.
You will notice that the function library often has both versions for many
common functions (such as "Average"). (Look at the code for these to see
the differences.)
Series functions are functions that refer to previous values of a variable
such as:
Value1 = Price[1] {Price[1] refers to the value of Price on bar back}
These are actually evaluated on every bar, even if your code doesn't
require the value on every bar, so that it can keep the "Price[1]"
calculation correct. As a result, these functions may not contain variables
as inputs since the system doesn't necessarily know the values of those
variables on every bar.
Simple functions can have variables as inputs but they cannot refer to the
previous value of a variable with the "Variable[1]" notation. If the
function requires a previous value of a variable, you must explicitly save
it in some other variable.
A more complete discussion of this was posted a while back and I will
attach it below.
Bob Fulks
-------------------
At 6:52 PM -0500 3/15/98, Cab Vinton wrote:
>Does anyone have a real live _example_ of code where the series/ simple
>distinction makes a difference? (Maybe of code with a simple function
>that is _not_ evaluated on every bar?)
>
>That would help no end for those of us without extensive programming
>backgrounds.
Here is another example. It is the XAverage function.
The Omega version is shown first. It refers to a previous value of XAverage
as "XAverage[1]". Thus, the system knows this is a series function.
(Functions which refer to a previous value using the brackets force the
function to be series type.)
As Mark Jurik stated, the series function will be evaluated on every bar
automatically to assure that the value "XAverage[1]" is always correct. The
downside is that you cannot use a variable for the "Price" input to the
function. It has to be a data series. This is sometimes inconvenient.
The second version is a rewrite as a simple function. Here, instead of
referring to "XAverage[1]", I saved the last value of XAverage as the
variable "XLast". This eliminated the need to reference the previous value
so I could make this a simple function.
Now, I can use a variable as the "Price" input to the function. The
downside is that the function has to be called on every bar. If it is not,
the value of XLast will not be the value on the last bar, but will be THE
VALUE ON THE LAST BAR ON WHICH THE FUNCTION WAS EVALUATED. This means you
cannot include this function in a conditional expression that might prevent
it from being evaluated on every bar.
In addition, as noted in my post of 3/11/98, you should not include a
simple function in a complex comparison expression such as:
Condition1 = A > B and XAverage.V(M,50) < N;
since if the first comparison
A > B
is not true, then the second expression
XAverage.V(M,50) < N
will not be evaluated on that bar so the function will return the wrong
value on future bars.
Bob Fulks
{ *******************************************************************
Study : XAverage
Last Edit : 7/7/95
Provided By : Omega Research, Inc. (c) Copyright 1995
********************************************************************}
inputs : Price(NumericSeries),Length(NumericSimple);
vars : Factor(0);
if Length + 1 <> 0
then begin
if CurrentBar <= 1
then begin
Factor = 2 / (Length + 1);
XAverage = Price;
end
else
XAverage = Factor * Price + (1 - Factor) * XAverage[1];
end;
{ *******************************************************************
Study : XAverage.V
Last Edit : 11/2/96
Provided By : Bob Fulks
Description : This is a recoding of the XAverage function as a
"simple function" rather than as a "series function". For
correct results it must be evaluated on every bar, as is
normal for Omega simple functions.
********************************************************************}
inputs : Price(NumericSeries), Length(NumericSimple);
vars : Factor(0), XLast(0);
if Length + 1 <> 0
then begin
if CurrentBar <= 1
then begin
Factor = 2 / (Length + 1);
XAverage.V = Price;
XLast = Price;
end
else begin
Value1 = Factor * Price + (1 - Factor) * XLast;
XAverage.V = Value1;
XLast = Value1;
end;
end;
|