yXyX
This commit is contained in:
@@ -14,8 +14,9 @@ final class AnalyticsService
|
||||
$this->fx = $fx;
|
||||
}
|
||||
|
||||
public function enrichMeasurements(array $measurements, array $settings): array
|
||||
public function enrichMeasurements(array $measurements, array $settings, array $options = []): array
|
||||
{
|
||||
$fullLatestOnly = !empty($options['full_latest_only']);
|
||||
$baselineCoins = (float) ($settings['baseline_coins_total'] ?? 0.0);
|
||||
$baselineAt = (string) ($settings['baseline_measured_at'] ?? '');
|
||||
$costPlans = is_array($settings['cost_plans'] ?? null) ? $settings['cost_plans'] : [];
|
||||
@@ -38,9 +39,11 @@ final class AnalyticsService
|
||||
$payoutsByAsset = [];
|
||||
$latestPriceByCurrency = [];
|
||||
|
||||
foreach ($measurements as $row) {
|
||||
$lastIndex = count($measurements) - 1;
|
||||
foreach ($measurements as $index => $row) {
|
||||
$measuredTs = $this->utcTimestamp((string) $row['measured_at']);
|
||||
$coinCurrency = strtoupper(trim((string) ($row['coin_currency'] ?? $settings['crypto_currency'] ?? 'DOGE')));
|
||||
$includeFullDetail = !$fullLatestOnly || $index === $lastIndex;
|
||||
while (isset($payouts[$payoutIndex])) {
|
||||
$payoutTs = $this->utcTimestamp((string) ($payouts[$payoutIndex]['payout_at'] ?? ''));
|
||||
if ($payoutTs <= 0 || $payoutTs > $measuredTs) {
|
||||
@@ -134,20 +137,23 @@ final class AnalyticsService
|
||||
}
|
||||
}
|
||||
|
||||
$effectiveDailyCost = $this->effectiveDailyCost($costPlans, $measuredTs, $priceCurrency, $row);
|
||||
$currentValue = $price !== null ? $visibleCoinsTotal * $price : null;
|
||||
$currentValueEffective = $price !== null ? $effectiveCoinsTotal * $price : null;
|
||||
$theoreticalDailyRevenue = ($price !== null && $perDayInterval !== null) ? $perDayInterval * $price : null;
|
||||
$effectiveDailyCost = $includeFullDetail ? $this->effectiveDailyCost($costPlans, $measuredTs, $priceCurrency, $row) : null;
|
||||
$currentValue = ($includeFullDetail && $price !== null) ? $visibleCoinsTotal * $price : null;
|
||||
$currentValueEffective = ($includeFullDetail && $price !== null) ? $effectiveCoinsTotal * $price : null;
|
||||
$theoreticalDailyRevenue = ($includeFullDetail && $price !== null && $perDayInterval !== null) ? $perDayInterval * $price : null;
|
||||
$theoreticalDailyProfit = (
|
||||
$includeFullDetail &&
|
||||
$theoreticalDailyRevenue !== null &&
|
||||
$effectiveDailyCost !== null
|
||||
) ? $theoreticalDailyRevenue - $effectiveDailyCost : null;
|
||||
$breakEvenPricePerCoin = (
|
||||
$includeFullDetail &&
|
||||
$effectiveDailyCost !== null &&
|
||||
$perDayInterval !== null &&
|
||||
$perDayInterval > 0
|
||||
) ? $effectiveDailyCost / $perDayInterval : null;
|
||||
$profitMarginPercent = (
|
||||
$includeFullDetail &&
|
||||
$theoreticalDailyRevenue !== null &&
|
||||
$theoreticalDailyRevenue > 0 &&
|
||||
$theoreticalDailyProfit !== null
|
||||
@@ -325,9 +331,22 @@ final class AnalyticsService
|
||||
)
|
||||
: null;
|
||||
$walletBalances = $this->walletBalances($payouts, $purchasedMiners, $latestMeasuredTs);
|
||||
$latestWalletSnapshot = $this->latestWalletSnapshot(is_array($options['wallet_snapshots'] ?? null) ? $options['wallet_snapshots'] : []);
|
||||
if (is_array($latestWalletSnapshot)) {
|
||||
$snapshotBalances = $this->walletSnapshotBalances($latestWalletSnapshot);
|
||||
if ($snapshotBalances !== []) {
|
||||
$walletBalances = $snapshotBalances;
|
||||
}
|
||||
}
|
||||
$walletBalanceCurrentAsset = (float) ($walletBalances[strtoupper(trim((string) ($latest['coin_currency'] ?? $settings['crypto_currency'] ?? 'DOGE')))] ?? 0.0);
|
||||
$holdingsCurrentAsset = $walletBalanceCurrentAsset + (float) ($latest['coins_total_visible'] ?? $latest['coins_total'] ?? 0);
|
||||
$walletValue = $latestCurrency !== '' ? $this->walletBalanceValue($walletBalances, $latestCurrency, $latest) : null;
|
||||
$walletValue = $latestCurrency !== ''
|
||||
? (
|
||||
is_array($latestWalletSnapshot)
|
||||
? $this->walletSnapshotValue($latestWalletSnapshot, $latestCurrency, $latest)
|
||||
: $this->walletBalanceValue($walletBalances, $latestCurrency, $latest)
|
||||
)
|
||||
: null;
|
||||
$currentVisibleValue = is_numeric($latest['current_value'] ?? null) ? (float) $latest['current_value'] : null;
|
||||
$totalHoldingsValue = ($walletValue !== null || $currentVisibleValue !== null)
|
||||
? (float) ($walletValue ?? 0.0) + (float) ($currentVisibleValue ?? 0.0)
|
||||
@@ -353,6 +372,7 @@ final class AnalyticsService
|
||||
'wallet_balance_current_asset' => $this->roundOrNull($walletBalanceCurrentAsset, 6),
|
||||
'holdings_current_asset' => $this->roundOrNull($holdingsCurrentAsset, 6),
|
||||
'wallet_value' => $this->roundOrNull($walletValue, 8),
|
||||
'wallet_snapshot_measured_at' => is_array($latestWalletSnapshot) ? (string) ($latestWalletSnapshot['measured_at'] ?? '') : null,
|
||||
'total_holdings_value' => $this->roundOrNull($totalHoldingsValue, 8),
|
||||
'break_even_remaining_amount' => $this->roundOrNull($breakEvenRemainingAmount, 8),
|
||||
'break_even_days_overall' => $this->roundOrNull($breakEvenDaysOverall, 4),
|
||||
@@ -1121,6 +1141,101 @@ final class AnalyticsService
|
||||
return array_map(fn (float $value): float => round($value, 8), $balances);
|
||||
}
|
||||
|
||||
private function latestWalletSnapshot(array $walletSnapshots): ?array
|
||||
{
|
||||
foreach ($walletSnapshots as $snapshot) {
|
||||
if (is_array($snapshot)) {
|
||||
return $snapshot;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function walletSnapshotBalances(array $snapshot): array
|
||||
{
|
||||
$balances = [];
|
||||
$rawBalances = is_array($snapshot['balances_json'] ?? null) ? $snapshot['balances_json'] : [];
|
||||
foreach ($rawBalances as $code => $asset) {
|
||||
$normalizedCode = strtoupper(trim((string) $code));
|
||||
if ($normalizedCode === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$balance = is_array($asset)
|
||||
? ($asset['balance'] ?? null)
|
||||
: $asset;
|
||||
if (!is_numeric($balance)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$balances[$normalizedCode] = round((float) $balance, 8);
|
||||
}
|
||||
|
||||
ksort($balances);
|
||||
return $balances;
|
||||
}
|
||||
|
||||
private function walletSnapshotValue(array $snapshot, string $targetCurrency, ?array $fxContext = null): ?float
|
||||
{
|
||||
$target = strtoupper(trim($targetCurrency));
|
||||
if ($target === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$balances = is_array($snapshot['balances_json'] ?? null) ? $snapshot['balances_json'] : [];
|
||||
if ($balances === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$total = 0.0;
|
||||
$matched = false;
|
||||
foreach ($balances as $code => $asset) {
|
||||
$currency = strtoupper(trim((string) $code));
|
||||
if ($currency === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$balance = is_array($asset) ? ($asset['balance'] ?? null) : $asset;
|
||||
if (!is_numeric($balance)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$numericBalance = (float) $balance;
|
||||
if ($currency === $target) {
|
||||
$total += $numericBalance;
|
||||
$matched = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
$snapshotPrice = is_array($asset) && is_numeric($asset['price_amount'] ?? null)
|
||||
? (float) $asset['price_amount']
|
||||
: null;
|
||||
$snapshotPriceCurrency = is_array($asset)
|
||||
? strtoupper(trim((string) ($asset['price_currency'] ?? '')))
|
||||
: '';
|
||||
|
||||
if ($snapshotPrice !== null && $snapshotPrice > 0 && $snapshotPriceCurrency !== '') {
|
||||
$convertedPrice = $snapshotPriceCurrency === $target
|
||||
? $snapshotPrice
|
||||
: $this->convertAmount($snapshotPrice, $snapshotPriceCurrency, $target, $fxContext);
|
||||
if ($convertedPrice !== null) {
|
||||
$total += $numericBalance * $convertedPrice;
|
||||
$matched = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$convertedBalance = $this->convertAmount($numericBalance, $currency, $target, $fxContext);
|
||||
if ($convertedBalance !== null) {
|
||||
$total += $convertedBalance;
|
||||
$matched = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $matched ? $total : null;
|
||||
}
|
||||
|
||||
private function walletBalanceValue(array $balances, string $targetCurrency, ?array $fxContext = null): ?float
|
||||
{
|
||||
$target = strtoupper(trim($targetCurrency));
|
||||
|
||||
Reference in New Issue
Block a user