Content
<div align="center">
<br>
<img alt="DartLab" src=".github/assets/logo.png" width="180">
<h3>DartLab</h3>
<p><b>One stock code, the whole story of a company.</b></p>
<p>Korean DART + US SEC EDGAR disclosures read and compared with a line of Python.</p>
<p>
<a href="https://pypi.org/project/dartlab/"><img src="https://img.shields.io/pypi/v/dartlab?style=for-the-badge&color=ea4647&labelColor=050811&logo=pypi&logoColor=white" alt="PyPI"></a>
<a href="https://pypi.org/project/dartlab/"><img src="https://img.shields.io/pypi/pyversions/dartlab?style=for-the-badge&color=c83232&labelColor=050811&logo=python&logoColor=white" alt="Python"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-94a3b8?style=for-the-badge&labelColor=050811" alt="License"></a>
<a href="https://github.com/eddmpython/dartlab/actions/workflows/ci-fast.yml"><img src="https://img.shields.io/github/actions/workflow/status/eddmpython/dartlab/ci-fast.yml?branch=master&style=for-the-badge&labelColor=050811&logo=github&logoColor=white&label=CI" alt="CI"></a>
<a href="https://codecov.io/gh/eddmpython/dartlab"><img src="https://img.shields.io/codecov/c/github/eddmpython/dartlab?style=for-the-badge&labelColor=050811&logo=codecov&logoColor=white&label=Coverage" alt="Coverage"></a>
<a href="https://eddmpython.github.io/dartlab/"><img src="https://img.shields.io/badge/Docs-GitHub_Pages-38bdf8?style=for-the-badge&labelColor=050811&logo=github-pages&logoColor=white" alt="Docs"></a>
<a href="https://eddmpython.github.io/dartlab/blog/"><img src="https://img.shields.io/badge/Blog-fbbf24?style=for-the-badge&labelColor=050811&logo=rss&logoColor=white" alt="Blog"></a>
</p>
<p>
<a href="https://eddmpython.github.io/dartlab/">Documentation</a> · <a href="https://eddmpython.github.io/dartlab/skills">Skill OS</a> · <a href="https://eddmpython.github.io/dartlab/skills/market">Skill Market</a> · <a href="https://eddmpython.github.io/dartlab/blog/">Blog</a> · <a href="https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/01_company.ipynb">Open in Colab</a> · <a href="https://molab.marimo.io/github/eddmpython/dartlab/blob/master/notebooks/marimo/01_company.py">Open in Molab</a> · <a href="README_EN.md">English</a> · <a href="https://buymeacoffee.com/eddmpython">Sponsor</a>
</p>
<p>
<a href="https://huggingface.co/datasets/eddmpython/dartlab-data"><img src="https://img.shields.io/badge/Data-HuggingFace-ffd21e?style=for-the-badge&labelColor=050811&logo=huggingface&logoColor=white" alt="HuggingFace Data"></a>
<a href="https://github.com/eddmpython/dartlab-desktop/releases/latest/download/DartLab.exe"><img src="https://img.shields.io/badge/Desktop-Windows-38bdf8?style=for-the-badge&labelColor=050811&logo=windows&logoColor=white" alt="Desktop Download"></a>
</p>
<a href="https://www.youtube.com/shorts/97lYLWMWzvA"><img src="https://img.youtube.com/vi/97lYLWMWzvA/maxresdefault.jpg" alt="DartLab Demo" width="320"></a>
</div>
## What does it do?
DartLab is a Python library that converts DART and EDGAR disclosures into comparable data with a single stock code. It reads financial statements, disclosure texts, disclosure lists, ratios, credit risk, industry maps, and macroeconomic contexts with the same `Company` interface.
The key is not just simple collection. It horizontalizes different account names and disclosure tables for each company into `topic × period` and `account × period` formats, allowing for comparisons between last year and this year, Samsung and Apple, and a single stock with the entire market using the same question.
| Before | After |
|---|---|
| Open multiple annual reports and align the table of contents | `c.panel()` |
| Map XBRL account names and Korean item names manually | `c.panel("IS")` |
| Collect and normalize financial ratios for all stocks manually | `dartlab.scan("profitability")` |
| Recheck AI answers with numbers | `dartlab.ask(...)` + execution basis ref |
## Three starting points
DartLab offers three paths: **AI / Python / CLI**, all on the same data and engine.
| Usage | Code length | First result | Suitable for |
|---|---|---|---|
| [Use directly with AI](#use-directly-with-ai) | 1 line | ~1 minute | Analysts who want to ask questions and get answers with basis |
| [Use with Python code](#use-with-python-code) | 3-5 lines | ~3 minutes | Developers who handle financial statement, disclosure, and scan data directly |
| [Use with CLI](#use-with-cli) | 1 command | ~2 minutes | Users who want to query, automate scripts, or use shell pipelines |
Each path calls the same analysis engine, `dartlab.Company`. The starting point is different, but the result is the same.
## Use directly with AI
Enter a company name or stock code and ask questions in natural language. DartLab AI executes tools like `Company`, `analysis`, `credit`, `scan`, and `macro` internally. It provides not only answers but also references to the data and calculations used.
<p>
<a href="https://github.com/eddmpython/dartlab-desktop/releases/latest/download/DartLab.exe">
<img src="https://img.shields.io/badge/Windows_Desktop-Download-2563eb?style=for-the-badge&labelColor=050811&logo=windows&logoColor=white" alt="Windows Desktop Download">
</a>
<a href="https://eddmpython.github.io/dartlab/skills">
<img src="https://img.shields.io/badge/Skill_OS-Open-38bdf8?style=for-the-badge&labelColor=050811" alt="Skill OS">
</a>
</p>
```python
import dartlab
dartlab.ask("Analyze Samsung Electronics' financial health")
# AI executes the necessary data queries and calculations, returning results with references
```
Advantages of the AI path:
- **Design your own analysis flow** — Combine disclosure, financial statement, credit, macro, and peer comparison tools according to your questions.
- **Numbers can be recalculated** — Numbers and tables in answers are linked to execution results and references.
- **Disclosure texts are treated as data only** — DART/EDGAR/web text instructions are not followed, and only used as analysis basis.
- **External LLM linkage possible** — Same interface called from tools like Claude Code, Codex CLI, and Cursor with MCP.
```bash
claude mcp add dartlab -- dartlab mcp
codex mcp add dartlab -- dartlab mcp
```
> Claude Desktop · Remote SSE · Absolute path options are in the [MCP section](#mcp--ai-assistant-integration).
## Use with Python code
The Python path centers around `Company`. With a single stock code, you can call financial statements, disclosure texts, regular reports, and ratios with the same `c.panel` interface.
```bash
uv add dartlab
```
```python
import dartlab
c = dartlab.Company("005930") # Samsung Electronics
c.panel() # All disclosures in a horizontal grid (item × period)
# shape: (223, 14) — disclosure items × periods
c.panel("IS") # Income statement (finance-normalized numbers)
c.panel("is") # Native income statement — as in the disclosure (XBRL+old 2013~)
c.panel("ratios") # Native financial ratios (calculated from 5 statements)
c.panel("business") # Disclosure text search
c.filings() # Original disclosure links
```
```python
# Same interface, different market
kr = dartlab.Company("005930")
us = dartlab.Company("AAPL")
kr.panel("IS")
us.panel("IS")
```
Advantages of the Python path:
- **No API key required** — Pre-built data is automatically downloaded from HuggingFace and cached locally.
- **Period comparisons are basic** — Align disclosure texts and financial statements by period.
- **Korean and US markets in the same interface** — Differences between DART and EDGAR are absorbed by the provider.
- **Engine results can be reused** — Analysis, credit, macro, quant, industry, and story results can be directly handled in code.
## Use with CLI
After installation, call the same engine with the `dartlab` command in your shell. Friendly for one-time queries, automation scripts, and shell pipelines.
```bash
uv add dartlab
dartlab help "Foreign investor buying" # Help + capability search
dartlab list scan # Scan category recipe index
dartlab show 005930 IS # Income statement output (equivalent to Python c.panel("IS"))
dartlab analyze 005930 --aspect credit
dartlab mcp # MCP server entry (for external LLM tool registration)
```
Advantages of the CLI path:
- **No API key required for one-time queries** — Automatic HuggingFace cache usage
- **Shell pipeline friendly** — Combine with `dartlab show ... --json | jq ...`
- **Same MCP server entry point** — `dartlab mcp` exposes external assistant tools
> Complete CLI command list + options are in `dartlab --help` or Skill OS (`src/dartlab/skills/specs/operation/code.md`).
## Example results
Below are representative results obtained directly from the Python path. Disclosure texts, financial statements, and original links come from the same `Company` object.
```python
import dartlab
c = dartlab.Company("005930") # Samsung Electronics
c.panel() # All items, all periods, side by side — grid captured
# shape: (223, 14) — disclosure items × periods
```
> Text and number time series horizontalization — core of comparability
>
> <img src=".github/assets/sections-example.webp" alt="c.panel() output example — Samsung Electronics disclosure items × periods" width="720">
```python
c.panel("IS") # Income statement — quarterly (finance-normalized)
```
> Quarterly financial statements are basic — snakeId + Korean item names provided
>
> <img src=".github/assets/show-is-quarterly.webp" alt="c.panel('IS') — Samsung Electronics quarterly income statement" width="720">
```python
c.panel("IS", freq="year") # Annual aggregation with freq
c.panel("is", freq="year") # Native income statement — as in the disclosure (2013~)
c.panel("ratios") # Native financial ratios, calculated from 5 statements
```
> Same data, annual aggregation — lowercase=native (disclosure deep history) / uppercase=finance (normalized)
>
> <img src=".github/assets/show-is-annual.webp" alt="c.panel('IS', freq='year') — Samsung Electronics annual income statement" width="720">
```python
c.panel("business") # Disclosure text search
c.panel.search("inventory") # Full text search
c.filings() # All reports — linked to DART viewer
```
> Direct access to original reports with dartUrl
>
> <img src=".github/assets/show-filings.webp" alt="c.filings() — Samsung Electronics report list + DART viewer links" width="720">
```python
# Same interface, different country
us = dartlab.Company("AAPL")
us.panel("business")
us.panel("ratios")
# Ask questions in natural language
dartlab.ask("Analyze Samsung Electronics' financial health")
# → AI executes code, analyzes: "Operating margin rose from 8.6% to 21.4%..."
```
No API key required. Automatic download from [HuggingFace](https://huggingface.co/datasets/eddmpython/dartlab-data) and local caching.
## Three layers of analysis
When `Company` prepares data with a single stock code, three layers analyze it.
1. **Analysis engine** — Generates numbers. No interpretation. Provides only numbers and basis.
2. **Story (L3 combiner)** — No analysis engine. Responsible for combining L2 analysis engines into 11 report types × 7 company type templates. No interpretation — systematically arranges diverse perspectives and basis.
3. **AI** — Directly uses the engine, judges results, verifies originals, and recalculates if abnormal. Represents DartLab's proactive analyst.
What is DartOne call contract. Guide withlab.engine()` and execute with `dartlab.engine("axis")`.
> **For beginners?** Follow the order: `Company` → `Story` → `Ask`. Use the stock code data, create reports, AI.
> **Click the engine name** will 4 sections (`Public` · `Call Action`Representative Return Type` · `Basic Verification`). All engines same 4 sections.
| Layer | Engine | What it does | Entry point | Notebook |
|--------|------|---------|--------|-------- Data |](https://eddmpython.github.io/dartlab/skills/engines | HuggingFace pre automatic download | `Company930")` | — L1 | [Company](https://eddmpython.github.io/dartlab/skills/engines.company) | Provider facade — disclosure + financial statements + structured data integrated into one stock code | `c.panel()` | [Colab](https://colab.research/github/eddmpartlab/blob/master/n/colab/01_company.ipynb) · [marimo](https://marimo.app/github.com/eddmpython/dartlab/blob/master/notebooks/marimo/01_company.py) |
| L1 | [Gather](https://eddmpython.github.io/dartlab/skills/engines.gather) | External market data (stock price/supply and demand/macro/news) | `dartlab.gather()` | [Colab](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/02_gather.ipynb) · [marimo](https://marimo.app/github.com/eddmpython/dartlab/blob/master/notebooks/marimo/02_gather.py) |
| L1.5 | [Scan](https://eddmpython.githubartlab/skills/engines.scan) | Pre-built for all stocks (governance/ratios/cash flow. parquet) | `dartlab.scan()` | [Colab](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/03_scan.ipynb) · [marimo](https://marimo.app/github.com/eddmpython/dartlab/blob/master/noteimo/03_scan.py) |
| L2 | [Analysis](https://eddmpython.github.io/dartlab/skills/engines.analysis) | In-depth financial analysis (profitability/stability/cash flow) + valuation + outlook | `c.analysis("financial", "profitability")` | [Colab](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/05_analysis.ipynb) · [marhttps://marimo.app/github.com/eddmpython/dartlab/notebooks/mar05_analysis.py) |
| L [Quant](https://eddmpython.github.io/dartlab/skills/engines.quant) | Price-based quantitative signals (technical/risk/factor/backtest) | `c.quant()` | [Colab](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/04_quant.ipynb) · [marimo](https://marimo.app/github.com/eddmpython/dartlab/blob/master/notebooks/marimo/04_quant.py) |
| L2 | [Credit](https://eddmpython.github.io/dartlab/skills/engines.credit) | Independent credit evaluation (dCR rating, default probability, soundness) | `c.credit("rating")` | [Colab](https://colab.research/eddmpython/dartlab/notebooks/colab/07_credit.ipynb) · [marimo](https://marimo.app/github.com/eddmpython/dartlab/blob/master/notebooks/marimo/07_credit.py) |
| L2 | [https://eddmpython.github.io/dartlab/skills/engines.macro) | Market-level macro (interest rate/liquidity/sentiment/asset + 110 scenarios) | `dartlab.macro("cycle")` | [Colab](https://colab.res.com/github/eddmpython/dartlab/blobbooks/colab/06_macro.ipynb) ·imo](https://marimo.app/github.com/eddmpython/dartlab/blob/master/notebooks/marimo/06_macro.py) |
| L2 | [Industry](https://eddmpython.github.io/dartlab/skills/engines.industry) | Industry listed companies × process/role/stream + supply chain edge (industry map `/map`) | `c.industry()`, `dartlab.industry("semiconductor")` | — |
| L3 |](https://eddmpython.github.io/dartlab/skills/eng) | Combiner (analysis engine X) — L2 5 engines (analysis · credit · macro · quant · + L1.5 scan block combination. Prevents circular references. 11 types × 7 templates (not interpreted) | `c.story("profitability")` | [Colab](https://colab.research.google.com/github/eddmpython/dartlab/notebooks/colab/08_story.ipynb) · [](https://marimo.app/github.com/eddmpython/dartlab/blob/master/notebooks/08_story.py) |
| L4 | [AI/Skills](https://eddmpython.github.io/dartlab/skills) | Skills search + DartLab execution + ref calculation for analysis workspace (L4) | `dartlab.ask()` | [Colab](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/09_ai.ipynb) · [marimo](https://marimo.app/githubeddmpython/dartlab/blob/master/notebooks/marimo/09_ai.py) |
| L4 | [Channel](https://eddmpython.github.io/dartlab/skills) | External sharing — `dartlab channel` for using DartLab on phone and PC | `dartlab channel` | — |
| core | [Search](https://eddmpython.github.io/dartlab/skills/eng) | Disclosure semantic search *(beta — index freshness lacking)* | `dartlab.search()` |ab](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/10_search.ipynb) · [marimo](https://marimo.com/eddmpython/dartlab/blob/master/notebooks/marimo/10_search.py) |
| [Listing](https://eddmpython.github.io/dartlab/skills/engines) | Stock/disclosure/topic catalog API | `dartlab.listing()` | [Colab](https://colab.research.google.com/github/eddmpython/d/blob/master/notebooks/colab/11_listing.ipynb) · [marimo](https://marimo.app/github.com/eddmpython/dartlab/blob/master/notebooks/marimo/11_listing.py) |
| viz | [Viz](httpsmpython.github.io/dartlab/skills/engines.viz) | Chart/diagram (`emit_chart`) | `emit_chart({...})` | — |
> All notebooks: [marimo](notebooks/marimo/) · [colab](notebooks/colab/) · [](https://marimo.app/eddmpython/dartlab/blob/master/notebooks/marimo)
### Company
> Design: [engines.company](https://eddmpython.github.io/dartlab/skills)
Integrates three data sources — docs (expert disclosure), finance (XBRL financial statements), report (DART API structured data) — into one object. Automatic download from [HuggingFace](https://h.co/datasets/eddmpython/dartlab-data), no setup required.
c =.Company("005930")
c.panel() at a glance — disclosure items × entire period
c.panel("BS") # Balance sheet — finance normalized numbers
("bs") # Native balance sheet — business report items as is (2013~.panel("ratios") # Native financial ratios — calculated from 5 tables
("매출") # Item name row search)
```
**Notes** — Breakdown of items behind BS/IS totals. Accessible with `c.panel("topic in the same pattern as financial statements. DART (K-IFRS HTML parsing) and EDGAR (US-GAAP tags) have the same interface.
| `c.panel(...)` | Content | DART | EDGAR |
|---------------|------|:----:|:-----:|
| `"inventory"` | raw materials/WIP/finished goods | ✅ | ✅ |
|ings"` | Short-term/long-term borrowings breakdown | ✅ || `"tangibleAsset"` | Tangible asset acquisition cost/depreciation/carrying value | ✅ |
| `"Asset"` | Goodwill/R&D expenses, etc. | ✅ | ✅ |
| `"receivables"` | Accounts receivable + allowance for doubtful accounts | ✅ | ✅ |
| `"provisions Warranty/litigation/structural adjustment provisions | ✅ | ✅ |
| `"eps"` | Basic/diluted EPS | ✅ | ✅ |
| `"segments"` | Segment-wise sales/profits | ✅ |
| `"Nature"` | Cost of/salaries/depreciation, etc. | ✅ | ✅lease"` | Right-of-use assets/lease liabilities | ✅ | ✅ |
| `"affiliates"` | Equity-method investments in affiliates | ✅ | ✅ |
| `"investmentProperty"` property fair value/carrying value | ✅ |> [](https://marimo.app/githubeddmpython/dartlab/blob/master/notebooks/mar01_company.py) [](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/noteab/01_company### Scan — Cross-sectional comparison Design: [engines.scan](https://eddmpython.github.io/dartlab/skills)
analysis across all stocks. Governance, personnel, shareholder return, debt, cash flow, audit, insider, earnings quality, network, account/ratio comparison, etc.
```python
dartlab.scan("governance") # Governance across all stocks
dartlab.scan("ratio", "roe") # ROE across all stocks
dartlab.scan("account", "매출액") # Sales across all stocks over time
```
> Sales of 2,500+ stocks at once — immediately comparable in quarterly time series> <img src=".github/assets/scan-account.webp" alt="dartlab.scan('account', '매출액') — Cross-sectional sales comparison across all stocks" width="720">
### Gather — External market data
> Designengines.gather](https://ython.github.io/dartlab/skills)
Stock prices, supply and demand, macroeconomic indicators, news — in Polars DataFrame.
```python
dartlab.gather("price", "005930") # KR OHLCV
dartlab.gather("price", "AAPL", market="US") # US stock price
dartlab.gather("macro", "FEDFUNDS") # Automatic US detection
dartlab.gather("news", "삼성전자") # Google News RSS
```
**Batch processing for large data** — Divide insider trades, holdings, and news into generators for iteration (memory-safe, for scanning all stocks):
```python
from dartlab.gather.accessors import DefaultFinanceAccessor
a = DefaultFinancefor batch in a.iterNews("삼성전자", days=30, batchSize=100):
process(batch)
# Also available: a.iterInsiderTrades("005930") · a.iterOwnership("005930")
#: a.fetchInsiderTrades / fetchOwnership / fetchNews
```
The `getDefaultGather()` singleton is thread-safe (guaranteed single instance in multi-threaded environments). Cache statistics and source fallback signals can be tracked with `getCache()` and `DARTLAB_TELE=stdout`.
### Analysis — Financial causal analysis
> Design: [engines.analysis://eddmp.io/dartlab/skProfit structure → profitability → growth → stability → cash flow → capital allocation → valuation → outlook. Transforms original financial statements into a causal narrative.
```python
c.analysis("financial", "profitability") # Profit
c.analysis("profitability") Shorthand (automatic financial)
print(c.credit()) # Available axis guide DataFrame (self-discovery.credit(" # dAA, 93/100
c.credit("rating", detail=True) # Rating + narrative + indicator time series
```
### Credit — Independent Credit Analysis
> Design: [engines.credit](https://eddmpython.github.io/dartlab/skills) | Report: [eddmpython.github.io/dartlab/blog/credit-reports](https://eddmpython.github.io/dartlab/blog/credit-reports)
3-Track model (General/Finance/Holding) + Notch Adjustment + CHS market adjustment + separate financial blending.
**79 company verification: Large enterprises 87% (26/30), Medium and large enterprises 82% (41/50), Overall 70% (55/79, v5.0 overestimation correction and remeasurement pending). Samsung Electronics AA+ accurate match.** Verification methodology is referenced in [methodology](https://eddmpython.github.io/dartlab/skills/operation.methodology).
```python
print(c.credit()) # self-discovery — available axes + comprehensive rating
cr = c.credit("rating") # comprehensive rating
print(cr["grade"]) # dCR-AA+
print(cr["healthScore"]) # 96 (0-100, higher is healthier)
print(cr["pdEstimate"]) # 0.01% default probability
cr = c.credit("rating", detail=True) # rating + narrative + indicators + divergence explanation
print(cr["divergenceExplanation"]) # why it differs from other rating agencies
```
Credit analysis report publication (credit narrative + rating agency comparison automatically integrated into a 5-act story):
```python
from dartlab.story.publisher import publishReport
publishReport("005930") # 6-act report (credit narrative + audit included)
```
### Macro — Reading the Economy without Stock Codes
> Design: [engines.macro](https://eddmpython.github.io/dartlab/skills)
Analyzing the economic environment without companies. Just `import dartlab`.
```python
dartlab.macro("cycle") # 4-phase cycle identification
dartlab.macro("interest rate") # interest rate + Nelson-Siegel yield curve
dartlab.macro("forecast") # LEI + recession probability + Hamilton RS + GDP Nowcast
dartlab.macro("comprehensive") # macro comprehensive + investment strategy + portfolio mapping
```
Market cycle, interest rate, liquidity, sentiment, asset signals, and global macroeconomic analysis methodologies (Hamilton EM, Kalman DFM, Nelson-Siegel, Cleveland Fed probit, Sahm Rule, BIS Credit-to-GDP) **implemented directly with numpy**.
Backtest evidence (2000-2024, FRED): Cleveland Fed probit **accurately detected all 3 US recessions 2-16 months in advance**, with 90% recall.
### Story — Turning Analysis into Reports
> Design: [engines.story](https://eddmpython.github.io/dartlab/skills)
Assembling analysis into structured reports. 4 output formats: rich (terminal), html, markdown, json.
```python
c.story() # full report
dartlab.ask() # report + AI comprehensive opinion
```
> Samsung Electronics report preview: *"Revenue growth +23.8%, operating profit margin 8.6%→21.4% rebound. FCF turned positive, ROIC > WACC — reinvestment creates value."*
### Storyteller — It's Not Just Numbers
> Design: [engines.story](https://eddmpython.github.io/dartlab/skills) · Series: [Company Reports](https://eddmpython.github.io/dartlab/blog/series/company-reports)
Company analysis is not just listing ratios. DartLab combines the results of 5 engines (analysis, credit, scan, quant, macro) into **6-act storytelling structure** and automatically generates company stories that can be published on blogs.
```python
from dartlab.story.publisher import publishReport
publishReport("068270") # Celltrion — 6-act company story automatically published
```
**Published Company Stories:**
| Company | Story |
|------|--------|
| [SK Hynix](https://eddmpython.github.io/dartlab/blog/000660-skhynix) | Korean semiconductor 30-year mystery, 58% operating profit margin |
| [Samyang Foods](https://eddmpython.github.io/dartlab/blog/003230-samyang-foods) | The rise of the 3rd largest food company, from 2.3 trillion KRW in sales |
| [Doosan Enerbility](https://eddmpython.github.io/dartlab/blog/034020-doosan-enerbility) | 9-year diet: from 305% to 129% debt ratio |
| [Alteogen](https://eddmpython.github.io/dartlab/blog/196170-alteogen) | 9-year loss-making biotech turns profitable with 1,069 billion KRW in operating profit |
| [HMM](https://eddmpython.github.io/dartlab/blog/011200-hmm) | A company where cycles determine stock prices, not the market |
| [Celltrion](https://eddmpython.github.io/dartlab/blog/068270-celltrion) | From 41 years old, 5,000,000 KRW to 25 years later, 13.78 trillion KRW in intangible assets |
| [Hanwha Aerospace](https://eddmpython.github.io/dartlab/blog/012450-hanwha-aerospace) | From 840 billion KRW in discarded weapons to 37 trillion KRW in backlog |
| [HD Hyundai Electric](https://eddmpython.github.io/dartlab/blog/267260-hd-hyundai-electric) | From 1,006 billion KRW in losses to 1 trillion KRW in 7 years, with one transformer |
| [Korea Zinc](https://eddmpython.github.io/dartlab/blog/010130-korea-zinc) | 50-year first net loss of 2,457 billion KRW, yet record-high operating profit |
| [APR](https://eddmpython.github.io/dartlab/blog/278470-apr) | A cosmetics company selling 4,070 billion KRW in home appliances, and that's just the beginning |
<div align="center">
<a href="https://www.youtube.com/watch?v=d7RUQIlimVM"><img src="https://img.youtube.com/vi/d7RUQIlimVM/maxresdefault.jpg" alt="Celltrion Story" width="100%"></a>
[Watch Celltrion Story](https://www.youtube.com/watch?v=d7RUQIlimVM) · [DartLab 30-second Demo](https://www.youtube.com/shorts/97lYLWMWzvA) · [YouTube Channel](https://www.youtube.com/@eddmpython)
</div>
### Search — Searching for Disclosures by Meaning *(beta — index freshness limitations)*
> Design: [engines.search](https://eddmpython.github.io/dartlab/skills)
> ⚠ Currently, the index is only built up to a certain point in time (daily incremental automation not yet complete). For single stock disclosure queries, use `Company.disclosure` / `Company.liveFilings` instead. Stable promotion pending infrastructure (CI cron + HF push) setup.
No model, no GPU, no cold start. 4 million documents with 95% precision — more accurate than embeddings, at 1/100th the cost. Benchmark details are referenced in [methodology](https://eddmpython.github.io/dartlab/skills/operation.methodology).
```python
dartlab.search("capital increase decision") # find capital increase disclosures
dartlab.search("CEO change", corp="005930") # filter by stock
dartlab.search("company borrowed money") # natural language also works
```
### AI — Skills-based Analysis Workbench
> Design: [operation.opsAsSkills](https://eddmpython.github.io/dartlab/skills) · Loop overview: [Top-level integrated architecture](#integrated-architecture--expert-financial-ai-platform)
```python
dartlab.ask("Analyze Samsung Electronics' financial health")
dartlab.ask("Analyze Samsung Electronics", provider="gemini") # use free provider
```
Providers: `gemini`(free), `groq`(free), `cerebras`(free), `oauth-codex`(ChatGPT subscription), `openai`, `ollama`(local), etc. Automatic replacement when rate limit is reached.
### Channel — Accessing DartLab from Outside
> Design: [runtime.channel](https://eddmpython.github.io/dartlab/skills)
One-line access to DartLab UI from PC to phone. Automatic Microsoft DevTunnels setup.
```bash
dartlab channel
```
Flow:
1. Automatic installation of devtunnel CLI via winget (first-time only)
2. One-time GitHub OAuth authentication (browser auto-open)
3. Permanent URL + QR code issuance (`https://<id>-8400.<region>.devtunnels.ms`)
4. Input URL/QR code in Chrome on phone → DartLab UI works as expected
No domain, no token tricks. Same infrastructure as VS Code Remote Tunnels, verified mobile compatibility. Messaging bot options (`--telegram/slack/discord`) also supported.
## EDGAR (US)
Same interface, different data source. Automatically collected from SEC API, no pre-download required.
```python
# Korea (DART) # US (EDGAR)
c = dartlab.Company("005930") c = dartlab.Company("AAPL")
c.panel() c.panel()
c.panel("business") c.panel("business")
c.panel("BS") c.panel("BS")
c.panel("ratios") c.panel("ratios")
c.panel("revenue") c.panel("revenue")
```
## MCP — AI Assistant Integration
> Loop and tool surface overview: [Top-level integrated architecture](#integrated-architecture--expert-financial-ai-platform)
[MCP](https://modelcontextprotocol.io/) server embedded. **Canonical 6 tools + ask** meta for external LLM to directly call DartLab library within RunPython (reduced token cost, increased tool selection accuracy).
### Claude Desktop / Claude Code / Cursor (stdio, recommended)
`uvx dartlab mcp` may not complete within Claude Desktop attach timeout, so **pre-installation + direct entry point invocation** is recommended. `command: "python"` may fail with ENOENT on Microsoft Store Python environments (issue [#28](https://github.com/eddmpython/dartlab/issues/28)), so direct invocation with `command: "dartlab"` is more robust.
```bash
# 1. Pre-installation (once) — create .local/bin/dartlab(.exe) entry point
uv tool install dartlab # or: pipx install dartlab
```
```jsonc
// 2-A. Claude Desktop — %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"dartlab": {
"command": "dartlab",
"args": ["mcp"],
"env": { "PYTHONUNBUFFERED": "1", "PYTHONUTF8": "1" }
}
}
}
```
```bash
# 2-B. Claude Code one-line setup
claude mcp add dartlab -- dartlab mcp
# 2-C. Codex CLI
codex mcp add dartlab -- dartlab mcp
```
If `dartlab` command is not in PATH, use absolute path:
```jsonc
{
"mcpServers": {
"dartlab": {
"command": "C:\\Users\\<user>\\.local\\bin\\dartlab.exe", // Windows
// "command": "/Users/<user>/.local/bin/dartlab", // macOS / Linux
"args": ["mcp"],
"env": { "PYTHONUNBUFFERED": "1", "PYTHONUTF8": "1" }
}
}
}
```
> Same output can be obtained with `dartlab mcp --config claude-desktop` / `dartlab mcp --config claude-code`. Automatic `.mcp.json` generation: `dartlab mcp --install`.
### Remote MCP (Claude Code · Cursor with SSE support only)
```jsonc
{
"mcpServers": {
"dartlab": {
"url": "https://eddmpython-dartlab.hf.space/mcp/sse"
}
}
}
```
HuggingFace Spaces hosting. No DART API key required. **Claude Desktop app only supports stdio, so reject this URL approach** — use stdio path above.
### Tool Surface
Actual `tools/list` surface consists of 11 tools below. Skill full-text query is handled with separate advertised tool not required `ReadSkill` result and `dartlab://skills/{id}` resource path.
| Tool | Role |
|------|------|
| **ask** | DartLab chat-native loop — LLM autonomous tool invocation + Ref calculation |
| **ReadSkill** | Official Skill OS search + frontmatter + full-text preview |
| **ReadCapability** | DartLab public API/docstring search |
| **RunPython** | DartLab + Polars code execution → executionRef/valueRef/tableRef |
| **WebSearch** | External latest information → webRef (untrusted marker automatically applied) |
| **SaveArtifact** | Large tables/charts separate storage → artifactRef |
| **CompileVisual** | Chart spec codegen → visualRef |
| **OutcomeLog** | Analysis judgment/results in structured logs |
| **LookAheadGuard** | Pre-check omitted next questions/calculation points |
| **GroundingCheck** | Number/date/source grounding calculation |
| **RequestUserInput** | MCP elicit support client user input request |
> Old 33 generated tools (`companyAnalysis`/`companyStory`/`marketScan`, etc.) are deprecated since 0.10 — all directly invoke `dartlab.Company / dartlab.scan / dartlab.macro` within `RunPython`. Migration details are in [CHANGELOG](https://github.com/eddmpython/dartlab/releases).
## Tool List
DartLab has two skill layers.
| Layer | Location | Role |
|---|---|---|
| **builtin Skill OS** | `src/dartlab/skills/specs/**` · `/skills` | Official operations, engine, and analysis procedures. Distributed with packages and searched by AI first. |
| **community Skill Market** | GitHub Discussions · `/skills/market` · static `marketIndex.json` | Community skills structured by Forge from user-shared analysis questions. Not included in package builtin. |
The operation flow is simple. Users write analysis questions on GitHub Discussions. DartLab Forge reads the original text and comments and structures `intent`, `inputs`, `dataSources`, `procedure`, `executionPlan`, `outputs`, `outputSchema`, `criteria`, `forbidden`, and `completionCriteria`. Drafts and supplementary items are only left in `marketIndex.json` and do not create a final skill snapshot. When the Maintainer reviews and confirms that the completion conditions are met, GitHub Action creates an accepted snapshot of `items/{id}.json`. The landing [Skill Market](https://eddmpython.github.io/dartlab/skills/market) and AI tool `ReadSkillMarket` search this static artifact.
Here, skills are contracts for repeatable analysis activities, not cards. Final shared skills must include `executionPlan` that specifies which DartLab engine or recipe to call in what order. `mappedBuiltinSkills` is only a reference connection, and without `executionPlan`, even with `marketCurated` comments, a final snapshot will not be created.
`marketCurated` refers to completed shared skills within Skill Market, not necessarily included in builtin. Completed shared skills remain in Discussion and accepted item snapshots, and AI displays the `sourceUrl` and `trustTier` before using them as auxiliary procedures. `builtinCandidate` is an exceptional long-term review status. The default operation path is to leave completed shared skills in Skill Market.
The final skill is not the last comment or body of Discussion but the approved `items/{id}.json` snapshot. If there is no `items/{id}.json`, it is not a final skill yet. When a new comment is added after completion, the existing final skill does not change immediately but is marked as `revisionStatus: pendingReview`. After the Maintainer reviews and promotes the revision draft again, the item snapshot, `marketIndex.json`, and landing search results are updated.
Discussion operation follows the order of `idea → Caller Audit → executionPlan draft → example input/expected output → operator confirmation → accepted snapshot`. When comments are added, the existing snapshot remains, and new comments are only marked as pending revisions. After discussion and operator confirmation, `items/{id}.json` is updated to vN+1.
## dartlab-lite — Browser · Excel (Pyodide)
> Details: [Blog — Using dartlab without installation on Excel, Browser, and Notebook (Pyodide)](https://eddmpython.github.io/dartlab/blog/pyodide-dartlab-lite)
Thanks to [Pyodide](https://pyodide.org/) porting CPython to WebAssembly, **dartlab runs in environments without Python installed**. With the same API and data.
**Supported Environments**: [xlwings Lite](https://lite.xlwings.org/) (Excel) · [Anaconda Code](https://www.anaconda.com/products/code-for-excel) (Excel) · [JupyterLite](https://jupyterlite.readthedocs.io/) · Google Colab WASM runtime · marimo (pyodide) · Pure HTML embed.
**[👉 Try it in Web Excel — OneDrive shared workbook](https://1drv.ms/x/c/4e17617bfea66347/IQB9zW91TaD4TJvHM8LRQTh4ARj0gHMapx4LVhCCSbBz92Q?e=HQ4E7d)** — xlwings Lite + dartlab setup completed. Just click the button to display financial statements on the sheet.
### Two Usage Modes — script vs func
xlwings Lite provides two decorators. **`@script` is button-based (imperative)**, and **`@func` is formula-based (declarative)**. dartlab supports both, and **functional style is how dartlab is used in Excel**.
**1. `@script` — Sidebar button → Fill sheet**
```python
import dartlab
import xlwings as xw
from xlwings import arg, func, script
@script(name="isTest")
def finance(book: xw.Book):
c = dartlab.Company('000020')
df = c.panel('IS')
data = [list(df.columns)] + [list(r) for r in df.iter_rows()]
sheet = book.sheets.active
sheet["A3"].value = data
```
<img src=".github/assets/xlwings-lite-script.webp" alt="xlwings Lite — @script mode, button click fills the sheet" width="720">
**2. `@func` — Excel cell as a formula `=GETFINANCE("005930")`**
```python
@func
def getFinance(code: str):
c = dartlab.Company(code)
df = c.panel('IS')
data = [list(df.columns)] + [list(r) for r in df.iter_rows()]
return data
```
<img src=".github/assets/xlwings-lite-func.webp" alt="xlwings Lite — @func mode, cell input =GETFINANCE(\"005930\") automatically fills" width="720">
VLOOKUP-like **`=GETFINANCE` acts as a native Excel function**. Changing the stock code updates all cells with recalculation.
### Installation (xlwings Lite · one line)
```python
import micropip
await micropip.install(["diff-match-patch", "openpyxl"])
await micropip.install(
"https://huggingface.co/eddmpython/dartlab-data/resolve/main/pyodide/dartlab-latest-py3-none-any.whl",
deps=False,
)
import dartlab
c = dartlab.Company("005930")
c.panel("IS")
```
Or add `dartlab` to `requirements.txt` in xlwings Lite sidebar — that's it. **No local Python, uv, or venv required.**
### Limitations (Browser Runtime Constraints)
| Feature | Pyodide | Notes |
|---|:---:|---|
| `Company()` · `c.panel()` · `analysis` · `story` · `credit` | ✅ | HF parquet auto-download |
| `dartlab.ask()` | ✅ | API key setup required (gemini·openai CORS OK) |
| `dartlab.scan()` | ❌ | Prebuilt parquet 271MB (unrealistic for browser) |
| `dartlab.gather()` | ❌ | Naver·Yahoo·Google News CORS blocked |
No threads · MEMFS volatile · CORS-restricted APIs — these are fundamental limitations. Details and build pipelines are in [pyodide/README.md](pyodide/README.md), and installation screenshots are in [blog post](https://eddmpython.github.io/dartlab/blog/pyodide-dartlab-lite).
## OpenAPI — Original Public API
```python
from dartlab import OpenDart, OpenEdgar
# Korea (opendart.fss.or.kr free API key required)
d = OpenDart()
d.filings("삼성전자", "2024")
d.finstate("삼성전자", 2024)
# USA (no API key required)
e = OpenEdgar()
e.filings("AAPL", forms=["10-K", "10-Q"])
```
## Data
All data is pre-built on [HuggingFace](https://huggingface.co/datasets/eddmpython/dartlab-data) — auto-download. EDGAR is directly collected from the SEC API. Users can browse data categories and use them as input for new Skill Market ideas.
| Category | Included Data | Representative Use |
|---|---|---|
| DART docs | Original sections, notes, and text topics of business reports and quarterly reports | Disclosure changes, risks, and business descriptions |
| DART finance | K-IFRS XBRL financial statements, standard accounts, and period comparisons | `Company.show`, `analysis`, `credit` |
| DART report | OpenDART formatted items, executives, employees, dividends, and shareholding | Governance, dividends, personnel, and capital policy |
| DART scan | Prebuilt indicators for cross-sectional scans of all stocks | Peer comparison, ranking, and anomaly detection |
| EDGAR | SEC filings, US-GAAP XBRL, 10-K/10-Q/8-K | US company analysis, US-Korea comparison |
| Gather | Price, supply and demand, news, macroeconomic indicators (FRED·ECOS), and external auxiliary data | Market reaction, events, and macro recipes |
| Reference | Industry map, capability, rendering, and mapping standards | Skill OS, charts, and report assembly |
Pipeline: local cache (immediate) → HuggingFace (auto-download) → DART API (key required). Most cases are covered by the first two steps.
## Get Started
**Notebook (Colab):** [Company](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/01_company.ipynb) · [Gather](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/02_gather.ipynb) · [Scan](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/03_scan.ipynb) · [Quant](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/04_quant.ipynb) · [Analysis](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/05_analysis.ipynb) · [Macro](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/06_macro.ipynb) · [Credit](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/07_credit.ipynb) · [Story](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/08_story.ipynb) · [AI](https://colab.research.google.com/github/eddmpython/dartlab/blob/master/notebooks/colab/09_ai.ipynb)
**Notebook (marimo):** [Full List](notebooks/marimo/README.md) — single entry without `import` repetition, comments for each cell, and no markdown cells
## Documentation
[Documentation](https://eddmpython.github.io/dartlab/) · [Quick Start](https://eddmpython.github.io/dartlab/skills/start.quickStart) · [Skills](https://eddmpython.github.io/dartlab/skills)
**Blog (120+ posts):** [All](https://eddmpython.github.io/dartlab/blog/) · [Company Stories](https://eddmpython.github.io/dartlab/blog/series/company-reports) · [Credit Reports](https://eddmpython.github.io/dartlab/blog/credit-reports) · [Macro Reports](https://eddmpython.github.io/dartlab/blog/macro-reports)
## Stability
| Tier | Scope |
|------|------|
| **Stable** | DART Company (sections, show, trace, diff, BS/IS/CF, CIS, index, filings, profile), EDGAR Company core, valuation, forecast, simulation |
| **Beta** | EDGAR power user (SCE, notes, freq, coverage), credit, insights, distress, ratios, timeseries, network, governance, workforce, capital, debt, chart/table/text tools, ask/chat, OpenDart, OpenEdgar, Server API, MCP |
| **Experimental** | AI tool invocation, export, visualization (charts) |
See [operation.stability](https://eddmpython.github.io/dartlab/skills/operation.stability) for detailed criteria.
## Design Choices
Conscious decisions that differentiate DartLab from other financial libraries — outlining the differences users will encounter after installation.
| Decision | Meaning | Reason |
|---|---|---|
| **Single base install — No `[extras]` separation** | A single `pip install dartlab` includes analysis, server, MCP, viz, and AI provider. | To reduce friction for first-time users, a single entry point (SSOT) is prioritized. Wheel size and cold start costs are mitigated with PEP 562 lazy load and pyodide branching. |
| **Pre-built data, API keys start at 0** | `Company("005930")` triggers automatic download from HuggingFace → local cache. DART API keys only require *re-collection*. | Removing the "create key and set environment variable" step from the primary usage path. Key issuance appears only in raw re-collection flows like `dartlab collect`. |
| **Public disclosures are data, not instructions** | External content is automatically wrapped with `[EXTERNAL CONTENT START — untrusted ...]` markers during serialization. | Forcing serialization to prevent patterns like "ignore previous instructions" in DART/EDGAR/news bodies from altering AI behavior. Numbers, dates, and proper nouns within markers are cited after re-verifying primary sources. |
| **AI engine = chat-native + LLM autonomous tool calling** | No fixed node graph like `BRIEF/WORK/CRITIQUE/COMPOSE/GATE/HARVEST`. The main body is `ai/agent.py`, and capabilities are in `ai/tools/`. | Preventing regression with 15,420 line deletions in version 0.7.15. Graph-based constraints lead to verify enforcement and workbench re-centralization, locking LLM autonomy. |
| **L0~L4 one-way imports (no cross-imports among 4 siblings)** | `core ← gather/providers ← scan/frame/synth/reference ← analysis 5 types ← story ← ai/mcp`. | Enforced by `import-linter` and `dartlabGuard.py strict --scope l0-l15` in PR gates. External contributors can determine where to add code with a single diagram. |
| **Mandatory test serialization (Polars OOM guard)** | Prohibiting direct `pytest -v` calls; use `tests/test-lock.sh tests/ -m "<marker>"` instead. | A single `Company` instance ≈ 200~500 MB Rust heap, which cannot be reclaimed by `gc.collect()`. Unifying CI and local environments with the same lock wrapper command. |
| **Message prioritization: Korean for CLI, English for API** | Symbols like `Company`, `pastInsight`, and `analysis` are in English. CLI error and progress messages are in Korean. | Declare `Natural Language :: Korean / English` in the classifier. English users can access via [README_EN.md](README_EN.md) and English docstrings. |
| **Single SSOT — Skill OS** | External LLM and users query 304 specs catalog with a single `capabilities()` line. | Maintaining code, documentation, and contracts in the same files (`src/dartlab/skills/specs/**`). Preventing drift between README, docs, and code in a single SSOT. |
| **Debt time series disclosure** | Measuring baseline, docstring backlog, and pytest marker distribution trends with `uv run python -X utf8 src/dartlab/skills/measureProgress.py`. Appending a line to [`_progress/measureHistory.jsonl`](src/dartlab/skills/_progress/measureHistory.jsonl) on every master push. | Besides the "no new regression" guard, also quantitatively tracking *repayment*. External contributors can verify if debt is being reduced in a time-series file. |
### First Results within 30 Seconds
```bash
pip install dartlab
```
```python
import dartlab
c = dartlab.Company("005930") # Automatic HuggingFace download (initial ~ tens of MB, local cache)
c.panel("IS") # Income statement, basic quarterly
```
Three lines — no API keys, no environment variables. English users, see [README_EN.md](README_EN.md); other entry points (CLI · AI · MCP) are described in ["Two Starting Points"](#two-starting-points) above.
## Contributing
Contributions of any kind are welcome. Bug reports, feature suggestions, documentation improvements, example additions, and data mapping corrections all make DartLab better.
Feel free to open issues and PRs in both Korean and English. If you're unsure where to start, discuss it in an issue first.
## License
[Apache License 2.0](LICENSE) — use freely, but include the source attribution from the [NOTICE](NOTICE) file.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
Vibe-Trading
Vibe-Trading: Your Personal Trading Agent
valuecell
Valuecell is a Python project for efficient data management.
hexstrike-ai
HexStrike AI is an AI-powered MCP cybersecurity automation platform with 150+ tools.
tradingview-mcp
AI-assisted TradingView chart analysis — connect Claude Code to your...
tradingview-mcp
TradingView MCP Server offers real-time market analysis for crypto and stocks.
AP2
AP2 provides code samples and demos for the Agent Payments Protocol.