//+------------------------------------------------------------------+ //| albus_MultiChart_1.mq4 | //| Albus Dumbledore © | //| Ad opus! | //|индикатор позволяет рисовать в основном окне график | //|любого инструмента, любого** периода, | //|допчарт можно перемещать в любую точку окна (двигать ТХТ маркер) | //| | //| * Сделан по мотивам Instrument2.mq4 от Denis Orlov | //| * Глюк с отрисовкой тел баров при перекомпиляции (если инд. вкл) | //| решение - открыть окно настроек нажать ОК, дальше порядок | //| ** В тестере не выводить периоды меньше чем основной чарт | //| ** В тестере не запускать больше чем на недельном графике :) | //| *** При запуске на древней истории поставить много баров в окне | //| *** При запуске на древней истории убедиться что она есть | //+------------------------------------------------------------------+ #property indicator_chart_window #property indicator_buffers 4 double Line1[], Line2[], Line3[], Line4[]; extern string Instrument = ""; // любой инструмент (должна присутствовать история) extern int TimeFrame = 0; // период цифрами (для Н1 - 60)(должна присутствовать история) extern int History = 100; // длина прорисовки extern double KoefPress = 1; // сжатие(разжатие) графика для удобства (3-втрое растянут, 0,5-вдвое сжат и т.д.) extern double KoefJPY = 1; // при работе с еновыми + нееновыми парами (изменять 0.01 или 100 или около того) extern double KoefInvers = 1; // норм = 1 инверсия = -1 extern int ColorStyle = 1; // цветовая схема индикатора (изменять от 1 до 9) extern int TxtHorizShift = 0; // зазор между ТХТ и графиком (кол. баров) extern double TxtAngle = 90.0; // поворот ТХТ градусов (90 - вертикально) extern color TxtColor = Red; // цвет ТХТ int LastTxtTime; //описывает координаты ТХТ double LastTxtPrice; //описывает координаты ТХТ int BarsOnLastTick = 0; // для контроля появления нового бара double LastOpenPrice = 0; // для контроля вертикального смещения графика при новом баре string IndName; // символ + ТФ //—————————————————————————————————————————————————————————————————————— // init() //—————————————————————————————————————————————————————————————————————— int init() { SetIndexBuffer(0, Line1); SetIndexBuffer(1, Line2); SetIndexBuffer(2, Line3); SetIndexBuffer(3, Line4); //назначение буферов индикаторов SetColorStyle(); if(Instrument == "") Instrument = Symbol(); if(TimeFrame == 0) TimeFrame = Period(); IndName = Instrument + " " + PeriodToStr(TimeFrame); DrawText(IndName + "TXT", Time[1], Open[0], TxtAngle, IndName, TxtColor, 12, 0); // рисование ТХТ маркера LastTxtTime = Time[1]; LastTxtPrice = Open[1]; return(0); } //—————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————— // deinit() //—————————————————————————————————————————————————————————————————————— int deinit() { ObjectDelete(IndName + "TXT"); return(0); } //—————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————— // start() //—————————————————————————————————————————————————————————————————————— int start() { int i = 0; // кол. баров которые нужно перерисовывать double koefChart = KoefPress * KoefJPY * KoefInvers; int testingShift; if(IsTester()) testingShift = iBarShift(Instrument, TimeFrame, Time[0]); else testingShift = 0; //если индикатор только запущен, LastOpenPrice ставим по последнему рисуемому бару if(LastOpenPrice == 0) if(Instrument == Symbol() && TimeFrame == Period()) LastOpenPrice = Open[0]; else LastOpenPrice = iOpen(Instrument, TimeFrame,testingShift); // если новый бар if(BarsOnLastTick < Bars) { BarsOnLastTick = Bars; i = History - 1; // если новый бар - перерисовывать все (т.к. разные периоды, все смещается) ArrayInitialize(Line1, 0.0); ArrayInitialize(Line2, 0.0); ArrayInitialize(Line3, 0.0); ArrayInitialize(Line4, 0.0); //перемещение ТХТ double txtPriceShift; //сдвиг по цене if(Instrument == Symbol() && TimeFrame == Period()) { txtPriceShift = Open[0] - LastOpenPrice; LastOpenPrice = Open[0]; } else { txtPriceShift = iOpen(Instrument, TimeFrame, testingShift) - LastOpenPrice; LastOpenPrice = iOpen(Instrument, TimeFrame, testingShift); } ObjectSet(IndName+"TXT", OBJPROP_PRICE1, ObjectGet(IndName + "TXT",OBJPROP_PRICE1) + koefChart * txtPriceShift); ObjectSet(IndName + "TXT", OBJPROP_TIME1, ObjectGet(IndName + "TXT", OBJPROP_TIME1) + Time[0] - Time[1]); } //если двигали ТХТ или она автоматически переместилась при приходе нового бара if((LastTxtTime != ObjectGet(IndName + "TXT", OBJPROP_TIME1)) || (LastTxtPrice != ObjectGet(IndName + "TXT", OBJPROP_PRICE1))) //полный пересчет если двигали ТХТ { i = History - 1; // всё перерисовать LastTxtTime = ObjectGet(IndName+"TXT", OBJPROP_TIME1); LastTxtPrice = ObjectGet(IndName+"TXT", OBJPROP_PRICE1); ArrayInitialize(Line1, 0.0); ArrayInitialize(Line2, 0.0); ArrayInitialize(Line3, 0.0); ArrayInitialize(Line4, 0.0); } //подготовка к расчету индикатора int HorizMovChart = iBarShift(NULL,0,LastTxtTime); i = i + HorizMovChart + TxtHorizShift + testingShift; //учет смещения графика по горизонтали double H, L, O, C, OLast; while(i >= (HorizMovChart + TxtHorizShift + testingShift)) { H = iHigh(Instrument, TimeFrame, i - HorizMovChart - TxtHorizShift); L = iLow(Instrument, TimeFrame, i - HorizMovChart - TxtHorizShift); O = iOpen(Instrument,TimeFrame, i - HorizMovChart - TxtHorizShift); C = iClose(Instrument, TimeFrame, i - HorizMovChart - TxtHorizShift); OLast = iOpen(Instrument, TimeFrame, testingShift); //в тестере последний бар допчарта - только опен, чтоб не подсматривать ;) if(IsTester() && ((i - HorizMovChart - TxtHorizShift) == testingShift)) { H = O; C = O; L = O; } if(C > O) { Line1[i - testingShift] = LastTxtPrice + koefChart * (C - OLast); Line2[i - testingShift] = LastTxtPrice + koefChart * (O - OLast); Line3[i - testingShift] = LastTxtPrice + koefChart * (H - OLast); Line4[i - testingShift] = LastTxtPrice + koefChart * (L - OLast); } else if(C < O) { Line1[i - testingShift] = LastTxtPrice + koefChart * (C - OLast); Line2[i - testingShift] = LastTxtPrice + koefChart * (O - OLast); Line3[i - testingShift] = LastTxtPrice + koefChart * (L - OLast); Line4[i - testingShift] = LastTxtPrice + koefChart * (H - OLast); } else { Line1[i - testingShift] = LastTxtPrice + koefChart * (O - OLast); Line2[i - testingShift] = Line1[i - testingShift] + 0.01 * Point; Line3[i - testingShift] = LastTxtPrice + koefChart * (L - OLast); Line4[i - testingShift] = LastTxtPrice + koefChart * (H - OLast); } i--; } //while return(0); } //—————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————— // SetColorStyle() // Функция устанавиливает/меняет цветовую схему графика индикатора // номер схемы берется из внешней переменной ColorStyle //—————————————————————————————————————————————————————————————————————— int SetColorStyle() { color bullsBar, bearsBar; switch(ColorStyle) { case 1: bullsBar = DarkTurquoise; bearsBar = DarkBlue; break; case 2: bullsBar = Orange; bearsBar = Maroon; break; case 3: bullsBar = LimeGreen; bearsBar = DarkGreen; break; case 4: bullsBar = DeepPink; bearsBar = DarkViolet; break; case 5: bullsBar = DarkGray; bearsBar = Black; break; case 6: bullsBar = Red; bearsBar = Black; break; case 7: bullsBar = Gray; bearsBar = Red; break; case 8: bullsBar = LimeGreen; bearsBar = Red; break; case 9: bullsBar = LimeGreen; bearsBar = Black; } SetIndexStyle(0, DRAW_HISTOGRAM, 0, 3, bullsBar); SetIndexStyle(1, DRAW_HISTOGRAM, 0, 3, bearsBar); SetIndexStyle(2, DRAW_HISTOGRAM, 0, 1, bullsBar); SetIndexStyle(3, DRAW_HISTOGRAM, 0, 1, bearsBar); } //—————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————— // PeriodToStr() // Функция преобразования цифрового вида периода (240) к символьному (Н4) //—————————————————————————————————————————————————————————————————————— string PeriodToStr(int per) { switch(per) { case 1: return("M1"); case 5: return("M5"); case 15: return("M15"); case 30: return("M30"); case 60: return("H1"); case 240: return("H4"); case 1440: return("D1"); case 10080: return("W1"); case 43200: return("МN"); } } //—————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————— // DrawText() // Функция выводит на график текстовую метку //—————————————————————————————————————————————————————————————————————— int DrawText ( string name, //1 имя datetime times, //2 кордината времени double price, //3 координата цены double angle, //4 угол наклона метки (90-вертикально) string text, //5 содержание color clr, //6 цвет int size = 10, //7 размер шрифта int win = 0) //8 окно вывода (0-график цены) { ObjectCreate (name, OBJ_TEXT, win, times, price); ObjectSet (name, OBJPROP_PRICE1, price); ObjectSet (name, OBJPROP_TIME1, times); ObjectSet (name, OBJPROP_ANGLE, angle); ObjectSetText (name, text ,size,"Arial",clr); return (0); } //—————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————— // IsTester() bool // Функция проверяет в тестере мы? // Да - возвращает TRUE. // Нет - возвращает FALSE. // Если время последнего бара даного графика меньше времени последнего // исторического бара старшего периода мы в тестере //—————————————————————————————————————————————————————————————————————— bool IsTester() { int nextPeriod; switch(Period()) { case 1: nextPeriod = 5; break; case 5: nextPeriod = 15; break; case 15: nextPeriod = 30; break; case 30: nextPeriod = 60; break; case 60: nextPeriod = 240; break; case 240: nextPeriod = 1440; break; case 1440: nextPeriod = 10080; break; case 10080: nextPeriod = 43200; } if(Time[0] < iTime(NULL,nextPeriod,0)) return (TRUE); else return (FALSE); } //——————————————————————————————————————————————————————————————————————