Schiff Lines.afl
上传用户:shiqiang
上传日期:2009-06-12
资源大小:1289k
文件大小:10k
源码类别:

金融证券系统

开发平台:

Others

  1. //------------------------------------------------------------------------------
  2. //
  3. //  Formula Name:    Schiff Lines
  4. //  Author/Uploader: Bob Johnson 
  5. //  E-mail:          bjohnson314@kc.rr.com
  6. //  Date/Time Added: 2006-09-14 21:53:50
  7. //  Origin:          
  8. //  Keywords:        Schiff
  9. //  Level:           semi-advanced
  10. //  Flags:           indicator
  11. //  Formula URL:     http://www.amibroker.com/library/formula.php?id=707
  12. //  Details URL:     http://www.amibroker.com/library/detail.php?id=707
  13. //
  14. //------------------------------------------------------------------------------
  15. //
  16. //  Variation on Andrew's Pitchfork. Uses the midpoint between the left 2
  17. //  peak/trough points instead of the leftmost peak/trough to determine the
  18. //  slope of the lines.
  19. //
  20. //------------------------------------------------------------------------------
  21. // Schiff Lines
  22. // Modified from Andrews Pitchfork V3.3
  23. // Use Peak() & Trough() to get peaks & troughs.
  24. // This version deals with adjacent peaks and adjacent
  25. // troughs, i.e. two peaks without an intervening trough or vice-versa.
  26. // It goes backwards from the selected bar until it has a set of 
  27. // peak,trough,peak or trough,peak,trough points to use for calulating
  28. // the Schiff lines.  When 2 or more peaks or 2 or more troughs are adjacent
  29. // it only uses the last one, i.e. the rightmost one, of the series.
  30. //
  31. // This plots the Schiff lines based on the last 3 identified peaks and troughs.
  32. // Instead of a fixed look-back period it identifies the actual bars where the
  33. // peaks AND troughs were revealed by the price action.  i.e. the price has to have
  34. // moved off the high/low by the zigzag pct before the peak or trough will
  35. // be used.
  36. //
  37. // Plots the trendlines as exponential curves that plot as
  38. // straight lines on an semilog chart.
  39. //
  40. SetBarsRequired( 999999,999999);
  41. bi=BarIndex();
  42. sbi=SelectedValue(bi);
  43. // Pct threshhold for peak() & trough()
  44. Zigpct=Param("Zigpct",4.6,1.0,30.0,0.1,0);
  45. // Since the Zig function only works on a single array, to get a true
  46. // High/Low peak/trough have to approximate it by an EMA choosing the 
  47. // High/Low based on the direction the EMA is moving.  Very occasionally
  48. // it misses the correct High/Low.  To just use value, for example the close,
  49. // just change zpr=IIf(ROC(zema,1) > 0,H,L); to zpr=C;
  50. zema=EMA(C,14);
  51. zpr=IIf(ROC(zema,1) > 0,H,L);
  52. zag=Zig(zpr,zigpct);
  53. tr=Ref(zag,-1) > zag AND zag < Ref(zag,1);
  54. pk=Ref(zag,-1) < zag AND zag > Ref(zag,1);
  55. pkprice=ValueWhen(pk,zpr);
  56. trprice=ValueWhen(tr,zpr);
  57. // This bit is still valid at the right edge.  If price moves far enough in 1 day to show
  58. // a peak or trough on the last bar, the peak or trough won't go away later.  The pk_id or 
  59. // tr_id (below) will appear on the same bar.  Normally peaks & troughs appear in 'the past',
  60. // e.g. the high 10 days ago wasn't a peak yesterday but today it is because the price dropped
  61. // enough to make it a peak. 
  62. pklast=IIf(BarsSince(pk) < BarsSince(tr),1,0);
  63. trlast=IIf(BarsSince(tr) < BarsSince(pk),1,0);
  64. // A peak or trough is defined as the price moving X pct down or up from a high or low.
  65. // The identification point is when the price has actually moved that far.  The peak/trough
  66. // will appear 'in the past' on the same day as the pk_id or tr_id appears on the rightmost
  67. // bar.
  68. // Use 'OR tr/OR pk' because when the bar that reveals the pk/tr is also a pk/tr the pklast/
  69. // trlast will have flipped.
  70. // Can't use cross of H or L in the 2nd AND because the H or L may not get above or below the
  71. // trigger price when the pk/tr occurs.
  72. // The NOT conditions eliminate same-day pk/tr pk_id/tr_id cases. i.e. when the day's price 
  73. // range was >= zpct on the pk/tr day.
  74. pk_id=((pklast OR tr) AND pkprice*(1-(zigpct*0.01)) > L ) AND NOT ( pk AND (H - L)/L >= 0.01 * zigpct);
  75. tr_id=((trlast OR pk) AND H > trprice*(1+(zigpct*0.01)) ) AND NOT ( tr AND (H - L)/L >= 0.01 * zigpct);
  76. // The pk_id/tr_id conditions can recur before the next pk or tr
  77. pk_id=ExRem(pk_id,tr_id);
  78. tr_id=ExRem(tr_id,pk_id);
  79. pk_idlast=IIf(BarsSince(pk_id) < BarsSince(tr_id),1,0);
  80. tr_idlast=IIf(BarsSince(tr_id) < BarsSince(pk_id),1,0);
  81. Lookbk=IIf(pk_idlast,BarsSince(pk),BarsSince(tr));
  82. // How many bars to extend the pitchfork past the selected bar.
  83. xtsn=Param("Extension",62,1,2500,1);
  84. // Shift to move pitchfork up/down from original position one penny at time.
  85. shift=Param("Shift",0,-2000,2000,0.01);
  86. // Filter out cases when the angle of the median lines is too extreme,
  87. // The loop will continue until it finds a set of lines whose slope falls 
  88. // between +- the Angle Limit.  Setting the angle limit to 90 effectively
  89. // turns it off.
  90. alimit=Param("Angle Limit",40,1,180,1);
  91. // bkgrndcolor should match your background color.  It's used to mask the 
  92. // parts of the pitchfork arrays outside the calculated pitchfork from view.
  93. bkgrndcolor=ParamColor("Background Color",colorLightGrey);
  94. pitchforkcolor=ParamColor("Line Color",colorRed);
  95. // The peak/trough lines will be used to determine the y coordinates
  96. // of the pitchfork's 3 determining points.
  97. //pline1=Peak(H,Zigpct,1);
  98. //tline1=Trough(L,Zigpct,1);
  99. pline1=pkprice;
  100. tline1=trprice;
  101. // Identify the pivots.
  102. pzag1=pline1 != Ref(pline1,-1);
  103. tzag1=tline1 != Ref(tline1,-1);
  104. // Get the x,y coordinates of the pivots skipping adjacent
  105. // peaks and troughs.  Go backwards from the current bar minus the lookback.
  106. // These will hold the x,y coordinates of the pivot points in arrays at the
  107. // sbi index.
  108. zagx1=0;
  109. zagx2=0;
  110. zagx3=0;
  111. zagy1=0;
  112. zagy2=0;
  113. zagy3=0;
  114. for ( i = sbi - Lookbk[sbi], zagfnd = 0, pzagfnd = 0, tzagfnd = 0 ; i >= 0 && zagfnd < 3; i-- ) {
  115.     if ( pzag1[i] || tzag1[i] ) {
  116.         if ( pzag1[i] && NOT pzagfnd ) {
  117.              zagfnd=zagfnd+1;
  118.              pzagfnd=1;
  119.              tzagfnd=0;
  120.              if ( zagfnd == 1 ) {
  121.                  zagx1[sbi]=i;
  122.                  zagy1[sbi]=pline1[i];
  123.              } else if (zagfnd == 2) {
  124.                  zagx2[sbi]=i;
  125.                  zagy2[sbi]=pline1[i];
  126.              } else if (zagfnd == 3) {
  127.                  zagx3[sbi]=i;
  128.                  zagy3[sbi]=pline1[i];
  129.              }
  130.         } else if ( tzag1[i] && NOT tzagfnd ) {
  131.              zagfnd=zagfnd+1;
  132.              tzagfnd=1;
  133.              pzagfnd=0;
  134.              if ( zagfnd == 1 ) {
  135.                  zagx1[sbi]=i;
  136.                  zagy1[sbi]=tline1[i];
  137.              } else if (zagfnd == 2) {
  138.                  zagx2[sbi]=i;
  139.                  zagy2[sbi]=tline1[i];
  140.              } else if (zagfnd == 3) {
  141.                  zagx3[sbi]=i;
  142.                  zagy3[sbi]=tline1[i];
  143.              }
  144.         }
  145.     }
  146.     if ( zagfnd == 3 ) {  // Got 3 candidate peak/trough points
  147.         echng=0;
  148.         midx=0;
  149.         midy=0;
  150.         schiffx=0;
  151.         schiffy=0;
  152.         Handle=0;
  153.         Top=0;
  154.         Bot=0;
  155.         // For Schiff lines instead of Andrew's Pitchfork, move the left pivot point
  156.         // to the mid point of the left most pivots.
  157.         schiffx[sbi]=zagx3[sbi] + (zagx2[sbi]-zagx3[sbi]) / 2;
  158.         schiffy[sbi]=exp( log(zagy2[sbi]) - ( log(zagy2[sbi])-log(zagy3[sbi]) ) / 2);
  159.         // to avoid changing all the instances of zagx3,zagy3 from the old Andrew's code
  160.         // just reset x3 & y3 to the schiff values.
  161.         zagx3[sbi] = schiffx[sbi];
  162.         zagy3[sbi] = schiffy[sbi];
  163.         echng=(log(midy[sbi])-log(zagy3[sbi]))/(midx[sbi]-zagx3[sbi]);
  164.         // Determine Midpoint between the rightmost 2 pivots and the slope from the
  165.         // Schiff point determined above to the midpoint.
  166.         Midx[sbi]=zagx2[sbi] + (zagx1[sbi]-zagx2[sbi]) / 2;
  167.         Midy[sbi]=exp( log(zagy1[sbi]) - ( log(zagy1[sbi])-log(zagy2[sbi]) ) / 2);
  168.         echng=(log(midy[sbi])-log(zagy3[sbi]))/(midx[sbi]-zagx3[sbi]);
  169.         // Apply the Angle Limit filter
  170.         angle_rad = atan(echng);//radians
  171.         angle_deg = 100 * angle_rad * 180/3.1416;//degrees
  172.         if ( angle_deg < -alimit || angle_deg > alimit ) { // Too steep, reset the search
  173.                                                            // to begin from the 2nd pivot found
  174.             if ( tzagfnd == 1 ) {  // was tr,pk,tr so switch to pk,tr,pk
  175.                 tzagfnd = 0;
  176.                 pzagfnd = 1;
  177.                 zagfnd = 1;
  178.                 zagx1[sbi]=zagx2[sbi];
  179.                 zagy1[sbi]=zagy2[sbi];
  180.                 i = zagx1[sbi];
  181.                 zagx2=0;
  182.                 zagx3=0;
  183.                 zagy2=0;
  184.                 zagy3=0;
  185.             } else {  // was pk,tr,pk so switch to tr,pk,tr
  186.                 tzagfnd = 1;
  187.                 pzagfnd = 0;
  188.                 zagfnd = 1;
  189.                 zagx1[sbi]=zagx2[sbi];
  190.                 zagy1[sbi]=zagy2[sbi];
  191.                 i = zagx1[sbi];
  192.                 zagx2=0;
  193.                 zagx3=0;
  194.                 zagy2=0;
  195.                 zagy3=0;
  196.             } 
  197.        }
  198.     }
  199. }
  200. // Calculate the Schiff lines themselves
  201. // Handle first
  202. for ( j=zagx3[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
  203.    Handle[j]=exp(log(zagy3[sbi]) + n*echng) + shift;
  204. }
  205. // High & low median lines.
  206. if ( (exp(log(zagy2[sbi]) + (sbi-zagx2[sbi])*echng)) 
  207.      > (exp(log(zagy1[sbi]) + (sbi-zagx1[sbi])*echng)) ) {  // Which one is top?
  208.    for ( j=zagx2[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
  209.       top[j]=exp(log(zagy2[sbi]) + n*echng) + shift;
  210.    }
  211.    for ( j=zagx1[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
  212.       bot[j]=exp(log(zagy1[sbi]) + n*echng) + shift;
  213.    }
  214. } else {
  215.    for ( j=zagx2[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
  216.       bot[j]=exp(log(zagy2[sbi]) + n*echng) + shift;
  217.    }
  218.    for ( j=zagx1[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
  219.       top[j]=exp(log(zagy1[sbi]) + n*echng) + shift;
  220.    }
  221. }
  222. Hcolor=IIf(Handle==0,bkgrndcolor,IIf(Ref(handle,-1)== 0 AND handle != 0, bkgrndcolor,pitchforkcolor));
  223. Tcolor=IIf(Top==0,bkgrndcolor,IIf(Ref(top,-1)== 0 AND top != 0, bkgrndcolor,pitchforkcolor));
  224. Bcolor=IIf(Bot==0,bkgrndcolor,IIf(Ref(bot,-1)== 0 AND bot != 0, bkgrndcolor,pitchforkcolor));
  225. Htitle=EncodeColor(pitchforkcolor)
  226.       + StrFormat("nSchiff: pct=%g lkbk=%g shft=%g alimit=%g Angle=%3.2f Handle=",
  227.         Zigpct, Lookbk, shift, alimit, angle_deg);
  228. Plot(Handle,Htitle,Hcolor,styleLine+styleDashed+styleNoRescale);
  229. Plot(Bot,EncodeColor(pitchforkcolor)+" Bot=",Bcolor,styleLine+styleDashed+styleNoRescale);
  230. Plot(Top,EncodeColor(pitchforkcolor)+" Top=",Tcolor,styleLine+styleDashed+styleNoRescale);