Нашёл, где допустил основную ошибку.))
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate (const int rates_total, // размер входных таймсерий const int prev_calculated, // обработано баров на предыдущем вызове const datetime& time[], // Time const double& open[], // Open const double& High[], // High const double& Low[], // Low const double& close[], // Close const long& tick_volume[], // Tick Volume const long& volume[], // Real Volume const int& spread[]) // Spread { int i,limit; if(rates_total < 5) return(0); if(prev_calculated < 7) { limit = 2; ArrayInitialize(fr_upBuffer,STYLE_SOLID); ArrayInitialize(fr_dwBuffer,STYLE_SOLID); } else limit=rates_total-5; for(i=limit;i<rates_total-3;i++) { //---- Верхний фрактал if (High[i] > High[i+1] && High[i] >= High[i-1]) fr_upBuffer[i] = High[i]; else fr_upBuffer[i] = fr_upBuffer[i-1]; //---- Нижний фрактал if (Low[i] < Low[i+1] && Low[i] <= Low[i-1]) fr_dwBuffer[i] = Low[i]; else fr_dwBuffer[i] = fr_dwBuffer[i-1]; } return(rates_total); }
Получилась такая картинка:
Как то он только странно обрывается в конце. Как это можно исправить?
И какую роль играет вот эта часть кода?
if(rates_total < 3) return(0); if(prev_calculated < 7) { limit = 2; //--- clean up arrays ArrayInitialize(fr_upBuffer,STYLE_SOLID); ArrayInitialize(fr_dwBuffer,STYLE_SOLID); } else limit = rates_total - 3;
Значения индикатора не пересчитывались на каждом баре и, чтобы это исправить, я добавил вот такую часть кода:
int i; int limit; static datetime Old_Time; // статическая переменная datetime New_Time[1]; // массив bool IsNewBar = false; // подтверждение нового бара int copied = CopyTime(_Symbol,_Period,0,1,New_Time); // копируем время текущего бара в массив New_Time[0] if(copied > 0) // если копирование прошло успешно и { if(Old_Time!=New_Time[0]) // если время предыдущего бара не равно времени текущего бара, то... { IsNewBar=true; Old_Time=New_Time[0]; } } else { Alert("Ошибка копирования времени, номер ошибки: ",GetLastError()); ResetLastError(); return(1); } if(IsNewBar == false) { return(1); }
Также я забыл об одном важном моменте - индексация массивов:
ArraySetAsSeries(High,true); ArraySetAsSeries(Low,true); ArraySetAsSeries(fr_upBuffer,true); ArraySetAsSeries(fr_dwBuffer,true);
Но теперь у меня вообще ничего не отображается на графике. Вот теперь я в конкретном тупике и метод тыка уже не помогает.))) Подскажите, пожалуйста, что я делаю не правильно. Файл с тем, что на данный момент сделал прилагаю:
Значения индикатора не пересчитывались на каждом баре и, чтобы это исправить, я добавил вот такую часть кода:
Также я забыл об одном важном моменте - индексация массивов:
Но теперь у меня вообще ничего не отображается на графике. Вот теперь я в конкретном тупике и метод тыка уже не помогает.))) Подскажите, пожалуйста, что я делаю не правильно. Файл с тем, что на данный момент сделал прилагаю:
небольшой совет, в индикаторах динамические массивы автоматически индексируются как тайм серии так что нет необходимости ее делать.
когда я писал подобный индикатор для мт4 у меня тоже проблемка была как у вас в конце линии уходили вниз, решил это таким способом. может поможет (код для мт4) , под мт5 еще его не пробовал переписывать
#property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Blue #property indicator_color2 Red double UpperBuffer[]; double LowerBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { SetIndexStyle(0,DRAW_LINE); SetIndexStyle(1,DRAW_LINE); SetIndexBuffer(0,UpperBuffer); SetIndexBuffer(1,LowerBuffer); SetIndexDrawBegin(0,0); SetIndexDrawBegin(1,0); return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { //int limit; int counted_bars=IndicatorCounted(); //---- last counted bar will be recounted //if(counted_bars>0) counted_bars--; //limit=counted_bars; //---- for(int i=0; i<counted_bars; i++) { UpperBuffer[i] = Fractal(i,counted_bars,MODE_UPPER); LowerBuffer[i] = Fractal(i,counted_bars,MODE_LOWER); } //---- return(0); } //+------------------------------------------------------------------+ double Fractal(int ind,int bar,int mode) { for(int k=ind; k<=bar;k++) { double val=iFractals(NULL, 0, mode, k); if (val>0) { return(val); } } }
в мкл5 все массивы индексируются как массивы...
в мкл5 все массивы индексируются как массивы...
вот писал индикатор без всякой индексации массивов, все прекрасно работает, а вот в экспертах приходилось делать индексацию иначе данные переворачивались при копировании.
#property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 3 #property indicator_type1 DRAW_LINE #property indicator_type2 DRAW_LINE #property indicator_type3 DRAW_LINE #property indicator_color1 DodgerBlue #property indicator_color2 DodgerBlue #property indicator_color3 Blue #property indicator_style3 STYLE_DOT //--- input parameters input int ADX_period=14; // Period //---- buffers double ExtHighBuffer[]; double ExtLowBuffer[]; double ExtMiddBuffer[]; double adxBuffer[]; //--- handles for ADX int h_adx; //--- bars minimum for calculation #define DATA_LIMIT 60 //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ExtHighBuffer,INDICATOR_DATA); SetIndexBuffer(1,ExtLowBuffer,INDICATOR_DATA); SetIndexBuffer(2,ExtMiddBuffer,INDICATOR_DATA); SetIndexBuffer(3,adxBuffer,INDICATOR_CALCULATIONS); //--- sets first bar from what index will be drawn PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,DATA_LIMIT); PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,DATA_LIMIT); PlotIndexSetInteger(3,PLOT_DRAW_BEGIN,DATA_LIMIT); //--- get handles h_adx=iADX(Symbol(),0,ADX_period); //--- initialization done 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[]) { if(rates_total<DATA_LIMIT) return(0); int calculated=BarsCalculated(h_adx); if(calculated<rates_total) { return(0); } int to_copy; if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total; else { to_copy=rates_total-prev_calculated; if(prev_calculated>0) to_copy++; } if(CopyBuffer(h_adx,0,0,to_copy,adxBuffer)<=0) { return(0); } int i,limit; if(prev_calculated<=DATA_LIMIT) limit=DATA_LIMIT; else limit=prev_calculated-1; for(i=limit;i<rates_total;i++) { int InpChannelPeriod=(int)floor(150/adxBuffer[i]); ExtHighBuffer[i]=Highest(high,InpChannelPeriod,i); ExtLowBuffer[i]=Lowest(low,InpChannelPeriod,i); ExtMiddBuffer[i]=(ExtHighBuffer[i]+ExtLowBuffer[i])/2.0;; } return(rates_total); } //+------------------------------------------------------------------+ //| get highest value for range | //+------------------------------------------------------------------+ double Highest(const double &array[],int range,int fromIndex) { double res; int i; //--- res=array[fromIndex]; for(i=fromIndex;i>fromIndex-range && i>=0;i--) { if(res<array[i]) res=array[i]; } //--- return(res); } //+------------------------------------------------------------------+ //| get lowest value for range | //+------------------------------------------------------------------+ double Lowest(const double &array[],int range,int fromIndex) { double res; int i; //--- res=array[fromIndex]; for(i=fromIndex;i>fromIndex-range && i>=0;i--) { if(res>array[i]) res=array[i]; } //--- return(res); } //+------------------------------------------------------------------+
- www.mql5.com
//+------------------------------------------------------------------+ //| fract 3.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot fr_up #property indicator_label1 "fr_up" #property indicator_type1 DRAW_LINE #property indicator_color1 RoyalBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot fr_dw #property indicator_label2 "fr_dw" #property indicator_type2 DRAW_LINE #property indicator_color2 OrangeRed #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- indicator buffers double fr_upBuffer[]; double fr_dwBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,fr_upBuffer,INDICATOR_DATA); SetIndexBuffer(1,fr_dwBuffer,INDICATOR_DATA); //--- PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID); PlotIndexSetInteger(1,PLOT_LINE_STYLE,STYLE_SOLID); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate (const int rates_total, // размер входных таймсерий const int prev_calculated, // обработано баров на предыдущем вызове const datetime& time[], // Time const double& open[], // Open const double& High[], // High const double& Low[], // Low const double& close[], // Close const long& tick_volume[], // Tick Volume const long& volume[], // Real Volume const int& spread[]) // Spread { int i; int limit; datetime Old_Time; // статическая переменная datetime New_Time[1]; // массив bool IsNewBar = false; // подтверждение нового бара int copied = CopyTime(_Symbol,_Period,0,1,New_Time); // копируем время текущего бара в массив New_Time[0] if(copied > 0) // если копирование прошло успешно и { if(Old_Time!=New_Time[0]) // если время предыдущего бара не равно времени текущего бара, то { IsNewBar=true; Old_Time=New_Time[0]; } } else { Alert("Ошибка копирования времени, номер ошибки: ",GetLastError()); ResetLastError(); return(1); } if(IsNewBar == false) // советник должен проверять условия для совершения торговой операции только при новом баре { return(1); } if(rates_total < 3) return(0); if(prev_calculated < 3) { limit = 3; ArrayInitialize(fr_upBuffer,STYLE_SOLID); ArrayInitialize(fr_dwBuffer,STYLE_SOLID); } else limit = rates_total; for(i=limit;i<rates_total;i++) { //---- Верхний фрактал if (High[i-2] > High[i-3] && High[i-2] > High[i+++1]) fr_upBuffer[i] = High[i-2]; else fr_upBuffer[i] = fr_upBuffer[i-1]; //---- Нижний фрактал if (Low[i-2] < Low[i-3] && Low[i-2] < Low[i-1]) fr_dwBuffer[i] = Low[i-2]; else fr_dwBuffer[i] = fr_dwBuffer[i-1]; } return(rates_total); } //+------------------------------------------------------------------+
1) запутался в направлениях пересчета
неправильно организовал циклы и что конфликтовало с направлением перебора
2) неправильно рассчитал начало отсчета.
тут надо внимательно с направлением индексации и направлением перебора
я тоже пол года назад сталкивался с такими проблемы данные не переворачиваются
просто они так хранятся в мкл 5
и такие щекотливые темы можно встретить ежемесячно.
так что почитайте и вникните с функции копи буфер, аррау инит и копу аррау
и каждая функция по своему обращается с массивами.
и в мкл5 нету тайм серий пока их не укажеш
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Приветствую уважаемые члены сообщества! )
Совсем недавно начал изучать программирование на MQL5. Чтобы хоть немного подготовиться к решению вопросов и задач, прочитал для начала справку от корки до корки. Так же прочитал практически все статьи по MQL5. Кстати, лучшие статьи на мой взгляд, как раз таки для начинающих, где действительно всё подробно и понятно написано, опубликовал Samuel. Вот кому учебник бы взяться писать. Но это моё субъективное мнение. Многое конечно после статей прояснилось, но изучение чего-либо это, как лабиринт - выходы есть, но тупики в процессе поиска этих выходов неизбежны. Прежде, чем приступить к созданию чего-либо, решил для начала поковырять и изменить вид уже существующих индикаторов, для практики. Взял самый наипростейший индикатор - Fractals. И попробовал с ним сделать наипростейшую модификацию. Всего то:
1. Вместо 5 свечей в построении фрактала участвуют 3.
2. Рисует не стрелки, а линии, чтобы получился вот такой вид:
И вот мой первый тупик в этом лабиринте! ))) В МТ5 у меня выходит вот так:
Подскажите, пожалуйста, что я делаю не так и, если не сложно, прокомментируйте буквально каждую строку кода, я так лучше усваиваю предмет.
На данный момент код такой:
P.S. В справку не посылайте, она у меня всегда открыта.)))