added function aggregating multiple ticker data

This commit is contained in:
2025-11-24 17:19:36 +01:00
parent 7b680f960f
commit 9cfcae84ea
14 changed files with 443 additions and 44 deletions

View File

@@ -1,54 +1,80 @@
// src/corporate/update.rs
use super::{scraper::*, storage::*, helpers::*, types::*};
use super::{scraper::*, storage::*, helpers::*, types::*, aggregation::aggregate_best_price_data};
use crate::config::Config;
use yfinance_rs::{Range, Interval};
use chrono::Local;
use std::collections::HashMap;
pub async fn run_full_update(client: &fantoccini::Client, tickers: Vec<String>, config: &Config) -> anyhow::Result<()> {
println!("Updating {} tickers (prices from {})", tickers.len(), config.corporate_start_date);
pub async fn run_full_update(client: &fantoccini::Client, config: &Config) -> anyhow::Result<()> {
println!("Starting company-centric corporate update (ISIN-based)");
let companies = load_companies().await?;
let today = chrono::Local::now().format("%Y-%m-%d").to_string();
let mut existing = load_existing_events().await?;
let mut existing_events = load_existing_events().await?;
for ticker in &tickers {
print!("{:6} ", ticker);
for company in companies {
println!("\nProcessing company: {} ({})", company.name, company.isin);
if let Ok(new_events) = fetch_earnings_history(client, ticker).await {
let result = process_batch(&new_events, &mut existing, &today);
save_changes(&result.changes).await?;
println!("{} earnings, {} changes", new_events.len(), result.changes.len());
}
ensure_company_dirs(&company.isin).await?;
save_company_metadata(&company).await?;
// DAILY full history
if let Ok(prices) = fetch_daily_price_history(ticker, &config.corporate_start_date, &today).await {
save_prices_for_ticker(ticker, "daily", prices).await?;
}
for ticker_info in &company.tickers {
let ticker = &ticker_info.ticker;
println!(" → Trying ticker: {ticker} ({})", ticker_info.exchange_mic);
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
let mut daily_success = false;
let mut intraday_success = false;
// 5-MINUTE only last 60 days (Yahoo limit for intraday)
let sixty_days_ago = (chrono::Local::now() - chrono::Duration::days(60))
.format("%Y-%m-%d")
.to_string();
if let Ok(prices) = fetch_price_history_5min(ticker, &sixty_days_ago, &today).await {
if !prices.is_empty() {
save_prices_for_ticker(ticker, "5min", prices.clone()).await?;
println!(" Saved {} 5min bars for {ticker}", prices.len());
} else {
println!(" No 5min data available for {ticker} (market closed? retry later)");
// Earnings
if let Ok(new_events) = fetch_earnings_history(client, ticker).await {
let result = process_batch(&new_events, &mut existing_events, &today);
save_changes(&result.changes).await?;
println!(" {} earnings events", new_events.len());
}
} else {
println!(" 5min fetch failed for {ticker} (rate limit? try again)");
// Daily prices
if let Ok(prices) = fetch_daily_price_history(ticker, &config.corporate_start_date, &today).await {
if !prices.is_empty() {
save_prices_by_source(&company.isin, ticker, "daily", prices).await?;
daily_success = true;
}
}
// 5-minute prices (last 60 days)
let sixty_days_ago = (chrono::Local::now() - chrono::Duration::days(60))
.format("%Y-%m-%d")
.to_string();
if let Ok(prices) = fetch_price_history_5min(ticker, &sixty_days_ago, &today).await {
if !prices.is_empty() {
save_prices_by_source(&company.isin, ticker, "5min", prices.clone()).await?;
intraday_success = true;
println!(" Saved {} 5min bars from {ticker}", prices.len());
}
}
// Record success
update_available_exchange(
&company.isin,
ticker,
&ticker_info.exchange_mic,
daily_success,
intraday_success,
).await?;
aggregate_best_price_data(&company.isin).await?;
tokio::time::sleep(tokio::time::Duration::from_millis(800)).await;
}
tokio::time::sleep(tokio::time::Duration::from_millis(250)).await;
// Optional: run aggregation after all sources
// aggregate_best_price_data(&company.isin).await?;
}
save_optimized_events(existing).await?;
save_optimized_events(existing_events).await?;
println!("Corporate update complete (ISIN-based)");
Ok(())
}