首页 > 解决方案 > TA-Lib : 技术分析库、回顾和不稳定期

问题描述

TA-Lib 是一个用于 Java、C++、.Net 等的金融/市场/OHLC 技术分析库。其中有大约 158 个技术函数(EMA、MAMA、MACD、SMA 等),每个都有一个关联的回溯函数

public static int EmaLookback(int optInTimePeriod) 

每个函数的 Lookback 似乎返回准确计算每个函数所需的最小处理长度。startIdx 到 endIdx 等于 Lookback。

Core.RetCode retcode = Core.Ema(startIdx, endIdx, double inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, double outReal)

其中一些函数使用一个名为

Globals.unstablePeriod[0x17]

如果这在任何方面都不正确,请纠正我。现在的问题...

  1. 对于所有条目,数组不稳定期[] 初始化为 0。这是应该发生的事情吗,如果不是,我在 TA-Lib 的哪里可以找到初始化它的代码或数据?

  2. 我们正在编写的代码只需要数组 outReal[0](或任何其他“outArray[]”)中的单个最新元素。有没有办法返回单个元素(a),或者 startIdx 和 endIdx 之间的差值是否必须等于 Lookback(b)?

一个)

int startIdx = this.ohlcArray.IdxCurrent;
int endIdx = startIdx; 
// call to TA Routine goes here

b)

int lookBack = Core.EmaLookback(optInTimePeriod) - 1;
int startIdx = this.ohlcArray.IdxCurrent;
int endIdx = startIdx + lookBack;
// call to TA Routine goes here
retcode = Core.Ema(startIdx, endIdx, inReal, optInTimePeriod, ref outBegIdx, ref outNBElement, outReal);
  1. 为什么当 startIdx 等于 0 时,对于第一个 outArray[0] 元素,这些例程返回 0?

  2. 因为我得到了如此奇怪的结果。startIdx 应该在最早的日期还是最新的日期?意思是你应该从过去(startIdx)到现在(endIdx),还是从现在(startIdx)到最旧的日期(endIdx)?我猜我正在向后计算(b)

    a) 2000 (startIdx) - 2003 (endIdx),

    b) 2003 (startIdx) - 2000 (endIdx)

标签: c#ta-libtechnical-indicator

解决方案


我已经忘记了 C# 所以可能是错的,但是:

每个函数的 Lookback 似乎返回准确计算每个函数所需的最小处理长度。startIdx 到 endIdx 等于 Lookback。

不,它返回计算第一个输出元素所需的输入元素的数量。这通常等于或大于 timePeriod 值。就这样。因此,如果您输入 1000 个元素(StartIdx == 0 和 endIdx == 9999),而 Lookback 函数为您提供 25 个元素,您将得到 1000-25 = 9975 == outNBElement 结果元素。而 outBegIdx 将为 24。注意:没有人保证函数的准确性。回顾只是让您预先计算结果数组的大小,这对于可能分配固定大小数组的 C/C++ 至关重要。

对于所有条目,数组不稳定期[] 初始化为 0。这是应该发生的事情吗,如果不是,我在 TA-Lib 的哪里可以找到初始化它的代码或数据?

好像是这样的。它发生在 TA-Lib-Core.h 的 Core::GlobalsType 构造函数中

Globals.unstablePeriod 是一个数组,用于保存一些 TA 函数的不稳定设置。所寻址的值enum class FuncUnstId在 中声明ta_defs.h。0x17 值将对应于 T3 技术指标。

在 T3 指标的情况下,这个不稳定期只是为回溯结果增加了一个值。所以T3的回顾是6 * (timePeriod-1) + TA_GLOBALS_UNSTABLE_PERIOD[TA_FUNC_UNST_T3]。这就是为什么它默认为 0 的原因。很明显,函数的准确性并不是那么简单。

考虑 EMA。它的回顾是timePeriod-1 + TA_GLOBALS_UNSTABLE_PERIOD[TA_FUNC_UNST_EMA]. 假设不稳定值是 0。所以 EMA 只是一个 timePeriod-1。(我建议不要无缘无故地触及不稳定因素)。根据我看到的代码 - 默认情况下,它的第一个 EMA 结果计算为元素的第一个“回溯计数”的简单平均值。有一个全局兼容性设置可能是 {CLASSIC, METASTOCK, TRADESTATION} 并影响第一个元素的计算,但这并没有太大变化。您的第一个元素是平均值,其他元素计算为 EMA_today = (value_today - old_EMA)*coefficient + old_EMA

这就是你不能只传递元素的“回溯计数”并获得“准确的函数结果”的原因。它不会是准确的——它将是第一个,而不是正确的。在 EMA 的情况下,它总是一个简单的平均值,因为简单的平均值用作此函数的种子。并且以下结果不仅在前 N 个输入元素上计算,而且包括先前的 EMA 值。而这个以前的 EMA 包括它以前的 EMA 等。所以你不能只传递元素的回溯计数并期望得到准确的结果。您还需要传递以前的函数值。此外,大多数滚动指标的行为都是如此。它们的前 N ​​个值在很大程度上取决于您开始计算它们的点。这可能会通过不稳定期解决,但您最好不要限制输入数据。

为什么这些例程返回 0,对于第一个 outArray[0] 元素我猜在您的回溯计算中它是 -1 的 bcs。对于 outBegIdx'th 元素也返回 0,而不是 0 元素。

有没有办法返回单个元素(a)

使用常规的 TA-Lib - 不,或者您每次都需要处理足够大的数据以确保您的滚动结果确实“收敛”。但是我在这里为自己做了一个 TA-Lib 叉子这是为此目的而设计的。自述文件中描述了主要思想。它应该几乎与原始数据一样快,您只需传递单个值和状态对象即可返回单个结果,而无需重新计算所有数据。因此,当新数据到达时,计算可能会暂停并继续,而不会丢失先前的计算结果。问题是 TA-Lib 是用 C 编写的,其所有 C#/Java 等包装器的代码实际上是由其内部工具 (ta-gen) 生成的。没有人尝试通过这些包装接口使用我的 fork。所以他们可能会坏掉。此外,我不提供预编译的二进制文件,并且由于 TA-Lib 非常古老,而且它的基础设施非常漂亮,它可能需要一些技巧和努力才能在目标平台上构建它


推荐阅读