![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Вспомнил один способ кластеризации. Как-то так: в множестве выделяются группы элементов (кластеры), такие, что максимальное расстояние между элементами одного кластера меньше минимального расстояния от любого элемента этого кластера до элемента, не входящего в этот кластер. Расстояние можно брать обычное, модуль разности вещественных чисел. Конечно, такой кластер будет не обязательно один. Может быть, Вам и не нужна ровно одна группа, может, их стоит сравнивать друг с другом еще и по другим признакам. Например, среднее время возникновения уровня в группе.
Это интересно, но пока не получается понять, как определить, что числа в кластере - путем тупого перебора? Тогда, предположу, появятся группы, которые будут наслаиваться друг на друга так как, если определять кластер путем поиска наименьшей дельты, но большей по отношению к остальным элементам, то выкидывая из такого кластера часть элементом мы будем смещать сам кластер - тут важны будут расстояния между кластерами, если он существенны, то все должно получиться.
Расстояние между двумя точками на вещественной оси мы все измеряем как модуль их разности. В математике это принято называть метрикой. Как измерять расстояние на плоскости между точками, парами чисел, каждое из которых вещественное? Опять у нас есть готовое привычное решение - евклидово расстояние, корень квадратный из суммы квадратов покоординатных разностей. А у математиков есть и другие метрики на плоскости, например, наибольший модуль из двух разностей, сумма модулей разностей (http://ad.cctpu.edu.ru/Math_method/math/45.htm). И это всего лишь в случае пар чисел. Только двух чисел, и всегда двух. А Вам нужно ввести меру близости в гораздо более сложной ситуации. В группе не два числа, и в разных группах их разное число.
Нам надо определить наибольшую группу, или одинаковые группы по количеству элементов в них. Моим недостатком является неумение правильно читать сложные формулы, поэтому приходиться все пытаться понять из примеров и комментариев к ним.
Есть в математике метрики, измеряющие расстояние между двумя функциями. Но вновь, всегда между двумя. Опять Вам не подходит, у вас группа.
Вот почему важно самому досконально понять, что именно нужно. Пишите, может быть, удастся это формализовать до алгоритма получения числовой характеристики близости в множестве.
Однако подумайте и об отказе от попыток ее создать. В ссылке выше сказано, каким требованиям должна удовлетворять метрика. Они не сдуру там появились, без любого из них будут возникать странные эффекты. Сообщением выше я привел пример, как отказаться от столь всеобъемлющих попыток - пусть точки в группе будут ближе попарно друг к другу на вещественной оси, чем к элементам вне точки. Не надо будет изобретать что-то очень нетривиальное.
Так правильно, первоначально мы и определяем близость двух точек, а потом пытаемся исключить то расстояние, которое велико - в этом и вопрос, как определить велико это расстояние или нет? Именно на этом сейчас алгоритм дал сбой - при появлении расстояния на порядок больше.
Не написал - сначала разницы посчитать. Потом все остальное.
Тестирую такой алгоритм фильтрации данных перед обработкой:
1. Суммируем последовательно две дельты и умножаем значение на два
2. Находим среднее значение получившегося числового ряда
3. Составляем новый числовой ряд, если значение меньше среднего значения
4. Повторяем пункт 2-3 пока числовой ряд не будет меньше половины первоначального ряда
5. После фильтрации делаем уже расчет по вышеописанному алгоритму
Пробовал разные цифры - получался правдоподобный вариант, буду рад услышать критические замечания.
Так разницы посчитали в столбце "Дельта", что делать дальше предлагаете?
А что вы кругами ходите? Уже давно написано здесь
В чем недостаток то?
Фильтр не является заменителем алгоритма. Фильтр является добавлением к алгоритму.
В чем недостаток то?
Фильтр не является заменителем алгоритма. Фильтр является добавлением к алгоритму.
Недостаток я не знаю в чём - мне его может быть пока и не видно.
Думаю, что теперь надо попробовать это закодировать - поможете, если у меня возникнут трудности?
Недостаток я не знаю в чём - мне его может быть пока и не видно.
Думаю, что теперь надо попробовать это закодировать - поможете, если у меня возникнут трудности?
а то который раз выясняется, что я то не о том думаю то не так думаю...
Приступил к разработке алгоритма - пока делаю фильтр. Возникла сложность в синхронизации двух столбцов - "Число" и "Дельта"
Буду рад идеям, как устранить неточность:
//| Test_FindOblast.mq4 |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int massivSize=19; //размер массива
double Digit[19]=
{
10,
20,
30,
40,
50,
51,
52,
53,
54,
60,
70,
80,
120,
150,
190,
210,
223,
232,
250,
260
};
double summDelta[19-1];
int N=massivSize-1;//Количество оставшихся цифровых значений
double avrMass=0;//Среднее значение массива дельт
//-Фильтр
//1. Суммируем последовательно две дельты и умножаем значение на два
for(int i=1;i<massivSize;i++)
{
summDelta[i-1]=((Digit[i]-Digit[i-1])+(Digit[i+1]-Digit[i]))*2;
}
for(int i=0;i<massivSize-1;i++) printf("summDelta[%d] = %G",i,summDelta[i]);
//2. Находим среднее значение получившегося числового ряда
//3. Составляем новый числовой ряд, если значение меньше среднего значения
//4. Повторяем пункт 2-3 пока числовой ряд не будет меньше половины первоначального ряда
for(int Z=0;N>massivSize/2;Z++)
{
int SizeMass=ArraySize(summDelta);//Узнаем размер массива
avrMass=iMAOnArray(summDelta,0,SizeMass,0,0,0);
Print("Среднее значение получившегося числового ряда",Z,"=",avrMass);
for(int i=0;i<SizeMass;i++)
{
if(summDelta[i]>avrMass)
{
summDelta[i]=0;
Digit[i]=0;
N--;
}
}
Print("N=",N);
ArraySort(summDelta,WHOLE_ARRAY,0,MODE_DESCEND);
ArraySort(Digit,WHOLE_ARRAY,0,MODE_DESCEND);
if(N!=0)
{
ArrayResize(summDelta,N,0);
for(int i=0;i<N;i++) printf("summDelta[%d] = %G",i,summDelta[i]);
ArrayResize(Digit,N+1,0);
for(int i=0;i<N+1;i++) printf("Digit[%d] = %G",i,Digit[i]);
}
else
{
for(int i=0;i<N;i++) printf("summDelta[%d] = %G",i,summDelta[i]);
for(int i=0;i<N+1;i++) printf("Digit[%d] = %G",i,Digit[i]);
return;
}
}
int SizeMass=ArraySize(summDelta);//Узнаем размер массива
avrMass=iMAOnArray(summDelta,0,SizeMass,0,0,0);
Print("Среднее значение получившегося числового ряда=",avrMass);
//-Основной алгоритм
//1. Находим разницу между числами - это как раз их близость друг от друга.
//2. Если число меньше среднего значения дельт, получившихся из п.1, то - 1, а если нет - 0.
//3. Если значение из п.2 равно 1, то суммируем значение с предыдущим итогом, если нет - 0.
//4. Находим максимальное значение из пункта 3.
//5. Определяем диапазон - находим значение из пункта 4 и ищем вверх из пункта 3 число с нулевым значением, потом увеличиваем найденное число на единицу.
//Таким образом мы получаем диапазон чисел, плотность которых наибольшая по отношению к другим.
}
//+------------------------------------------------------------------+