Как сместить МА по вертикали или как в МА "впихнуть" сумму нескольких ценовых значений - страница 3
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Ваш индикатор сконструирован крайне неэффективно - Вы на каждом тике (при каждом входе в OnCalculate()) перечитываете два индикаторных буфера на всю глубину:
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
}
Прочтите, что означают переменные rates_total и prev_calculated.
Здравствуйте!
Зарегистрировал новый аккаунт, надеюсь на этот раз корректный. Переделал код. Подскажите пожалуйста, как прицепить стрелки к индикатору ниже (2 линии), чтобы стрелки появлялись при касании или пробитии линий используемого индикатора, до закрытия текущей свечи (то есть, касание или пробитие текущей ценой (после open до close) линии индикатора, - стрелка) в MQL5:
//| 2Lines Оптимизированный.mq5 |
//| Copyright 2016, Вован |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Вован"
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//--- plot Line1
#property indicator_label1 "Line1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- plot Line2
#property indicator_label2 "Line2"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//--- input parameters
input ushort Y=30;
double ExtY=0.0;
//--- indicator buffers
double Line1Buffer[];
double Line2Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Line1Buffer,INDICATOR_DATA);
SetIndexBuffer(1,Line2Buffer,INDICATOR_DATA);
//---
ExtY=Y*Point(); // tuning
//---
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[])
{
int first; //---- объявление локальных переменных (новое условное значение)
//--- Проверка количества баров на достаточность для расчета
if(rates_total<1)
return(0);
//---- расчёт стартового номера first для цикла пересчёта баров
if (prev_calculated==0) // проверка на первый старт расчёта индикатора
first=0; // стартовый номер для расчёта всех баров
else first=prev_calculated - 1; // стартовый номер для расчёта новых баров
//--- Основной цикл расчета индикатора
for(int i=0;i<rates_total;i++)
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
Здравствуйте!
Зарегистрировал новый аккаунт, надеюсь на этот раз корректный. Переделал код. Подскажите пожалуйста, как прицепить стрелки к индикатору ниже (2 линии), чтобы стрелки появлялись при касании или пробитии линий используемого индикатора, до закрытия текущей свечи (то есть, касание или пробитие текущей ценой (после open до close) линии индикатора, - стрелка) в MQL5:
У Вас всё-равно неэкономный расчёт - Вы просчитываете на всю глубину. Вот экономный пересчёт: при prev_calculated==0 (это бывает при первом старте или при подкачке истории) рассчитываем на всю глубину - от limit=="0" до "rates_total". При последующих заходах в OnCalculate() limit=prev_calculated-1 - то есть будет всё время перечитывать только текущий бар или два бара, когда появится новый бар:
//| Line.mq5 |
//| Copyright 2016, Вован |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Вован"
#property link "https://www.mql5.com"
#property version "1.001"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//--- plot Line1
#property indicator_label1 "Line1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- plot Line2
#property indicator_label2 "Line2"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//--- input parameters
input ushort Y=30;
double ExtY=0.0;
//--- indicator buffers
double Line1Buffer[];
double Line2Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Line1Buffer,INDICATOR_DATA);
SetIndexBuffer(1,Line2Buffer,INDICATOR_DATA);
//---
ExtY=Y*Point(); // tuning
//---
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[])
{
//---
int limit=0;
if(prev_calculated==0) // the first start or the history has been changed
{
for(int i=limit;i<rates_total;i++) // calculation on all depth of history
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
}
}
else
{
limit=prev_calculated-1; // economical recalculation of bars
for(int i=limit;i<rates_total;i++)
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
}
}
Comment("rates_total=",rates_total,"\n",
"limit=",limit);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
}
//+------------------------------------------------------------------+
Про стрелочки чуть позже, а пока для прочтения:
Как-то вот так:
//| EMA.mq5 |
//| MQL5 code: Copyright © 2010, Nikolay Kositsin |
//| Khabarovsk, farria@mail.redcom.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//---- номер версии индикатора
#property version "1.01"
//---- отрисовка индикатора в главном окне
#property indicator_chart_window
//---- количество индикаторных буферов
#property indicator_buffers 1
//---- использовано всего одно графическое построение
#property indicator_plots 1
//+-----------------------------------+
//| Параметры отрисовки индикатора |
//+-----------------------------------+
//---- отрисовка индикатора в виде линии
#property indicator_type1 DRAW_LINE
//---- в качестве цвета линии индикатора использован clrMediumSlateBlue цвет
#property indicator_color1 clrMediumSlateBlue
//---- линия индикатора - непрерывная кривая
#property indicator_style1 STYLE_SOLID
//---- толщина линии индикатора равна 2
#property indicator_width1 2
//---- отображение метки индикатора
#property indicator_label1 "EMA"
//+-----------------------------------+
//| объявление перечислений |
//+-----------------------------------+
enum Applied_price_ //Тип константы
{
PRICE_CLOSE_ = 1, //Close
PRICE_OPEN_, //Open
PRICE_HIGH_, //High
PRICE_LOW_, //Low
PRICE_MEDIAN_, //Median Price (HL/2)
PRICE_TYPICAL_, //Typical Price (HLC/3)
PRICE_WEIGHTED_, //Weighted Close (HLCC/4)
PRICE_SIMPL_, //Simpl Price (OC/2)
PRICE_QUARTER_, //Quarted Price (HLOC/4)
PRICE_TRENDFOLLOW0_, //TrendFollow_1 Price
PRICE_TRENDFOLLOW1_, //TrendFollow_2 Price
PRICE_DEMARK_ //Demark Price
};
//+-----------------------------------+
//| ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА |
//+-----------------------------------+
input double EmaLength=12.75; // глубина сглаживания
input Applied_price_ IPC=PRICE_CLOSE_; // ценовая константа
input int Shift=0; // сдвиг индикатора по горизонтали в барах
input int PriceShift=0; // cдвиг индикатора по вертикали в пунктах
//+-----------------------------------+
//---- индикаторный буфер
double EMABuffer[];
double dPriceShift;
//---- Объявление глобальных переменных
int min_rates_total;
//+------------------------------------------------------------------+
// Описание класса CMoving_Average |
//+------------------------------------------------------------------+
#include <SmoothAlgorithms.mqh>
//+------------------------------------------------------------------+
//| EMA indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//---- Инициализация переменных начала отсчёта данных
min_rates_total=2;
//---- превращение динамического массива в индикаторный буфер
SetIndexBuffer(0,EMABuffer,INDICATOR_DATA);
//---- осуществление сдвига индикатора по горизонтали на Shift
PlotIndexSetInteger(0,PLOT_SHIFT,Shift);
//---- осуществление сдвига начала отсчёта отрисовки индикатора
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
//--- создание метки для отображения в DataWindow
PlotIndexSetString(0,PLOT_LABEL,"EMA");
//---- установка значений индикатора, которые не будут видимы на графике
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
//---- инициализации переменной для короткого имени индикатора
string shortname;
StringConcatenate(shortname,"EMA( Length = ",EmaLength,")");
//--- создание имени для отображения в отдельном подокне и во всплывающей подсказке
IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- определение точности отображения значений индикатора
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- Инициализация сдвига по вертикали
dPriceShift=_Point*PriceShift;
//---- завершение инициализации
}
//+------------------------------------------------------------------+
//| EMA 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(rates_total<min_rates_total) return(0);
//---- Объявление локальных переменных
int first,bar;
double series,ema;
if(prev_calculated>rates_total || prev_calculated<=0) // проверка на первый старт расчёта индикатора
{
first=0; // стартовый номер для расчёта всех баров
}
else first=prev_calculated-min_rates_total; // стартовый номер для расчёта новых баров
//---- объявление переменных класса CMoving_Average из файла SmoothAlgorithms.mqh
static CMoving_Average EMA;
//---- основной цикл расчёта индикатора
for(bar=first; bar<rates_total && !IsStopped(); bar++)
{
series=PriceSeries(IPC,bar,open,low,high,close);
ema=EMA.EMASeries(0,prev_calculated,rates_total,EmaLength,series,bar,false);
EMABuffer[bar]=ema+dPriceShift;
}
//----
return(rates_total);
}
//+------------------------------------------------------------------+
Про стрелочки чуть позже, а пока для прочтения:
Прочитал несколько раз ссылки, но что-то не пойму ничего. Может я ошибаюсь, но мне кажется в моем случае можно сделать проще по принципу индикатора "Fractals", то есть добавить 2 буфера данных - стрелки и рисовать их при наступлении определенного условия, например:
//| 2Lines & Arrows.mq5 |
//| Copyright 2016, Вован |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Вован"
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4
//--- plot Line1
#property indicator_label1 "Line1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- plot Line2
#property indicator_label2 "Line2"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrGreen
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//--- plot Arrow1
#property indicator_label3 "Arrow1"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrRed
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//--- plot Arrow2
#property indicator_label4 "Arrow2"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrGreen
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//--- input parameters
input ushort Y=30;
double ExtY=0.0;
//--- indicator buffers
double Line1Buffer[];
double Line2Buffer[];
double Arrow1Buffer[];
double Arrow2Buffer[];
//--- 10 пунктов под/над high price
int ExtArrowShift=-10;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Line1Buffer,INDICATOR_DATA);
SetIndexBuffer(1,Line2Buffer,INDICATOR_DATA);
SetIndexBuffer(2,Arrow1Buffer,INDICATOR_DATA);
SetIndexBuffer(3,Arrow2Buffer,INDICATOR_DATA);
//---
ExtY=Y*Point(); // tuning
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
PlotIndexSetInteger(2,PLOT_ARROW,234);
PlotIndexSetInteger(3,PLOT_ARROW,233);
//---- arrow shifts when drawing
PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,ExtArrowShift);
PlotIndexSetInteger(3,PLOT_ARROW_SHIFT,-ExtArrowShift);
//---
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[])
{
//---
int limit=0;
if(prev_calculated==0) // the first start or the history has been changed
{
for(int i=limit;i<rates_total;i++) // calculation on all depth of history
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
}
}
else
{
limit=prev_calculated-1; // economical recalculation of bars
for(int i=limit;i<rates_total;i++)
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
}
}
Comment("rates_total=",rates_total,"\n",
"limit=",limit);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
}
//+------------------------------------------------------------------+
Только вот не уверен на счет:
int ExtArrowShift=-10;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---- arrow shifts when drawing
PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,ExtArrowShift);
PlotIndexSetInteger(3,PLOT_ARROW_SHIFT,-ExtArrowShift);
и не пойму как прописать условие привязки стрелок в функцию
PLOT_ARROW_SHIFT Задаёт смещение в пикселях, а не в пунктах/пипсах. Также для стиля "стрелки" важно указать значение, которое не будет отображаться. Как это работает: если мы хотим нарисовать стрелку, то нужно в индикаторный буфер стрелки записать текущую цену - эта цена будет точкой привязки (координатой) для рисования стрелки. Если мы не хотим рисовать стрелку, то в индикаторный буфер стрелки записываем 0.0. Но "0.0" это тоже цена и стрелка нарисуется где-то там внизу - это не есть хорошо, поэтому делают так:
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0.0);
"PLOT_EMPTY_VALUE" - пустое значение для построения, для которого нет отрисовки. То есть после такого объявления, когда в индикаторном буфера стрелки будет значение "0.0" ничего отрисовываться не будет.
Индикатор примет вид:
//| Line.mq5 |
//| Copyright 2016, Вован |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Вован"
#property link "https://www.mql5.com"
#property version "1.002"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 4
//--- plot Line1
#property indicator_label1 "Line1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- plot Line2
#property indicator_label2 "Line2"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
//--- plot Arrow1
#property indicator_label3 "Arrow1"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrBlue
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//--- plot Arrow2
#property indicator_label4 "Arrow2"
#property indicator_type4 DRAW_ARROW
#property indicator_color4 clrRed
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//--- input parameters
input ushort Y=30;
//---
double ExtY=0.0;
int ArrowShift=10; // vertical shift of arrows for style DRAW_ARROW (in pixels)
//--- indicator buffers
double Line1Buffer[];
double Line2Buffer[];
double Arrow1Buffer[];
double Arrow2Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Line1Buffer,INDICATOR_DATA);
SetIndexBuffer(1,Line2Buffer,INDICATOR_DATA);
SetIndexBuffer(2,Arrow1Buffer,INDICATOR_DATA);
SetIndexBuffer(3,Arrow2Buffer,INDICATOR_DATA);
//--- define the symbol code from the Wingdings font to draw in PLOT_ARROW
PlotIndexSetInteger(2,PLOT_ARROW,233);
PlotIndexSetInteger(3,PLOT_ARROW,234);
//--- set the vertical shift of arrows in pixels
PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,ArrowShift);
PlotIndexSetInteger(3,PLOT_ARROW_SHIFT,-ArrowShift);
//--- set an empty value
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0.0);
//--- tuning for 3 or 5 digits
int digits_adjust=1;
if(Digits()==3 || Digits()==5)
digits_adjust=10;
ExtY=Y*digits_adjust*Point(); // tuning
//---
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[])
{
//---
int limit=0;
if(prev_calculated==0) // the first start or the history has been changed
{
for(int i=limit;i<rates_total;i++) // calculation on all depth of history
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
if(close[i]>Line1Buffer[i])
Arrow1Buffer[i]=Line1Buffer[i];
else
Arrow1Buffer[i]=0.0;
if(close[i]<Line2Buffer[i])
Arrow2Buffer[i]=Line2Buffer[i];
else
Arrow2Buffer[i]=0.0;
}
}
else
{
limit=prev_calculated-1; // economical recalculation of bars
for(int i=limit;i<rates_total;i++)
{
Line1Buffer[i]=open[i]+ExtY;
Line2Buffer[i]=open[i]-ExtY;
if(close[i]>Line1Buffer[i])
Arrow1Buffer[i]=Line1Buffer[i];
else
Arrow1Buffer[i]=0.0;
if(close[i]<Line2Buffer[i])
Arrow2Buffer[i]=Line2Buffer[i];
else
Arrow2Buffer[i]=0.0;
}
}
Comment("rates_total=",rates_total,"\n",
"limit=",limit);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
}
//+------------------------------------------------------------------+
Но учтите, данная версия работает внутри бара и может быть такая ситуация:
PLOT_ARROW_SHIFT Задаёт смещение в пикселях, а не в пунктах/пипсах. Также для стиля "стрелки" важно указать значение, которое не будет отображаться. Как это работает: если мы хотим нарисовать стрелку, то нужно в индикаторный буфер стрелки записать текущую цену - эта цена будет точкой привязки (координатой) для рисования стрелки. Если мы не хотим рисовать стрелку, то в индикаторный буфер стрелки записываем 0.0. Но "0.0" это тоже цена и стрелка нарисуется где-то там внизу - это не есть хорошо, поэтому делают так:
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0.0);
"PLOT_EMPTY_VALUE" - пустое значение для построения, для которого нет отрисовки. То есть после такого объявления, когда в индикаторном буфера стрелки будет значение "0.0" ничего отрисовываться не будет.
Индикатор примет вид:
Спасибо огромное, код выглядит как я и ожидал. Идеально! Но что-то у меня не отображается индикатор на графике теперь.
Терминал, меню "Вид", пункт "Окно данных". Есть индикатор?
Я сделал вот такую штуку: