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
|
|
@ -1,14 +1,16 @@
|
|||
//! Fixture-backed provider for tests, enabled by the `testing` feature and
|
||||
//! `IDX_USE_MOCK_PROVIDER`. Release builds do not contain it.
|
||||
|
||||
use super::stockbit::exodus;
|
||||
use super::stockbit::{corpaction, exodus};
|
||||
use super::types::{Bar, Fundamentals, Interval, Intraday, OrderBook, Period, Quote};
|
||||
use super::{
|
||||
BrokerSummaryProvider, FundamentalsProvider, HistoryProvider, IntradayProvider,
|
||||
OrderBookProvider, QuoteProvider, TradingSummaryProvider, idx, ipot, msn, stockbit, yahoo,
|
||||
BrokerSummaryProvider, CorporateActionProvider, FundamentalsProvider, HistoryProvider,
|
||||
IntradayProvider, OrderBookProvider, QuoteProvider, TradingSummaryProvider, idx, ipot, msn,
|
||||
stockbit, yahoo,
|
||||
};
|
||||
use crate::broker::types::{BrokerBoard, BrokerInvestor, BrokerQuery};
|
||||
use crate::config::ProviderKind;
|
||||
use crate::corporate::types::{ActionKind, CorporateAction};
|
||||
use crate::error::IdxError;
|
||||
|
||||
pub(crate) fn enabled() -> bool {
|
||||
|
|
@ -224,6 +226,34 @@ impl OrderBookProvider for MockStockbitProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/// `stockbit_exodus_corpaction_<type>.json` for the market,
|
||||
/// `..._<type>_<code>.json` for one stock; a stock without a fixture has none
|
||||
/// of that kind, as Stockbit answers.
|
||||
impl CorporateActionProvider for MockStockbitProvider {
|
||||
fn corporate_actions(
|
||||
&self,
|
||||
kind: ActionKind,
|
||||
symbol: Option<&str>,
|
||||
) -> Result<Vec<CorporateAction>, IdxError> {
|
||||
let subject = symbol.unwrap_or("corporate actions");
|
||||
let name = match symbol {
|
||||
Some(symbol) => format!(
|
||||
"corpaction_{}_{}.json",
|
||||
corpaction::path_type(kind),
|
||||
stockbit::stockbit_code(symbol)?.to_ascii_lowercase()
|
||||
),
|
||||
None => format!("corpaction_{}.json", corpaction::path_type(kind)),
|
||||
};
|
||||
let body = match self.exodus(subject, &name) {
|
||||
Err(IdxError::SymbolNotFound(_)) if symbol.is_some() => {
|
||||
r#"{"data":{"none":[]}}"#.to_string()
|
||||
}
|
||||
other => other?,
|
||||
};
|
||||
corpaction::parse_corporate_actions(kind, &body)
|
||||
}
|
||||
}
|
||||
|
||||
impl HistoryProvider for MockStockbitProvider {
|
||||
fn history(
|
||||
&self,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue