mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
refactor: split into idx-core library and idx-cli binary workspace
Phase 2 of docs/DESIGN.md, no behavior change: - crates/idx-core (library): api, analysis, cache, config file handling and provider selection, curl_impersonate, error, ownership, runtime, plus the shared test fixtures. clap derives are behind an optional `clap` feature so the library does not require clap. - crates/idx-cli (binary `idx`): cli/, output/, and IdxConfig (output format and color resolution). Package and binary names are unchanged. - config.rs is split: file read/write and validation move to core; a CLI test keeps core's OUTPUT_VALUES in sync with OutputSetting. - ownership::db::open_db/db_path drop their unused IdxConfig argument. - One workspace version; shared dependency versions; no third-party version changes in Cargo.lock. LICENSE is symlinked into each crate. - flake: workspace version, new source paths, and a per-crate package check (idx-cli is built from its tarball against packaged idx-core, since idx-core is not on crates.io yet). CI cache key, release path filter, and the golden whitespace-hook exclusion follow the new layout. Parity: all 143 golden outputs match byte for byte without regeneration; 157 core + 17 CLI unit tests (173 before plus the new OUTPUT_VALUES sync test), 62 CLI tests pass. Live A/B against main: 16/16 stocks cases identical; ownership discover got IDX 403 on both (exit 4 vs 1 is the phase 1 exit-code change). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
22b6dabaeb
commit
15947de51a
238 changed files with 544 additions and 375 deletions
8
crates/idx-cli/tests/golden/auto-format-env-table.golden
Normal file
8
crates/idx-cli/tests/golden/auto-format-env-table.golden
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
┌─────────┬───────┬──────┬────────┬────────────┬───────────────────────┬────────────┐
|
||||
│ SYMBOL ┆ PRICE ┆ CHG ┆ CHG% ┆ VOLUME ┆ MKT CAP ┆ 52W RANGE │
|
||||
╞═════════╪═══════╪══════╪════════╪════════════╪═══════════════════════╪════════════╡
|
||||
│ BBCA.JK ┆ 9,875 ┆ +117 ┆ +1.20% ┆ 12,300,000 ┆ 1,215,200,000,000,000 ┆ ████████░░ │
|
||||
└─────────┴───────┴──────┴────────┴────────────┴───────────────────────┴────────────┘
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/auto-format-piped.golden
Normal file
4
crates/idx-cli/tests/golden/auto-format-piped.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[{"symbol":"BBCA.JK","price":9875,"change":117,"change_pct":1.2,"volume":12300000,"market_cap":1215200000000000,"week52_high":10250,"week52_low":7800,"week52_position":0.8469387755102041,"range_signal":"upper","prev_close":9758,"avg_volume":10000000,"as_of":null},{"symbol":"BBRI.JK","price":9875,"change":117,"change_pct":1.2,"volume":12300000,"market_cap":1215200000000000,"week52_high":10250,"week52_low":7800,"week52_position":0.8469387755102041,"range_signal":"upper","prev_close":9758,"avg_volume":10000000,"as_of":null}]
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/cache-clear.json.golden
Normal file
4
crates/idx-cli/tests/golden/cache-clear.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"failed":[],"removed":0}
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/cache-clear.table.golden
Normal file
4
crates/idx-cli/tests/golden/cache-clear.table.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
cleared 0 files
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/cache-info-empty.json.golden
Normal file
4
crates/idx-cli/tests/golden/cache-info-empty.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"files":0,"newest":null,"oldest":null,"path":"<ROOT>/cache/idx","size_bytes":0}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
path: <ROOT>/cache/idx
|
||||
files: 0
|
||||
size_bytes: 0
|
||||
oldest: -
|
||||
newest: -
|
||||
--- stderr
|
||||
382
crates/idx-cli/tests/golden/cases.toml
Normal file
382
crates/idx-cli/tests/golden/cases.toml
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
# Golden output cases for tests/golden.rs.
|
||||
#
|
||||
# Each case runs once per entry in `formats` (default: table and json) with
|
||||
# `-o <format>` prepended; `formats = []` runs the args as given, which means
|
||||
# the auto format: stdout is a pipe here, so auto resolves to compact JSON.
|
||||
# Every run uses the mock provider (IDX_USE_MOCK_PROVIDER=1) and an isolated
|
||||
# home directory. `ownership = true` seeds the fixture DB; `before` runs setup
|
||||
# commands first; `stdin` is piped to the command.
|
||||
#
|
||||
# `idx version` is excluded on purpose: its output changes with every release.
|
||||
|
||||
# --- help and shell completions ---------------------------------------------
|
||||
|
||||
[[case]]
|
||||
name = "help-root"
|
||||
args = ["--help"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "help-stocks"
|
||||
args = ["stocks", "--help"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "help-ownership"
|
||||
args = ["ownership", "--help"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "help-config"
|
||||
args = ["config", "--help"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "help-cache"
|
||||
args = ["cache", "--help"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "completions-bash"
|
||||
args = ["completions", "bash"]
|
||||
formats = []
|
||||
|
||||
# --- config and cache ---------------------------------------------------------
|
||||
|
||||
[[case]]
|
||||
name = "config-path"
|
||||
args = ["config", "path"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "config-init"
|
||||
args = ["config", "init"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "config-get"
|
||||
args = ["config", "get", "general.provider"]
|
||||
formats = []
|
||||
before = [["config", "init"]]
|
||||
|
||||
[[case]]
|
||||
name = "config-set"
|
||||
args = ["config", "set", "general.provider", "yahoo"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "config-set-output-jsonl"
|
||||
args = ["config", "set", "general.output", "jsonl"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "config-set-output-invalid"
|
||||
args = ["config", "set", "general.output", "yaml"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "config-output-table-pins-format"
|
||||
args = ["stocks", "quote", "BBCA"]
|
||||
formats = []
|
||||
before = [["config", "set", "general.output", "table"]]
|
||||
|
||||
[[case]]
|
||||
name = "cache-info-empty"
|
||||
args = ["cache", "info"]
|
||||
|
||||
[[case]]
|
||||
name = "cache-clear"
|
||||
args = ["cache", "clear"]
|
||||
|
||||
# --- stocks: MSN (default provider) --------------------------------------------
|
||||
|
||||
[[case]]
|
||||
name = "stocks-quote"
|
||||
args = ["stocks", "quote", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-quote-multi"
|
||||
formats = ["table", "json", "jsonl"]
|
||||
args = ["stocks", "quote", "BBCA,BBRI"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-history"
|
||||
formats = ["table", "json", "jsonl"]
|
||||
args = ["stocks", "history", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-history-msn"
|
||||
args = ["stocks", "history", "BBCA", "--history-provider", "msn"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-technical"
|
||||
args = ["stocks", "technical", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-growth"
|
||||
args = ["stocks", "growth", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-valuation"
|
||||
args = ["stocks", "valuation", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-valuation-nonfinite"
|
||||
args = ["stocks", "valuation", "BBCA"]
|
||||
env = { IDX_MOCK_MSN_KEYRATIOS_FIXTURE = "tests/fixtures/msn_keyratios_infinity.json" }
|
||||
|
||||
[[case]]
|
||||
name = "stocks-risk"
|
||||
args = ["stocks", "risk", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-fundamental"
|
||||
formats = ["table", "json", "jsonl"]
|
||||
args = ["stocks", "fundamental", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-compare"
|
||||
args = ["stocks", "compare", "BBCA", "BBRI"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-profile"
|
||||
args = ["stocks", "profile", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-financials"
|
||||
args = ["stocks", "financials", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-financials-income"
|
||||
args = ["stocks", "financials", "BBCA", "--statement", "income"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-earnings"
|
||||
args = ["stocks", "earnings", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-earnings-history-quarterly"
|
||||
args = ["stocks", "earnings", "BBCA", "--history", "--quarterly"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-earnings-forecast-annual"
|
||||
args = ["stocks", "earnings", "BBCA", "--forecast", "--annual"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-sentiment"
|
||||
args = ["stocks", "sentiment", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-insights"
|
||||
args = ["stocks", "insights", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-news"
|
||||
args = ["stocks", "news", "BBCA", "--limit", "5"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-screen"
|
||||
args = ["stocks", "screen"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-screen-worst"
|
||||
args = ["stocks", "screen", "--filter", "worst-performers", "--limit", "5"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-screen-high-volume"
|
||||
args = ["stocks", "screen", "--filter", "high-volume"]
|
||||
|
||||
[[case]]
|
||||
name = "stocks-screen-large-cap"
|
||||
args = ["stocks", "screen", "--filter", "large-cap"]
|
||||
|
||||
[[case]]
|
||||
name = "auto-format-piped"
|
||||
args = ["stocks", "quote", "BBCA,BBRI"]
|
||||
formats = []
|
||||
|
||||
[[case]]
|
||||
name = "auto-format-env-table"
|
||||
args = ["stocks", "quote", "BBCA"]
|
||||
formats = []
|
||||
env = { IDX_OUTPUT = "table" }
|
||||
|
||||
[[case]]
|
||||
name = "stocks-quote-stdin"
|
||||
args = ["stocks", "quote", "-"]
|
||||
stdin = "BBCA\nBBRI\n"
|
||||
|
||||
[[case]]
|
||||
name = "stocks-compare-stdin"
|
||||
args = ["stocks", "compare", "-"]
|
||||
stdin = "BBCA, BBRI"
|
||||
|
||||
[[case]]
|
||||
name = "error-stdin-empty"
|
||||
args = ["stocks", "quote", "-"]
|
||||
stdin = ""
|
||||
|
||||
[[case]]
|
||||
name = "error-invalid-output-env"
|
||||
args = ["stocks", "quote", "BBCA"]
|
||||
formats = []
|
||||
env = { IDX_OUTPUT = "yaml" }
|
||||
|
||||
[[case]]
|
||||
name = "stocks-quote-offline-warm"
|
||||
args = ["--offline", "stocks", "quote", "BBCA"]
|
||||
before = [["stocks", "quote", "BBCA"]]
|
||||
|
||||
# --- stocks: Yahoo provider -----------------------------------------------------
|
||||
|
||||
[[case]]
|
||||
name = "yahoo-quote"
|
||||
args = ["stocks", "quote", "BBCA"]
|
||||
env = { IDX_PROVIDER = "yahoo" }
|
||||
|
||||
[[case]]
|
||||
name = "yahoo-history"
|
||||
args = ["stocks", "history", "BBCA"]
|
||||
env = { IDX_PROVIDER = "yahoo" }
|
||||
|
||||
[[case]]
|
||||
name = "yahoo-fundamental"
|
||||
args = ["stocks", "fundamental", "BBCA"]
|
||||
env = { IDX_PROVIDER = "yahoo" }
|
||||
|
||||
# --- errors ---------------------------------------------------------------------
|
||||
|
||||
[[case]]
|
||||
name = "error-usage-missing-symbol"
|
||||
args = ["stocks", "quote"]
|
||||
|
||||
[[case]]
|
||||
name = "error-invalid-provider"
|
||||
args = ["stocks", "quote", "BBCA"]
|
||||
env = { IDX_PROVIDER = "bogus" }
|
||||
|
||||
[[case]]
|
||||
name = "error-yahoo-profile-unsupported"
|
||||
args = ["stocks", "profile", "BBCA"]
|
||||
env = { IDX_PROVIDER = "yahoo" }
|
||||
|
||||
[[case]]
|
||||
name = "error-industry-only-fundamentals"
|
||||
args = ["stocks", "valuation", "BBCA"]
|
||||
env = { IDX_MOCK_MSN_KEYRATIOS_FIXTURE = "tests/fixtures/msn_keyratios_industry_only.json" }
|
||||
|
||||
[[case]]
|
||||
name = "error-screen-region"
|
||||
formats = ["table", "json", "jsonl"]
|
||||
args = ["stocks", "screen", "--region", "eu"]
|
||||
|
||||
[[case]]
|
||||
name = "error-offline-no-cache-flags"
|
||||
args = ["--offline", "--no-cache", "stocks", "quote", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "error-offline-cache-miss"
|
||||
args = ["--offline", "stocks", "quote", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "error-provider-failure"
|
||||
args = ["stocks", "quote", "BBCA"]
|
||||
env = { IDX_MOCK_ERROR = "1" }
|
||||
|
||||
[[case]]
|
||||
name = "error-compare-total-failure"
|
||||
args = ["stocks", "compare", "BBCA", "BBRI"]
|
||||
env = { IDX_MOCK_ERROR = "1" }
|
||||
|
||||
[[case]]
|
||||
name = "error-fetch-bing-unsupported"
|
||||
args = ["ownership", "import", "--fetch-bing", "BBCA"]
|
||||
|
||||
# --- ownership --------------------------------------------------------------------
|
||||
|
||||
[[case]]
|
||||
name = "ownership-releases-empty"
|
||||
args = ["ownership", "releases"]
|
||||
|
||||
[[case]]
|
||||
name = "ownership-ticker-empty"
|
||||
args = ["ownership", "ticker", "BBCA"]
|
||||
|
||||
[[case]]
|
||||
name = "ownership-import-xlsx"
|
||||
args = ["ownership", "import", "--file", "tests/fixtures/ksei_above1_20260831_excerpt.xlsx"]
|
||||
|
||||
[[case]]
|
||||
name = "ownership-import-archive-txt"
|
||||
args = ["ownership", "import", "--file", "tests/fixtures/ksei_balancepos_20260227_excerpt.txt"]
|
||||
|
||||
[[case]]
|
||||
name = "ownership-releases"
|
||||
args = ["ownership", "releases"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-ticker"
|
||||
args = ["ownership", "ticker", "BBCA"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-ticker-ksei"
|
||||
args = ["ownership", "ticker", "BBCA", "--source", "ksei"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-entity"
|
||||
args = ["ownership", "entity", "ANTHONI SALIM"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-search"
|
||||
args = ["ownership", "search", "salim"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-cross-holders"
|
||||
args = ["ownership", "cross-holders", "--min-tickers", "1"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-concentration"
|
||||
args = ["ownership", "concentration"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-flow"
|
||||
args = ["ownership", "flow", "BBCA"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-changes"
|
||||
formats = ["table", "json", "jsonl"]
|
||||
args = ["ownership", "changes", "--from", "2026-01-30", "--to", "2026-02-27"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-graph"
|
||||
args = ["ownership", "graph", "BBCA"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-graph-dot"
|
||||
args = ["ownership", "graph", "BBCA", "--format", "dot"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-resolve-unresolved"
|
||||
args = ["ownership", "resolve", "unresolved"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-resolve-map"
|
||||
args = ["ownership", "resolve", "map", "SALIM ANTHONI", "ANTHONI SALIM"]
|
||||
ownership = true
|
||||
|
||||
[[case]]
|
||||
name = "ownership-resolve-merge"
|
||||
args = ["ownership", "resolve", "merge", "1", "2"]
|
||||
ownership = true
|
||||
2851
crates/idx-cli/tests/golden/completions-bash.golden
Normal file
2851
crates/idx-cli/tests/golden/completions-bash.golden
Normal file
File diff suppressed because it is too large
Load diff
4
crates/idx-cli/tests/golden/config-get.golden
Normal file
4
crates/idx-cli/tests/golden/config-get.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
msn
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/config-init.golden
Normal file
4
crates/idx-cli/tests/golden/config-init.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
<ROOT>/config/idx/config.toml
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
┌─────────┬───────┬──────┬────────┬────────────┬───────────────────────┬────────────┐
|
||||
│ SYMBOL ┆ PRICE ┆ CHG ┆ CHG% ┆ VOLUME ┆ MKT CAP ┆ 52W RANGE │
|
||||
╞═════════╪═══════╪══════╪════════╪════════════╪═══════════════════════╪════════════╡
|
||||
│ BBCA.JK ┆ 9,875 ┆ +117 ┆ +1.20% ┆ 12,300,000 ┆ 1,215,200,000,000,000 ┆ ████████░░ │
|
||||
└─────────┴───────┴──────┴────────┴────────────┴───────────────────────┴────────────┘
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/config-path.golden
Normal file
4
crates/idx-cli/tests/golden/config-path.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
<ROOT>/config/idx/config.toml
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"INVALIDINPUT","error":true,"message":"invalid input: invalid output format 'yaml': expected 'auto', 'table', 'json', or 'jsonl'"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
ok
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/config-set.golden
Normal file
4
crates/idx-cli/tests/golden/config-set.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
ok
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 4
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"PROVIDERUNAVAILABLE","error":true,"message":"provider unavailable"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 4
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: provider unavailable
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 5
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"UNSUPPORTED","error":true,"message":"unsupported: --fetch-bing import is not implemented yet"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 5
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: unsupported: --fetch-bing import is not implemented yet
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 1
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"PARSEERROR","error":true,"message":"parse error: unsupported: company fundamentals unavailable from MSN; industry fallback is disabled"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 1
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: parse error: unsupported: company fundamentals unavailable from MSN; industry fallback is disabled
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"CONFIGERROR","error":true,"message":"config error: invalid IDX_OUTPUT value: 'yaml', expected 'auto', 'table', 'json', or 'jsonl'"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"CONFIGERROR","error":true,"message":"config error: invalid provider 'bogus' (expected yahoo or msn)"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: config error: invalid provider 'bogus' (expected yahoo or msn)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 3
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"CACHEMISS","error":true,"message":"cache miss: msn-quote/BBCA.JK"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 3
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: cache miss: msn-quote/BBCA.JK
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"INVALIDINPUT","error":true,"message":"invalid input: cannot combine --offline with --no-cache"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: invalid input: cannot combine --offline with --no-cache
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 4
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"PROVIDERUNAVAILABLE","error":true,"message":"provider unavailable"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 4
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: provider unavailable
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"INVALIDINPUT","error":true,"message":"invalid input: invalid screener region 'eu' (expected one of: id, us, sg, hk, jp)"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"INVALIDINPUT","error":true,"message":"invalid input: invalid screener region 'eu' (expected one of: id, us, sg, hk, jp)"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: invalid input: invalid screener region 'eu' (expected one of: id, us, sg, hk, jp)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"INVALIDINPUT","error":true,"message":"invalid input: no symbols read from stdin"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: invalid input: no symbols read from stdin
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
error: the following required arguments were not provided:
|
||||
<SYMBOLS>...
|
||||
|
||||
Usage: idx stocks quote <SYMBOLS>...
|
||||
|
||||
For more information, try '--help'.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
exit: 2
|
||||
--- stdout
|
||||
--- stderr
|
||||
error: the following required arguments were not provided:
|
||||
<SYMBOLS>...
|
||||
|
||||
Usage: idx stocks quote <SYMBOLS>...
|
||||
|
||||
For more information, try '--help'.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 5
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"UNSUPPORTED","error":true,"message":"unsupported: BBCA.JK: command requires --provider msn"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 5
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: unsupported: BBCA.JK: command requires --provider msn
|
||||
20
crates/idx-cli/tests/golden/help-cache.golden
Normal file
20
crates/idx-cli/tests/golden/help-cache.golden
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Manage local cache
|
||||
|
||||
Usage: idx cache [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
info Show cache usage information
|
||||
clear Clear all cached files
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-o, --output <OUTPUT> Output format [default: auto = table on a terminal, json when piped] [possible values: auto, table, json, jsonl]
|
||||
--no-color Disable colored output
|
||||
-q, --quiet Suppress non-essential output
|
||||
-v, --verbose... Increase verbosity (-v, -vv)
|
||||
--offline Run without network requests
|
||||
--no-cache Bypass local cache
|
||||
-h, --help Print help
|
||||
--- stderr
|
||||
22
crates/idx-cli/tests/golden/help-config.golden
Normal file
22
crates/idx-cli/tests/golden/help-config.golden
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Manage configuration
|
||||
|
||||
Usage: idx config [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
init Create default configuration file
|
||||
get Get a configuration value by key
|
||||
set Set a configuration value by key
|
||||
path Print configuration file path
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-o, --output <OUTPUT> Output format [default: auto = table on a terminal, json when piped] [possible values: auto, table, json, jsonl]
|
||||
--no-color Disable colored output
|
||||
-q, --quiet Suppress non-essential output
|
||||
-v, --verbose... Increase verbosity (-v, -vv)
|
||||
--offline Run without network requests
|
||||
--no-cache Bypass local cache
|
||||
-h, --help Print help
|
||||
--- stderr
|
||||
58
crates/idx-cli/tests/golden/help-ownership.golden
Normal file
58
crates/idx-cli/tests/golden/help-ownership.golden
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Ownership intelligence (KSEI + Bing).
|
||||
|
||||
Preferred bootstrap path:
|
||||
1. Run `idx ownership sync` to install or refresh a maintained SQLite snapshot.
|
||||
2. If no snapshot manifest is available, run `idx ownership discover` and then `idx ownership import --url <pdf-url>`.
|
||||
3. Local `.xlsx`, `.pdf`, `.zip`, and `.txt` imports remain available for manual or fallback workflows.
|
||||
|
||||
Usage: idx ownership [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
discover Discover the latest IDX-hosted ownership report URLs
|
||||
import Import ownership data directly from source files
|
||||
sync Install or refresh a maintained ownership SQLite snapshot
|
||||
ticker Show all holders for a ticker (KSEI + Bing combined)
|
||||
entity Show all holdings for an entity across tickers
|
||||
search Search entities by name
|
||||
cross-holders Rank entities by cross-ownership breadth
|
||||
concentration Rank tickers by ownership concentration
|
||||
flow Show Bing institutional flow for a ticker
|
||||
changes Diff two KSEI releases
|
||||
graph Ownership network graph
|
||||
resolve Manual entity resolution workflow
|
||||
releases List imported KSEI releases
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-o, --output <OUTPUT>
|
||||
Output format [default: auto = table on a terminal, json when piped]
|
||||
|
||||
[possible values: auto, table, json, jsonl]
|
||||
|
||||
--no-color
|
||||
Disable colored output
|
||||
|
||||
-q, --quiet
|
||||
Suppress non-essential output
|
||||
|
||||
-v, --verbose...
|
||||
Increase verbosity (-v, -vv)
|
||||
|
||||
--offline
|
||||
Run without network requests
|
||||
|
||||
--no-cache
|
||||
Bypass local cache
|
||||
|
||||
-h, --help
|
||||
Print help (see a summary with '-h')
|
||||
|
||||
Examples:
|
||||
idx ownership sync
|
||||
idx ownership sync --manifest /path/to/ownership-snapshot-manifest.json
|
||||
idx ownership discover --limit 1
|
||||
idx ownership import --url <pdf-url>
|
||||
idx ownership releases
|
||||
--- stderr
|
||||
40
crates/idx-cli/tests/golden/help-root.golden
Normal file
40
crates/idx-cli/tests/golden/help-root.golden
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
idx-cli is a Rust command-line tool for Indonesian stock market (IDX) analysis.
|
||||
It supports quote lookup, historical data, local caching, and output formats for both humans and AI agents.
|
||||
|
||||
Usage: idx [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
stocks Stock data and analysis
|
||||
config Manage configuration
|
||||
cache Manage local cache
|
||||
ownership Ownership intelligence (bootstrap with `ownership sync`)
|
||||
completions Generate shell completions
|
||||
version Show idx-cli version
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-o, --output <OUTPUT>
|
||||
Output format [default: auto = table on a terminal, json when piped]
|
||||
|
||||
[possible values: auto, table, json, jsonl]
|
||||
|
||||
--no-color
|
||||
Disable colored output
|
||||
|
||||
-q, --quiet
|
||||
Suppress non-essential output
|
||||
|
||||
-v, --verbose...
|
||||
Increase verbosity (-v, -vv)
|
||||
|
||||
--offline
|
||||
Run without network requests
|
||||
|
||||
--no-cache
|
||||
Bypass local cache
|
||||
|
||||
-h, --help
|
||||
Print help (see a summary with '-h')
|
||||
--- stderr
|
||||
33
crates/idx-cli/tests/golden/help-stocks.golden
Normal file
33
crates/idx-cli/tests/golden/help-stocks.golden
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Stock data and analysis
|
||||
|
||||
Usage: idx stocks [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
quote Get real-time stock quotes
|
||||
history Get historical OHLC data
|
||||
technical Run technical analysis on a stock
|
||||
growth Run growth analysis on a stock
|
||||
valuation Run valuation analysis on a stock
|
||||
risk Run risk analysis on a stock
|
||||
fundamental Run full fundamental analysis on a stock
|
||||
profile Get company profile
|
||||
financials Get financial statements
|
||||
earnings Get earnings report
|
||||
sentiment Get crowd sentiment
|
||||
insights Get AI insights
|
||||
news Get stock news
|
||||
screen MSN screener
|
||||
compare Compare fundamentals across stocks
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
|
||||
Options:
|
||||
-o, --output <OUTPUT> Output format [default: auto = table on a terminal, json when piped] [possible values: auto, table, json, jsonl]
|
||||
--no-color Disable colored output
|
||||
-q, --quiet Suppress non-essential output
|
||||
-v, --verbose... Increase verbosity (-v, -vv)
|
||||
--offline Run without network requests
|
||||
--no-cache Bypass local cache
|
||||
-h, --help Print help
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL ID","change_type":"decreased","old_bps":2400,"new_bps":2334,"delta_bps":-66},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL IS","change_type":"increased","old_bps":75,"new_bps":129,"delta_bps":54},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL MF","change_type":"increased","old_bps":117,"new_bps":152,"delta_bps":35},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN MF","change_type":"increased","old_bps":307,"new_bps":337,"delta_bps":30},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN OT","change_type":"decreased","old_bps":91,"new_bps":64,"delta_bps":-27},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN PF","change_type":"decreased","old_bps":76,"new_bps":56,"delta_bps":-20},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN CP","change_type":"increased","old_bps":72,"new_bps":86,"delta_bps":14},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL CP","change_type":"decreased","old_bps":6481,"new_bps":6467,"delta_bps":-14},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL SC","change_type":"decreased","old_bps":36,"new_bps":29,"delta_bps":-7},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN IB","change_type":"decreased","old_bps":267,"new_bps":263,"delta_bps":-4},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN SC","change_type":"increased","old_bps":51,"new_bps":55,"delta_bps":4},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL PF","change_type":"increased","old_bps":17,"new_bps":20,"delta_bps":3},{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN ID","change_type":"decreased","old_bps":3,"new_bps":2,"delta_bps":-1}]
|
||||
--- stderr
|
||||
16
crates/idx-cli/tests/golden/ownership-changes.jsonl.golden
Normal file
16
crates/idx-cli/tests/golden/ownership-changes.jsonl.golden
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL ID","change_type":"decreased","old_bps":2400,"new_bps":2334,"delta_bps":-66}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL IS","change_type":"increased","old_bps":75,"new_bps":129,"delta_bps":54}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL MF","change_type":"increased","old_bps":117,"new_bps":152,"delta_bps":35}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN MF","change_type":"increased","old_bps":307,"new_bps":337,"delta_bps":30}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN OT","change_type":"decreased","old_bps":91,"new_bps":64,"delta_bps":-27}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN PF","change_type":"decreased","old_bps":76,"new_bps":56,"delta_bps":-20}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN CP","change_type":"increased","old_bps":72,"new_bps":86,"delta_bps":14}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL CP","change_type":"decreased","old_bps":6481,"new_bps":6467,"delta_bps":-14}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL SC","change_type":"decreased","old_bps":36,"new_bps":29,"delta_bps":-7}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN IB","change_type":"decreased","old_bps":267,"new_bps":263,"delta_bps":-4}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN SC","change_type":"increased","old_bps":51,"new_bps":55,"delta_bps":4}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE LOCAL PF","change_type":"increased","old_bps":17,"new_bps":20,"delta_bps":3}
|
||||
{"ticker_code":"AADI","entity_name":"KSEI AGGREGATE FOREIGN ID","change_type":"decreased","old_bps":3,"new_bps":2,"delta_bps":-1}
|
||||
--- stderr
|
||||
32
crates/idx-cli/tests/golden/ownership-changes.table.golden
Normal file
32
crates/idx-cli/tests/golden/ownership-changes.table.golden
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
┌────────┬───────────────────────────┬───────────┬────────┬────────┬────────┐
|
||||
│ TICKER ┆ ENTITY ┆ CHANGE ┆ OLD% ┆ NEW% ┆ DELTA% │
|
||||
╞════════╪═══════════════════════════╪═══════════╪════════╪════════╪════════╡
|
||||
│ AADI ┆ KSEI AGGREGATE LOCAL ID ┆ DECREASED ┆ 24.00% ┆ 23.34% ┆ -0.66% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE LOCAL IS ┆ INCREASED ┆ 0.75% ┆ 1.29% ┆ +0.54% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE LOCAL MF ┆ INCREASED ┆ 1.17% ┆ 1.52% ┆ +0.35% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE FOREIGN MF ┆ INCREASED ┆ 3.07% ┆ 3.37% ┆ +0.30% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE FOREIGN OT ┆ DECREASED ┆ 0.91% ┆ 0.64% ┆ -0.27% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE FOREIGN PF ┆ DECREASED ┆ 0.76% ┆ 0.56% ┆ -0.20% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE FOREIGN CP ┆ INCREASED ┆ 0.72% ┆ 0.86% ┆ +0.14% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE LOCAL CP ┆ DECREASED ┆ 64.81% ┆ 64.67% ┆ -0.14% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE LOCAL SC ┆ DECREASED ┆ 0.36% ┆ 0.29% ┆ -0.07% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE FOREIGN IB ┆ DECREASED ┆ 2.67% ┆ 2.63% ┆ -0.04% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE FOREIGN SC ┆ INCREASED ┆ 0.51% ┆ 0.55% ┆ +0.04% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE LOCAL PF ┆ INCREASED ┆ 0.17% ┆ 0.20% ┆ +0.03% │
|
||||
├╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ AADI ┆ KSEI AGGREGATE FOREIGN ID ┆ DECREASED ┆ 0.03% ┆ 0.02% ┆ -0.01% │
|
||||
└────────┴───────────────────────────┴───────────┴────────┴────────┴────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[["AALI",{"top1_bps":7968,"top3_bps":7968,"hhi":6348,"free_float_bps":2032,"holder_count":1}],["BBCA",{"top1_bps":5494,"top3_bps":5716,"hhi":3021,"free_float_bps":4182,"holder_count":4}],["AADI",{"top1_bps":4110,"top3_bps":6230,"hhi":2009,"free_float_bps":2030,"holder_count":10}],["ABBA",{"top1_bps":283,"top3_bps":418,"hhi":9,"free_float_bps":9582,"holder_count":2}]]
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
┌──────┬────────┬────────┬────────┬──────┬─────────────┬─────────┐
|
||||
│ RANK ┆ TICKER ┆ TOP1% ┆ TOP3% ┆ HHI ┆ FREE_FLOAT% ┆ HOLDERS │
|
||||
╞══════╪════════╪════════╪════════╪══════╪═════════════╪═════════╡
|
||||
│ 1 ┆ AALI ┆ 79.68% ┆ 79.68% ┆ 6348 ┆ 20.32% ┆ 1 │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
|
||||
│ 2 ┆ BBCA ┆ 54.94% ┆ 57.16% ┆ 3021 ┆ 41.82% ┆ 4 │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
|
||||
│ 3 ┆ AADI ┆ 41.10% ┆ 62.30% ┆ 2009 ┆ 20.30% ┆ 10 │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
|
||||
│ 4 ┆ ABBA ┆ 2.83% ┆ 4.18% ┆ 9 ┆ 95.82% ┆ 2 │
|
||||
└──────┴────────┴────────┴────────┴──────┴─────────────┴─────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[{"entity":{"id":11,"canonical_name":"ASTRA INTERNATIONAL","entity_type":null,"country":null},"ticker_count":1,"total_bps":7968},{"entity":{"id":14,"canonical_name":"DWIMURIA INVESTAMA ANDALAN","entity_type":null,"country":null},"ticker_count":1,"total_bps":5494},{"entity":{"id":4,"canonical_name":"ADARO STRATEGIC INVESTMENTS","entity_type":null,"country":null},"ticker_count":1,"total_bps":4110},{"entity":{"id":5,"canonical_name":"ALAMTRI RESOURCES INDONESIA TBK PT","entity_type":null,"country":null},"ticker_count":1,"total_bps":1537},{"entity":{"id":7,"canonical_name":"GARIBALDI THOHIR","entity_type":null,"country":null},"ticker_count":1,"total_bps":583},{"entity":{"id":2,"canonical_name":"SARATOGA INVESTAMA SEDAYA","entity_type":null,"country":null},"ticker_count":1,"total_bps":438},{"entity":{"id":9,"canonical_name":"EDWIN SOERYADJAYA","entity_type":null,"country":null},"ticker_count":1,"total_bps":352},{"entity":{"id":8,"canonical_name":"IR. T. PERMADI RACHMAT","entity_type":null,"country":null},"ticker_count":1,"total_bps":348},{"entity":{"id":13,"canonical_name":"YAYASAN ABDI BANGSA","entity_type":null,"country":null},"ticker_count":1,"total_bps":283},{"entity":{"id":10,"canonical_name":"SANDIAGA SALAHUDDIN UNO","entity_type":null,"country":null},"ticker_count":1,"total_bps":204},{"entity":{"id":1,"canonical_name":"PERSADA CAPITAL INVESTAMA","entity_type":null,"country":null},"ticker_count":1,"total_bps":154},{"entity":{"id":12,"canonical_name":"YAYASAN BINA SEJAHTERA WARGA BULOG","entity_type":null,"country":null},"ticker_count":1,"total_bps":135},{"entity":{"id":6,"canonical_name":"FTAG INVESTMENT BANK","entity_type":null,"country":null},"ticker_count":1,"total_bps":129},{"entity":{"id":17,"canonical_name":"ANTHONI SALIM","entity_type":null,"country":null},"ticker_count":1,"total_bps":115},{"entity":{"id":3,"canonical_name":"TRINUGRAHA THOHIR","entity_type":null,"country":null},"ticker_count":1,"total_bps":115},{"entity":{"id":16,"canonical_name":"TRICIPTA MANDHALA GUMILANG","entity_type":null,"country":null},"ticker_count":1,"total_bps":107},{"entity":{"id":15,"canonical_name":"CATURGUWIRATNA SUMAPALA","entity_type":null,"country":null},"ticker_count":1,"total_bps":102}]
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
┌──────┬────────────────────────────────────┬─────────┬───────────┐
|
||||
│ RANK ┆ ENTITY ┆ TICKERS ┆ TOTAL_BPS │
|
||||
╞══════╪════════════════════════════════════╪═════════╪═══════════╡
|
||||
│ 1 ┆ ASTRA INTERNATIONAL ┆ 1 ┆ 79.68% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 2 ┆ DWIMURIA INVESTAMA ANDALAN ┆ 1 ┆ 54.94% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 3 ┆ ADARO STRATEGIC INVESTMENTS ┆ 1 ┆ 41.10% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 4 ┆ ALAMTRI RESOURCES INDONESIA TBK PT ┆ 1 ┆ 15.37% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 5 ┆ GARIBALDI THOHIR ┆ 1 ┆ 5.83% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 6 ┆ SARATOGA INVESTAMA SEDAYA ┆ 1 ┆ 4.38% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 7 ┆ EDWIN SOERYADJAYA ┆ 1 ┆ 3.52% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 8 ┆ IR. T. PERMADI RACHMAT ┆ 1 ┆ 3.48% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 9 ┆ YAYASAN ABDI BANGSA ┆ 1 ┆ 2.83% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 10 ┆ SANDIAGA SALAHUDDIN UNO ┆ 1 ┆ 2.04% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 11 ┆ PERSADA CAPITAL INVESTAMA ┆ 1 ┆ 1.54% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 12 ┆ YAYASAN BINA SEJAHTERA WARGA BULOG ┆ 1 ┆ 1.35% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 13 ┆ FTAG INVESTMENT BANK ┆ 1 ┆ 1.29% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 14 ┆ ANTHONI SALIM ┆ 1 ┆ 1.15% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 15 ┆ TRINUGRAHA THOHIR ┆ 1 ┆ 1.15% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 16 ┆ TRICIPTA MANDHALA GUMILANG ┆ 1 ┆ 1.07% │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 17 ┆ CATURGUWIRATNA SUMAPALA ┆ 1 ┆ 1.02% │
|
||||
└──────┴────────────────────────────────────┴─────────┴───────────┘
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/ownership-entity.json.golden
Normal file
4
crates/idx-cli/tests/golden/ownership-entity.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"entity":{"id":17,"canonical_name":"ANTHONI SALIM","entity_type":null,"country":null},"ticker_count":1,"holdings":[{"ticker":{"id":4,"code":"BBCA","name":"BANK CENTRAL ASIA Tbk","sector":null},"source":"ksei","shares":1416306835,"percentage_bps":115,"report_date":"2026-08-31"}]}
|
||||
--- stderr
|
||||
10
crates/idx-cli/tests/golden/ownership-entity.table.golden
Normal file
10
crates/idx-cli/tests/golden/ownership-entity.table.golden
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Entity: ANTHONI SALIM
|
||||
┌────────┬────────┬───────────────┬───────┬─────────────┐
|
||||
│ TICKER ┆ SOURCE ┆ SHARES ┆ % ┆ REPORT_DATE │
|
||||
╞════════╪════════╪═══════════════╪═══════╪═════════════╡
|
||||
│ BBCA ┆ KSEI ┆ 1,416,306,835 ┆ 1.15% ┆ 2026-08-31 │
|
||||
└────────┴────────┴───────────────┴───────┴─────────────┘
|
||||
Total tickers: 1
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/ownership-flow.json.golden
Normal file
4
crates/idx-cli/tests/golden/ownership-flow.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
null
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/ownership-flow.table.golden
Normal file
4
crates/idx-cli/tests/golden/ownership-flow.table.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
No institutional flow data available for BBCA.
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"nodes":[{"id":"entity:14","label":"DWIMURIA INVESTAMA ANDALAN","node_type":"entity"},{"id":"entity:15","label":"CATURGUWIRATNA SUMAPALA","node_type":"entity"},{"id":"entity:16","label":"TRICIPTA MANDHALA GUMILANG","node_type":"entity"},{"id":"entity:17","label":"ANTHONI SALIM","node_type":"entity"},{"id":"ticker:BBCA","label":"BBCA","node_type":"ticker"}],"edges":[{"from":"entity:17","to":"ticker:BBCA","percentage_bps":115,"source":"ksei"},{"from":"entity:15","to":"ticker:BBCA","percentage_bps":102,"source":"ksei"},{"from":"entity:14","to":"ticker:BBCA","percentage_bps":5494,"source":"ksei"},{"from":"entity:16","to":"ticker:BBCA","percentage_bps":107,"source":"ksei"}]}
|
||||
--- stderr
|
||||
20
crates/idx-cli/tests/golden/ownership-graph-dot.table.golden
Normal file
20
crates/idx-cli/tests/golden/ownership-graph-dot.table.golden
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
digraph ownership {
|
||||
rankdir=LR;
|
||||
graph [fontname="Helvetica"];
|
||||
node [fontname="Helvetica"];
|
||||
edge [fontname="Helvetica"];
|
||||
|
||||
"entity:14" [label="DWIMURIA INVESTAMA ANDALAN", shape=ellipse];
|
||||
"entity:15" [label="CATURGUWIRATNA SUMAPALA", shape=ellipse];
|
||||
"entity:16" [label="TRICIPTA MANDHALA GUMILANG", shape=ellipse];
|
||||
"entity:17" [label="ANTHONI SALIM", shape=ellipse];
|
||||
"ticker:BBCA" [label="BBCA", shape=box];
|
||||
|
||||
"entity:17" -> "ticker:BBCA" [label="1.15% (ksei)"];
|
||||
"entity:15" -> "ticker:BBCA" [label="1.02% (ksei)"];
|
||||
"entity:14" -> "ticker:BBCA" [label="54.94% (ksei)"];
|
||||
"entity:16" -> "ticker:BBCA" [label="1.07% (ksei)"];
|
||||
}
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/ownership-graph.json.golden
Normal file
4
crates/idx-cli/tests/golden/ownership-graph.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"nodes":[{"id":"entity:14","label":"DWIMURIA INVESTAMA ANDALAN","node_type":"entity"},{"id":"entity:15","label":"CATURGUWIRATNA SUMAPALA","node_type":"entity"},{"id":"entity:16","label":"TRICIPTA MANDHALA GUMILANG","node_type":"entity"},{"id":"entity:17","label":"ANTHONI SALIM","node_type":"entity"},{"id":"ticker:BBCA","label":"BBCA","node_type":"ticker"}],"edges":[{"from":"entity:17","to":"ticker:BBCA","percentage_bps":115,"source":"ksei"},{"from":"entity:15","to":"ticker:BBCA","percentage_bps":102,"source":"ksei"},{"from":"entity:14","to":"ticker:BBCA","percentage_bps":5494,"source":"ksei"},{"from":"entity:16","to":"ticker:BBCA","percentage_bps":107,"source":"ksei"}]}
|
||||
--- stderr
|
||||
10
crates/idx-cli/tests/golden/ownership-graph.table.golden
Normal file
10
crates/idx-cli/tests/golden/ownership-graph.table.golden
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
nodes: 5 edges: 4
|
||||
|
||||
BBCA [TICKER]
|
||||
├─ DWIMURIA INVESTAMA ANDALAN (54.94%, ksei)
|
||||
├─ ANTHONI SALIM (1.15%, ksei)
|
||||
├─ TRICIPTA MANDHALA GUMILANG (1.07%, ksei)
|
||||
└─ CATURGUWIRATNA SUMAPALA (1.02%, ksei)
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"action":"imported","inserted_rows":18,"ticker_count":1,"as_of_date":"2026-02-27","sha256":"7b8da1d820f67062410c48988bb6c70fec2088c24961d481d1c0fce8b9372547","source_url":null}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Imported 18 rows for 1 tickers (as of 2026-02-27).
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"action":"imported","inserted_rows":17,"ticker_count":4,"as_of_date":"2026-08-31","sha256":"7c1a4c209b8ce5bde9112436a0c64d66b042915995b584d2bbf7ca7b15ce81e3","source_url":null}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Imported 17 rows for 4 tickers (as of 2026-08-31).
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[]
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
No ownership releases imported yet.
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[{"id":1,"source_url":null,"sha256":"7c1a4c209b8ce5bde9112436a0c64d66b042915995b584d2bbf7ca7b15ce81e3","as_of_date":"2026-08-31","row_count":17,"imported_at":0},{"id":3,"source_url":null,"sha256":"7b8da1d820f67062410c48988bb6c70fec2088c24961d481d1c0fce8b9372547","as_of_date":"2026-02-27","row_count":18,"imported_at":0},{"id":2,"source_url":null,"sha256":"efb3d8fb19c9e0d803dc1b1734c8389356605d0f78d73db6729fb76d3d75753d","as_of_date":"2026-01-30","row_count":18,"imported_at":0}]
|
||||
--- stderr
|
||||
12
crates/idx-cli/tests/golden/ownership-releases.table.golden
Normal file
12
crates/idx-cli/tests/golden/ownership-releases.table.golden
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
┌────────────┬──────┬──────────────────────────────────────────────────────────────────┬────────┬─────────────┐
|
||||
│ AS_OF ┆ ROWS ┆ SHA256 ┆ SOURCE ┆ IMPORTED_AT │
|
||||
╞════════════╪══════╪══════════════════════════════════════════════════════════════════╪════════╪═════════════╡
|
||||
│ 2026-08-31 ┆ 17 ┆ 7c1a4c209b8ce5bde9112436a0c64d66b042915995b584d2bbf7ca7b15ce81e3 ┆ - ┆ 0 │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 2026-02-27 ┆ 18 ┆ 7b8da1d820f67062410c48988bb6c70fec2088c24961d481d1c0fce8b9372547 ┆ - ┆ 0 │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ 2026-01-30 ┆ 18 ┆ efb3d8fb19c9e0d803dc1b1734c8389356605d0f78d73db6729fb76d3d75753d ┆ - ┆ 0 │
|
||||
└────────────┴──────┴──────────────────────────────────────────────────────────────────┴────────┴─────────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"action":"mapped","alias":"SALIM ANTHONI","entity":"ANTHONI SALIM"}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Mapped alias 'SALIM ANTHONI' -> 'ANTHONI SALIM'.
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"action":"merged","alias_updates":1,"bing_holdings_updates":0,"keep":1,"ksei_holdings_updates":1,"merge":2}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Merged entity 2 into 1 (aliases: 1, ksei_holdings: 1, bing_holdings: 0).
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[]
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
No unresolved or low-confidence aliases found.
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/ownership-search.json.golden
Normal file
4
crates/idx-cli/tests/golden/ownership-search.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[{"id":17,"canonical_name":"ANTHONI SALIM","entity_type":null,"country":null}]
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
┌───────────────┬──────┬─────────┐
|
||||
│ ENTITY ┆ TYPE ┆ COUNTRY │
|
||||
╞═══════════════╪══════╪═════════╡
|
||||
│ ANTHONI SALIM ┆ - ┆ - │
|
||||
└───────────────┴──────┴─────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 3
|
||||
--- stdout
|
||||
--- stderr
|
||||
{"code":"SYMBOLNOTFOUND","error":true,"message":"symbol not found: BBCA"}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 3
|
||||
--- stdout
|
||||
--- stderr
|
||||
Error: symbol not found: BBCA
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"ticker":{"id":4,"code":"BBCA","name":"BANK CENTRAL ASIA Tbk","sector":null},"ksei_as_of":"2026-08-31","bing_as_of":null,"holders":[{"rank":1,"source":"ksei","name":"DWIMURIA INVESTAMA ANDALAN","entity_id":14,"investor_type":"CORPORATE","locality":"Local","shares":67729950000,"percentage_bps":5494,"signal":null},{"rank":2,"source":"ksei","name":"ANTHONI SALIM","entity_id":17,"investor_type":"INDIVIDUAL","locality":"Local","shares":1416306835,"percentage_bps":115,"signal":null},{"rank":3,"source":"ksei","name":"TRICIPTA MANDHALA GUMILANG","entity_id":16,"investor_type":"CORPORATE","locality":"Local","shares":1313250000,"percentage_bps":107,"signal":null},{"rank":4,"source":"ksei","name":"CATURGUWIRATNA SUMAPALA","entity_id":15,"investor_type":"CORPORATE","locality":"Local","shares":1261750000,"percentage_bps":102,"signal":null}],"concentration":{"top1_bps":5494,"top3_bps":5716,"hhi":3021,"free_float_bps":4182,"holder_count":4},"flow":null}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Ownership: BBCA KSEI=2026-08-31 Bing=-
|
||||
┌──────┬────────┬────────────────────────────┬────────────┬─────┬────────────────┬────────┬────────┐
|
||||
│ RANK ┆ SOURCE ┆ INVESTOR ┆ TYPE ┆ L/F ┆ SHARES ┆ % ┆ SIGNAL │
|
||||
╞══════╪════════╪════════════════════════════╪════════════╪═════╪════════════════╪════════╪════════╡
|
||||
│ 1 ┆ KSEI ┆ DWIMURIA INVESTAMA ANDALAN ┆ CORPORATE ┆ L ┆ 67,729,950,000 ┆ 54.94% ┆ - │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ 2 ┆ KSEI ┆ ANTHONI SALIM ┆ INDIVIDUAL ┆ L ┆ 1,416,306,835 ┆ 1.15% ┆ - │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ 3 ┆ KSEI ┆ TRICIPTA MANDHALA GUMILANG ┆ CORPORATE ┆ L ┆ 1,313,250,000 ┆ 1.07% ┆ - │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ 4 ┆ KSEI ┆ CATURGUWIRATNA SUMAPALA ┆ CORPORATE ┆ L ┆ 1,261,750,000 ┆ 1.02% ┆ - │
|
||||
└──────┴────────┴────────────────────────────┴────────────┴─────┴────────────────┴────────┴────────┘
|
||||
Concentration: top1=54.94% top3=57.16% hhi=3021 free_float=41.82% holders=4
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/ownership-ticker.json.golden
Normal file
4
crates/idx-cli/tests/golden/ownership-ticker.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"ticker":{"id":4,"code":"BBCA","name":"BANK CENTRAL ASIA Tbk","sector":null},"ksei_as_of":"2026-08-31","bing_as_of":null,"holders":[{"rank":1,"source":"ksei","name":"DWIMURIA INVESTAMA ANDALAN","entity_id":14,"investor_type":"CORPORATE","locality":"Local","shares":67729950000,"percentage_bps":5494,"signal":null},{"rank":2,"source":"ksei","name":"ANTHONI SALIM","entity_id":17,"investor_type":"INDIVIDUAL","locality":"Local","shares":1416306835,"percentage_bps":115,"signal":null},{"rank":3,"source":"ksei","name":"TRICIPTA MANDHALA GUMILANG","entity_id":16,"investor_type":"CORPORATE","locality":"Local","shares":1313250000,"percentage_bps":107,"signal":null},{"rank":4,"source":"ksei","name":"CATURGUWIRATNA SUMAPALA","entity_id":15,"investor_type":"CORPORATE","locality":"Local","shares":1261750000,"percentage_bps":102,"signal":null}],"concentration":{"top1_bps":5494,"top3_bps":5716,"hhi":3021,"free_float_bps":4182,"holder_count":4},"flow":null}
|
||||
--- stderr
|
||||
16
crates/idx-cli/tests/golden/ownership-ticker.table.golden
Normal file
16
crates/idx-cli/tests/golden/ownership-ticker.table.golden
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Ownership: BBCA KSEI=2026-08-31 Bing=-
|
||||
┌──────┬────────┬────────────────────────────┬────────────┬─────┬────────────────┬────────┬────────┐
|
||||
│ RANK ┆ SOURCE ┆ INVESTOR ┆ TYPE ┆ L/F ┆ SHARES ┆ % ┆ SIGNAL │
|
||||
╞══════╪════════╪════════════════════════════╪════════════╪═════╪════════════════╪════════╪════════╡
|
||||
│ 1 ┆ KSEI ┆ DWIMURIA INVESTAMA ANDALAN ┆ CORPORATE ┆ L ┆ 67,729,950,000 ┆ 54.94% ┆ - │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ 2 ┆ KSEI ┆ ANTHONI SALIM ┆ INDIVIDUAL ┆ L ┆ 1,416,306,835 ┆ 1.15% ┆ - │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ 3 ┆ KSEI ┆ TRICIPTA MANDHALA GUMILANG ┆ CORPORATE ┆ L ┆ 1,313,250,000 ┆ 1.07% ┆ - │
|
||||
├╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
|
||||
│ 4 ┆ KSEI ┆ CATURGUWIRATNA SUMAPALA ┆ CORPORATE ┆ L ┆ 1,261,750,000 ┆ 1.02% ┆ - │
|
||||
└──────┴────────┴────────────────────────────┴────────────┴─────┴────────────────┴────────┴────────┘
|
||||
Concentration: top1=54.94% top3=57.16% hhi=3021 free_float=41.82% holders=4
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[{"symbol":"BBCA.JK","growth":{"revenue_growth":0.081,"earnings_growth":0.121,"revenue_growth_pct":8.1,"earnings_growth_pct":12.1,"revenue_signal":"slow","earnings_signal":"moderate","overall_signal":"mixed"},"valuation":{"pe_trailing":25.4,"pe_forward":null,"pb":4.6,"roe":0.198,"roe_pct":19.8,"net_margin":0.324,"net_margin_pct":32.4,"ev_ebitda":null,"pe_signal":"premium","pb_signal":"expensive","roe_signal":"strong","margin_signal":"excellent","ev_ebitda_signal":"no data","overall_signal":"expensive"},"risk":{"debt_to_equity":0.42,"current_ratio":1.18,"roa":0.031,"roa_pct":3.1,"de_signal":"conservative","current_ratio_signal":"tight","overall_signal":"moderate risk"},"overall_signal":"mixed"},{"symbol":"BBRI.JK","growth":{"revenue_growth":0.081,"earnings_growth":0.121,"revenue_growth_pct":8.1,"earnings_growth_pct":12.1,"revenue_signal":"slow","earnings_signal":"moderate","overall_signal":"mixed"},"valuation":{"pe_trailing":25.4,"pe_forward":null,"pb":4.6,"roe":0.198,"roe_pct":19.8,"net_margin":0.324,"net_margin_pct":32.4,"ev_ebitda":null,"pe_signal":"premium","pb_signal":"expensive","roe_signal":"strong","margin_signal":"excellent","ev_ebitda_signal":"no data","overall_signal":"expensive"},"risk":{"debt_to_equity":0.42,"current_ratio":1.18,"roa":0.031,"roa_pct":3.1,"de_signal":"conservative","current_ratio_signal":"tight","overall_signal":"moderate risk"},"overall_signal":"mixed"}]
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Fundamental Comparison
|
||||
┌────────────────┬───────────────┬───────────────┐
|
||||
│ METRIC ┆ BBCA.JK ┆ BBRI.JK │
|
||||
╞════════════════╪═══════════════╪═══════════════╡
|
||||
│ Symbol ┆ BBCA.JK ┆ BBRI.JK │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Overall ┆ mixed ┆ mixed │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Growth ┆ mixed ┆ mixed │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Valuation ┆ expensive ┆ expensive │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Risk ┆ moderate risk ┆ moderate risk │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ P/E ┆ 25.40 ┆ 25.40 │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ ROE ┆ +19.80% ┆ +19.80% │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Revenue Growth ┆ +8.10% ┆ +8.10% │
|
||||
└────────────────┴───────────────┴───────────────┘
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/stocks-compare.json.golden
Normal file
4
crates/idx-cli/tests/golden/stocks-compare.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
[{"symbol":"BBCA.JK","growth":{"revenue_growth":0.081,"earnings_growth":0.121,"revenue_growth_pct":8.1,"earnings_growth_pct":12.1,"revenue_signal":"slow","earnings_signal":"moderate","overall_signal":"mixed"},"valuation":{"pe_trailing":25.4,"pe_forward":null,"pb":4.6,"roe":0.198,"roe_pct":19.8,"net_margin":0.324,"net_margin_pct":32.4,"ev_ebitda":null,"pe_signal":"premium","pb_signal":"expensive","roe_signal":"strong","margin_signal":"excellent","ev_ebitda_signal":"no data","overall_signal":"expensive"},"risk":{"debt_to_equity":0.42,"current_ratio":1.18,"roa":0.031,"roa_pct":3.1,"de_signal":"conservative","current_ratio_signal":"tight","overall_signal":"moderate risk"},"overall_signal":"mixed"},{"symbol":"BBRI.JK","growth":{"revenue_growth":0.081,"earnings_growth":0.121,"revenue_growth_pct":8.1,"earnings_growth_pct":12.1,"revenue_signal":"slow","earnings_signal":"moderate","overall_signal":"mixed"},"valuation":{"pe_trailing":25.4,"pe_forward":null,"pb":4.6,"roe":0.198,"roe_pct":19.8,"net_margin":0.324,"net_margin_pct":32.4,"ev_ebitda":null,"pe_signal":"premium","pb_signal":"expensive","roe_signal":"strong","margin_signal":"excellent","ev_ebitda_signal":"no data","overall_signal":"expensive"},"risk":{"debt_to_equity":0.42,"current_ratio":1.18,"roa":0.031,"roa_pct":3.1,"de_signal":"conservative","current_ratio_signal":"tight","overall_signal":"moderate risk"},"overall_signal":"mixed"}]
|
||||
--- stderr
|
||||
23
crates/idx-cli/tests/golden/stocks-compare.table.golden
Normal file
23
crates/idx-cli/tests/golden/stocks-compare.table.golden
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Fundamental Comparison
|
||||
┌────────────────┬───────────────┬───────────────┐
|
||||
│ METRIC ┆ BBCA.JK ┆ BBRI.JK │
|
||||
╞════════════════╪═══════════════╪═══════════════╡
|
||||
│ Symbol ┆ BBCA.JK ┆ BBRI.JK │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Overall ┆ mixed ┆ mixed │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Growth ┆ mixed ┆ mixed │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Valuation ┆ expensive ┆ expensive │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Risk ┆ moderate risk ┆ moderate risk │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ P/E ┆ 25.40 ┆ 25.40 │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ ROE ┆ +19.80% ┆ +19.80% │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Revenue Growth ┆ +8.10% ┆ +8.10% │
|
||||
└────────────────┴───────────────┴───────────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"symbol":"BBCA.JK","eps_last_year":1200.0,"revenue_last_year":100000000000.0,"forecast":[{"eps_actual":null,"eps_forecast":1300.0,"eps_surprise":null,"eps_surprise_pct":null,"revenue_actual":null,"revenue_forecast":110000000000.0,"revenue_surprise":null,"earning_release_date":"2026-03-15","period_type":"2026"}],"history":[]}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
|
||||
── Earnings Forecast ──
|
||||
┌────────┬─────────┬─────────────────┬────────────┐
|
||||
│ PERIOD ┆ EPS FC ┆ REV FC ┆ DATE │
|
||||
╞════════╪═════════╪═════════════════╪════════════╡
|
||||
│ FY2026 ┆ 1300.00 ┆ 110,000,000,000 ┆ 2026-03-15 │
|
||||
└────────┴─────────┴─────────────────┴────────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"symbol":"BBCA.JK","eps_last_year":1200.0,"revenue_last_year":100000000000.0,"forecast":[],"history":[{"eps_actual":320.0,"eps_forecast":null,"eps_surprise":5.0,"eps_surprise_pct":1.5,"revenue_actual":27000000000.0,"revenue_forecast":null,"revenue_surprise":200000000.0,"earning_release_date":"2025-11-20","period_type":"Q42025"}]}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
── Earnings History ──
|
||||
┌─────────┬─────────┬────────┬──────────┬───────────┬────────────────┬────────────┐
|
||||
│ PERIOD ┆ EPS ACT ┆ EPS FC ┆ SURPRISE ┆ SURPRISE% ┆ REV ACT ┆ DATE │
|
||||
╞═════════╪═════════╪════════╪══════════╪═══════════╪════════════════╪════════════╡
|
||||
│ Q4 2025 ┆ 320.00 ┆ - ┆ 5.00 ┆ 1.50 ┆ 27,000,000,000 ┆ 2025-11-20 │
|
||||
└─────────┴─────────┴────────┴──────────┴───────────┴────────────────┴────────────┘
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/stocks-earnings.json.golden
Normal file
4
crates/idx-cli/tests/golden/stocks-earnings.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"symbol":"BBCA.JK","eps_last_year":1200.0,"revenue_last_year":100000000000.0,"forecast":[{"eps_actual":null,"eps_forecast":1300.0,"eps_surprise":null,"eps_surprise_pct":null,"revenue_actual":null,"revenue_forecast":110000000000.0,"revenue_surprise":null,"earning_release_date":"2026-03-15","period_type":"2026"},{"eps_actual":null,"eps_forecast":330.0,"eps_surprise":null,"eps_surprise_pct":null,"revenue_actual":null,"revenue_forecast":28000000000.0,"revenue_surprise":null,"earning_release_date":"2026-04-20","period_type":"Q12026"}],"history":[{"eps_actual":1250.0,"eps_forecast":null,"eps_surprise":20.0,"eps_surprise_pct":1.6,"revenue_actual":105000000000.0,"revenue_forecast":null,"revenue_surprise":500000000.0,"earning_release_date":"2025-03-15","period_type":"2025"},{"eps_actual":320.0,"eps_forecast":null,"eps_surprise":5.0,"eps_surprise_pct":1.5,"revenue_actual":27000000000.0,"revenue_forecast":null,"revenue_surprise":200000000.0,"earning_release_date":"2025-11-20","period_type":"Q42025"}]}
|
||||
--- stderr
|
||||
20
crates/idx-cli/tests/golden/stocks-earnings.table.golden
Normal file
20
crates/idx-cli/tests/golden/stocks-earnings.table.golden
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
── Earnings History ──
|
||||
┌─────────┬─────────┬────────┬──────────┬───────────┬─────────────────┬────────────┐
|
||||
│ PERIOD ┆ EPS ACT ┆ EPS FC ┆ SURPRISE ┆ SURPRISE% ┆ REV ACT ┆ DATE │
|
||||
╞═════════╪═════════╪════════╪══════════╪═══════════╪═════════════════╪════════════╡
|
||||
│ FY2025 ┆ 1250.00 ┆ - ┆ 20.00 ┆ 1.60 ┆ 105,000,000,000 ┆ 2025-03-15 │
|
||||
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Q4 2025 ┆ 320.00 ┆ - ┆ 5.00 ┆ 1.50 ┆ 27,000,000,000 ┆ 2025-11-20 │
|
||||
└─────────┴─────────┴────────┴──────────┴───────────┴─────────────────┴────────────┘
|
||||
|
||||
── Earnings Forecast ──
|
||||
┌─────────┬─────────┬─────────────────┬────────────┐
|
||||
│ PERIOD ┆ EPS FC ┆ REV FC ┆ DATE │
|
||||
╞═════════╪═════════╪═════════════════╪════════════╡
|
||||
│ FY2026 ┆ 1300.00 ┆ 110,000,000,000 ┆ 2026-03-15 │
|
||||
├╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Q1 2026 ┆ 330.00 ┆ 28,000,000,000 ┆ 2026-04-20 │
|
||||
└─────────┴─────────┴─────────────────┴────────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"instrument":{"id":"bn91jc","symbol":"BBCA.JK","name":"Bank Central Asia Tbk PT"},"balance_sheet":null,"cash_flow":null,"income_statement":{"values":{"netIncome":400000000.0,"totalRevenue":1000000000.0},"currency":"IDR","report_date":"2025-12-31","end_date":"2025-12-31"}}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
|
||||
── Income Statement (2025-12-31) ──
|
||||
┌───────────────┬───────────────┐
|
||||
│ LINE ITEM ┆ VALUE (IDR) │
|
||||
╞═══════════════╪═══════════════╡
|
||||
│ Net Income ┆ 400,000,000 │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Total Revenue ┆ 1,000,000,000 │
|
||||
└───────────────┴───────────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"instrument":{"id":"bn91jc","symbol":"BBCA.JK","name":"Bank Central Asia Tbk PT"},"balance_sheet":{"values":{"cashAndShortTermInvestments":500000000.0,"totalEquity":900000000.0},"currency":"IDR","report_date":"2025-12-31","end_date":"2025-12-31"},"cash_flow":{"values":{"operatingCashFlow":600000000.0},"currency":"IDR","report_date":"2025-12-31","end_date":"2025-12-31"},"income_statement":{"values":{"netIncome":400000000.0,"totalRevenue":1000000000.0},"currency":"IDR","report_date":"2025-12-31","end_date":"2025-12-31"}}
|
||||
--- stderr
|
||||
28
crates/idx-cli/tests/golden/stocks-financials.table.golden
Normal file
28
crates/idx-cli/tests/golden/stocks-financials.table.golden
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
|
||||
── Income Statement (2025-12-31) ──
|
||||
┌───────────────┬───────────────┐
|
||||
│ LINE ITEM ┆ VALUE (IDR) │
|
||||
╞═══════════════╪═══════════════╡
|
||||
│ Net Income ┆ 400,000,000 │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Total Revenue ┆ 1,000,000,000 │
|
||||
└───────────────┴───────────────┘
|
||||
|
||||
── Balance Sheet (2025-12-31) ──
|
||||
┌─────────────────────────────────┬─────────────┐
|
||||
│ LINE ITEM ┆ VALUE (IDR) │
|
||||
╞═════════════════════════════════╪═════════════╡
|
||||
│ Cash And Short Term Investments ┆ 500,000,000 │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Total Equity ┆ 900,000,000 │
|
||||
└─────────────────────────────────┴─────────────┘
|
||||
|
||||
── Cash Flow (2025-12-31) ──
|
||||
┌─────────────────────┬─────────────┐
|
||||
│ LINE ITEM ┆ VALUE (IDR) │
|
||||
╞═════════════════════╪═════════════╡
|
||||
│ Operating Cash Flow ┆ 600,000,000 │
|
||||
└─────────────────────┴─────────────┘
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"symbol":"BBCA.JK","growth":{"revenue_growth":0.081,"earnings_growth":0.121,"revenue_growth_pct":8.1,"earnings_growth_pct":12.1,"revenue_signal":"slow","earnings_signal":"moderate","overall_signal":"mixed"},"valuation":{"pe_trailing":25.4,"pe_forward":null,"pb":4.6,"roe":0.198,"roe_pct":19.8,"net_margin":0.324,"net_margin_pct":32.4,"ev_ebitda":null,"pe_signal":"premium","pb_signal":"expensive","roe_signal":"strong","margin_signal":"excellent","ev_ebitda_signal":"no data","overall_signal":"expensive"},"risk":{"debt_to_equity":0.42,"current_ratio":1.18,"roa":0.031,"roa_pct":3.1,"de_signal":"conservative","current_ratio_signal":"tight","overall_signal":"moderate risk"},"overall_signal":"mixed"}
|
||||
--- stderr
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"symbol":"BBCA.JK","growth":{"revenue_growth":0.081,"earnings_growth":0.121,"revenue_growth_pct":8.1,"earnings_growth_pct":12.1,"revenue_signal":"slow","earnings_signal":"moderate","overall_signal":"mixed"},"valuation":{"pe_trailing":25.4,"pe_forward":null,"pb":4.6,"roe":0.198,"roe_pct":19.8,"net_margin":0.324,"net_margin_pct":32.4,"ev_ebitda":null,"pe_signal":"premium","pb_signal":"expensive","roe_signal":"strong","margin_signal":"excellent","ev_ebitda_signal":"no data","overall_signal":"expensive"},"risk":{"debt_to_equity":0.42,"current_ratio":1.18,"roa":0.031,"roa_pct":3.1,"de_signal":"conservative","current_ratio_signal":"tight","overall_signal":"moderate risk"},"overall_signal":"mixed"}
|
||||
--- stderr
|
||||
49
crates/idx-cli/tests/golden/stocks-fundamental.table.golden
Normal file
49
crates/idx-cli/tests/golden/stocks-fundamental.table.golden
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Fundamental Analysis for BBCA.JK
|
||||
|
||||
Growth Analysis for BBCA.JK
|
||||
┌─────────────────┬─────────┬──────────┐
|
||||
│ METRIC ┆ VALUE ┆ SIGNAL │
|
||||
╞═════════════════╪═════════╪══════════╡
|
||||
│ Revenue Growth ┆ +8.10% ┆ slow │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Earnings Growth ┆ +12.10% ┆ moderate │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Overall ┆ - ┆ mixed │
|
||||
└─────────────────┴─────────┴──────────┘
|
||||
|
||||
Valuation Analysis for BBCA.JK
|
||||
┌────────────────┬─────────┬───────────┐
|
||||
│ METRIC ┆ VALUE ┆ SIGNAL │
|
||||
╞════════════════╪═════════╪═══════════╡
|
||||
│ P/E (Trailing) ┆ 25.40 ┆ premium │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ P/E (Forward) ┆ - ┆ - │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Price/Book ┆ 4.60 ┆ expensive │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ ROE ┆ +19.80% ┆ strong │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Net Margin ┆ +32.40% ┆ excellent │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ EV/EBITDA ┆ - ┆ no data │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Overall ┆ - ┆ expensive │
|
||||
└────────────────┴─────────┴───────────┘
|
||||
|
||||
Risk Analysis for BBCA.JK
|
||||
┌───────────────┬────────┬───────────────┐
|
||||
│ METRIC ┆ VALUE ┆ SIGNAL │
|
||||
╞═══════════════╪════════╪═══════════════╡
|
||||
│ Debt/Equity ┆ 0.42 ┆ conservative │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Current Ratio ┆ 1.18 ┆ tight │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ ROA ┆ +3.10% ┆ - │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Overall ┆ - ┆ moderate risk │
|
||||
└───────────────┴────────┴───────────────┘
|
||||
|
||||
Overall Signal: mixed
|
||||
--- stderr
|
||||
4
crates/idx-cli/tests/golden/stocks-growth.json.golden
Normal file
4
crates/idx-cli/tests/golden/stocks-growth.json.golden
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
{"revenue_growth":0.081,"earnings_growth":0.121,"revenue_growth_pct":8.1,"earnings_growth_pct":12.1,"revenue_signal":"slow","earnings_signal":"moderate","overall_signal":"mixed"}
|
||||
--- stderr
|
||||
13
crates/idx-cli/tests/golden/stocks-growth.table.golden
Normal file
13
crates/idx-cli/tests/golden/stocks-growth.table.golden
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
exit: 0
|
||||
--- stdout
|
||||
Growth Analysis for BBCA.JK
|
||||
┌─────────────────┬─────────┬──────────┐
|
||||
│ METRIC ┆ VALUE ┆ SIGNAL │
|
||||
╞═════════════════╪═════════╪══════════╡
|
||||
│ Revenue Growth ┆ +8.10% ┆ slow │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Earnings Growth ┆ +12.10% ┆ moderate │
|
||||
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
|
||||
│ Overall ┆ - ┆ mixed │
|
||||
└─────────────────┴─────────┴──────────┘
|
||||
--- stderr
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue