mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
fix(quotes): keep negative price changes
From the Codex re-gate of the 0.3.3 fixes: the price sanity check also applied to MSN's priceChange, so a falling stock without a previous close got change: null. Bound a change by its size instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3syn2fN2LNo5pvTSqc6eh
This commit is contained in:
parent
66207d24b6
commit
46cf69db6e
1 changed files with 15 additions and 2 deletions
|
|
@ -33,7 +33,7 @@ pub(super) fn parse_quote(symbol: &str, quotes: &[MsnQuote]) -> Result<Quote, Id
|
||||||
})?;
|
})?;
|
||||||
let change = prev_close
|
let change = prev_close
|
||||||
.map(|previous| price - previous)
|
.map(|previous| price - previous)
|
||||||
.or_else(|| quote.price_change.and_then(round_price));
|
.or_else(|| quote.price_change.and_then(round_change));
|
||||||
|
|
||||||
let ticker = quote
|
let ticker = quote
|
||||||
.symbol
|
.symbol
|
||||||
|
|
@ -208,6 +208,11 @@ fn round_price(value: f64) -> Option<i64> {
|
||||||
(value.is_finite() && (0.0..=MAX_PRICE).contains(&value)).then(|| value.round() as i64)
|
(value.is_finite() && (0.0..=MAX_PRICE).contains(&value)).then(|| value.round() as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A price change can be negative; same bound on its size.
|
||||||
|
fn round_change(value: f64) -> Option<i64> {
|
||||||
|
(value.is_finite() && value.abs() <= MAX_PRICE).then(|| value.round() as i64)
|
||||||
|
}
|
||||||
|
|
||||||
fn round_u64(value: Option<f64>) -> Option<u64> {
|
fn round_u64(value: Option<f64>) -> Option<u64> {
|
||||||
value.and_then(|number| {
|
value.and_then(|number| {
|
||||||
if !number.is_finite() || number.is_sign_negative() {
|
if !number.is_finite() || number.is_sign_negative() {
|
||||||
|
|
@ -679,7 +684,7 @@ pub(super) fn parse_screener_results(raw: &RawScreenerResponse) -> Result<Vec<Qu
|
||||||
let prev_close = q.price_previous_close.and_then(round_price);
|
let prev_close = q.price_previous_close.and_then(round_price);
|
||||||
let change = prev_close
|
let change = prev_close
|
||||||
.map(|pc| price - pc)
|
.map(|pc| price - pc)
|
||||||
.or_else(|| q.price_change.and_then(round_price));
|
.or_else(|| q.price_change.and_then(round_change));
|
||||||
let ticker = q
|
let ticker = q
|
||||||
.symbol
|
.symbol
|
||||||
.as_deref()
|
.as_deref()
|
||||||
|
|
@ -912,6 +917,14 @@ mod tests {
|
||||||
assert_eq!(quote.prev_close, None);
|
assert_eq!(quote.prev_close, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_quote_keeps_a_negative_change_without_a_previous_close() {
|
||||||
|
let raw: Vec<MsnQuote> =
|
||||||
|
serde_json::from_str(r#"[{"symbol":"BBCA","price":100.0,"priceChange":-5.0}]"#)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(parse_quote("BBCA.JK", &raw).unwrap().change, Some(-5));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parses_news_fixture_items() {
|
fn parses_news_fixture_items() {
|
||||||
let raw: RawNewsFeed =
|
let raw: RawNewsFeed =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue