PureBytes Links
Trading Reference Links
|
{[Was: Re: Message pops up say can't divide by zero.}
Dans un courrier daté du 28/08/98 04:22:10 , vous avez écrit :
<< Robert,
This indicator was written by me about a year ago for an article in
Futures that discussed the Bollinger bands indicator (Nov. -97). It
normalizes the price to fluctuate around zero, with the upper
Bollingerband set to 100 and the lower band to -100, for easier
interpretation.
Alternative (and much better) code:
{Indicator name: $%B}
Input: Price(C), Length(18), SDev(2);
Vars: Upper(0), Lower(0), Where(0);
Upper = 100 * (Price - $Lowerband(Price, Length, SDev));
Lower = $Upperband(Price, Length, SDev) - $Lowerband(Price, Length,
SDev);
If Lower <> 0 Then
Where = ((Upper / Lower) - 50) * 2;
Plot1(Where, "Where");
Plot2(100,"Upper");
Plot3(-100,"Lower");
{Function name: $Lowerband}
Input: Price(NumericSeries),Length(NumericSimple),SDev(NumericSimple);
$Lowerband = Average(Price, Length) - StdDev(Price, Length) * SDev
{Function name: $Upperband}
Input: Price(NumericSeries),Length(NumericSimple),SDev(NumericSimple);
$Upperband = Average(Price, Length) + StdDev(Price, Length) * SDev
Thomas Stridsman
Futures magazine
>>
So, this is interesting.
First, the B% oscillator is a very appealing one that I sometimes use
(filtered) as an input to some AI program that I do not want to shameless
fuzzy self promote here.
Thomas Stridsman's B% implementation above is correct, and the -100 +100
rescaling produces a better reading because recentering around 0.
In this sense, it behaves like Lambert's CCI, rather than Wilder's RSI.
The point that I want to highlight here is the obvious need to learn to
simplify the code, in a general manner, and not only this ne that I take as an
example.
I could have done this one many others posted here, but this one covers
interesting simplification possibilities.
Suppose that you want to use %B in a system and run te TS optimiser, the
fastest code will produce the fastest optimisation.
For sake of clarity , I'll code the indicator above with the original TS
functions:
STEP0:
{Indicator name: $%B}
Input: Price(C), Length(18), SDev(2);
Vars: Upper(0), Lower(0), Where(0);
Upper = 100 * (Price -BollingerBand(Price, Length, -SDev));
Lower =BollingerBand(Price, Length, SDev) -BollingerBand(Price, Length,-SDev);
If Lower <> 0 Then
Where = ((Upper / Lower) -50) * 2;
Plot1(Where, "Where");
Plot2(100,"Upper");
Plot3(-100,"Lower");
plot4(value0,"BB1");
[
The only difference is that we use the same TS function for Bollinger bands,
but it do not simplify yet anything.
Inputs: Price(NumericSeries), Length(NumericSimple), SDev(NumericSimple) ;
BollingerBand = Average(Price,Length) + (SDev * StdDev(Price,Length)) ;
]
STEP1:
______
A close examination of $B% shows that we use this BollingerBand function
three times.
So we call three times the same code that also contains the same sub EL user
functions:
-StdDev
-Average.
(Used also three time in the BollingerBand code and a fourth in the $B% code
for the average).
STEP2 : Simplifying for the StdDev multiple case:
_________________________________________
This is why I had said that understanding ALL of the EL functions is so
important.
BBands are calculated from an average with STddev added or substracted from
the average (using a coefficient, usually 2).
So, calling a code with several BBands to produce a single result can be
simplified:
I'll put this directly to an user fuction BB1 that you will be able to call.
This do not simplify by itself, but the code of the UF is now simplified, and
you will see later why I use an user function (BB1, below).
==================================================
input:price(numericseries), length(numeric), coeff(numeric);
value1=average(price,length); {<========= light bulb must flash here}
value2=stddev(price,length); {<========= light bulb must flash here}
value3=value1-coeff*value2;
if value2<>0 then begin
BB1=100*(price-value3)/(coeff*value2)-100;
end;
==================================================
If you call BB1 from an indicator, it will produce the same result than the
$B% original indicator code.
But it uses only :
One StdDev instance instead of 3, so it will run faster
STEP3
_______
There is better to do.
Knowing and understandind all the functions is important,and the glaring proof
is below.
We just spare 2 StdDev function in step2.
We could have been to evaluate this improvement by knowing was was StdDev
doing.
So, let's open the StdDev code:
==================================================
inputs : Price(NumericSeries),Length(NumericSimple);
vars : SumSqr(0),Avg(0),Counter(0);
if Length <> 0
then begin
Avg = Average(Price,Length); {<========= light bulb must flash here}
SumSqr = 0;
for counter = 0 to Length - 1
begin
SumSqr = SumSqr + (Price[counter]-Avg) * (Price[counter]-Avg);
end;
StdDev = SquareRoot(SumSqr / Length);
end
else
StdDev = 0;
==================================================
What could we see here ?
Surprise: we use the same average calculation than in the original code
(already calculated).
We need to modify the User function to make it run faster, by avoiding the
twin average calculation:
First, we will use the StdDev code directly in the user function, then apply
it to BB1 (becomes BB2)
Then perform some basic maths to get the simplest way to calculate BB2
(below). Et voilà.
==================================================
input:price(numericseries), length(numeric), coeff(numeric);
vars : SumSqr(0),Avg(0),Counter(0),xstddev(0);
if Length <> 0
then begin
Avg = Average(Price,Length);
SumSqr = 0;
for counter = 0 to Length - 1
begin
SumSqr = SumSqr + (Price[counter]-Avg) * (Price[counter]-Avg);
end;
xStdDev = SquareRoot(SumSqr / Length);
end
else
xStdDev = 0;
if XstdDev<>0 then begin
BB2=100*(price-Avg+coeff*xStdDev)/(coeff*xStdDev)-100;
end;
==================================================
BB2 calls now only one average instead of 2 and distracts it to its profit
from the Stddev code.
This one will run now faster than BB1.
STEP4:Conclusion.
________________
No need to be a genius to understand this.
It's only knowkledge and knowing what we do when coding.
TS is a good program that can be enhanced, but the user can also enhance it
with some homework.
In fact, I have made unnecessary steps to me.
My first tought would to remove the average from the redundant hidden Stddev
directly because I already knew that this function used the same Average
function than the one used for the center of Bollinger band.
So, I would have directly jumped to step3.
I explained the steps in detail for those who are not familiar with the
concept.
If solving this king of problem is of interest to you, you can subscribe to TS
Express that posts a similar problem to the readers in almost every issue. The
complete collection is a gold mine for people wanting to shorten their EL
code,and an excellent exercise to try to solve the problem posted (you cannot
better learn than by suffering during the search phase).
I also propose a yearly and expensive unlimited EL support addressing any
kind of question regarding to TradeStation programming.
More details on my (well known as) self promoted web site.
(If someone do not know it, please drop an E-Mail to:
http://www.sirtrade.com, and I'll give you back the URL of my web site).
Link to TS Express is also available there.
Sincerely,
-Pierre Orphelin
|