//--- описание #property description "Скрипт строит графический объект \"Линия Ганна\"." #property description "Координаты точек привязки задаются в процентах от" #property description "размеров окна графика." //--- покажем окно входных параметров при запуске скрипта #property script_show_inputs //--- входные параметры скрипта input string InpName="GannLine"; // Имя линии input int InpDate1=20; // Дата 1-ой точки в % input int InpPrice1=75; // Цена 1-ой точки в % input int InpDate2=80; // Дата 2-ой точки в % input double InpAngle=0.0; // Угол Ганна input double InpScale=1.0; // Масштаб input color InpColor=clrRed; // Цвет линии input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // Стиль линии input int InpWidth=2; // Толщина линии input bool InpBack=false; // Линия на заднем плане input bool InpSelection=true; // Выделить для перемещений input bool InpRayLeft=false; // Продолжение линии влево input bool InpRayRight=true; // Продолжение линии вправо input bool InpHidden=true; // Скрыт в списке объектов input long InpZOrder=0; // Приоритет на нажатие мышью //+------------------------------------------------------------------+ //| Создает "Линию Ганна" по координатам, углу и масштабу | //+------------------------------------------------------------------+ bool GannLineCreate(const long chart_ID=0, // ID графика const string name="GannLine", // имя линии const int sub_window=0, // номер подокна datetime time1=0, // время первой точки double price1=0, // цена первой точки datetime time2=0, // время второй точки const double angle=1.0, // угол Ганна const double scale=1.0, // масштаб const color clr=clrRed, // цвет линии const ENUM_LINE_STYLE style=STYLE_SOLID, // стиль линии const int width=1, // толщина линии const bool back=false, // на заднем плане const bool selection=true, // выделить для перемещений const bool ray_left=false, // продолжение линии влево const bool ray_right=true, // продолжение линии вправо const bool hidden=true, // скрыт в списке объектов const long z_order=0) // приоритет на нажатие мышью { //--- установим координаты точек привязки, если они не заданы ChangeGannLineEmptyPoints(time1,price1,time2); //--- сбросим значение ошибки ResetLastError(); //--- создадим "Линию Ганна" по заданным координатам //--- правильная координата цены второй точки привязки переопределится //--- автоматически после изменения угла Ганна и (или) масштаба, if(!ObjectCreate(chart_ID,name,OBJ_GANNLINE,sub_window,time1,price1,time2,0)) { Print(__FUNCTION__, ": не удалось создать \"Линию Ганна\"! Код ошибки = ",GetLastError()); return(false); } //--- изменим угол Ганна ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle); //--- изменим масштаб (количество пипсов на бар) ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale); //--- установим цвет линии ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- установим стиль отображения линии ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- установим толщину линии ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- отобразим на переднем (false) или заднем (true) плане ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- включим (true) или отключим (false) режим выделения линии для перемещений //--- при создании графического объекта функцией ObjectCreate, по умолчанию объект //--- нельзя выделить и перемещать. Внутри же этого метода параметр selection //--- по умолчанию равен true, что позволяет выделять и перемещать этот объект ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- включим (true) или отключим (false) режим продолжения отображения линии влево ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left); //--- включим (true) или отключим (false) режим продолжения отображения линии вправо ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right); //--- скроем (true) или отобразим (false) имя графического объекта в списке объектов ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- установим приоритет на получение события нажатия мыши на графике ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Перемещает точку привязки "Линии Ганна" | //+------------------------------------------------------------------+ bool GannLinePointChange(const long chart_ID=0, // ID графика const string name="GannLine", // имя линии const int point_index=0, // номер точки привязки datetime time=0, // координата времени точки привязки double price=0) // координата цены точки привязки { //--- если координаты точки не заданы, то перемещаем ее на текущий бар с ценой Bid if(!time) time=TimeCurrent(); if(!price) price=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- сбросим значение ошибки ResetLastError(); //--- переместим точку привязки линии if(!ObjectMove(chart_ID,name,point_index,time,price)) { Print(__FUNCTION__, ": не удалось переместить точку привязки! Код ошибки = ",GetLastError()); return(false); } //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Изменяет угол Ганна | //+------------------------------------------------------------------+ bool GannLineAngleChange(const long chart_ID=0, // ID графика const string name="GannLine", // имя линии const double angle=1.0) // угол Ганна { //--- сбросим значение ошибки ResetLastError(); //--- изменим угол Ганна if(!ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle)) { Print(__FUNCTION__, ": не удалось изменить угол Ганна! Код ошибки = ",GetLastError()); return(false); } //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Изменяет масштаб "Линии Ганна" | //+------------------------------------------------------------------+ bool GannLineScaleChange(const long chart_ID=0, // ID графика const string name="GannLine", // имя линии const double scale=1.0) // масштаб { //--- сбросим значение ошибки ResetLastError(); //--- изменим масштаб (количество пипсов на бар) if(!ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale)) { Print(__FUNCTION__, ": не удалось изменить масштаб! Код ошибки = ",GetLastError()); return(false); } //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Функция удаляет "Линию Ганна" с графика | //+------------------------------------------------------------------+ bool GannLineDelete(const long chart_ID=0, // ID графика const string name="GannLine") // имя линии { //--- сбросим значение ошибки ResetLastError(); //--- удалим линию Ганна if(!ObjectDelete(chart_ID,name)) { Print(__FUNCTION__, ": не удалось удалить \"Линию Ганна\"! Код ошибки = ",GetLastError()); return(false); } //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Проверяет значения точек привязки "Линии Ганна" и для пустых | //| значений устанавливает значения по умолчанию | //+------------------------------------------------------------------+ void ChangeGannLineEmptyPoints(datetime &time1,double &price1,datetime &time2) { //--- если время второй точки не задано, то она будет на текущем баре if(!time2) time2=TimeCurrent(); //--- если время первой точки не задано, то она лежит на 9 баров левее первой if(!time1) { //--- массив для приема времени открытия 10 последних баров datetime temp[10]; CopyTime(Symbol(),Period(),time2,10,temp); //--- установим первую точку на 9 баров левее второй time1=temp[0]; } //--- если цена первой точки не задана, то она будет иметь значение Bid if(!price1) price1=SymbolInfoDouble(Symbol(),SYMBOL_BID); } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- проверим входные параметры на корректность if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 || InpDate2<0 || InpDate2>100) { Print("Ошибка! Некорректные значения входных параметров!"); return; } //--- количество видимых баров в окне графика int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS); //--- размер массива price int accuracy=1000; //--- массивы для хранения значений дат и цен, которые будут использованы //--- для установки и изменения координат точек привязки линии datetime date[]; double price[]; //--- выделение памяти ArrayResize(date,bars); ArrayResize(price,accuracy); //--- заполним массив дат ResetLastError(); if(CopyTime(Symbol(),Period(),0,bars,date)==-1) { Print("Не удалось скопировать значения времени! Код ошибки = ",GetLastError()); return; } //--- заполним массив цен //--- найдем максимальное и минимальное значение графика double max_price=ChartGetDouble(0,CHART_PRICE_MAX); double min_price=ChartGetDouble(0,CHART_PRICE_MIN); //--- определим шаг изменения цены и заполним массив double step=(max_price-min_price)/accuracy; for(int i=0;i<accuracy;i++) price[i]=min_price+i*step; //--- определим точки для рисования линии Ганна int d1=InpDate1*(bars-1)/100; int d2=InpDate2*(bars-1)/100; int p1=InpPrice1*(accuracy-1)/100; //--- создадим линию Ганна if(!GannLineCreate(0,InpName,0,date[d1],price[p1],date[d2],InpAngle,InpScale,InpColor, InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder)) { return; } //--- перерисуем график и подождем 1 секунду ChartRedraw(); Sleep(1000); //--- теперь будем перемещать точку привязки линии и менять угол //--- счетчик цикла int v_steps=accuracy/2; //--- перемещаем первую точку привязки по вертикали for(int i=0;i<v_steps;i++) { //--- возьмем следующее значение if(p1>1) p1-=1; //--- сдвигаем точку if(!GannLinePointChange(0,InpName,0,date[d1],price[p1])) return; //--- проверим факт принудительного завершения скрипта if(IsStopped()) return; //--- перерисуем график ChartRedraw(); } //--- задержка в полсекунды Sleep(500); //--- определим текущее значение угла Ганна (изменился //--- после перемещения первой точки привязки) double curr_angle; if(!ObjectGetDouble(0,InpName,OBJPROP_ANGLE,0,curr_angle)) return; //--- счетчик цикла v_steps=accuracy/8; //--- изменяем угол Ганна for(int i=0;i<v_steps;i++) { if(!GannLineAngleChange(0,InpName,curr_angle-0.05*i)) return; //--- проверим факт принудительного завершения скрипта if(IsStopped()) return; //--- перерисуем график ChartRedraw(); } //--- задержка в 1 секунду Sleep(1000); //--- удалим линию с графика GannLineDelete(0,InpName); ChartRedraw(); //--- задержка в 1 секунду Sleep(1000); //--- } |