MACD Function Returns Incorrect Values

I am trying to use the PHPs trader function (available as a PECL extension) to calculate the convergence / divergence in the moving average (MACD) of various securities. However, the return values ​​do not match my calculations.

Consider the following array of close stock prices:

$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, ); 

Based on these MACD numbers, the signal line and the MACD histogram should come out:

 // 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 ) 

Please note that the MACD requires a 26-day moving average calculation, therefore, although there are 66 different data points for the closing price, there are a total of 41 calculated MACD values. In addition, the signal line (and therefore the MACD histogram, which requires a signal line) requires a 9-day moving average MACD, so there are only 31 calculations for the signal line / MACD histogram.

The above data were calculated based on excel and are correct MACD. Short script I have to calculate the MACD in PHP:

 <?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); ?> 

However, var_dump($macd) prints:

 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) } } 

As stated above, PHP returns an array containing 3 arrays. The documentation gives little hint that each array, stating only that the MACD function

Returns an array with calculated data or false on error.

A user note made by the user (although it has a rating of -1) adds that the first array (index 0) is the MACD value, the second array (index 1) is the signal value, and the last array (index 2) is the divergence value.

Even if the user's note is correct, the returned arrays do not match my calculations (which, as I know, are correct). Why is trader_macd() returning invalid values ​​/ what am I doing wrong?

The PHP documentation for trader functions contains a little more than the argument list of each function. As a note, is there anywhere I can get more detailed documentation for trader extension? This is not the first time that I have had problems with a function in an extension.

+4
source share
1 answer

I do not know PHP, but I can explain the behavior of ta-lib in terms of C / C ++. I debugged my MACD with your dataset. If you call the ta-lib C ta_macd() for your data, you will get the following.

 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 

It does not match your excel bcs file with the following content:

  • TA-Lib calculates a 26-day EMA, where the first EMA result is the average initial 26-day period. This is the default behavior (non-metastock).
  • TA-lib calculates a 12-day EMA, where the first EMA result is the average initial 12-day period. But it came to the day when it was possible to get the first 26-day EMA. Therefore, he uses days 15-26 to calculate the average, which is the first value for the 12-day EMA. This is the main difference from your Excel. Just enter the formula =AVERAGE(B19:B30) into cell C30 and the Excel results will match the results of function C.
  • Then TA-lib calculates the values ​​of the \ hist signal using the 9-day (default signal period) EMA over the values ​​obtained in steps 2 and 3. And it returns the results only for days that have both MACD and signal. In other words, it does not return the first 8 MACD values. If you made the changes proposed in step 2 in Excel, you will see that the results of the C ++ function will correspond to the E38-G70 range.

Good thing how TA-Lib works, as far as I can see. But if you compare my results with the results of your PHP function, you will find that they do not match either. But you may notice that my MACDs are equal to the values ​​in your first array, starting with

 [33]=> float(-3.085) 

And if you compare the results of PHP with Excel (updated), you will find that the first elements of the 1st array are equal to E30-E37 . These are the first 8 MACDs that TA-Libs omits, since they do not have the corresponding signal \ hist values. The bcs signal is calculated with a 9-day EMA. It also means the following:

  • The authors of the trader function do not use vanilla ta-lib. Perhaps they rewrote the logic of TA_MACD functions in PHP or branched ta-lib or used a very old version that I do not know. Because ta-lib just doesn't return the MACD values ​​that they return (although it computes them).
  • I don’t understand their format of the result arrays, or I don’t understand how they calculate the values ​​of the \ hist signal (the first bcs array is understandable).

I would recommend looking inside the source code of a PHP function. I could not find him. If you want to double check the MACD implementation in ta-lib with vanilla C, you should refer to the following pages: macd , ema .

+4
source

All Articles