diff --git a/app/Console/Commands/SyncDailyChange.php b/app/Console/Commands/SyncDailyChange.php index dda0b35..58aee77 100644 --- a/app/Console/Commands/SyncDailyChange.php +++ b/app/Console/Commands/SyncDailyChange.php @@ -2,17 +2,21 @@ namespace App\Console\Commands; +use App\Models\Portfolio; use Illuminate\Console\Command; -use App\Interfaces\MarketData\MarketDataInterface; +use Illuminate\Contracts\Console\PromptsForMissingInput; +use function Laravel\Prompts\search; -class SyncDailyChange extends Command +class SyncDailyChange extends Command implements PromptsForMissingInput { /** * The name and signature of the console command. * * @var string */ - protected $signature = 'sync:daily-change'; + protected $signature = 'sync:daily-change + {portfolio_id : The ID of the portfolio to re-calculate.} + {--force : Don\'t ask to confirm.}'; /** * The console command description. @@ -21,6 +25,24 @@ class SyncDailyChange extends Command */ protected $description = 'Re-calculates daily snapshots of your portfolio\'s daily performance. Use discretion as this is a resource intensive command.'; + /** + * Prompt for missing input arguments using the returned questions. + * + * @return array + */ + protected function promptForMissingArgumentsUsing(): array + { + return [ + 'portfolio_id' => fn () => search( + label: 'Choose the portfolio you wish to re-calculate:', + placeholder: 'E.g. My favorite stocks', + options: fn ($value) => strlen($value) > 0 + ? Portfolio::where('title', 'like', "%{$value}%")->pluck('title', 'id')->all() + : [] + ), + ]; + } + /** * Create a new command instance. * @@ -38,7 +60,17 @@ class SyncDailyChange extends Command */ public function handle() { - // get history - // $history = app(MarketDataInterface::class)->history($symbol); + try { + + $portfolio = Portfolio::findOrFail($this->argument('portfolio_id')); + + $portfolio->syncDailyChanges(); + + $this->line('Awesome! Daily change history for '. $portfolio->title .' has been completed.'); + + } catch (\Throwable $e) { + + $this->error($e->getMessage()); + } } } diff --git a/app/Interfaces/MarketData/AlphaVantageMarketData.php b/app/Interfaces/MarketData/AlphaVantageMarketData.php index e1347dd..f388c3f 100644 --- a/app/Interfaces/MarketData/AlphaVantageMarketData.php +++ b/app/Interfaces/MarketData/AlphaVantageMarketData.php @@ -89,7 +89,7 @@ class AlphaVantageMarketData implements MarketDataInterface public function history($symbol, $startDate, $endDate): Collection { - $history = Alphavantage::timeSeries()->daily($symbol); + $history = Alphavantage::timeSeries()->daily($symbol, 'full'); $history = Arr::get($history, 'Time Series (Daily)', []); diff --git a/app/Models/Holding.php b/app/Models/Holding.php index 0fba5bc..5848841 100644 --- a/app/Models/Holding.php +++ b/app/Models/Holding.php @@ -232,7 +232,12 @@ class Holding extends Model $date_interval = "DATE_ADD(date, INTERVAL 1 DAY)"; if (config('database.default') === 'sqlite') { + $date_interval = "date(date, '+1 day')"; + + } else if (config('database.default') === 'mysql') { + + DB::statement('SET GLOBAL cte_max_recursion_depth = 20000;'); } return DB::table(DB::raw("( diff --git a/app/Models/Portfolio.php b/app/Models/Portfolio.php index fae8ed8..70beb99 100644 --- a/app/Models/Portfolio.php +++ b/app/Models/Portfolio.php @@ -98,15 +98,16 @@ class Portfolio extends Model $join->on('transactions.symbol', '=', 'holdings.symbol') ->where('transactions.portfolio_id', '=', $this->id); }) - ->select('holdings.*', DB::raw('min(transactions.date) as first_transaction_date')) // get first transaction date - ->groupBy('holdings.symbol') + ->select('holdings.symbol', 'holdings.portfolio_id', DB::raw('min(transactions.date) as first_transaction_date')) // get first transaction date + ->groupBy(['holdings.symbol', 'holdings.portfolio_id']) ->get(); $total_performance = []; $holdings->each(function($holding) use (&$total_performance) { - $all_history = app(MarketDataInterface::class)->history('ACME', $holding->first_transaction_date, now()); + $all_history = app(MarketDataInterface::class)->history($holding->symbol, $holding->first_transaction_date, now()); + $quantity = $holding->dailyPerformance($holding->first_transaction_date, now()); $dividends = $holding->dividends->keyBy(function ($dividend, $key) { @@ -150,8 +151,12 @@ class Portfolio extends Model } }); - $this->daily_change()->delete(); + if (!empty($total_performance)) { + DB::transaction(function () use ($total_performance) { + $this->daily_change()->delete(); - DailyChange::insert($total_performance); + DailyChange::insert($total_performance); + }); + } } }