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:
hermes 2026-10-14 09:13:46 +00:00
commit 15947de51a
238 changed files with 544 additions and 375 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,47 +0,0 @@
[
{
"investorName": "Norges Bank Investment Management",
"investorType": "Government / Sovereign Wealth",
"sharesHeld": 278330000.0,
"sharesChanged": 3200000.0,
"percentageOfSharesOutstanding": 1.13,
"value": 275196270000.0,
"reportDate": "2024-12-31"
},
{
"investorName": "Dimensional Fund Advisors LP",
"investorType": "Institutional",
"sharesHeld": 156920000.0,
"sharesChanged": 14750000.0,
"percentageOfSharesOutstanding": 0.64,
"value": 155110680000.0,
"reportDate": "2024-12-31"
},
{
"investorName": "Baillie Gifford & Co",
"investorType": "Institutional",
"sharesHeld": 132450000.0,
"sharesChanged": 11200000.0,
"percentageOfSharesOutstanding": 0.54,
"value": 130965450000.0,
"reportDate": "2024-12-31"
},
{
"investorName": "BlackRock Inc",
"investorType": "Institutional",
"sharesHeld": 498112750.0,
"sharesChanged": 5600000.0,
"percentageOfSharesOutstanding": 2.02,
"value": 492523521250.0,
"reportDate": "2024-12-31"
},
{
"investorName": "Fidelity Management & Research",
"investorType": "Institutional",
"sharesHeld": 89340000.0,
"sharesChanged": 4100000.0,
"percentageOfSharesOutstanding": 0.36,
"value": 88346060000.0,
"reportDate": "2024-12-31"
}
]

View file

@ -1,56 +0,0 @@
[
{
"investorName": "PT Dwimuria Investama Andalan",
"investorType": "Corporate",
"sharesHeld": 13533682440.0,
"sharesChanged": 0.0,
"percentageOfSharesOutstanding": 54.94,
"value": 13380524934600.0,
"reportDate": "2024-12-31"
},
{
"investorName": "Vanguard Group Inc",
"investorType": "Institutional",
"sharesHeld": 621438200.0,
"sharesChanged": -12000000.0,
"percentageOfSharesOutstanding": 2.52,
"value": 614321778000.0,
"reportDate": "2024-12-31"
},
{
"investorName": "BlackRock Inc",
"investorType": "Institutional",
"sharesHeld": 498112750.0,
"sharesChanged": 5600000.0,
"percentageOfSharesOutstanding": 2.02,
"value": 492523521250.0,
"reportDate": "2024-12-31"
},
{
"investorName": "Government Pension Investment Fund (Japan)",
"investorType": "Government / Sovereign Wealth",
"sharesHeld": 312045000.0,
"sharesChanged": 0.0,
"percentageOfSharesOutstanding": 1.27,
"value": 308564505000.0,
"reportDate": "2024-12-31"
},
{
"investorName": "Norges Bank Investment Management",
"investorType": "Government / Sovereign Wealth",
"sharesHeld": 278330000.0,
"sharesChanged": 3200000.0,
"percentageOfSharesOutstanding": 1.13,
"value": 275196270000.0,
"reportDate": "2024-12-31"
},
{
"investorName": "Capital Research and Management",
"investorType": "Institutional",
"sharesHeld": 248760000.0,
"sharesChanged": -8000000.0,
"percentageOfSharesOutstanding": 1.01,
"value": 245971800000.0,
"reportDate": "2024-12-31"
}
]

View file

@ -1,30 +0,0 @@
{
"chart": {
"result": [
{
"meta": {
"symbol": "BBCA.JK",
"regularMarketPrice": 9875.0,
"previousClose": 9758.0,
"regularMarketVolume": 12300000,
"marketCap": 1215200000000000,
"fiftyTwoWeekHigh": 10250.0,
"fiftyTwoWeekLow": 7800.0,
"averageDailyVolume3Month": 10000000
},
"timestamp": [1709251200],
"indicators": {
"quote": [
{
"open": [9800.0],
"high": [9900.0],
"low": [9750.0],
"close": [9875.0],
"volume": [12300000]
}
]
}
}
]
}
}

View file

@ -1,25 +0,0 @@
{
"chart": {
"result": [
{
"meta": {
"symbol": "BBCA.JK",
"regularMarketPrice": 9875.0,
"previousClose": 9758.0
},
"timestamp": [1709251200, 1709337600, 1709424000],
"indicators": {
"quote": [
{
"open": [9800.0, 9850.0, 9860.0],
"high": [9900.0, 9920.0, 9950.0],
"low": [9750.0, 9800.0, 9820.0],
"close": [9875.0, 9880.0, 9925.0],
"volume": [12300000, 11000000, 14000000]
}
]
}
}
]
}
}

View file

@ -1,17 +0,0 @@
{
"chart": {
"result": [{
"timestamp": [1709251200, 1709337600],
"indicators": {
"quote": [{
"open": [9800.0, 9850.0],
"high": [9900.0, 9900.0],
"low": [9750.0, 9800.0],
"close": [9875.0, null],
"volume": [12300000, 11000000]
}]
}
}],
"error": null
}
}

View file

@ -1,48 +0,0 @@
{
"Items": [
{
"Id": "20260327163420-Peng-LKS-00043/BEI.PLP/03-2026_id-id",
"AnnouncementNo": "Peng-LKS-00043/BEI.PLP/03-2026",
"PublishDate": "2026-03-27T16:34:20",
"Title": "Pemegang Saham di atas 5% (KSEI)",
"AnnouncementType": "",
"Code": "Semua Emiten Saham",
"Attachments": [
{
"PDFFilename": "20260327_Semua Emiten Saham_Pengumuman Bursa_32055594.pdf",
"FullSavePath": "https://www.idx.co.id/StaticData/NewsAndAnnouncement/ANNOUNCEMENTSTOCK/From_EREP/202603/5d31bb6f49_announcement.pdf",
"IsAttachment": 0,
"OriginalFilename": "20260327_Semua Emiten Saham_Pengumuman Bursa_32055594.pdf"
},
{
"PDFFilename": "20260327_Semua Emiten Saham_Pengumuman Bursa_32055594_lamp1.pdf",
"FullSavePath": "https://www.idx.co.id/StaticData/NewsAndAnnouncement/ANNOUNCEMENTSTOCK/From_EREP/202603/4f5c4efc6f_bf70f249ac_lamp1.pdf",
"IsAttachment": 1,
"OriginalFilename": "20260327_Semua Emiten Saham_Pengumuman Bursa_32055594_lamp1.pdf"
}
],
"PdfPath": "[{\"PDFFilename\":\"20260327_Semua Emiten Saham_Pengumuman Bursa_32055594.pdf\",\"FullSavePath\":\"https://www.idx.co.id/StaticData/NewsAndAnnouncement/ANNOUNCEMENTSTOCK/From_EREP/202603/5d31bb6f49_announcement.pdf\",\"IsAttachment\":\"0\",\"OriginalFilename\":\"20260327_Semua Emiten Saham_Pengumuman Bursa_32055594.pdf\"},{\"PDFFilename\":\"20260327_Semua Emiten Saham_Pengumuman Bursa_32055594_lamp1.pdf\",\"FullSavePath\":\"https://www.idx.co.id/StaticData/NewsAndAnnouncement/ANNOUNCEMENTSTOCK/From_EREP/202603/4f5c4efc6f_bf70f249ac_lamp1.pdf\",\"IsAttachment\":\"1\",\"OriginalFilename\":\"20260327_Semua Emiten Saham_Pengumuman Bursa_32055594_lamp1.pdf\"}]"
},
{
"Id": "20260328114739-LK/28032026/0001/1_id-id",
"AnnouncementNo": "LK/28032026/0001/1",
"PublishDate": "2026-03-28T11:47:39",
"Title": "LAPORAN KEPEMILIKAN ATAU SETIAP PERUBAHAN KEPEMILIKAN SAHAM PERUSAHAAN TERBUKA",
"AnnouncementType": "LKS",
"Code": "CASH",
"Attachments": [
{
"PDFFilename": "LK-28032026-2468-00.pdf-0",
"FullSavePath": "https://www.idx.co.id/StaticData/NewsAndAnnouncement/ANNOUNCEMENTSTOCK/From_KSEI/LK-28032026-2468-00.pdf-0.pdf",
"IsAttachment": 1,
"OriginalFilename": "LK-28032026-2468-00.pdf"
}
],
"PdfPath": "[{\"PDFFilename\":\"LK-28032026-2468-00.pdf-0\",\"FullSavePath\":\"https://www.idx.co.id/StaticData/NewsAndAnnouncement/ANNOUNCEMENTSTOCK/From_KSEI/LK-28032026-2468-00.pdf-0.pdf\",\"IsAttachment\":1,\"OriginalFilename\":\"LK-28032026-2468-00.pdf\"}]"
}
],
"ItemCount": 2,
"PageSize": 10,
"PageNumber": 1,
"PageCount": 1
}

View file

@ -1,5 +0,0 @@
<!doctype html>
<html lang="id"><head><title>Data Kepemilikan Saham - Bursa Efek Indonesia</title></head>
<body><div id="__nuxt"><!-- trimmed excerpt of https://www.idx.co.id/id/perusahaan-tercatat/data-kepemilikan-saham/ (2026-09-24) --></div>
<script>window.__NUXT__=(function(a,r){return {fetch:{"data-v-8c8e470a:0":{tableData:[{Description:"Pemegang Saham di Atas 5% per 23 September 2026",Prospectus:"https:\u002F\u002Fwww.idx.co.id\u002FMedia\u002Fsucngcwy\u002Fpeng-2026-09-23-00080-lima-persen.xlsx",ListingDate:"2026-09-23T12:00:00"},{Description:"Pemegang Saham di Atas 5% per 31 Agustus 2026",Prospectus:"https:\u002F\u002Fwww.idx.co.id\u002FMedia\u002Fumrls4il\u002Fpeng-2026-08-31-00063-lima-persen.xlsx",ListingDate:r},{Description:"Data Kepemilikan Saham Perusahaan Tercatat Berdasarkan Klasifikasi Investor per 31 Agustus 2026",Prospectus:"https:\u002F\u002Fwww.idx.co.id\u002FMedia\u002Fy0vjakdz\u002Fpeng-2026-08-00018-klasifikasi.xlsx",ListingDate:r},{Description:"Data Kepemilikan Saham Perusahaan Tercatat per Tipe Investor per 31 Agustus 2026",Prospectus:"https:\u002F\u002Fwww.idx.co.id\u002FMedia\u002Fwkjfudt3\u002Fpeng-2026-08-00019-tipe.xlsx",ListingDate:r},{Description:"Pemegang Saham di Atas 1% per 31 Agustus 2026",Prospectus:"https:\u002F\u002Fwww.idx.co.id\u002FMedia\u002Ffahlw1o2\u002Fpeng-2026-08-00017-satu-persen.xlsx",ListingDate:r},{Description:"Pemegang Saham di Atas 1% per 31 Juli 2026",Prospectus:"https:\u002F\u002Fwww.idx.co.id\u002FMedia\u002Ffjelt0en\u002Fpeng-2026-07-00016-satu-persen.xlsx",ListingDate:s},{Description:"Pemegang Saham di Atas 1% per 27 Februari 2026",Prospectus:"https:\u002F\u002Fwww.idx.co.id\u002FMedia\u002Fr2kjzpk5\u002Fpeng-02-00011-satu-persen.xlsx",ListingDate:K}]}}}}(null,"2026-09-01T12:00:00"));</script>
</body></html>

Binary file not shown.

View file

@ -1,27 +0,0 @@
<?xml version="1.0"?>
<document>
<page id="page1" width="612" height="792">
<line bbox="58.2 135.37999 63.566404 137.78" wmode="0" dir="1 0" flags="0" text="DATE"></line>
<line bbox="73.944 135.37999 87.46321 137.78" wmode="0" dir="1 0" flags="0" text="SHARE CODE"></line>
<line bbox="111.26 135.37999 125.50881 137.78" wmode="0" dir="1 0" flags="0" text="ISSUER NAME"></line>
<line bbox="199.73 135.37999 217.21158 137.78" wmode="0" dir="1 0" flags="0" text="INVESTOR NAME"></line>
<line bbox="288.53 135.37999 315.77238 137.78" wmode="0" dir="1 0" flags="0" text="INVESTOR CLASSIFICATION"></line>
<line bbox="337.63 135.37999 354.19963 137.78" wmode="0" dir="1 0" flags="0" text="LOCAL FOREIGN"></line>
<line bbox="363.31 135.37999 376.7908 137.78" wmode="0" dir="1 0" flags="0" text="NATIONALITY"></line>
<line bbox="398.11 135.37999 408.034 137.78" wmode="0" dir="1 0" flags="0" text="DOMICILE"></line>
<line bbox="432.55 135.37999 454.30836 137.78" wmode="0" dir="1 0" flags="0" text="HOLDINGS SCRIPLESS"></line>
<line bbox="466.78 135.37999 484.1248 137.78" wmode="0" dir="1 0" flags="0" text="HOLDINGS SCRIP"></line>
<line bbox="496.9 135.37999 522.97366 137.78" wmode="0" dir="1 0" flags="0" text="TOTAL HOLDING SHARES"></line>
<line bbox="534.34 135.37999 547.6168 137.78" wmode="0" dir="1 0" flags="0" text="PERCENTAGE"></line>
<line bbox="55.68 138.49999 75.26399 140.9" wmode="0" dir="1 0" flags="0" text="29-May-2026 AADI"></line>
<line bbox="91.944 138.49999 125.39758 140.9" wmode="0" dir="1 0" flags="0" text="ADARO ANDALAN INDONESIA Tbk"></line>
<line bbox="145.7 138.49999 175.97843 140.9" wmode="0" dir="1 0" flags="0" text="PERSADA CAPITAL INVESTAMA"></line>
<line bbox="272.09 138.49999 282.27076 140.9" wmode="0" dir="1 0" flags="0" text="Corporate"></line>
<line bbox="330.0 138.49999 332.0 140.9" wmode="0" dir="1 0" flags="0" text="D"></line>
<line bbox="360.0 138.49999 380.0 140.9" wmode="0" dir="1 0" flags="0" text="INDONESIA"></line>
<line bbox="430.0 138.49999 460.0 140.9" wmode="0" dir="1 0" flags="0" text="3.200.142.830"></line>
<line bbox="465.0 138.49999 470.0 140.9" wmode="0" dir="1 0" flags="0" text="0"></line>
<line bbox="495.0 138.49999 525.0 140.9" wmode="0" dir="1 0" flags="0" text="3.200.142.830"></line>
<line bbox="533.0 138.49999 548.0 140.9" wmode="0" dir="1 0" flags="0" text="41,10"></line>
</page>
</document>

View file

@ -1,29 +0,0 @@
<?xml version="1.0"?>
<document>
<page id="page1" width="792" height="612">
<block bbox="28.68 86.33 767.71438 600.02999" justify="unknown">
<line bbox="31.56 86.33 39.25776 89.810009" wmode="0" dir="1 0" flags="0" text="DATE"></line>
<line bbox="56.64 86.33 75.974887 89.810009" wmode="0" dir="1 0" flags="0" text="SHARE_CODE"></line>
<line bbox="121.22 86.33 142.22878 89.810009" wmode="0" dir="1 0" flags="0" text="ISSUER_NAME"></line>
<line bbox="267.17 86.33 292.6193 89.810009" wmode="0" dir="1 0" flags="0" text="INVESTOR_NAME"></line>
<line bbox="390.89 86.33 414.18165 89.810009" wmode="0" dir="1 0" flags="0" text="INVESTOR_TYPE"></line>
<line bbox="434.11 86.33 457.99674 89.810009" wmode="0" dir="1 0" flags="0" text="LOCAL_FOREIGN"></line>
<line bbox="475.87 86.33 495.66777 89.810009" wmode="0" dir="1 0" flags="0" text="NATIONALITY"></line>
<line bbox="525.19 86.33 539.60067 89.810009" wmode="0" dir="1 0" flags="0" text="DOMICILE"></line>
<line bbox="574.63 86.33 606.14498 89.810009" wmode="0" dir="1 0" flags="0" text="HOLDINGS_SCRIPLESS"></line>
<line bbox="629.98 86.33 655.1021 89.810009" wmode="0" dir="1 0" flags="0" text="HOLDINGS_SCRIP"></line>
<line bbox="680.02 86.33 717.5414 89.810009" wmode="0" dir="1 0" flags="0" text="TOTAL_HOLDING_SHARES"></line>
<line bbox="741.22 86.33 760.0782 89.810009" wmode="0" dir="1 0" flags="0" text="PERCENTAGE"></line>
<line bbox="28.68 91.009998 55.722299 94.49" wmode="0" dir="1 0" flags="0" text="27-Feb-2026 AADI"></line>
<line bbox="85.104 91.009998 133.29856 94.49" wmode="0" dir="1 0" flags="0" text="ADARO ANDALAN INDONESIA Tbk"></line>
<line bbox="179.3 91.009998 226.93775 94.49" wmode="0" dir="1 0" flags="0" text="ADARO STRATEGIC INVESTMENTS"></line>
<line bbox="381.41 91.009998 385.00923 94.49" wmode="0" dir="1 0" flags="0" text="CP"></line>
<line bbox="424.75 91.009998 426.8902 94.49" wmode="0" dir="1 0" flags="0" text="D"></line>
<line bbox="504.07 91.009998 519.99099 94.49" wmode="0" dir="1 0" flags="0" text="INDONESIA"></line>
<line bbox="597.58 91.009998 618.0213 94.49" wmode="0" dir="1 0" flags="0" text="3.200.142.830"></line>
<line bbox="662.26 91.009998 664.02438 94.49" wmode="0" dir="1 0" flags="0" text="0"></line>
<line bbox="710.26 91.009998 730.7013 94.49" wmode="0" dir="1 0" flags="0" text="3.200.142.830"></line>
<line bbox="759.72 91.009998 767.70999 94.49" wmode="0" dir="1 0" flags="0" text="41,10"></line>
</block>
</page>
</document>

View file

@ -1,29 +0,0 @@
<?xml version="1.0"?>
<document>
<page id="page1" width="792" height="612">
<block bbox="28.68 86.33 767.71438 600.02999" justify="unknown">
<line bbox="31.56 86.33 39.25776 89.810009" wmode="0" dir="1 0" flags="0" text="DATE"></line>
<line bbox="56.64 86.33 75.974887 89.810009" wmode="0" dir="1 0" flags="0" text="SHARE_CODE"></line>
<line bbox="121.22 86.33 142.22878 89.810009" wmode="0" dir="1 0" flags="0" text="ISSUER_NAME"></line>
<line bbox="267.17 86.33 292.6193 89.810009" wmode="0" dir="1 0" flags="0" text="INVESTOR_NAME"></line>
<line bbox="390.89 86.33 414.18165 89.810009" wmode="0" dir="1 0" flags="0" text="INVESTOR_TYPE"></line>
<line bbox="434.11 86.33 457.99674 89.810009" wmode="0" dir="1 0" flags="0" text="LOCAL_FOREIGN"></line>
<line bbox="475.87 86.33 495.66777 89.810009" wmode="0" dir="1 0" flags="0" text="NATIONALITY"></line>
<line bbox="525.19 86.33 539.60067 89.810009" wmode="0" dir="1 0" flags="0" text="DOMICILE"></line>
<line bbox="574.63 86.33 606.14498 89.810009" wmode="0" dir="1 0" flags="0" text="HOLDINGS_SCRIPLESS"></line>
<line bbox="629.98 86.33 655.1021 89.810009" wmode="0" dir="1 0" flags="0" text="HOLDINGS_SCRIP"></line>
<line bbox="680.02 86.33 717.5414 89.810009" wmode="0" dir="1 0" flags="0" text="TOTAL_HOLDING_SHARES"></line>
<line bbox="741.22 86.33 760.0782 89.810009" wmode="0" dir="1 0" flags="0" text="PERCENTAGE"></line>
<line bbox="28.68 91.009998 55.722299 94.49" wmode="0" dir="1 0" flags="0" text="31-Jan-2026 AADI"></line>
<line bbox="85.104 91.009998 133.29856 94.49" wmode="0" dir="1 0" flags="0" text="ADARO ANDALAN INDONESIA Tbk"></line>
<line bbox="179.3 91.009998 226.93775 94.49" wmode="0" dir="1 0" flags="0" text="ADARO STRATEGIC INVESTMENTS"></line>
<line bbox="381.41 91.009998 385.00923 94.49" wmode="0" dir="1 0" flags="0" text="CP"></line>
<line bbox="424.75 91.009998 426.8902 94.49" wmode="0" dir="1 0" flags="0" text="D"></line>
<line bbox="504.07 91.009998 519.99099 94.49" wmode="0" dir="1 0" flags="0" text="INDONESIA"></line>
<line bbox="597.58 91.009998 618.0213 94.49" wmode="0" dir="1 0" flags="0" text="3.050.000.000"></line>
<line bbox="662.26 91.009998 664.02438 94.49" wmode="0" dir="1 0" flags="0" text="0"></line>
<line bbox="710.26 91.009998 730.7013 94.49" wmode="0" dir="1 0" flags="0" text="3.050.000.000"></line>
<line bbox="759.72 91.009998 767.70999 94.49" wmode="0" dir="1 0" flags="0" text="39,82"></line>
</block>
</page>
</document>

Binary file not shown.

View file

@ -1,8 +0,0 @@
<?xml version="1.0"?>
<document>
<page id="page1" width="595" height="842">
<line bbox="0 0 10 10" text="Pemegang Saham di atas 5% (KSEI)"></line>
<line bbox="0 12 10 22" text="INVS"></line>
<line bbox="0 24 10 34" text="PT MAGNUS Capital (REKENING TAMPUNGAN KSEI UNTUK CLOSED MEMBER-ABC)"></line>
</page>
</document>

View file

@ -1,8 +0,0 @@
<?xml version="1.0"?>
<document>
<page id="page1" width="595" height="842">
<line bbox="0 0 10 10" text="PENGUMUMAN"></line>
<line bbox="0 12 10 22" text="PT Bursa Efek Indonesia (BEI)"></line>
<line bbox="0 24 10 34" text="Pemegang Saham di atas 1% (KSEI)"></line>
</page>
</document>

View file

@ -1,2 +0,0 @@
Date|Code|Type|Sec. Num|Price|Local IS|Local CP|Local PF|Local IB|Local ID|Local MF|Local SC|Local FD|Local OT|Total|Foreign IS|Foreign CP|Foreign PF|Foreign IB|Foreign ID|Foreign MF|Foreign SC|Foreign FD|Foreign OT|Total
30-JAN-2026|AADI|EQUITY|7786891760|7600|58704495|5046580437|13135269|41|1868661103|91475881|27984191|1966845|85275|7108593537|1150700|55820749|58897143|207783974|2127405|239139003|39765137|2493100|71121012|678298223

View file

@ -1,2 +0,0 @@
Date|Code|Type|Sec. Num|Price|Local IS|Local CP|Local PF|Local IB|Local ID|Local MF|Local SC|Local FD|Local OT|Total|Foreign IS|Foreign CP|Foreign PF|Foreign IB|Foreign ID|Foreign MF|Foreign SC|Foreign FD|Foreign OT|Total
27-FEB-2026|AADI|EQUITY|7786891760|9250|100730965|5035745466|15622269|41|1817092689|117982099|22932698|2060140|105275|7112271642|1150700|66705786|43311343|204936195|1261705|262226503|42723690|2493100|49811096|674620118

View file

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<document>
<page id="page1" width="595" height="842">
<line bbox="0 0 10 10" text="DATE"></line>
<line bbox="0 12 10 22" text="STOCK_CODE"></line>
<line bbox="0 24 10 34" text="NUMBER_OF_SHARES"></line>
<line bbox="0 36 10 46" text="FOREIGN"></line>
<line bbox="0 48 10 58" text="LOCAL INDIVIDUAL"></line>
</page>
</document>

View file

@ -1,328 +0,0 @@
<document>
<page id="page1" width="792" height="612">
<char x="40.0" y="40.0" c="P"/>
<char x="41.2" y="40.0" c="E"/>
<char x="42.4" y="40.0" c="N"/>
<char x="43.6" y="40.0" c="G"/>
</page>
<page id="page2" width="792" height="612">
<char x="21.7" y="100.0" c="2"/>
<char x="22.8" y="100.0" c="7"/>
<char x="23.9" y="100.0" c="-"/>
<char x="25.0" y="100.0" c="F"/>
<char x="26.1" y="100.0" c="e"/>
<char x="27.2" y="100.0" c="b"/>
<char x="28.3" y="100.0" c="-"/>
<char x="29.4" y="100.0" c="2"/>
<char x="30.5" y="100.0" c="0"/>
<char x="31.6" y="100.0" c="2"/>
<char x="32.7" y="100.0" c="6"/>
<char x="55.3" y="100.0" c="B"/>
<char x="56.4" y="100.0" c="B"/>
<char x="57.5" y="100.0" c="C"/>
<char x="58.6" y="100.0" c="A"/>
<char x="75.0" y="100.0" c="B"/>
<char x="76.1" y="100.0" c="A"/>
<char x="77.2" y="100.0" c="N"/>
<char x="78.3" y="100.0" c="K"/>
<char x="79.4" y="100.0" c=" "/>
<char x="80.8" y="100.0" c="C"/>
<char x="81.9" y="100.0" c="E"/>
<char x="83.0" y="100.0" c="N"/>
<char x="84.1" y="100.0" c="T"/>
<char x="85.2" y="100.0" c="R"/>
<char x="86.3" y="100.0" c="A"/>
<char x="87.4" y="100.0" c="L"/>
<char x="88.5" y="100.0" c=" "/>
<char x="89.9" y="100.0" c="A"/>
<char x="91.0" y="100.0" c="S"/>
<char x="92.1" y="100.0" c="I"/>
<char x="93.2" y="100.0" c="A"/>
<char x="94.3" y="100.0" c=" "/>
<char x="95.7" y="100.0" c="T"/>
<char x="96.8" y="100.0" c="b"/>
<char x="97.9" y="100.0" c="k"/>
<char x="167.9" y="100.0" c="P"/>
<char x="169.0" y="100.0" c="T"/>
<char x="170.1" y="100.0" c=" "/>
<char x="171.5" y="100.0" c="D"/>
<char x="172.6" y="100.0" c="W"/>
<char x="173.7" y="100.0" c="I"/>
<char x="174.8" y="100.0" c="M"/>
<char x="175.9" y="100.0" c="U"/>
<char x="177.0" y="100.0" c="R"/>
<char x="178.1" y="100.0" c="I"/>
<char x="179.2" y="100.0" c="A"/>
<char x="180.3" y="100.0" c=" "/>
<char x="181.7" y="100.0" c="I"/>
<char x="182.8" y="100.0" c="N"/>
<char x="183.9" y="100.0" c="V"/>
<char x="185.0" y="100.0" c="E"/>
<char x="186.1" y="100.0" c="S"/>
<char x="187.2" y="100.0" c="T"/>
<char x="188.3" y="100.0" c="A"/>
<char x="189.4" y="100.0" c="M"/>
<char x="190.5" y="100.0" c="A"/>
<char x="191.6" y="100.0" c=" "/>
<char x="193.0" y="100.0" c="A"/>
<char x="194.1" y="100.0" c="N"/>
<char x="195.2" y="100.0" c="D"/>
<char x="196.3" y="100.0" c="A"/>
<char x="197.4" y="100.0" c="L"/>
<char x="198.5" y="100.0" c="A"/>
<char x="199.6" y="100.0" c="N"/>
<char x="435.0" y="100.0" c="C"/>
<char x="436.1" y="100.0" c="P"/>
<char x="468.0" y="100.0" c="L"/>
<char x="500.0" y="100.0" c="I"/>
<char x="501.1" y="100.0" c="D"/>
<char x="560.0" y="100.0" c="I"/>
<char x="561.1" y="100.0" c="D"/>
<char x="620.0" y="100.0" c="1"/>
<char x="621.1" y="100.0" c="3"/>
<char x="622.2" y="100.0" c="."/>
<char x="623.3" y="100.0" c="5"/>
<char x="624.4" y="100.0" c="3"/>
<char x="625.5" y="100.0" c="3"/>
<char x="626.6" y="100.0" c="."/>
<char x="627.7" y="100.0" c="6"/>
<char x="628.8" y="100.0" c="8"/>
<char x="629.9" y="100.0" c="2"/>
<char x="631.0" y="100.0" c="."/>
<char x="632.1" y="100.0" c="4"/>
<char x="633.2" y="100.0" c="4"/>
<char x="634.3" y="100.0" c="0"/>
<char x="656.0" y="100.0" c="0"/>
<char x="696.0" y="100.0" c="1"/>
<char x="697.1" y="100.0" c="3"/>
<char x="698.2" y="100.0" c="."/>
<char x="699.3" y="100.0" c="5"/>
<char x="700.4" y="100.0" c="3"/>
<char x="701.5" y="100.0" c="3"/>
<char x="702.6" y="100.0" c="."/>
<char x="703.7" y="100.0" c="6"/>
<char x="704.8" y="100.0" c="8"/>
<char x="705.9" y="100.0" c="2"/>
<char x="707.0" y="100.0" c="."/>
<char x="708.1" y="100.0" c="4"/>
<char x="709.2" y="100.0" c="4"/>
<char x="710.3" y="100.0" c="0"/>
<char x="748.0" y="100.0" c="5"/>
<char x="749.1" y="100.0" c="4"/>
<char x="750.2" y="100.0" c=","/>
<char x="751.3" y="100.0" c="9"/>
<char x="752.4" y="100.0" c="4"/>
<char x="21.7" y="101.9" c="2"/>
<char x="22.8" y="101.9" c="7"/>
<char x="23.9" y="101.9" c="-"/>
<char x="25.0" y="101.9" c="F"/>
<char x="26.1" y="101.9" c="e"/>
<char x="27.2" y="101.9" c="b"/>
<char x="28.3" y="101.9" c="-"/>
<char x="29.4" y="101.9" c="2"/>
<char x="30.5" y="101.9" c="0"/>
<char x="31.6" y="101.9" c="2"/>
<char x="32.7" y="101.9" c="6"/>
<char x="55.3" y="101.9" c="B"/>
<char x="56.4" y="101.9" c="B"/>
<char x="57.5" y="101.9" c="C"/>
<char x="58.6" y="101.9" c="A"/>
<char x="75.0" y="101.9" c="B"/>
<char x="76.1" y="101.9" c="A"/>
<char x="77.2" y="101.9" c="N"/>
<char x="78.3" y="101.9" c="K"/>
<char x="79.4" y="101.9" c=" "/>
<char x="80.8" y="101.9" c="C"/>
<char x="81.9" y="101.9" c="E"/>
<char x="83.0" y="101.9" c="N"/>
<char x="84.1" y="101.9" c="T"/>
<char x="85.2" y="101.9" c="R"/>
<char x="86.3" y="101.9" c="A"/>
<char x="87.4" y="101.9" c="L"/>
<char x="88.5" y="101.9" c=" "/>
<char x="89.9" y="101.9" c="A"/>
<char x="91.0" y="101.9" c="S"/>
<char x="92.1" y="101.9" c="I"/>
<char x="93.2" y="101.9" c="A"/>
<char x="94.3" y="101.9" c=" "/>
<char x="95.7" y="101.9" c="T"/>
<char x="96.8" y="101.9" c="b"/>
<char x="97.9" y="101.9" c="k"/>
<char x="167.9" y="101.9" c="P"/>
<char x="169.0" y="101.9" c="T"/>
<char x="170.1" y="101.9" c=" "/>
<char x="171.5" y="101.9" c="G"/>
<char x="172.6" y="101.9" c="I"/>
<char x="173.7" y="101.9" c="T"/>
<char x="174.8" y="101.9" c="A"/>
<char x="175.9" y="101.9" c=" "/>
<char x="177.3" y="101.9" c="S"/>
<char x="178.4" y="101.9" c="U"/>
<char x="179.5" y="101.9" c="R"/>
<char x="180.6" y="101.9" c="Y"/>
<char x="181.7" y="101.9" c="A"/>
<char x="182.8" y="101.9" c=" "/>
<char x="184.2" y="101.9" c="H"/>
<char x="185.3" y="101.9" c="A"/>
<char x="186.4" y="101.9" c="S"/>
<char x="187.5" y="101.9" c="T"/>
<char x="188.6" y="101.9" c="A"/>
<char x="435.0" y="101.9" c="C"/>
<char x="436.1" y="101.9" c="P"/>
<char x="468.0" y="101.9" c="L"/>
<char x="500.0" y="101.9" c="I"/>
<char x="501.1" y="101.9" c="D"/>
<char x="560.0" y="101.9" c="I"/>
<char x="561.1" y="101.9" c="D"/>
<char x="620.0" y="101.9" c="5"/>
<char x="621.1" y="101.9" c="."/>
<char x="622.2" y="101.9" c="2"/>
<char x="623.3" y="101.9" c="0"/>
<char x="624.4" y="101.9" c="0"/>
<char x="625.5" y="101.9" c="."/>
<char x="626.6" y="101.9" c="0"/>
<char x="627.7" y="101.9" c="0"/>
<char x="628.8" y="101.9" c="0"/>
<char x="629.9" y="101.9" c="."/>
<char x="631.0" y="101.9" c="0"/>
<char x="632.1" y="101.9" c="0"/>
<char x="633.2" y="101.9" c="0"/>
<char x="656.0" y="101.9" c="0"/>
<char x="696.0" y="101.9" c="5"/>
<char x="697.1" y="101.9" c="."/>
<char x="698.2" y="101.9" c="2"/>
<char x="699.3" y="101.9" c="0"/>
<char x="700.4" y="101.9" c="0"/>
<char x="701.5" y="101.9" c="."/>
<char x="702.6" y="101.9" c="0"/>
<char x="703.7" y="101.9" c="0"/>
<char x="704.8" y="101.9" c="0"/>
<char x="705.9" y="101.9" c="."/>
<char x="707.0" y="101.9" c="0"/>
<char x="708.1" y="101.9" c="0"/>
<char x="709.2" y="101.9" c="0"/>
<char x="748.0" y="101.9" c="2"/>
<char x="749.1" y="101.9" c="1"/>
<char x="750.2" y="101.9" c=","/>
<char x="751.3" y="101.9" c="1"/>
<char x="752.4" y="101.9" c="1"/>
</page>
<page id="page3" width="792" height="612">
<char x="21.7" y="120.0" c="2"/>
<char x="22.8" y="120.0" c="7"/>
<char x="23.9" y="120.0" c="-"/>
<char x="25.0" y="120.0" c="F"/>
<char x="26.1" y="120.0" c="e"/>
<char x="27.2" y="120.0" c="b"/>
<char x="28.3" y="120.0" c="-"/>
<char x="29.4" y="120.0" c="2"/>
<char x="30.5" y="120.0" c="0"/>
<char x="31.6" y="120.0" c="2"/>
<char x="32.7" y="120.0" c="6"/>
<char x="55.3" y="120.0" c="B"/>
<char x="56.4" y="120.0" c="B"/>
<char x="57.5" y="120.0" c="R"/>
<char x="58.6" y="120.0" c="I"/>
<char x="75.0" y="120.0" c="B"/>
<char x="76.1" y="120.0" c="A"/>
<char x="77.2" y="120.0" c="N"/>
<char x="78.3" y="120.0" c="K"/>
<char x="79.4" y="120.0" c=" "/>
<char x="80.8" y="120.0" c="R"/>
<char x="81.9" y="120.0" c="A"/>
<char x="83.0" y="120.0" c="K"/>
<char x="84.1" y="120.0" c="Y"/>
<char x="85.2" y="120.0" c="A"/>
<char x="86.3" y="120.0" c="T"/>
<char x="87.4" y="120.0" c=" "/>
<char x="88.8" y="120.0" c="I"/>
<char x="89.9" y="120.0" c="N"/>
<char x="91.0" y="120.0" c="D"/>
<char x="92.1" y="120.0" c="O"/>
<char x="93.2" y="120.0" c="N"/>
<char x="94.3" y="120.0" c="E"/>
<char x="95.4" y="120.0" c="S"/>
<char x="96.5" y="120.0" c="I"/>
<char x="97.6" y="120.0" c="A"/>
<char x="98.7" y="120.0" c=" "/>
<char x="100.1" y="120.0" c="("/>
<char x="101.2" y="120.0" c="P"/>
<char x="102.3" y="120.0" c="E"/>
<char x="103.4" y="120.0" c="R"/>
<char x="104.5" y="120.0" c="S"/>
<char x="105.6" y="120.0" c="E"/>
<char x="106.7" y="120.0" c="R"/>
<char x="107.8" y="120.0" c="O"/>
<char x="108.9" y="120.0" c=")"/>
<char x="110.0" y="120.0" c=" "/>
<char x="111.4" y="120.0" c="T"/>
<char x="112.5" y="120.0" c="b"/>
<char x="113.6" y="120.0" c="k"/>
<char x="167.9" y="120.0" c="N"/>
<char x="169.0" y="120.0" c="E"/>
<char x="170.1" y="120.0" c="G"/>
<char x="171.2" y="120.0" c="A"/>
<char x="172.3" y="120.0" c="R"/>
<char x="173.4" y="120.0" c="A"/>
<char x="174.5" y="120.0" c=" "/>
<char x="175.9" y="120.0" c="R"/>
<char x="177.0" y="120.0" c="E"/>
<char x="178.1" y="120.0" c="P"/>
<char x="179.2" y="120.0" c="U"/>
<char x="180.3" y="120.0" c="B"/>
<char x="181.4" y="120.0" c="L"/>
<char x="182.5" y="120.0" c="I"/>
<char x="183.6" y="120.0" c="K"/>
<char x="184.7" y="120.0" c=" "/>
<char x="186.1" y="120.0" c="I"/>
<char x="187.2" y="120.0" c="N"/>
<char x="188.3" y="120.0" c="D"/>
<char x="189.4" y="120.0" c="O"/>
<char x="190.5" y="120.0" c="N"/>
<char x="191.6" y="120.0" c="E"/>
<char x="192.7" y="120.0" c="S"/>
<char x="193.8" y="120.0" c="I"/>
<char x="194.9" y="120.0" c="A"/>
<char x="435.0" y="120.0" c="C"/>
<char x="436.1" y="120.0" c="P"/>
<char x="468.0" y="120.0" c="L"/>
<char x="500.0" y="120.0" c="I"/>
<char x="501.1" y="120.0" c="D"/>
<char x="560.0" y="120.0" c="I"/>
<char x="561.1" y="120.0" c="D"/>
<char x="620.0" y="120.0" c="6"/>
<char x="621.1" y="120.0" c="7"/>
<char x="622.2" y="120.0" c="."/>
<char x="623.3" y="120.0" c="0"/>
<char x="624.4" y="120.0" c="0"/>
<char x="625.5" y="120.0" c="0"/>
<char x="626.6" y="120.0" c="."/>
<char x="627.7" y="120.0" c="0"/>
<char x="628.8" y="120.0" c="0"/>
<char x="629.9" y="120.0" c="0"/>
<char x="631.0" y="120.0" c="."/>
<char x="632.1" y="120.0" c="0"/>
<char x="633.2" y="120.0" c="0"/>
<char x="634.3" y="120.0" c="0"/>
<char x="656.0" y="120.0" c="0"/>
<char x="696.0" y="120.0" c="6"/>
<char x="697.1" y="120.0" c="7"/>
<char x="698.2" y="120.0" c="."/>
<char x="699.3" y="120.0" c="0"/>
<char x="700.4" y="120.0" c="0"/>
<char x="701.5" y="120.0" c="0"/>
<char x="702.6" y="120.0" c="."/>
<char x="703.7" y="120.0" c="0"/>
<char x="704.8" y="120.0" c="0"/>
<char x="705.9" y="120.0" c="0"/>
<char x="707.0" y="120.0" c="."/>
<char x="708.1" y="120.0" c="0"/>
<char x="709.2" y="120.0" c="0"/>
<char x="710.3" y="120.0" c="0"/>
<char x="748.0" y="120.0" c="5"/>
<char x="749.1" y="120.0" c="3"/>
<char x="750.2" y="120.0" c=","/>
<char x="751.3" y="120.0" c="1"/>
<char x="752.4" y="120.0" c="9"/>
</page>
</document>

View file

@ -1,17 +0,0 @@
[
{
"_p": "bn91jc",
"chartType": "3M",
"symbol": "BBCA",
"series": {
"timeStamps": [
"2026-01-13T17:00:00Z",
"2026-01-14T17:00:00Z",
"2026-01-15T17:00:00Z"
],
"prices": [8000.0, 8075.0, 8025.0],
"startTime": "2026-01-13T17:00:00Z",
"endTime": "2026-01-15T17:00:00Z"
}
}
]

View file

@ -1,22 +0,0 @@
[
{
"_p": "bn91jc",
"chartType": "3M",
"symbol": "BBCA",
"series": {
"timeStamps": [
"2025-01-06T00:00:00Z",
"2025-01-07T00:00:00Z",
"2025-01-08T00:00:00Z",
"2025-01-13T00:00:00Z",
"2025-01-14T00:00:00Z",
"2025-01-15T00:00:00Z"
],
"prices": [9875.0, 9880.0, 9895.0, 9910.0, 9925.0, 9940.0],
"openPrices": [9800.0, 9850.0, 9870.0, 9890.0, 9905.0, 9920.0],
"pricesHigh": [9900.0, 9905.0, 9910.0, 9930.0, 9940.0, 9950.0],
"pricesLow": [9750.0, 9825.0, 9855.0, 9880.0, 9890.0, 9910.0],
"volumes": [12300000.0, 11000000.0, 11300000.0, 12500000.0, 11800000.0, 12000000.0]
}
}
]

View file

@ -1,46 +0,0 @@
{
"EpsLastYear": 1200.0,
"RevenueLastYear": 100000000000.0,
"Forecast": {
"annual": {
"2026": {
"EpsForecast": 1300.0,
"RevenueForecast": 110000000000.0,
"EarningReleaseDate": "2026-03-15",
"CiqFiscalPeriodType": "2026"
}
},
"quarterly": {
"Q12026": {
"EpsForecast": 330.0,
"RevenueForecast": 28000000000.0,
"EarningReleaseDate": "2026-04-20",
"CiqFiscalPeriodType": "Q12026"
}
}
},
"History": {
"annual": {
"2025": {
"EpsActual": 1250.0,
"EpsSurprise": 20.0,
"EpsSurprisePercent": 1.6,
"RevenueActual": 105000000000.0,
"RevenueSurprise": 500000000.0,
"EarningReleaseDate": "2025-03-15",
"CiqFiscalPeriodType": "2025"
}
},
"quarterly": {
"Q42025": {
"EpsActual": 320.0,
"EpsSurprise": 5.0,
"EpsSurprisePercent": 1.5,
"RevenueActual": 27000000000.0,
"RevenueSurprise": 200000000.0,
"EarningReleaseDate": "2025-11-20",
"CiqFiscalPeriodType": "Q42025"
}
}
}
}

View file

@ -1,40 +0,0 @@
[
{
"underlyingInstrument": {
"instrumentId": "bn91jc",
"displayName": "Bank Central Asia Tbk PT",
"shortName": "BBCA",
"symbol": "BBCA.JK"
},
"balanceSheets": {
"currency": "IDR",
"reportDate": "2025-12-31",
"endDate": "2025-12-31",
"currentAssets": {
"cashAndShortTermInvestments": 500000000
},
"equity": {
"totalEquity": 900000000
}
},
"cashFlow": {
"currency": "IDR",
"reportDate": "2025-12-31",
"endDate": "2025-12-31",
"operating": {
"operatingCashFlow": 600000000
}
},
"incomeStatement": {
"currency": "IDR",
"reportDate": "2025-12-31",
"endDate": "2025-12-31",
"revenue": {
"totalRevenue": 1000000000
},
"income": {
"netIncome": 400000000
}
}
}
]

View file

@ -1,39 +0,0 @@
[
{
"instrumentId": "bn91jc",
"displayName": "Bank Central Asia Tbk PT",
"timeLastUpdated": "2026-03-26T04:14:57.9197955Z",
"insights": [
{
"insightName": "P/E ratio",
"category": "Valuation",
"insightStatement": "Unable to compare with peers due to missing earnings data",
"shortInsightStatement": "Earnings data unavailable, can't compare P/E ratio with peers",
"details": {
"evaluationStatus": "NA"
},
"timeLastUpdated": "0001-01-01T00:00:00"
},
{
"insightName": "Analyst price target",
"category": "Valuation",
"insightStatement": "BBCA target price is more than 20% higher than the current share price based on analyst forecast",
"shortInsightStatement": "Analysts forecast more than 20% upside for 12-month price target",
"details": {
"evaluationStatus": "good"
},
"timeLastUpdated": "0001-01-01T00:00:00"
},
{
"insightName": "Quarterly Revenue YoY Growth",
"category": "Earnings",
"insightStatement": "BBCA revenue declined by 6.09% YoY, which is 31.46% worse than its peers (25.37%)",
"shortInsightStatement": "Revenue grew worse than peers",
"details": {
"evaluationStatus": "bad"
},
"timeLastUpdated": "0001-01-01T00:00:00"
}
]
}
]

View file

@ -1,64 +0,0 @@
[
{
"stockId": "bn91jc",
"symbol": "BBCA",
"displayName": "Bank Central Asia Tbk",
"shortName": "Bank Central Asia",
"industryMetrics": [
{
"year": "2025",
"fiscalPeriodType": "FY",
"revenueGrowthRate": 0.081,
"earningsGrowthRate": 0.121,
"netMargin": 0.324,
"roe": 0.198,
"returnOnAssetCurrent": 0.031,
"debtToEquityRatio": 0.42,
"currentRatio": 1.18,
"priceToEarningsRatio": 25.4,
"priceToBookRatio": 4.6
},
{
"year": "2024",
"fiscalPeriodType": "FY",
"revenueGrowthRate": 0.073,
"earningsGrowthRate": 0.102,
"netMargin": 0.311,
"roe": 0.187,
"returnOnAssetCurrent": 0.029,
"debtToEquityRatio": 0.45,
"currentRatio": 1.14,
"priceToEarningsRatio": 24.1,
"priceToBookRatio": 4.2
}
],
"companyMetrics": [
{
"year": "2025",
"fiscalPeriodType": "FY",
"revenueGrowthRate": 0.081,
"earningsGrowthRate": 0.121,
"netMargin": 0.324,
"roe": 0.198,
"returnOnAssetCurrent": 0.031,
"debtToEquityRatio": 0.42,
"currentRatio": 1.18,
"priceToEarningsRatio": 25.4,
"priceToBookRatio": 4.6
},
{
"year": "2024",
"fiscalPeriodType": "FY",
"revenueGrowthRate": 0.073,
"earningsGrowthRate": 0.102,
"netMargin": 0.311,
"roe": 0.187,
"returnOnAssetCurrent": 0.029,
"debtToEquityRatio": 0.45,
"currentRatio": 1.14,
"priceToEarningsRatio": 24.1,
"priceToBookRatio": 4.2
}
]
}
]

View file

@ -1,20 +0,0 @@
[
{
"industryMetrics": [
{
"year": "2025",
"fiscalPeriodType": "TTM",
"priceToEarningsRatio": 12.5,
"forwardPriceToEPS": 11.8,
"priceToBookRatio": 1.7,
"roe": 18.4,
"profitMargin": 22.1,
"revenueGrowthRate": 9.4,
"earningsGrowthRate": 8.1,
"debtToEquityRatio": 0.4,
"currentRatio": 1.3
}
],
"companyMetrics": []
}
]

View file

@ -1,19 +0,0 @@
[
{
"companyMetrics": [
{
"year": "2025",
"fiscalPeriodType": "TTM",
"revenueGrowthRate": 8.1,
"earningsGrowthRate": 12.1,
"priceToEarningsRatio": "Infinity",
"priceToBookRatio": 4.6,
"roe": 19.8,
"profitMargin": 44.2,
"debtToEquityRatio": 0.75,
"currentRatio": 1.4,
"roaTTM": 3.79
}
]
}
]

View file

@ -1,19 +0,0 @@
[
{
"companyMetrics": [
{
"year": "2025",
"fiscalPeriodType": "TTM",
"revenueGrowthRate": 8.1,
"earningsGrowthRate": 12.1,
"priceToEarningsRatio": "-Infinity",
"priceToBookRatio": 4.6,
"roe": 19.8,
"profitMargin": 44.2,
"debtToEquityRatio": "-Infinity",
"currentRatio": 1.4,
"roaTTM": 3.79
}
]
}
]

View file

@ -1,15 +0,0 @@
{
"value": [
{
"id": "news-1",
"title": "BCA reports steady growth",
"url": "https://example.com/news/bca-growth",
"abstract": "BCA delivered steady quarterly growth across lending and deposits.",
"provider": {
"name": "Contoso News"
},
"publishedDateTime": "2026-03-20T10:00:00Z",
"readTimeMin": 3
}
]
}

View file

@ -1,37 +0,0 @@
[
{
"id": "feee16af-c94c-465d-a59d-a9727c22bd0e",
"symbol": "BBCA",
"shortName": "Bank Cntrl Asia",
"displayName": "Bank Central Asia Tbk PT",
"country": "ID",
"company": {
"address": {
"street": "Menara BCA, Grand, Jl. MH Thamrin No. 1",
"city": "JAKARTA PUSAT",
"country": "Indonesia",
"phone": "+62 21 23588000"
},
"description": "PT Bank Central Asia Tbk (the Bank) is an Indonesia-based commercial bank.",
"employees": 27937,
"industry": "Banking Services",
"sector": "Financials",
"website": "https://www.bca.co.id/"
},
"localizedAttributes": {
"en-us": {
"displayName": "PT Bank Central Asia Tbk",
"description": "PT Bank Central Asia Tbk (the Bank) is an Indonesia-based commercial bank."
}
},
"officers": [
{
"name": "Jahja Setiaatmadja",
"title": "President Director",
"age": 69,
"yearBorn": 1955,
"totalPay": 12000000000
}
]
}
]

View file

@ -1,18 +0,0 @@
[
{
"id": "bn91jc",
"instrumentId": "bn91jc",
"symbol": "BBCA",
"shortName": "Bank Central Asia",
"displayName": "Bank Central Asia Tbk",
"price": 9875.0,
"priceChange": 117.0,
"priceChangePercent": 1.2,
"pricePreviousClose": 9758.0,
"price52wHigh": 10250.0,
"price52wLow": 7800.0,
"accumulatedVolume": 12300000.0,
"averageVolume": 10000000.0,
"marketCap": 1215200000000000.0
}
]

View file

@ -1,31 +0,0 @@
{
"count": 2,
"quote": [
{
"symbol": "BBCA.XIDX",
"shortName": "BBCA",
"price": 9875,
"priceChange": 117,
"priceChangePercent": 1.2,
"pricePreviousClose": 9758,
"price52wHigh": 10500,
"price52wLow": 8000,
"accumulatedVolume": 12300000,
"averageVolume": 10000000,
"marketCap": 1215200000000000
},
{
"symbol": "BBRI.XIDX",
"shortName": "BBRI",
"price": 5100,
"priceChange": 210,
"priceChangePercent": 4.3,
"pricePreviousClose": 4890,
"price52wHigh": 5400,
"price52wLow": 3900,
"accumulatedVolume": 22200000,
"averageVolume": 18000000,
"marketCap": 780000000000000
}
]
}

View file

@ -1,20 +0,0 @@
[
{
"symbol": "BBCA.JK",
"displayName": "Bank Central Asia Tbk PT",
"sentimentStatistics": [
{
"timeRangeName": "1D",
"bullish": 10,
"bearish": 2,
"neutral": 3
},
{
"timeRangeName": "1W",
"bullish": 25,
"bearish": 5,
"neutral": 7
}
]
}
]

View file

@ -1,82 +0,0 @@
{
"quoteSummary": {
"result": [
{
"defaultKeyStatistics": {
"forwardPE": {
"raw": 23.1,
"fmt": "23.10"
},
"priceToBook": {
"raw": 4.6,
"fmt": "4.60"
},
"enterpriseValue": {
"raw": 1245000000000000,
"fmt": "1.25T"
},
"trailingEps": {
"raw": 384.25,
"fmt": "384.25"
},
"forwardEps": {
"raw": 410.18,
"fmt": "410.18"
}
},
"financialData": {
"trailingPE": {
"raw": 25.4,
"fmt": "25.40"
},
"marketCap": {
"raw": 1215200000000000,
"fmt": "1.22T"
},
"currentPrice": {
"raw": 9875,
"fmt": "9,875.00"
},
"returnOnEquity": {
"raw": 0.202,
"fmt": "20.20%"
},
"returnOnAssets": {
"raw": 0.038,
"fmt": "3.80%"
},
"profitMargins": {
"raw": 0.385,
"fmt": "38.50%"
},
"revenueGrowth": {
"raw": 0.118,
"fmt": "11.80%"
},
"earningsGrowth": {
"raw": 0.121,
"fmt": "12.10%"
},
"debtToEquity": {
"raw": 18.5,
"fmt": "18.50"
},
"currentRatio": {
"raw": 1.21,
"fmt": "1.21"
},
"ebitda": {
"raw": 58500000000000,
"fmt": "58.50B"
},
"totalRevenue": {
"raw": 147900000000000,
"fmt": "147.90B"
}
},
"incomeStatementHistory": {}
}
],
"error": null
}
}

View file

@ -1,231 +0,0 @@
//! Golden output tests: byte-for-byte parity of CLI stdout, stderr, and exit
//! code for every shipped command (see "Parity and Verification" in
//! docs/DESIGN.md).
//!
//! Cases live in `tests/golden/cases.toml`; expected output in
//! `tests/golden/<case>.golden`. Regenerate only for an intentional, reviewed
//! output change, and commit the diff with the reason:
//!
//! UPDATE_GOLDEN=1 cargo test --test golden
use std::collections::{BTreeMap, BTreeSet};
use std::fs;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::sync::OnceLock;
use serde::Deserialize;
const IDX: &str = env!("CARGO_BIN_EXE_idx");
const REPO: &str = env!("CARGO_MANIFEST_DIR");
#[derive(Deserialize)]
struct CaseFile {
case: Vec<Case>,
}
#[derive(Deserialize)]
struct Case {
name: String,
args: Vec<String>,
/// Output formats to expand the case into (`-o <format>` is prepended and
/// `.<format>` appended to the name). Empty means run the args as given.
#[serde(default = "default_formats")]
formats: Vec<String>,
#[serde(default)]
env: BTreeMap<String, String>,
/// Seed the fixture ownership DB before running.
#[serde(default)]
ownership: bool,
/// Commands run first in the same environment; their output is ignored.
#[serde(default)]
before: Vec<Vec<String>>,
/// Text piped to the command's stdin.
#[serde(default)]
stdin: Option<String>,
}
fn default_formats() -> Vec<String> {
vec!["table".into(), "json".into()]
}
fn golden_dir() -> PathBuf {
Path::new(REPO).join("tests").join("golden")
}
fn work_dir() -> PathBuf {
std::env::temp_dir().join(format!("idx-golden-{}", std::process::id()))
}
/// Runs idx with an isolated home under `root` and only the given IDX_* env.
fn idx(root: &Path, args: &[String], env: &BTreeMap<String, String>) -> std::process::Output {
idx_with_stdin(root, args, env, None)
}
fn idx_with_stdin(
root: &Path,
args: &[String],
env: &BTreeMap<String, String>,
stdin: Option<&str>,
) -> std::process::Output {
let mut cmd = Command::new(IDX);
cmd.current_dir(REPO).args(args);
for (key, _) in std::env::vars_os() {
if key.to_string_lossy().starts_with("IDX_") || key == "NO_COLOR" {
cmd.env_remove(key);
}
}
cmd.env("HOME", root)
.env("XDG_CONFIG_HOME", root.join("config"))
.env("XDG_CACHE_HOME", root.join("cache"))
.env("XDG_DATA_HOME", root.join("data"))
.env("IDX_USE_MOCK_PROVIDER", "1")
.envs(env)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped());
let mut child = cmd.spawn().expect("spawn idx");
let mut pipe = child.stdin.take().expect("stdin pipe");
if let Some(input) = stdin {
pipe.write_all(input.as_bytes()).expect("write stdin");
}
drop(pipe);
child.wait_with_output().expect("run idx")
}
/// Fixture ownership DB: the above-1% XLSX (2026-08-31) plus two KSEI archive
/// months (2026-01-30, 2026-02-27), with wall-clock columns pinned.
fn seeded_ownership_db() -> &'static Path {
static DB: OnceLock<PathBuf> = OnceLock::new();
DB.get_or_init(|| {
let root = work_dir().join("seed");
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(&root).expect("create seed dir");
// The importer derives the release from the IDX file name.
let xlsx = root.join("peng-2026-08-00017-satu-persen.xlsx");
fs::copy(
Path::new(REPO).join("tests/fixtures/ksei_above1_20260831_excerpt.xlsx"),
&xlsx,
)
.expect("copy xlsx fixture");
let inputs = [
xlsx,
Path::new(REPO).join("tests/fixtures/ksei_balancepos_20260130_excerpt.txt"),
Path::new(REPO).join("tests/fixtures/ksei_balancepos_20260227_excerpt.txt"),
];
for input in inputs {
let args = ["ownership", "import", "--file", input.to_str().unwrap()]
.map(String::from)
.to_vec();
let out = idx(&root, &args, &BTreeMap::new());
assert!(out.status.success(), "seed import failed: {out:?}");
}
let db = root.join("data/idx/ownership.db");
let conn = rusqlite::Connection::open(&db).expect("open seed db");
conn.execute_batch(
"UPDATE ownership_releases SET imported_at = 0;
UPDATE entities SET created_at = 0, updated_at = 0;
UPDATE bing_holdings SET fetched_at = 0;",
)
.expect("pin timestamps");
db
})
}
fn render(root: &Path, out: &std::process::Output) -> String {
let normalize = |bytes: &[u8]| {
String::from_utf8_lossy(bytes)
.replace(root.to_str().unwrap(), "<ROOT>")
.replace(REPO, "<REPO>")
};
format!(
"exit: {}\n--- stdout\n{}--- stderr\n{}",
out.status.code().map_or("signal".into(), |c| c.to_string()),
normalize(&out.stdout),
normalize(&out.stderr),
)
}
#[test]
fn cli_output_matches_golden_files() {
let raw = fs::read_to_string(golden_dir().join("cases.toml")).expect("read cases.toml");
let cases: CaseFile = toml::from_str(&raw).expect("parse cases.toml");
let update = std::env::var_os("UPDATE_GOLDEN").is_some();
let mut seen = BTreeSet::new();
let mut failures = Vec::new();
for case in &cases.case {
let runs: Vec<(String, Vec<String>)> = if case.formats.is_empty() {
vec![(case.name.clone(), case.args.clone())]
} else {
case.formats
.iter()
.map(|format| {
let mut args = vec!["-o".to_string(), format.clone()];
args.extend(case.args.iter().cloned());
(format!("{}.{format}", case.name), args)
})
.collect()
};
for (name, args) in runs {
assert!(seen.insert(name.clone()), "duplicate golden case {name}");
let root = work_dir().join(&name);
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(&root).expect("create case dir");
if case.ownership {
let target = root.join("data/idx/ownership.db");
fs::create_dir_all(target.parent().unwrap()).expect("create data dir");
fs::copy(seeded_ownership_db(), &target).expect("copy seeded db");
}
for before in &case.before {
idx(&root, before, &case.env);
}
let output = idx_with_stdin(&root, &args, &case.env, case.stdin.as_deref());
let actual = render(&root, &output);
let path = golden_dir().join(format!("{name}.golden"));
if update {
fs::write(&path, &actual).expect("write golden");
} else {
match fs::read_to_string(&path) {
Ok(expected) if expected == actual => {}
Ok(expected) => failures.push(format!(
"{name}: output differs\n--- expected\n{expected}\n--- actual\n{actual}"
)),
Err(_) => failures.push(format!("{name}: missing {}", path.display())),
}
}
}
}
for entry in fs::read_dir(golden_dir()).expect("read golden dir") {
let path = entry.expect("dir entry").path();
let Some(stem) = path
.file_name()
.unwrap()
.to_str()
.unwrap()
.strip_suffix(".golden")
else {
continue;
};
if !seen.contains(stem) {
if update {
fs::remove_file(&path).expect("remove orphan golden");
} else {
failures.push(format!("{stem}: golden file has no case in cases.toml"));
}
}
}
let _ = fs::remove_dir_all(work_dir());
assert!(
failures.is_empty(),
"{} golden mismatch(es); if the change is intentional, rerun with UPDATE_GOLDEN=1 \
and commit the diff with the reason\n\n{}",
failures.len(),
failures.join("\n\n")
);
}

View file

@ -1,8 +0,0 @@
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

View file

@ -1,4 +0,0 @@
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

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
{"failed":[],"removed":0}
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
cleared 0 files
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
{"files":0,"newest":null,"oldest":null,"path":"<ROOT>/cache/idx","size_bytes":0}
--- stderr

View file

@ -1,8 +0,0 @@
exit: 0
--- stdout
path: <ROOT>/cache/idx
files: 0
size_bytes: 0
oldest: -
newest: -
--- stderr

View file

@ -1,382 +0,0 @@
# 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

File diff suppressed because it is too large Load diff

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
msn
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
<ROOT>/config/idx/config.toml
--- stderr

View file

@ -1,8 +0,0 @@
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

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
<ROOT>/config/idx/config.toml
--- stderr

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
{"code":"INVALIDINPUT","error":true,"message":"invalid input: invalid output format 'yaml': expected 'auto', 'table', 'json', or 'jsonl'"}

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
ok
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
ok
--- stderr

View file

@ -1,4 +0,0 @@
exit: 4
--- stdout
--- stderr
{"code":"PROVIDERUNAVAILABLE","error":true,"message":"provider unavailable"}

View file

@ -1,4 +0,0 @@
exit: 4
--- stdout
--- stderr
Error: provider unavailable

View file

@ -1,4 +0,0 @@
exit: 5
--- stdout
--- stderr
{"code":"UNSUPPORTED","error":true,"message":"unsupported: --fetch-bing import is not implemented yet"}

View file

@ -1,4 +0,0 @@
exit: 5
--- stdout
--- stderr
Error: unsupported: --fetch-bing import is not implemented yet

View file

@ -1,4 +0,0 @@
exit: 1
--- stdout
--- stderr
{"code":"PARSEERROR","error":true,"message":"parse error: unsupported: company fundamentals unavailable from MSN; industry fallback is disabled"}

View file

@ -1,4 +0,0 @@
exit: 1
--- stdout
--- stderr
Error: parse error: unsupported: company fundamentals unavailable from MSN; industry fallback is disabled

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
{"code":"CONFIGERROR","error":true,"message":"config error: invalid IDX_OUTPUT value: 'yaml', expected 'auto', 'table', 'json', or 'jsonl'"}

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
{"code":"CONFIGERROR","error":true,"message":"config error: invalid provider 'bogus' (expected yahoo or msn)"}

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
Error: config error: invalid provider 'bogus' (expected yahoo or msn)

View file

@ -1,4 +0,0 @@
exit: 3
--- stdout
--- stderr
{"code":"CACHEMISS","error":true,"message":"cache miss: msn-quote/BBCA.JK"}

View file

@ -1,4 +0,0 @@
exit: 3
--- stdout
--- stderr
Error: cache miss: msn-quote/BBCA.JK

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
{"code":"INVALIDINPUT","error":true,"message":"invalid input: cannot combine --offline with --no-cache"}

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
Error: invalid input: cannot combine --offline with --no-cache

View file

@ -1,4 +0,0 @@
exit: 4
--- stdout
--- stderr
{"code":"PROVIDERUNAVAILABLE","error":true,"message":"provider unavailable"}

View file

@ -1,4 +0,0 @@
exit: 4
--- stdout
--- stderr
Error: provider unavailable

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
{"code":"INVALIDINPUT","error":true,"message":"invalid input: invalid screener region 'eu' (expected one of: id, us, sg, hk, jp)"}

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
{"code":"INVALIDINPUT","error":true,"message":"invalid input: invalid screener region 'eu' (expected one of: id, us, sg, hk, jp)"}

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
Error: invalid input: invalid screener region 'eu' (expected one of: id, us, sg, hk, jp)

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
{"code":"INVALIDINPUT","error":true,"message":"invalid input: no symbols read from stdin"}

View file

@ -1,4 +0,0 @@
exit: 2
--- stdout
--- stderr
Error: invalid input: no symbols read from stdin

View file

@ -1,9 +0,0 @@
exit: 2
--- stdout
--- stderr
error: the following required arguments were not provided:
<SYMBOLS>...
Usage: idx stocks quote <SYMBOLS>...
For more information, try '--help'.

View file

@ -1,9 +0,0 @@
exit: 2
--- stdout
--- stderr
error: the following required arguments were not provided:
<SYMBOLS>...
Usage: idx stocks quote <SYMBOLS>...
For more information, try '--help'.

View file

@ -1,4 +0,0 @@
exit: 5
--- stdout
--- stderr
{"code":"UNSUPPORTED","error":true,"message":"unsupported: BBCA.JK: command requires --provider msn"}

View file

@ -1,4 +0,0 @@
exit: 5
--- stdout
--- stderr
Error: unsupported: BBCA.JK: command requires --provider msn

View file

@ -1,20 +0,0 @@
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

View file

@ -1,22 +0,0 @@
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

View file

@ -1,58 +0,0 @@
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

View file

@ -1,40 +0,0 @@
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

View file

@ -1,33 +0,0 @@
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

View file

@ -1,4 +0,0 @@
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

View file

@ -1,16 +0,0 @@
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

View file

@ -1,32 +0,0 @@
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

View file

@ -1,4 +0,0 @@
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

View file

@ -1,14 +0,0 @@
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

View file

@ -1,4 +0,0 @@
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

View file

@ -1,40 +0,0 @@
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

View file

@ -1,4 +0,0 @@
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

View file

@ -1,10 +0,0 @@
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

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
null
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
No institutional flow data available for BBCA.
--- stderr

View file

@ -1,4 +0,0 @@
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

View file

@ -1,20 +0,0 @@
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

View file

@ -1,4 +0,0 @@
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

View file

@ -1,10 +0,0 @@
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

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
{"action":"imported","inserted_rows":18,"ticker_count":1,"as_of_date":"2026-02-27","sha256":"7b8da1d820f67062410c48988bb6c70fec2088c24961d481d1c0fce8b9372547","source_url":null}
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
Imported 18 rows for 1 tickers (as of 2026-02-27).
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
{"action":"imported","inserted_rows":17,"ticker_count":4,"as_of_date":"2026-08-31","sha256":"7c1a4c209b8ce5bde9112436a0c64d66b042915995b584d2bbf7ca7b15ce81e3","source_url":null}
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
Imported 17 rows for 4 tickers (as of 2026-08-31).
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
[]
--- stderr

View file

@ -1,4 +0,0 @@
exit: 0
--- stdout
No ownership releases imported yet.
--- stderr

Some files were not shown because too many files have changed in this diff Show more