finance-query v3.0.0

Economic Indicators#

info · Feature flag required

The economic domain requires at least one provider feature. FRED is the primary recommended provider:

toml
finance-query = { version = "...", features = ["fred"] }

The EconomicIndicator domain handle fetches macro-economic time series data. It is backed by FRED (Federal Reserve Economic Data), with optional Alpha Vantage and Polygon fallbacks, and is keyed by a series ID string.

Getting a Handle#

Create an EconomicIndicator handle from a Providers instance by routing the ECONOMIC capability to FRED, then call .series() to fetch the data:

rust · no_run feature=fred
use finance_query::{Capability, Provider, Providers};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let providers = Providers::builder()
        .route(Capability::ECONOMIC, [Provider::Fred])
        .build()
        .await?;
    let gdp = providers.economic("GDP");
    let series = gdp.series().await?;
    println!("{}: {} observations", series.series_id, series.observations.len());
    Ok(())
}

The series ID is a FRED series identifier such as "GDP", "FEDFUNDS", or "CPIAUCSL". See the FRED series catalog for the full list of 800k+ available series.

note · FRED API Key

FRED requires an API key. Initialise it once before building your Providers instance:

rust · no_run feature=fred
use finance_query::fred;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    fred::init(std::env::var("FRED_API_KEY")?)?;
    Ok(())
}

See FRED Provider Reference for setup details.

de_fred_seriesmedian time 109.6 µs(limit < 500.0 µs)0limit 500.0 µs

EconomicSeries Fields#

The returned EconomicSeries value contains:

FieldTypeDescription
series_idStringSeries identifier (e.g., "GDP", "FEDFUNDS")
titleOption<String>Human-readable series title
unitsOption<String>Unit of measurement (e.g., "Billions of Dollars", "Percent")
frequencyOption<String>Reporting frequency (e.g., "Annual", "Monthly")
observationsVec<MacroObservation>Chronologically ordered observations

Each MacroObservation has:

FieldTypeDescription
dateStringObservation date as YYYY-MM-DD
valueOption<f64>Observation value; None when FRED reports a missing value

Both tables are backed by a compiled, real value — EconomicSeries and MacroObservation are #[non_exhaustive] and have no public constructor, but both derive Deserialize, so a fixture value can be built from outside the crate with serde_json::from_value:

rust · runnable
use finance_query::EconomicSeries;
use finance_query::fred::MacroObservation;

fn main() {
    let series: EconomicSeries = serde_json::from_value(serde_json::json!({
        "series_id": "GDP",
        "title": "Gross Domestic Product",
        "units": "Billions of Dollars",
        "frequency": "Quarterly",
        "observations": [
            {"date": "2024-01-01", "value": 28624.1},
            {"date": "2024-04-01", "value": 29016.7}
        ]
    }))
    .unwrap();

    let first: &MacroObservation = &series.observations[0];
    println!("series_id = {}", series.series_id);
    println!("title = {:?}", series.title);
    println!("first observation = {} -> {:?}", first.date, first.value);
}
recorded outputcargo soothfast docs capture
series_id = GDP
title = Some("Gross Domestic Product")
first observation = 2024-01-01 -> Some(28624.1)
checked claims
EconomicSeriesverified current

Example: Inspecting GDP Data#

rust · no_run feature=fred
use finance_query::{Capability, Provider, Providers};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let providers = Providers::builder()
        .route(Capability::ECONOMIC, [Provider::Fred])
        .build()
        .await?;

    let gdp = providers.economic("GDP");
    let series = gdp.series().await?;

    println!("Series:    {}", series.series_id);
    if let Some(title) = &series.title {
        println!("Title:     {}", title);
    }
    if let Some(units) = &series.units {
        println!("Units:     {}", units);
    }
    if let Some(freq) = &series.frequency {
        println!("Frequency: {}", freq);
    }
    println!("Observations: {}", series.observations.len());

    // Print the last 5 observations
    for obs in series.observations.iter().rev().take(5) {
        match obs.value {
            Some(v) => println!("{}: {:.1}", obs.date, v),
            None => println!("{}: N/A", obs.date),
        }
    }
    Ok(())
}
checked claims
MacroObservationverified current

See Also#

built with cargo soothfast docs build source