MACD函数返回不正确的值

时间:2015-12-23 02:09:55

标签: php ta-lib technical-indicator

我正在尝试使用PHP trader functions(可用作PECL扩展)来计算各种证券的移动平均收敛/差异(MACD)。但是,返回的值似乎与我的计算不符。

考虑以下股票的收盘价格:

$close = array (
  0 => 459.99,
  1 => 448.85,
  2 => 446.06,
  3 => 450.81,
  4 => 442.8,
  5 => 448.97,
  6 => 444.57,
  7 => 441.4,
  8 => 430.47,
  9 => 420.05,
  10 => 431.14,
  11 => 425.66,
  12 => 430.58,
  13 => 431.72,
  14 => 437.87,
  15 => 428.43,
  16 => 428.35,
  17 => 432.5,
  18 => 443.66,
  19 => 455.72,
  20 => 454.49,
  21 => 452.08,
  22 => 452.73,
  23 => 461.91,
  24 => 463.58,
  25 => 461.14,
  26 => 452.08,
  27 => 442.66,
  28 => 428.91,
  29 => 429.79,
  30 => 431.99,
  31 => 427.72,
  32 => 423.2,
  33 => 426.21,
  34 => 426.98,
  35 => 435.69,
  36 => 434.33,
  37 => 429.8,
  38 => 419.85,
  39 => 426.24,
  40 => 402.8,
  41 => 392.05,
  42 => 390.53,
  43 => 398.67,
  44 => 406.13,
  45 => 405.46,
  46 => 408.38,
  47 => 417.2,
  48 => 430.12,
  49 => 442.78,
  50 => 439.29,
  51 => 445.52,
  52 => 449.98,
  53 => 460.71,
  54 => 458.66,
  55 => 463.84,
  56 => 456.77,
  57 => 452.97,
  58 => 454.74,
  59 => 443.86,
  60 => 428.85,
  61 => 434.58,
  62 => 433.26,
  63 => 442.93,
  64 => 439.66,
  65 => 441.35,
);

根据这些数字,MACD,信号线和MACD柱状图应该出现:

// MACD
Array
(
    [0] => 8.275269504
    [1] => 7.703378381
    [2] => 6.416074757
    [3] => 4.237519783
    [4] => 2.552583325
    [5] => 1.37888572
    [6] => 0.102981491
    [7] => -1.258401953
    [8] => -2.07055819
    [9] => -2.621842328
    [10] => -2.32906674
    [11] => -2.181632115
    [12] => -2.402626273
    [13] => -3.342121681
    [14] => -3.530363136
    [15] => -5.507471249
    [16] => -7.851274229
    [17] => -9.719367455
    [18] => -10.42286651
    [19] => -10.26016216
    [20] => -10.06920961
    [21] => -9.571919612
    [22] => -8.369633492
    [23] => -6.301635724
    [24] => -3.599681509
    [25] => -1.720148361
    [26] => 0.269003232
    [27] => 2.180173247
    [28] => 4.508637809
    [29] => 6.118020154
    [30] => 7.722430594
    [31] => 8.327453809
    [32] => 8.403441185
    [33] => 8.508406323
    [34] => 7.625761844
    [35] => 5.649949083
    [36] => 4.494654765
    [37] => 3.432989362
    [38] => 3.333473854
    [39] => 2.956662856
    [40] => 2.762561216
)

// Signal line
Array
(
    [0] => 3.037525869
    [1] => 1.905652229
    [2] => 1.058708435
    [3] => 0.410640325
    [4] => -0.152012994
    [5] => -0.790034732
    [6] => -1.338100413
    [7] => -2.17197458
    [8] => -3.30783451
    [9] => -4.590141099
    [10] => -5.756686181
    [11] => -6.657381376
    [12] => -7.339747023
    [13] => -7.786181541
    [14] => -7.902871931
    [15] => -7.58262469
    [16] => -6.786036054
    [17] => -5.772858515
    [18] => -4.564486166
    [19] => -3.215554283
    [20] => -1.670715865
    [21] => -0.112968661
    [22] => 1.45411119
    [23] => 2.828779714
    [24] => 3.943712008
    [25] => 4.856650871
    [26] => 5.410473066
    [27] => 5.458368269
    [28] => 5.265625568
    [29] => 4.899098327
    [30] => 4.585973432
    [31] => 4.260111317
    [32] => 3.960601297
)

// MACD histogram
Array
(
    [0] => -5.108084059
    [1] => -4.527494558
    [2] => -3.387775176
    [3] => -2.59227244
    [4] => -2.250613279
    [5] => -2.55208695
    [6] => -2.192262723
    [7] => -3.335496669
    [8] => -4.543439719
    [9] => -5.129226357
    [10] => -4.666180327
    [11] => -3.602780783
    [12] => -2.729462587
    [13] => -1.785738071
    [14] => -0.466761561
    [15] => 1.280988966
    [16] => 3.186354544
    [17] => 4.052710154
    [18] => 4.833489398
    [19] => 5.39572753
    [20] => 6.179353673
    [21] => 6.230988815
    [22] => 6.268319404
    [23] => 5.498674095
    [24] => 4.459729177
    [25] => 3.651755452
    [26] => 2.215288778
    [27] => 0.191580814
    [28] => -0.770970803
    [29] => -1.466108965
    [30] => -1.252499579
    [31] => -1.303448461
    [32] => -1.198040081
)

请注意,MACD需要计算26天移动平均线,因此虽然收盘价有66个不同的数据点,但只有41个计算的MACD值。此外,信号线(以及因此需要信号线的MACD直方图)需要9天的MACD移动平均线,因此信号线/ MACD柱状图只有31个计算。

以上数据是在excel上计算的,是正确的MACD。我必须用PHP计算MACD的短脚本是:

<?php
// The array $close is the same as it is in the above example, omitted here for brevity.
$macd = trader_macd($close, 12, 26);
var_dump($macd);
?>

然而,var_dump($macd)打印:

array(3) {
  [0]=>
  array(40) {
    [24]=>
    float(0)
    [25]=>
    float(4.415)
    [26]=>
    float(4.437)
    [27]=>
    float(3.652)
    [28]=>
    float(1.899)
    [29]=>
    float(0.574)
    [30]=>
    float(-0.295)
    [31]=>
    float(-1.314)
    [32]=>
    float(-2.457)
    [33]=>
    float(-3.085)
    [34]=>
    float(-3.48)
    [35]=>
    float(-3.055)
    [36]=>
    float(-2.796)
    [37]=>
    float(-2.923)
    [38]=>
    float(-3.782)
    [39]=>
    float(-3.903)
    [40]=>
    float(-5.822)
    [41]=>
    float(-8.118)
    [42]=>
    float(-9.945)
    [43]=>
    float(-10.614)
    [44]=>
    float(-10.422)
    [45]=>
    float(-10.206)
    [46]=>
    float(-9.688)
    [47]=>
    float(-8.467)
    [48]=>
    float(-6.384)
    [49]=>
    float(-3.67)
    [50]=>
    float(-1.779)
    [51]=>
    float(0.219)
    [52]=>
    float(2.138)
    [53]=>
    float(4.473)
    [54]=>
    float(6.088)
    [55]=>
    float(7.697)
    [56]=>
    float(8.306)
    [57]=>
    float(8.385)
    [58]=>
    float(8.493)
    [59]=>
    float(7.613)
    [60]=>
    float(5.639)
    [61]=>
    float(4.485)
    [62]=>
    float(3.425)
    [63]=>
    float(3.327)
  }
  [1]=>
  array(40) {
    [24]=>
    float(4.437)
    [25]=>
    float(3.652)
    [26]=>
    float(1.899)
    [27]=>
    float(0.574)
    [28]=>
    float(-0.295)
    [29]=>
    float(-1.314)
    [30]=>
    float(-2.457)
    [31]=>
    float(-3.085)
    [32]=>
    float(-3.48)
    [33]=>
    float(-3.055)
    [34]=>
    float(-2.796)
    [35]=>
    float(-2.923)
    [36]=>
    float(-3.782)
    [37]=>
    float(-3.903)
    [38]=>
    float(-5.822)
    [39]=>
    float(-8.118)
    [40]=>
    float(-9.945)
    [41]=>
    float(-10.614)
    [42]=>
    float(-10.422)
    [43]=>
    float(-10.206)
    [44]=>
    float(-9.688)
    [45]=>
    float(-8.467)
    [46]=>
    float(-6.384)
    [47]=>
    float(-3.67)
    [48]=>
    float(-1.779)
    [49]=>
    float(0.219)
    [50]=>
    float(2.138)
    [51]=>
    float(4.473)
    [52]=>
    float(6.088)
    [53]=>
    float(7.697)
    [54]=>
    float(8.306)
    [55]=>
    float(8.385)
    [56]=>
    float(8.493)
    [57]=>
    float(7.613)
    [58]=>
    float(5.639)
    [59]=>
    float(4.485)
    [60]=>
    float(3.425)
    [61]=>
    float(3.327)
    [62]=>
    float(2.951)
    [63]=>
    float(2.758)
  }
  [2]=>
  array(40) {
    [24]=>
    float(-4.437)
    [25]=>
    float(0.763)
    [26]=>
    float(2.538)
    [27]=>
    float(3.079)
    [28]=>
    float(2.194)
    [29]=>
    float(1.888)
    [30]=>
    float(2.162)
    [31]=>
    float(1.771)
    [32]=>
    float(1.023)
    [33]=>
    float(-0.03)
    [34]=>
    float(-0.684)
    [35]=>
    float(-0.133)
    [36]=>
    float(0.986)
    [37]=>
    float(0.98)
    [38]=>
    float(2.04)
    [39]=>
    float(4.215)
    [40]=>
    float(4.122)
    [41]=>
    float(2.496)
    [42]=>
    float(0.477)
    [43]=>
    float(-0.408)
    [44]=>
    float(-0.734)
    [45]=>
    float(-1.738)
    [46]=>
    float(-3.303)
    [47]=>
    float(-4.798)
    [48]=>
    float(-4.605)
    [49]=>
    float(-3.889)
    [50]=>
    float(-3.917)
    [51]=>
    float(-4.254)
    [52]=>
    float(-3.95)
    [53]=>
    float(-3.224)
    [54]=>
    float(-2.218)
    [55]=>
    float(-0.688)
    [56]=>
    float(-0.187)
    [57]=>
    float(0.772)
    [58]=>
    float(2.854)
    [59]=>
    float(3.127)
    [60]=>
    float(2.214)
    [61]=>
    float(1.159)
    [62]=>
    float(0.474)
    [63]=>
    float(0.569)
  }
}

如上所述,PHP返回一个包含3个数组的数组。 documentation几乎没有提示每个数组是什么,只说明了MACD函数

  

返回包含计算数据的数组,如果失败则返回false。

user contributed note(虽然得分为-1)添加第一个数组(索引0)是MACD值,第二个数组(索引1)是信号值,最后一个数组(指数2)是分歧值。

即使用户注释为真,返回的数组也不符合我的计算(我知道这是正确的)。为什么trader_macd()返回错误的值/我做错了什么?

交易者函数的PHP文档只包含每个函数的参数列表。作为旁注,我可以在任何地方获得更详细的交易者扩展文档吗?这不是我第一次遇到扩展程序中的函数问题。

1 个答案:

答案 0 :(得分:5)

我不懂PHP,但我可以从C / C ++的角度解释ta-lib的行为。我用你的数据集调试了它的MACD。如果你为你的数据拨打ta-lib的C函数ta_macd(),你就会得到关注。

macd     signal    hist
-3.08486 0.869685 -3.95455
-3.4801 -0.000272319 -3.47983
-3.05529 -0.611275 -2.44401
-2.79613 -1.04825 -1.74788
-2.92258 -1.42311 -1.49947
-3.78208 -1.89491 -1.88718
-3.90264 -2.29645 -1.60619
-5.82247 -3.00166 -2.82082
-8.11782 -4.02489 -4.09293
-9.9449 -5.20889 -4.73601
-10.6137 -6.28985 -4.32385
-10.4216 -7.11621 -3.30543
-10.2058 -7.73414 -2.47171
-9.68753 -8.12482 -1.56272
-8.46746 -8.19335 -0.274115
-6.38441 -7.83156 1.44715
-3.66972 -6.99919 3.32947
-1.77941 -5.95524 4.17582
0.218855 -4.72042 4.93927
2.13774 -3.34879 5.48653
4.47273 -1.78448 6.25722
6.08764 -0.210058 6.2977
7.69672 1.3713 6.32543
8.3057 2.75818 5.54752
8.38504 3.88355 4.50149
8.49283 4.80541 3.68743
7.61258 5.36684 2.24574
5.6388 5.42123 0.217565
4.48522 5.23403 -0.748811
3.42501 4.87223 -1.44722
3.32672 4.56312 -1.23641
2.95095 4.24069 -1.28974
2.75772 3.9441 -1.18637

它与以下的excel文件bcs不匹配:

  1. TA-Lib计算26天EMA,其中第一个EMA结果是最初26天的平均值。这是默认行为(非Metastock)。
  2. TA-lib计算12天EMA,其中第一个EMA结果是最初12天的平均值。但它调整到可以获得第一个26天EMA的日子。因此,它使用15-26天来计算12天EMA的第一个值的平均值。这与您的Excel有很大不同。只需将公式=AVERAGE(B19:B30)放入单元格C30,excel结果就会与C函数结果匹配。
  3. 然后TA-lib使用9天(默认信号周期)EMA计算信号\ hist值,超过它在步骤2和3上获得的值。并且它仅返回具有MACD,信号和hist的天数。换句话说,它不会返回前8个MACD值。如果您在Excel中的第2步中进行了更改,则会发现C ++函数结果将与范围E38-G70匹配。
  4. 嗯,就我所见,TA-Lib的工作原理。但是,如果您将我的结果与您的PHP函数结果进行比较,您会发现它们也不匹配。但是你可以注意到我的MACD等于从

    开始的第一个数组中的值
    [33]=>
        float(-3.085)
    

    如果您将PHP结果与Excel(已更新)进行比较,您会发现第一个数组的第一个元素等于E30-E37。这些是TA-Libs省略的前8个MACD,因为它们没有相应的信号\ hist值bcs信号是用9天EMA计算的。它还意味着:

    1. 交易者函数作者不使用vanilla ta-lib。也许他们已经在PHP中重写了TA_MACD函数逻辑,或者分叉了ta-lib或者使用了我不知道的非常旧的版本。因为ta-lib只是不返回它们返回的MACD值(尽管它会计算它们)。
    2. 我不了解他们的结果数组格式,或者我不理解他们如何计算signal \ hist值(bcs第一个数组是可以解释的。)
    3. 我建议查看PHP函数源代码。我无法找到它。 如果你想在ta-lib中双重检查MACD的vanilla C实现,你应该参考以下页面:macdema