Compare commits
1 Commits
main
...
nasdaq-provider
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d5fdda2cd |
@@ -0,0 +1,144 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Interfaces\MarketData;
|
||||||
|
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Tschucki\Alphavantage\Facades\Alphavantage;
|
||||||
|
|
||||||
|
class NasdaqMarketData implements MarketDataInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public function exists(String $symbol): Bool
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->quote($symbol)->isNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function quote(String $symbol): Collection
|
||||||
|
{
|
||||||
|
// https://api.nasdaq.com/api/quote/GOOG/info?assetclass=stocks
|
||||||
|
|
||||||
|
$quote = Alphavantage::core()->quoteEndpoint($symbol);
|
||||||
|
$quote = Arr::get($quote, 'Global Quote', []);
|
||||||
|
|
||||||
|
// https://api.nasdaq.com/api/quote/GOOG/summary?assetclass=stocks
|
||||||
|
|
||||||
|
$fundamental = cache()->tags(['quote', 'alpha-vantage', $symbol])->remember(
|
||||||
|
'symbol-'.$symbol,
|
||||||
|
1440,
|
||||||
|
function () use ($symbol) {
|
||||||
|
return Alphavantage::fundamentals()->overview($symbol);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (empty($fundamental)) return collect();
|
||||||
|
|
||||||
|
return collect([
|
||||||
|
'name' => Arr::get($fundamental, 'Name'),
|
||||||
|
'symbol' => Arr::get($fundamental, 'Symbol'),
|
||||||
|
'market_value' => Arr::get($quote, '05. price'),
|
||||||
|
'fifty_two_week_high' => Arr::get($fundamental, '52WeekHigh'),
|
||||||
|
'fifty_two_week_low' => Arr::get($fundamental, '52WeekLow'),
|
||||||
|
'forward_pe' => Arr::get($fundamental, 'ForwardPE'),
|
||||||
|
'trailing_pe' => Arr::get($fundamental, 'TrailingPE'),
|
||||||
|
'market_cap' => Arr::get($fundamental, 'MarketCapitalization'),
|
||||||
|
'book_value' => Arr::get($fundamental, 'BookValue'),
|
||||||
|
'last_dividend_date' => Arr::get($fundamental, 'DividendDate') != 'None'
|
||||||
|
? Arr::get($fundamental, 'DividendDate')
|
||||||
|
: null,
|
||||||
|
'dividend_yield' => Arr::get($fundamental, 'DividendYield') != 'None'
|
||||||
|
? Arr::get($fundamental, 'DividendYield')
|
||||||
|
: null
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dividends(String $symbol, $startDate, $endDate): Collection
|
||||||
|
{
|
||||||
|
// https://api.nasdaq.com/api/quote/GOOG/dividends?assetclass=stocks
|
||||||
|
|
||||||
|
$dividends = Alphavantage::fundamentals()->dividends($symbol);
|
||||||
|
$dividends = Arr::get($dividends, 'data', []);
|
||||||
|
|
||||||
|
return collect($dividends)
|
||||||
|
->filter(function($dividend) use ($startDate, $endDate) {
|
||||||
|
|
||||||
|
return Carbon::parse(Arr::get($dividend, 'ex_dividend_date'))->between($startDate, $endDate);
|
||||||
|
})
|
||||||
|
->map(function($dividend) use ($symbol) {
|
||||||
|
|
||||||
|
return [
|
||||||
|
'symbol' => $symbol,
|
||||||
|
'date' => Carbon::parse(Arr::get($dividend, 'ex_dividend_date'))
|
||||||
|
->format('Y-m-d H:i:s'),
|
||||||
|
'dividend_amount' => Arr::get($dividend, 'amount'),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function splits(String $symbol, $startDate, $endDate): Collection
|
||||||
|
{
|
||||||
|
throw new \Exception('The Nasdaq provider does not offer a splits endpoint.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function history(String $symbol, $startDate, $endDate): Collection
|
||||||
|
{
|
||||||
|
|
||||||
|
// https://api.nasdaq.com/api/quote/GOOG/historical?assetclass=stocks&fromdate=2014-09-16&limit=2000&offset=10&todate=2024-09-16
|
||||||
|
// https://api.nasdaq.com/api/quote/GOOG/chart?assetclass=stocks&fromdate=2014-09-16&todate=2024-09-16
|
||||||
|
|
||||||
|
$history = Alphavantage::timeSeries()->daily($symbol, 'full');
|
||||||
|
|
||||||
|
$history = Arr::get($history, 'Time Series (Daily)', []);
|
||||||
|
|
||||||
|
return collect($history)
|
||||||
|
->filter(function ($history, $date) use ($startDate, $endDate) {
|
||||||
|
|
||||||
|
return Carbon::parse($date)->between($startDate, $endDate);
|
||||||
|
})
|
||||||
|
->mapWithKeys(function($history, $date) use ($symbol) {
|
||||||
|
|
||||||
|
$date = Carbon::parse($date)->format('Y-m-d');
|
||||||
|
|
||||||
|
return [ $date => [
|
||||||
|
'symbol' => $symbol,
|
||||||
|
'date' => $date,
|
||||||
|
'close' => (float) Arr::get($history, '4. close')
|
||||||
|
]];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function nasdaqClient($symbol, $method, $params = [], $retry = false): Array|Object
|
||||||
|
// protected function nasdaqClient($symbol, $method, $params = [], $retry = false): Array|Object
|
||||||
|
{
|
||||||
|
|
||||||
|
$symbol = strtoupper($symbol);
|
||||||
|
$params = array_merge([
|
||||||
|
'assetclass' => 'stocks'
|
||||||
|
], $params);
|
||||||
|
|
||||||
|
if (!in_array($method, ['info', 'summary', 'dividends', 'historical', 'chart'])) {
|
||||||
|
|
||||||
|
throw new \Exception('This is not a valid method.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$endpoint = 'https://api.nasdaq.com/api/quote';
|
||||||
|
|
||||||
|
// return [url("$endpoint/$symbol/$method?assetclass=stock", $params), $params];
|
||||||
|
|
||||||
|
$response = Http::get("https://api.nasdaq.com/api/quote/$symbol/$method?assetclass=stock", $params)->json();
|
||||||
|
|
||||||
|
// if ($response->status->rCode != 200) {
|
||||||
|
|
||||||
|
// if ($retry == true) {
|
||||||
|
// throw new \Exception("Couldn't resolve $method for $symbol from Nasdaq.");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return $this->nasdaqClient($symbol, $method, array_merge($params, [ 'assetclass' => 'etf' ]), retry: true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use GuzzleHttp\Cookie\CookieJar;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use App\Http\Controllers\HoldingController;
|
use App\Http\Controllers\HoldingController;
|
||||||
use App\Http\Controllers\DashboardController;
|
use App\Http\Controllers\DashboardController;
|
||||||
use App\Http\Controllers\PortfolioController;
|
use App\Http\Controllers\PortfolioController;
|
||||||
use App\Http\Controllers\TransactionController;
|
use App\Http\Controllers\TransactionController;
|
||||||
|
use App\Interfaces\MarketData\NasdaqMarketData;
|
||||||
use Laravel\Jetstream\Http\Controllers\Livewire\PrivacyPolicyController;
|
use Laravel\Jetstream\Http\Controllers\Livewire\PrivacyPolicyController;
|
||||||
use Laravel\Jetstream\Http\Controllers\Livewire\TermsOfServiceController;
|
use Laravel\Jetstream\Http\Controllers\Livewire\TermsOfServiceController;
|
||||||
|
|
||||||
@@ -19,6 +22,29 @@ Route::get('/', function () {
|
|||||||
|
|
||||||
Route::get('/test', function () {
|
Route::get('/test', function () {
|
||||||
//
|
//
|
||||||
|
|
||||||
|
$cookieJar = new CookieJar();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response= Http::withQueryParameters([
|
||||||
|
'assetclass' => 'stocks',
|
||||||
|
])
|
||||||
|
->withCookies(['akaalb_ALB_Default' => '=~op=ao_api__east1:ao_api_east1|~rv=76~m=ao_api_east1:0|~os=ff51b6e767de05e2054c5c99e232919a~id=a7cdebc3132b5b30c8507ad37aec9418'], 'api.nasdaq.com')
|
||||||
|
->withHeader('accept', '*/*')
|
||||||
|
->withUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36')
|
||||||
|
->timeout(4)
|
||||||
|
->withOptions(['debug' => true])
|
||||||
|
->get("https://api.nasdaq.com/api/quote/GOOG/info");
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cookieJar->toArray();
|
||||||
|
return $response->getHeaders();
|
||||||
|
return $response;
|
||||||
|
// return Http::get("https://api.nasdaq.com/api/quote/GOOG/info?assetclass=stocks");
|
||||||
|
|
||||||
|
return (new NasdaqMarketData)->nasdaqClient('AAPL', 'info');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::middleware(['auth:sanctum', config('jetstream.auth_session'), 'verified'])->group(function () {
|
Route::middleware(['auth:sanctum', config('jetstream.auth_session'), 'verified'])->group(function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user