Вопросы от начинающих MQL4 MT4 MetaTrader 4 - страница 284

 

Код в советнике:

// ------------ Зелёная линия -----------------
        s_TrendLineName=StringConcatenate(SMB,"_",BuyTrendLine,"_Buy",TimeLocal());
        if(BtnSostoyanie("BtBuyTrLine")=="DOWN"){
                if(ObjectFind(s_TrendLineName)<0){
                        Exp.CreateTrendLine(0,s_TrendLineName,0,Time[20],Low[20],Time[1],High[1],BuyResetLineColor,STYLE_SOLID,2,false,true,false,false,0);
                        ObjectSetInteger(0,"BtBuyTrLine",OBJPROP_STATE,false);// отжимаем кнопку
                        if(ObjectFind(s_TrendLineName)>(-1)){// линия есть
                                // --------- Генерируем имя Dot-линии -----------------
                                s_DotLineName=StringConcatenate("Dot_",s_TrendLineName);
                                if(ObjectFind(s_DotLineName)<0){
                                        Exp.CreateTrendLine(0,s_DotLineName,0,Time[20],Low[20],Time[1],High[1],BuyResetLineColor,STYLE_DOT,1,false,false,true,false,0);
                                }
                        }
                }
                else{
                        ObjectSetInteger(0,"BtBuyTrLine",OBJPROP_STATE,false);// отжимаем кнопку
                }
        }
        Exp.CheckTrendLine(0,BuyTrendLine);// ровняем линию - могли сместить
        Exp.CheckDotTrendLine(BuyTrendLine);// ровняем Dot-линию - могли сместить

Это вызываемые подпрограммы

// ============================ CreateTrendLine() ==================================================
// Процедура создаёт линию тренда 
// ------------------------------
void CBasicExpert::CreateTrendLine(
        const long                                                      Chart_ID=0,
        const string                                            Name="TrLine",
        const int                         SubWindow=0,      // номер подокна
        datetime                                                                LeftTime=0,
        double                                                                  LeftPrice=0,
        datetime                                                                RightTime=0,
        double                                                                  RightPrice=0,
        const color                                                     LineColor=clrBlue,
        const ENUM_LINE_STYLE   Style=STYLE_SOLID,
        const int                                                               LineWidth=1,
        const bool                                                      Back=false,        // на заднем плане
        const bool                                                      Selection=true,    // выделить для перемещений 
        const bool                                                      Ray=true,
        const bool                                                      Hidden=false,       // скрыт в списке объектов 
        const long                                                      Z_order=0         // приоритет на нажатие мышью 
        ){
        if(ObjectFind(Name)<0){// Линии нет
                if(!ObjectCreate(Chart_ID,Name,OBJ_TREND,SubWindow,LeftTime,LeftPrice,RightTime,RightPrice)){
                        Print("Ошибка № ",GetLastError()," при создании линии ",Name);
                }
                else{
                        ObjectSet(Name,OBJPROP_COLOR,LineColor);
                        ObjectSetInteger(Chart_ID,Name,OBJPROP_STYLE,Style);//стиль отображения линии
                        ObjectSet(Name,OBJPROP_WIDTH,LineWidth);
                        //--- отобразим на переднем (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_RIGHT,Ray); 
                        //--- скроем (true) или отобразим (false) имя графического объекта в списке объектов 
                        ObjectSetInteger(Chart_ID,Name,OBJPROP_HIDDEN,Hidden); 
                        //--- установим приоритет на получение события нажатия мыши на графике 
                        ObjectSetInteger(Chart_ID,Name,OBJPROP_ZORDER,Z_order);                         
                        WindowRedraw();
                }
        }
        else{// линия есть - корректируем её
                // --------- Время первой точки ----------------
                if(ObjectGet(Name,OBJPROP_TIME1)!=LeftTime){
                        ObjectSet(Name,OBJPROP_TIME1,LeftTime);
                }
                // --------- Цена первой точки ----------------
                if(ObjectGet(Name,OBJPROP_PRICE1)!=LeftPrice){
                        ObjectSet(Name,OBJPROP_PRICE1,LeftPrice);
                }
                // --------- Время второй точки ----------------
                if(ObjectGet(Name,OBJPROP_TIME2)!=RightTime){
                        ObjectSet(Name,OBJPROP_TIME2,RightTime);
                }
                // --------- Цена второй точки ----------------
                if(ObjectGet(Name,OBJPROP_PRICE2)!=RightPrice){
                        ObjectSet(Name,OBJPROP_PRICE2,RightPrice);
                }
                WindowRedraw();
        }
}

// =================================================================================================
// Процедура ставит линию тренда горизонтально
// На вход подаётся часть имени линии (константа)
// ----------------------------------------------
void CBasicExpert::CheckTrendLine(long Chart_ID,string NamePart){
        string s_LinesName="";
        double LeftPrice=0,RightPrice=0;
        for(int i=ObjectsTotal(EMPTY);i>0;i--){
                s_LinesName=ObjectName(i);
                if(StringFind(s_LinesName,NamePart,0)>(-1)){
                        LeftPrice=NormalizeDouble(ObjectGet(s_LinesName,OBJPROP_PRICE1),m_DGS);
                        RightPrice=NormalizeDouble(ObjectGet(s_LinesName,OBJPROP_PRICE2),m_DGS);
                        if(ObjectFind(Chart_ID,s_LinesName)>(-1)){
                                // --------- Цена первой точки ----------------
                                if(LeftPrice!=RightPrice){
                                        ObjectSet(s_LinesName,OBJPROP_PRICE2,LeftPrice);
                                        CheckDotTrendLine(s_LinesName);
                                        WindowRedraw();
                                }
                        }
                }
        }
}
// =============== CheckDotTrendLine() =============================================================
// Процедура ровняет штриховую линию, чтоб совпадала с привязанной к ней линии тренда
// На вход процедуры подаётся имя основной (сплошной линии) и префикс Dot_
// --------------------------------------------------------------------------
void CBasicExpert::CheckDotTrendLine(string SolidLineName){
        string s_DotLine;
        double LeftPrice;
        datetime LeftTime,RightTime;
        // ------------- Генерируем имя Dot-линии
        s_DotLine=StringConcatenate("Dot_",SolidLineName);
        // если основная найдена, то получаем значение цены её левой координаты
        if(ObjectFind(SolidLineName)>(-1)){// основная линия есть
                // считываем её левую координату цены
                LeftPrice=NormalizeDouble(ObjectGet(SolidLineName,OBJPROP_PRICE1),m_DGS);
                LeftTime=(datetime)ObjectGet(SolidLineName,OBJPROP_TIME1);
                RightTime=(datetime)ObjectGet(SolidLineName,OBJPROP_TIME2);
                if(ObjectFind(s_DotLine)>(-1)){// Пунктирная существует.
                        if(NormalizeDouble(ObjectGet(s_DotLine,OBJPROP_PRICE1),m_DGS)!=LeftPrice){
                                Print("LeftPrice = ",LeftPrice);
                                ObjectSet(s_DotLine,OBJPROP_PRICE1,LeftPrice);
                        }
                        if(NormalizeDouble(ObjectGet(s_DotLine,OBJPROP_PRICE2),m_DGS)!=LeftPrice){
                                ObjectSet(s_DotLine,OBJPROP_PRICE2,LeftPrice);
                        }
                        if(ObjectGet(s_DotLine,OBJPROP_TIME1)!=LeftTime){
                                Print("LeftTime = ",LeftTime);
                                ObjectSet(s_DotLine,OBJPROP_TIME1,LeftTime);
                        }
                        if(ObjectGet(s_DotLine,OBJPROP_TIME2)!=RightTime){
                                Print("RightTime = ",RightTime);
                                ObjectSet(s_DotLine,OBJPROP_TIME2,RightTime);
                        }
                }
                WindowRedraw();
        }
}
 
Putnik #:

Как определяется местоположение линии?

Через события нужно считывать координаты и направлять куда нужно , используя mouse_мove,а не через таймер .но для таких объектов ещё нужно переводить цену в координаты чарта.Это сложно будет реализовать если ранее не имели с этим дело
 
Думается сбой где-то в графике. Получение новых координат от сплошной линии, или в подаче координат на пунктирную. Обновление графика... Как-то так
 
Putnik #:
Думается сбой где-то в графике. Получение новых координат от сплошной линии, или в подаче координат на пунктирную. Обновление графика... Как-то так
Нет там сбоя никакого,дело в таймере,который тут вообще не нужен ,не успевает правильно читать координаты .Пропишите в ,событиях движения мыши ,привязку линии при условии изменении цены основной линии,должно нормально работать 
 
Нда, засада, однако. Придётся снова придумывать костыли. Куда ж без них? Спасибо.
 

// =============== CheckDotTrendLine() =============================================================
// Процедура ровняет штриховую линию, чтоб совпадала с привязанной к ней линии тренда
// На вход процедуры подаётся имя основной (сплошной линии) и префикс Dot_
// --------------------------------------------------------------------------
void CBasicExpert::CheckDotTrendLine(string SolidLineName){
        string s_DotLine;
        double LeftPrice;
        datetime LeftTime,RightTime;
        // ------------- Генерируем имя Dot-линии
        s_DotLine=StringConcatenate("Dot_",SolidLineName);
        // если основная найдена, то получаем значение цены её левой координаты
        if(ObjectFind(SolidLineName)>(-1)){// основная линия есть
                // считываем её левую координату цены
                LeftPrice=NormalizeDouble(ObjectGet(SolidLineName,OBJPROP_PRICE1),m_DGS);
                LeftTime=(datetime)ObjectGet(SolidLineName,OBJPROP_TIME1);
                RightTime=(datetime)ObjectGet(SolidLineName,OBJPROP_TIME2);
                if(ObjectFind(s_DotLine)>(-1)){// Пунктирная существует.
                        if(NormalizeDouble(ObjectGet(s_DotLine,OBJPROP_PRICE1),m_DGS)!=LeftPrice){
                                Print("LeftPrice = ",LeftPrice);
                                ObjectSet(s_DotLine,OBJPROP_PRICE1,LeftPrice);
                        }
                        if(NormalizeDouble(ObjectGet(s_DotLine,OBJPROP_PRICE2),m_DGS)!=LeftPrice){
                                ObjectSet(s_DotLine,OBJPROP_PRICE2,LeftPrice);
                        }
                        if(ObjectGet(s_DotLine,OBJPROP_TIME1)!=LeftTime){
                                Print("LeftTime = ",LeftTime);
                                ObjectSet(s_DotLine,OBJPROP_TIME1,LeftTime);
                        }
                        if(ObjectGet(s_DotLine,OBJPROP_TIME2)!=RightTime){
                                Print("RightTime = ",RightTime);
                                ObjectSet(s_DotLine,OBJPROP_TIME2,RightTime);
                        }
                }
                WindowRedraw();
        }
}

Линии всегда горизонтальные? 

 
Vitaly Murlenko #:
Нда, засада, однако. Придётся снова придумывать костыли. Куда ж без них? Спасибо.

выше написали, чуть детальнее, потому-что это не костыли. Костыли как-раз таки таймер :-)

в OnChartEvent надо реагировать на события CHARTEVENT_OBJECT_DRAG, CHARTEVENT_OBJECT_CHANGE, CHARTEVENT_OBJECT_ENDEDIT (последнее на всяк.случай) для sparam=имя_объекта.

void OnChartEvent(int id, ..., const string &sparam) {
int type;
if (!ObjectGetInteger(myTrendLine,type)) {

// видимо пользователь случайно удалил трендовую линию - надо её переделать

        ...
        ChartRedraw(0);

} else {

if ( (id == CHARTEVENT_OBJECT_DRAG || id ==CHARTEVENT_OBJECT_CHANGE || id == CHARTEVENT_OBJECT_ENDEDIT) && sparam == myTrendLine ) {

   // трендовую линия переместили или в свойствах поменяли координаты

   // проверяем что координаты действительно поменялись и соотв.меняем вторую линию и прочие построения

   ...

   ChartRedraw(0); // ОБЯЗАТЕЛЬНО ! иначе перерисует, но когда-нибудь потом, а надо сейчас
}

}

PS/ а веб-дездельникам чтоб икалось.. никак не могут освоить  форматирование моноширинного текста и подсветку внутри. СТЫД И ПОЗОР. Единственный сайт такой. Я больше подобных не знаю.
 
Putnik #:

Линии всегда горизонтальные? 

Да.

 
 
 

Привет. Подскажите, пожалста. 

Может ли робот читать текст Алертов (от индикатора, если это важно) ?