Да уж, на MQL5 форуме, похоже, помощи не дождешся.
Не понятна цель
При инициализации нарисовать -это сделано в скрипте уже.
что еще надо?
Всегда отрисовывать только 100?
вывести в отельную фунцию и вызывать в
void OnStart() // инициализация
{
// тут вызов
}
и в 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 &TickVolume[],
const long &Volume[],
const int &Spread[])
{int i;
// тут вызов
return(i);
}
- при тике
может все дело в тайм сериях и организации доступа к данным
тут все немного иначе
Пришел к такому, заднепроходному решению. Есть варианты получше?
#property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 4 //--- plot Source #property indicator_label1 "Source" #property indicator_type1 DRAW_HISTOGRAM #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Etalon #property indicator_label2 "Etalon" #property indicator_type2 DRAW_LINE #property indicator_color2 Yellow #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot Normalised #property indicator_label3 "Normalised" #property indicator_type3 DRAW_LINE #property indicator_color3 DarkGreen #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot Label4 #property indicator_label4 "Label4" #property indicator_type4 DRAW_LINE #property indicator_color4 Red #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- input parameters input int Clusters =100; input int History =1000; input int Input3; input int Input4; input double HdifferenceBetweenBars =0.005; input double LdifferenceBetweenBars =0.01; input double HBarHeight =0.005; input double LBarHeight =0.01; //--- indicator buffers double SourceBuffer[]; //double EtalonBuffer[]; //double NormalisedBuffer[]; //double Label4Buffer[]; //double temp[]; //-------------------- double Open []; double Hight []; double Low []; double Close []; datetime Time []; datetime Ti []; double Peaks []; int CLUSTER[]; double BarLength[]; double DifferenceOfBars[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { ArraySetAsSeries(Open,true); CopyOpen (NULL,0,0,History+2,Open); ArraySetAsSeries(Hight,true); CopyHigh (NULL,0,0,History+2,Hight); ArraySetAsSeries(Low,true); CopyLow (NULL,0,0,History+2,Low); ArraySetAsSeries(Close,true); CopyClose(NULL,0,0,History+2,Close); ArraySetAsSeries(Time,true); CopyTime (NULL,0,0,History+2,Time); //----------------------------------------------------------- ArrayResize(CLUSTER, Clusters);ArrayInitialize(CLUSTER, 0); ArrayResize(BarLength,Clusters);ArrayInitialize(BarLength,0); //--- indicator buffers mapping SetIndexBuffer (0,SourceBuffer,INDICATOR_DATA); PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,2); PlotIndexSetString (0,PLOT_LABEL,"SourceBuffer"); /* SetIndexBuffer (1,EtalonBuffer,INDICATOR_DATA); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,2); PlotIndexSetString (1,PLOT_LABEL,"EtalonBuffer"); SetIndexBuffer(2,NormalisedBuffer,INDICATOR_DATA); SetIndexBuffer(3,Label4Buffer,INDICATOR_DATA); ArrayResize(temp,Clusters); */ //--- return(0); } //+------------------------------------------------------------------+ //| 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 i=0; while (i<rates_total-1) { SourceBuffer [i]=0.0; //EtalonBuffer [i]=0.0; //NormalisedBuffer[i]=0.0; i++; } if (Bars(NULL,PERIOD_CURRENT)== rates_total) { double DeltaLen=0.0; double DeltaAve=0.0; double BarLen =0.0; double Hi =0.0; double Lo =0.0; double Ave=0.0,AvePrev=0.0; double SumAve=0.0; double x=0.0; ObjectsDeleteAll(0,-1,-1); //1-e yoai SumAve=(Hight[1]+Low[1])/2.0; x=Hight[1]-Low[1]; DeltaLen=((2.0/(1.0+MathPow(2.0,-x*(10/LBarHeight))))-1.0)*HBarHeight/2.0; Hi=NormalizeDouble(SumAve+DeltaLen,Digits()); Lo=NormalizeDouble(SumAve-DeltaLen,Digits()); //CLUSTER[]; //BarLength[1]=Hi-Lo; ObjectCreate (0,"AltBar0",OBJ_TREND,0,Time[1],Hi,Time[1],Lo); if (Open[1]>Close[1]) ObjectSetInteger(0,"AltBar0",OBJPROP_COLOR,Yellow); else ObjectSetInteger(0,"AltBar0",OBJPROP_COLOR,Green); ObjectSetInteger(0,"AltBar0",OBJPROP_SELECTABLE,true); ObjectSetInteger(0,"AltBar0",OBJPROP_WIDTH,3); //------- for (int V=2;V<=Clusters;V++) { //2-e yoai Ave =(Hight[V-1]+Low[V-1])/2.0; AvePrev=(Hight[V] +Low[V]) /2.0; x=Ave-AvePrev; DeltaAve=((2.0/(1.0+MathPow(2.0,-x*(10/LdifferenceBetweenBars))))-1.0)*HdifferenceBetweenBars/2.0; SumAve-=DeltaAve; x=Hight[V]-Low[V]; DeltaLen=((2.0/(1.0+MathPow(2.0,-x*(10/LBarHeight))))-1.0)*HBarHeight/2.0; Hi=NormalizeDouble(SumAve+DeltaLen,Digits()); Lo=NormalizeDouble(SumAve-DeltaLen,Digits()); //BarLength[V] ObjectCreate (0,"AltBar"+(string)V,OBJ_TREND,0,Time[V],Hi,Time[V],Lo); if (Open[V]>Close[V]) ObjectSetInteger(0,"AltBar"+(string)V,OBJPROP_COLOR,Yellow); else ObjectSetInteger(0,"AltBar"+(string)V,OBJPROP_COLOR,Green); ObjectSetInteger (0,"AltBar"+(string)V,OBJPROP_SELECTABLE,true); ObjectSetInteger (0,"AltBar"+(string)V,OBJPROP_WIDTH,3); //------- } ChartRedraw(0); //----------------------------------------------------------- for (i=1;i<=Clusters;i++) SourceBuffer[rates_total-i-1]=Hight[i]-Low[i]; } return(rates_total); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ObjectsDeleteAll(0,-1,-1); ChartRedraw(0); } //+------------------------------------------------------------------+
ну да чуствуетсясоль уловил попробуй
сделать тайм сериями буферы
сразу все на место встанет
в отличие от мкл4
тут буферы индексируются от конца к началу
и обязательно надо делать связку
вот тут почитай
// У меня повилась такая странная ошибка.
ArraySetAsSeries(AtrBuffer,true); ArraySetAsSeries(TempBuffer,true); Print("AtrBuffer до",ArrayGetAsSeries(AtrBuffer)); Print("TempBuffer до",ArrayGetAsSeries(TempBuffer)); SetIndexBuffer(0,AtrBuffer,INDICATOR_DATA); SetIndexBuffer(1,TempBuffer,INDICATOR_CALCULATIONS); Print("AtrBuffer после",ArrayGetAsSeries(AtrBuffer)); Print("TempBuffer после",ArrayGetAsSeries(TempBuffer));
ArraySetAsSeries(AtrBuffer,false); ArraySetAsSeries(TempBuffer,false); Print("AtrBuffer до",ArrayGetAsSeries(AtrBuffer)); Print("TempBuffer до",ArrayGetAsSeries(TempBuffer)); SetIndexBuffer(0,AtrBuffer,INDICATOR_DATA); SetIndexBuffer(1,TempBuffer,INDICATOR_CALCULATIONS); Print("AtrBuffer после",ArrayGetAsSeries(AtrBuffer)); Print("TempBuffer после",ArrayGetAsSeries(TempBuffer));
Я уже сообщил в сервисдеск об этом не соответствии с текстом справки.
в справке все нормально =)
тут дело в головах который привыкли к мкл5
кто сказал что при инициализации буфер должен стать тайм серией...
и ваше что он должен
все дело в головах
Примечание
После связывания динамический массив buffer[] будет иметь индексацию как в обычных массивах, даже если для связываемого массива будет предварительно установлена индексация как в таймсериях. Если необходимо изменить порядок доступа к элементам индикаторного массива, необходимо применить функцию ArraySetAsSeries() после связывания массива функцией SetIndexBuffer().
Я же привёл пример, что если до связывания была таймсерия, то и после будет таймсерия!
Я же привёл пример, что если до связывания была таймсерия, то и после будет таймсерия!
и
Rosh:
Обратная индексация индикаторных
буферов, как это сделано в MQL4, изначально была сделана по традиции,
так как на то время было общепринято нумеровать бары задом наперед. Это
казалось удобным (и безусловно является удобным и сейчас, если
обращаться к барам из экспертов), так как последний незавершенный бар
всегда имел нулевой индекс.
и
да я немного понял когда немножко задумался про заполнения буферов и организацию доступа данных.
думаю данное примечание стоит написать не только к функции к SetIndexBuffer()
Теперь, люди добрые, объясните мне, что я именно не понимаю.
Вот код индикатора MQL4
#property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 DeepSkyBlue //---- input parameters extern int History=100; //---- buffers double HiBuffer[]; //------------------------------------------------------------------- int init() { //---- indicators SetIndexStyle(0,DRAW_HISTOGRAM); SetIndexBuffer(0,HiBuffer); //---- return(0); } //------------------------------------------------------------------- int deinit() { //---- //---- return(0); } //------------------------------------------------------------------- int start() { int counted_bars=IndicatorCounted(); //---- int i=0; while (i<counted_bars) { if (i<History) { HiBuffer[i]=High[i]; } else { HiBuffer[i]=0.0; } i++; } //---- return(0); } //-------------------------------------------------------------------
он рисует такую картинку:
Видим, что 0-й индекс буфера индикатора, который является таймсерией, будет совпадать с 0-м баром на графике.
Теперь посмотрим на код MQL5, того же индикатора:
#property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 //--- plot Hi #property indicator_label1 "Hi" #property indicator_type1 DRAW_LINE #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //------------------------------------------------------------------- input int History =100; //------------------------------------------------------------------- double HiBuffer[]; //------------------------------------------------------------------- int OnInit() { SetIndexBuffer (0,HiBuffer,INDICATOR_DATA); PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,1); PlotIndexSetString (0,PLOT_LABEL,"HiBuffer"); return(0); } //------------------------------------------------------------------- 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 i=0; while (i<rates_total) { if (i<History) { HiBuffer[i]=high[i]; } else { HiBuffer[i]=0.0; } i++; } return(rates_total); } //-------------------------------------------------------------------
Он рисует такую картинку:
Обратите внимание, что здесь 0-й индекс буфера индикатора соответствует самому старому бару на графике.
Зачем так? Объясните пожалуйста. Скажете, а в чем проблема, сделай буфер индикатора таймсерией, и всё будет ок.
Ок, делаю:
#property indicator_separate_window #property indicator_buffers 1 #property indicator_plots 1 //--- plot Hi #property indicator_label1 "Hi" #property indicator_type1 DRAW_LINE #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //------------------------------------------------------------------- input int History =100; //------------------------------------------------------------------- double HiBuffer[]; //------------------------------------------------------------------- int OnInit() { SetIndexBuffer (0,HiBuffer,INDICATOR_DATA); ArraySetAsSeries (HiBuffer,true);//Сделал как посоветовали. PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,1); PlotIndexSetString (0,PLOT_LABEL,"HiBuffer"); return(0); } //------------------------------------------------------------------- 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 i=0; while (i<rates_total) { if (i<History) { HiBuffer[i]=high[i]; } else { HiBuffer[i]=0.0; } i++; } return(rates_total); } //-------------------------------------------------------------------
Получаем такую картинку:
Что мы видим теперь? 0-й индекс буфера индекатоора будет соответствовать также самому старому бару на графике, только отображаются уже в самом конце истории.
Выше я показывал одно из заднепрходных решений. Но оно Заднепроходное!.
Или я что то не понимаю, объясните пожалуйста, как нужно работать с индикаторами, что бы стало "легче".
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Просмотрел индикаторы в CodeBase, почитал статьи. Не пойму, как организовать отрисовку индикаторных буферов только заданное количество последних баров и начиная с первого.
Кроме того, не соображу даже как подступится к одной задачке. Прилагаю скрипт, который рисует бары назад в прошлое.
Код скрипта: