黄金
stochastic + alma
回复:0  浏览:977
  • 楼主admin 圈主
  • 2019-05-05 05:02
EURUSDM30.png

  1. //------------------------------------------------------------------
  2. #property copyright "外汇EA之家,免费下载EA、指标"
  3. #property link      "http://www.eazhijia.com"
  4. //------------------------------------------------------------------
  5. #property indicator_separate_window
  6. #property indicator_buffers 4
  7. #property indicator_color1  clrDodgerBlue
  8. #property indicator_color2  clrSandyBrown
  9. #property indicator_color3  clrSandyBrown
  10. #property indicator_color4  clrRed
  11. #property indicator_width1  3
  12. #property indicator_width2  3
  13. #property indicator_width3  3
  14. #property indicator_style4  STYLE_DOT
  15. #property strict

  16. //
  17. //
  18. //
  19. //
  20. //

  21. enum enPrices
  22. {
  23.    pr_close,      // Close
  24.    pr_open,       // Open
  25.    pr_high,       // High
  26.    pr_low,        // Low
  27.    pr_median,     // Median
  28.    pr_typical,    // Typical
  29.    pr_weighted,   // Weighted
  30.    pr_average,    // Average (high+low+open+close)/4
  31.    pr_medianb,    // Average median body (open+close)/2
  32.    pr_tbiased,    // Trend biased price
  33.    pr_haclose,    // Heiken ashi close
  34.    pr_haopen ,    // Heiken ashi open
  35.    pr_hahigh,     // Heiken ashi high
  36.    pr_halow,      // Heiken ashi low
  37.    pr_hamedian,   // Heiken ashi median
  38.    pr_hatypical,  // Heiken ashi typical
  39.    pr_haweighted, // Heiken ashi weighted
  40.    pr_haaverage,  // Heiken ashi average
  41.    pr_hamedianb,  // Heiken ashi median body
  42.    pr_hatbiased   // Heiken ashi trend biased price
  43. };
  44. enum enDoWhat
  45. {
  46.    do_sto,  // Make stochastic using alma as price filter
  47.    do_alm,  // Make alma smoothed stochastic
  48.    do_sta   // Make stochastic with alma signal line
  49. };
  50. enum enColorOn
  51. {
  52.    clr_onSlope, // Change color on slope change
  53.    clr_onSignal // Change color on signal cross (only if alma signal line chosen)
  54. };

  55. extern ENUM_TIMEframeS Timeframe   = PERIOD_CURRENT; // Time frame to use
  56. extern int             pperiod     = 14;             // Stochastic calculating period
  57. extern int             speriod     = 14;             // Stochastic slowing period
  58. extern enPrices        ppriceh     = pr_high;        // Price to use for high
  59. extern enPrices        ppricel     = pr_low;         // Price to use for low
  60. extern enPrices        ppricec     = pr_close;       // Price to use for close
  61. extern int             AlmaPeriod  = 7;              // Alma calculation length
  62. extern double          AlmaSigma   = 8.0;            // Alma sigma
  63. extern double          AlmaSample  = 0.85;           // Alma sample
  64. extern enDoWhat        doWhat      = do_sto;         // Make what?
  65. extern enColorOn       colorOn     = clr_onSlope;    // When should the color change?
  66. extern int             linesWidth  =  3;             // Lines width
  67. extern bool            Interpolate = true;           // Interpolate in multi time frame mode?


  68. double buffer[];
  69. double bufferda[];
  70. double bufferdb[];
  71. double signal[];
  72. double trend[];
  73. string indicatorFileName;
  74. bool   returnBars;

  75. //------------------------------------------------------------------
  76. //
  77. //------------------------------------------------------------------
  78. //
  79. //
  80. //
  81. //
  82. //

  83. int init()
  84. {
  85.    IndicatorBuffers(5);
  86.    SetIndexBuffer(0,buffer,  INDICATOR_DATA); SetIndexStyle(0,EMPTY,EMPTY,linesWidth);
  87.    SetIndexBuffer(1,bufferda,INDICATOR_DATA); SetIndexStyle(1,EMPTY,EMPTY,linesWidth);
  88.    SetIndexBuffer(2,bufferdb,INDICATOR_DATA); SetIndexStyle(2,EMPTY,EMPTY,linesWidth);
  89.    SetIndexBuffer(3,signal,  INDICATOR_DATA);
  90.    SetIndexBuffer(4,trend   ,INDICATOR_CALCULATIONS);
  91.             indicatorFileName = WindowExpertName();
  92.             returnBars        = Timeframe==-99;
  93.             Timeframe         = MathMax(Timeframe,_Period);
  94.    IndicatorShortName(timeframeToString(Timeframe)+" stochastic alma ("+(string)pperiod+","+(string)speriod+","+(string)AlmaPeriod+")");
  95.    return(0);
  96. }

  97. //
  98. //
  99. //
  100. //
  101. //

  102. int start()
  103. {
  104.    int counted_bars=IndicatorCounted();
  105.       if(counted_bars<0) return(-1);
  106.       if(counted_bars>0) counted_bars--;
  107.            int limit=MathMin(Bars-counted_bars,Bars-2);
  108.             if (returnBars) { buffer[0] = MathMin(limit+1,Bars-1); return(0); }
  109.             if (Timeframe != Period())
  110.             {
  111.                if (trend[limit]==-1) CleanPoint(limit,bufferda,bufferdb);
  112.                for(int i=limit; i>=0; i--)
  113.                {
  114.                   int y = iBarShift(NULL,Timeframe,Time[i]);
  115.                   buffer[i]   = iCustom(NULL,Timeframe,indicatorFileName,PERIOD_CURRENT,pperiod,speriod,ppriceh,ppricel,ppricec,AlmaPeriod,AlmaSigma,AlmaSample,doWhat,0,y);
  116.                   signal[i]   = iCustom(NULL,Timeframe,indicatorFileName,PERIOD_CURRENT,pperiod,speriod,ppriceh,ppricel,ppricec,AlmaPeriod,AlmaSigma,AlmaSample,doWhat,3,y);
  117.                   trend[i]    = iCustom(NULL,Timeframe,indicatorFileName,PERIOD_CURRENT,pperiod,speriod,ppriceh,ppricel,ppricec,AlmaPeriod,AlmaSigma,AlmaSample,doWhat,4,y);
  118.                   bufferda[i] = EMPTY_VALUE;
  119.                   bufferdb[i] = EMPTY_VALUE;
  120.                   if (!Interpolate || (i>0 && y==iBarShift(NULL,Timeframe,Time[i-1]))) continue;
  121.                   
  122.                   //
  123.                   //
  124.                   //
  125.                   //
  126.                   //
  127.                   
  128.                   int n,k; datetime time = iTime(NULL,Timeframe,y);
  129.                      for(n = 1; (i+n)<Bars && Time[i+n] >= time; n++) continue;       
  130.                      for(k = 1; k<n && (i+n)<Bars && (i+k)<Bars; k++)
  131.                      {
  132.                            buffer[i+k] = buffer[i] + (buffer[i+n] - buffer[i]) * k/n;
  133.                            signal[i+k] = signal[i] + (signal[i+n] - signal[i]) * k/n;
  134.                      }
  135.                }
  136.                for(int i=limit; i>=0; i--) if (trend[i] == -1) PlotPoint(i,bufferda,bufferdb,buffer);
  137.                return(0);
  138.             }

  139.    //
  140.    //
  141.    //
  142.    //
  143.    //

  144.    if (trend[limit]==-1) CleanPoint(limit,bufferda,bufferdb);
  145.    for(int i=limit; i>=0; i--)
  146.    {
  147.       double priceh = getPrice(ppriceh,Open,Close,High,Low,i,0);
  148.       double pricel = getPrice(ppricel,Open,Close,High,Low,i,1);
  149.       double pricec = getPrice(ppricec,Open,Close,High,Low,i,2);
  150.       
  151.       //
  152.       //
  153.       //
  154.       //
  155.       //

  156.       signal[i]   = EMPTY_VALUE;
  157.       bufferda[i] = EMPTY_VALUE;
  158.       bufferdb[i] = EMPTY_VALUE;
  159.       if (doWhat==do_sto)
  160.       {
  161.          priceh = iAlma(priceh,AlmaPeriod,AlmaSigma,AlmaSample,i,0);
  162.          pricel = iAlma(pricel,AlmaPeriod,AlmaSigma,AlmaSample,i,1);
  163.          pricec = iAlma(pricec,AlmaPeriod,AlmaSigma,AlmaSample,i,2);
  164.          buffer[i] = NormalizeDouble(iStoch(pricec,priceh,pricel,pperiod,speriod,i),_Digits);
  165.       }         
  166.       if (doWhat==do_alm)
  167.          buffer[i] = iAlma(iStoch(pricec,priceh,pricel,pperiod,speriod,i),AlmaPeriod,AlmaSigma,AlmaSample,i,3);
  168.       if (doWhat==do_sta)
  169.       {
  170.          buffer[i] = iStoch(pricec,priceh,pricel,pperiod,speriod,i);
  171.          signal[i] = iAlma(buffer[i],AlmaPeriod,AlmaSigma,AlmaSample,i,3);
  172.       }
  173.       if (i<Bars-1)
  174.       {
  175.          trend[i] = trend[i+1];
  176.          if (doWhat==do_sta && clr_onSignal)
  177.          {
  178.             if (buffer[i]>signal[i]) trend[i] =  1;
  179.             if (buffer[i]<signal[i]) trend[i] = -1;
  180.          }
  181.          else
  182.          {
  183.             if (buffer[i]>buffer[i+1]) trend[i] =  1;
  184.             if (buffer[i]<buffer[i+1]) trend[i] = -1;
  185.          }            
  186.          if (trend[i] == -1) PlotPoint(i,bufferda,bufferdb,buffer);
  187.       }         
  188.    }      
  189.    return(0);
  190. }

  191. //------------------------------------------------------------------
  192. //
  193. //------------------------------------------------------------------
  194. //
  195. //
  196. //
  197. //

  198. double workSto[][5];
  199. #define _hi 0
  200. #define _lo 1
  201. #define _re 2
  202. #define _ma 3
  203. #define _mi 4
  204. double iStoch(double priceR, double priceH, double priceL, int period, int slowing, int i, int instanceNo=0)
  205. {
  206.    if (ArrayRange(workSto,0)!=Bars) ArrayResize(workSto,Bars); i = Bars-i-1; instanceNo *= 5;
  207.    
  208.    //
  209.    //
  210.    //
  211.    //
  212.    //
  213.    
  214.       workSto[i][_hi+instanceNo] = priceH;
  215.       workSto[i][_lo+instanceNo] = priceL;
  216.       workSto[i][_re+instanceNo] = priceR;
  217.       workSto[i][_ma+instanceNo] = priceH;
  218.       workSto[i][_mi+instanceNo] = priceL;
  219.       for (int k=1; k<period && (i-k)>=0; k++)
  220.       {
  221.          workSto[i][_mi+instanceNo] = MathMin(workSto[i][_mi+instanceNo],workSto[i-k][_lo+instanceNo]);
  222.          workSto[i][_ma+instanceNo] = MathMax(workSto[i][_ma+instanceNo],workSto[i-k][_hi+instanceNo]);
  223.       }                  
  224.       double sumlow  = 0.0;
  225.       double sumhigh = 0.0;
  226.       for(int k=0; k<slowing && (i-k)>=0; k++)
  227.       {
  228.          sumlow  += workSto[i-k][_re+instanceNo]-workSto[i-k][_mi+instanceNo];
  229.          sumhigh += workSto[i-k][_ma+instanceNo]-workSto[i-k][_mi+instanceNo];
  230.       }

  231.    //
  232.    //
  233.    //
  234.    //
  235.    //
  236.    
  237.    if(sumhigh!=0.0)
  238.          return(100.0*sumlow/sumhigh);
  239.    else  return(0);   
  240. }

  241. //------------------------------------------------------------------
  242. //                                                                  
  243. //------------------------------------------------------------------
  244. //
  245. //
  246. //
  247. //
  248. //

  249. #define almaInstances 4
  250. double  almaWork[][almaInstances];
  251. double  almaCoeffs[];

  252. double iAlma(double price, int period, double sigma, double sample, int r, int instanceNo=0)
  253. {
  254.    if (period<=1) return(price);
  255.    if (ArrayRange(almaWork,0)!=Bars) ArrayResize(almaWork,Bars); r = Bars-r-1; almaWork[r][instanceNo] = price;
  256.    
  257.    //
  258.    //
  259.    //
  260.    //
  261.    //

  262.    if (ArraySize(almaCoeffs)!=period) ArrayResize(almaCoeffs,period);
  263.          double m = MathFloor(sample * (period - 1.0));
  264.          double s = period/sigma;
  265.          for (int i=0; i<period; i++)
  266.             almaCoeffs[i] = MathExp(-((i-m)*(i-m))/(2.0*s*s));
  267.    
  268.          double sum=0;
  269.          double div=0;
  270.          for (int k=0; k<period && (r-k)>=0; k++)
  271.          {
  272.             sum += almaCoeffs[k]*almaWork[r-k][instanceNo];
  273.             div += almaCoeffs[k];
  274.          }
  275.          double alma = price; if (div!=0) alma = sum/div;
  276.    return(alma);
  277. }

  278. //-------------------------------------------------------------------
  279. //
  280. //-------------------------------------------------------------------
  281. //
  282. //
  283. //
  284. //
  285. //

  286. void CleanPoint(int i,double& first[],double& second[])
  287. {
  288.    if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
  289.         second[i+1] = EMPTY_VALUE;
  290.    else
  291.       if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
  292.           first[i+1] = EMPTY_VALUE;
  293. }

  294. //
  295. //
  296. //
  297. //
  298. //

  299. void PlotPoint(int i,double& first[],double& second[],double& from[])
  300. {
  301.    if (i>=Bars-2) return;
  302.    if (first[i+1] == EMPTY_VALUE)
  303.          {
  304.             if (first[i+2] == EMPTY_VALUE)
  305.                   { first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }
  306.             else  { second[i] = from[i]; second[i+1] = from[i+1]; first[i]  = EMPTY_VALUE; }
  307.          }
  308.    else  { first[i] = from[i]; second[i] = EMPTY_VALUE; }
  309. }

  310. //------------------------------------------------------------------
  311. //
  312. //------------------------------------------------------------------
  313. //
  314. //
  315. //
  316. //
  317. //
  318. //

  319. double workHa[][12];
  320. double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int instanceNo=0)
  321. {
  322.   if (tprice>=pr_haclose)
  323.    {
  324.       if (ArrayRange(workHa,0)!= Bars) ArrayResize(workHa,Bars); instanceNo*=4;
  325.          int r = Bars-i-1;
  326.          
  327.          //
  328.          //
  329.          //
  330.          //
  331.          //
  332.          
  333.          double haOpen;
  334.          if (r>0)
  335.                 haOpen  = (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0;
  336.          else   haOpen  = (open[i]+close[i])/2;
  337.          double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;
  338.          double haHigh  = MathMax(high[i], MathMax(haOpen,haClose));
  339.          double haLow   = MathMin(low[i] , MathMin(haOpen,haClose));

  340.          if(haOpen  <haClose) { workHa[r][instanceNo+0] = haLow;  workHa[r][instanceNo+1] = haHigh; }
  341.          else                 { workHa[r][instanceNo+0] = haHigh; workHa[r][instanceNo+1] = haLow;  }
  342.                                 workHa[r][instanceNo+2] = haOpen;
  343.                                 workHa[r][instanceNo+3] = haClose;
  344.          //
  345.          //
  346.          //
  347.          //
  348.          //
  349.          
  350.          switch (tprice)
  351.          {
  352.             case pr_haclose:     return(haClose);
  353.             case pr_haopen:      return(haOpen);
  354.             case pr_hahigh:      return(haHigh);
  355.             case pr_halow:       return(haLow);
  356.             case pr_hamedian:    return((haHigh+haLow)/2.0);
  357.             case pr_hamedianb:   return((haOpen+haClose)/2.0);
  358.             case pr_hatypical:   return((haHigh+haLow+haClose)/3.0);
  359.             case pr_haweighted:  return((haHigh+haLow+haClose+haClose)/4.0);
  360.             case pr_haaverage:   return((haHigh+haLow+haClose+haOpen)/4.0);
  361.             case pr_hatbiased:
  362.                if (haClose>haOpen)
  363.                      return((haHigh+haClose)/2.0);
  364.                else  return((haLow+haClose)/2.0);        
  365.          }
  366.    }
  367.    
  368.    //
  369.    //
  370.    //
  371.    //
  372.    //
  373.    
  374.    switch (tprice)
  375.    {
  376.       case pr_close:     return(close[i]);
  377.       case pr_open:      return(open[i]);
  378.       case pr_high:      return(high[i]);
  379.       case pr_low:       return(low[i]);
  380.       case pr_median:    return((high[i]+low[i])/2.0);
  381.       case pr_medianb:   return((open[i]+close[i])/2.0);
  382.       case pr_typical:   return((high[i]+low[i]+close[i])/3.0);
  383.       case pr_weighted:  return((high[i]+low[i]+close[i]+close[i])/4.0);
  384.       case pr_average:   return((high[i]+low[i]+close[i]+open[i])/4.0);
  385.       case pr_tbiased:   
  386.                if (close[i]>open[i])
  387.                      return((high[i]+close[i])/2.0);
  388.                else  return((low[i]+close[i])/2.0);        
  389.    }
  390.    return(0);
  391. }
  392.    
  393. //-------------------------------------------------------------------
  394. //
  395. //-------------------------------------------------------------------
  396. //
  397. //
  398. //
  399. //
  400. //

  401. string sTfTable[] = {"M1","M5","M10","M15","M30","H1","H4","D1","W1","MN"};
  402. int    iTfTable[] = {1,5,10,15,30,60,240,1440,10080,43200};

  403. string timeframeToString(int tf)
  404. {
  405.    for (int i=ArraySize(iTfTable)-1; i>=0; i--)
  406.          if (tf==iTfTable[i]) return(sTfTable[i]);
  407.                               return("");
  408. }