This commit is contained in:
hackerESQ
2024-08-24 22:19:40 -05:00
parent 5e89e66e7b
commit 54cf25aabc
13 changed files with 423 additions and 179 deletions
@@ -2,27 +2,28 @@
namespace App\Interfaces\MarketData; namespace App\Interfaces\MarketData;
use App\Models\Holding;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Scheb\YahooFinanceApi\ApiClientFactory; use Scheb\YahooFinanceApi\ApiClientFactory;
class YahooMarketData implements MarketDataInterface class YahooMarketData implements MarketDataInterface
{ {
// api client
public $client; public $client;
public function __construct() { public function __construct() {
// create yahoo finance client factory // create yahoo finance client factory
$this->client = ApiClientFactory::createApiClient(); $this->client = ApiClientFactory::createApiClient();
} }
public function exists(String $symbol): Bool public function exists(String $symbol): Bool
{ {
return $this->quote($symbol)->isNotEmpty(); return $this->quote($symbol)->isNotEmpty();
} }
public function quote($symbol): Collection public function quote($symbol): Collection
{ {
$quote = $this->client->getQuote($symbol); $quote = $this->client->getQuote($symbol);
if (empty($quote)) return collect(); if (empty($quote)) return collect();
@@ -33,13 +34,18 @@ class YahooMarketData implements MarketDataInterface
'market_value' => $quote->getRegularMarketPrice(), 'market_value' => $quote->getRegularMarketPrice(),
'fifty_two_week_high' => $quote->getFiftyTwoWeekHigh(), 'fifty_two_week_high' => $quote->getFiftyTwoWeekHigh(),
'fifty_two_week_low' => $quote->getFiftyTwoWeekLow(), 'fifty_two_week_low' => $quote->getFiftyTwoWeekLow(),
'forward_pe' => $quote->getForwardPE(),
'trailing_pe' => $quote->getTrailingPE(),
'market_cap' => $quote->getMarketCap()
]); ]);
} }
public function dividends($symbol, $startDate, $endDate): Collection public function dividends($symbol, $startDate, $endDate): Collection
{ {
return collect($this->client->getHistoricalDividendData($symbol, $startDate, $endDate)) return collect($this->client->getHistoricalDividendData($symbol, $startDate, $endDate))
->map(function($dividend) use ($symbol) { ->map(function($dividend) use ($symbol) {
return [ return [
'symbol' => $symbol, 'symbol' => $symbol,
'date' => $dividend->getDate()->format('Y-m-d H:i:s'), 'date' => $dividend->getDate()->format('Y-m-d H:i:s'),
@@ -50,6 +56,7 @@ class YahooMarketData implements MarketDataInterface
public function splits($symbol, $startDate, $endDate): Collection public function splits($symbol, $startDate, $endDate): Collection
{ {
return collect($this->client->getHistoricalSplitData($symbol, $startDate, $endDate)) return collect($this->client->getHistoricalSplitData($symbol, $startDate, $endDate))
->map(function($split) use ($symbol) { ->map(function($split) use ($symbol) {
$split_amount = explode(':', $split->getStockSplits()); $split_amount = explode(':', $split->getStockSplits());
+18 -10
View File
@@ -14,11 +14,6 @@ class Holding extends Model
protected $with = ['market_data']; protected $with = ['market_data'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [ protected $fillable = [
'portfolio_id', 'portfolio_id',
'symbol', 'symbol',
@@ -31,16 +26,29 @@ class Holding extends Model
'dividends_synced_at' 'dividends_synced_at'
]; ];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [ protected $casts = [
'splits_synced_at' => 'datetime', 'splits_synced_at' => 'datetime',
'dividends_synced_at' => 'datetime', 'dividends_synced_at' => 'datetime',
]; ];
protected $appends = [
'market_gain_percent'
];
/**
* Append the market gain / loss percent attribute
*
* @return int
*
*/
public function getMarketGainPercentAttribute()
{
return (int) !empty($this->market_data?->market_value) && !empty($this->average_cost_basis)
? (($this->market_data->market_value - $this->average_cost_basis) / $this->average_cost_basis) * 100
: 0;
}
/** /**
* Market data for holding * Market data for holding
* *
+10 -5
View File
@@ -25,6 +25,9 @@ class MarketData extends Model
'market_value', 'market_value',
'fifty_two_week_high', 'fifty_two_week_high',
'fifty_two_week_low', 'fifty_two_week_low',
'forward_pe',
'trailing_pe',
'market_cap'
]; ];
public static function setSplitsHoldingSynced($symbol) public static function setSplitsHoldingSynced($symbol)
@@ -49,15 +52,17 @@ class MarketData extends Model
]); ]);
// check if new or stale // check if new or stale
if (!$market_data->exists || now()->diffInMinutes($market_data->updated_at) >= config('market_data.refresh')) { if (
!$market_data->exists
|| is_null($market_data->updated_at)
|| $market_data->updated_at->diffInMinutes(now()) >= config('market_data.refresh')
) {
// get quote // get quote
// $quote = app(MarketDataInterface::class)->quote($symbol); $quote = app(MarketDataInterface::class)->quote($symbol);
// fill data // fill data
// $market_data->fill($quote->toArray()); $market_data->fill($quote->toArray());
} }
// save with timestamps updated // save with timestamps updated
+12
View File
@@ -3,6 +3,7 @@
namespace App\Models; namespace App\Models;
use App\Models\MarketData; use App\Models\MarketData;
use Illuminate\Support\Arr;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Concerns\HasUuids; use Illuminate\Database\Eloquent\Concerns\HasUuids;
@@ -143,6 +144,17 @@ class Transaction extends Model
* @return void * @return void
*/ */
public function syncHolding() { public function syncHolding() {
// sync previous symbol too
if (Arr::has($this->changes, 'symbol')) {
$temp = new Transaction;
$temp->symbol = $this->original['symbol'];
$temp->portfolio_id = $this->portfolio_id;
$temp->syncHolding();
}
// get the holding for a symbol and portfolio (or create one) // get the holding for a symbol and portfolio (or create one)
$holding = Holding::firstOrNew([ $holding = Holding::firstOrNew([
'portfolio_id' => $this->portfolio_id, 'portfolio_id' => $this->portfolio_id,
+10 -1
View File
@@ -11,7 +11,16 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function register(): void public function register(): void
{ {
//
$market_data = config(
"market_data." .
config('market_data.default', 'yahoo')
);
$this->app->bind(
\App\Interfaces\MarketData\MarketDataInterface::class,
$market_data
);
} }
/** /**
+45
View File
@@ -0,0 +1,45 @@
<?php
namespace App\Rules;
use App\Interfaces\MarketData\MarketDataInterface;
use App\Models\MarketData;
use Illuminate\Contracts\Validation\ValidationRule;
class SymbolValidationRule implements ValidationRule
{
public $symbol;
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Validate the attribute.
*
* @param string $attribute
* @param mixed $value
* @param \Closure $fail
* @return void
*/
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$this->symbol = $value;
if (MarketData::find($this->symbol)) {
return;
}
// Check if the symbol exists in the Market Data table first (avoid API call)
if (!app(MarketDataInterface::class)->exists($value)) {
$fail('The symbol provided (' . $this->symbol . ') is not valid');
}
}
}
+1
View File
@@ -15,6 +15,7 @@
"maatwebsite/excel": "^3.1", "maatwebsite/excel": "^3.1",
"predis/predis": "^2.2", "predis/predis": "^2.2",
"robsontenorio/mary": "^1.35", "robsontenorio/mary": "^1.35",
"scheb/yahoo-finance-api": "^4.10",
"staudenmeir/eloquent-has-many-deep": "^1.20" "staudenmeir/eloquent-has-many-deep": "^1.20"
}, },
"require-dev": { "require-dev": {
Generated
+196 -140
View File
@@ -4,7 +4,7 @@
"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": "87ff0113a9121d64fb4518b040767e96", "content-hash": "3d6ea585015c0a9442f1faf0d5c9b141",
"packages": [ "packages": [
{ {
"name": "bacon/bacon-qr-code", "name": "bacon/bacon-qr-code",
@@ -131,16 +131,16 @@
}, },
{ {
"name": "blade-ui-kit/blade-icons", "name": "blade-ui-kit/blade-icons",
"version": "1.7.0", "version": "1.7.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/blade-ui-kit/blade-icons.git", "url": "https://github.com/blade-ui-kit/blade-icons.git",
"reference": "74275f44c71e815b85bf7cea66e3bf98c57fb7e4" "reference": "8f787baf09d88cdfd6ec4dbaba11ebfa885f0595"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/74275f44c71e815b85bf7cea66e3bf98c57fb7e4", "url": "https://api.github.com/repos/blade-ui-kit/blade-icons/zipball/8f787baf09d88cdfd6ec4dbaba11ebfa885f0595",
"reference": "74275f44c71e815b85bf7cea66e3bf98c57fb7e4", "reference": "8f787baf09d88cdfd6ec4dbaba11ebfa885f0595",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -208,7 +208,7 @@
"type": "paypal" "type": "paypal"
} }
], ],
"time": "2024-07-29T21:49:30+00:00" "time": "2024-08-14T14:25:11+00:00"
}, },
{ {
"name": "brick/math", "name": "brick/math",
@@ -422,23 +422,23 @@
}, },
{ {
"name": "dasprid/enum", "name": "dasprid/enum",
"version": "1.0.5", "version": "1.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/DASPRiD/Enum.git", "url": "https://github.com/DASPRiD/Enum.git",
"reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016" "reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/DASPRiD/Enum/zipball/6faf451159fb8ba4126b925ed2d78acfce0dc016", "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/8dfd07c6d2cf31c8da90c53b83c026c7696dda90",
"reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016", "reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1 <9.0" "php": ">=7.1 <9.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^7 | ^8 | ^9", "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11",
"squizlabs/php_codesniffer": "*" "squizlabs/php_codesniffer": "*"
}, },
"type": "library", "type": "library",
@@ -466,9 +466,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/DASPRiD/Enum/issues", "issues": "https://github.com/DASPRiD/Enum/issues",
"source": "https://github.com/DASPRiD/Enum/tree/1.0.5" "source": "https://github.com/DASPRiD/Enum/tree/1.0.6"
}, },
"time": "2023-08-25T16:18:39+00:00" "time": "2024-08-09T14:30:48+00:00"
}, },
{ {
"name": "dflydev/dot-access-data", "name": "dflydev/dot-access-data",
@@ -1685,16 +1685,16 @@
}, },
{ {
"name": "laravel/fortify", "name": "laravel/fortify",
"version": "v1.22.0", "version": "v1.24.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/fortify.git", "url": "https://github.com/laravel/fortify.git",
"reference": "33f8af0d4d11c4d30c47b450d097815d0eebd665" "reference": "fbe67f018c1fe26d00913de56a6d60589b4be9b2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/fortify/zipball/33f8af0d4d11c4d30c47b450d097815d0eebd665", "url": "https://api.github.com/repos/laravel/fortify/zipball/fbe67f018c1fe26d00913de56a6d60589b4be9b2",
"reference": "33f8af0d4d11c4d30c47b450d097815d0eebd665", "reference": "fbe67f018c1fe26d00913de56a6d60589b4be9b2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1746,20 +1746,20 @@
"issues": "https://github.com/laravel/fortify/issues", "issues": "https://github.com/laravel/fortify/issues",
"source": "https://github.com/laravel/fortify" "source": "https://github.com/laravel/fortify"
}, },
"time": "2024-07-22T14:37:15+00:00" "time": "2024-08-20T14:43:56+00:00"
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v11.18.1", "version": "v11.21.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8" "reference": "9d9d36708d56665b12185493f684abce38ad2d30"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/b19ba518c56852567e99fbae9321bc436c2cc5a8", "url": "https://api.github.com/repos/laravel/framework/zipball/9d9d36708d56665b12185493f684abce38ad2d30",
"reference": "b19ba518c56852567e99fbae9321bc436c2cc5a8", "reference": "9d9d36708d56665b12185493f684abce38ad2d30",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1952,20 +1952,20 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2024-07-26T10:39:29+00:00" "time": "2024-08-20T15:00:52+00:00"
}, },
{ {
"name": "laravel/jetstream", "name": "laravel/jetstream",
"version": "v5.1.4", "version": "v5.1.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/jetstream.git", "url": "https://github.com/laravel/jetstream.git",
"reference": "0eecfe8554e934d15c73cba5fd6c7f30ed640f3d" "reference": "653a422fe65278c1c4f319e99d5cb700c4117ea0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/jetstream/zipball/0eecfe8554e934d15c73cba5fd6c7f30ed640f3d", "url": "https://api.github.com/repos/laravel/jetstream/zipball/653a422fe65278c1c4f319e99d5cb700c4117ea0",
"reference": "0eecfe8554e934d15c73cba5fd6c7f30ed640f3d", "reference": "653a422fe65278c1c4f319e99d5cb700c4117ea0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2019,20 +2019,20 @@
"issues": "https://github.com/laravel/jetstream/issues", "issues": "https://github.com/laravel/jetstream/issues",
"source": "https://github.com/laravel/jetstream" "source": "https://github.com/laravel/jetstream"
}, },
"time": "2024-07-10T19:01:59+00:00" "time": "2024-08-08T13:28:23+00:00"
}, },
{ {
"name": "laravel/prompts", "name": "laravel/prompts",
"version": "v0.1.24", "version": "v0.1.25",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/prompts.git", "url": "https://github.com/laravel/prompts.git",
"reference": "409b0b4305273472f3754826e68f4edbd0150149" "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/prompts/zipball/409b0b4305273472f3754826e68f4edbd0150149", "url": "https://api.github.com/repos/laravel/prompts/zipball/7b4029a84c37cb2725fc7f011586e2997040bc95",
"reference": "409b0b4305273472f3754826e68f4edbd0150149", "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2075,9 +2075,9 @@
"description": "Add beautiful and user-friendly forms to your command-line applications.", "description": "Add beautiful and user-friendly forms to your command-line applications.",
"support": { "support": {
"issues": "https://github.com/laravel/prompts/issues", "issues": "https://github.com/laravel/prompts/issues",
"source": "https://github.com/laravel/prompts/tree/v0.1.24" "source": "https://github.com/laravel/prompts/tree/v0.1.25"
}, },
"time": "2024-06-17T13:58:22+00:00" "time": "2024-08-12T22:06:33+00:00"
}, },
{ {
"name": "laravel/sanctum", "name": "laravel/sanctum",
@@ -2145,26 +2145,27 @@
}, },
{ {
"name": "laravel/serializable-closure", "name": "laravel/serializable-closure",
"version": "v1.3.3", "version": "v1.3.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/serializable-closure.git", "url": "https://github.com/laravel/serializable-closure.git",
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754" "reference": "61b87392d986dc49ad5ef64e75b1ff5fee24ef81"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754", "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/61b87392d986dc49ad5ef64e75b1ff5fee24ef81",
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754", "reference": "61b87392d986dc49ad5ef64e75b1ff5fee24ef81",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.3|^8.0" "php": "^7.3|^8.0"
}, },
"require-dev": { "require-dev": {
"nesbot/carbon": "^2.61", "illuminate/support": "^8.0|^9.0|^10.0|^11.0",
"nesbot/carbon": "^2.61|^3.0",
"pestphp/pest": "^1.21.3", "pestphp/pest": "^1.21.3",
"phpstan/phpstan": "^1.8.2", "phpstan/phpstan": "^1.8.2",
"symfony/var-dumper": "^5.4.11" "symfony/var-dumper": "^5.4.11|^6.2.0|^7.0.0"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@@ -2201,7 +2202,7 @@
"issues": "https://github.com/laravel/serializable-closure/issues", "issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure" "source": "https://github.com/laravel/serializable-closure"
}, },
"time": "2023-11-08T14:08:06+00:00" "time": "2024-08-02T07:48:17+00:00"
}, },
{ {
"name": "laravel/tinker", "name": "laravel/tinker",
@@ -2271,16 +2272,16 @@
}, },
{ {
"name": "league/commonmark", "name": "league/commonmark",
"version": "2.5.1", "version": "2.5.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/commonmark.git", "url": "https://github.com/thephpleague/commonmark.git",
"reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c" "reference": "b650144166dfa7703e62a22e493b853b58d874b0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/ac815920de0eff6de947eac0a6a94e5ed0fb147c", "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0",
"reference": "ac815920de0eff6de947eac0a6a94e5ed0fb147c", "reference": "b650144166dfa7703e62a22e493b853b58d874b0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2293,8 +2294,8 @@
}, },
"require-dev": { "require-dev": {
"cebe/markdown": "^1.0", "cebe/markdown": "^1.0",
"commonmark/cmark": "0.31.0", "commonmark/cmark": "0.31.1",
"commonmark/commonmark.js": "0.31.0", "commonmark/commonmark.js": "0.31.1",
"composer/package-versions-deprecated": "^1.8", "composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4", "embed/embed": "^4.4",
"erusev/parsedown": "^1.0", "erusev/parsedown": "^1.0",
@@ -2373,7 +2374,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-24T12:52:09+00:00" "time": "2024-08-16T11:46:16+00:00"
}, },
{ {
"name": "league/config", "name": "league/config",
@@ -2647,16 +2648,16 @@
}, },
{ {
"name": "livewire/livewire", "name": "livewire/livewire",
"version": "v3.5.4", "version": "v3.5.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/livewire/livewire.git", "url": "https://github.com/livewire/livewire.git",
"reference": "b158c6386a892efc6c5e4682e682829baac1f933" "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/livewire/livewire/zipball/b158c6386a892efc6c5e4682e682829baac1f933", "url": "https://api.github.com/repos/livewire/livewire/zipball/597a2808d8d3001cc3ed5ce89a6ebab00f83b80f",
"reference": "b158c6386a892efc6c5e4682e682829baac1f933", "reference": "597a2808d8d3001cc3ed5ce89a6ebab00f83b80f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2664,6 +2665,7 @@
"illuminate/routing": "^10.0|^11.0", "illuminate/routing": "^10.0|^11.0",
"illuminate/support": "^10.0|^11.0", "illuminate/support": "^10.0|^11.0",
"illuminate/validation": "^10.0|^11.0", "illuminate/validation": "^10.0|^11.0",
"laravel/prompts": "^0.1.24",
"league/mime-type-detection": "^1.9", "league/mime-type-detection": "^1.9",
"php": "^8.1", "php": "^8.1",
"symfony/console": "^6.0|^7.0", "symfony/console": "^6.0|^7.0",
@@ -2672,7 +2674,6 @@
"require-dev": { "require-dev": {
"calebporzio/sushi": "^2.1", "calebporzio/sushi": "^2.1",
"laravel/framework": "^10.15.0|^11.0", "laravel/framework": "^10.15.0|^11.0",
"laravel/prompts": "^0.1.6",
"mockery/mockery": "^1.3.1", "mockery/mockery": "^1.3.1",
"orchestra/testbench": "^8.21.0|^9.0", "orchestra/testbench": "^8.21.0|^9.0",
"orchestra/testbench-dusk": "^8.24|^9.1", "orchestra/testbench-dusk": "^8.24|^9.1",
@@ -2711,7 +2712,7 @@
"description": "A front-end framework for Laravel.", "description": "A front-end framework for Laravel.",
"support": { "support": {
"issues": "https://github.com/livewire/livewire/issues", "issues": "https://github.com/livewire/livewire/issues",
"source": "https://github.com/livewire/livewire/tree/v3.5.4" "source": "https://github.com/livewire/livewire/tree/v3.5.6"
}, },
"funding": [ "funding": [
{ {
@@ -2719,7 +2720,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-15T18:27:32+00:00" "time": "2024-08-19T11:52:18+00:00"
}, },
{ {
"name": "livewire/volt", "name": "livewire/volt",
@@ -2795,16 +2796,16 @@
}, },
{ {
"name": "maatwebsite/excel", "name": "maatwebsite/excel",
"version": "3.1.55", "version": "3.1.56",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/SpartnerNL/Laravel-Excel.git", "url": "https://github.com/SpartnerNL/Laravel-Excel.git",
"reference": "6d9d791dcdb01a9b6fd6f48d46f0d5fff86e6260" "reference": "0381d0225b42c3f328d90f0dd05ca071fca3953f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/6d9d791dcdb01a9b6fd6f48d46f0d5fff86e6260", "url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/0381d0225b42c3f328d90f0dd05ca071fca3953f",
"reference": "6d9d791dcdb01a9b6fd6f48d46f0d5fff86e6260", "reference": "0381d0225b42c3f328d90f0dd05ca071fca3953f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2860,7 +2861,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues", "issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.55" "source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.56"
}, },
"funding": [ "funding": [
{ {
@@ -2872,7 +2873,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-02-20T08:27:10+00:00" "time": "2024-08-19T09:40:43+00:00"
}, },
{ {
"name": "maennchen/zipstream-php", "name": "maennchen/zipstream-php",
@@ -3229,16 +3230,16 @@
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "3.7.0", "version": "3.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139" "reference": "bbd3eef89af8ba66a3aa7952b5439168fbcc529f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cb4374784c87d0a0294e8513a52eb63c0aff3139", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bbd3eef89af8ba66a3aa7952b5439168fbcc529f",
"reference": "cb4374784c87d0a0294e8513a52eb63c0aff3139", "reference": "bbd3eef89af8ba66a3aa7952b5439168fbcc529f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3331,7 +3332,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-16T22:29:20+00:00" "time": "2024-08-19T06:22:39+00:00"
}, },
{ {
"name": "nette/schema", "name": "nette/schema",
@@ -3397,20 +3398,20 @@
}, },
{ {
"name": "nette/utils", "name": "nette/utils",
"version": "v4.0.4", "version": "v4.0.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nette/utils.git", "url": "https://github.com/nette/utils.git",
"reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218" "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218", "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
"reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218", "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.0 <8.4" "php": "8.0 - 8.4"
}, },
"conflict": { "conflict": {
"nette/finder": "<3", "nette/finder": "<3",
@@ -3477,9 +3478,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nette/utils/issues", "issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.4" "source": "https://github.com/nette/utils/tree/v4.0.5"
}, },
"time": "2024-01-17T16:50:36+00:00" "time": "2024-08-07T15:39:19+00:00"
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
@@ -4300,16 +4301,16 @@
}, },
{ {
"name": "psr/log", "name": "psr/log",
"version": "3.0.0", "version": "3.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/log.git", "url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" "reference": "79dff0b268932c640297f5208d6298f71855c03e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "reference": "79dff0b268932c640297f5208d6298f71855c03e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4344,9 +4345,9 @@
"psr-3" "psr-3"
], ],
"support": { "support": {
"source": "https://github.com/php-fig/log/tree/3.0.0" "source": "https://github.com/php-fig/log/tree/3.0.1"
}, },
"time": "2021-07-14T16:46:02+00:00" "time": "2024-08-21T13:31:24+00:00"
}, },
{ {
"name": "psr/simple-cache", "name": "psr/simple-cache",
@@ -4705,16 +4706,16 @@
}, },
{ {
"name": "robsontenorio/mary", "name": "robsontenorio/mary",
"version": "1.35.3", "version": "1.35.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/robsontenorio/mary.git", "url": "https://github.com/robsontenorio/mary.git",
"reference": "5b641d64b8cd2f8602758eb0e2c6ad0ae68cb6a9" "reference": "46294f8e692836109011b0264e006adb49bf2506"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/robsontenorio/mary/zipball/5b641d64b8cd2f8602758eb0e2c6ad0ae68cb6a9", "url": "https://api.github.com/repos/robsontenorio/mary/zipball/46294f8e692836109011b0264e006adb49bf2506",
"reference": "5b641d64b8cd2f8602758eb0e2c6ad0ae68cb6a9", "reference": "46294f8e692836109011b0264e006adb49bf2506",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4780,7 +4781,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/robsontenorio/mary/issues", "issues": "https://github.com/robsontenorio/mary/issues",
"source": "https://github.com/robsontenorio/mary/tree/1.35.3" "source": "https://github.com/robsontenorio/mary/tree/1.35.6"
}, },
"funding": [ "funding": [
{ {
@@ -4788,7 +4789,62 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-26T15:41:31+00:00" "time": "2024-08-17T21:24:32+00:00"
},
{
"name": "scheb/yahoo-finance-api",
"version": "v4.10.1",
"source": {
"type": "git",
"url": "https://github.com/scheb/yahoo-finance-api.git",
"reference": "9a43debe17ce90a9aeea9c998aa1ecce2bd9f8ed"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scheb/yahoo-finance-api/zipball/9a43debe17ce90a9aeea9c998aa1ecce2bd9f8ed",
"reference": "9a43debe17ce90a9aeea9c998aa1ecce2bd9f8ed",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/guzzle": "^6.0|^7.0",
"php": ">=7.1.3"
},
"require-dev": {
"escapestudios/symfony2-coding-standard": "^3.9",
"phpunit/phpunit": "^7.5 || ^8 || ^9",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^3.11|^4.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Scheb\\YahooFinanceApi\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Scheb",
"email": "me@christianscheb.de"
}
],
"description": "PHP library for accessing Yahoo Finance data",
"homepage": "https://github.com/scheb/yahoo-finance-api",
"keywords": [
"api",
"finance",
"stock",
"yahoo"
],
"support": {
"issues": "https://github.com/scheb/yahoo-finance-api/issues",
"source": "https://github.com/scheb/yahoo-finance-api/tree/v4.10.1"
},
"time": "2024-06-09T11:50:56+00:00"
}, },
{ {
"name": "staudenmeir/eloquent-has-many-deep", "name": "staudenmeir/eloquent-has-many-deep",
@@ -7656,16 +7712,16 @@
}, },
{ {
"name": "laravel/pint", "name": "laravel/pint",
"version": "v1.17.0", "version": "v1.17.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/pint.git", "url": "https://github.com/laravel/pint.git",
"reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5" "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", "url": "https://api.github.com/repos/laravel/pint/zipball/e8a88130a25e3f9d4d5785e6a1afca98268ab110",
"reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5", "reference": "e8a88130a25e3f9d4d5785e6a1afca98268ab110",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -7676,13 +7732,13 @@
"php": "^8.1.0" "php": "^8.1.0"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^3.59.3", "friendsofphp/php-cs-fixer": "^3.61.1",
"illuminate/view": "^10.48.12", "illuminate/view": "^10.48.18",
"larastan/larastan": "^2.9.7", "larastan/larastan": "^2.9.8",
"laravel-zero/framework": "^10.4.0", "laravel-zero/framework": "^10.4.0",
"mockery/mockery": "^1.6.12", "mockery/mockery": "^1.6.12",
"nunomaduro/termwind": "^1.15.1", "nunomaduro/termwind": "^1.15.1",
"pestphp/pest": "^2.34.8" "pestphp/pest": "^2.35.0"
}, },
"bin": [ "bin": [
"builds/pint" "builds/pint"
@@ -7718,20 +7774,20 @@
"issues": "https://github.com/laravel/pint/issues", "issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint" "source": "https://github.com/laravel/pint"
}, },
"time": "2024-07-23T16:40:20+00:00" "time": "2024-08-06T15:11:54+00:00"
}, },
{ {
"name": "laravel/sail", "name": "laravel/sail",
"version": "v1.31.0", "version": "v1.31.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/sail.git", "url": "https://github.com/laravel/sail.git",
"reference": "48d89608a3bb5be763c9bb87121d31e7da27c1cb" "reference": "3d06dd18cee8059baa7b388af00ba47f6d96bd85"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/sail/zipball/48d89608a3bb5be763c9bb87121d31e7da27c1cb", "url": "https://api.github.com/repos/laravel/sail/zipball/3d06dd18cee8059baa7b388af00ba47f6d96bd85",
"reference": "48d89608a3bb5be763c9bb87121d31e7da27c1cb", "reference": "3d06dd18cee8059baa7b388af00ba47f6d96bd85",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -7781,7 +7837,7 @@
"issues": "https://github.com/laravel/sail/issues", "issues": "https://github.com/laravel/sail/issues",
"source": "https://github.com/laravel/sail" "source": "https://github.com/laravel/sail"
}, },
"time": "2024-07-22T14:36:50+00:00" "time": "2024-08-02T07:45:47+00:00"
}, },
{ {
"name": "mockery/mockery", "name": "mockery/mockery",
@@ -7928,23 +7984,23 @@
}, },
{ {
"name": "nunomaduro/collision", "name": "nunomaduro/collision",
"version": "v8.3.0", "version": "v8.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nunomaduro/collision.git", "url": "https://github.com/nunomaduro/collision.git",
"reference": "b49f5b2891ce52726adfd162841c69d4e4c84229" "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/b49f5b2891ce52726adfd162841c69d4e4c84229", "url": "https://api.github.com/repos/nunomaduro/collision/zipball/e7d1aa8ed753f63fa816932bbc89678238843b4a",
"reference": "b49f5b2891ce52726adfd162841c69d4e4c84229", "reference": "e7d1aa8ed753f63fa816932bbc89678238843b4a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"filp/whoops": "^2.15.4", "filp/whoops": "^2.15.4",
"nunomaduro/termwind": "^2.0.1", "nunomaduro/termwind": "^2.0.1",
"php": "^8.2.0", "php": "^8.2.0",
"symfony/console": "^7.1.2" "symfony/console": "^7.1.3"
}, },
"conflict": { "conflict": {
"laravel/framework": "<11.0.0 || >=12.0.0", "laravel/framework": "<11.0.0 || >=12.0.0",
@@ -7952,13 +8008,13 @@
}, },
"require-dev": { "require-dev": {
"larastan/larastan": "^2.9.8", "larastan/larastan": "^2.9.8",
"laravel/framework": "^11.16.0", "laravel/framework": "^11.19.0",
"laravel/pint": "^1.16.2", "laravel/pint": "^1.17.1",
"laravel/sail": "^1.30.2", "laravel/sail": "^1.31.0",
"laravel/sanctum": "^4.0.2", "laravel/sanctum": "^4.0.2",
"laravel/tinker": "^2.9.0", "laravel/tinker": "^2.9.0",
"orchestra/testbench-core": "^9.2.1", "orchestra/testbench-core": "^9.2.3",
"pestphp/pest": "^2.34.9 || ^3.0.0", "pestphp/pest": "^2.35.0 || ^3.0.0",
"sebastian/environment": "^6.1.0 || ^7.0.0" "sebastian/environment": "^6.1.0 || ^7.0.0"
}, },
"type": "library", "type": "library",
@@ -8021,7 +8077,7 @@
"type": "patreon" "type": "patreon"
} }
], ],
"time": "2024-07-16T22:41:01+00:00" "time": "2024-08-03T15:32:23+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
@@ -8143,32 +8199,32 @@
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "11.0.5", "version": "11.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861" "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/19b6365ab8b59a64438c0c3f4241feeb480c9861", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ebdffc9e09585dafa71b9bffcdb0a229d4704c45",
"reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861", "reference": "ebdffc9e09585dafa71b9bffcdb0a229d4704c45",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-dom": "*", "ext-dom": "*",
"ext-libxml": "*", "ext-libxml": "*",
"ext-xmlwriter": "*", "ext-xmlwriter": "*",
"nikic/php-parser": "^5.0", "nikic/php-parser": "^5.1.0",
"php": ">=8.2", "php": ">=8.2",
"phpunit/php-file-iterator": "^5.0", "phpunit/php-file-iterator": "^5.0.1",
"phpunit/php-text-template": "^4.0", "phpunit/php-text-template": "^4.0.1",
"sebastian/code-unit-reverse-lookup": "^4.0", "sebastian/code-unit-reverse-lookup": "^4.0.1",
"sebastian/complexity": "^4.0", "sebastian/complexity": "^4.0.1",
"sebastian/environment": "^7.0", "sebastian/environment": "^7.2.0",
"sebastian/lines-of-code": "^3.0", "sebastian/lines-of-code": "^3.0.1",
"sebastian/version": "^5.0", "sebastian/version": "^5.0.1",
"theseer/tokenizer": "^1.2.0" "theseer/tokenizer": "^1.2.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^11.0" "phpunit/phpunit": "^11.0"
@@ -8180,7 +8236,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "11.0-dev" "dev-main": "11.0.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -8209,7 +8265,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.5" "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.6"
}, },
"funding": [ "funding": [
{ {
@@ -8217,7 +8273,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-03T05:05:37+00:00" "time": "2024-08-22T04:37:56+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
@@ -8466,16 +8522,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "11.2.8", "version": "11.3.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39" "reference": "fe179875ef0c14e90b75617002767eae0a742641"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a7a29e8d3113806f18f99d670f580a30e8ffff39", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fe179875ef0c14e90b75617002767eae0a742641",
"reference": "a7a29e8d3113806f18f99d670f580a30e8ffff39", "reference": "fe179875ef0c14e90b75617002767eae0a742641",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -8496,7 +8552,7 @@
"phpunit/php-timer": "^7.0.1", "phpunit/php-timer": "^7.0.1",
"sebastian/cli-parser": "^3.0.2", "sebastian/cli-parser": "^3.0.2",
"sebastian/code-unit": "^3.0.1", "sebastian/code-unit": "^3.0.1",
"sebastian/comparator": "^6.0.1", "sebastian/comparator": "^6.0.2",
"sebastian/diff": "^6.0.2", "sebastian/diff": "^6.0.2",
"sebastian/environment": "^7.2.0", "sebastian/environment": "^7.2.0",
"sebastian/exporter": "^6.1.3", "sebastian/exporter": "^6.1.3",
@@ -8514,7 +8570,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "11.2-dev" "dev-main": "11.3-dev"
} }
}, },
"autoload": { "autoload": {
@@ -8546,7 +8602,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.8" "source": "https://github.com/sebastianbergmann/phpunit/tree/11.3.1"
}, },
"funding": [ "funding": [
{ {
@@ -8562,7 +8618,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-07-18T14:56:37+00:00" "time": "2024-08-13T06:14:23+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",
@@ -8736,16 +8792,16 @@
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "6.0.1", "version": "6.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "131942b86d3587291067a94f295498ab6ac79c20" "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/131942b86d3587291067a94f295498ab6ac79c20", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/450d8f237bd611c45b5acf0733ce43e6bb280f81",
"reference": "131942b86d3587291067a94f295498ab6ac79c20", "reference": "450d8f237bd611c45b5acf0733ce43e6bb280f81",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -8801,7 +8857,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues", "issues": "https://github.com/sebastianbergmann/comparator/issues",
"security": "https://github.com/sebastianbergmann/comparator/security/policy", "security": "https://github.com/sebastianbergmann/comparator/security/policy",
"source": "https://github.com/sebastianbergmann/comparator/tree/6.0.1" "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.2"
}, },
"funding": [ "funding": [
{ {
@@ -8809,7 +8865,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-03T04:48:07+00:00" "time": "2024-08-12T06:07:25+00:00"
}, },
{ {
"name": "sebastian/complexity", "name": "sebastian/complexity",
+11
View File
@@ -0,0 +1,11 @@
<?php
return [
'refresh' => 30, // minutes
'default' => env('MARKET_DATA_PROVIDER', 'yahoo'),
'yahoo' => App\Interfaces\MarketData\YahooMarketData::class,
// 'fake' => App\Interfaces\MarketData\FakeMarketData::class,
];
@@ -21,6 +21,11 @@ class CreateMarketDataTable extends Migration
$table->float('fifty_two_week_high', 12, 4)->nullable(); $table->float('fifty_two_week_high', 12, 4)->nullable();
$table->timestamp('last_dividend_date')->nullable(); $table->timestamp('last_dividend_date')->nullable();
$table->float('last_dividend_amount', 12, 4)->nullable(); $table->float('last_dividend_amount', 12, 4)->nullable();
$table->unsignedBigInteger('market_cap')->nullable();
$table->float('trailing_pe', 12, 4)->nullable();
$table->float('forward_pe', 12, 4)->nullable();
$table->float('pe_growth', 12, 4)->nullable();
$table->json('meta_data')->nullable();
$table->timestamps(); $table->timestamps();
}); });
} }
+81
View File
@@ -0,0 +1,81 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
class MarketDataSeeder extends Seeder
{
use WithoutModelEvents;
/**
* Run the database seeds.
*/
public function run(): void
{
$chunkSize = 500;
// Path to the CSV file
$csvFilePath = storage_path('app/market_data_seed.csv');
// Open the file in read mode
if (($handle = fopen($csvFilePath, 'r')) !== false) {
$header = null;
$rows = [];
$rowCount = 0;
while (($row = fgetcsv($handle, 0, ',')) !== false) {
if (!$header) {
// header must be the first row
$header = $row;
} else {
try {
$data = array_combine($header, $row);
$rows[] = [
'symbol' => $data['symbol'],
'name' => $data['name'],
'meta_data' => json_encode([
'country' => $data['country'],
'first_trade_year' => $data['first_trade_year'],
'sector' => $data['sector'],
'industry' => $data['industry'],
]),
];
$rowCount++;
if ($rowCount % $chunkSize == 0) {
DB::table('market_data')->insertOrIgnore($rows);
$rows = [];
}
} catch (\Throwable $e) {
throw new \Exception('Error: '. $e->getMessage());
}
}
}
// final clean up
if (!empty($rows)) {
DB::table('market_data')->insertOrIgnore($rows);
}
// Close the CSV file
fclose($handle);
echo "Imported $rowCount items successfully!\n";
} else {
echo "Failed to open the CSV.\n";
}
}
}
@@ -2,11 +2,11 @@
use App\Models\Transaction; use App\Models\Transaction;
use App\Models\Portfolio; use App\Models\Portfolio;
use App\Rules\SymbolValidationRule;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Livewire\Attributes\Rule; use Livewire\Attributes\{Computed};
use Livewire\Volt\Component; use Livewire\Volt\Component;
use Mary\Traits\Toast; use Mary\Traits\Toast;
use Livewire\Attributes\Computed;
new class extends Component { new class extends Component {
use Toast; use Toast;
@@ -15,27 +15,29 @@ new class extends Component {
public ?Portfolio $portfolio; public ?Portfolio $portfolio;
public ?Transaction $transaction; public ?Transaction $transaction;
#[Rule('required|string|max:15')]
public String $symbol; public String $symbol;
#[Rule('required|string|in:BUY,SELL')]
public String $transaction_type; public String $transaction_type;
#[Rule('required|date_format:Y-m-d')]
public String $date; public String $date;
#[Rule('required|min:0|numeric')]
public Float $quantity; public Float $quantity;
#[Rule('exclude_if:transaction_type,SELL|min:0|numeric')]
public ?Float $cost_basis; public ?Float $cost_basis;
#[Rule('exclude_if:transaction_type,BUY|min:0|numeric')]
public ?Float $sale_price; public ?Float $sale_price;
public Bool $confirmingTransactionDeletion = false; public Bool $confirmingTransactionDeletion = false;
// methods // methods
public function rules()
{
return [
'symbol' => ['required', 'string', new SymbolValidationRule],
'transaction_type' => 'required|string|in:BUY,SELL',
'date' => 'required|date_format:Y-m-d',
'quantity' => 'required|min:0|numeric',
'cost_basis' => 'exclude_if:transaction_type,SELL|min:0|numeric',
'sale_price' => 'exclude_if:transaction_type,BUY|min:0|numeric',
];
}
public function mount() public function mount()
{ {
if (isset($this->transaction)) { if (isset($this->transaction)) {
@@ -128,7 +130,13 @@ new class extends Component {
/> />
@endif @endif
<x-button label="{{ $transaction ? 'Update' : 'Create' }}" type="submit" icon="o-paper-airplane" class="btn-primary" spinner="save" /> <x-button
label="{{ $transaction ? 'Update' : 'Create' }}"
type="submit"
icon="o-paper-airplane"
class="btn-primary"
spinner="{{ $transaction ? 'update' : 'save' }}"
/>
</x-slot:actions> </x-slot:actions>
</x-form> </x-form>
@@ -17,7 +17,7 @@ new class extends Component {
<div class=""> <div class="">
@foreach( @foreach(
$holdings->sortBy('market_gain_percent') $holdings->sortByDesc('market_gain_percent')
->where('quantity', '>', 0) ->where('quantity', '>', 0)
->where('market_data.market_value', '>', 0) ->where('market_data.market_value', '>', 0)
->take(5) ->take(5)
@@ -29,17 +29,13 @@ new class extends Component {
link="{{ route('portfolio.show', ['portfolio' => $holding->portfolio_id]) }}" link="{{ route('portfolio.show', ['portfolio' => $holding->portfolio_id]) }}"
> >
@php
$gainPercent = (($holding->market_data->market_value - $holding->average_cost_basis) / $holding->average_cost_basis) * 100;
@endphp
<x-slot:value class="flex items-center"> <x-slot:value class="flex items-center">
{{ $holding->market_data?->name }} ({{ $holding->symbol }}) {{ $holding->market_data?->name }} ({{ $holding->symbol }})
<x-badge class="{{ $gainPercent > 0 ? 'badge-success' : 'badge-error' }} ml-2 badge-sm" > <x-badge class="{{ $holding->market_gain_percent > 0 ? 'badge-success' : 'badge-error' }} ml-2 badge-sm" >
<x-slot:value> <x-slot:value>
{{ Number::percentage($gainPercent) }} {{ Number::percentage($holding->market_gain_percent) }}
</x-slot:value> </x-slot:value>
</x-badge> </x-badge>