//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2012, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ /* вызов из кодов по полям параметров ничем не отличается от стандартной iMA: double iCustom( string symbol, // символьное имя инструмента (NULL- текущий) int timeframe, // тайм-фрейм (0- текущий) "iFMA", // имя этого индикатора double period, // период MA; м.б.дробным (>1) и в виде коэфф-та (<1) double ma_shift, // сдвиг MA; м.б. дробным (>0) int ma_method, // метод усреднения: // 0- SMA (простая), // 1- EMA (экспоненциальная), // 2- SSMA (сглаженная), // 3- LWMA (линейно-взвешенная) int applied_price, // тип сглаживаемых данных: // 0- Close, 1- Open, 2- High, 3- Low, // 4- Middle=(High+Low)/2 (средняя), // 5- Typical=(High+Low+Close)/3 (типичная), // 6- Weighted=High+Low+2*Close)/4 (взвешенная), // 7- Volume (объем) 0, // mode - номер буфера индикатора (0) int shift // сдвиг ) ============== iCustom(NULL,0,"iFMA",MAperiod,Shift,Method,Price, 0,i); */ #property indicator_chart_window // в окне инструмента #property indicator_buffers 3 #property indicator_color1 Red // входные параметры extern double MAperiod=3; extern double Shift=0; extern int Method=0; extern int Price=0; int History=0; // 0- все бары double MA[],b0[],b1[]; // массивы инд. и вспомогательных буферов double k0,k1,period; // коэфф. EMA и производный период double rt; // дробная часть периода int per; // целая часть периода double rts0,rts1; // целый и дробный веса баров сдвига int pers; // целая часть сдвига //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // инициализация void init() { if(MAperiod>1) {k0=2/(1+MAperiod); period=MAperiod;} else {k0=MAperiod; period=(2-MAperiod)/MAperiod;} k1=1-k0; per=MathFloor(period); rt=period-per; pers=MathFloor(Shift); rts1=Shift-pers; rts0=1-rts1; string _sn=_method(Method)+"("+DoubleToStr(period,2)+")"; IndicatorShortName(_sn); SetIndexBuffer(0,MA); // индикатор SetIndexLabel(0,_sn); SetIndexEmptyValue(0,0.0); SetIndexBuffer(1,b0); // вспомогательный буфер SetIndexStyle(1,DRAW_NONE); SetIndexLabel(1,NULL); SetIndexEmptyValue(1,0.0); SetIndexBuffer(2,b1); // вспомогательный буфер SetIndexStyle(2,DRAW_NONE); SetIndexLabel(2,NULL); SetIndexEmptyValue(2,0.0); ArrayInitialize(MA,0.0); ArrayInitialize(b0,0.0); ArrayInitialize(b1,0.0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void start() { /*int limit=Bars-IndicatorCounted()-1; if(limit>1) { limit=Bars-1; ArrayInitialize(MA,0.0); ArrayInitialize(b0,0.0); ArrayInitialize(b1,0.0); } */ // if(History!=0 && limit>History) limit=History-1; // кол-во пересчетов по истории // // цикл пересчета int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; int limit=Bars-counted_bars; if(counted_bars==0) limit-=1+per; for(int i=limit; i>=0; i--) { double ma=0,mp=0; switch(Method) { case 0: // SMA int lim=limit-per-(rt>0)+1; if(i<=lim || i<2) { // расчетная история int j=i+per; // положение старшего дробного бара if(i==lim) { // начальное значение ma=rt*Price(Price,j); // вес старшего дробного бара j--; for(; j>=i; j--) ma+=Price(Price,j); // сумма целых баров } else { // основной расчет if(rt>0) ma=b0[i+1]*period-rt*Price(Price,j+1)-(1-rt)*Price(Price,j)+Price(Price,i); else ma=b0[i+1]*period-Price(Price,j)+Price(Price,i); } b0[i]=ma/period; // MA } break; case 1: // EMA if(i==limit && i>1) ma=Price(Price,i); // начальное значение else ma=k0*Price(Price,i)+k1*b0[i+1]; // основной расчет b0[i]=ma; break; case 2: // SMMA lim=limit-per-(rt>0)+1; if(i<=lim || i<2) { // расчетная история if(i==lim) { // начальное значение j=i+per; // положение старшего дробного бара ma=rt*Price(Price,j); // вес старшего дробного бара j--; for(; j>=i; j--) ma+=Price(Price,j); // сумма целых баров ma/=period; } else ma=((period-1)*b0[i+1]+Price(Price,i))/period; // основной расчет } b0[i]=ma; // MA break; case 3: // LWMA static double wt; lim=limit-per-(rt>0)+1; j=i+per; // положение старшего дробного бара if(i<=lim || i<2) { // расчетная история if(i==lim) { // начальное значение if(rt>0) { ma=rt*Price(Price,j); // вес старшего дробного бара mp=ma; wt=rt; } else {wt=0; ma=0; mp=0;} j--; for(int k=1; j>=i; j--,k++) { // сумма весов целых баров ma+=Price(Price,j)*k; mp+=Price(Price,j); wt+=k; } } else { // основной расчет if(rt>0) { ma=b0[i+1]*wt-b1[i+1]+rt*Price(Price,j)+per*Price(Price,i); mp=b1[i+1]-rt*Price(Price,j+1)-(1-rt)*Price(Price,j)+Price(Price,i); } else { ma=b0[i+1]*wt-b1[i+1]+per*Price(Price,i); mp=b1[i+1]-Price(Price,j)+Price(Price,i); } } b0[i]=ma/wt; b1[i]=mp;// MA } } // сдвиг (линейная интерполяция) double b01=b0[i+pers+1]; if(b01!=0 || rts1==0) MA[i]=rts1*b01+rts0*b0[i+pers]; } } // тип цены double Price(int ApplPrice,int i) { switch(ApplPrice) { case 0: return(Close[i]); case 1: return(Open[i]); case 2: return(High[i]); case 3: return(Low[i]); case 4: return((High[i]+Low[i])/2); // Middle case 5: return((High[i]+Low[i]+Close[i])/3); // Typical case 6: return((High[i]+Low[i]+2*Close[i])/4); // Weighted case 7: return(Volume[i]); default: return(Close[i]); } } // название метода string _method(int m) { switch(m) { case 0: return("SMA"); // SMA case 1: return("EMA"); // EMA case 2: return("SMMA"); // SMMA case 3: return("LWMA"); // LWMA default: return("SMA"); } } //+------------------------------------------------------------------+