Нахождение минимального максимума графика акций - PullRequest
22 голосов
/ 15 августа 2011

stock

Существуют ли какие-либо конкретные алгоритмы, которые позволят мне найти минимальные и максимальные точки на рисунке выше?

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

Я думаю об использовании цифровых фильтров (домен z) и сглаживании графика, но у меня все еще остается слишком много локализованных минимумов и максимумов.

Я также пытался использовать скользящее среднее, чтобы сгладить график, но опять же у меня слишком много максимумов и минут.

EDIT:

Я прочитал некоторые комментарии и просто случайно не обвел некоторые минимумы и максимумы.

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

Ответы [ 8 ]

13 голосов
/ 20 сентября 2011

Я обычно использую комбинацию скользящего среднего и экспоненциального скользящего среднего. Он оказался (эмпирически) хорошо приспособленным для этой задачи (по крайней мере, достаточно для моих нужд). Результаты настраиваются только с двумя параметрами. Вот образец:

enter image description here

Редактировать

Если это кому-нибудь пригодится, вот мой код Mathematica:

f[sym_] := Module[{l},
  (*get data*)
  l = FinancialData[sym, "Jan. 1, 2010"][[All, 2]];
  (*perform averages*)
  l1 = ExponentialMovingAverage[MovingAverage[l, 10], .2];
  (*calculate ma and min positions in the averaged list*)
  l2 = {#[[1]], l1[[#[[1]]]]} & /@ 
    MapIndexed[If[#1[[1]] < #1[[2]] > #1[[3]], #2, Sequence @@ {}] &, 
     Partition[l1, 3, 1]];
  l3 = {#[[1]], l1[[#[[1]]]]} & /@ 
    MapIndexed[If[#1[[1]] > #1[[2]] < #1[[3]], #2, Sequence @@ {}] &, 
     Partition[l1, 3, 1]];
  (*correlate with max and mins positions in the original list*)
  maxs = First /@ (Ordering[-l[[#[[1]] ;; #[[2]]]]] + #[[1]] - 
        1 & /@ ({4 + #[[1]] - 5, 4 + #[[1]] + 5} & /@ l2));
  mins = Last /@ (Ordering[-l[[#[[1]] ;; #[[2]]]]] + #[[1]] - 
        1 & /@ ({4 + #[[1]] - 5, 4 + #[[1]] + 5} & /@ l3));
  (*Show the plots*)
  Show[{
    ListPlot[l, Joined -> True, PlotRange -> All, 
     PlotLabel -> 
      Style[Framed[sym], 16, Blue, Background -> Lighter[Yellow]]],
    ListLinePlot[ExponentialMovingAverage[MovingAverage[l, 10], .2]], 
    ListPlot[{#, l[[#]]} & /@ maxs, 
     PlotStyle -> Directive[PointSize[Large], Red]],
    ListPlot[{#, l[[#]]} & /@ mins, 
     PlotStyle -> Directive[PointSize[Large], Black]]}, 
   ImageSize -> 400]
  ]
4 голосов
/ 15 августа 2011

Я не знаю, что вы подразумеваете под "простыми производными". Я понимаю, что это означает, что вы протестировали градиентный спуск и нашли его неудовлетворительным из-за обилия локальных экстремумов. Если это так, вы хотите посмотреть имитация отжига :

Отжиг - это металлургический процесс, используемый для закалки металлов путем нагревания и охлаждения. (...). Эти нарушения происходят из-за залипания атомов в неправильном месте структуры. В процессе отжига металл нагревается, а затем ему дают медленно остыть. Нагревание дает атомам энергию, необходимую для того, чтобы они застряли, а медленный период охлаждения позволяет им перейти в правильное положение в структуре.

(...) Однако, чтобы избежать локальной оптимы, алгоритм будет иметь вероятность сделать шаг в неправильном направлении : другими словами, сделать шаг, который увеличивает значение для задачи минимизации или уменьшает значение для задачи максимизации. Для моделирования процесса отжига эта вероятность будет частично зависеть от параметра «температуры» в алгоритме, который инициализируется при высоком значении и уменьшается на каждой итерации. Следовательно, алгоритм изначально будет иметь высокую вероятность ухода от ближайшего (вероятно, локального) оптимума . В течение итераций эта вероятность будет уменьшаться, и алгоритм будет сходиться к (мы надеемся, глобальному) оптимуму, от которого у него не было шансов уйти. ( источник , порезы &, выделение мое)

Я знаю , что локальная оптима - это именно то, что круги на вашем рисунке представляют выше, и, следовательно, то, что вы хотите найти. Но, поскольку я интерпретирую цитату « так много локальных мин и макс, простые производные не будут работать. », это также то, что вы найдете слишком много. Я предполагаю, что у вас есть проблемы со всем "зигзагообразным", который ваша кривая делает между двумя обведенными точками.

Все, что, по-видимому, отличает оптимум, который вы обводите от остальных точек кривой, это их глобальность , а именно: чтобы найти более низкую точку , чем первая точка, которую вы обведите слева вам нужно пройти дальше от в любую сторону в координате x, чем вам нужно сделать то же самое для его ближайших соседей. Это то, что дает вам отжиг: в зависимости от температурного параметра вы можете контролировать размер скачков, которые вы позволяете себе делать. Там имеет , чтобы быть значением, для которого вы ловите «большие» локальные оптимумы, и все же пропускаете «маленькие». То, что я предлагаю, не является революционным: есть несколько примеров (например, 1 2 ), где люди получают хорошие результаты из таких шумных данных.

3 голосов
/ 23 сентября 2011

Вы заметите, что многие ответы относятся к производным с некоторой фильтрацией нижних частот. Скользящая средняя какого-то рода, если хотите. И fft, скользящее среднее в квадратном окне и экспоненциальное скользящее среднее все довольно похожи на фундаментальном уровне. Однако, учитывая выбор всех скользящих средних, какой из них лучший?

Ответ: скользящее среднее Гаусса; Это нормальное распределение, о котором вы знаете.

Причина: фильтр Гаусса является единственным фильтром, который никогда не выдаст «фальшивый» максимум; Максимум, которого не было с самого начала. Это было теоретически доказано как для непрерывных, так и для дискретных данных (хотя убедитесь, что вы используете дискретный гауссов для дискретных данных!). Когда вы увеличиваете гауссовскую сигму, локальные максимумы и минимумы будут объединяться наиболее интуитивным способом. Таким образом, если вы хотите, чтобы в день было не более одного локального максимума, установите для сигмы один, ET cetera.

2 голосов
/ 20 сентября 2011

Вы можете использовать Сплайн-метод , чтобы создать непрерывный аппроксимативный полином для вашей исходной функции [с желаемой степенью].После того, как у вас есть этот полином, ищите локальный минимум / максимум [используя базовое исчисление] на нем [сгенерированный полином].

Обратите внимание, что метод сплайна дает вам полином аппроксимации, который является «гладким», поэтому легко найти локальные минимальные и максимальные значения, и оба, максимально приближенные к исходной функции, и, таким образом, локальные минимальные / минимальные значения.max должно быть очень близко к истинному значению в исходной функции.

Для повышения точности после нахождения локальных mins / max в сгенерированном полиноме для каждого x0, которые представляют локальные min / max,Вы должны посмотреть на все x так, чтобы x0-delta < x < x0 + delta, чтобы найти реальные минимальные / максимальные значения, которые эта точка представляет.

2 голосов
/ 15 августа 2011

Просто определите, что вы подразумеваете под минимумом и максимумом, точным, но настраиваемым способом, а затем настраивайте его, пока не найдете нужное количество минимумов и максимумов.Например, вы можете сначала сгладить график, заменив каждое значение средним значением этого значения и значениями N слева и справа от него.Увеличивая N, вы можете уменьшить количество найденных минимумов и максимумов.

Затем вы можете определить минимум как точку, в которой, если вы пропустите значения A влево и вправо, все следующие значения B будут показывать последовательное увеличениетенденция.Увеличивая B, вы можете найти меньше минимумов и максимумов.Регулируя A, вы можете настроить, насколько «плоским» может быть минимальное или максимальное значение.

Как только вы используете настраиваемый алгоритм, вы можете просто настроить его, пока он не будет выглядеть правильно.

1 голос
/ 18 сентября 2011

Я часто обнаруживал, что экстремумы, субъективно воспринимаемые людьми (читай: единственные экстремумы на биржевых диаграммах, которые в основном представляют собой случайный шум), часто обнаруживаются после полосовой фильтрации Фурье.Вы можете попробовать этот алгоритм:

  1. Выполнить БПФ
  2. Сделать полосу пропускания в частотном пространстве.Выберите параметры полосы пропускания на основе диапазона данных, на котором вы хотите, чтобы ваши экстремумы выглядели хорошо, то есть временной шкалы интереса.
  3. Выполните обратное БПФ.
  4. Выберите локальные максимумырезультирующая кривая.

Параметры второго шага кажутся довольно субъективными, но опять же, субъективность является самой природой анализа биржевой диаграммы.

0 голосов
/ 23 сентября 2011

Как упомянуло Велисарием, наилучший метод, по-видимому, предусматривает фильтрацию данных. При достаточном сглаживании поиск изменений наклона должен точно определять локальные минимумы и максимумы (здесь поможет производная). Я бы использовал центрированное скользящее окно для текущей медианы / среднего или текущей EMA (или аналогичного фильтра IIR).

0 голосов
/ 15 августа 2011

Теорема Ферма поможет вам найти локальные минимумы и максимумы.

...