- //------------------------------------------------------------------
- #property copyright "外汇EA之家,免费下载EA、指标"
- #property link "http://www.eazhijia.com"
- //------------------------------------------------------------------
- #property indicator_separate_window
- #property indicator_buffers 4
- #property indicator_color1 clrDodgerBlue
- #property indicator_color2 clrSandyBrown
- #property indicator_color3 clrSandyBrown
- #property indicator_color4 clrRed
- #property indicator_width1 3
- #property indicator_width2 3
- #property indicator_width3 3
- #property indicator_style4 STYLE_DOT
- #property strict
- //
- //
- //
- //
- //
- enum enPrices
- {
- pr_close, // Close
- pr_open, // Open
- pr_high, // High
- pr_low, // Low
- pr_median, // Median
- pr_typical, // Typical
- pr_weighted, // Weighted
- pr_average, // Average (high+low+open+close)/4
- pr_medianb, // Average median body (open+close)/2
- pr_tbiased, // Trend biased price
- pr_haclose, // Heiken ashi close
- pr_haopen , // Heiken ashi open
- pr_hahigh, // Heiken ashi high
- pr_halow, // Heiken ashi low
- pr_hamedian, // Heiken ashi median
- pr_hatypical, // Heiken ashi typical
- pr_haweighted, // Heiken ashi weighted
- pr_haaverage, // Heiken ashi average
- pr_hamedianb, // Heiken ashi median body
- pr_hatbiased // Heiken ashi trend biased price
- };
- enum enDoWhat
- {
- do_sto, // Make stochastic using alma as price filter
- do_alm, // Make alma smoothed stochastic
- do_sta // Make stochastic with alma signal line
- };
- enum enColorOn
- {
- clr_onSlope, // Change color on slope change
- clr_onSignal // Change color on signal cross (only if alma signal line chosen)
- };
- extern ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // Time frame to use
- extern int pperiod = 14; // Stochastic calculating period
- extern int speriod = 14; // Stochastic slowing period
- extern enPrices ppriceh = pr_high; // Price to use for high
- extern enPrices ppricel = pr_low; // Price to use for low
- extern enPrices ppricec = pr_close; // Price to use for close
- extern int AlmaPeriod = 7; // Alma calculation length
- extern double AlmaSigma = 8.0; // Alma sigma
- extern double AlmaSample = 0.85; // Alma sample
- extern enDoWhat doWhat = do_sto; // Make what?
- extern enColorOn colorOn = clr_onSlope; // When should the color change?
- extern int linesWidth = 3; // Lines width
- extern bool Interpolate = true; // Interpolate in multi time frame mode?
- double buffer[];
- double bufferda[];
- double bufferdb[];
- double signal[];
- double trend[];
- string indicatorFileName;
- bool returnBars;
- //------------------------------------------------------------------
- //
- //------------------------------------------------------------------
- //
- //
- //
- //
- //
- int init()
- {
- IndicatorBuffers(5);
- SetIndexBuffer(0,buffer, INDICATOR_DATA); SetIndexStyle(0,EMPTY,EMPTY,linesWidth);
- SetIndexBuffer(1,bufferda,INDICATOR_DATA); SetIndexStyle(1,EMPTY,EMPTY,linesWidth);
- SetIndexBuffer(2,bufferdb,INDICATOR_DATA); SetIndexStyle(2,EMPTY,EMPTY,linesWidth);
- SetIndexBuffer(3,signal, INDICATOR_DATA);
- SetIndexBuffer(4,trend ,INDICATOR_CALCULATIONS);
- indicatorFileName = WindowExpertName();
- returnBars = TimeFrame==-99;
- TimeFrame = MathMax(TimeFrame,_Period);
- IndicatorShortName(timeFrameToString(TimeFrame)+" stochastic alma ("+(string)pperiod+","+(string)speriod+","+(string)AlmaPeriod+")");
- return(0);
- }
- //
- //
- //
- //
- //
- int start()
- {
- int counted_bars=IndicatorCounted();
- if(counted_bars<0) return(-1);
- if(counted_bars>0) counted_bars--;
- int limit=MathMin(Bars-counted_bars,Bars-2);
- if (returnBars) { buffer[0] = MathMin(limit+1,Bars-1); return(0); }
- if (TimeFrame != Period())
- {
- if (trend[limit]==-1) CleanPoint(limit,bufferda,bufferdb);
- for(int i=limit; i>=0; i--)
- {
- int y = iBarShift(NULL,TimeFrame,Time[i]);
- buffer[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,pperiod,speriod,ppriceh,ppricel,ppricec,AlmaPeriod,AlmaSigma,AlmaSample,doWhat,0,y);
- signal[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,pperiod,speriod,ppriceh,ppricel,ppricec,AlmaPeriod,AlmaSigma,AlmaSample,doWhat,3,y);
- trend[i] = iCustom(NULL,TimeFrame,indicatorFileName,PERIOD_CURRENT,pperiod,speriod,ppriceh,ppricel,ppricec,AlmaPeriod,AlmaSigma,AlmaSample,doWhat,4,y);
- bufferda[i] = EMPTY_VALUE;
- bufferdb[i] = EMPTY_VALUE;
- if (!Interpolate || (i>0 && y==iBarShift(NULL,TimeFrame,Time[i-1]))) continue;
-
- //
- //
- //
- //
- //
-
- int n,k; datetime time = iTime(NULL,TimeFrame,y);
- for(n = 1; (i+n)<Bars && Time[i+n] >= time; n++) continue;
- for(k = 1; k<n && (i+n)<Bars && (i+k)<Bars; k++)
- {
- buffer[i+k] = buffer[i] + (buffer[i+n] - buffer[i]) * k/n;
- signal[i+k] = signal[i] + (signal[i+n] - signal[i]) * k/n;
- }
- }
- for(int i=limit; i>=0; i--) if (trend[i] == -1) PlotPoint(i,bufferda,bufferdb,buffer);
- return(0);
- }
- //
- //
- //
- //
- //
- if (trend[limit]==-1) CleanPoint(limit,bufferda,bufferdb);
- for(int i=limit; i>=0; i--)
- {
- double priceh = getPrice(ppriceh,Open,Close,High,Low,i,0);
- double pricel = getPrice(ppricel,Open,Close,High,Low,i,1);
- double pricec = getPrice(ppricec,Open,Close,High,Low,i,2);
-
- //
- //
- //
- //
- //
- signal[i] = EMPTY_VALUE;
- bufferda[i] = EMPTY_VALUE;
- bufferdb[i] = EMPTY_VALUE;
- if (doWhat==do_sto)
- {
- priceh = iAlma(priceh,AlmaPeriod,AlmaSigma,AlmaSample,i,0);
- pricel = iAlma(pricel,AlmaPeriod,AlmaSigma,AlmaSample,i,1);
- pricec = iAlma(pricec,AlmaPeriod,AlmaSigma,AlmaSample,i,2);
- buffer[i] = NormalizeDouble(iStoch(pricec,priceh,pricel,pperiod,speriod,i),_Digits);
- }
- if (doWhat==do_alm)
- buffer[i] = iAlma(iStoch(pricec,priceh,pricel,pperiod,speriod,i),AlmaPeriod,AlmaSigma,AlmaSample,i,3);
- if (doWhat==do_sta)
- {
- buffer[i] = iStoch(pricec,priceh,pricel,pperiod,speriod,i);
- signal[i] = iAlma(buffer[i],AlmaPeriod,AlmaSigma,AlmaSample,i,3);
- }
- if (i<Bars-1)
- {
- trend[i] = trend[i+1];
- if (doWhat==do_sta && clr_onSignal)
- {
- if (buffer[i]>signal[i]) trend[i] = 1;
- if (buffer[i]<signal[i]) trend[i] = -1;
- }
- else
- {
- if (buffer[i]>buffer[i+1]) trend[i] = 1;
- if (buffer[i]<buffer[i+1]) trend[i] = -1;
- }
- if (trend[i] == -1) PlotPoint(i,bufferda,bufferdb,buffer);
- }
- }
- return(0);
- }
- //------------------------------------------------------------------
- //
- //------------------------------------------------------------------
- //
- //
- //
- //
- double workSto[][5];
- #define _hi 0
- #define _lo 1
- #define _re 2
- #define _ma 3
- #define _mi 4
- double iStoch(double priceR, double priceH, double priceL, int period, int slowing, int i, int instanceNo=0)
- {
- if (ArrayRange(workSto,0)!=Bars) ArrayResize(workSto,Bars); i = Bars-i-1; instanceNo *= 5;
-
- //
- //
- //
- //
- //
-
- workSto[i][_hi+instanceNo] = priceH;
- workSto[i][_lo+instanceNo] = priceL;
- workSto[i][_re+instanceNo] = priceR;
- workSto[i][_ma+instanceNo] = priceH;
- workSto[i][_mi+instanceNo] = priceL;
- for (int k=1; k<period && (i-k)>=0; k++)
- {
- workSto[i][_mi+instanceNo] = MathMin(workSto[i][_mi+instanceNo],workSto[i-k][_lo+instanceNo]);
- workSto[i][_ma+instanceNo] = MathMax(workSto[i][_ma+instanceNo],workSto[i-k][_hi+instanceNo]);
- }
- double sumlow = 0.0;
- double sumhigh = 0.0;
- for(int k=0; k<slowing && (i-k)>=0; k++)
- {
- sumlow += workSto[i-k][_re+instanceNo]-workSto[i-k][_mi+instanceNo];
- sumhigh += workSto[i-k][_ma+instanceNo]-workSto[i-k][_mi+instanceNo];
- }
- //
- //
- //
- //
- //
-
- if(sumhigh!=0.0)
- return(100.0*sumlow/sumhigh);
- else return(0);
- }
- //------------------------------------------------------------------
- //
- //------------------------------------------------------------------
- //
- //
- //
- //
- //
- #define almaInstances 4
- double almaWork[][almaInstances];
- double almaCoeffs[];
- double iAlma(double price, int period, double sigma, double sample, int r, int instanceNo=0)
- {
- if (period<=1) return(price);
- if (ArrayRange(almaWork,0)!=Bars) ArrayResize(almaWork,Bars); r = Bars-r-1; almaWork[r][instanceNo] = price;
-
- //
- //
- //
- //
- //
- if (ArraySize(almaCoeffs)!=period) ArrayResize(almaCoeffs,period);
- double m = MathFloor(sample * (period - 1.0));
- double s = period/sigma;
- for (int i=0; i<period; i++)
- almaCoeffs[i] = MathExp(-((i-m)*(i-m))/(2.0*s*s));
-
- double sum=0;
- double div=0;
- for (int k=0; k<period && (r-k)>=0; k++)
- {
- sum += almaCoeffs[k]*almaWork[r-k][instanceNo];
- div += almaCoeffs[k];
- }
- double alma = price; if (div!=0) alma = sum/div;
- return(alma);
- }
- //-------------------------------------------------------------------
- //
- //-------------------------------------------------------------------
- //
- //
- //
- //
- //
- void CleanPoint(int i,double& first[],double& second[])
- {
- if ((second[i] != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
- second[i+1] = EMPTY_VALUE;
- else
- if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
- first[i+1] = EMPTY_VALUE;
- }
- //
- //
- //
- //
- //
- void PlotPoint(int i,double& first[],double& second[],double& from[])
- {
- if (i>=Bars-2) return;
- if (first[i+1] == EMPTY_VALUE)
- {
- if (first[i+2] == EMPTY_VALUE)
- { first[i] = from[i]; first[i+1] = from[i+1]; second[i] = EMPTY_VALUE; }
- else { second[i] = from[i]; second[i+1] = from[i+1]; first[i] = EMPTY_VALUE; }
- }
- else { first[i] = from[i]; second[i] = EMPTY_VALUE; }
- }
- //------------------------------------------------------------------
- //
- //------------------------------------------------------------------
- //
- //
- //
- //
- //
- //
- double workHa[][12];
- double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int instanceNo=0)
- {
- if (tprice>=pr_haclose)
- {
- if (ArrayRange(workHa,0)!= Bars) ArrayResize(workHa,Bars); instanceNo*=4;
- int r = Bars-i-1;
-
- //
- //
- //
- //
- //
-
- double haOpen;
- if (r>0)
- haOpen = (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0;
- else haOpen = (open[i]+close[i])/2;
- double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;
- double haHigh = MathMax(high[i], MathMax(haOpen,haClose));
- double haLow = MathMin(low[i] , MathMin(haOpen,haClose));
- if(haOpen <haClose) { workHa[r][instanceNo+0] = haLow; workHa[r][instanceNo+1] = haHigh; }
- else { workHa[r][instanceNo+0] = haHigh; workHa[r][instanceNo+1] = haLow; }
- workHa[r][instanceNo+2] = haOpen;
- workHa[r][instanceNo+3] = haClose;
- //
- //
- //
- //
- //
-
- switch (tprice)
- {
- case pr_haclose: return(haClose);
- case pr_haopen: return(haOpen);
- case pr_hahigh: return(haHigh);
- case pr_halow: return(haLow);
- case pr_hamedian: return((haHigh+haLow)/2.0);
- case pr_hamedianb: return((haOpen+haClose)/2.0);
- case pr_hatypical: return((haHigh+haLow+haClose)/3.0);
- case pr_haweighted: return((haHigh+haLow+haClose+haClose)/4.0);
- case pr_haaverage: return((haHigh+haLow+haClose+haOpen)/4.0);
- case pr_hatbiased:
- if (haClose>haOpen)
- return((haHigh+haClose)/2.0);
- else return((haLow+haClose)/2.0);
- }
- }
-
- //
- //
- //
- //
- //
-
- switch (tprice)
- {
- case pr_close: return(close[i]);
- case pr_open: return(open[i]);
- case pr_high: return(high[i]);
- case pr_low: return(low[i]);
- case pr_median: return((high[i]+low[i])/2.0);
- case pr_medianb: return((open[i]+close[i])/2.0);
- case pr_typical: return((high[i]+low[i]+close[i])/3.0);
- case pr_weighted: return((high[i]+low[i]+close[i]+close[i])/4.0);
- case pr_average: return((high[i]+low[i]+close[i]+open[i])/4.0);
- case pr_tbiased:
- if (close[i]>open[i])
- return((high[i]+close[i])/2.0);
- else return((low[i]+close[i])/2.0);
- }
- return(0);
- }
-
- //-------------------------------------------------------------------
- //
- //-------------------------------------------------------------------
- //
- //
- //
- //
- //
- string sTfTable[] = {"M1","M5","M10","M15","M30","H1","H4","D1","W1","MN"};
- int iTfTable[] = {1,5,10,15,30,60,240,1440,10080,43200};
- string timeFrameToString(int tf)
- {
- for (int i=ArraySize(iTfTable)-1; i>=0; i--)
- if (tf==iTfTable[i]) return(sTfTable[i]);
- return("");
- }
复制代码
stochastic alma.zip
|