查找股票图表的最小最大值

问题描述 投票:22回答:8

是否有任何特定的算法可以让我找到上图中的最小和最大点?

我有文本格式的数据,所以我不需要在图片中找到它。股票的问题在于它们拥有如此多的本地市场和最大限度的简单衍生品将无法运作。

我正在考虑使用数字滤波器(z域),并平滑图形,但我仍然留下太多的局部最小值和最大值。

我也试图使用移动平均线来平滑图形,但我又有太多的最大值和分钟。

编辑:

我读了一些评论,但我没有意外地圈出一些最小值和最大值。

我想我想出了一个可行的算法。首先找到最低点和最高点(当天的高点和当天的低点)。然后画出三条线,一条从开到高或低,先从一条线到一条线从低到高或从高到低,最后再闭合。然后在这三个区域中的每一个中找到距离线最远点的点作为我的高和低然后重复循环。

algorithm finance stocks
8个回答
13
投票

我通常使用移动平均线和指数移动平均线的组合。事实证明(经验上)适合于任务(至少足以满足我的需要)。仅使用两个参数调整结果。这是一个示例:

编辑

如果它对某人有用,这是我的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
投票

我不知道“简单衍生物”是什么意思。我理解这意味着你已经测试了一个gradient descent并发现它不能令人满意,因为当地的极端情况很多。如果是这样,你想看看simulated annealing

退火是一种冶金工艺,用于通过加热和冷却处理来回火金属。 (......)。这些不规则性是由于原子被卡在结构的错误位置。在退火过程中,将金属加热,然后缓慢冷却。加热为原子提供了不被卡住所需的能量,缓慢的冷却时间允许它们移动到结构中的正确位置。

(...)但是,为了逃避局部最优,算法将有可能向坏的方向迈出一步:换句话说,采取增加最小化问题的值或降低值的步骤为了最大化问题。为了模拟退火过程,该概率部分取决于算法中的“温度”参数,该参数在高值处初始化并在每次迭代时减小。因此,该算法最初将具有远离附近(可能是局部的)最佳值的高概率。在迭代中,概率将减小,算法将收敛于(希望全局)最优,它没有机会逃脱。 (source,削减&,强调我的)

我知道局部最佳值恰好是图中的圆圈代表的,上面的,以及您想要找到的内容。但是,当我解释引用“如此多的地方分钟和最大简单的衍生物将不起作用。”时,这也正是你发现的太多。我假设你在两个圆圈点之间曲线所做的所有“之字形”都有问题。

所有这些似乎将你圈出的最佳点与曲线的其余点区分开来的是它们的全局性,正是:为了找到比你在左边圈出的第一个点更低的点,你必须在x坐标的任何一个方向上走得更远比你需要为它的近邻做同样的事情。这就是退火给你的东西:根据温度参数,你可以控制自己允许的跳跃大小。必须有一个值,你可以捕捉到“大”的本地最优,但却错过了“小”的最佳。我所建议的并不是革命性的:有几个例子(例如1 2),人们从这些嘈杂的数据中获得了很好的结果。


3
投票

您会注意到许多答案都适用于具有某种低通滤波的衍生产品。某种移动平均线,如果你愿意的话。 fft,方窗移动平均线和指数移动平均线在基本水平上都非常相似。但是,考虑到所有移动平均线的选择,哪个是最好的?

答案:高斯移动平均线;正常分布的,你知道的。

原因是:高斯滤波器是唯一永远不会产生“伪”最大值的滤波器;最大的不是开始的。这在理论上已经证明了连续和离散数据(确保你使用离散高斯来表示离散数据!)。当您增加高斯西格玛时,局部最大值和最小值将以最直观的方式合并。因此,如果您希望每天不超过一个局部最大值,则将sigma设置为1,即ET cetera。


2
投票

只需以精确但可调的方式定义最小值和最大值的含义,然后对其进行调整,直到找到正确的最小值和最大值。例如,您可以先通过将每个值替换为该值的平均值以及它左右的N值来平滑图形。通过增加N,您可以减少找到的最小值和最大值。

然后,您可以将最小值定义为一个点,如果您向左和向右跳过A值,则下一个B值都会显示一致的增加趋势。通过增加B,您可以找到更少的最小值和最大值。通过调整A,您可以调整允许的最小值或最大值的“平坦度”。

使用可调算法后,您可以调整它直到它看起来正确。


2
投票

您可以使用Spline method为原始函数[具有所需程度]创建一个有趣的approximation polynom。拥有此多项式后,在其上查找[使用基本微积分]的局部最小值/最大值[生成的多项式]。

请注意,样条方法为您提供了一个“平滑”的近似多项式 - 因此很容易找到局部最小值/最大值,并且两者尽可能接近原始函数,因此局部最小值/最大值应该非常接近真正的价值,在原始的功能。

为了提高准确性,在生成的多项式中找到局部mins / max后,对于表示局部最小值/最大值的每个x0,您应该查看所有x,使x0-delta < x < x0 + delta找到此点所代表的实际最小值/最大值。


1
投票

我经常发现人类主观感知的极值(读取:股票图表中唯一的极值,主要是随机噪声)经常在傅立叶带通滤波后发现。您可以尝试这种算法:

  1. 执行FFT
  2. 在频率空间中进行带通。根据您希望极值看起来很好的数据范围,即感兴趣的时间刻度,选择带通'参数。
  3. 执行逆FFT。
  4. 选择结果曲线的局部最大值。

第二步的参数似乎很主观,但同样,主观性是股票图表分析的本质。


0
投票

正如belisarius所提到的,最好的方法似乎涉及平滑过滤数据。通过足够的平滑,寻找斜率的变化应该精确定位局部的分钟和最大值(导数将在这里有所帮助)。我会使用居中的滑动窗口来表示正在运行的中值/平均值,或者正在进行的EMA(或类似的IIR滤波器)。


-2
投票

Fermat's Theorem将帮助您找到当地的最小值和最大值。

© www.soinside.com 2019 - 2024. All rights reserved.