PureBytes Links
Trading Reference Links
|
Hi Howard,
Thanks for the code and extra documentation
effort.
Do you think it's applicable to a scenario
where I:
a) buy when a symbol's 50-day MA
crosses above its 200-day MA
b) short when a symbol's 50-day
MA crosses below its 200-day MA
?
If so, I am not clear how to put in my values and
then backtest the scenario.
Any guidance will be appreciated.
thanks,
-john
<BLOCKQUOTE dir=ltr
>
----- Original Message -----
<DIV
>From:
howard
bandy
To: <A title=amibroker@xxxxxxxxxxxxxxx
href="">amibroker@xxxxxxxxxxxxxxx
Cc: <A title=howardbandy@xxxxxxxxx
href="">howardbandy@xxxxxxxxx
Sent: Thursday, January 29, 2004 7:46
PM
Subject: [amibroker] Search Routine for
Crossover Point
<SPAN
>Greetings
–
<SPAN
>
<SPAN
>Included in this message is <SPAN
class=SpellE>afl code which determines the
price at which two simple moving averages will
crossover.
<SPAN
>
<SPAN
>Thanks,
<SPAN
>Howard
<SPAN
>
<SPAN
>//==============================================
<SPAN
>//<SPAN
>
Solve MA Cross Point
<SPAN
>//
<SPAN
>//<SPAN
>
Howard Bandy
<SPAN
>//<SPAN
>
<FONT face=Arial
size=2>January 29,
2004<SPAN
>
<SPAN
>//
<SPAN
>//<SPAN
>
Load this routine into Indicator Builder
and
<SPAN
>//<SPAN
>
apply it to any bar chart.
<SPAN
>//
<SPAN
>//<SPAN
>
This routine uses a binary search to
compute
<SPAN
>//<SPAN
>
the value of the close
<SPAN
>//<SPAN
>
of the next bar such that two simple moving
<SPAN
>//<SPAN
>
averages will cross.
<SPAN
>//
<SPAN
>//<SPAN
>
It plots the price necessary and the change
<SPAN
>//<SPAN
>
from the most recent close.
<SPAN
>//
<SPAN
>//<SPAN
>
If MA1Length is shorter than MA2Length,
<SPAN
>//<SPAN
>
then MA1 is the faster moving average.
<SPAN
>//<SPAN
>
MA1 is plotted as a Blue line.
<SPAN
>//<SPAN
>
MA2 is plotted as a Green line.
<SPAN
>//
<SPAN
>//<SPAN
>
The computed price is plotted as a Red
line.
<SPAN
>//<SPAN
>
The change from today's close to
the
<SPAN
>//<SPAN
>
computed price is plotted as a Yellow
line.
<SPAN
>//
<SPAN
>//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<SPAN
>//<SPAN
>
In order to use this technique, you must
be
<SPAN
>//<SPAN
>
able to compute the indicator you want to
evaluate
<SPAN
>//<SPAN
>
for a variety of trial values for the next
bar.
<SPAN
>//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
<SPAN
>//
<SPAN
>//<SPAN
>
This example makes use of the fact that
the
<SPAN
>//<SPAN
>
new simple moving average is computed by
<SPAN
>//<SPAN
>
dropping off the oldest value and picking up the
<SPAN
>//<SPAN
>
newest value.
<SPAN
>//
<SPAN
>
<SPAN
>MA1Length =
3;
<SPAN
>MA2Length =
10;
<SPAN
>Longest = <SPAN
class=GramE>Max(MA1Length,MA2Length);
<SPAN
>
<SPAN
>MA1 = MA(C<SPAN
class=GramE>,MA1Length);
<SPAN
>MA2 = MA(C<SPAN
class=GramE>,MA2Length);
<SPAN
>
<SPAN
>//<SPAN
>
Establish initial values for the
search.
<SPAN
>//<SPAN
>
Since the movign
average will cross over at
<SPAN
>//<SPAN
>
only one point, we only need to be sure
that
<SPAN
>//<SPAN
>
one startinging value is too high (above the
<SPAN
>//<SPAN
>
crossover point) and the other starting value
<SPAN
>//<SPAN
>
is too low (below the crossover point).
<SPAN
>
<SPAN
>MinC<FONT
face=Arial size=2> = 0.1 *
C;
<SPAN
>MaxC<FONT
face=Arial size=2> = 10.0 *
C;
<SPAN
>
<SPAN
>//<SPAN
>
Note on computational implications --
<SPAN
>//<SPAN
>
Assume the stock being processed has a Close
<SPAN
>//<SPAN
>
of $50.00. <SPAN
class=SpellE>MaxC starts at $500.00, MinC at
$5.00.
<SPAN
>//<SPAN
>
The range being searched is $495.00.<SPAN
> The search
stops
<SPAN
>//<SPAN
>
HighC and LowC are
within $0.005. The ratio of
$495.00
<SPAN
>//<SPAN
>
to $0.005 is 100000 to 1.
Each search step cuts the range
<SPAN
>//<SPAN
>
in half. So it will take
about 17 steps to converge -- that
<SPAN
>//<SPAN
>
is 17 passes through the While loop for each bar in
the
<SPAN
>//<SPAN
>
range being processed.
<SPAN
>//<SPAN
>
If MinC starts at 0.5 * C and <SPAN
class=SpellE>MaxC starts at 2.0 * C,
<SPAN
>//<SPAN
>
the search is cut to 14 passes through the While
loop.
<SPAN
>//<SPAN
>
If MinC and MaxC
are 0.9 * C and 1.1 * C, 11 passes.
<SPAN
>//<SPAN
>
Increasing the stopping <SPAN
class=SpellE>citerion from 0.005 to 0.02
<SPAN
>//<SPAN
>
cuts 2 passes off for any MinC and <SPAN
class=SpellE>MaxC.
<SPAN
>//<SPAN
>
<SPAN
>//<SPAN
>
All that is necessary is that MinC and <SPAN
class=SpellE>MaxC bracket the
<SPAN
>//<SPAN
>
solution. In some cases,
it might be advantageous to use
<SPAN
>//<SPAN
>
a short routine that does not go through
the
<SPAN
>//<SPAN
>
entire While loop can be used to pick MinC
and MaxC close
<SPAN
>//<SPAN
>
together, but with different signs for the
"Difference".
<SPAN
>//
<SPAN
>
<SPAN
>//<SPAN
>
Declare the variables and initialize
them
<SPAN
>MA1atCP1 = C;<SPAN
> //<SPAN
>
MA1 at Ref(MA1,+1) using trial value of
Close.
<SPAN
>MA2atCP1 = C;<SPAN
> //<SPAN
>
MA2 at Ref(MA2,+1) using trial value of
Close.
<SPAN
>MidC<FONT
face=Arial size=2> = C;<SPAN
>
//<SPAN
>
Next trial value of Close.
<SPAN
>ChgReq<FONT
face=Arial size=2> = 0;<SPAN
> //<SPAN
>
Change in Close required for Crossover.
<SPAN
>
<SPAN
>//<SPAN
>
Of course, if we could use Ref(MA1,1), there
would be no need
<SPAN
>//<SPAN
>
for all this. The
difficulty is that we want to repeatedly
<SPAN
>//<SPAN
>
change the value of the final element until we
determine
<SPAN
>//<SPAN
>
the solution to the crossover.
<SPAN
>
<SPAN
>//<SPAN
>
Loop through all the bars
<SPAN
>for<FONT
face=Arial size=2> (<SPAN
class=SpellE>i=Longest; i<<SPAN
class=SpellE>BarCount; <SPAN
class=SpellE>i++)
<SPAN
>{
<SPAN
><SPAN
>
//<SPAN
>
Initialize the Low test value and compute the
indicators
<SPAN
><SPAN
>
LowC[i] = <SPAN
class=SpellE>MinC[<SPAN
class=SpellE>i];
<SPAN
><SPAN
>
MA1atCP1[i] =
(MA1Length*MA1[i]-C[<SPAN
class=SpellE>i-(MA1Length-1)]+LowC[<SPAN
class=SpellE>i])/MA1Length;
<SPAN
><SPAN
>
MA2atCP1[i] =
(MA2Length*MA2[i]-C[<SPAN
class=SpellE>i-(MA2Length-1)]+LowC[<SPAN
class=SpellE>i])/MA2Length;
<SPAN
><SPAN
>
DiffLowC[i] = <SPAN
class=GramE>MA1atCP1[i] - MA2atCP1[<SPAN
class=SpellE>i];
<SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
Initialize the High test value and compute the
indicators
<SPAN
><SPAN
>
HighC[i] = <SPAN
class=SpellE>MaxC[<SPAN
class=SpellE>i];
<SPAN
><SPAN
>
MA1atCP1[i] =
(MA1Length*MA1[i]-C[<SPAN
class=SpellE>i-(MA1Length-1)]+HighC[<SPAN
class=SpellE>i])/MA1Length;
<SPAN
><SPAN
>
MA2atCP1[i] =
(MA2Length*MA2[i]-C[<SPAN
class=SpellE>i-(MA2Length-1)]+HighC[<SPAN
class=SpellE>i])/MA2Length;
<SPAN
><SPAN
>
DiffHighC[i] =
MA1atCP1[i] -
MA2atCP1[i];
<SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
Test to see if the two indicators have
converged.
<SPAN
><SPAN
>
//<SPAN
>
They probably have not yet, but we need a
value
<SPAN
><SPAN
>
//<SPAN
>
at the first test of the loop.
<SPAN
><SPAN
>
Difference[i] = <SPAN
class=GramE>abs(DiffLowC[<SPAN
class=SpellE>i] - DiffHighC[<SPAN
class=SpellE>i]);
<SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
Stay in the search loop until the upper limit
price
<SPAN
><SPAN
>
//<SPAN
>
and lower limit price are within 0.005 (one half cent in
US)
<SPAN
><SPAN
>
while (Difference[i]
> 0.005)
<SPAN
><SPAN
>
{
<SPAN
><SPAN
>
//<SPAN
>
Pick the midpoint of LowC and <SPAN
class=SpellE>HighC to test next.
<SPAN
><SPAN
>
MidC[i] = (<SPAN
class=SpellE>LowC[i] + <SPAN
class=SpellE>HighC[i]) /
2;
<SPAN
><SPAN
>
//<SPAN
>
And compute the
indicators
<SPAN
><SPAN
>
MA1atCP1[i] =
(MA1Length*MA1[i]-C[<SPAN
class=SpellE>i-(MA1Length-1)]+MidC[<SPAN
class=SpellE>i])/MA1Length;
<SPAN
><SPAN
>
MA2atCP1[i] =
(MA2Length*MA2[i]-C[<SPAN
class=SpellE>i-(MA2Length-1)]+MidC[<SPAN
class=SpellE>i])/MA2Length;
<SPAN
><SPAN
>
DiffMidC[i] = <SPAN
class=GramE>MA1atCP1[i] - MA2atCP1[<SPAN
class=SpellE>i];
<SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
Using the signs of the
differences,
<SPAN
><SPAN
>
//<SPAN
>
decide whether to replace the high test
point
<SPAN
><SPAN
>
//<SPAN
>
or the low test point by the new Middle test point
<SPAN
><SPAN
>
SignMid[i] = <SPAN
class=SpellE>DiffMidC[i] >
0.0;
<SPAN
><SPAN
>
SignLow[i] = <SPAN
class=SpellE>DiffLowC[i] >
0.0;
<SPAN
><SPAN
>
<SPAN
><SPAN
>
if (SignMid[<SPAN
class=SpellE>i] == SignLow[<SPAN
class=SpellE>i])
<SPAN
><SPAN
>
{
<SPAN
><SPAN
>
//<SPAN
>
The sign of the difference at the <SPAN
class=SpellE>LowC point and at the
<SPAN
><SPAN
>
//<SPAN
>
MidC point are the same.<SPAN
> That means <SPAN
class=SpellE>LowC and MidC are
on
<SPAN
><SPAN
>
//<SPAN
>
the same side of the crossover point we are looking
for,
<SPAN
><SPAN
>
//<SPAN
>
but MidC is
closer.
<SPAN
><SPAN
>
//<SPAN
>
So, replace Low with
Middle
<SPAN
><SPAN
>
LowC[i] = <SPAN
class=SpellE>MidC[<SPAN
class=SpellE>i];
<SPAN
><SPAN
>
MA1atCP1[i] =
(MA1Length*MA1[i]-C[<SPAN
class=SpellE>i-(MA1Length-1)]+LowC[<SPAN
class=SpellE>i])/MA1Length;
<SPAN
><SPAN
>
MA2atCP1[i] =
(MA2Length*MA2[i]-C[<SPAN
class=SpellE>i-(MA2Length-1)]+LowC[<SPAN
class=SpellE>i])/MA2Length;
<SPAN
><SPAN
>
DiffLowC[i] = <SPAN
class=GramE>MA1atCP1[i] - MA2atCP1[<SPAN
class=SpellE>i];
<SPAN
><SPAN
>
}
<SPAN
><SPAN
>
else
<SPAN
><SPAN
>
{
<SPAN
><SPAN
>
//<SPAN
>
Replace High with Middle
<SPAN
><SPAN
>
HighC[i] = <SPAN
class=SpellE>MidC[<SPAN
class=SpellE>i];
<SPAN
><SPAN
>
MA1atCP1[i] =
(MA1Length*MA1[i]-C[<SPAN
class=SpellE>i-(MA1Length-1)]+HighC[<SPAN
class=SpellE>i])/MA1Length;
<SPAN
><SPAN
>
MA2atCP1[i] =
(MA2Length*MA2[i]-C[<SPAN
class=SpellE>i-(MA2Length-1)]+HighC[<SPAN
class=SpellE>i])/MA2Length;
<SPAN
><SPAN
>
DiffHighC[i] =
MA1atCP1[i] -
MA2atCP1[i];
<SPAN
>
<SPAN
><SPAN
>
}<SPAN
>
//<SPAN
>
if-else
<SPAN
><SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
One of DiffLowC or <SPAN
class=SpellE>DiffHighC has changed as the
<SPAN
><SPAN
>
//<SPAN
>
search range has tightened, the other
<SPAN
><SPAN
>
//<SPAN
>
remains as it was on the last pass through the
loop.
<SPAN
><SPAN
>
//<SPAN
>
Compute the new difference between the
two.
<SPAN
><SPAN
>
Difference[i] = <SPAN
class=GramE>abs(DiffLowC[<SPAN
class=SpellE>i] - DiffHighC[<SPAN
class=SpellE>i]);
<SPAN
>
<SPAN
><SPAN
>
}<SPAN
>
//<SPAN
>
while
<SPAN
>
<SPAN
><SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
After the loop, the value of <SPAN
class=SpellE>MidC is the value
<SPAN
><SPAN
>
//<SPAN
>
at which the curves will cross
<SPAN
><SPAN
>
MidC[i] = (<SPAN
class=SpellE>LowC[i] + <SPAN
class=SpellE>HighC[<SPAN
class=SpellE>i])/2;
<SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
Limit MidC so that it plots
reasonably
<SPAN
><SPAN
>
MidC[i] = <SPAN
class=SpellE>IIf<SPAN
class=GramE>(MidC[<SPAN
class=SpellE>i]>1.25*C[i],1.25*C[<SPAN
class=SpellE>i], MidC[<SPAN
class=SpellE>i]);
<SPAN
><SPAN
>
MidC[i] = <SPAN
class=SpellE>IIf<SPAN
class=GramE>(MidC[<SPAN
class=SpellE>i]<0.80*C[i],0.80*C[<SPAN
class=SpellE>i], MidC[<SPAN
class=SpellE>i]);
<SPAN
>
<SPAN
><SPAN
>
//<SPAN
>
Compute the change required from the most
recent
<SPAN
><SPAN
>
//<SPAN
>
Close to the next Close if crossover is to
happen.
<SPAN
><SPAN
>
ChgReq[i] = <SPAN
class=SpellE>MidC[i] - C[<SPAN
class=SpellE>i];
<SPAN
>
<SPAN
>}<SPAN
>
//<SPAN
>
for
<SPAN
>
<SPAN
>//<SPAN
>
Plot Close, MA1, MA2, and Computed Cross
Point
<SPAN
>Plot(C,"C"<SPAN
class=GramE>,colorBlack,styleCandle);
<SPAN
>Plot(<FONT
face=Arial size=2><SPAN
>MA(C,MA1Length),"MA1",colorBlue,styleLine);
<SPAN
>Plot(<FONT
face=Arial size=2><SPAN
>MA(C,MA2Length),"MA2",colorGreen,styleLine);
<SPAN
>Plot(<SPAN
class=SpellE><SPAN
>MidC,"Computed<FONT
face=Arial size=2> <SPAN
class=SpellE>Cross",colorRed,styleLine);
<SPAN
>
<SPAN
>//<SPAN
>
Plot Change Required to Cross
<SPAN
>Plot(<SPAN
class=SpellE><SPAN
>ChgReq,"Change<FONT
face=Arial size=2> <SPAN
class=SpellE>Required",colorYellow,styleDots|styleLeftAxisScale);
<SPAN
>Plot(<FONT
face=Arial size=2><SPAN
>0.0,"",colorYellow,styleLine|styleLeftAxisScale);Send
BUG REPORTS to bugs@xxxxxxxxxxxxxSend SUGGESTIONS to
suggest@xxxxxxxxxxxxx-----------------------------------------Post
AmiQuote-related messages ONLY to: amiquote@xxxxxxxxxxxxxxx (Web page: <A
href="">http://groups.yahoo.com/group/amiquote/messages/)--------------------------------------------Check
group FAQ at: <A
href="">http://groups.yahoo.com/group/amibroker/files/groupfaq.html
Yahoo! Groups Links
To visit your group on the web, go to:<A
href="">http://groups.yahoo.com/group/amibroker/
To unsubscribe from this group, send an email to:<A
href="">amibroker-unsubscribe@xxxxxxxxxxxxxxx
Your use of Yahoo! Groups is subject to the <A
href="">Yahoo! Terms of Service.
---Outgoing mail is certified Virus Free.Checked by
AVG anti-virus system (http://www.grisoft.com).Version: 6.0.553 / Virus
Database: 345 - Release Date:
12/18/2003
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.
|