//+------------------------------------------------------------------+ //| Color_RSI.mq5 | //+------------------------------------------------------------------+ // группа информационных свойств. #property copyright "TheXpert" #property link "theforexpert@gmail.com" #property version "1.00" // описание индикатора -- суммарно не должно превышать 511 символов // с учетом символов перевода строки #property description " " #property description "Демонстрация построения индикатора" #property description "на примере раскрашивания RSI" // свойства непосредственно индикатора #property indicator_separate_window // индикатор будет отображен в отдельном подокне //#property indicator_minimum 0 //#property indicator_maximum 100 #property indicator_buffers 4 // количество используемых буферов #property indicator_plots 2 // количество отображаемых буферов #property indicator_color1 DarkSalmon, DeepSkyBlue // используем 2 цвета #property indicator_type1 DRAW_COLOR_LINE // и специальный цветной тип отображения #property indicator_color2 DarkSalmon, DeepSkyBlue // используем 2 цвета #property indicator_type2 DRAW_COLOR_LINE // и специальный цветной тип отображения //---- buffers double Values[]; // буфер значений double ValuesPainting[]; // буфер индексов цветов double SmoothedValues[]; // буфер сглаженных значений double SmoothedValuesPainting[]; // буфер индексов цветов double BufferForCopy[]; // входные параметры индикатора input string _1 = "Параметры для RSI"; input int RSIPeriod = 5; input int SmoothPeriod = 5; input ENUM_APPLIED_PRICE AppliedPrice = PRICE_CLOSE; input string _2 = "Настройки цветов"; input color Down = DarkSalmon; input color Up = DeepSkyBlue; // переменная, в которой будет содержаться хэндл индикатора int RSIHandle; int SmoothHandle; // функция инициализации индикатора int OnInit() { // регистрируем индикаторные буферы // Values как буфер для отображения SetIndexBuffer(0, Values, INDICATOR_DATA); // ValuesPainting как буфер для хранения цветов SetIndexBuffer(1, ValuesPainting, INDICATOR_COLOR_INDEX); // Values как буфер для отображения SetIndexBuffer(2, SmoothedValues, INDICATOR_DATA); // ValuesPainting как буфер для хранения цветов SetIndexBuffer(3, SmoothedValuesPainting, INDICATOR_COLOR_INDEX); // Устанавливаем начало рисования буфера Values PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, RSIPeriod); // Устанавливаем начало рисования буфера Values PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, RSIPeriod + SmoothPeriod); // Устанавливаем имя индикатора IndicatorSetString(INDICATOR_SHORTNAME, "Цветной RSI(" + string(RSIPeriod) + "," + string(SmoothPeriod) + ")"); // Устанавливаем пустое значение для буфера Values PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, EMPTY_VALUE); // Устанавливаем цвета буфера PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, Down); PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, Up); PlotIndexSetInteger(2, PLOT_LINE_COLOR, 0, Down); PlotIndexSetInteger(2, PLOT_LINE_COLOR, 1, Up); RSIHandle = iRSI(NULL, 0, RSIPeriod, AppliedPrice); SmoothHandle = iMA(NULL, 0, SmoothPeriod, 0, MODE_EMA, RSIHandle); ArrayResize(BufferForCopy, 3); // Устанавливаем порядок индексации буферов ArraySetAsSeries(Values, true); ArraySetAsSeries(ValuesPainting, true); ArraySetAsSeries(SmoothedValues, true); ArraySetAsSeries(SmoothedValuesPainting, true); ArraySetAsSeries(BufferForCopy, true); return(0); } // функция расчета даных // параметры функции _можно_ переименовывать int OnCalculate(const int rates_total, const int prev_calculated, const datetime& time[], const double& open[], const double& high[], const double& low[], const double& close[], const long& tick_volume[], const long& volume[], const int& spread[]) { int toCount = (int)MathMin(rates_total, rates_total - prev_calculated + 1); // "умное" копирование данных, чтобы не копировать каждый раз целиком if (toCount <= 3) { int copied = CopyBuffer(RSIHandle, 0, 0, toCount, BufferForCopy); if (copied == -1) { Print("Ошибка во время копирования данных №", GetLastError()); return 0; } for (int i = toCount - 1; i >= 0; --i) { Values[i] = BufferForCopy[i]; } copied = CopyBuffer(SmoothHandle, 0, 0, toCount, BufferForCopy); if (copied == -1) { Print("Ошибка во время копирования сглаженных данных №", GetLastError()); return 0; } for (int i = toCount - 1; i >= 0; --i) { SmoothedValues[i] = BufferForCopy[i]; } } else { int copied = CopyBuffer(RSIHandle, 0, 0, rates_total, Values); if (copied == -1) { Print("Ошибка во время копирования данных №", GetLastError()); return 0; } copied = CopyBuffer(SmoothHandle, 0, 0, rates_total, SmoothedValues); if (copied == -1) { Print("Ошибка во время копирования данных №", GetLastError()); return 0; } } // раскрашивание. Да, теперь оно стало таким простым for (int i = toCount - 2; i >= 0; --i) { if (Values[i + 1] != EMPTY_VALUE && Values[i] > Values[i + 1]) ValuesPainting[i] = 1; else ValuesPainting[i] = 0; if (SmoothedValues[i + 1] != EMPTY_VALUE && SmoothedValues[i] > SmoothedValues[i + 1]) SmoothedValuesPainting[i] = 1; else SmoothedValuesPainting[i] = 0; } return rates_total; }