Ваша проблема в том, что в данной функции неправильно работает расчет стандартного отклонения
формула StdDev = SQRT (SUM ((CLOSE — SMA (CLOSE, N))^2, N)/N),
так вот почему то CLOSE с значениями 0.0017812 , 0.00017812 и т.д. именно данная функция округляет до нуля, хотя в данной библиотеке все стальные работают нормально.
Поэтому нужно написать данный индикатор самому
Полосы Боллинджера представляют собой три линии:
1. Средняя линия ML (обычное скользящее среднее) рассчитывается по формуле:
ML = SUM (CLOSE, N) / N = SMA (CLOSE, N),
где:
— SUM (…, N) — сумма за N периодов;
— CLOSE — цена закрытия;
— N — количество периодов, используемых для расчета;
— SMA — простая скользящая средняя.
2. Верхняя линия TL (средняя линия ML, смещенная вверх на определенное число D стандартных отклонений StdDev) рассчитывается по формуле:
TL = ML + (D * StdDev),
3. Нижняя линия BL (средняя линия ML, смещенная вниз на число стандартных D отклонений StdDev) рассчитывается по формуле:
BL = ML — (D * StdDev).
StdDev – стандартное отклонение рассчитывается как:
StdDev = SQRT (SUM ((CLOSE — SMA (CLOSE, N))^2, N)/N),
где SQRT — квадратный корень.
код на php
$arValues = [
0.0017875,
0.001791,
0.0017904,
0.0017912,
0.001783,
0.0017821,
0.0017821,
0.001783,
0.0017888,
0.0017871,
0.0017877,
0.0017883,
0.0017869,
0.001783,
0.0017866,
0.0017879,
0.0017911,
0.0017936,
0.0017896,
0.0017902,
0.0017839,
0.0017818,
0.0017835,
0.0017836,
0.0017831,
0.0017832,
0.0017812,
0.0017816,
0.0017819,
0.0017803
];
function standard_deviation(array $a, $sample = false)
{
$n = count($a);
if ($n === 0) {
trigger_error("The array has zero elements", E_USER_WARNING);
return false;
}
if ($sample && $n === 1) {
trigger_error("The array has only 1 element", E_USER_WARNING);
return false;
}
$mean = array_sum($a) / $n;
$carry = 0.0;
foreach ($a as $val) {
$d = ((double) $val) - $mean;
$carry += $d * $d;
};
if ($sample) {
--$n;
}
return sqrt($carry / $n);
}
function trader_stddev($data, $period) {
$stds = [];
$current = [];
foreach ($data as $i => $close) {
$current[] = $close;
if ($i < $period) {
$stds[$i] = false;
} else {
$stds[$i] = TechnicalAnalysis::standard_deviation($current);
array_shift($current);
}
}
return $stds;
}
function mytraderBbands ($array_rates, $time_period, $upper_deviation_multiplier, $lower_deviation_multiplier,$ma_type = null) {
$trader_sma = trader_sma($array_rates, $time_period);
$StdDev = trader_stddev ($array_rates,$time_period);
$bb_up = end($trader_sma ) +
($upper_deviation_multiplier * end($StdDev));
$bb_down = end($trader_sma ) -
($lower_deviation_multiplier * end($StdDev));
return [$bb_up, $trader_sma, $bb_down];
}
$bb = mytraderBbands ($arValues, 20, 2, 2);
print_r ($bb );
функция trader_sma - это стандартная функция данной библиотеки
пс: Смотрю, прям ответами люди помогают, а главное подробно и конструктивно.
ПСПС: увидел почему разработчики решили не работать с числами с тысячными, при таких цифрах стандарная формула отклонения выдает немного не точный результат и чем больше нулей после запятой тем более он неточный. Но все равно, с приведенным мной кодом, вполне можно работать, неточность минимальная.