PureBytes Links
Trading Reference Links
|
Greetings all – particularly Chuck –
Here is a version that handles Exponential Moving Averages.
If any of you find good uses for this technique, please feel
free to
let us all know about them.<span
>
If there are other functions that would be valuable to
compute
<span
>crossover<font
size=2 face=Arial> or prediction
points for, let me know.
Thanks,
Howard
//================================================
//
// Solve
EMA Cross Point
//
// Howard
Bandy
// <st1:date
Month="1" Day="29" Year="2004">January 29, 2004<font
size=2 face=Arial>
//
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// <span
class=GramE>This code is a variation of "Solve MA Cross
Point".
// <span
class=GramE>In that version, the moving averages were Simple.
// <span
class=GramE>In this version, the moving averages are Exponential.
//
// <span
class=GramE>Some background for those who have forgotten:
// EMA
needs only the previous value of the EMA,
// the
"alpha" value, and the next data point.
// <span
class=GramE>EMA(i) = alpha * Close(<span
class=SpellE>i) + (1 - alpha) * EMA(i-1)
//
// alpha
= 2 / (N + 1), where N is the number of days
// in
the average.
//
// In
our case, we want EMA(i+1), which is
// alpha
* Close(i+1) + (1-alpha) * EMA(i),
// where
the Close(i+1) is varied until we find
// values
that converge.
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
//
// Load
this routine into Indicator Builder and
// apply
it to any bar chart.
//
// <span
class=GramE>This routine uses a binary search to compute
// the
value of the close
// of
the next bar such that two simple moving
// averages
will cross.
//
// It
plots the price necessary and the change
// from
the most recent close.
//
// If
MA1Length is shorter than MA2Length,
// then
MA1 is the faster moving average.
// MA1
is plotted as a Blue line.
// MA2
is plotted as a Green line.
//
// <span
class=GramE>The computed price is plotted as a Red line.
// <span
class=GramE>The change from today's close to the
// computed
price is plotted as a Yellow line.
//
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// In
order to use this technique, you must be
// able
to compute the indicator you want to evaluate
// for
a variety of trial values for the next bar.
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// <span
class=GramE>This example makes use of the fact that the
// new
simple moving average is computed by
// dropping
off the oldest value and picking up the
// newest
value.
//
MA1Length = 3;
MA2Length = 10;
Longest = Max(MA1Length,MA2Length);
Alpha1 = 2/(MA1Length+1);
Alpha2 = 2/(MA2Length+1);
MA1 = EMA(C,MA1Length);
MA2 = EMA(C,MA2Length);
// <span
class=GramE>Establish initial values for the search.
// <span
class=GramE>Since the movign average will
cross over at
// only
one point, we only need to be sure that
// one
startinging value is too high (above the
// crossover
point) and the other starting value
// is
too low (below the crossover point).
<span
>MinC<font
size=2 face=Arial> = 0.1 * C;
<span
>MaxC<font
size=2 face=Arial> = 10.0 * C;
// Note
on computational implications --
// <span
class=GramE>Assume the stock being processed has a Close
// of
$50.00. MaxC
starts at $500.00, MinC at $5.00.
// <span
class=GramE>The range being searched is $495.00.<span
> The search stops
// <span
class=SpellE>HighC and LowC are within
$0.005. The ratio of $495.00
// to
$0.005 is 100000 to 1. Each search
step cuts the range
// in
half. So it will take about 17
steps to converge -- that
// is
17 passes through the While loop for each bar in the
// range
being processed.
// If
MinC starts at 0.5 * C and MaxC
starts at 2.0 * C,
// the
search is cut to 14 passes through the While loop.
// If
MinC and MaxC are 0.9 * C
and 1.1 * C, 11 passes.
// <span
class=GramE>Increasing the stopping citerion
from 0.005 to 0.02
// cuts
2 passes off for any MinC and MaxC.
//
// All
that is necessary is that MinC and <span
class=SpellE>MaxC bracket the
// solution.<span
> In some cases, it might be advantageous
to use
// a
short routine that does not go through the
// entire
While loop can be used to pick MinC and <span
class=SpellE>MaxC close
// together,
but with different signs for the "Difference".
//
// <span
class=GramE>Declare the variables and initialize them
MA1atCP1 = C; //<span
> MA1
at Ref(MA1,+1) using trial value of Close.
MA2atCP1 = C; //<span
> MA2
at Ref(MA2,+1) using trial value of Close.
<span
>MidC<font
size=2 face=Arial> = C;<span
> //<span
> Next
trial value of Close.
<span
>ChgReq<font
size=2 face=Arial> = 0;<span
> //<span
> Change
in Close required for Crossover.
// Of
course, if we could use Ref(MA1,1), there would be no
need
// for
all this. The difficulty is that we
want to repeatedly
// change
the value of the final element until we determine
// the
solution to the crossover.
// Loop
through all the bars
<span
>for<font
size=2 face=Arial> (<span
class=SpellE>i=Longest; i<<span
class=SpellE>BarCount; i++)
{
//<span
> Initialize
the Low test value and compute the indicators
<span
class=SpellE>LowC[i] = MinC[<span
class=SpellE>i];
<span
class=GramE>MA1atCP1[i] = (Alpha1*<span
class=SpellE>LowC[i]) + (1-Alpha1) * MA1[i-1];
<span
class=GramE>MA2atCP1[i] = (Alpha2*<span
class=SpellE>LowC[i]) + (1-Alpha2) * MA2[i-1];
<span
class=SpellE>DiffLowC[i] = MA1atCP1[<span
class=SpellE>i] - MA2atCP1[i];
//<span
> Initialize
the High test value and compute the indicators
<span
class=SpellE>HighC[i] = MaxC[<span
class=SpellE>i];
<span
class=GramE>MA1atCP1[i] = (Alpha1*<span
class=SpellE>HighC[i]) + (1-Alpha1) *
MA1[i-1];
<span
class=GramE>MA2atCP1[i] = (Alpha2*<span
class=SpellE>HighC[i]) + (1-Alpha2) *
MA2[i-1];
<span
class=SpellE>DiffHighC[i] = MA1atCP1[<span
class=SpellE>i] - MA2atCP1[i];
//<span
> Test
to see if the two indicators have converged.
//<span
> <span
class=GramE>They probably have not yet, but we need a value
//<span
> at
the first test of the loop.
Difference[<span
class=SpellE>i] = abs(DiffLowC[<span
class=SpellE>i] - DiffHighC[<span
class=SpellE>i]);
//<span
> Stay
in the search loop until the upper limit price
//<span
> and
lower limit price are within 0.005 (one half cent in US)
<span
class=GramE>while (Difference[i] > 0.005)
{
//<span
> Pick
the midpoint of LowC and HighC
to test next.
<span
class=SpellE>MidC[i] = (LowC[<span
class=SpellE>i] + HighC[i])
/ 2;
//<span
> <span
class=GramE>And compute the indicators
<span
class=GramE>MA1atCP1[i] = (Alpha1*<span
class=SpellE>MidC[i]) + (1-Alpha1) * MA1[i-1];
<span
class=GramE>MA2atCP1[i] = (Alpha2*<span
class=SpellE>MidC[i]) + (1-Alpha2) * MA2[i-1];
<span
class=SpellE>DiffMidC[i] = MA1atCP1[<span
class=SpellE>i] - MA2atCP1[i];
//<span
> <span
class=GramE>Using the signs of the differences,
//<span
> decide
whether to replace the high test point
//<span
> or
the low test point by the new Middle test point
<span
class=SpellE>SignMid[i] = DiffMidC[<span
class=SpellE>i] > 0.0;
<span
class=SpellE>SignLow[i] = DiffLowC[<span
class=SpellE>i] > 0.0;
<span
class=GramE>if (SignMid[i]
== SignLow[i])
{
//<span
> <span
class=GramE>The sign of the difference at the LowC
point and at the
//<span
> <span
class=SpellE>MidC point are the same.<span
> That means LowC
and MidC are on
//<span
> the
same side of the crossover point we are looking for,
//<span
> but
MidC is closer.
//<span
> <span
class=GramE>So, replace Low with Middle
<span
class=SpellE>LowC[i] = MidC[<span
class=SpellE>i];
<span
class=GramE>MA1atCP1[i] = (Alpha1*<span
class=SpellE>LowC[i]) + (1-Alpha1) * MA1[i-1];
<span
class=GramE>MA2atCP1[i] = (Alpha2*<span
class=SpellE>LowC[i]) + (1-Alpha2) * MA2[i-1];
<span
class=SpellE>DiffLowC[i] = MA1atCP1[<span
class=SpellE>i] - MA2atCP1[i];
}
<span
class=GramE>else
{
//<span
> Replace
High with Middle
<span
class=SpellE>HighC[i] = MidC[<span
class=SpellE>i];
<span
class=GramE>MA1atCP1[i] = (Alpha1*<span
class=SpellE>HighC[i]) + (1-Alpha1) *
MA1[i-1];
<span
class=GramE>MA2atCP1[i] = (Alpha2*<span
class=SpellE>HighC[i]) + (1-Alpha2) *
MA2[i-1];
<span
class=SpellE>DiffHighC[i] = MA1atCP1[<span
class=SpellE>i] - MA2atCP1[i];
}<span
> //<span
> if-else
//<span
> One
of DiffLowC or DiffHighC
has changed as the
//<span
> search
range has tightened, the other
//<span
> remains
as it was on the last pass through the loop.
//<span
> Compute
the new difference between the two.
Difference[<span
class=SpellE>i] = abs(DiffLowC[<span
class=SpellE>i] - DiffHighC[<span
class=SpellE>i]);
}<span
> //<span
> while
//<span
> <span
class=GramE>After the loop, the value of MidC
is the value
//<span
> at
which the curves will cross
<span
class=SpellE>MidC[i] = (LowC[<span
class=SpellE>i] + HighC[i])/2;
//<span
> Limit
MidC so that it plots reasonably
<span
class=SpellE>MidC[i] = <span
class=GramE>IIf(MidC[<span
class=SpellE>i]>1.25*C[i],1.25*C[<span
class=SpellE>i], MidC[i]);
<span
class=SpellE>MidC[i] = <span
class=GramE>IIf(MidC[<span
class=SpellE>i]<0.80*C[i],0.80*C[<span
class=SpellE>i], MidC[i]);
//<span
> Compute
the change required from the most recent
//<span
> Close
to the next Close if crossover is to happen.
<span
class=SpellE>ChgReq[i] = MidC[<span
class=SpellE>i] - C[i];
} //<span
> for
// Plot
Close, MA1, MA2, and Computed Cross Point
Plot(C,"C",colorBlack,styleCandle);
<span
>Plot(<font
size=2 face=Arial>EMA(C,MA1Length),"EMA1",colorBlue,styleLine);
<span
>Plot(<font
size=2 face=Arial>EMA(C,MA2Length),"EMA2",colorGreen,styleLine);
<span
>Plot(<span
class=SpellE>MidC,"Computed<span
> Cross",colorRed,styleLine);
// Plot
Change Required to Cross
<span
>Plot(<span
class=SpellE>ChgReq,"Change<span
> Required",colorYellow,styleDots|styleLeftAxisScale);
<span
>Plot(<font
size=2 face=Arial>0.0,"",colorYellow,styleLine|styleLeftAxisScale);
Send BUG REPORTS to bugs@xxxxxxxxxxxxx
Send SUGGESTIONS to suggest@xxxxxxxxxxxxx
-----------------------------------------
Post AmiQuote-related messages ONLY to: amiquote@xxxxxxxxxxxxxxx
(Web page: http://groups.yahoo.com/group/amiquote/messages/)
--------------------------------------------
Check group FAQ at: http://groups.yahoo.com/group/amibroker/files/groupfaq.html
Yahoo! Groups Sponsor
ADVERTISEMENT
Yahoo! Groups Links
To visit your group on the web, go to:http://groups.yahoo.com/group/amibroker/
To unsubscribe from this group, send an email to:amibroker-unsubscribe@xxxxxxxxxxxxxxx
Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.574 / Virus Database: 364 - Release Date: 1/29/2004
|