Может, так:
// Копирование HLine в Line int fHLine2Line(string OldName,string NewName="Прежний",string Text="Прежний",int Action=0){ int Error, Type=ObjectType(OldName); bool Ray; datetime Time0; double Price0; if( Type!=OBJ_HLINE ){ if( ПечататьПредупреждения ) Print("*** "+OldName+" недопустимый тип: "+Type); return(MyError); } if( NewName=="Прежний" ) NewName=OldName; if( NewName==OldName ) Action=2; // Удалять оригинал if( ObjectFind(OldName)==0 ){ // Копирование OldName в NewName double Price1=ObjectGet(OldName,OBJPROP_PRICE1); datetime Time1=ObjectGet(OldName,OBJPROP_TIME1); if( Time1==Time[LastBar-1] ){ Time1 =0; Price1=0; } if( Price1<=Zero ){ if( ПечататьПредупреждения ) Print("*** "+OldName+" не задана цена"); return(MyError); } double Price2=ObjectGet(OldName,OBJPROP_PRICE2); datetime Time2=ObjectGet(OldName,OBJPROP_TIME2); if( Time2==Time[LastBar-1] ){ Time2 =0; Price2=0; } double Price3=ObjectGet(OldName,OBJPROP_PRICE3); datetime Time3=ObjectGet(OldName,OBJPROP_TIME3); if( Time3==Time[LastBar-1] ){ Time3 =0; Price3=0; } if( (MathAbs(Price1-Price2)>Zero && Price2>Zero ) || (MathAbs(Price1-Price3)>Zero && Price3>Zero ) ){ if( ПечататьПредупреждения ) Print("*** "+OldName+" цены в точках уровня не совпадают"); return(MyError); } if( Price3>Zero ){ Ray=false; // Задан отрезок 2(1)-3 if( Price2>Zero ){ // Отрезок 2-3 Time0 =Time1; Price0=Price1; Time1 =Time2; // Начало отрезка Price1=Price2; } Time2=Time3; // Конец отрезка Price2=Price3; Time3=Time0; // Промежуточная точка Price3=Price0; if( РежимОтладки && ПечататьПредупреждения ) Print("* "+OldName+" заданы цены отрезка: " +DoubleToStr(Price1,Digits)+" / "+TimeToStr(Time1) +" ... "+DoubleToStr(Price3,Digits)+" / "+TimeToStr(Time3) +" ... "+DoubleToStr(Price2,Digits)+" / "+TimeToStr(Time2)); } else{ if( Price2>Zero ){ Ray=true; // Задан луч 2-1 Time0 =Time1; Price0=Price1; Time1 =Time2; // Начало луча Price1=Price2; Time2 =Time0; // Промежуточная точка Price2=Price0; if( РежимОтладки && ПечататьПредупреждения ) Print("* "+OldName+" заданы цены луча: " +DoubleToStr(Price1,Digits)+" / "+TimeToStr(Time1) +" ... "+DoubleToStr(Price2,Digits)+" / "+TimeToStr(Time2)); } else{ // Задан уровень 1 if( РежимОтладки && ПечататьПредупреждения ) Print("* "+OldName+" задана только цена уровня: " +DoubleToStr(Price1,Digits)+" / "+TimeToStr(Time1)); Error=fObjectCopy(OldName,NewName,Text,Action); return(Error); } } bool Фон =ObjectGet(OldName,OBJPROP_BACK); color Цвет =ObjectGet(OldName,OBJPROP_COLOR); int Стиль =ObjectGet(OldName,OBJPROP_STYLE); int Видимость=ObjectGet(OldName,OBJPROP_TIMEFRAMES); int Размер =ObjectGet(OldName,OBJPROP_WIDTH); if( Text=="Прежний" ) Text=ObjectDescription(OldName); if( Action==1 ){ // Спрятать оригинал if( !ObjectSet(OldName,OBJPROP_TIMEFRAMES,EMPTY) ){ Error=GetLastError(); if( !РежимОтладки ) PlaySound("alert.wav"); Print("***** "+OldName+" - ошибка при задании невидимости "+Error); } } if( Action==2 ) Error=fObjectDelete(OldName);// Удалить оригинал Error=fObjectDelete(NewName); // Удалить копию if( ObjectCreate(NewName,OBJ_TREND,0,Time1,Price1,Time2,Price2,Time3,Price3) ) { if( !ObjectSetText(NewName,Text) || !ObjectSet(NewName,OBJPROP_RAY,Ray) || !ObjectSet(NewName,OBJPROP_BACK,Фон) || !ObjectSet(NewName,OBJPROP_COLOR,Цвет) || !ObjectSet(NewName,OBJPROP_STYLE,Стиль) || !ObjectSet(NewName,OBJPROP_TIMEFRAMES,Видимость) || !ObjectSet(NewName,OBJPROP_WIDTH,Размер) ){ Error=GetLastError(); if( !РежимОтладки ) PlaySound("alert.wav"); Print("***** "+NewName+" - ошибка модификации параметров "+Error); } } else{ Error=GetLastError(); if( !РежимОтладки ) PlaySound("alert.wav"); Print("***** "+OldName+" - Копия "+NewName+" не создана, ошибка "+Error); } } else{ Error=MyError; if( ПечататьПредупреждения ) Print("*** "+OldName+" - Объект для копирования не найден!"); } return(Error); }
Лучше 1 раз увидеть
добрый день
Вижу вы мастер, а я не слишком продвинут в этом. Подскажите пожалуйста, мне ваш текст скопировать и создать новый индикатор? или как поступить?
Заранее благодарен
С уважением, Рушан
Может, так:
добрый день
Вижу вы мастер, а я не слишком продвинут в этом. Подскажите пожалуйста, мне ваш текст скопировать и создать новый индикатор? или как поступить?
Заранее благодарен
С уважением, Рушан
Добрый день всем. Ребята, помогите пожалуйста разобраться и исправить ошибку в индикаторе. Программа строит прямые линии (уровни) на графике цены по определённому алгоритму и задаваемым параметрам. Но к сожалению не всегда правильно закрывает эти лучи - в тех случаях когда цена открытия и закрытия находятся ниже (выше) этих лучей они не закрываются. Я могу пояснить скрин-шотами. Пожалуйста помогите разобраться.
Вот текст программы.
//+------------------------------------------------------------------+
//| trendline.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
#property version "1.20"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
//--- input parameters
input int maxbars=1488;//Количество свечей для расчёта
input color o_color=clrGold; //Цвет неактивного уровня
input color a_color=clrOrange; //Цвет активного уровня
input int dist=150; //Расстояние до ближайшего луча
input bool mark=false; //Метки экстремумов
double extr_high[];
double extr_low[];
color old_color=o_color;
color active_color=a_color;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
IndicatorShortName("trendline");
IndicatorDigits(5);
IndicatorBuffers(2);
SetIndexDrawBegin(0, 0);
SetIndexBuffer(0, extr_high);
if (mark) SetIndexStyle(0, DRAW_ARROW); else SetIndexStyle(0, DRAW_NONE);
SetIndexArrow(0, 117);
SetIndexEmptyValue(0,0.0);
SetIndexLabel(0,"extr high");
SetIndexDrawBegin(1, 0);
SetIndexBuffer(1, extr_low);
if (mark) SetIndexStyle(1, DRAW_ARROW); else SetIndexStyle(1, DRAW_NONE);
SetIndexArrow(1, 117);
SetIndexEmptyValue(1,0.0);
SetIndexLabel(1,"extr low");
if (old_color==active_color)active_color++;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
//---
ObjectsDeleteAll(0,"tr_",0,OBJ_TREND);
for (int i=1;i<maxbars;i++)
{
extr_high[i]=0;
extr_low[i]=0;
if (High[i]>High[i-1])
{
if (High[i]>High[i+1]) extr_high[i]=High[i];
if (High[i]==High[i+1] && High[i]>High[i+2])extr_high[i]=High[i];
}
if (Low[i]<Low[i-1])
{
if (Low[i]<Low[i+1]) extr_low[i]=Low[i];
if (Low[i]==Low[i+1] && Low[i]>Low[i+2])extr_low[i]=Low[i];
}
}
for (int i=maxbars;i>0;i--)
{
for (int j=0;j<ObjectsTotal();j++)
{
if (ObjectType(ObjectName(j))==OBJ_TREND
&& StringSubstr(ObjectName(j),0,3)=="tr_"
&& ObjectGet(ObjectName(j),OBJPROP_COLOR)==active_color)
{
if (Open[i]<ObjectGet(ObjectName(j),OBJPROP_PRICE1) && ObjectGet(ObjectName(j),OBJPROP_PRICE1)<Close[i] && ObjectGet(ObjectName(j),OBJPROP_TIME1 != Time[i]))
{
ObjectMove(0,ObjectName(j),1,Time[i],ObjectGet(ObjectName(j),OBJPROP_PRICE1));
ObjectSet(ObjectName(j),OBJPROP_COLOR,old_color);
ObjectSet(ObjectName(j),OBJPROP_RAY,false);
}
if (Open[i]>ObjectGet(ObjectName(j),OBJPROP_PRICE1) && ObjectGet(ObjectName(j),OBJPROP_PRICE1)>Close[i] && ObjectGet(ObjectName(j),OBJPROP_TIME1 != Time[i]))
{
ObjectMove(0,ObjectName(j),1,Time[i],ObjectGet(ObjectName(j),OBJPROP_PRICE1));
ObjectSet(ObjectName(j),OBJPROP_COLOR,old_color);
ObjectSet(ObjectName(j),OBJPROP_RAY,false);
}
}
}
if (extr_high[i]!=0)
{
bool dist_check=true;
for (int j=0;j<ObjectsTotal();j++)
{
if (ObjectType(ObjectName(j))==OBJ_TREND
&& StringSubstr(ObjectName(j),0,3)=="tr_"
&& ObjectGet(ObjectName(j),OBJPROP_COLOR)==active_color)
{
if (extr_high[i]!=0 && MathAbs(ObjectGet(ObjectName(j),OBJPROP_PRICE1)-extr_high[i])<dist/MathPow(10,Digits)) dist_check = false;
}
}
if (dist_check)
{
ObjectCreate("tr_H"+Time[i],OBJ_TREND, 0, Time[i],extr_high[i],Time[0],extr_high[i]);
ObjectSet("tr_H"+Time[i],OBJPROP_COLOR,active_color);
ObjectSet("tr_H"+Time[i],OBJPROP_RAY,true);
}
}
if (extr_low[i]!=0)
{
bool dist_check=true;
for (int j=0;j<ObjectsTotal();j++)
{
if (ObjectType(ObjectName(j))==OBJ_TREND
&& StringSubstr(ObjectName(j),0,3)=="tr_"
&& ObjectGet(ObjectName(j),OBJPROP_COLOR)==active_color)
{
if (extr_low[i]!=0 && MathAbs(ObjectGet(ObjectName(j),OBJPROP_PRICE1)-extr_low[i])<dist/MathPow(10,Digits)) dist_check = false;
}
}
if (dist_check)
{
ObjectCreate("tr_L"+Time[i],OBJ_TREND, 0, Time[i],extr_low[i],Time[0],extr_low[i]);
ObjectSet("tr_L"+Time[i],OBJPROP_COLOR,active_color);
ObjectSet("tr_L"+Time[i],OBJPROP_RAY,true);
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Добрый день,
пожалуйста помогите написать индикатор, который на графике цены рисует уровень поддержки и сопротивления (инструмент трендовая линия) параллельно горизонтальной шкале времени. Уровень начинает строится от появляющегося экстремума от цены High или Low, сначала в виде луча слева направо. Луч должен превратиться в отрезок на той свече, на которой цена её закрытия будет выше (для сопротивления) или ниже (для поддержки).
Луч должен начинать строиться только в том случае если другой ближайший действительный уровень в виде луча находится на расстоянии более 100 пунктов