From eb3782288e8f04e5a286ab35fc4c2c4bc3e4f3fb Mon Sep 17 00:00:00 2001 From: Romulo De Lazzari Date: Sat, 27 Jun 2020 16:14:37 +0100 Subject: [PATCH] first commit --- .github/workflows/{ssl.yml => mfi.yml} | 2 +- README.md | 46 +-- composer.json | 4 +- composer.lock | 31 +- src/Mfi.php | 52 +++ src/Ssl.php | 48 --- tests/{SslTest.php => MfiTest.php} | 21 +- tests/values.php | 526 ++++++++++++------------- 8 files changed, 367 insertions(+), 363 deletions(-) rename .github/workflows/{ssl.yml => mfi.yml} (96%) create mode 100644 src/Mfi.php delete mode 100644 src/Ssl.php rename tests/{SslTest.php => MfiTest.php} (51%) diff --git a/.github/workflows/ssl.yml b/.github/workflows/mfi.yml similarity index 96% rename from .github/workflows/ssl.yml rename to .github/workflows/mfi.yml index df835bf..3c1e780 100644 --- a/.github/workflows/ssl.yml +++ b/.github/workflows/mfi.yml @@ -1,4 +1,4 @@ -name: SSL +name: MFI on: push: diff --git a/README.md b/README.md index 1828bfc..a5f359b 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,41 @@ -# SSL Channel +# Money Flow Index -Calculate the SSL Channel +Calculate the Money Flow Index (MFI) in pure PHP ## Instalation ``` -composer require romulodl/ssl +composer require romulodl/mfi ``` -or add `romulodl/ssl` to your `composer.json`. Please check the latest version in releases. +or add `romulodl/mfi` to your `composer.json`. Please check the latest version in releases. ## Usage ```php -$ssl = new Romulodl\Ssl(); -$ssl->calculate(array $hlc_values); // [high, low, close] -//returns integer (1 for positive channel or -1 for negative channel) +$mfi = new Romulodl\Mfi(); +$mfi->calculate(array $hlcv_values); // [high, low, close, volume] +//returns float ``` Example of use: ```php -$ssl = new Romulodl\Ssl(); -$ssl->calculate([ - [9950.00,9250.66,9786.80], - [9843.50,9100.00,9310.73], - [9585.00,9210.03,9374.99], - [9880.00,9317.16,9678.57], - [9958.67,9450.00,9731.10], - [9900.00,9462.00,9773.64], - [9838.00,9281.42,9508.11], - [9573.00,8812.20,9060.00], - [9259.38,8920.00,9166.40], - [9300.00,9076.90,9176.41], - [9294.44,8674.00,8711.37], - [8977.00,8623.38,8895.65], - [9011.82,8693.18,8837.05], - [9230.00,8811.00,9197.32], +$mfi = new Romulodl\Mfi(); +$mfi->calculate([ + [9950.00,9250.66,9786.80,602528.438], + [9843.50,9100.00,9310.73,504107.096], + [9585.00,9210.03,9374.99,287768.201], + [9880.00,9317.16,9678.57,300859.340], + [9958.67,9450.00,9731.10,363732.370], + [9900.00,9462.00,9773.64,376313.845], + [9838.00,9281.42,9508.11,334423.590], + [9573.00,8812.20,9060.00,461439.193], + [9259.38,8920.00,9166.40,276008.073], + [9300.00,9076.90,9176.41,201589.660], + [9294.44,8674.00,8711.37,339643.378], + [8977.00,8623.38,8895.65,302980.106], + [9011.82,8693.18,8837.05,275619.158], + [9230.00,8811.00,9197.32,272253.998], ]); ``` diff --git a/composer.json b/composer.json index abf5557..c4ebe2f 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "romulodl/ssl", - "description": "calculate the Ssl channel without the PECL trader extension", + "name": "romulodl/mfi", + "description": "calculate the Money Flow Index in pure PHP", "license": "Apache-2.0", "require-dev": { "phpunit/phpunit": "^8.5" diff --git a/composer.lock b/composer.lock index ae8d52c..b0b67da 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "867f6eda18eb5cd2b712f7ded472316b", + "content-hash": "eadacc857eb558c1be0a211e5f443d07", "packages": [], "packages-dev": [ { @@ -229,25 +229,25 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "2.1.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b" + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b", - "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "php": ">=7.1" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -274,7 +274,7 @@ "reflection", "static analysis" ], - "time": "2020-04-27T09:25:28+00:00" + "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -331,25 +331,24 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "30441f2752e493c639526b215ed81d54f369d693" + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30441f2752e493c639526b215ed81d54f369d693", - "reference": "30441f2752e493c639526b215ed81d54f369d693", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", "shasum": "" }, "require": { - "php": "^7.2", + "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "^7.2", - "mockery/mockery": "~1" + "ext-tokenizer": "*" }, "type": "library", "extra": { @@ -373,7 +372,7 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-19T20:22:09+00:00" + "time": "2020-06-27T10:12:23+00:00" }, { "name": "phpspec/prophecy", diff --git a/src/Mfi.php b/src/Mfi.php new file mode 100644 index 0000000..b41db84 --- /dev/null +++ b/src/Mfi.php @@ -0,0 +1,52 @@ +isValidValue($val)) { + throw new \Exception('[' . __METHOD__ . '] invalid HLC value'); + } + + $typical_price = $this->getTypicalPrice($val[0], $val[1], $val[2]); + + if ($typical_price > $prev_typical_price) { + $pos_money_flow += $typical_price * $val[3]; + } elseif ($typical_price < $prev_typical_price) { + $neg_money_flow += $typical_price * $val[3]; + } + + $prev_typical_price = $typical_price; + } + + return 100 - 100/(1 + $pos_money_flow / $neg_money_flow); + } + + private function getTypicalPrice($high, $low, $close) { + return ($high + $low + $close) / 3; + } + + private function isValidValue($values) : bool + { + return is_array($values) && + count($values) === 4 && + is_numeric($values[0]) && + is_numeric($values[1]) && + is_numeric($values[2]) && + is_numeric($values[3]); + } +} diff --git a/src/Ssl.php b/src/Ssl.php deleted file mode 100644 index d1f9dfd..0000000 --- a/src/Ssl.php +++ /dev/null @@ -1,48 +0,0 @@ -isValidHLCValue($val)) { - throw new \Exception('[' . __METHOD__ . '] invalid HLC value'); - } - - $high[] = $val[0]; - $low[] = $val[1]; - - if (count($high) < $period) { - continue; - } - - $sma_high = array_sum(array_slice($high, -1 * $period)) / $period; - $sma_low = array_sum(array_slice($low, -1 * $period)) / $period; - $close = $val[2] > $sma_high ? 1 : $close < $sma_low ? -1 : $close; - } - - return $close; - } - - private function isValidHLCValue($values) : bool - { - return is_array($values) && - count($values) === 3 && - is_numeric($values[0]) && - is_numeric($values[1]) && - is_numeric($values[2]); - } -} diff --git a/tests/SslTest.php b/tests/MfiTest.php similarity index 51% rename from tests/SslTest.php rename to tests/MfiTest.php index e7d4f1b..018c63e 100644 --- a/tests/SslTest.php +++ b/tests/MfiTest.php @@ -2,33 +2,34 @@ declare(strict_types=1); use PHPUnit\Framework\TestCase; -use Romulodl\Ssl; +use Romulodl\Mfi; -final class SslTest extends TestCase +final class MfiTest extends TestCase { public function testCalculateWithWrongTypeValues(): void { $this->expectException(Exception::class); - $ssl = new Ssl(); - $ssl->calculate(['poop']); + $mfi = new Mfi(); + $mfi->calculate(['poop']); } public function testCalculateWithEmptyValues(): void { $this->expectException(Exception::class); - $ssl = new Ssl(); - $ssl->calculate([]); + $mfi = new Mfi(); + $mfi->calculate([]); } public function testCalculateWithValidValues(): void { - $values = require(__DIR__ . '/values.php'); + $val = require(__DIR__ . '/values.php'); + $values = array_slice($val, -14); - $ssl = new Ssl(); - $ssl = $ssl->calculate($values); + $mfi = new Mfi(); + $mfi = $mfi->calculate($values); - $this->assertSame(-1, $ssl); + $this->assertSame(41.56, round($mfi, 2)); } } diff --git a/tests/values.php b/tests/values.php index 62d060d..7ecdd53 100644 --- a/tests/values.php +++ b/tests/values.php @@ -1,267 +1,267 @@