Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 573

 
Andrey Koldorkin:

Попробую разобраться. Спасибо.

Не за что. Просто сохраняются в массив все high, а потом в цикле распечатываются в журнале все сохранённые в массиве данные.

Вовсе не обязательно, что этот скрипт делает именно то, что вам нужно. Просто показан принцип сохранения данных в массиве.

 
Artyom Trishkin:

Не за что. Просто сохраняются в массив все high, а потом в цикле распечатываются в журнале все сохранённые в массиве данные.

Вовсе не обязательно, что этот скрипт делает именно то, что вам нужно. Просто показан принцип сохранения данных в массиве.

я именно это и искал. Мне нужно, было чтобы как-то сохранить данные в массив за тот период, который я выбираю. Эту часть я у вас понял.

Теперь у меня стоит вопрос, КАК обратиться к записанным данным в массиве и сравнить их между собой?

Тут получается, что поехали итерации, записали пошагово массив. Это хорошо. Но теперь нужно сравнить элементы между собой.

Нужно объявить новый счет итераций? и уже как-то извлекать данные и сравнивать их? Но это опять куда-то записывать результаты и ... все в итоге повторяется.

Грубо, если период сравнения 5-7 свечей, то у нас 1я должна быть сравнена с другими 6ю, потом 2я и т.д....  И если из них две или более имеют равную величину High, то нужно во-первых, вычислить этот High, во вторых, их этих свечек найти ту, у которой минимальный Low.  Т.е. нужно обращение к конкретным свечам в итоге, чтобы все их параметры извлечь.

 Можно ли вообще такое сделать. 

 
Andrey Koldorkin:

я именно это и искал. Мне нужно, было чтобы как-то сохранить данные в массив за тот период, который я выбираю. Эту часть я у вас понял.

Теперь у меня стоит вопрос, КАК обратиться к записанным данным в массиве и сравнить их между собой?

Тут получается, что поехали итерации, записали пошагово массив. Это хорошо. Но теперь нужно сравнить элементы между собой.

Нужно объявить новый счет итераций? и уже как-то извлекать данные и сравнивать их? Но это опять куда-то записывать результаты и ... все в итоге повторяется.

Грубо, если период сравнения 5-7 свечей, то у нас 1я должна быть сравнена с другими 6ю, потом 2я и т.д....  И если из них две или более имеют равную величину High, то нужно во-первых, вычислить этот High, во вторых, их этих свечек найти ту, у которой минимальный Low.  Т.е. нужно обращение к конкретным свечам в итоге, чтобы все их параметры извлечь.

 Можно ли вообще такое сделать. 

Вот тут как раз опрос сохранённого массива, и вывод всех сохранённых данных в журнал:

for(int i=0; i<ArrayRange(mass_high,0); i++) {
   printf("Время: %s, High: %.5f",TimeToString((int)mass_high[i][1],TIME_DATE|TIME_MINUTES),mass_high[i][0]);
   }

Давайте конкретизируем задачу:

Нужно в сохранённом массиве найти ... что конкретно?

 
Artyom Trishkin:

Вот тут как раз опрос сохранённого массива, и вывод всех сохранённых данных в журнал:

Давайте конкретизируем задачу:

Нужно в сохранённом массиве найти ... что конкретно?

Мне нужно, записать массив из данных для всех закрытых свечей (т.е. текущую не считаем) - Хай, Лоу, Опен, Клоуз свечей (4 параметра) за период, который указывается в настройках. - это есть.

Далее, мне нужно сравнить параметры. Пусть период поиска равен 10 свечам. Вот нужно проверить все High за период 10 свечей. Если есть два или более совпадений, то нужно вернуть:

1.  Флаг - "Совпадения есть".

1. Значение High, на котором нашлись одинаковые значения у свечек.

2. Номера этих свечей, чтобы можно было к ним обратиться и выяснить для них параметры Low, Close, Open.

В целом понятно многое из этого как сделать. 

Не понятно как обратиться именно к тем свечкам, которые образуют уровень.  По идее можно было бы при пересчете запоминать номер итерации (i), но у нас же сначала идет пересчет по которому идет запись в журнал, его не применишь.

А в том варианте, как идет вывод записей журнала - тут тоже не то, что требуется.

Я примерно понимаю, что мне нужно сначала взять свечу 1 и сравнить ее с 9ю другими, если найдется совпадение, то вычленить номера этих свечей и их параметры, включить флажок. Далее проверить свечу 2 с остальными и так до середины выборки, т.к. потом пойдут уже дубли сравнений только с другой стороны. 

НО!! Если бы число свечей было фиксированным, я бы так и написал - грубо 5 циклов сравнений.  Но вот как сделать возможность такого пересчета для любого размера выборки - вот вопрос.

 
Andrey Koldorkin:

Мне нужно, записать массив из данных для всех закрытых свечей (т.е. текущую не считаем) - Хай, Лоу, Опен, Клоуз свечей (4 параметра) за период, который указывается в настройках. - это есть.

Далее, мне нужно сравнить параметры. Пусть период поиска равен 10 свечам. Вот нужно проверить все High за период 10 свечей. Если есть два или более совпадений, то нужно вернуть:

1.  Флаг - "Совпадения есть".

1. Значение High, на котором нашлись одинаковые значения у свечек.

2. Номера этих свечей, чтобы можно было к ним обратиться и выяснить для них параметры Low, Close, Open.

В целом понятно многое из этого как сделать. 

Не понятно как обратиться именно к тем свечкам, которые образуют уровень.  По идее можно было бы при пересчете запоминать номер итерации (i), но у нас же сначала идет пересчет по которому идет запись в журнал, его не применишь.

А в том варианте, как идет вывод записей журнала - тут тоже не то, что требуется.

Я примерно понимаю, что мне нужно сначала взять свечу 1 и сравнить ее с 9ю другими, если найдется совпадение, то вычленить номера этих свечей и их параметры, включить флажок. Далее проверить свечу 2 с остальными и так до середины выборки, т.к. потом пойдут уже дубли сравнений только с другой стороны. 

НО!! Если бы число свечей было фиксированным, я бы так и написал - грубо 5 циклов сравнений.  Но вот как сделать возможность такого пересчета для любого размера выборки - вот вопрос.

И, кстати, точное совпадение значений цен вряд ли будет частым. Нужно задать некую дельту, и считать совпадением значений если цены различаются не более этого значения.

Значит, если нужно, чтобы для каждой из свечей диапазона соответствовал свой список совпадающих свечей, то я бы попробовал использовать массив структур. Подумаю - отпишусь.
 
Andrey Koldorkin:

Мне нужно, записать массив из данных для всех закрытых свечей (т.е. текущую не считаем) - Хай, Лоу, Опен, Клоуз свечей (4 параметра) за период, который указывается в настройках. - это есть.

Далее, мне нужно сравнить параметры. Пусть период поиска равен 10 свечам. Вот нужно проверить все High за период 10 свечей. Если есть два или более совпадений, то нужно вернуть:

1.  Флаг - "Совпадения есть".

1. Значение High, на котором нашлись одинаковые значения у свечек.

2. Номера этих свечей, чтобы можно было к ним обратиться и выяснить для них параметры Low, Close, Open.

В целом понятно многое из этого как сделать. 

Не понятно как обратиться именно к тем свечкам, которые образуют уровень.  По идее можно было бы при пересчете запоминать номер итерации (i), но у нас же сначала идет пересчет по которому идет запись в журнал, его не применишь.

А в том варианте, как идет вывод записей журнала - тут тоже не то, что требуется.

Я примерно понимаю, что мне нужно сначала взять свечу 1 и сравнить ее с 9ю другими, если найдется совпадение, то вычленить номера этих свечей и их параметры, включить флажок. Далее проверить свечу 2 с остальными и так до середины выборки, т.к. потом пойдут уже дубли сравнений только с другой стороны. 

НО!! Если бы число свечей было фиксированным, я бы так и написал - грубо 5 циклов сравнений.  Но вот как сделать возможность такого пересчета для любого размера выборки - вот вопрос.

Вместо флага "совпадений" поставьте счетчик, на значении high где счетчик найбольший , есть уровень

Значения high можно округлить , например значение 1.23456 округляем до 1.2346

и значение 1.23462 округляем до 1.2346

потому что маловероятно что из 10 свечей , 2 будут иметь high равный 1.23456 

т.е танцуйте от уровня 

и число свечей у вас фиксированно, вы же записываете в структуру определенное количество данных 

т.е сколько свечей записано в структуре столько и итераций 

 
Andrey Koldorkin:

Мне нужно, записать массив из данных для всех закрытых свечей (т.е. текущую не считаем) - Хай, Лоу, Опен, Клоуз свечей (4 параметра) за период, который указывается в настройках. - это есть.

Далее, мне нужно сравнить параметры. Пусть период поиска равен 10 свечам. Вот нужно проверить все High за период 10 свечей. Если есть два или более совпадений, то нужно вернуть:

1.  Флаг - "Совпадения есть".

1. Значение High, на котором нашлись одинаковые значения у свечек.

2. Номера этих свечей, чтобы можно было к ним обратиться и выяснить для них параметры Low, Close, Open.

В целом понятно многое из этого как сделать. 

Не понятно как обратиться именно к тем свечкам, которые образуют уровень.  По идее можно было бы при пересчете запоминать номер итерации (i), но у нас же сначала идет пересчет по которому идет запись в журнал, его не применишь.

А в том варианте, как идет вывод записей журнала - тут тоже не то, что требуется.

Я примерно понимаю, что мне нужно сначала взять свечу 1 и сравнить ее с 9ю другими, если найдется совпадение, то вычленить номера этих свечей и их параметры, включить флажок. Далее проверить свечу 2 с остальными и так до середины выборки, т.к. потом пойдут уже дубли сравнений только с другой стороны. 

НО!! Если бы число свечей было фиксированным, я бы так и написал - грубо 5 циклов сравнений.  Но вот как сделать возможность такого пересчета для любого размера выборки - вот вопрос.

Задача интересная, но понимание, как решить эту проблему у Вас неверное, т.к. знаний в программирование пока не так много.

Смотрите: у Вас есть некий набор котировок. Ваша задача сводится к тому, что бы из этого набора отобрать только те бары, которые удовлетворяют определенным условиям. Например, вы хотите получить коллекцию баров, чьи High совпадают друг с другом. В действительности, условий отбора может быть множество и они со временем могут добавляться. Получив коллекцию баров, Вы без проблем сможете проанализировать любые их прочие параметры.

Значит для Вашей задачи требуется написать функцию, которая бы возвращала массив баров удовлетворяющих определенному условию (псевдокод):

массив_баров = ПолучитьНужныеБары(Символ(), Таймфрейм(), Период(), УсловиеОтбора);
Т.е. в действительности нет никаких проблем с запоминанием и итерацицией каких-то данных и индексов. Вам нужны не сами индексы баров, а конкретная коллекция, удовлетворяющая заданному условию. Получив ее, Вы решите кучу проблем одним махом.
 
Artyom Trishkin:
Значит, если нужно, чтобы для каждой из свечей диапазона соответствовал свой список совпадающих свечей, то я бы попробовал использовать массив структур. Подумаю - отпишусь.

Подумал. Отписываюсь скриптом проверочным:

//+------------------------------------------------------------------+
//|                                                     TestCopy.mq4 |
//|              Copyright 2016, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Artem A. Trishkin, Skype artmedia70"
#property link      "https://login.mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict
#property script_show_inputs
//--- input parameters
input int Search_Period=10;   // Количество копируемых свечей
int searchPeriod=(Search_Period<1)?1:Search_Period;
input int Delta=2;            // Количество пунктов допуска
int delta=(Delta<0)?0:Delta;
MqlRates array[];             // Массив структур для копирования Open, High, Low, Close, Time
  
struct DataCandle             // Структура для хранения всех совпадений
  {
   int number_matched;           // Количество совпадений
   MqlRates reference_candle;    // Данные эталонной свечи
   MqlRates matched_candles[];   // Массив свечей, совпадающих с эталонной по нужному критерию 
  };
  DataCandle dataCandle[];    // Массив структур данных свечей и их совпадений
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period()));   // количество копируемых свечей
   int copied=CopyRates(Symbol(),PERIOD_CURRENT,1,copy_bars,array);  // копируем данные
   if(copied>0) {                                                    // если скопировали
      ArrayResize(dataCandle,copied);                                // задаём размер структуры равным числу скопированных данных
      ZeroMemory(dataCandle);                                        // Обнуляем данные в структуре
      //--- основной цикл по "эталонным" свечам в массиве array. Их параметры будем искать в доп. цикле
      for(int i=0; i<copy_bars-1; i++) {                             // цикл по скопированным данным от начала до "на один меньше размера массива"
         dataCandle[i].reference_candle.high=array[i].high;          // ищем этот high
         dataCandle[i].reference_candle.low=array[i].low;            // запомнили low для сравнения
         dataCandle[i].reference_candle.time=array[i].time;          // запомнили time для вывода в журнал
         //--- поиск совпадений с эталонной свечой, индексируемой индексом основного цикла i
         int size=0;                                                 // размер массива совпадающих свечей
         ArrayResize(dataCandle[i].matched_candles,size);            // Размер массива совпадений в ноль
         dataCandle[i].number_matched=size;                          // Инициализируем количество совпадений нулём
         //--- теперь ищем совпадения по high свечей в цикле j с high эталонной свечи с индексом i
         for(int j=i+1; j<copy_bars; j++) {                          // в цикле от i+1 до copy_bars
            //--- если совпадают high эталонной свечи (i) и свечи с индексом j (с допуском на величину delta*Point)
            if(NormalizeDouble(delta*Point()-fabs(array[i].high-array[j].high),Digits())>=0) {
               size++;                                               
               ArrayResize(dataCandle[i].matched_candles,size);            // увеличим размер массива совпадающих свечей
               dataCandle[i].number_matched=size;                          // запишем количество совпадений
               dataCandle[i].matched_candles[size-1].high=array[j].high;   // запишем в массив high совпадающей свечи
               dataCandle[i].matched_candles[size-1].low=array[j].low;     // запишем в массив low совпадающей свечи
               dataCandle[i].matched_candles[size-1].time=array[j].time;   // запишем в массив время совпадающей свечи
               //Print("Время свечи ",i," :",TimeToString(dataCandle[i].reference_candle.time=array[i].time),", high=",DoubleToString(dataCandle[i].reference_candle.high=array[i].high,Digits()),". Совпадение со свечой ",TimeToString(dataCandle[i].matched_candles[size-1].time=array[j].time),", её high ",DoubleToString(dataCandle[i].matched_candles[size-1].high=array[j].high,Digits()),". Совпадений: ",(string)dataCandle[i].number_matched);
               }
            }
         }
      }

   //--- Посмотрим чего понаписали в массивы
   for(int i=0; i<ArraySize(dataCandle)-1; i++) {
      string refs_txt="";
      string matched_txt="";
      refs_txt="Свеча "+IntegerToString(i,2,'0')+": время "+TimeToString(dataCandle[i].reference_candle.time)+", high: "+DoubleToString(dataCandle[i].reference_candle.high,Digits())+" имеет совпадений: "+(string)dataCandle[i].number_matched+" шт. ";
      if(dataCandle[i].number_matched>0) {
         for(int j=0; j<ArraySize(dataCandle[i].matched_candles); j++) {
            matched_txt="Совпадение "+IntegerToString(j+1)+": "+TimeToString(dataCandle[i].matched_candles[j].time)+", high: "+DoubleToString(dataCandle[i].matched_candles[j].high,Digits());
            }
         }
      Print(refs_txt,matched_txt);
      }
  }
//+------------------------------------------------------------------+

Постарался описать все действия.

После заполнения в цикле всех совпадений, имеем массив, содержащий все свечи и их совпадающие свечи. Далее уже в нём можно искать low. А можно прямо в цикле поиска это организовать. Как вам удобнее.

 

Ну вот можно ещё так: тут для каждой свечи диапазона записываются совпадения. В прошлой версии совпадения писались только для одной свечи - т.е., для той, которая совпадает с этой, уже совпадение не писалось.

//+------------------------------------------------------------------+
//|                                                     TestCopy.mq4 |
//|              Copyright 2016, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Artem A. Trishkin, Skype artmedia70"
#property link      "https://login.mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict
#property script_show_inputs
//--- input parameters
input int Search_Period=10;   // Количество копируемых свечей
int searchPeriod=(Search_Period<1)?1:Search_Period;
input int Delta=2;            // Количество пунктов допуска
int delta=(Delta<0)?0:Delta;
MqlRates array[];             // Массив структур для копирования Open, High, Low, Close, Time
  
struct DataCandle             // Структура для хранения всех совпадений
  {
   int number_matched;           // Количество совпадений
   MqlRates reference_candle;    // Данные эталонной свечи
   MqlRates matched_candles[];   // Массив свечей, совпадающих с эталонной по нужному критерию 
  };
  DataCandle dataCandle[];    // Массив структур данных свечей и их совпадений
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period()));   // количество копируемых свечей
   int copied=CopyRates(Symbol(),PERIOD_CURRENT,1,copy_bars,array);  // копируем данные
   if(copied>0) {                                                    // если скопировали
      ArrayResize(dataCandle,copied);                                // задаём размер структуры равным числу скопированных данных
      ZeroMemory(dataCandle);                                        // Обнуляем данные в структуре
      //--- основной цикл по "эталонным" свечам в массиве array. Их параметры будем искать в доп. цикле
      for(int i=0; i<copy_bars; i++) {                               // цикл по скопированным данным от начала до конца
         dataCandle[i].reference_candle.high=array[i].high;          // ищем этот high
         dataCandle[i].reference_candle.low=array[i].low;            // запомнили low для сравнения
         dataCandle[i].reference_candle.time=array[i].time;          // запомнили time для вывода в журнал
         //--- поиск совпадений с эталонной свечой, индексируемой индексом основного цикла i
         int size=0;                                                 // размер массива совпадающих свечей
         ArrayResize(dataCandle[i].matched_candles,size);            // Размер массива совпадений в ноль
         dataCandle[i].number_matched=size;                          // Инициализируем количество совпадений нулём
         //--- теперь ищем совпадения по high свечей в цикле j с high эталонной свечи с индексом i
         for(int j=0; j<copy_bars; j++) {                            // в цикле от 0 до copy_bars
            if(j==i) continue;                                       // пропустим свечу "саму себя"
            //--- если совпадают high эталонной свечи (i) и свечи с индексом j (с допуском на величину Point)
            if(NormalizeDouble(delta*Point()-fabs(array[i].high-array[j].high),Digits())>=0) {
               size++;                                               
               ArrayResize(dataCandle[i].matched_candles,size);            // увеличим размер массива совпадающих свечей
               dataCandle[i].number_matched=size;                          // запишем количество совпадений
               dataCandle[i].matched_candles[size-1].high=array[j].high;   // запишем в массив high совпадающей свечи
               dataCandle[i].matched_candles[size-1].low=array[j].low;     // запишем в массив low совпадающей свечи
               dataCandle[i].matched_candles[size-1].time=array[j].time;   // запишем в массив время совпадающей свечи
               //Print("Время свечи ",i," :",TimeToString(dataCandle[i].reference_candle.time=array[i].time),", high=",DoubleToString(dataCandle[i].reference_candle.high=array[i].high,Digits()),". Совпадение со свечой ",TimeToString(dataCandle[i].matched_candles[size-1].time=array[j].time),", её high ",DoubleToString(dataCandle[i].matched_candles[size-1].high=array[j].high,Digits()),". Совпадений: ",(string)dataCandle[i].number_matched);
               }
            }
         }
      }

   //--- Посмотрим чего понаписали в массивы
   for(int i=0; i<ArraySize(dataCandle)-1; i++) {
      string refs_txt="";
      string matched_txt="";
      refs_txt="Свеча "+IntegerToString(i,2,'0')+": время "+TimeToString(dataCandle[i].reference_candle.time)+", high: "+DoubleToString(dataCandle[i].reference_candle.high,Digits())+" имеет совпадений: "+(string)dataCandle[i].number_matched+" шт. ";
      if(dataCandle[i].number_matched>0) {
         for(int j=0; j<ArraySize(dataCandle[i].matched_candles); j++) {
            matched_txt+=" Совпадение "+IntegerToString(j+1)+": "+TimeToString(dataCandle[i].matched_candles[j].time)+", high: "+DoubleToString(dataCandle[i].matched_candles[j].high,Digits());
            }
         }
      Print(refs_txt,matched_txt);
      }
  }
//+------------------------------------------------------------------+
 
Идея открытия ордеров по сигналам бачего или медвежего захвата, как сделать, чтобы была только одна сделка на бай/селл и одна сделка отложенного ордера, у меня открывается на каждом тике сделки. Помогите решить проблему.
Файлы:
ritfv.png  46 kb
ohs.txt  5 kb
Причина обращения: