//--- описание #property description "Скрипт строит графический объект \"Импульсная волна Эллиота\"." #property description "Координаты точек привязки задаются в процентах от размеров" #property description "окна графика." //--- покажем окно входных параметров при запуске скрипта #property script_show_inputs //--- входные параметры скрипта input string InpName="ElliotWave5"; // Имя объекта input int InpDate1=10; // Дата 1-ой точки в % input int InpPrice1=90; // Цена 1-ой точки в % input int InpDate2=20; // Дата 2-ой точки в % input int InpPrice2=40; // Цена 2-ой точки в % input int InpDate3=30; // Дата 3-ей точки в % input int InpPrice3=60; // Цена 3-ей точки в % input int InpDate4=40; // Дата 4-ой точки в % input int InpPrice4=10; // Цена 4-ой точки в % input int InpDate5=60; // Дата 5-ой точки в % input int InpPrice5=40; // Цена 5-ой точки в % input ENUM_ELLIOT_WAVE_DEGREE InpDegree=ELLIOTT_MINOR; // Уровень input bool InpDrawLines=true; // Отображение линий input color InpColor=clrRed; // Цвет линий input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Стиль линий input int InpWidth=2; // Толщина линий input bool InpBack=false; // Объект на заднем плане input bool InpSelection=true; // Выделить для перемещений input bool InpHidden=true; // Скрыт в списке объектов input long InpZOrder=0; // Приоритет на нажатие мышью //+------------------------------------------------------------------+ //| Cоздает "Импульсную волну Эллиота" по заданным координатам | //+------------------------------------------------------------------+ bool ElliotWave5Create(const long chart_ID=0, // ID графика const string name="ElliotWave5", // имя волны const int sub_window=0, // номер подокна datetime time1=0, // время первой точки double price1=0, // цена первой точки datetime time2=0, // время второй точки double price2=0, // цена второй точки datetime time3=0, // время третьей точки double price3=0, // цена третьей точки datetime time4=0, // время четвертой точки double price4=0, // цена четвертой точки datetime time5=0, // время пятой точки double price5=0, // цена пятой точки const ENUM_ELLIOT_WAVE_DEGREE degree=ELLIOTT_MINUETTE, // степень const bool draw_lines=true, // отображение линий 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 hidden=true, // скрыт в списке объектов const long z_order=0) // приоритет на нажатие мышью { //--- установим координаты точек привязки, если они не заданы ChangeElliotWave5EmptyPoints(time1,price1,time2,price2,time3,price3,time4,price4,time5,price5); //--- сбросим значение ошибки ResetLastError(); //--- создадим "Импульсную волну Эллиота" по заданным координатам if(!ObjectCreate(chart_ID,name,OBJ_ELLIOTWAVE5,sub_window,time1,price1,time2,price2,time3, price3,time4,price4,time5,price5)) { Print(__FUNCTION__, ": не удалось создать \"Импульсную волну Эллиота\"! Код ошибки = ",GetLastError()); return(false); } //--- установим степень (размер волны) ObjectSetInteger(chart_ID,name,OBJPROP_DEGREE,degree); //--- включим (true) или отключим (false) режим отображения линий ObjectSetInteger(chart_ID,name,OBJPROP_DRAWLINES,draw_lines); //--- установим цвет объекта 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_HIDDEN,hidden); //--- установим приоритет на получение события нажатия мыши на графике ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Перемещает точку привязки "Импульсной волны Эллиота" | //+------------------------------------------------------------------+ bool ElliotWave5PointChange(const long chart_ID=0, // ID графика const string name="ElliotWave5", // имя объекта 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 ElliotWave5Delete(const long chart_ID=0, // ID графика const string name="ElliotWave5") // имя объекта { //--- сбросим значение ошибки ResetLastError(); //--- удалим объект if(!ObjectDelete(chart_ID,name)) { Print(__FUNCTION__, ": не удалось удалить \"Импульсную волну Эллиота\"! Код ошибки = ",GetLastError()); return(false); } //--- успешное выполнение return(true); } //+------------------------------------------------------------------+ //| Проверяет значения точек привязки "Импульсной волны Эллиота" и | //| для пустых значений устанавливает значения по умолчанию | //+------------------------------------------------------------------+ void ChangeElliotWave5EmptyPoints(datetime &time1,double &price1, datetime &time2,double &price2, datetime &time3,double &price3, datetime &time4,double &price4, datetime &time5,double &price5) { //--- массив для приема времени открытия 10 последних баров datetime temp[]; ArrayResize(temp,10); //--- получим данные CopyTime(Symbol(),Period(),TimeCurrent(),10,temp); //--- получим величину одного пункта на текущем графике double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT); //--- если время первой точки не задано, то она будет на 9 баре слева от последнего бара if(!time1) time1=temp[0]; //--- если цена первой точки не задана, то она будет иметь значение Bid if(!price1) price1=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- если время второй точки не задано, то она будет на 7 баре слева от последнего бара if(!time2) time2=temp[2]; //--- если цена второй точки не задана, сдвинем ее на 300 пунктов ниже первой if(!price2) price2=price1-300*point; //--- если время третьей точки не задано, то она будет на 5 баров слева от последнего бара if(!time3) time3=temp[4]; //--- если цена третьей точки не задана, сдвинем ее на 250 пунктов ниже первой if(!price3) price3=price1-250*point; //--- если время четвертой точки не задано, то она будет на 3 бара слева от последнего бара if(!time4) time4=temp[6]; //--- если цена четвертой точки не задана, сдвинем ее на 550 пунктов ниже первой if(!price4) price4=price1-550*point; //--- если время пятой точки не задано, то она будет на последнем баре if(!time5) time5=temp[9]; //--- если цена пятой точки не задана, сдвинем ее на 450 пунктов ниже первой if(!price5) price5=price1-450*point; } //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- проверим входные параметры на корректность if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 || InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 || InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100 || InpDate4<0 || InpDate4>100 || InpPrice4<0 || InpPrice4>100 || InpDate5<0 || InpDate5>100 || InpPrice5<0 || InpPrice5>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 d3=InpDate3*(bars-1)/100; int d4=InpDate4*(bars-1)/100; int d5=InpDate5*(bars-1)/100; int p1=InpPrice1*(accuracy-1)/100; int p2=InpPrice2*(accuracy-1)/100; int p3=InpPrice3*(accuracy-1)/100; int p4=InpPrice4*(accuracy-1)/100; int p5=InpPrice5*(accuracy-1)/100; //--- создадим "Импульсную волну Эллиота" if(!ElliotWave5Create(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3], date[d4],price[p4],date[d5],price[p5],InpDegree,InpDrawLines,InpColor,InpStyle,InpWidth, InpBack,InpSelection,InpHidden,InpZOrder)) { return; } //--- перерисуем график и подождем 1 секунду ChartRedraw(); Sleep(1000); //--- теперь будем перемещать точки привязки //--- счетчик цикла int v_steps=accuracy/5; //--- перемещаем пятую точку привязки for(int i=0;i<v_steps;i++) { //--- возьмем следующее значение if(p5<accuracy-1) p5+=1; //--- сдвигаем точку if(!ElliotWave5PointChange(0,InpName,4,date[d5],price[p5])) return; //--- проверим факт принудительного завершения скрипта if(IsStopped()) return; //--- перерисуем график ChartRedraw(); } //--- задержка в 1 секунду Sleep(1000); //--- счетчик цикла v_steps=accuracy/5; //--- перемещаем вторую и третью точки привязки for(int i=0;i<v_steps;i++) { //--- возьмем следующие значения if(p2<accuracy-1) p2+=1; if(p3>1) p3-=1; //--- сдвигаем точки if(!ElliotWave5PointChange(0,InpName,1,date[d2],price[p2])) return; if(!ElliotWave5PointChange(0,InpName,2,date[d3],price[p3])) return; //--- проверим факт принудительного завершения скрипта if(IsStopped()) return; //--- перерисуем график ChartRedraw(); } //--- задержка в 1 секунду Sleep(1000); //--- счетчик цикла v_steps=accuracy*4/5; //--- перемещаем первую и четвертую точки привязки for(int i=0;i<v_steps;i++) { //--- возьмем следующие значения if(p1>1) p1-=1; if(p4<accuracy-1) p4+=1; //--- сдвигаем точки if(!ElliotWave5PointChange(0,InpName,0,date[d1],price[p1])) return; if(!ElliotWave5PointChange(0,InpName,3,date[d4],price[p4])) return; //--- проверим факт принудительного завершения скрипта if(IsStopped()) return; //--- перерисуем график ChartRedraw(); } //--- задержка в 1 секунду Sleep(1000); //--- удалим объект с графика ElliotWave5Delete(0,InpName); ChartRedraw(); //--- задержка в 1 секунду Sleep(1000); //--- } |