我曾经做了一个这样的东西 ...

 

有一天,我突然意识到一个简单的问题:最小二乘法的逼近本质上是对向量的线性组合进行最小化。也就是说,可以制造出某种通用的近似函数。这是一笔交易,所以这里是函数的标题。

//+------------------------------------------------------------------+
//  Аппроксимация методом наименьших квадратов                       |
//+------------------------------------------------------------------+
bool LSA(double& V[], int M, int N, double& A[], double& C[]) {
// Имеется N векторов размером M
// и вектор их линейной комбинации Y размером естестственно тоже M.
// На вход функции они подаются в виде матрицы V[0..M-1][0..N],
// где Y размещён в столбце N 
// На выходе мы должны получить вектор коэффициентов C размером M.
// Нам нужна также матрица A[N][N+1] для размещения коэффициентов системы уравнений

重要的细节,所有的数组V和A其实都是一维的,数组A虽然是纯粹的工作,但数组V需要被正确的填充。

它还需要一个函数来解决一个线性方程组。当我在做这个的时候,我只知道MQL中的一个实现,即 ANG3110用于多项式回归的高斯方法。 自然,我采取了阻力最小的方法,并使用了这个特殊的算法来实现这个功能。换句话说,有更有效的算法,特别是在矩阵变成对称的情况下,但我没有采用这些算法。

如何使用它。

首先,我们决定要对哪个函数进行近似。比如说,让它成为一个线性回归。也就是说,我们将有一个A*1+B*X的线性组合,只是两个向量,一个单位向量和参数本身。

让我们创建工作数组,并在init()中为它们分配内存。

double V[];
double A[],С[];

...

  ArrayResize(A,6);  // размер N*(N+1)
  ArrayResize(C,2);  // размер N
  ArrayResize(V,M*3);  // M*(N+1), M - не что иное как размер выборки

剩下的就是正确填写V阵列和计算系数了。这可以按以下方式进行。

    ind = 0;
    Stop = Start + M;
// Заполняем векторы
    for(pos = Start; i < Stop; i++) {
     V[ind] = 1.0;
     ind++;
     V[ind] = pos;
     ind++;
     V[ind] = Close[pos];   
     ind++;
    }
// Считаем коэффициенты
   LSA(V, M, N, A, C);

完成后,线性回归C[0]+C[1]*pos就可以了。

我们需要做的第一件事是检查算法。为此,基于ang_PR (Din)-v1.mq4指标(ANG3110 ),我们使用LSA编写了一个多项式回归指标,并比较了结果。 结果在视觉上吻合,这就是测试的结束:)。LSA_PR.mq4指标附后。

附加的文件:
pr_lsa.mq4  7 kb
 

这都是很久以前的事了,最近我想起来了,决定再次把我做的工具付诸行动。

我的第一个想法是在报价图中寻找周期性。可能会出现这样的问题,为什么,因为有一个离散傅里叶变换(DFT)用于搜索谐波。但FFT只会给出周期短于采样长度的谐波。我们现在可以尝试将周期长于样本长度的谐波拟合到价格图中。当然,成功的拟合不会成为支持其真实存在的 "铁证",对某一特定近似值的信任程度问题应单独决定。

在所附的指标LSA_SinLRR.mq4中,线性趋势是在尝试谐波前计算的。它是用上层地平线计算的。在一定范围内搜索所有可能的样本长度,并选择 样本 的均方根误差最小的一个(取为基本样本量的1/4)。

谐波周期与样品的长度有关,通过乘以一个给定的系数。例如,如果它等于2,那么样本将包含半个周期的谐波,如果它等于0.5,则是两个周期。样本长度本身的确定方式与线性回归 相同,只是在最下层的地平线内进行列举。

为了减少计算量,对每个水平线采取不同的采样步骤。

矢量矩阵的填写方法如下

  for(i = IntShift; i < Frame; i++) {
    pos = HShift+i*Step;
    VT[ind] = MathSin(AFreq*pos);
    ind ++;
    VT[ind] = MathCos(AFreq*pos);
    ind ++;
    VT[ind] = Resid[i];   
    ind ++;
  }  //  for(i = IntShift; i < Frame; i++)

Resid是价格和旧趋势之间的差异。

指标参数。

extern double kPer = 4.0;   // Коэффициент для определения периода
extern int LRRank = 1;      // Номер старшего горизонта, больше 3-х не ставить
extern int FShift = 120;    // Расстояние в барах, на которое производится экстраполяция в будущее
extern int HShift = 1;      // Сдвиг текущего времени индикатора в прошлое в барах, бары правее него тоже будут проэктраполированы
extern double PointFactor = 0.1;  // Масштабирование гистограммы ошибок аппроксимации, 0.1 подойдёт для минуток на пятизнаке 
extern bool PriceClose = true; // Если false, то будет считаться по HL/2


唉,不知怎的,我写得很累:)

简而言之,其要点如下。这个功能并不假装是最优的,它只是让你把近似的东西做成煎饼,并立即尝试,直接出锅 :) 。因此,这些指标是以这样的方式制定的,也就是说,在风格和效率方面,它们不做任何假装。

这种情况下工作不是很迅速,所以不计算历史。这意味着在visualizer中学习更好。但它很快就会变得无趣 :)。但不排除有病人能找到一种方式从中受益:)。


总的来说,我知道我无法做出一个连贯的描述,如果有人感兴趣,他们可能会指望解释。


基本上,我们应该谈论另一个指标,它比提出的指标更接近和推断得更漂亮。也就是说,我对它印象非常深刻,我显然最终成为了片面的价格决定论的立场。但这并没有使事情变得简单,因为我还没有设法确定这些作品的长度 :) 。

但我没有精力再写了,我只能给出几张图片:)

成功外推的近似例子

被脉冲 "挫败 "的近似推断的例子

附加的文件:
lsa_sinlr.mq4  14 kb
 
Candid:

你能不能添加一段代码,HShift不被设置,而是由第一行的实际位置决定?更准确地说,如果它被设置为<0 - 那么这两种机制都会起作用,它将有可能在图表上拉到历史深处,并分析在那一点上的预测与之后发生的事情是如何吻合的。这将是有趣的;)

 
ForexTools:

你能不能添加一小段代码,HShift不是设置的,而是由第一行的实际位置决定的? 更准确地说,如果它被设置为<0 - 那么这两种机制都会起作用,你可以把它拖到历史深处的图表上,分析该点的预测与之后发生的事情是如何吻合的。这将是很有趣的;)

是的,这很方便,我给你一个版本。我应该指出,我不是特别热衷于图形控制,所以不能保证一切都会顺利。


顺便说一下,我想我没有在任何地方明确说过,右下角的直方图显示了基础样本的近似误差和样本外的推断误差。我们有理由认为,这些信息与评估情况有关。


P.S. 是的,忘了有一句话要补充。指示器在11:50更换

附加的文件:
 

再多说几句。究竟为什么要采取线性趋势?总之,真正的趋势看起来是线性的。假设这样的去趋势可以无意识地完成,那么就有希望在谐波的背后也能有现实。

原则上,提高多项式的度数不是问题,事实上我一开始就选择了抛物线。这是初级的,在几个添加和纠正的行中完成的,任何人都可以自己尝试,作为一种练习。

 

下午好。

请解释一下这些图纸。我对垂直线 感兴趣。我是否正确地理解了在蓝线之间的预测数据? 红色的是什么意思?- 为什么红色(蓝色)预测线有缺口?

我还没有看代码,因为你的MQL编程水平对我来说太低了,要接近这个水平就像做梦一样?

 

Prival:

请解释一下这些图纸。我对垂直线感兴趣。我是否正确地理解了在蓝线之间的预测数据? 红色的是什么意思?- 为什么红色(蓝色)预测线有空隙?


是的,实际上近似值是在蓝线之间完成的。在蓝色和红色之间,计算出了外推的有效值。只是在我们的能力范围内,用HShift转移它(现在只是沿着图表拖动线),看看它没有看到什么。

差距是 "浪费",指标的工作窗口随时间推移而转移,尾巴被留下。这很容易用一个永久性的窗口来解决,但由于它的适应性,我还没有想到一个便宜的方法来清理它。

我给你的是重新画了线的版本。

附加的文件:
 

你的新代码没有按照我的要求工作 :(

我冒昧地拆了我的编辑,效果很好,特别是与ft.AutoRefresh搭配使用时。

附加的文件:
lsa_sinlr_1.mq4  16 kb
 

ForexTools:

在这里,我允许自己拆解我的编辑。特别是与ft.AutoRefresh搭配使用时,效果非常好。

好吧,我认为你的版本更防干扰,但你可能也需要在那里添加HShift--,这样在没有用户操作的情况下,窗口会随着时间推移而移动。虽然,嗯,也许这正是你想要避免的?
 
当然!在分析历史时,图表不应该去任何地方,而应该 "站 "在我放线的地方。
 
ForexTools:
当然!在分析历史时,图表不应该去任何地方,而应该 "站 "在我放线的地方。

好吧,我先做了一个固定的变体,然后替换了它:)。我感兴趣的是,首先,对重绘的动态感兴趣。实际上,添加一个参数是很容易的,比如

if (ModeMoving) HShift--;
但太好也不好,让变体闲置起来。