//+------------------------------------------------------------------+ //| Version July 20, 2006 | //| Editing Nikolay Kositsin 15.06.2006 farria@mail.redcom.ru | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| #MAMA_NK.mq4 | //| | //| http://forex.kbpauk.ru/ | //+------------------------------------------------------------------+ #property link "http://forex.kbpauk.ru/" //---- отрисовка индикатора в главном окне #property indicator_chart_window //---- количество индикаторных буфферов #property indicator_buffers 2 //---- цвета индикатора #property indicator_color1 Blue #property indicator_color2 Red //---- толщина индикаторных линий #property indicator_width1 1 #property indicator_width2 1 //---- ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА extern double FastLimit = 0.5; extern double SlowLimit = 0.05; //---- индикаторные буфферы double FABuffer[]; double MABuffer[]; //+------------------------------------------------------------------+ //| #MAMA initialization function | //+------------------------------------------------------------------+ int init() { //---- Стиль исполнения графика SetIndexStyle(0, DRAW_LINE, 0, 2); SetIndexStyle(1, DRAW_LINE, 0, 2); //---- 2 индикаторных буффера использованы для счёта SetIndexBuffer(0, FABuffer); SetIndexBuffer(1, MABuffer); //---- установка значений индикатора, которые не будут видимы на графике SetIndexEmptyValue(0, 0.0); SetIndexEmptyValue(1, 0.0); //---- имя для окон данных и лэйба для субъокон IndicatorShortName("#MAMA_NK"); SetIndexLabel(0, "#FAMA_NK"); SetIndexLabel(1, "#MAMA_NK"); //---- установка номера бара, начиная с которого будет отрисовываться индикатор SetIndexDrawBegin(0, 50); SetIndexDrawBegin(1, 50); //---- завершение инициализации return(0); } //+------------------------------------------------------------------+ //| #MAMA | //+------------------------------------------------------------------+ int start() { //---- проверка количества баров на достаточность для расчёта if(Bars <= 7) return(0); //---- введение переменных памяти static int time2; static double Price[4][2], Smooth[7][2], Detrender[7][2], Q1[7][2]; static double I1[7][2], I2[3][2], Q2[3][2]; static double Re[2][2], Im[2][2], SmoothPeriod[2][2], Period_[3][2]; static double Phase[2][2], MAMA[2][2], FAMA[2][2]; //----+ Введение целых переменных и получение уже подсчитанных баров int MaxBar, limit, bar, iii, counted_bars = IndicatorCounted(); //---- проверка на возможные ошибки if(counted_bars < 0) return(-1); //---- последний подсчитанный бар должен быть пересчитан if(counted_bars > 0) counted_bars--; //----+ Введение переменных с плавающей точкой double jI, jQ, DeltaPhase, alpha; //---- определение номера самого старого бара, начиная с которого будет произведён полный пересчёт всех баров MaxBar = Bars - 1 - 7; //---- определение номера самого старого бара, начиная с которого будет произедён пересчёт только новых баров limit = Bars - 1 - counted_bars; //---- инициализация нуля if(limit >= MaxBar) { for(iii = Bars - 1; iii > MaxBar; iii--) { FABuffer[bar] = 0; MABuffer[bar] = 0; limit = MaxBar; } } //+--- восстановление значений переменных +====+ int Tnew = (int)Time[limit+1]; if(limit < MaxBar) if(Tnew == time2) { for(iii = 0; iii < 4; iii++) Price[iii][0] = Price[iii][1]; for(iii = 0; iii < 7; iii++) { Smooth[iii][0] = Smooth[iii][1]; Detrender[iii][0] = Detrender[iii][1]; Q1[iii][0] = Q1[iii][1]; I1[iii][0] = I1[iii][1]; } for(iii = 0; iii < 2; iii++) { I2[iii][0] = I2[iii][1]; Q2[iii][0] = Q2[iii][1]; Re[iii][0] = Re[iii][1]; Im[iii][0] = Im[iii][1]; SmoothPeriod[iii][0] = SmoothPeriod[iii][1]; Period_[iii][0] = Period_[iii][1]; Phase[iii][0] = Phase[iii][1]; MAMA [iii][0] = MAMA [iii][1]; FAMA [iii][0] = FAMA [iii][1]; } } else { if(Tnew > time2) Print("ERROR01"); else Print("ERROR02"); return(-1); } //---- bar = limit; while(bar >= 0) { //+--- Сохранение значений переменных +==========+ if(bar == 1) if(((limit == 1) && (time2 == Time[2])) || (limit > 1)) { for(iii = 0; iii < 4; iii++) Price[iii][1] = Price[iii][0]; //---- for(iii = 0; iii < 7; iii++) { time2 = (int)Time[2]; Smooth[iii][1] = Smooth[iii][0]; Detrender[iii][1] = Detrender[iii][0]; Q1[iii][1] = Q1[iii][0]; I1[iii][1] = I1[iii][0]; } //---- for(iii = 0; iii < 2; iii++) { I2[iii][1] = I2[iii][0]; Q2[iii][1] = Q2[iii][0]; Re[iii][1] = Re[iii][0]; Im[iii][1] = Im[iii][0]; SmoothPeriod[iii][1] = SmoothPeriod[iii][0]; Period_[iii][1] = Period_[iii][0]; Phase[iii][1] = Phase[iii][0]; MAMA [iii][1] = MAMA [iii][0]; FAMA [iii][1] = FAMA [iii][0]; } } //+---+==========================================+ for(iii = 0; iii < 4; iii++) Price[iii][0] = (High[bar+iii] + Low[bar+iii]) / 2; Smooth[0][0] = (4*Price[0][0] + 3*Price[1][0] + 2*Price[2][0] + Price[3][0]) / 10; Detrender[0][0] = (0.0962*Smooth[0][0] + 0.5769*Smooth[2][0] - 0.5769*Smooth[4][0] - 0.0962*Smooth[6][0])*(0.075*Period_[2][0] + 0.54); // {Compute InPhase and Quadrature components} Q1[0][0] = (0.0962*Detrender[0][0] + 0.5769*Detrender[2][0] - 0.5769*Detrender[4][0] - 0.0962*Detrender[6][0])*(0.075*Period_[2][0] + 0.54); I1[0][0] = Detrender[3][0]; // {Advance the phase of I1 and Q1 by 90 degrees} jI = (0.0962*I1[0][0] + 0.5769*I1[2][0] - 0.5769*I1[4][0] - 0.0962*I1[6][0])*(0.075*Period_[1][0] + 0.54); jQ = (0.0962*Q1[0][0] + 0.5769*Q1[2][0] - 0.5769*Q1[4][0] - 0.0962*Q1[6][0])*(0.075*Period_[1][0] + 0.54); // {Phasor addition for 3 bar averaging)} I2[0][0] = I1[0][0] - jQ; Q2[0][0] = Q1[0][0] + jI; // {Smooth the I and Q components before applying the discriminator} I2[1][0] = 0.2*I2[1][0] + 0.8*I2[2][0]; Q2[1][0] = 0.2*Q2[1][0] + 0.8*Q2[2][0]; // {Homodyne Discriminator} Re[0][0] = I2[0][0]*I2[1][0] + Q2[0][0]*Q2[1][0]; Im[0][0] = I2[0][0]*Q2[1][0] - Q2[0][0]*I2[1][0]; Re[0][0] = 0.2*Re[0][0] + 0.8*Re[1][0]; Im[0][0] = 0.2*Im[0][0] + 0.8*Im[1][0]; //---- if(Im[0][0] != 0 && Re[0][0] != 0) Period_ [0][0]= 360 / MathArctan(Im[0][0] / Re[0][0]); //---- if(Period_[0][0] > 1.5*Period_[1][0]) Period_[0][0] = 1.5*Period_[1][0]; //---- if(Period_[0][0] < 0.67*Period_[1][0]) Period_[0][0] = 0.67*Period_[1][0]; //---- if(Period_[0][0] < 6) Period_[0][0] = 6; //---- if(Period_[0][0] > 50) Period_[0][0] = 50; //---- Period_[0][0] = 0.2*Period_[0][0] + 0.8*Period_[1][0]; SmoothPeriod[0][0] = 0.33*Period_[0][0] + 0.67*SmoothPeriod[1][0]; //---- if(I1[0][0] != 0) Phase[0][0] = (MathArctan(Q1[0][0] / I1[0][0])); DeltaPhase = Phase[1][0] - Phase[0][0]; //---- if(DeltaPhase < 1) DeltaPhase = 1; alpha = FastLimit / DeltaPhase; //---- if(alpha < SlowLimit) alpha = SlowLimit; MAMA[0][0] = alpha*Price[0][0] + (1 - alpha)*MAMA[1][0]; FAMA[0][0] = 0.5*alpha*MAMA[0][0] + (1 - 0.5*alpha)*FAMA[1][0]; //---- if(bar <= Bars - 50) { FABuffer[bar] = MAMA[0][0]; MABuffer[bar] = FAMA[0][0]; } else { FABuffer[bar] = 0; MABuffer[bar] = 0; } //---- bar--; //---- if(bar < 0) break; //---- Smooth[6][0] = Smooth[5][0]; Smooth[5][0] = Smooth[4][0]; Smooth[4][0] = Smooth[3][0]; Smooth[3][0] = Smooth[2][0]; Smooth[2][0] = Smooth[1][0]; Smooth[1][0] = Smooth[0][0]; //---- Detrender[6][0] = Detrender[5][0]; Detrender[5][0] = Detrender[4][0]; Detrender[4][0] = Detrender[3][0]; Detrender[3][0] = Detrender[2][0]; Detrender[2][0] = Detrender[1][0]; Detrender[1][0] = Detrender[0][0]; //---- Q1[6][0] = Q1[5][0]; Q1[5][0] = Q1[4][0]; Q1[4][0] = Q1[3][0]; Q1[3][0] = Q1[2][0]; Q1[2][0] = Q1[1][0]; Q1[1][0] = Q1[0][0]; //---- I1[6][0] = I1[5][0]; I1[5][0] = I1[4][0]; I1[4][0] = I1[3][0]; I1[3][0] = I1[2][0]; I1[2][0] = I1[1][0]; I1[1][0] = I1[0][0]; //---- Q2[1][0] = Q2[0][0]; I2[1][0] = I2[0][0]; Re[1][0] = Re[0][0]; Im[1][0] = Im[0][0]; SmoothPeriod[1][0] = SmoothPeriod[0][0]; Phase[1][0] = Phase[0][0]; Period_[1][0] = Period_[0][0]; MAMA[1][0] = MAMA[0][0]; FAMA[1][0] = FAMA[0][0]; //---- } return(0); } //+------------------------------------------------------------------+