mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
feat: corporate actions from the Stockbit session (stocks actions, stocks calendar)
`idx stocks actions SYM [--kind ...]`: one stock's cash and stock
dividends, bonus shares, rights, warrants, splits and reverse splits,
meetings, public exposes and tender offers (`--kind ipo` adds its IPO),
newest first. `idx stocks calendar [--from] [--to] [--kind ...]`: the
market's actions dated in the range (default today and 30 days ahead),
oldest first. MCP: get_corporate_actions, get_corporate_calendar.
Stockbit's `/corpaction/{type}` serves one kind per request; each type has
its own field prefix and list key, so entitlements are read by field
suffix. An action's `date` is the cum date for entitlements, else the
event's first day. Dividends keep their decimals. One request per kind,
cached 6 hours. AUTHERROR without a session.
Fixtures are the 2026-11-03 recordings (market-wide ones trimmed to
October-December). Goldens added; help-stocks and completions-bash gain
the two subcommands, MCP tools.json the two tools (regenerated with
UPDATE_GOLDEN=1). The MCP docs counted 17 tools without stockbit_login;
now 20.
Claude-Session: https://claude.ai/code/session_01RqPPVeVDrnLoP7NUZmLRxY
This commit is contained in:
parent
8a1b29043c
commit
43ff4aa433
55 changed files with 2026 additions and 34 deletions
|
|
@ -25,9 +25,11 @@ use chrono::{Months, NaiveDate};
|
|||
use serde_json::Value;
|
||||
|
||||
use super::auth::SessionStore;
|
||||
use super::corpaction;
|
||||
use super::parse::number;
|
||||
use super::{USER_AGENT, pace, stockbit_code};
|
||||
use crate::api::types::{BookLevel, Interval, Ohlc, OrderBook, Period, Quote};
|
||||
use crate::corporate::types::{ActionKind, CorporateAction};
|
||||
use crate::error::IdxError;
|
||||
|
||||
const BASE_URL: &str = "https://exodus.stockbit.com";
|
||||
|
|
@ -120,6 +122,24 @@ impl Exodus {
|
|||
daily_for_period(&body, period)
|
||||
}
|
||||
|
||||
/// Corporate actions of `kind`: one stock's (`resolved`) or the market's.
|
||||
pub(crate) fn corporate_actions(
|
||||
&self,
|
||||
kind: ActionKind,
|
||||
resolved: Option<&str>,
|
||||
) -> Result<Vec<CorporateAction>, IdxError> {
|
||||
let path = format!("/corpaction/{}", corpaction::path_type(kind));
|
||||
let (path, subject) = match resolved {
|
||||
Some(resolved) => (
|
||||
format!("{path}?symbol={}", stockbit_code(resolved)?),
|
||||
resolved.to_string(),
|
||||
),
|
||||
None => (path, "corporate actions".to_string()),
|
||||
};
|
||||
let body = self.get(&path, &subject)?;
|
||||
corpaction::parse_corporate_actions(kind, &body)
|
||||
}
|
||||
|
||||
/// The market's state, read at most every `MARKET_STATE_TTL` per process.
|
||||
/// Unknown on any failure, which hides bid/offer.
|
||||
fn market_status(&self) -> Option<String> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue