Reputation: 6628
I want to calculate the EMA (Exponential Moving Average) value in PHP.
I've tried with following code but it's giving me 500 error.
$real = array(12,15,17,19,21,25,28,12,15,16);
$timePeriod = 3;
$data = trader_ema($real,$timePeriod);
var_dump($data);
PHP: EMA calculation function trader-ema
Tried with long time Googling but not getting any help on this in PHP. So, I've no clue what needs to be done to calculate the EMA value.
Edit-1: Installed extensions
I've installed all the necessary extensions, Now I am getting the output. But it doesn't seems giving proper output.
I think PHP function for calculating EMA is not working properly. Any help in this would be greatly appreciated.
Upvotes: 3
Views: 6036
Reputation: 69681
The trader extension for PHP actually looks quite promising. The underlying code looks very mature, and I notice at the time of writing the latest stable PHP module (0.5.1) was released at the first of this year with support for PHP8.
It may take some reading of the documentation, for example the note around trader_set_unstable_period, and god-forbid, the trader source code to become proficient.
If I do a quick installation of the trader module in a PHP Docker container
apt-get update
pecl install trader
docker-php-ext-enable trader
using the article from here as a benchmark
and put together a simple test script comparing the function supplied by @Tryke and trader_ema
function exponentialMovingAverage(array $numbers, int $n): array
{
$m = count($numbers);
$α = 2 / ($n + 1);
$EMA = [];
// Start off by seeding with the first data point
$EMA[] = $numbers[0];
// Each day after: EMAtoday = α⋅xtoday + (1-α)EMAyesterday
for ($i = 1; $i < $m; $i++) {
$EMA[] = ($α * $numbers[$i]) + ((1 - $α) * $EMA[$i - 1]);
}
return $EMA;
}
function merge_results($input, $avgs) {
$results = [];
$empty = count($input) - count($avgs);
foreach($input as $i => $price) {
$results[] = $i < $empty ? [$price, null] : [$price, round($avgs[$i], 2)];
}
return $results;
}
$real = [
22.27,
22.19,
22.08,
22.17,
22.18,
22.13,
22.23,
22.43,
22.24,
22.29,
22.15,
22.39,
22.38,
22.61,
23.36,
24.05,
23.75,
23.83,
23.95,
23.63,
23.82,
23.87,
23.65,
23.19,
23.10,
23.33,
22.68,
23.10,
22.40,
22.17
];
$timePeriod = 10;
$traderData = trader_ema($real,$timePeriod);
echo "trader ema\n";
var_dump(merge_results($real, $traderData));
$phpData = exponentialMovingAverage($real, 3);
echo "\n\nphp ema\n";
var_dump(merge_results($real, $phpData));
The results of the trader_ema
match exactly. The results from Tryke's function do not. It seems to have results starting on the first day, whereas my expectation (and the output of the trader_ema
and benchmark numbers reflect) is that there are no results until the $timePeriod
has elapsed. See this note from the Investopedia article on EMA
Calculating the EMA requires one more observation than the SMA. Suppose that you want to use 20 days as the number of observations for the EMA. Then, you must wait until the 20th day to obtain the SMA. On the 21st day, you can then use the SMA from the previous day as the first EMA for yesterday.
Upvotes: 1
Reputation: 69
I recommend to use the math library from: https://github.com/markrogoyski/math-php
public static function exponentialMovingAverage(array $numbers, int $n): array
{
$m = count($numbers);
$α = 2 / ($n + 1);
$EMA = [];
// Start off by seeding with the first data point
$EMA[] = $numbers[0];
// Each day after: EMAtoday = α⋅xtoday + (1-α)EMAyesterday
for ($i = 1; $i < $m; $i++) {
$EMA[] = ($α * $numbers[$i]) + ((1 - $α) * $EMA[$i - 1]);
}
return $EMA;
}
Upvotes: 6