Files

124 lines
4.3 KiB
PHP
Raw Permalink Normal View History

2024-09-12 21:05:01 -05:00
<?php
2025-01-28 17:33:54 -06:00
declare(strict_types=1);
2024-09-12 21:05:01 -05:00
namespace App\Interfaces\MarketData;
2025-01-28 17:14:49 -06:00
use App\Interfaces\MarketData\Types\Dividend;
use App\Interfaces\MarketData\Types\Ohlc;
use App\Interfaces\MarketData\Types\Quote;
use App\Interfaces\MarketData\Types\Split;
2025-04-09 19:25:15 -05:00
use Finnhub\ObjectSerializer;
2025-01-28 17:14:49 -06:00
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
2024-09-12 21:05:01 -05:00
class FinnhubMarketData implements MarketDataInterface
{
public \Finnhub\Api\DefaultApi $client;
public function __construct()
{
2025-01-28 17:14:49 -06:00
2024-09-12 21:05:01 -05:00
$this->client = new \Finnhub\Api\DefaultApi(
2025-01-28 17:14:49 -06:00
new \GuzzleHttp\Client,
2024-09-12 21:05:01 -05:00
\Finnhub\Configuration::getDefaultConfiguration()->setApiKey('token', config('finnhub.key'))
);
}
2025-01-28 17:14:49 -06:00
public function exists(string $symbol): bool
2024-09-12 21:05:01 -05:00
{
return (bool) $this->quote($symbol);
2024-09-12 21:05:01 -05:00
}
public function quote(string $symbol): Quote
2024-09-12 21:05:01 -05:00
{
$quote = $this->client->quote($symbol);
2025-04-09 19:25:15 -05:00
if (is_null(Arr::get($quote, 'd'))) {
throw new \Exception('Could not find ticker on Finnhub');
}
$fundamental = cache()->remember(
2025-01-28 17:14:49 -06:00
'fh-symbol-'.$symbol,
1440,
2024-09-12 21:05:01 -05:00
function () use ($symbol) {
2025-04-09 19:25:15 -05:00
return array_merge(
(array) ObjectSerializer::sanitizeForSerialization($this->client->companyProfile2($symbol)),
(array) ObjectSerializer::sanitizeForSerialization($this->client->companyBasicFinancials($symbol, 'all')),
);
2024-09-12 21:05:01 -05:00
}
);
2025-01-28 17:14:49 -06:00
return new Quote([
2025-04-09 19:25:15 -05:00
'name' => Arr::get($fundamental, 'name'),
2024-09-12 21:05:01 -05:00
'symbol' => $symbol,
2025-04-09 19:25:15 -05:00
'currency' => Arr::get($fundamental, 'currency'),
2025-01-28 17:14:49 -06:00
'market_value' => Arr::get($quote, 'c'),
'fifty_two_week_high' => Arr::get($fundamental, 'metric.52WeekHigh'),
'fifty_two_week_low' => Arr::get($fundamental, 'metric.52WeekLow'),
2025-04-09 19:25:15 -05:00
'forward_pe' => Arr::get($fundamental, 'metric.peAnnual'),
'trailing_pe' => Arr::get($fundamental, 'metric.peTTM'),
'market_cap' => Arr::get($fundamental, 'metric.marketCapitalization', 0) * 1000000,
'book_value' => Arr::get($fundamental, 'metric.bookValuePerShareAnnual'),
'dividend_yield' => Arr::get($fundamental, 'metric.dividendYieldIndicatedAnnual'),
'meta_data' => [
'country' => Arr::get($fundamental, 'country'),
'exchange' => Arr::get($fundamental, 'exchange'),
'first_trade_year' => Arr::get($fundamental, 'ipo') ? Carbon::parse(Arr::get($fundamental, 'ipo'))->format('Y') : null,
'source' => 'finnhub',
],
2025-01-28 17:14:49 -06:00
]);
2024-09-12 21:05:01 -05:00
}
public function dividends($symbol, $startDate, $endDate): Collection
{
2025-04-09 19:25:15 -05:00
$dividends = $this->client->stockDividends($symbol, $startDate->toDateString(), $endDate->toDateString());
2025-01-28 17:14:49 -06:00
return collect($dividends)->map(function ($dividend) use ($symbol) {
return new Dividend([
2024-09-12 21:05:01 -05:00
'symbol' => $symbol,
'date' => Carbon::parse(Arr::get($dividend, 'date')),
2024-09-12 21:05:01 -05:00
'dividend_amount' => Arr::get($dividend, 'amount'),
]);
2024-09-12 21:05:01 -05:00
});
}
public function splits($symbol, $startDate, $endDate): Collection
2025-01-28 17:14:49 -06:00
{
2024-09-12 21:05:01 -05:00
2025-04-09 19:25:15 -05:00
$splits = $this->client->stockSplits($symbol, $startDate->toDateString(), $endDate->toDateString());
2024-09-12 21:05:01 -05:00
2025-01-28 17:14:49 -06:00
return collect($splits)->map(function ($split) use ($symbol) {
return new Split([
2024-09-12 21:05:01 -05:00
'symbol' => $symbol,
'date' => Carbon::parse(Arr::get($split, 'date')),
2024-09-12 21:05:01 -05:00
'split_amount' => Arr::get($split, 'toFactor') / Arr::get($split, 'fromFactor'),
]);
2024-09-12 21:05:01 -05:00
});
}
public function history($symbol, $startDate, $endDate): Collection
{
2025-01-28 17:14:49 -06:00
$history = $this->client->stockCandles($symbol, 'D', $startDate->timestamp, $endDate->timestamp);
2024-09-12 21:05:01 -05:00
$timestamps = Arr::get($history, 't', []);
$closes = Arr::get($history, 'c', []);
return collect($timestamps)->mapWithKeys(function ($timestamp, $index) use ($symbol, $closes) {
2025-04-09 19:25:15 -05:00
$date = Carbon::createFromTimestamp($timestamp)->toDateString();
2025-01-28 17:14:49 -06:00
return [$date => new Ohlc([
2024-09-12 21:05:01 -05:00
'symbol' => $symbol,
'date' => $date,
'close' => $closes[$index],
2025-01-28 17:14:49 -06:00
])];
2024-09-12 21:05:01 -05:00
});
}
2025-01-28 17:14:49 -06:00
}