Функция MACD, возвращающая неверные значения

Я пытаюсь использовать PHP функции трейдера (доступно как расширение 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, для которой требуется сигнальная линия), требуется скользящее среднее значение MACD за 9 дней, поэтому для гистограммы сигнальной линии / MACD имеется только 31 расчет.

Приведенные выше данные были рассчитаны на Excel и является правильным MACD. Короткий скрипт, который я должен вычислить MACD в 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);
?>

Тем не мение, 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 массива. документация дает небольшую подсказку о том, что представляет собой каждый массив, утверждая только, что функция MACD

Возвращает массив с вычисленными данными или false при ошибке.

Пользователь добавил примечание (хотя тот, который имеет оценку -1) добавляет, что первый массив (индекс 0) — это значения MACD, второй массив (индекс 1) — это значения сигнала, а последний массив (индекс 2) — значения расхождения.

Даже если примечание пользователя верно, возвращенные массивы не соответствуют моим вычислениям (что я знаю, чтобы быть правильным). Почему trader_macd() возвращает неправильные значения / что я делаю не так?

Документация PHP по функциям трейдера содержит чуть больше, чем список аргументов каждой функции. Как примечание, могу ли я где-нибудь получить более подробную документацию для расширения трейдера? Это не первый раз, когда у меня возникают проблемы с функцией в расширении.

5

Решение

Я не знаю PHP, но я могу объяснить поведение ta-lib с точки зрения C / C ++. Я отладил его MACD с вашим набором данных. Если вы вызываете C-функцию ta-lib 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 следующего:

  1. TA-Lib рассчитывает 26-дневную EMA, где первый результат EMA является средним значением начального 26-дневного периода. Это поведение по умолчанию (не для Metastock).
  2. TA-lib рассчитывает 12-дневную EMA, где первый результат EMA является средним значением начального 12-дневного периода. Но он приспособился к дню, когда можно было получить первую 26-дневную ЕМА. Таким образом, он использует дни 15-26 для вычисления среднего значения, которое является первым значением для 12-дневной EMA. Это главное отличие вашего Excel. Просто поставь формулу =AVERAGE(B19:B30) в клетке C30 и результаты Excel будут соответствовать результатам функции C.
  3. Затем TA-lib вычисляет значения «сигнал \ гист», используя 9-дневную (период сигнала по умолчанию) EMA, по значениям, полученным на шагах 2 и 3. И возвращает результаты только для дней с MACD, сигналом и «гистом». Другими словами, он не возвращает первые 8 значений MACD. Если вы внесли изменения, предложенные на шаге 2 в Excel, вы увидите, что результаты функции C ++ будут соответствовать диапазону E38-G70,

Ну, вот так TA-Lib работает, насколько я вижу. Но если вы сравните мои результаты с результатами вашей функции PHP, вы обнаружите, что они тоже не совпадают. Но вы можете заметить, что мои MACD равны значениям в вашем первом массиве, начиная с

[33]=>
float(-3.085)

И если вы сравните результаты PHP с Excel (обновлено), вы обнаружите, что первые элементы первого массива равны E30-E37, Это первые 8 MACD, которые TA-Lib опускает, так как они не имеют соответствующих значений сигнала \ исторических значений. Сигнал bcs рассчитывается с помощью EMA за 9 дней. Это также означает следующее:

  1. Авторы функций трейдера не используют ванильный ta-lib. Возможно, они переписали логику функций TA_MACD в PHP, или раздвоили ta-lib, или использовали очень старую версию, которую я не знаю. Потому что ta-lib просто не возвращает значения MACD, которые они возвращают (хотя он их вычисляет).
  2. Я не понимаю формат их результирующих массивов или не понимаю, как они вычисляют значения «сигнал \ гист» (первый массив bcs вполне объясним).

Я бы порекомендовал заглянуть внутрь исходного кода функции PHP. Я не мог найти это.
Если вы хотите перепроверить реализацию MACD в vanilla C в ta-lib, обратитесь к следующим страницам: МАКД, ЕМА.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]