umstellung
This commit is contained in:
@@ -15,7 +15,7 @@ final class DashboardPage
|
||||
private array $moduleSettings;
|
||||
private string $defaultReportCurrency;
|
||||
private float $fxMaxAgeHours;
|
||||
private int $alphaMinIntervalMinutes;
|
||||
private int $marketDataMinIntervalMinutes;
|
||||
private int $editPortfolioId;
|
||||
private int $editPositionId;
|
||||
private string $portfolioTable;
|
||||
@@ -49,9 +49,9 @@ final class DashboardPage
|
||||
$this->fxMaxAgeHours = 6.0;
|
||||
}
|
||||
|
||||
$this->alphaMinIntervalMinutes = (int) ($this->moduleSettings['alpha_vantage_min_interval_minutes'] ?? 60);
|
||||
if ($this->alphaMinIntervalMinutes <= 0) {
|
||||
$this->alphaMinIntervalMinutes = 60;
|
||||
$this->marketDataMinIntervalMinutes = (int) ($this->moduleSettings['bavest_min_interval_minutes'] ?? 60);
|
||||
if ($this->marketDataMinIntervalMinutes <= 0) {
|
||||
$this->marketDataMinIntervalMinutes = 60;
|
||||
}
|
||||
|
||||
$this->editPortfolioId = (int) ($_GET['edit_portfolio'] ?? 0);
|
||||
@@ -100,7 +100,7 @@ final class DashboardPage
|
||||
'availableOwners' => array_values($this->availableOwners),
|
||||
'defaultReportCurrency' => $this->defaultReportCurrency,
|
||||
'fxMaxAgeHours' => $this->fxMaxAgeHours,
|
||||
'alphaMinIntervalMinutes' => $this->alphaMinIntervalMinutes,
|
||||
'marketDataMinIntervalMinutes' => $this->marketDataMinIntervalMinutes,
|
||||
'symbolSearchKeywords' => $this->symbolSearchKeywords,
|
||||
'symbolSearchResults' => $this->symbolSearchResults,
|
||||
'editPortfolio' => $state['editPortfolio'],
|
||||
@@ -127,8 +127,8 @@ final class DashboardPage
|
||||
'save_position' => $this->savePosition(),
|
||||
'delete_position' => $this->deletePosition(),
|
||||
'save_quote' => $this->saveQuote(),
|
||||
'refresh_alpha_vantage_position' => $this->refreshAlphaVantagePosition(),
|
||||
'refresh_alpha_vantage_all' => $this->refreshAlphaVantageAll(),
|
||||
'refresh_market_data_position' => $this->refreshMarketDataPosition(),
|
||||
'refresh_market_data_all' => $this->refreshMarketDataAll(),
|
||||
'search_symbol' => $this->searchSymbol(),
|
||||
'delete_quote' => $this->deleteQuote(),
|
||||
'refresh_fx' => $this->refreshFx(),
|
||||
@@ -172,6 +172,7 @@ final class DashboardPage
|
||||
|
||||
$candidateName = trim((string) ($_GET['instrument_name_candidate'] ?? ''));
|
||||
$candidateSymbol = trim((string) ($_GET['symbol_candidate'] ?? ''));
|
||||
$candidateIsin = trim((string) ($_GET['isin_candidate'] ?? ''));
|
||||
$candidateMarket = trim((string) ($_GET['market_candidate'] ?? ''));
|
||||
$candidateCurrency = $this->normalizeCurrency((string) ($_GET['quote_currency_candidate'] ?? $this->defaultReportCurrency));
|
||||
|
||||
@@ -179,6 +180,7 @@ final class DashboardPage
|
||||
$editPosition = [
|
||||
'instrument_name' => $candidateName,
|
||||
'symbol' => $candidateSymbol,
|
||||
'isin' => $candidateIsin,
|
||||
'market' => $candidateMarket,
|
||||
'quote_currency' => $candidateCurrency,
|
||||
'purchase_currency' => $this->defaultReportCurrency,
|
||||
@@ -191,6 +193,9 @@ final class DashboardPage
|
||||
if ($candidateSymbol !== '') {
|
||||
$editPosition['symbol'] = $candidateSymbol;
|
||||
}
|
||||
if ($candidateIsin !== '') {
|
||||
$editPosition['isin'] = $candidateIsin;
|
||||
}
|
||||
if ($candidateMarket !== '') {
|
||||
$editPosition['market'] = $candidateMarket;
|
||||
}
|
||||
@@ -378,7 +383,7 @@ final class DashboardPage
|
||||
return 'Kurs gespeichert.';
|
||||
}
|
||||
|
||||
private function refreshAlphaVantagePosition(): string
|
||||
private function refreshMarketDataPosition(): string
|
||||
{
|
||||
$positionId = (int) ($_POST['position_id'] ?? 0);
|
||||
$stmt = $this->pdo->prepare(
|
||||
@@ -386,6 +391,7 @@ final class DashboardPage
|
||||
p.instrument_id,
|
||||
i.name AS instrument_name,
|
||||
i.symbol,
|
||||
i.isin,
|
||||
i.quote_currency
|
||||
FROM ' . $this->positionTable . ' p
|
||||
INNER JOIN ' . $this->instrumentTable . ' i ON i.id = p.instrument_id
|
||||
@@ -402,19 +408,19 @@ final class DashboardPage
|
||||
}
|
||||
|
||||
$instrumentId = (int) $row['instrument_id'];
|
||||
$symbol = strtoupper(trim((string) ($row['symbol'] ?? '')));
|
||||
$isin = strtoupper(trim((string) ($row['isin'] ?? '')));
|
||||
$quoteCurrency = $this->normalizeCurrency((string) ($row['quote_currency'] ?? $this->defaultReportCurrency));
|
||||
if ($symbol === '') {
|
||||
throw new RuntimeException('Fuer diese Aktie ist noch kein API-Symbol / Ticker hinterlegt.');
|
||||
if ($isin === '') {
|
||||
throw new RuntimeException('Fuer diese Aktie ist noch keine ISIN hinterlegt.');
|
||||
}
|
||||
|
||||
$latestApiQuote = $this->latestApiQuoteForInstrument($instrumentId);
|
||||
$latestTimestamp = is_array($latestApiQuote) ? strtotime((string) ($latestApiQuote['quoted_at'] ?? '')) : false;
|
||||
if ($latestTimestamp !== false && (time() - $latestTimestamp) < ($this->alphaMinIntervalMinutes * 60)) {
|
||||
return 'Vorhandener Alpha-Vantage-Kurs fuer ' . (string) $row['instrument_name'] . ' wiederverwendet.';
|
||||
if ($latestTimestamp !== false && (time() - $latestTimestamp) < ($this->marketDataMinIntervalMinutes * 60)) {
|
||||
return 'Vorhandener Bavest-Kurs fuer ' . (string) $row['instrument_name'] . ' wiederverwendet.';
|
||||
}
|
||||
|
||||
$apiResult = \module_fn('boersenchecker', 'alpha_vantage_fetch_quote', $symbol);
|
||||
$apiResult = \module_fn('boersenchecker', 'bavest_fetch_quote_by_isin', $isin);
|
||||
if (empty($apiResult['ok'])) {
|
||||
throw new RuntimeException((string) ($apiResult['message'] ?? 'API-Abruf fehlgeschlagen.'));
|
||||
}
|
||||
@@ -426,16 +432,17 @@ final class DashboardPage
|
||||
(string) $apiResult['fetched_at'],
|
||||
(string) $apiResult['source']
|
||||
);
|
||||
return 'API-Kurs fuer ' . (string) $row['instrument_name'] . ' gespeichert.';
|
||||
return 'Bavest-Kurs fuer ' . (string) $row['instrument_name'] . ' gespeichert.';
|
||||
}
|
||||
|
||||
private function refreshAlphaVantageAll(): string
|
||||
private function refreshMarketDataAll(): string
|
||||
{
|
||||
$stmt = $this->pdo->prepare(
|
||||
'SELECT DISTINCT
|
||||
i.id,
|
||||
i.name,
|
||||
i.symbol,
|
||||
i.isin,
|
||||
i.quote_currency
|
||||
FROM ' . $this->positionTable . ' p
|
||||
INNER JOIN ' . $this->instrumentTable . ' i ON i.id = p.instrument_id
|
||||
@@ -454,58 +461,68 @@ final class DashboardPage
|
||||
$failed = 0;
|
||||
$errors = [];
|
||||
|
||||
$bulkRows = [];
|
||||
foreach ($rows as $row) {
|
||||
$instrumentId = (int) ($row['id'] ?? 0);
|
||||
$symbol = strtoupper(trim((string) ($row['symbol'] ?? '')));
|
||||
$quoteCurrency = $this->normalizeCurrency((string) ($row['quote_currency'] ?? $this->defaultReportCurrency));
|
||||
|
||||
if ($instrumentId <= 0 || $symbol === '') {
|
||||
$isin = strtoupper(trim((string) ($row['isin'] ?? '')));
|
||||
if ($instrumentId <= 0 || $isin === '') {
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$latestApiQuote = $this->latestApiQuoteForInstrument($instrumentId);
|
||||
$latestTimestamp = is_array($latestApiQuote) ? strtotime((string) ($latestApiQuote['quoted_at'] ?? '')) : false;
|
||||
if ($latestTimestamp !== false && (time() - $latestTimestamp) < ($this->alphaMinIntervalMinutes * 60)) {
|
||||
if ($latestTimestamp !== false && (time() - $latestTimestamp) < ($this->marketDataMinIntervalMinutes * 60)) {
|
||||
$reused++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$apiResult = \module_fn('boersenchecker', 'alpha_vantage_fetch_quote', $symbol);
|
||||
if (empty($apiResult['ok'])) {
|
||||
$failed++;
|
||||
$errors[] = (string) ($row['name'] ?? $symbol) . ': ' . (string) ($apiResult['message'] ?? 'API-Abruf fehlgeschlagen.');
|
||||
if (stripos((string) ($apiResult['message'] ?? ''), 'limit') !== false) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
$bulkRows[] = $row;
|
||||
}
|
||||
|
||||
if ($bulkRows !== []) {
|
||||
$bulkResult = \module_fn('boersenchecker', 'bavest_fetch_bulk_quotes', $bulkRows);
|
||||
if (empty($bulkResult['ok'])) {
|
||||
throw new RuntimeException((string) ($bulkResult['message'] ?? 'Bavest Bulk-Abruf fehlgeschlagen.'));
|
||||
}
|
||||
|
||||
$this->storeQuote(
|
||||
$instrumentId,
|
||||
(float) $apiResult['price'],
|
||||
$quoteCurrency,
|
||||
(string) $apiResult['fetched_at'],
|
||||
(string) $apiResult['source']
|
||||
);
|
||||
$fetched++;
|
||||
$bulkQuotes = is_array($bulkResult['quotes'] ?? null) ? $bulkResult['quotes'] : [];
|
||||
foreach ($bulkRows as $row) {
|
||||
$instrumentId = (int) ($row['id'] ?? 0);
|
||||
$quoteCurrency = $this->normalizeCurrency((string) ($row['quote_currency'] ?? $this->defaultReportCurrency));
|
||||
$apiResult = $bulkQuotes[$instrumentId] ?? null;
|
||||
if (!is_array($apiResult) || !is_numeric($apiResult['price'] ?? null)) {
|
||||
$failed++;
|
||||
$errors[] = (string) ($row['name'] ?? $instrumentId) . ': kein Preis in der Bavest-Antwort.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->storeQuote(
|
||||
$instrumentId,
|
||||
(float) $apiResult['price'],
|
||||
$quoteCurrency,
|
||||
(string) $apiResult['fetched_at'],
|
||||
(string) $apiResult['source']
|
||||
);
|
||||
$fetched++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors !== []) {
|
||||
throw new RuntimeException(
|
||||
'Alpha Vantage: ' . $fetched . ' neu, ' . $reused . ' wiederverwendet, ' . $skipped . ' ohne Symbol, ' . $failed . ' Fehler. '
|
||||
'Bavest: ' . $fetched . ' neu, ' . $reused . ' wiederverwendet, ' . $skipped . ' ohne ISIN, ' . $failed . ' Fehler. '
|
||||
. implode(' | ', array_slice($errors, 0, 3))
|
||||
);
|
||||
}
|
||||
|
||||
return 'Alpha Vantage: ' . $fetched . ' neu, ' . $reused . ' wiederverwendet, ' . $skipped . ' ohne Symbol, ' . $failed . ' Fehler.';
|
||||
return 'Bavest: ' . $fetched . ' neu, ' . $reused . ' wiederverwendet, ' . $skipped . ' ohne ISIN, ' . $failed . ' Fehler.';
|
||||
}
|
||||
|
||||
private function searchSymbol(): string
|
||||
{
|
||||
$keywords = trim((string) ($_POST['search_keywords'] ?? ''));
|
||||
$this->symbolSearchKeywords = $keywords;
|
||||
$result = \module_fn('boersenchecker', 'alpha_vantage_search_symbols', $keywords);
|
||||
$result = \module_fn('boersenchecker', 'bavest_search_symbols', $keywords);
|
||||
$this->symbolSearchResults = is_array($result['results'] ?? null) ? $result['results'] : [];
|
||||
|
||||
if (empty($result['ok'])) {
|
||||
@@ -708,7 +725,7 @@ final class DashboardPage
|
||||
);
|
||||
$stmt->execute([
|
||||
'instrument_id' => $instrumentId,
|
||||
'source' => 'alpha_vantage:%',
|
||||
'source' => 'bavest:%',
|
||||
]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
return is_array($row) ? $row : null;
|
||||
|
||||
Reference in New Issue
Block a user