added function aggregating multiple ticker data
This commit is contained in:
51
src/corporate/fx.rs
Normal file
51
src/corporate/fx.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
// src/corporate/fx.rs
|
||||
use std::collections::HashMap;
|
||||
use reqwest;
|
||||
use serde_json::Value;
|
||||
use tokio::fs;
|
||||
use std::path::Path;
|
||||
|
||||
static FX_CACHE_PATH: &str = "fx_rates.json";
|
||||
|
||||
pub async fn get_usd_rate(currency: &str) -> anyhow::Result<f64> {
|
||||
if currency == "USD" {
|
||||
return Ok(1.0);
|
||||
}
|
||||
|
||||
let mut cache: HashMap<String, (f64, String)> = if Path::new(FX_CACHE_PATH).exists() {
|
||||
let content = fs::read_to_string(FX_CACHE_PATH).await?;
|
||||
serde_json::from_str(&content).unwrap_or_default()
|
||||
} else {
|
||||
HashMap::new()
|
||||
};
|
||||
|
||||
let today = chrono::Local::now().format("%Y-%m-%d").to_string();
|
||||
if let Some((rate, date)) = cache.get(currency) {
|
||||
if date == &today {
|
||||
return Ok(*rate);
|
||||
}
|
||||
}
|
||||
|
||||
let symbol = format!("{}USD=X", currency);
|
||||
let url = format!("https://query1.finance.yahoo.com/v8/finance/chart/{}?range=1d&interval=1d", symbol);
|
||||
|
||||
let json: Value = reqwest::Client::new()
|
||||
.get(&url)
|
||||
.header("User-Agent", "Mozilla/5.0")
|
||||
.send()
|
||||
.await?
|
||||
.json()
|
||||
.await?;
|
||||
|
||||
let close = json["chart"]["result"][0]["meta"]["regularMarketPrice"]
|
||||
.as_f64()
|
||||
.or_else(|| json["chart"]["result"][0]["indicators"]["quote"][0]["close"][0].as_f64())
|
||||
.unwrap_or(1.0);
|
||||
|
||||
let rate = if currency == "JPY" || currency == "KRW" { close } else { 1.0 / close }; // inverse pairs
|
||||
|
||||
cache.insert(currency.to_string(), (rate, today.clone()));
|
||||
let _ = fs::write(FX_CACHE_PATH, serde_json::to_string_pretty(&cache)?).await;
|
||||
|
||||
Ok(rate)
|
||||
}
|
||||
Reference in New Issue
Block a user