@@ -5,6 +5,9 @@ | |||||
"php": "^7.2.5", | "php": "^7.2.5", | ||||
"ext-ctype": "*", | "ext-ctype": "*", | ||||
"ext-iconv": "*", | "ext-iconv": "*", | ||||
"myclabs/php-enum": "^1.7", | |||||
"nyholm/psr7": "^1.2", | |||||
"psr/http-client": "^1.0", | |||||
"symfony/console": "5.0.*", | "symfony/console": "5.0.*", | ||||
"symfony/dotenv": "5.0.*", | "symfony/dotenv": "5.0.*", | ||||
"symfony/flex": "^1.3.1", | "symfony/flex": "^1.3.1", | ||||
@@ -4,8 +4,166 @@ | |||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | ||||
"This file is @generated automatically" | "This file is @generated automatically" | ||||
], | ], | ||||
"content-hash": "7f769bc9dabc952a9e9210886c4900c8", | |||||
"content-hash": "ed2d4bb6d2a2abe584b5f0867281d0ab", | |||||
"packages": [ | "packages": [ | ||||
{ | |||||
"name": "myclabs/php-enum", | |||||
"version": "1.7.6", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/myclabs/php-enum.git", | |||||
"reference": "5f36467c7a87e20fbdc51e524fd8f9d1de80187c" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/myclabs/php-enum/zipball/5f36467c7a87e20fbdc51e524fd8f9d1de80187c", | |||||
"reference": "5f36467c7a87e20fbdc51e524fd8f9d1de80187c", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"ext-json": "*", | |||||
"php": ">=7.1" | |||||
}, | |||||
"require-dev": { | |||||
"phpunit/phpunit": "^7", | |||||
"squizlabs/php_codesniffer": "1.*", | |||||
"vimeo/psalm": "^3.8" | |||||
}, | |||||
"type": "library", | |||||
"autoload": { | |||||
"psr-4": { | |||||
"MyCLabs\\Enum\\": "src/" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "PHP Enum contributors", | |||||
"homepage": "https://github.com/myclabs/php-enum/graphs/contributors" | |||||
} | |||||
], | |||||
"description": "PHP Enum implementation", | |||||
"homepage": "http://github.com/myclabs/php-enum", | |||||
"keywords": [ | |||||
"enum" | |||||
], | |||||
"time": "2020-02-14T08:15:52+00:00" | |||||
}, | |||||
{ | |||||
"name": "nyholm/psr7", | |||||
"version": "1.2.1", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/Nyholm/psr7.git", | |||||
"reference": "55ff6b76573f5b242554c9775792bd59fb52e11c" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/Nyholm/psr7/zipball/55ff6b76573f5b242554c9775792bd59fb52e11c", | |||||
"reference": "55ff6b76573f5b242554c9775792bd59fb52e11c", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": "^7.1", | |||||
"php-http/message-factory": "^1.0", | |||||
"psr/http-factory": "^1.0", | |||||
"psr/http-message": "^1.0" | |||||
}, | |||||
"provide": { | |||||
"psr/http-factory-implementation": "1.0", | |||||
"psr/http-message-implementation": "1.0" | |||||
}, | |||||
"require-dev": { | |||||
"http-interop/http-factory-tests": "dev-master", | |||||
"php-http/psr7-integration-tests": "dev-master", | |||||
"phpunit/phpunit": "^7.5" | |||||
}, | |||||
"type": "library", | |||||
"extra": { | |||||
"branch-alias": { | |||||
"dev-master": "1.0-dev" | |||||
} | |||||
}, | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Nyholm\\Psr7\\": "src/" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "Tobias Nyholm", | |||||
"email": "tobias.nyholm@gmail.com" | |||||
}, | |||||
{ | |||||
"name": "Martijn van der Ven", | |||||
"email": "martijn@vanderven.se" | |||||
} | |||||
], | |||||
"description": "A fast PHP7 implementation of PSR-7", | |||||
"homepage": "http://tnyholm.se", | |||||
"keywords": [ | |||||
"psr-17", | |||||
"psr-7" | |||||
], | |||||
"time": "2019-09-05T13:24:16+00:00" | |||||
}, | |||||
{ | |||||
"name": "php-http/message-factory", | |||||
"version": "v1.0.2", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/php-http/message-factory.git", | |||||
"reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", | |||||
"reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": ">=5.4", | |||||
"psr/http-message": "^1.0" | |||||
}, | |||||
"type": "library", | |||||
"extra": { | |||||
"branch-alias": { | |||||
"dev-master": "1.0-dev" | |||||
} | |||||
}, | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Http\\Message\\": "src/" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "Márk Sági-Kazár", | |||||
"email": "mark.sagikazar@gmail.com" | |||||
} | |||||
], | |||||
"description": "Factory interfaces for PSR-7 HTTP Message", | |||||
"homepage": "http://php-http.org", | |||||
"keywords": [ | |||||
"factory", | |||||
"http", | |||||
"message", | |||||
"stream", | |||||
"uri" | |||||
], | |||||
"time": "2015-12-19T14:08:53+00:00" | |||||
}, | |||||
{ | { | ||||
"name": "psr/cache", | "name": "psr/cache", | ||||
"version": "1.0.1", | "version": "1.0.1", | ||||
@@ -147,6 +305,157 @@ | |||||
], | ], | ||||
"time": "2019-01-08T18:20:26+00:00" | "time": "2019-01-08T18:20:26+00:00" | ||||
}, | }, | ||||
{ | |||||
"name": "psr/http-client", | |||||
"version": "1.0.0", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/php-fig/http-client.git", | |||||
"reference": "496a823ef742b632934724bf769560c2a5c7c44e" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/php-fig/http-client/zipball/496a823ef742b632934724bf769560c2a5c7c44e", | |||||
"reference": "496a823ef742b632934724bf769560c2a5c7c44e", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": "^7.0", | |||||
"psr/http-message": "^1.0" | |||||
}, | |||||
"type": "library", | |||||
"extra": { | |||||
"branch-alias": { | |||||
"dev-master": "1.0.x-dev" | |||||
} | |||||
}, | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Psr\\Http\\Client\\": "src/" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "PHP-FIG", | |||||
"homepage": "http://www.php-fig.org/" | |||||
} | |||||
], | |||||
"description": "Common interface for HTTP clients", | |||||
"homepage": "https://github.com/php-fig/http-client", | |||||
"keywords": [ | |||||
"http", | |||||
"http-client", | |||||
"psr", | |||||
"psr-18" | |||||
], | |||||
"time": "2018-10-30T23:29:13+00:00" | |||||
}, | |||||
{ | |||||
"name": "psr/http-factory", | |||||
"version": "1.0.1", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/php-fig/http-factory.git", | |||||
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", | |||||
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": ">=7.0.0", | |||||
"psr/http-message": "^1.0" | |||||
}, | |||||
"type": "library", | |||||
"extra": { | |||||
"branch-alias": { | |||||
"dev-master": "1.0.x-dev" | |||||
} | |||||
}, | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Psr\\Http\\Message\\": "src/" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "PHP-FIG", | |||||
"homepage": "http://www.php-fig.org/" | |||||
} | |||||
], | |||||
"description": "Common interfaces for PSR-7 HTTP message factories", | |||||
"keywords": [ | |||||
"factory", | |||||
"http", | |||||
"message", | |||||
"psr", | |||||
"psr-17", | |||||
"psr-7", | |||||
"request", | |||||
"response" | |||||
], | |||||
"time": "2019-04-30T12:38:16+00:00" | |||||
}, | |||||
{ | |||||
"name": "psr/http-message", | |||||
"version": "1.0.1", | |||||
"source": { | |||||
"type": "git", | |||||
"url": "https://github.com/php-fig/http-message.git", | |||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" | |||||
}, | |||||
"dist": { | |||||
"type": "zip", | |||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", | |||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", | |||||
"shasum": "" | |||||
}, | |||||
"require": { | |||||
"php": ">=5.3.0" | |||||
}, | |||||
"type": "library", | |||||
"extra": { | |||||
"branch-alias": { | |||||
"dev-master": "1.0.x-dev" | |||||
} | |||||
}, | |||||
"autoload": { | |||||
"psr-4": { | |||||
"Psr\\Http\\Message\\": "src/" | |||||
} | |||||
}, | |||||
"notification-url": "https://packagist.org/downloads/", | |||||
"license": [ | |||||
"MIT" | |||||
], | |||||
"authors": [ | |||||
{ | |||||
"name": "PHP-FIG", | |||||
"homepage": "http://www.php-fig.org/" | |||||
} | |||||
], | |||||
"description": "Common interface for HTTP messages", | |||||
"homepage": "https://github.com/php-fig/http-message", | |||||
"keywords": [ | |||||
"http", | |||||
"http-message", | |||||
"psr", | |||||
"psr-7", | |||||
"request", | |||||
"response" | |||||
], | |||||
"time": "2016-08-06T14:39:51+00:00" | |||||
}, | |||||
{ | { | ||||
"name": "psr/log", | "name": "psr/log", | ||||
"version": "1.1.3", | "version": "1.1.3", | ||||
@@ -0,0 +1,21 @@ | |||||
services: | |||||
# Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories) | |||||
Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory' | |||||
Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory' | |||||
Psr\Http\Message\ServerRequestFactoryInterface: '@nyholm.psr7.psr17_factory' | |||||
Psr\Http\Message\StreamFactoryInterface: '@nyholm.psr7.psr17_factory' | |||||
Psr\Http\Message\UploadedFileFactoryInterface: '@nyholm.psr7.psr17_factory' | |||||
Psr\Http\Message\UriFactoryInterface: '@nyholm.psr7.psr17_factory' | |||||
# Register nyholm/psr7 services for autowiring with HTTPlug factories | |||||
Http\Message\MessageFactory: '@nyholm.psr7.httplug_factory' | |||||
Http\Message\RequestFactory: '@nyholm.psr7.httplug_factory' | |||||
Http\Message\ResponseFactory: '@nyholm.psr7.httplug_factory' | |||||
Http\Message\StreamFactory: '@nyholm.psr7.httplug_factory' | |||||
Http\Message\UriFactory: '@nyholm.psr7.httplug_factory' | |||||
nyholm.psr7.psr17_factory: | |||||
class: Nyholm\Psr7\Factory\Psr17Factory | |||||
nyholm.psr7.httplug_factory: | |||||
class: Nyholm\Psr7\Factory\HttplugFactory |
@@ -0,0 +1,16 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Exchanges; | |||||
interface ExchangeInterface | |||||
{ | |||||
/** | |||||
* @return MarketInterface[] | |||||
*/ | |||||
public function getMarkets(): array; | |||||
} |
@@ -0,0 +1,47 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Exchanges\Kuna; | |||||
use Nyholm\Psr7\Request; | |||||
use Psr\Http\Client\ClientInterface; | |||||
class KunaApiExecutor | |||||
{ | |||||
public const API_BASE_URL = 'https://api.kuna.io'; | |||||
/** | |||||
* @var ClientInterface | |||||
*/ | |||||
private ClientInterface $client; | |||||
/** | |||||
* @var KunaSigner | |||||
*/ | |||||
private KunaSigner $signer; | |||||
public function __construct( | |||||
ClientInterface $client, | |||||
KunaSigner $signer | |||||
) | |||||
{ | |||||
$this->client = $client; | |||||
$this->signer = $signer; | |||||
} | |||||
public function getMarkets(): array | |||||
{ | |||||
$response = $this | |||||
->client | |||||
->sendRequest( | |||||
new Request( | |||||
'GET', | |||||
self::API_BASE_URL . '/v3/markets' | |||||
) | |||||
); | |||||
return json_decode($response->getBody(), true); | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Exchanges\Kuna; | |||||
use App\Exchanges\ExchangeInterface; | |||||
class KunaExchange implements ExchangeInterface | |||||
{ | |||||
/** | |||||
* @var KunaApiExecutor | |||||
*/ | |||||
private KunaApiExecutor $apiExecutor; | |||||
public function __construct( | |||||
KunaApiExecutor $apiExecutor | |||||
) | |||||
{ | |||||
$this->apiExecutor = $apiExecutor; | |||||
} | |||||
/** | |||||
* @inheritDoc | |||||
*/ | |||||
public function getMarkets(): array | |||||
{ | |||||
$data = $this->apiExecutor->getMarkets(); | |||||
$markets = []; | |||||
foreach ($data as $marketData) { | |||||
$markets[] = KunaMarket::createFromApiData($marketData, $this->apiExecutor); | |||||
} | |||||
return $markets; | |||||
} | |||||
} |
@@ -0,0 +1,51 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Exchanges\Kuna; | |||||
use App\Exchanges\MarketInterface; | |||||
use App\Utils\Money\Currency; | |||||
use App\Utils\Money\CurrencyPair; | |||||
class KunaMarket implements MarketInterface | |||||
{ | |||||
private KunaApiExecutor $apiExecutor; | |||||
private CurrencyPair $currencyPair; | |||||
private string $id; | |||||
public static function createFromApiData( | |||||
array $marketData, | |||||
KunaApiExecutor $apiExecutor | |||||
): self | |||||
{ | |||||
return new self( | |||||
$apiExecutor, | |||||
new CurrencyPair( | |||||
new Currency($marketData['base_unit'], (int)$marketData['base_precision']), | |||||
new Currency($marketData['quote_unit'], (int)$marketData['quote_precision']), | |||||
), | |||||
$marketData['id'] | |||||
); | |||||
} | |||||
public function __construct( | |||||
KunaApiExecutor $apiExecutor, | |||||
CurrencyPair $currencyPair, | |||||
string $id | |||||
) | |||||
{ | |||||
$this->apiExecutor = $apiExecutor; | |||||
$this->currencyPair = $currencyPair; | |||||
$this->id = $id; | |||||
} | |||||
public function getPair(): CurrencyPair | |||||
{ | |||||
return $this->currencyPair; | |||||
} | |||||
} |
@@ -0,0 +1,30 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Exchanges\Kuna; | |||||
use Psr\Http\Message\RequestInterface; | |||||
class KunaSigner | |||||
{ | |||||
private string $publicKey; | |||||
private string $privateKey; | |||||
public function __construct( | |||||
string $publicKey, | |||||
string $privateKey | |||||
) | |||||
{ | |||||
$this->publicKey = $publicKey; | |||||
$this->privateKey = $privateKey; | |||||
} | |||||
public function signRequest(RequestInterface $request): void | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Exchanges; | |||||
use App\Utils\Money\CurrencyPair; | |||||
interface MarketInterface | |||||
{ | |||||
public function getPair(): CurrencyPair; | |||||
} |
@@ -0,0 +1,22 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Utils\Money; | |||||
class Currency | |||||
{ | |||||
private string $code; | |||||
private int $precision; | |||||
public function __construct( | |||||
string $code, | |||||
int $precision = 2 | |||||
) | |||||
{ | |||||
$this->code = $code; | |||||
$this->precision = $precision; | |||||
} | |||||
} |
@@ -0,0 +1,30 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Utils\Money; | |||||
class CurrencyPair | |||||
{ | |||||
private Currency $base; | |||||
private Currency $quote; | |||||
public function __construct(Currency $base, Currency $quote) | |||||
{ | |||||
$this->base = $base; | |||||
$this->quote = $quote; | |||||
} | |||||
public function getBase(): Currency | |||||
{ | |||||
return $this->base; | |||||
} | |||||
public function getQuote(): Currency | |||||
{ | |||||
return $this->quote; | |||||
} | |||||
} |
@@ -0,0 +1,39 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Utils\Money; | |||||
class Money | |||||
{ | |||||
private string $amount; | |||||
private Currency $currency; | |||||
public function __construct( | |||||
string $amount, | |||||
Currency $currency | |||||
) | |||||
{ | |||||
$this->amount = $amount; | |||||
$this->currency = $currency; | |||||
} | |||||
/** | |||||
* @return Currency | |||||
*/ | |||||
public function getCurrency(): Currency | |||||
{ | |||||
return $this->currency; | |||||
} | |||||
/** | |||||
* @return string | |||||
*/ | |||||
public function getAmount(): string | |||||
{ | |||||
return $this->amount; | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
<?php | |||||
declare(strict_types=1); | |||||
namespace App\Utils\Order\Book; | |||||
use App\Utils\Money\Money; | |||||
class OrderBook | |||||
{ | |||||
/** | |||||
* @var array | |||||
*/ | |||||
private array $bids; | |||||
/** | |||||
* @var array | |||||
*/ | |||||
private array $asks; | |||||
/** | |||||
* OrderBook constructor. | |||||
* @param Money[] $bids | |||||
* @param Money[] $asks | |||||
*/ | |||||
public function __construct( | |||||
array $bids, | |||||
array $asks | |||||
) | |||||
{ | |||||
$this->bids = $bids; | |||||
$this->asks = $asks; | |||||
} | |||||
} |
@@ -1,7 +1,25 @@ | |||||
{ | { | ||||
"myclabs/php-enum": { | |||||
"version": "1.7.6" | |||||
}, | |||||
"nyholm/psr7": { | |||||
"version": "1.0", | |||||
"recipe": { | |||||
"repo": "github.com/symfony/recipes", | |||||
"branch": "master", | |||||
"version": "1.0", | |||||
"ref": "7c0a9352a57376f04f5444e74565102c3a23d0c7" | |||||
}, | |||||
"files": [ | |||||
"config/packages/nyholm_psr7.yaml" | |||||
] | |||||
}, | |||||
"php": { | "php": { | ||||
"version": "7.4" | "version": "7.4" | ||||
}, | }, | ||||
"php-http/message-factory": { | |||||
"version": "v1.0.2" | |||||
}, | |||||
"psr/cache": { | "psr/cache": { | ||||
"version": "1.0.1" | "version": "1.0.1" | ||||
}, | }, | ||||
@@ -11,6 +29,15 @@ | |||||
"psr/event-dispatcher": { | "psr/event-dispatcher": { | ||||
"version": "1.0.0" | "version": "1.0.0" | ||||
}, | }, | ||||
"psr/http-client": { | |||||
"version": "1.0.0" | |||||
}, | |||||
"psr/http-factory": { | |||||
"version": "1.0.1" | |||||
}, | |||||
"psr/http-message": { | |||||
"version": "1.0.1" | |||||
}, | |||||
"psr/log": { | "psr/log": { | ||||
"version": "1.1.3" | "version": "1.1.3" | ||||
}, | }, | ||||