| 
 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
 
 |