/* // входные параметры для вставки в др.индикаторы extern int Source=1; // 0 - объем; 1 - ATR; 2 - ст.девиация цены; extern int SourcePeriod=88; // период входного индикатора extern int Window=111; // длина выборки нормирования extern double Sensitivity=0; // чувствительность extern int Signal=55; // сглаживание нормированного индикатора (сигнальная) // вызов из др.индикаторов iCustom(NULL,0,"_MasterSlave",Source,SourcePeriod,Window,Sensitivity,Signal, 0,i); */ #property indicator_separate_window // в подокне #property indicator_buffers 7 #property indicator_color1 Red // сигнальная #property indicator_color6 Blue // гистограмма динамики длины выборки #property indicator_maximum 1 #property indicator_minimum 0 // входные параметры extern int Source=1; // 0 - объем; 1 - ATR; 2 - ст.девиация цены; int ApplPrice=0; // 0 - Close; 4 - (high+low)/2; 5 - (high+low+close)/3; 6 - (high+low+close+close)/4; extern int SourcePeriod=88; // период входного индикатора int Shift=0; // сдвиг bool MAtypeI=1; // 0 - SMA, 1 - EMA int PrePeriod=1; // для девиации дополнительное сглаживание, остальные - медленная MA для MACD bool MAtypeP=1; // 0 - SMA, 1 - EMA extern int Window=111; // длина выборки нормирования int WindowLimit=0; // множитель ограничение длины выборки нормирования int WindowShift=0; // сдвиг выборки нормирования bool WindowMethod=0; // 0 - фиксированная выборка для нормирования, 1 - плавающая extern double Sensitivity=0; // чувствительность bool abs=1; // вывод через буфер NP[] со знаком движения ст.девиации bool ToRange=1; // принудительное ограничение диап. 0...1; имеет смысл только при WindowShift>0 double Power=1; // степень по нормированию extern int Signal=55; // сглаживание нормированного индикатора (сигнальная) bool MAtypeS=1; // 0 - SMA, 1 - EMA int SignalShift=0; // сдвиг сигнальной int History=0; // индикаторные буферы double Ind[], // нормируемый индикатор PR[], // префильтрация NORM[], // результаты нормирования SM[], // сигнальная Input[], // буфер аргументов нормируемого индикатора (цена или объем) MA[], // МА нормируемого индикатора NP[], // плавающий период нормирования - в вычислиниях не участвует - для наглядности SIGN[]; // емулированный буфер - вспомогательная MA double sens, // чувствительность в масштабе цены/объема sensLimit, // минимальная чувсвительность sn, IndPeriodK, // коэфф. EMA для девиации PrePeriodK, // коэфф. EMA для префильтра SignalK; // коэфф. EMA для сглаживания bool Em=0; // флаг для эмуляции вспомогательной MA //int WindowLimit; // ограничение длины выборки нормирования //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { switch(Source) { case 0: // Объем SetIndexStyle(2,DRAW_LINE,0,1,LimeGreen); string ShortName="Volume("; double punkt=1; WindowShift++; break; case 3: // Стохастик SetIndexStyle(2,DRAW_LINE,0,1,LightSeaGreen); ShortName="MA("; WindowMethod=1; // использовать плавающую длину выборки нормирования punkt=Point; break; case 2: // ст.девиация SetIndexStyle(2,DRAW_LINE,0,1,MediumSeaGreen); ShortName="StDev("; punkt=Point; break; case 1: //ATR SetIndexStyle(2,DRAW_LINE,0,1,DodgerBlue); ShortName="ATR("; punkt=Point; } if(WindowMethod) { if(WindowLimit==0) WindowLimit=Window*10; // ограничение длины выборки нормирования else WindowLimit=MathMax(WindowLimit,Window); } ShortName=ShortName+_Price()+SourcePeriod; if(Shift>0) ShortName=ShortName+"+"+Shift; ShortName=ShortName+") "; if(PrePeriod>1) ShortName=ShortName+PrePeriod+" "; ShortName=ShortName+"["+Window; if(WindowMethod && Sensitivity>0) ShortName=ShortName+"_"+WindowLimit; if(WindowShift>0) ShortName=ShortName+"+"+WindowShift; if(Sensitivity>0) ShortName=ShortName+"@"+DoubleToStr(Sensitivity,1); ShortName=ShortName+"]"; if(Power!=1) ShortName=ShortName+"^"+DoubleToStr(Power,1); if(Signal>1 || SignalShift>0) { ShortName=ShortName+" ("+Signal; if(SignalShift>0) ShortName=ShortName+"+"+SignalShift; ShortName=ShortName+")"; } IndicatorShortName(ShortName); // задать имя индикатора в подокне //---- indicators SetIndexBuffer(0,SM); // сигнальная SetIndexStyle(0,DRAW_LINE); SetIndexLabel(0,"Signal"); SetIndexBuffer(1,Ind); // индикатор SetIndexStyle(1,DRAW_NONE); SetIndexLabel(1,NULL); SetIndexBuffer(2,NORM); // результаты нормирования SetIndexLabel(2,"Normed"); SetIndexBuffer(3,MA); // MA индикатора SetIndexStyle(3,DRAW_NONE); SetIndexLabel(3,NULL); SetIndexBuffer(4,Input); // буфер входных данных (объем или цена) SetIndexStyle(4,DRAW_NONE); SetIndexLabel(4,NULL); SetIndexBuffer(5,NP); // гистограмма и вывод со знаком ст.дев. if(Source==-3 && Sensitivity>0) // показать длину выборки нормирования { SetIndexStyle(5,DRAW_HISTOGRAM); Source=-Source; } else SetIndexStyle(5,DRAW_NONE); if(Source==3 && Sensitivity>0) SetIndexLabel(5,"Window"); else SetIndexLabel(5,NULL); if(abs) SetIndexLabel(5,"NormSign"); else SetIndexLabel(5,NULL); SetIndexBuffer(6,PR); // результаты префильтрации индикатора (подаются в нормирование) SetIndexStyle(6,DRAW_NONE); SetIndexLabel(6,"Source"); //---- sensLimit=punkt/1000; // минимальная чувсвительность sens=MathMax(Sensitivity*punkt,sensLimit); // чувствительность в масштабе индикатора if(WindowMethod) sn=sensLimit; // если динамическое нормирование else sn=sens; if(SourcePeriod<0) {MAtypeI=0; SourcePeriod=-SourcePeriod;} // SMA else IndPeriodK=2.0/(SourcePeriod+1); // EMA if(PrePeriod<0) {MAtypeP=0; PrePeriod=-PrePeriod;} // SMA else PrePeriodK=2.0/(PrePeriod+1); // EMA if(Signal<0) {MAtypeS=0; Signal=-Signal;} // SMA else SignalK=2.0/(Signal+1); // EMA if(Source==0 || Source==1) Em=1; // флаг для эмуляции вспомогательной MA return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { if(Em) EmBuff(); int ic=IndicatorCounted(); if(Bars-ic-1>1) {ic=reinit();} int limit=Bars-ic; //BarsPrev=Bars; // кол-во пересчетов if(ic==0) limit-=4; //if(History!=0 && limit>History) limit=History-1; // кол-во пересчетов по истории for(int i=limit; i>=0; i--) // цикл по непосчитанным и предпоследнему барам { double ma; int n; int iShift=i+Shift; if(Em) { // Эмулируемая МА if(MAtypeI) // EMA SIGN[i]=IndPeriodK*Price(4,iShift)+(1-IndPeriodK)*SIGN[i+1]; else { // SMA int sh=iShift+SourcePeriod; ma=SIGN[i+1]*SourcePeriod-Price(4,sh); SIGN[i]=(ma+Close[iShift])/SourcePeriod; } } // выбор источника switch(Source) { case 0: // объем Input[i]=Volume[iShift]; break; case 3: // цена Input[i]=Price(ApplPrice,iShift); break; case 2: Input[i]=Price(ApplPrice,iShift); break; case 1: // ATR Input[i]=MathMax(High[iShift],Close[iShift+1])-MathMin(Low[iShift],Close[iShift+1]); } // MA if(MAtypeI) { // EMA MA[i]=IndPeriodK*Input[i]+(1-IndPeriodK)*MA[i+1]; ma=MA[i]; } else { // SMA sh=i+SourcePeriod; ma=MA[i+1]*SourcePeriod-Input[sh]; MA[i]=(ma+Input[i])/SourcePeriod; ma=MA[i]; } // ст.девиация if(Source==2) // нормируется девиация { double std=0; for(n=0; n0) x=MathPow(x,Power); NORM[i]=x; if(ToRange) // при сдвиге выборки убрать значения вне диап.0...1 {NORM[i]=MathMax(NORM[i],0); NORM[i]=MathMin(NORM[i],1);} if(abs) // вывод нормирования со знаком if(Em) // если объем или ATR {if(Close[i]>SIGN[i+3]) NP[i]=NORM[i]; else NP[i]=-NORM[i];} else // если ст.дев. {if(Close[i]>MA[i+3]) NP[i]=NORM[i]; else NP[i]=-NORM[i];} // Сглаживание . if(Signal==1) SM[i]=NORM[i+SignalShift]; else if(MAtypeS) // EMA SM[i]=SignalK*NORM[i+SignalShift]+(1-SignalK)*SM[i+1]; else { // SMA sh=i+SignalShift+Signal; ma=SM[i+1]*Signal-NORM[sh]; SM[i]=(ma+NORM[i+SignalShift])/Signal; } } //---- return(0); } //---------------------------------------------------- // ф-я дополнительной инициализации int reinit() { ArrayInitialize(Input,0.0); ArrayInitialize(Ind,0.0); ArrayInitialize(PR,0.0); ArrayInitialize(NORM,0.0); ArrayInitialize(SM,0.0); ArrayInitialize(MA,0.0); ArrayInitialize(NP,0.0); return(0); } 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); case 5: return((High[i]+Low[i]+Close[i])/3); case 6: return((High[i]+Low[i]+2*Close[i])/4); default: return(Close[i]); } } string _Price() { switch(ApplPrice) { case 0: return(""); case 1: return("O"); case 2: return("H"); case 3: return("L"); case 4: return("M"); case 5: return("T"); case 6: return("W"); default: return(""); } } void EmBuff() { static int NewSize; if(NewSize==Bars) return; NewSize=Bars; ArraySetAsSeries(SIGN,0); ArrayResize(SIGN,NewSize); ArraySetAsSeries(SIGN,1); } //+------------------------------------------------------------------+