Serzh_2018:
Хочу написать индикатор. Написал 0-й уровень который выставляет точки над максимумами и минимумами. Теперь нужно в 1 уровне отфильтровать ненужные максимумы и минимумы. Так чтобы максимумы и минимумы ишли поочередно и чтобы между двумя максимумами был только один минимум и наоборот.
Сейчас в индикаторе точки отображаются так:
А нужно чтобы отображались так:
Вото код моего индикатора:
Код смотреть не стал, ибо нет смысла. Алгоритм же предельно ясен - если нашелся второй максимум больше первого, первый удаляем, второй переименовываем в первый. То же и с минимумами, только наоборот.
Помогите пожалуйста! прикрепить горизонтальные линии к точкам.
//+------------------------------------------------------------------+ //| San.mq5 | //| Copyright © 2005, BrainTrading Inc | //| http://www.braintrading.com | //+------------------------------------------------------------------+ //---- авторство индикатора #property copyright "Copyright © 2005, BrainTrading Inc." //---- ссылка на сайт автора #property link "http://www.braintrading.com/" //---- номер версии индикатора #property version "1.00" //---- отрисовка индикатора в главном окне #property indicator_chart_window //---- для расчета и отрисовки индикатора использовано два буфера #property indicator_buffers 2 //---- использовано всего два графических построения #property indicator_plots 2 //+----------------------------------------------+ //| Параметры отрисовки медвежьего индикатора | //+----------------------------------------------+ //---- отрисовка индикатора 1 в виде символа #property indicator_type1 DRAW_ARROW //---- в качестве цвета медвежьей линии индикатора использован розовый цвет #property indicator_color1 clrRed //---- толщина линии индикатора 1 равна 4 #property indicator_width1 2 //---- отображение метки медвежьей линии индикатора #property indicator_label1 "San Sell" //+----------------------------------------------+ //| Параметры отрисовки бычьго индикатора | //+----------------------------------------------+ //---- отрисовка индикатора 2 в виде символа #property indicator_type2 DRAW_ARROW //---- в качестве цвета бычей линии индикатора использован зеленый цвет #property indicator_color2 clrBlue //---- толщина линии индикатора 2 равна 4 #property indicator_width2 2 //---- отображение метки бычьей линии индикатора #property indicator_label2 "San Buy" //+----------------------------------------------+ //| Входные параметры индикатора | //+----------------------------------------------+ input int ATR_Period=7; //период ATR input int STO_Period=9; //период стохастика input ENUM_MA_METHOD MA_Method = MODE_SMA; //метод усреднения input ENUM_STO_PRICE STO_Price = STO_LOWHIGH; //метод расчета цен //--- input parameters input string InpUpperName = "Trend line upper"; // "Trend line upper": name input string InpLowerName = "Trend line lower"; // "Trend line lower": name //+----------------------------------------------+ //---- объявление динамических массивов, которые будут в //---- дальнейшем использованы в качестве индикаторных буферов double SellBuffer[]; double BuyBuffer[]; //--- double d,s; int p,x1,x2,P_,StartBars,OldTrend; int ATR_Handle,STO_Handle,RSI_Handle,MACD_Handle; datetime m_prev_bars = 0; // "0" -> D'1970.01.01 00:00'; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //--- CreateHline(0,0,InpUpperName,0,clrRed,0,0,1,1,1,1,2); CreateHline(0,0,InpLowerName,0,clrBlue,0,0,1,1,1,1,2); //---- инициализация глобальных переменных d=2.3; s=1.5; x1 = 53; x2 = 47; StartBars=MathMax(ATR_Period,STO_Period)+2; //---- получение хендла индикатора ATR ATR_Handle=iATR(NULL,0,ATR_Period); if(ATR_Handle==INVALID_HANDLE) Print(" Не удалось получить хендл индикатора ATR"); //---- получение хендла индикатора Stochastic STO_Handle=iStochastic(NULL,0,STO_Period,STO_Period,1,MA_Method,STO_Price); if(STO_Handle==INVALID_HANDLE) Print(" Не удалось получить хендл индикатора Stochastic"); //---- получение хендла индикатора RSI RSI_Handle=iRSI(NULL,0,9,PRICE_CLOSE); if(RSI_Handle==INVALID_HANDLE) Print(" Не удалось получить хендл индикатора iRSI"); //---- получение хендла индикатора MACD MACD_Handle=iCustom(Symbol(),Period(),"Examples\\ZigzagColor",12,5,3); if(MACD_Handle==INVALID_HANDLE) Print(" Не удалось получить хендл индикатора iMACD"); //---- превращение динамического массива в индикаторный буфер SetIndexBuffer(0,SellBuffer,INDICATOR_DATA); //---- осуществление сдвига начала отсчета отрисовки индикатора 1 PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartBars); //--- создание метки для отображения в DataWindow PlotIndexSetString(0,PLOT_LABEL,"San Sell"); //---- символ для индикатора PlotIndexSetInteger(0,PLOT_ARROW,217); //---- индексация элементов в буфере как в таймсерии ArraySetAsSeries(SellBuffer,true); //---- превращение динамического массива в индикаторный буфер SetIndexBuffer(1,BuyBuffer,INDICATOR_DATA); //---- осуществление сдвига начала отсчета отрисовки индикатора 2 PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,StartBars); //--- создание метки для отображения в DataWindow PlotIndexSetString(1,PLOT_LABEL,"San Buy"); //---- символ для индикатора PlotIndexSetInteger(1,PLOT_ARROW,218); //---- индексация элементов в буфере как в таймсерии ArraySetAsSeries(BuyBuffer,true); //---- установка формата точности отображения индикатора IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //---- имя для окон данных и лэйба для субъокон string short_name="San"; IndicatorSetString(INDICATOR_SHORTNAME,short_name); //---- } //+------------------------------------------------------------------+ //| Indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(ATR_Handle!=INVALID_HANDLE) IndicatorRelease(ATR_Handle); if(STO_Handle!=INVALID_HANDLE) IndicatorRelease(STO_Handle); if(RSI_Handle!=INVALID_HANDLE) IndicatorRelease(RSI_Handle); if(MACD_Handle!=INVALID_HANDLE) IndicatorRelease(MACD_Handle); //--- ObjectsDeleteAll(0,InpUpperName); ObjectsDeleteAll(0,InpLowerName); } //+------------------------------------------------------------------+ //| 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[]) { //---- проверка количества баров на достаточность для расчета if(BarsCalculated(ATR_Handle)<rates_total || BarsCalculated(STO_Handle)<rates_total || BarsCalculated(RSI_Handle)<rates_total || BarsCalculated(MACD_Handle)<rates_total || rates_total<StartBars) return(0); //---- объявления локальных переменных int to_copy,limit,bar; double value2[],Range[],RSI[],MACD[],MACDS[],range,range2,val1,val2,val3; bool RsiUp,RsiDn,MacdUp,MacdDn; //---- double upper_left=0.0,upper_right=0.0,lower_left=0.0,lower_right=0.0; datetime upper_left_date=0,upper_right_date=0,lower_left_date=0,lower_right_date=0; //---- расчеты необходимого количества копируемых данных и //стартового номера limit для цикла пересчета баров if(prev_calculated>rates_total || prev_calculated<=0)// проверка на первый старт расчета индикатора { to_copy=rates_total; // расчетное количество всех баров limit=rates_total-StartBars; // стартовый номер для расчета всех баров } else { to_copy=rates_total-prev_calculated+1; // расчетное количество только новых баров limit=rates_total-prev_calculated; // стартовый номер для расчета новых баров } //---- копируем вновь появившиеся данные в массивы Range[] и value2[] if(CopyBuffer(ATR_Handle,0,0,to_copy,Range)<=0) return(0); if(CopyBuffer(STO_Handle,0,0,to_copy,value2)<=0) return(0); if(CopyBuffer(RSI_Handle,0,0,to_copy,RSI)<=0) return(0); if(CopyBuffer(MACD_Handle,0,0,to_copy,MACD)<=0) return(0); if(CopyBuffer(MACD_Handle,1,0,to_copy,MACDS)<=0) return(0); //---- индексация элементов в массивах как в таймсериях ArraySetAsSeries(RSI,true); ArraySetAsSeries(MACD,true); ArraySetAsSeries(MACDS,true); ArraySetAsSeries(Range,true); ArraySetAsSeries(value2,true); ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); //---- восстанавливаем значения переменных p=P_; //--- main loop //--- we work only at the time of the birth of new bar datetime time_0=iTime(Symbol(),Period(),0); if(time_0==m_prev_bars) return(rates_total); m_prev_bars=time_0; //---- основной цикл расчета индикатора for(bar=limit; bar>=0; bar--) { //---- запоминаем значения переменных перед прогонами на текущем баре if(rates_total!=prev_calculated && bar==0) P_=p; range=Range[bar]/d; range2=Range[bar]*s/4; val1 = 0.0; val2 = 0.0; SellBuffer[bar]=0.0; BuyBuffer[bar]=0.0; RsiDn=RSI[bar]>=x2; RsiUp=RSI[bar]<=x1; MacdDn=MACD[bar]>MACDS[bar]; MacdUp=MACD[bar]<MACDS[bar]; val3=MathAbs(close[bar]-close[bar+2]); //---- if(RsiDn && MacdDn && value2[bar] > x1 && val3 > range) p = 1; if(RsiUp && MacdUp && value2[bar] < x2 && val3 > range) p = 2; if(val3<=range) continue; //---- if(RsiDn && MacdDn && value2[bar]>x1 && (p==1 || p==0)) { if(OldTrend>0) SellBuffer[bar]=high[bar]+range2; if(bar!=0) OldTrend=-1; //---- if(SellBuffer[bar]!=0.0 && SellBuffer[bar]!=EMPTY_VALUE) { if(lower_left==0.0) { lower_left=SellBuffer[bar]; lower_left_date=time[bar]; } else if(lower_right==0.0) { lower_right=SellBuffer[bar]; lower_right_date=time[bar]; } } } //---- if(RsiUp && MacdUp && value2[bar]<x2 && (p==2 || p==0)) { if(OldTrend<0) BuyBuffer[bar]=low[bar]-range2; if(bar!=0) OldTrend=+1; //---- if(BuyBuffer[bar]!=0.0 && BuyBuffer[bar]!=EMPTY_VALUE) { if(upper_left==0.0) { upper_left=BuyBuffer[bar]; upper_left_date=time[bar]; } else if(upper_right==0.0) { upper_right=BuyBuffer[bar]; upper_right_date=time[bar]; } } } if(upper_left!=0.0 && upper_right!=0.0 && lower_left!=0.0 && lower_right!=0.0) break; } if(upper_left==0.0 || upper_right==0.0 || lower_left==0.0 || lower_right==0.0) return(rates_total); //--- if(!ObjectMove(0,InpUpperName,0,upper_left_date,upper_left)) return(rates_total); if(!ObjectMove(0,InpLowerName,0,lower_left_date,lower_left)) return(rates_total); //---- return(rates_total); } //+------------------------------------------------------------------+ //| Создание горизонтального, ценового уровня | //+------------------------------------------------------------------+ bool CreateHline(long ch_id,int sub_window, string name,double price, color clr,ENUM_LINE_STYLE style, int width,bool back, bool selectable,bool selected, bool hidden,long z_order) { ObjectCreate(ch_id,name,OBJ_HLINE,sub_window,0,price); ObjectSetInteger(ch_id,name,OBJPROP_COLOR,clr); ObjectSetInteger(ch_id,name,OBJPROP_STYLE,style); ObjectSetInteger(ch_id,name,OBJPROP_WIDTH,width); ObjectSetInteger(ch_id,name,OBJPROP_BACK,back); ObjectSetInteger(ch_id,name,OBJPROP_SELECTABLE,selectable); ObjectSetInteger(ch_id,name,OBJPROP_SELECTED,selected); ObjectSetInteger(ch_id,name,OBJPROP_HIDDEN,hidden); ObjectSetInteger(ch_id,name,OBJPROP_ZORDER,z_order); return(true); } //+------------------------------------------------------------------+на рисунке 2 получилось через другой индикатор - хотелось бы, в этом как то. Может кто поможет?
Файлы:
ez0evw.PNG
98 kb
ip9lr82.PNG
110 kb
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Хочу написать индикатор. Написал 0-й уровень который выставляет точки над максимумами и минимумами. Теперь нужно в 1 уровне отфильтровать ненужные максимумы и минимумы. Так чтобы максимумы и минимумы ишли поочередно и чтобы между двумя максимумами был только один минимум и наоборот.
Сейчас в индикаторе точки отображаются так:
А нужно чтобы отображались так:
Вото код моего индикатора: