//MQL4 Version 25 January, 2015 Final //+------------------------------------------------------------------+ //| SmoothAlgorithms.mqh | //| Copyright © 2016, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+------------------------------------------------------------------+ #property copyright "2013, Nikolay Kositsin" #property link "farria@mail.redcom.ru" #property version "3.24" //+------------------------------------------------------------------+ //| Классы для усреднения ценовых рядов | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Функциональные утилиты для классов алгоритмов усреднения | //+------------------------------------------------------------------+ class CMovSeriesTools { public: void MALengthCheck(string LengthName,int ExternLength); void MALengthCheck(string LengthName,double ExternLength); protected: bool BarCheck1(int begin,int bar,bool Set); bool BarCheck2(int begin,int bar,bool Set,int Length); bool BarCheck3(int begin,int bar,bool Set,int Length); bool BarCheck4(int rates_total,int bar,bool Set); bool BarCheck5(int rates_total,int bar,bool Set); bool BarCheck6(int rates_total,int bar,bool Set); void LengthCheck(int &ExternLength); void LengthCheck(double &ExternLength); void Recount_ArrayZeroPos( int &count, int Length, uint prev_calculated, uint rates_total, double series, int bar, double &Array[], bool set ); int Recount_ArrayNumber(int count,int Length,int Number); bool SeriesArrayResize(string FunctionsName, int Length, double &Array[], int &Size_ ); bool ArrayResizeErrorPrint(string FunctionsName,int &Size_); }; //+------------------------------------------------------------------+ //| Функции для классического усреднения ценовых рядов | //+------------------------------------------------------------------+ class CMoving_Average : public CMovSeriesTools { public: double MASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения ENUM_MA_METHOD MA_Method,// Метод усреднения (MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA) double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); double SMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); double EMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике double Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); double SMMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); double LWMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: double m_SeriesArray[]; int m_Size_,m_count,m_weight; double m_Moving,m_MOVING,m_Pr; double m_sum,m_SUM,m_lsum,m_LSUM; }; //+------------------------------------------------------------------+ //| Алгоритм получения стандартного отклонения | //+------------------------------------------------------------------+ class CStdDeviation : public CMovSeriesTools { public: double StdDevSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double deviation,// Девиация double series,// Значение ценового ряда, расчитанное для бара с номером bar double MovSeries,// Значение мувинга, относительно которого расчитывается StdDeviation uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: int m_Size_,m_count; double m_Sum,m_SUM,m_Sum2,m_SUM2; double m_SeriesArray[]; }; //+------------------------------------------------------------------+ //| Алгоритм JMA усреднения произвольных ценовых рядов | //+------------------------------------------------------------------+ class CJJMA : public CMovSeriesTools { public: double JJMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Din,// разрешение изменять параметры Length и Phase на каждом баре. // 0 - запрет изменения параметров, любое другое значение - разрешение. double Phase,// параметр, изменяющийся в пределах -100 ... +100, влияет на качество переходного процесса усреднения double Length,// глубина сглаживания double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); void JJMALengthCheck(string LengthName,int ExternLength); void JJMAPhaseCheck(string PhaseName,int ExternPhase); protected: void JJMAInit(uint begin,int Din,double Phase,double Length,double series,uint bar); //----+ Объявление глобальных переменных bool m_start; //---- double m_array[62]; //---- double m_degree,m_Phase,m_sense; double m_Krx,m_Kfd,m_Krj,m_Kct; double m_var1,m_var2; //---- int m_pos2,m_pos1; int m_Loop1,m_Loop2; int m_midd1,m_midd2; int m_count1,m_count2,m_count3; //---- double m_ser1,m_ser2; double m_Sum1,m_Sum2,m_JMA; double m_storage1,m_storage2,m_djma; double m_hoop1[128],m_hoop2[11],m_data[128]; //----+ Переменные для восстановления расчётов на незакрытом баре int m_pos2_,m_pos1_; int m_Loop1_,m_Loop2_; int m_midd1_,m_midd2_; int m_count1_,m_count2_,m_count3_; //---- double m_ser1_,m_ser2_; double m_Sum1_,m_Sum2_,m_JMA_; double m_storage1_,m_storage2_,m_djma_; double m_hoop1_[128],m_hoop2_[11],m_data_[128]; //---- bool m_bhoop1[128],m_bhoop2[11],m_bdata[128]; }; //+------------------------------------------------------------------+ //| Алгоритм усреднения Тильсона произвольных ценовых рядов | //+------------------------------------------------------------------+ class CT3 : public CMovSeriesTools { public: double T3Series(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Din,// разрешение изменять параметр Length на каждом баре. // 0 - запрет изменения параметров, любое другое значение - разрешение. double Curvature,// Коэффициент (для удобства его величина измерения увеличина в сто раз!) double Length,// глубина сглаживания double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: void T3Init(uint begin, int Din, double Curvature, double Length, double series, uint bar ); //----+ Объявление глобальных переменных double m_b2,m_b3; //---- double m_e1,m_e2,m_e3,m_e4,m_e5,m_e6; double m_E1,m_E2,m_E3,m_E4,m_E5,m_E6; double m_c1,m_c2,m_c3,m_c4,m_w1,m_w2; }; //+------------------------------------------------------------------+ //| Алгоритм ультралинейного усреднения произвольных ценовых рядов | //+------------------------------------------------------------------+ class CJurX : public CMovSeriesTools { public: double JurXSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Din,// разрешение изменять параметр Length на каждом баре. // 0 - запрет изменения параметров, любое другое значение - разрешение. double Length,// глубина сглаживания double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: void JurXInit(uint begin, int Din, double Length, double series, uint bar ); //----+ Объявление глобальных переменных double m_AB,m_AC; double m_f1,m_f2,m_f3,m_f4,m_f5; double m_f6,m_Kg,m_Hg,m_F1,m_F2; double m_F3,m_F4,m_F5,m_F6,m_w; }; //+------------------------------------------------------------------+ //| Алгоритмы усреднения Тушара Чанда для произвольных ценовых рядов | //+------------------------------------------------------------------+ class CCMO : public CMovSeriesTools { public: double VIDYASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int CMO_Length,// CMO период double EMA_Length, double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); double CMOSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int CMO_Length,// CMO период double series, uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: double m_dSeriesArray[]; int m_Size_,m_count; double m_UpSum_,m_UpSum,m_DnSum_,m_DnSum,m_Vidya,m_Vidya_; double m_AbsCMO_,m_AbsCMO,m_series1,m_series1_,m_SmoothFactor; }; //+------------------------------------------------------------------+ //| Алгоритм получения индикатора АМА от произвольных ценовых рядов | //+------------------------------------------------------------------+ class CAMA : public CMovSeriesTools { public: double AMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// период AMA int Fast_Length, // период быстрой скользящей int Slow_Length, // период медленной скользящей double Rate,// степень, в которую возводится сглаживающая константа double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: //----+ double m_SeriesArray[]; double m_dSeriesArray[]; double m_NOISE,m_noise; double m_Ama,m_AMA_,m_slowSC,m_fastSC,m_dSC; int m_Size_1,m_Size_2,m_count; }; //+------------------------------------------------------------------+ //| Алгоритм параболического усреднения произвольных ценовых рядов | //+------------------------------------------------------------------+ class CParMA : public CMovSeriesTools { public: double ParMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: void ParMAInit(double Length); double m_SeriesArray[]; int m_Size_,m_count; int m_sum_x,m_sum_x2,m_sum_x3,m_sum_x4; }; //+------------------------------------------------------------------+ //| Алгоритм моментума (версия Мерфи!) от произвольных ценовых рядов | //+------------------------------------------------------------------+ class CMomentum : public CMovSeriesTools { public: double MomentumSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: double m_SeriesArray[]; int m_Size_,m_count; }; //+------------------------------------------------------------------+ //| Алгоритм нормированного моментума от произвольных ценовых рядов | //+------------------------------------------------------------------+ class CnMomentum : public CMovSeriesTools { public: double nMomentumSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: double m_SeriesArray[]; int m_Size_,m_count; }; //+------------------------------------------------------------------+ //| Алгоритм Скорость изменения от произвольных ценовых рядов | //+------------------------------------------------------------------+ class CROC : public CMovSeriesTools { public: double ROCSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); protected: double m_SeriesArray[]; int m_Size_,m_count; }; //+------------------------------------------------------------------+ //| Функции для усреднения ценовых рядов цифровым фильтром FATL | //+------------------------------------------------------------------+ class CFATL : public CMovSeriesTools { public: double FATLSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); CFATL(); protected: double m_SeriesArray[39]; int m_Size_,m_count; double m_FATL; //---- объявление и инициализация массива для коэффициентов цифрового фильтра double m_FATLTable[39]; }; //+------------------------------------------------------------------+ //| Функции для усреднения ценовых рядов цифровым фильтром SATL | //+------------------------------------------------------------------+ class CSATL : public CMovSeriesTools { public: double SATLSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); CSATL(); protected: double m_SeriesArray[65]; int m_Size_,m_count; double m_SATL; //---- объявление и инициализация массива для коэффициентов цифрового фильтра double m_SATLTable[65]; }; //+------------------------------------------------------------------+ //| Функции для усреднения ценовых рядов цифровым фильтром RFTL | //+------------------------------------------------------------------+ class CRFTL : public CMovSeriesTools { public: double RFTLSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); CRFTL(); protected: double m_SeriesArray[44]; int m_Size_,m_count; double m_RFTL; //---- объявление и инициализация массива для коэффициентов цифрового фильтра double m_RFTLTable[44]; }; //+------------------------------------------------------------------+ //| Функции для усреднения ценовых рядов цифровым фильтром RSTL | //+------------------------------------------------------------------+ class CRSTL : public CMovSeriesTools { public: double RSTLSeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); CRSTL(); protected: double m_SeriesArray[99]; int m_Size_,m_count; double m_RSTL; //---- объявление и инициализация массива для коэффициентов цифрового фильтра double m_RSTLTable[99]; }; //+------------------------------------------------------------------+ //| Алгоритм универсального усреднения | //+------------------------------------------------------------------+ class CXMA { public: enum Smooth_Method { MODE_SMA_, //SMA MODE_EMA_, //EMA MODE_SMMA_, //SMMA MODE_LWMA_, //LWMA MODE_JJMA, //JJMA MODE_JurX, //JurX MODE_ParMA, //ParMA MODE_T3, //T3 MODE_VIDYA, //VIDYA MODE_AMA //AMA }; double XMASeries(uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике // 0 - запрет изменения параметров, любое другое значение - разрешение. Smooth_Method Method, int Phase,// параметр, изменяющийся в пределах -100 ... +100, //влияет на качество переходного процесса усреднения int Length,// глубина сглаживания double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ); int GetStartBars(Smooth_Method Method,int Length,int Phase); string GetString_MA_Method(Smooth_Method Method); void XMAPhaseCheck(string PhaseName,int ExternPhase,Smooth_Method Method); void XMALengthCheck(string LengthName,int ExternLength); void XMAInit(Smooth_Method Method); CXMA(){m_init=false;}; ~CXMA(); protected: CMoving_Average *SMA; CMoving_Average *EMA; CMoving_Average *SMMA; CMoving_Average *LWMA; CJJMA *JJMA; CJurX *JurX; CParMA *ParMA; CT3 *T3; CCMO *VIDYA; CAMA *AMA; bool m_init; Smooth_Method m_Method; }; //+------------------------------------------------------------------+ //| расчёт минимального количества необходимых баров алгоритма XMA | //+------------------------------------------------------------------+ int GetStartBars(Smooth_Method Method,int Length,int Phase) { //----+ switch(Method) { case MODE_SMA_: return(Length); case MODE_EMA_: return(0); case MODE_SMMA_: return(Length+1); case MODE_LWMA_: return(Length); case MODE_JJMA: return(30); case MODE_JurX: return(0); case MODE_ParMA: return(Length); case MODE_T3: return(0); case MODE_VIDYA: return(Phase+2); case MODE_AMA: return(Length+2); } //----+ return(0); } //Version May 1, 2010 //+------------------------------------------------------------------+ //| iPriceSeries.mqh | //| Copyright © 2010, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+------------------------------------------------------------------+ /* * Функция iPriceSeries() возвращает входную цену бара по его номеру * bar и по номеру цены applied_price: * 1-CLOSE, 2-OPEN, 3-HIGH, 4-LOW, 5-MEDIAN, 6-TYPICAL, 7-WEIGHTED, * 8-SIMPL, 9-QUARTER, 10-TRENDFOLLOW, 11-0.5 * TRENDFOLLOW, 12-Demark Price. * * Пример: * double dPrice = iPriceSeries("GBPJPY", 240, 5, bar, true) * - iPriceSeries("GBPJPY", 240, 5, bar + 1, true); */ //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ /* //---- объявление и инициализация перечисления типов ценовых констант enum Applied_price_ //Тип константы { PRICE_CLOSE_ = 1, //Close PRICE_OPEN_, //Open PRICE_HIGH_, //High PRICE_LOW_, //Low PRICE_MEDIAN_, //Median Price (HL/2) PRICE_TYPICAL_, //Typical Price (HLC/3) PRICE_WEIGHTED_, //Weighted Close (HLCC/4) PRICE_SIMPL_, //Simpl Price (OC/2) PRICE_QUARTER_, //Quarted Price (HLOC/4) PRICE_TRENDFOLLOW0_, //TrendFollow_1 Price PRICE_TRENDFOLLOW1_, //TrendFollow_2 Price PRICE_DEMARK_ //Demark Price }; */ //+------------------------------------------------------------------+ //| PriceSeries() function | //+------------------------------------------------------------------+ double PriceSeries ( uint applied_price,// Ценовая константа uint bar,// Индекс сдвига относительно текущего бара на указанное количество периодов назад или вперёд). const double &dOpen[], const double &dLow[], const double &dHigh[], const double &dClose[] ) //PriceSeries(applied_price, bar, dOpen, dLow, dHigh, dClose) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ switch(applied_price) { //----+ Ценовые константы из перечисления ENUM_APPLIED_PRICE case PRICE_CLOSE: return(dClose[bar]); case PRICE_OPEN: return(dOpen [bar]); case PRICE_HIGH: return(dHigh [bar]); case PRICE_LOW: return(dLow[bar]); case PRICE_MEDIAN: return((dHigh[bar]+dLow[bar])/2.0); case PRICE_TYPICAL: return((dClose[bar]+dHigh[bar]+dLow[bar])/3.0); case PRICE_WEIGHTED: return((2*dClose[bar]+dHigh[bar]+dLow[bar])/4.0); //----+ case 8: return((dOpen[bar] + dClose[bar])/2.0); case 9: return((dOpen[bar] + dClose[bar] + dHigh[bar] + dLow[bar])/4.0); //---- case 10: { if(dClose[bar]>dOpen[bar]) return(dHigh[bar]); else { if(dClose[bar]dOpen[bar])return((dHigh[bar]+dClose[bar])/2.0); else { if(dClose[bar]dOpen[bar]) res=(res+dHigh[bar])/2; if(dClose[bar]==dOpen[bar]) res=(res+dClose[bar])/2; return(((res-dLow[bar])+(res-dHigh[bar]))/2); } //---- default: return(dClose[bar]); } //----+ //return(0); } //+------------------------------------------------------------------+ //| iPriceSeries() function | //+------------------------------------------------------------------+ /*double iPriceSeries ( string symbol,// Символьное имя инструмента. NULL означает текущий символ. ENUM_TIMEFRAMES timeframe,// Период. Может быть одним из периодов графика. 0 означает период текущего графика. uint applied_price,// Ценовая константа uint bar,// Индекс сдвига относительно текущего бара на указанное количество периодов назад или вперёд). bool set // Направление индексирования массивов. ) //iPriceSeries(symbol, timeframe, applied_price, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ uint Bar; double Open_,Low_,High_,Close_; double diPriceSeries,price; //---- if(!set)Bar=iBars(symbol,timeframe)-1-bar; else Bar=bar; //---- switch(applied_price) { case 1: diPriceSeries=iClose(symbol, timeframe, Bar); break; case 2: diPriceSeries=iOpen(symbol, timeframe, Bar); break; case 3: diPriceSeries=iHigh(symbol, timeframe, Bar); break; case 4: diPriceSeries=iLow(symbol, timeframe, Bar); break; //---- case 5: price=iHigh(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries=price; price=iLow(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries+=price; diPriceSeries/=2.0; break; //---- case 6: price=iClose(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries=price; price=iHigh(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; price=iLow(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; diPriceSeries/=3.0; break; //---- case 7: price=iClose(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries=price*2; price=iHigh(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; price=iLow(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; diPriceSeries/=4.0; break; //---- case 8: price=iClose(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries=price; price=iOpen(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; diPriceSeries/=2.0; break; //---- case 9: price=iClose(symbol, timeframe, Bar); diPriceSeries=price; price=iOpen(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; price=iHigh(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; price=iLow(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries += price; diPriceSeries/=4.0; break; //---- case 10: { price=iClose(symbol, timeframe, Bar); if(!price) return(0); Close_= price; price=iOpen(symbol, timeframe, Bar); if(!price) return(0); Open_ = price; price=iHigh(symbol, timeframe, Bar); if(!price) return(0); High_ = price; price=iLow(symbol, timeframe, Bar); if(!price) return(0); Low_ = price; //---- if(Close_>Open_)diPriceSeries=High_; else { if(Close_Open_)diPriceSeries=(High_+Close_)/2.0; else { if(Close_Open_) res=(res+High_)/2; if(Close_==Open_) res=(res+Close_)/2; diPriceSeries=((res-Low_)+(res-High_))/2; break; } //---- default: price=iClose(symbol, timeframe, Bar); if(!price) return(0); diPriceSeries=price; break; } //----+ return(diPriceSeries); }*/ double iPriceSeries ( string symbol,// Символьное имя инструмента. NULL означает текущий символ. ENUM_TIMEFRAMES timeframe,// Период. Может быть одним из периодов графика. 0 означает период текущего графика. uint applied_price,// Ценовая константа uint bar,// Индекс сдвига относительно текущего бара на указанное количество периодов назад или вперёд). bool set // Направление индексирования массивов. ) //iPriceSeries(symbol, timeframe, applied_price, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ uint Bar; double diPriceSeries,price[1]; double Open_[1],Low_[1],High_[1],Close_[1]; //---- if(!set) Bar=Bars(symbol,timeframe)-1-bar; else Bar=bar; //---- switch(applied_price) { case 1: CopyClose(symbol, timeframe, Bar, 1, price); diPriceSeries = price[0]; break; case 2: CopyOpen (symbol, timeframe, Bar, 1, price); diPriceSeries = price[0]; break; case 3: CopyHigh (symbol, timeframe, Bar, 1, price); diPriceSeries = price[0]; break; case 4: CopyLow (symbol, timeframe, Bar, 1, price); diPriceSeries = price[0]; break; //---- case 5: CopyHigh(symbol,timeframe,Bar,1,price); diPriceSeries=price[0]; CopyLow(symbol,timeframe,Bar,1,price); diPriceSeries+=price[0]; diPriceSeries/=2.0; break; //---- case 6: CopyClose(symbol,timeframe,Bar,1,price); diPriceSeries=price[0]; CopyHigh (symbol, timeframe, Bar, 1, price); diPriceSeries += price[0]; CopyLow (symbol, timeframe, Bar, 1, price); diPriceSeries += price[0]; diPriceSeries/=3.0; break; //---- case 7: CopyClose(symbol,timeframe,Bar,1,price); diPriceSeries=price[0]*2; CopyHigh (symbol, timeframe, Bar, 1, price); diPriceSeries += price[0]; CopyLow (symbol, timeframe, Bar, 1, price); diPriceSeries += price[0]; diPriceSeries/=4.0; break; //---- case 8: CopyClose(symbol,timeframe,Bar,1,price); diPriceSeries=price[0]; CopyOpen(symbol,timeframe,Bar,1,price); diPriceSeries+=price[0]; diPriceSeries/=2.0; break; //---- case 9: CopyClose(symbol,timeframe,Bar,1,price); diPriceSeries=price[0]; CopyOpen (symbol, timeframe, Bar, 1, price); diPriceSeries += price[0]; CopyHigh (symbol, timeframe, Bar, 1, price); diPriceSeries += price[0]; CopyLow (symbol, timeframe, Bar, 1, price); diPriceSeries += price[0]; diPriceSeries/=4.0; break; //---- case 10: { CopyClose(symbol,timeframe,Bar,1,Close_); CopyOpen(symbol,timeframe,Bar,1,Open_); CopyHigh(symbol,timeframe,Bar,1,High_); CopyLow(symbol,timeframe,Bar,1,Low_); //---- if(Close_[0]>Open_[0])diPriceSeries=High_[0]; else { if(Close_[0]Open_[0])diPriceSeries=(High_[0]+Close_[0])/2.0; else { if(Close_[0]Open_[0]) res=(res+High_[0])/2; if(Close_[0]==Open_[0]) res=(res+Close_[0])/2; diPriceSeries=((res-Low_[0])+(res-High_[0]))/2; break; } //---- default: CopyClose(symbol,timeframe,Bar,1,price); diPriceSeries=price[0]; break; } //----+ return(diPriceSeries); } //+------------------------------------------------------------------+ //| iPriceSeriesAlert() function | //+------------------------------------------------------------------+ /* * Функция iPriceSeriesAlert() предназначена для индикации недопустимого * значения параметра applied_price передаваемого в функцию iPriceSeries(). */ void iPriceSeriesAlert(uchar applied_price) { //----+ if(applied_price<1) Alert("Параметр applied_price должен быть не менее 1. Вы ввели недопустимое ", applied_price," будет использовано 1"); //----+ if(applied_price>12) Alert("Параметр applied_price должен быть не более 12. Вы ввели недопустимое ", applied_price," будет использовано 1"); //----+ } //+------------------------------------------------------------------+ //| Классические алгоритмы усреднения | //+------------------------------------------------------------------+ double CMoving_Average::MASeries ( uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения ENUM_MA_METHOD MA_Method,// Метод усреднения (MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA) double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ) // MASeries(begin, prev_calculated, Length, MA_Method, series, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ switch(MA_Method) { case MODE_SMA: return(SMASeries (begin, prev_calculated, rates_total, Length, series, bar, set)); case MODE_EMA: return(EMASeries (begin, prev_calculated, rates_total, Length, series, bar, set)); case MODE_SMMA: return(SMMASeries(begin, prev_calculated, rates_total, Length, series, bar, set)); case MODE_LWMA: return(LWMASeries(begin, prev_calculated, rates_total, Length, series, bar, set)); default: { if(bar==begin) { string word; StringConcatenate(word,__FUNCTION__,"():", " Параметр MA_Method должен быть от MODE_SMA до MODE_LWMA.", " Вы ввели недопустимое ",MA_Method," будет использовано MODE_SMA!"); Print(word); } return(SMASeries(begin,prev_calculated,rates_total,Length,series,bar,set)); } } //----+ } //+------------------------------------------------------------------+ //| Простое усреднение | //+------------------------------------------------------------------+ double CMoving_Average::SMASeries ( uint begin,// Номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов ) // SMASeries(begin, prev_calculated, rates_total, Length, series, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ Проверка начала достоверного отсчёта баров if(BarCheck1(begin,bar,set)) return(EMPTY_VALUE); //----+ Объявление локальных переменных int iii,kkk; double sma; //----+ проверка внешего параметра Length на корректность LengthCheck(Length); //----+ Изменение размеров массива переменных if(bar==begin && !SeriesArrayResize(__FUNCTION__,Length,m_SeriesArray,m_Size_)) return(EMPTY_VALUE); //----+ перестановка и инициализация ячеек массива m_SeriesArray Recount_ArrayZeroPos(m_count,Length,prev_calculated,rates_total,series,bar,m_SeriesArray,set); //----+ Инициализация нуля if(BarCheck2(begin,bar,set,Length)) { m_sum=0.0; for(iii=1; iii>> if(m_Loop1>30) { if(!m_start) { m_start= true; shift1 = 1; back=29; //---- m_ser2 = m_array[1]; m_ser1 = m_ser2; } else back=0; //-S-S-S-S-+ for(int rrr=back; rrr>=0; rrr--) { if(rrr==0) ser0=series; else ser0=m_array[31-rrr]; //---- dser1 = ser0 - m_ser1; dser2 = ser0 - m_ser2; //---- if(MathAbs(dser1)>MathAbs(dser2)) m_var2=MathAbs(dser1); else m_var2=MathAbs(dser2); //---- Res=m_var2; newvel=Res+0.0000000001; if(m_count1<=1) m_count1=127; else m_count1--; //---- if(m_count2<=1) m_count2=10; else m_count2--; //---- if(m_count3<128) m_count3++; //---- m_Sum1+=newvel-m_hoop2[m_count2]; //---- m_hoop2[m_count2]=newvel; m_bhoop2[m_count2]=true; //---- if(m_count3>10) SmVel=m_Sum1/10.0; else SmVel=m_Sum1/m_count3; //---- if(m_count3>127) { hoop1=m_hoop1[m_count1]; m_hoop1[m_count1]=SmVel; m_bhoop1[m_count1]=true; numb = 64; posB = numb; //---- while(numb>1) { if(m_data[posB]127) { m_midd2--; posB=m_midd2; } else { m_midd1++; posB=m_midd1; } //---- if(m_midd1>96) m_pos2=96; else m_pos2=m_midd1; //---- if(m_midd2<32) m_pos1=32; else m_pos1=m_midd2; } //---- numb = 64; posA = numb; //---- while(numb>1) { if(m_data[posA]>=SmVel) { if(m_data[posA-1]<=SmVel) numb=1; else { numb /= 2.0; posA -= numb; } } else { numb /= 2.0; posA += numb; } //---- if(posA==127) if(SmVel>m_data[127]) posA=128; } //---- if(m_count3>127) { if(posB>=posA) { if(m_pos2+1>posA) if(m_pos1-1posA) if(m_pos1-1=posA) { if(m_pos2+1posB) m_Sum2+=m_data[m_pos2+1]; } else if(m_pos2+2>posA) m_Sum2+=SmVel; //---- else if(m_pos2+1posB) m_Sum2+=m_data[m_pos2+1]; //---- if(posB>posA) { if(m_pos1-1posB) m_Sum2-=m_data[posB]; //---- else if(m_pos2posA) m_Sum2-=m_data[m_pos2]; } else { if(m_pos2+1>posB && m_pos1-1posB) if(m_pos1-0=posA; numb--) { m_data[numb+1]=m_data[numb]; m_bdata[numb+1]=true; } //---- m_data[posA]=SmVel; m_bdata[posA]=true; } //---- if(m_count3<=127) { m_Sum2=0; for(numb=m_pos1; numb<=m_pos2; numb++) m_Sum2+=m_data[numb]; } //---- resalt=m_Sum2/(m_pos2-m_pos1+1.0); //---- if(m_Loop2>30) m_Loop2=31; else m_Loop2++; //---- if(m_Loop2<=30) { if(dser1>0.0) m_ser1=ser0; else m_ser1=ser0-dser1*m_Kct; //---- if(dser2<0.0) m_ser2=ser0; else m_ser2=ser0-dser2*m_Kct; //---- m_JMA=series; //---- if(m_Loop2!=30) continue; else { m_storage1=series; if(MathCeil(m_Krx)>=1) dSupr=MathCeil(m_Krx); else dSupr=1.0; //---- if(dSupr>0) Suprem2=MathFloor(dSupr); else { if(dSupr<0) Suprem2=MathCeil(dSupr); else Suprem2=0.0; } //---- if(MathFloor(m_Krx)>=1) m_var2=MathFloor(m_Krx); else m_var2=1.0; //---- if(m_var2>0) Suprem1=MathFloor(m_var2); else { if(m_var2<0) Suprem1=MathCeil(m_var2); else Suprem1=0.0; } //---- if(Suprem2==Suprem1) factor=1.0; else { dSupr=Suprem2-Suprem1; factor=(m_Krx-Suprem1)/dSupr; } //---- if(Suprem1<=29) shift1=(int)Suprem1; else shift1=29; //---- if(Suprem2<=29) shift2=(int)Suprem2; else shift2=29; dser3 = series - m_array[m_Loop1 - shift1]; dser4 = series - m_array[m_Loop1 - shift2]; //---- m_djma=dser3 *(1.0-factor)/Suprem1+dser4*factor/Suprem2; } } else { if(resalt) ResPow=MathPow(Res/resalt,m_degree); else ResPow=0.0; //---- if(m_Kfd>=ResPow) m_var1= ResPow; else m_var1=m_Kfd; //---- if(m_var1<1.0)m_var2=1.0; else { if(m_Kfd>=ResPow) m_sense=ResPow; else m_sense=m_Kfd; m_var2=m_sense; } //---- extent=m_var2; Pow1=MathPow(m_Kct,MathSqrt(extent)); //---- if(dser1>0.0) m_ser1=ser0; else m_ser1=ser0-dser1*Pow1; //---- if(dser2<0.0) m_ser2=ser0; else m_ser2=ser0-dser2*Pow1; } } //---- if(m_Loop2>30) { Pow2=MathPow(m_Krj,extent); //---- m_storage1 *= Pow2; m_storage1 += (1.0 - Pow2) * series; m_storage2 *= m_Krj; m_storage2 += (series - m_storage1) * (1.0 - m_Krj); //---- Extr=m_Phase*m_storage2+m_storage1; //---- Pow2x2= Pow2 * Pow2; ratio = Pow2x2-2.0 * Pow2+1.0; m_djma *= Pow2x2; m_djma += (Extr - m_JMA) * ratio; //---- m_JMA+=m_djma; } } //-x-x-x-x-x-x-x-+ if(m_Loop1<=30) return(EMPTY_VALUE); jjma=m_JMA; //----+ Восстановление значений переменных if(BarCheck5(rates_total,bar,set)) { //---- Восстановление изменённых ячеек массивов из пямяти for(numb = 0; numb < 128; numb++) if(m_bhoop1[numb]) m_hoop1[numb] = m_hoop1_[numb]; for(numb = 0; numb < 11; numb++) if(m_bhoop2[numb]) m_hoop2[numb] = m_hoop2_[numb]; for(numb = 0; numb < 128; numb++) if(m_bdata [numb]) m_data [numb] = m_data_ [numb]; //---- Обнуление номеров изменённых ячеек массивов ArrayInitialize(m_bhoop1,false); ArrayInitialize(m_bhoop2,false); ArrayInitialize(m_bdata,false); //---- запись значений переменных из пямяти m_JMA=m_JMA_; m_djma = m_djma_; m_ser1 = m_ser1_; m_ser2 = m_ser2_; m_Sum2 = m_Sum2_; m_pos1 = m_pos1_; m_pos2 = m_pos2_; m_Sum1 = m_Sum1_; m_Loop1 = m_Loop1_; m_Loop2 = m_Loop2_; m_count1 = m_count1_; m_count2 = m_count2_; m_count3 = m_count3_; m_storage1 = m_storage1_; m_storage2 = m_storage2_; m_midd1 = m_midd1_; m_midd2 = m_midd2_; } //----+ Сохранение значений переменных if(BarCheck4(rates_total,bar,set)) { //---- запись изменённых ячеек массивов в пямять for(numb = 0; numb < 128; numb++) if(m_bhoop1[numb]) m_hoop1_[numb] = m_hoop1[numb]; for(numb = 0; numb < 11; numb++) if(m_bhoop2[numb]) m_hoop2_[numb] = m_hoop2[numb]; for(numb = 0; numb < 128; numb++) if(m_bdata [numb]) m_data_ [numb] = m_data [numb]; //---- Обнуление номеров изменённых ячеек массивов ArrayInitialize(m_bhoop1,false); ArrayInitialize(m_bhoop2,false); ArrayInitialize(m_bdata,false); //---- запись значений переменных в пямять m_JMA_=m_JMA; m_djma_ = m_djma; m_Sum2_ = m_Sum2; m_ser1_ = m_ser1; m_ser2_ = m_ser2; m_pos1_ = m_pos1; m_pos2_ = m_pos2; m_Sum1_ = m_Sum1; m_Loop1_ = m_Loop1; m_Loop2_ = m_Loop2; m_count1_ = m_count1; m_count2_ = m_count2; m_count3_ = m_count3; m_storage1_ = m_storage1; m_storage2_ = m_storage2; m_midd1_ = m_midd1; m_midd2_ = m_midd2; } //----+ Завершение вычислений функции JMASeries() return(jjma); } //+------------------------------------------------------------------+ //| Инициализация переменных алгоритма JMA | //+------------------------------------------------------------------+ void CJJMA::JJMAInit ( uint begin, int Din, double Phase, double Length, double series, uint bar ) // JMAInit(begin, Din, Phase, Length, series, bar) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //----+ <<< Расчёт коэффициентов >>> if(bar==begin || Din!=0) { if(bar==begin) { m_midd1 = 63; m_midd2 = 64; m_start = false; int numb= 0; //---- for(numb = 0; numb <= m_midd1; numb++) m_data[numb] = -1000000.0; for(numb = m_midd2; numb <= 127; numb++) m_data[numb] = +1000000.0; //----+ Все ячейки массивов должны быть переписаны ArrayInitialize(m_bhoop1,true); ArrayInitialize(m_bhoop2,true); ArrayInitialize(m_bdata,true); //----+ Удаление мусора из массивов при повторных инициализациях ArrayInitialize(m_hoop1_, 0.0); ArrayInitialize(m_hoop2_, 0.0); ArrayInitialize(m_hoop1, 0.0); ArrayInitialize(m_hoop2, 0.0); ArrayInitialize(m_array, 0.0); //---- m_djma = 0.0; m_Sum1 = 0.0; m_Sum2 = 0.0; m_ser1 = 0.0; m_ser2 = 0.0; m_pos1 = 0.0; m_pos2 = 0.0; m_Loop1 = 0.0; m_Loop2 = 0.0; m_count1 = 0.0; m_count2 = 0.0; m_count3 = 0.0; m_storage1 = 0.0; m_storage2 = 0.0; m_JMA=series; } if(Phase>=-100 && Phase<=100) m_Phase=Phase/100.0+1.5; //---- if(Phase > +100) m_Phase = 2.5; if(Phase < -100) m_Phase = 0.5; //---- double velA,velB,velC,velD; //---- if(Length>=1.0000000002) velA=(Length-1.0)/2.0; else velA=0.0000000001; //---- velA *= 0.9; m_Krj = velA / (velA + 2.0); velC = MathSqrt(velA); velD = MathLog(velC); m_var1= velD; m_var2= m_var1; //---- velB=MathLog(2.0); m_sense=(m_var2/velB)+2.0; if(m_sense<0.0) m_sense=0.0; m_Kfd=m_sense; //---- if(m_Kfd>=2.5) m_degree=m_Kfd-2.0; else m_degree=0.5; //---- m_Krx = velC * m_Kfd; m_Kct = m_Krx / (m_Krx + 1.0); } //----+ } //+------------------------------------------------------------------+ //| Проверка глубины усреднения Lengt на корректность | //+------------------------------------------------------------------+ void CJJMA::JJMALengthCheck(string LengthName,int ExternLength) // Jm_JMALengthCheck(LengthName, ExternLength) { //----+ //---- сброс сообщений при недопустимых значениях входных параметров if(ExternLength<1) { string word; StringConcatenate (word,__FUNCTION__," (): Параметр ",LengthName, " должен быть не менее 1. Вы ввели недопустимое ", ExternLength," будет использовано 1"); Print(word); return; } //----+ } //+------------------------------------------------------------------+ //| Проверка параметра усреднения Phase на корректность | //+------------------------------------------------------------------+ void CJJMA::JJMAPhaseCheck(string PhaseName,int ExternPhase) // Jm_JMAPhaseCheck(PhaseName, ExternPhase) { //----+ string word; //---- сброс сообщений при недопустимых значениях входных параметров if(ExternPhase<-100) { StringConcatenate(word,string(__FUNCTION__)," (): Параметр ",PhaseName, " должен быть не менее -100. Вы ввели недопустимое ", ExternPhase," будет использовано -100"); Print(word); return; } //---- if(ExternPhase>+100) { StringConcatenate(word,__FUNCTION__," (): Параметр ",PhaseName, " должен быть не более +100. Вы ввели недопустимое ", ExternPhase," будет использовано +100"); Print(word); return; } //----+ } //+------------------------------------------------------------------+ //| T3 усреднение | //+------------------------------------------------------------------+ double CT3::T3Series ( uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Din,// разрешение изменять параметр Length на каждом баре. // 0 - запрет изменения параметров, любое другое значение - разрешение. double Curvature,// Коэффициент (для удобства его величина измерения увеличина в сто раз!) double Length,// глубина сглаживания double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ) // T3Series(begin, prev_calculated, rates_total, Din, Curvature, Length, series, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //---- Проверка начала достоверного отсчёта баров if(BarCheck1(begin,bar,set)) return(EMPTY_VALUE); //----+ Объявление локальных переменных double e0,T3_; //----+ проверка внешего параметра Length на корректность LengthCheck(Length); //----+ Расчёт коэффициентов T3Init(begin,Din,Curvature,Length,series,bar); e0=series; //----+ <<< вычисление T3 >>> m_e1 = m_w1 * e0 + m_w2 * m_e1; m_e2 = m_w1 * m_e1 + m_w2 * m_e2; m_e3 = m_w1 * m_e2 + m_w2 * m_e3; m_e4 = m_w1 * m_e3 + m_w2 * m_e4; m_e5 = m_w1 * m_e4 + m_w2 * m_e5; m_e6 = m_w1 * m_e5 + m_w2 * m_e6; //---- T3_=m_c1*m_e6+m_c2*m_e5+m_c3*m_e4+m_c4*m_e3; //----+ Восстановление значений переменных if(BarCheck5(rates_total,bar,set)) { m_e1 = m_E1; m_e2 = m_E2; m_e3 = m_E3; m_e4 = m_E4; m_e5 = m_E5; m_e6 = m_E6; } //----+ Сохранение значений переменных if(BarCheck4(rates_total,bar,set)) { m_E1 = m_e1; m_E2 = m_e2; m_E3 = m_e3; m_E4 = m_e4; m_E5 = m_e5; m_E6 = m_e6; } //----+ завершение вычислений значения функции T3Series() return(T3_); } //+------------------------------------------------------------------+ //| Инициализация переменных алгоритма T3 | //+------------------------------------------------------------------+ void CT3::T3Init ( uint begin, int Din, double Curvature, double Length, double series, uint bar ) // T3InitInit(begin, Din, Curvature, Length, series, bar) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //----+ <<< Расчёт коэффициентов >>> if(bar==begin || Din!=0) { double b=Curvature/100.0; m_b2 = b * b; m_b3 = m_b2 * b; m_c1 = -m_b3; m_c2 = (3 * (m_b2 + m_b3)); m_c3 = -3 * (2 * m_b2 + b + m_b3); m_c4 = (1 + 3 * b + m_b3 + 3 * m_b2); double n=1+0.5 *(Length-1); m_w1 = 2 / (n + 1); m_w2 = 1 - m_w1; if(bar==begin) { m_e1 = series; m_e2 = series; m_e3 = series; m_e4 = series; m_e5 = series; m_e6 = series; } } //----+ } //+------------------------------------------------------------------+ //| Ультралинейное усреднение | //+------------------------------------------------------------------+ double CJurX::JurXSeries ( uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Din,// разрешение изменять параметр Length на каждом баре // 0 - запрет изменения параметров, любое другое значение - разрешение double Length,// глубина сглаживания double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ) // JurXSeries(begin, prev_calculated, rates_total, Din, Length, series, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //---- Проверка начала достоверного отсчёта баров if(BarCheck1(begin,bar,set)) return(EMPTY_VALUE); //----+ Объявление локальных переменных double V1,V2,JurX_; //----+ проверка внешего параметра Length на корректность LengthCheck(Length); //----+ Инициализация коэффициентов JurXInit(begin,Din,Length,series,bar); //---- <<< вычисление JurX >>> m_f1 = m_Hg * m_f1 + m_Kg * series; m_f2 = m_Kg * m_f1 + m_Hg * m_f2; V1 = m_AC * m_f1 - m_AB * m_f2; m_f3 = m_Hg * m_f3 + m_Kg * V1; m_f4 = m_Kg * m_f3 + m_Hg * m_f4; V2 = m_AC * m_f3 - m_AB * m_f4; m_f5 = m_Hg * m_f5 + m_Kg * V2; m_f6 = m_Kg * m_f5 + m_Hg * m_f6; JurX_ = m_AC * m_f5 - m_AB * m_f6; //----+ Восстановление значений переменных if(BarCheck5(rates_total,bar,set)) { m_f1 = m_F1; m_f2 = m_F2; m_f3 = m_F3; m_f4 = m_F4; m_f5 = m_F5; m_f6 = m_F6; } //----+ Сохранение значений переменных if(BarCheck4(rates_total,bar,set)) { m_F1 = m_f1; m_F2 = m_f2; m_F3 = m_f3; m_F4 = m_f4; m_F5 = m_f5; m_F6 = m_f6; } //----+ завершение вычислений значения функции JurX.Series return(JurX_); } //+------------------------------------------------------------------+ //| Инициализация переменных алгоритма JurX | //+------------------------------------------------------------------+ void CJurX::JurXInit ( uint begin, int Din, double Length, double series, uint bar ) // JurXInit(begin, Din, Length, series, bar) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ if(bar==begin || Din!=0) { if(Length>=6) m_w=Length-1; else m_w=5; m_Kg = 3 / (Length + 2.0); m_Hg = 1.0 - m_Kg; //---- if(bar==begin) { m_f1 = series; m_f2 = series; m_f3 = series; m_f4 = series; m_f5 = series; m_f6 = series; m_AB = 0.5; m_AC = 1.5; } } //----+ } //+------------------------------------------------------------------+ //| Параболлическое усреднение | //+------------------------------------------------------------------+ double CParMA::ParMASeries ( uint begin,// Номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// Период усреднения double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов ) // SMASeries(Number, symbol, timeframe, begin, limit, Length, series, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //---- Проверка начала достоверного отсчёта баров if(BarCheck1(begin,bar,set)) return(EMPTY_VALUE); //----+ Объявление локальных переменных int iii,kkk; //---- double S,B0,B1,B2,parma; double A,B,C,D,E,F; double K,L,M,P,Q,R; double sum_y,sum_xy,sum_x2y,var_tmp; //----+ Изменение размеров массива переменных if(bar==begin && !SeriesArrayResize(__FUNCTION__,Length,m_SeriesArray,m_Size_)) return(EMPTY_VALUE); //----+ проверка внешего параметра Length на корректность LengthCheck(Length); //----+ перестановка и инициализация ячеек массива m_SeriesArray Recount_ArrayZeroPos(m_count,Length,prev_calculated,rates_total,series,bar,m_SeriesArray,set); //----+ Инициализация нуля if(BarCheck2(begin,bar,set,Length)) ParMAInit(Length); else if(BarCheck3(begin,bar,set,Length)) return(EMPTY_VALUE); //----+ Вычисление ParMA sum_y = 0.0; sum_xy = 0.0; sum_x2y = 0.0; //---- for(iii=1; iii<=Length; iii++) { kkk=Recount_ArrayNumber(m_count,Length,Length-iii); var_tmp = m_SeriesArray[kkk]; sum_y += var_tmp; sum_xy += iii * var_tmp; sum_x2y += iii * iii * var_tmp; } // разница между двумя ближайшими барами для sum_x2y: Sum(i=0; i 0) m_UpSum += dseries; if(dseries < 0) m_DnSum -= dseries; } m_AbsCMO=0.000000001; } else if(BarCheck3(begin,bar,set,CMO_Length+3)) { m_series1=series; return(EMPTY_VALUE); } dseries=m_dSeriesArray[m_count]; if(dseries > 0) m_UpSum += dseries; if(dseries < 0) m_DnSum -= dseries; if(m_UpSum+m_DnSum>0) m_AbsCMO=MathAbs((m_UpSum-m_DnSum)/(m_UpSum+m_DnSum)); abcmo=m_AbsCMO; //---- rrr=Recount_ArrayNumber(m_count,size,CMO_Length-1); dseries=m_dSeriesArray[rrr]; if(dseries > 0) m_UpSum -= dseries; if(dseries < 0) m_DnSum += dseries; //----+ Восстановление значений переменных if(BarCheck5(rates_total,bar,set)) { m_AbsCMO= m_AbsCMO_; m_UpSum = m_UpSum_; m_DnSum = m_DnSum_; m_series1=m_series1_; } else m_series1=series; //----+ Сохранение значений переменных if(BarCheck4(rates_total,bar,set)) { m_AbsCMO_=m_AbsCMO; m_UpSum_ = m_UpSum; m_DnSum_ = m_DnSum; m_series1_=m_series1; } //----+ return(abcmo); } //+------------------------------------------------------------------+ //| VIDYASeries() function | //+------------------------------------------------------------------+ double CCMO::VIDYASeries ( uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int CMO_Length,// CMO период double EMA_Length,// EMA период double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ) // VIDYASeries(begin, prev_calculated, rates_total, CMO_Length, EMA_Length, series, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //----+ Объявление локальных переменных double vidya,CMO_=CMOSeries(begin,prev_calculated,rates_total,CMO_Length,series,bar,set); //----+ Инициализация нуля if(BarCheck2(begin,bar,set,CMO_Length+3)) { m_Vidya=series; //---- Инициализация фактора сглаживания ЕМА m_SmoothFactor=2.0/(EMA_Length+1.0); } else if(BarCheck3(begin,bar,set,CMO_Length+3)) return(EMPTY_VALUE); //---- CMO_*=m_SmoothFactor; m_Vidya=CMO_*series+(1-CMO_)*m_Vidya; vidya=m_Vidya; //----+ Восстановление значений переменных if(BarCheck5(rates_total,bar,set)) { m_Vidya=m_Vidya_; } //----+ Сохранение значений переменных if(BarCheck4(rates_total,bar,set)) { m_Vidya_=m_Vidya; } //----+ return(vidya); } //+------------------------------------------------------------------+ //| Усреднение Кауфмана | //+------------------------------------------------------------------+ double CAMA::AMASeries ( uint begin,// номер начала достоверного отсчёта баров uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике int Length,// период AMA int Fast_Length, // период быстрой скользящей int Slow_Length, // период медленной скользящей double Rate,// степень, в которую возводится сглаживающая константа double series,// Значение ценового ряда, расчитанное для бара с номером bar uint bar,// Номер бара bool set // Направление индексирования массивов. ) // AMASeries(symbol, timeframe, begin, limit, Length, series, bar, set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //---- Проверка начала достоверного отсчёта баров if(BarCheck1(begin,bar,set)) return(EMPTY_VALUE); //----+ Объявление локальных переменных double signal,ER,ERSC,SSC,dprice,ama; int iii,kkk,rrr,size=Length+1; //----+ Изменение размеров массивов переменных if(bar==begin) if(!SeriesArrayResize(__FUNCTION__,size,m_SeriesArray,m_Size_1) || !SeriesArrayResize(__FUNCTION__,size,m_dSeriesArray,m_Size_2)) return(EMPTY_VALUE); //----+ проверка внешего параметра Length на корректность LengthCheck(Length); //----+ перестановка и инициализация ячеек массива m_SeriesArray Recount_ArrayZeroPos(m_count,size,prev_calculated,rates_total,series,bar,m_SeriesArray,set); //---- Проверка начала достаточности баров if(BarCheck1(begin+1,bar,set)) return(EMPTY_VALUE); kkk=Recount_ArrayNumber(m_count,size,1); dprice=series-m_SeriesArray[kkk]; m_dSeriesArray[m_count]=dprice; //----+ Инициализация нуля if(BarCheck2(begin,bar,set,Length+3)) { //---- инициализация констант rrr=Recount_ArrayNumber(m_count,size,1); m_Ama=m_SeriesArray[rrr]; m_slowSC = (2.0 / (Slow_Length + 1)); m_fastSC = (2.0 / (Fast_Length + 1)); m_dSC=m_fastSC-m_slowSC; m_noise=0.000000001; for(iii=1; iii+100) { StringConcatenate(word,__FUNCTION__," (): Параметр ",PhaseName, " должен быть не более +100. Вы ввели недопустимое ",ExternPhase," будет использовано +100"); Print(word); break;; } break; case MODE_JurX: break; case MODE_ParMA: break; case MODE_T3: break; if(ExternPhase<1) { StringConcatenate(word,__FUNCTION__," (): Параметр ",PhaseName, " должен быть не менее 1. Вы ввели недопустимое ",ExternPhase," будет использовано 1"); Print(word); break; } case MODE_VIDYA: if(ExternPhase<1) { StringConcatenate(word,__FUNCTION__," (): Параметр ",PhaseName, " должен быть не менее 1. Вы ввели недопустимое ",ExternPhase," будет использовано 1"); Print(word); break; } case MODE_AMA: if(ExternPhase<1) { StringConcatenate(word,__FUNCTION__," (): Параметр ",PhaseName, " должен быть не менее 1. Вы ввели недопустимое ",ExternPhase," будет использовано 1"); Print(word); break; } } //----+ } //+------------------------------------------------------------------+ //| Проверка глубины усреднения Lengt на корректность | //+------------------------------------------------------------------+ void CXMA::XMALengthCheck(string LengthName,int ExternLength) // XMALengthCheck(LengthName, ExternLength) { //----+ //---- сброс сообщений при недопустимых значениях входных параметров if(ExternLength<1) { string word=""; StringConcatenate (word,__FUNCTION__," (): Параметр ",LengthName, " должен быть не менее 1. Вы ввели недопустимое ", ExternLength," будет использовано 1"); Print(word); return; } //----+ } //+------------------------------------------------------------------+ //| Проверка периода усреднения на корректность | //+------------------------------------------------------------------+ void CMovSeriesTools::MALengthCheck(string LengthName,int ExternLength) // MALengthCheck(LengthName, ExternLength) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ if(ExternLength<1) { string word; StringConcatenate (word,__FUNCTION__," (): Параметр ",LengthName, " должен быть не менее 1. Вы ввели недопустимое ", ExternLength," будет использовано 1"); Print(word); return; } //----+ } //+------------------------------------------------------------------+ //| Проверка периода усреднения на корректность | //+------------------------------------------------------------------+ void CMovSeriesTools::MALengthCheck(string LengthName,double ExternLength) // MALengthCheck(LengthName, ExternLength) { //----+ if(ExternLength<1) { string word; StringConcatenate (word,__FUNCTION__," (): Параметр ",LengthName, " должен быть не менее 1. Вы ввели недопустимое ", ExternLength," будет использовано 1"); Print(word); return; } //----+ } //+------------------------------------------------------------------+ //| Проверка бара на его присутствие в диапозоне расчёта | //+------------------------------------------------------------------+ bool CMovSeriesTools::BarCheck1(int begin,int bar,bool Set) // BarCheck1(begin, bar, Set) { //----+ if((!Set && barbegin)) return(true); //----+ return(false); } //+------------------------------------------------------------------+ //| Проверка бара на старт расчёта | //+------------------------------------------------------------------+ bool CMovSeriesTools::BarCheck2(int begin,int bar,bool Set,int Length) // BarCheck2(begin, bar, Set, Length) { //----+ if((!Set && bar==begin+Length-1) || (Set && bar==begin-Length+1)) return(true); //----+ return(false); } //+------------------------------------------------------------------+ //| Проверка бара на отсутствие баров для усреднения | //+------------------------------------------------------------------+ bool CMovSeriesTools::BarCheck3(int begin,int bar,bool Set,int Length) // BarCheck3(begin, bar, Set, Length) { //----+ if((!Set && barbegin-Length+1)) return(true); //----+ return(false); } //+------------------------------------------------------------------+ //| Проверка бара на момент сохранения данных | //+------------------------------------------------------------------+ bool CMovSeriesTools::BarCheck4(int rates_total,int bar,bool Set) // BarCheck4(rates_total, bar, Set) { //----+ //----+ Сохранение значений переменных if((!Set && bar==rates_total-2) || (Set && bar==1)) return(true); //----+ return(false); } //+------------------------------------------------------------------+ //| Проверка бара на момент восстановления данных | //+------------------------------------------------------------------+ bool CMovSeriesTools::BarCheck5(int rates_total,int bar,bool Set) // BarCheck5(rates_total, begin, bar, set) { //----+ //----+ Восстановление значений переменных if((!Set && bar==rates_total-1) || (Set && bar==0)) return(true); //----+ return(false); } //+------------------------------------------------------------------+ //| Изменение некорректного периода усреднения | //+------------------------------------------------------------------+ void CMovSeriesTools::LengthCheck(int &ExternLength) // LengthCheck(LengthName, ExternLength) { //----+ if(ExternLength<1) ExternLength=1; //----+ } //+------------------------------------------------------------------+ //| Изменение некорректного периода усреднения | //+------------------------------------------------------------------+ void CMovSeriesTools::LengthCheck(double &ExternLength) // LengthCheck(ExternLength) { //----+ if(ExternLength<1) ExternLength=1; //----+ } //+------------------------------------------------------------------+ //| пересчёт позиции самого нового элемента в массиве | //+------------------------------------------------------------------+ void CMovSeriesTools::Recount_ArrayZeroPos ( int &count,// Возврат по ссылке номера текущего значения ценового ряда int Length, uint prev_calculated,// Количество истории в барах на предыдущем тике uint rates_total,// Количество истории в барах на текущем тике double series,// Значение ценового ряда, расчитанное для бара с номером bar int bar, double &Array[], bool set // Направление индексирования массивов ) // Recount_ArrayZeroPos(count, Length, prev_calculated, rates_total, series, bar, Array[], set) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ if(set) { if(bar!=rates_total-prev_calculated) { count--; if(count<0) count=Length-1; } } else { if(bar!=prev_calculated-1) { count--; if(count<0) count=Length-1; } } Array[count]=series; //----+ } //+------------------------------------------------------------------+ //| Преобразование номера таймсерии в позицию в массиве | //+------------------------------------------------------------------+ int CMovSeriesTools::Recount_ArrayNumber ( int count,// Номер текущего значения ценового ряда int Length, int Number // Позиция запрашиваемого значения относительно текущего бара bar ) // Recount_ArrayNumber(count, Length, Number) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ int ArrNumber=Number+count; if(ArrNumber>Length-1) ArrNumber-=Length; //----+ return(ArrNumber); } //+------------------------------------------------------------------+ //| Изменение размера массива Array[] | //+------------------------------------------------------------------+ bool CMovSeriesTools::SeriesArrayResize ( string FunctionsName,// Название функции, внутри которой меняется размер int Length,// новый размер массива double &Array[],// Изменяемый массив int &Size_ // Получившийся размер массива ) // SeriesArrayResize(FunctionsName, Length, Array, Size_) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ //----+ Изменение размеров массива переменных if(Length>Size_) { int Size=Length+1; if(ArrayResize(Array,Size)==-1) { ArrayResizeErrorPrint(FunctionsName,Size_); return(false); } Size_=Size; } //----+ return(true); } //+------------------------------------------------------------------+ //| Сброс в логфайл ошибки изменения размера массива | //+------------------------------------------------------------------+ bool CMovSeriesTools::ArrayResizeErrorPrint ( string FunctionsName, int &Size_ ) // ArrayResizeErrorPrint(FunctionsName, Size_) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ string lable,word; StringConcatenate(lable,FunctionsName,"():"); StringConcatenate(word,lable," Ошибка!!! Не удалось изменить", " размеры массива переменных функции ",FunctionsName,"()!"); Print(word); //---- int error=GetLastError(); ResetLastError(); //---- if(error>4000) { StringConcatenate(word,lable,"(): Код ошибки ",error); Print(word); } Size_=-2; return(false); //----+ return(true); } //+X----------------------+ <<< The End >>> +-----------------------X+