[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [amibroker] Re: Backtesting and Backtesters



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.