adds feature to backfill daily change
This commit is contained in:
@@ -2,7 +2,10 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Interfaces\MarketData\MarketDataInterface;
|
||||
use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
@@ -74,7 +77,8 @@ class Portfolio extends Model
|
||||
return $this->users()->firstWhere('owner', 1)?->id;
|
||||
}
|
||||
|
||||
public static function syncUsers(self $model) {
|
||||
public static function syncUsers(self $model)
|
||||
{
|
||||
// make sure we don't remove owner access
|
||||
$user_id[$model->owner_id ?? auth()->user()->id] = ['owner' => true];
|
||||
|
||||
@@ -86,4 +90,68 @@ class Portfolio extends Model
|
||||
// save
|
||||
$model->users()->sync($user_id);
|
||||
}
|
||||
|
||||
public function syncDailyChanges(): void
|
||||
{
|
||||
$holdings = $this->holdings()
|
||||
->join('transactions', function($join) {
|
||||
$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')
|
||||
->get();
|
||||
|
||||
$total_performance = [];
|
||||
|
||||
$holdings->each(function($holding) use (&$total_performance) {
|
||||
|
||||
$all_history = app(MarketDataInterface::class)->history('ACME', $holding->first_transaction_date, now());
|
||||
$quantity = $holding->dailyPerformance($holding->first_transaction_date, now());
|
||||
|
||||
$dividends = $holding->dividends->keyBy(function ($dividend, $key) {
|
||||
return $dividend['date']->format('Y-m-d');
|
||||
})->toArray();
|
||||
|
||||
$dividends_earned = 0;
|
||||
$daily_performance = [];
|
||||
|
||||
$all_history->sortBy('date')->each(function ($history, $date) use ($quantity, $dividends, &$daily_performance, &$dividends_earned) {
|
||||
|
||||
$close = Arr::get($history, 'close', 0);
|
||||
$total_market_value = $quantity->get($date)->owned * $close;
|
||||
$dividend = Arr::get($dividends, $date, []);
|
||||
$dividends_earned += $quantity->get($date)->owned * Arr::get($dividend, 'dividend_amount', 0);
|
||||
|
||||
$daily_performance[$date] = [
|
||||
'date' => $date,
|
||||
'portfolio_id' => $this->id,
|
||||
'total_market_value' => $total_market_value,
|
||||
'total_cost_basis' => $quantity->get($date)->cost_basis,
|
||||
'total_gain' => $total_market_value - $quantity->get($date)->cost_basis,
|
||||
'realized_gains' => $quantity->get($date)->realized_gains,
|
||||
'total_dividends_earned' => $dividends_earned
|
||||
];
|
||||
});
|
||||
|
||||
foreach ($daily_performance as $date => $performance) {
|
||||
if (!isset($total_performance[$date])) {
|
||||
|
||||
$total_performance[$date] = $performance;
|
||||
|
||||
} else {
|
||||
|
||||
$total_performance[$date]['total_market_value'] += $performance['total_market_value'];
|
||||
$total_performance[$date]['total_cost_basis'] += $performance['total_cost_basis'];
|
||||
$total_performance[$date]['total_gain'] += $performance['total_gain'];
|
||||
$total_performance[$date]['realized_gains'] += $performance['realized_gains'];
|
||||
$total_performance[$date]['total_dividends_earned'] += $performance['total_dividends_earned'];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$this->daily_change()->delete();
|
||||
|
||||
DailyChange::insert($total_performance);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user