use serde::{Deserialize, Deserializer, Serialize};
use crate::types::{Count, Date, Price, StatementAmount, Ticker};
fn required_option<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de>,
{
Option::<T>::deserialize(deserializer)
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct FinancialEstimate {
pub symbol: Ticker,
pub date: Date,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub revenue_low: StatementAmount,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub revenue_high: StatementAmount,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub revenue_avg: StatementAmount,
#[serde(deserialize_with = "required_option")]
#[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")]
pub ebitda_low: Option<StatementAmount>,
#[serde(deserialize_with = "required_option")]
#[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")]
pub ebitda_high: Option<StatementAmount>,
#[serde(deserialize_with = "required_option")]
#[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")]
pub ebitda_avg: Option<StatementAmount>,
#[serde(deserialize_with = "required_option")]
#[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")]
pub ebit_low: Option<StatementAmount>,
#[serde(deserialize_with = "required_option")]
#[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")]
pub ebit_high: Option<StatementAmount>,
#[serde(deserialize_with = "required_option")]
#[serde(serialize_with = "crate::codecs::integral_f64::serialize_option")]
pub ebit_avg: Option<StatementAmount>,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub net_income_low: StatementAmount,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub net_income_high: StatementAmount,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub net_income_avg: StatementAmount,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub sga_expense_low: StatementAmount,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub sga_expense_high: StatementAmount,
#[serde(serialize_with = "crate::codecs::integral_f64::serialize")]
pub sga_expense_avg: StatementAmount,
pub eps_avg: f64,
pub eps_high: f64,
pub eps_low: f64,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub num_analysts_revenue: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub num_analysts_eps: Count,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct RatingSnapshot {
pub symbol: Ticker,
pub rating: String,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub overall_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub discounted_cash_flow_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub return_on_equity_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub return_on_assets_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub debt_to_equity_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub price_to_earnings_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub price_to_book_score: Count,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct HistoricalRating {
pub symbol: Ticker,
pub date: Date,
pub rating: String,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub overall_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub discounted_cash_flow_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub return_on_equity_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub return_on_assets_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub debt_to_equity_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub price_to_earnings_score: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub price_to_book_score: Count,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct PriceTargetSummary {
pub symbol: Ticker,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub last_month_count: Count,
pub last_month_avg_price_target: Price,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub last_quarter_count: Count,
pub last_quarter_avg_price_target: Price,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub last_year_count: Count,
pub last_year_avg_price_target: Price,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub all_time_count: Count,
pub all_time_avg_price_target: Price,
pub publishers: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct PriceTargetConsensus {
pub symbol: Ticker,
pub target_high: Price,
pub target_low: Price,
pub target_consensus: Price,
pub target_median: Price,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct StockGrade {
pub symbol: Ticker,
pub date: Date,
pub grading_company: String,
pub previous_grade: String,
pub new_grade: String,
pub action: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct HistoricalStockGrade {
pub symbol: Ticker,
pub date: Date,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub analyst_ratings_strong_buy: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub analyst_ratings_buy: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub analyst_ratings_hold: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub analyst_ratings_sell: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub analyst_ratings_strong_sell: Count,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(rename_all = "camelCase")]
pub struct StockGradesSummary {
pub symbol: Ticker,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub strong_buy: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub buy: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub hold: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub sell: Count,
#[serde(deserialize_with = "crate::codecs::count::deserialize")]
pub strong_sell: Count,
pub consensus: String,
}