Commit graph

47 commits

Author SHA1 Message Date
Ciphercat
6671e22976 feat(ownership): complete ownership intelligence module
Sprints 0-8: Types, schema, KSEI parser, entity resolution, DB CRUD,
Bing API client, import pipeline, query commands, graph traversal,
changes diff, entity resolution CLI, FTS5 search.

- KSEI PDF parser (mutool stext + quick-xml, 99.2% accuracy)
- 7 query commands: ticker, entity, search, cross-holders, concentration, flow, releases
- Ownership graph with recursive CTE (ASCII tree + Graphviz DOT)
- Release diff/changes between KSEI snapshots
- Entity resolution CLI: unresolved, map, merge
- FTS5 trigram search on entity names
- Feature-gated under 'ownership' (default-on)
- 82 tests passing
2026-03-07 21:10:58 +00:00
Rasyidan A F
d49a8ed60e
Merge pull request #4 from 0xrsydn/feat/hybrid-provider
feat: hybrid provider with Yahoo history fallback
2026-03-07 19:22:10 +07:00
Ciphercat
ed85428c90 feat: hybrid provider with Yahoo history fallback 2026-03-07 08:22:39 +00:00
Rasyidan A F
17e90d4601
Merge pull request #3 from 0xrsydn/feat/msn-full
feat(msn): full MSN Finance endpoint coverage
2026-03-07 04:30:24 +07:00
Ciphercat
6d6d51a04f refactor(msn): remove HistoryProvider — Finance/Charts 404s on all IDX stocks
MSN Finance/Charts does not serve OHLCV data for XIDX stocks (returns 404).
Following the FP principle of not exposing capabilities a provider cannot fulfil:

- Remove impl HistoryProvider for MsnProvider entirely
- Remove fetch_charts from MsnClient
- Remove parse_chart_history, resample_history, trim_history_to_period from map.rs
- Remove MsnChart, ChartSeries, RawChart from raw_types.rs
- Remove parse_history_from_str, parse_close_only_history from parse.rs
- Decouple HistoryProvider from MarketDataProvider trait bound
- Add history_provider() factory: returns None for MSN, Some(Yahoo) for Yahoo
- CLI gates History/Technical on history_provider(), fails fast for MSN
- MSN mock returns Err(Unsupported); tests verify the behaviour explicitly
2026-03-06 20:55:35 +00:00
Ciphercat
2207c928b2 fix(msn): correct API response parsing for profile, financials, insights, screener, history
- financials: fix incomeStatement serde rename (was incomeStatements, API sends singular)
- financials: flatten nested sub-objects (income/revenue/expense/cash) in parse_statement_section
- insights: rewrite RawInsight to match actual API shape ({insights:[{insightName,insightStatement,category}]})
- insights: group insight items into highlights (non-risk) and risks by category
- screener: build Quote directly in parse_screener_results, skip stocks with no price
- profile: use short_name fallback when long_name is null, hide empty fields
- history: map Finance/Charts 404 to Unsupported with clear IDX-specific message
- tests: update MSN history/technical tests to use mock provider
2026-03-06 20:08:03 +00:00
Ciphercat
a0da0a3adb feat(msn): implement full MSN Finance endpoint coverage
- Finance/Equities: company profile + executives (idx stock profile)
- Finance/Equities/financialstatements: balance sheet, cash flow, income (idx stock financials)
- Finance/Events/Earnings: EPS history + forecast (idx stock earnings)
- Finance/Charts: OHLCV chart history, unblocks MSN history command
- Finance/SentimentBrowser: crowd sentiment (idx stock sentiment)
- api.msn.com/insights: AI insights (idx stock insights)
- MSN/Feed/me: stock news feed (idx stock news)
- Finance/Screener: IDX universe screener with 8 presets (idx screen)
- Wire ProfileProvider, EarningsProvider, FinancialsProvider, SentimentProvider,
  InsightsProvider, NewsProvider traits on MsnProvider
- Remove HISTORY_UNSUPPORTED_REASON — MSN history now works via charts API
2026-03-06 19:32:56 +00:00
Ciphercat
3998e38ffc refactor: schema-driven architecture, capability traits, hardened error paths
- Split parse.rs into raw_types.rs (serde structs) + map.rs (pure transforms) for MSN and Yahoo
- Replace Yahoo fundamentals dynamic HashMap with typed structs (SummaryDetail, DefaultKeyStatistics, etc.)
- Introduce capability-based provider traits: QuoteProvider, FundamentalsProvider, HistoryProvider
- Add future MSN capability traits: ProfileProvider, EarningsProvider, FinancialsProvider,
  SentimentProvider, InsightsProvider, NewsProvider (all dead_code until wired to CLI)
- Add shared domain types in src/api/types.rs (CompanyProfile, EarningsReport, FinancialStatements,
  SentimentData, InsightData, NewsItem)
- Harden error propagation: Yahoo cookie auth, MSN partial fundamentals, history symbol context,
  cache clear failures
- Strict config parsing: invalid IDX_OUTPUT returns ConfigError instead of silent fallback
- Cache schema version enforcement: version mismatch treated as cache miss
- Extract fetch_with_cache() helper in cli/stocks.rs
- Add MSN retry/backoff parity with Yahoo client
- Standardize Option<T> policy through parse/map layers
- All 56 tests passing, clippy clean
2026-03-06 19:17:50 +00:00
Ciphercat
a45ee3620f docs: add FEATURE_SPEC.md for MSN full coverage (feat/msn-full) 2026-03-06 18:50:04 +00:00
0xrsydn
4f338a92d6 refactor: yahoo code restructure 2026-03-06 16:54:16 +00:00
Rasyidan A F
343dac92ee
Merge pull request #1 from 0xrsydn/feature/msn-provider-mvp
feat(api): add MSN Finance as alternative data provider
2026-03-06 18:41:29 +07:00
0xrsydn
0a7d123f90 fix(api): disable unsupported MSN history 2026-03-06 11:23:04 +00:00
0xrsydn
9b2e32e0c6 refactor(api): split MSN provider module 2026-03-06 10:51:20 +00:00
0xrsydn
aeab18e94f fix(ci): format MSN mock provider parsing 2026-03-06 10:39:21 +00:00
0xrsydn
2cdefeb7a6 feat(api): add MSN Finance as alternative data provider
Add MsnProvider implementing MarketDataProvider trait with quote,
fundamentals, and history support. Includes provider-aware config
(file/env/CLI), cache namespace isolation per provider, symbol ID
mapping via embedded TSV, OHLCV resampling, and comprehensive unit
+ integration tests with MSN fixture data.

Key changes:
- MsnProvider with quote, key-ratios, and chart endpoints
- ProviderKind enum (yahoo/msn) with config hierarchy support
- Provider-namespaced cache buckets to prevent cross-provider poisoning
- Provider-aware MockProvider loading correct fixtures per provider
- Integration tests for config round-trip and cache isolation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:19:10 +00:00
Ciphercat
3383fdd983 docs: update TODO.md — crumb auth resolved, fix flake.nix package rename 2026-03-06 07:49:57 +00:00
Ciphercat
67251d94c9 fix(yahoo): fix curl-impersonate binary name and QuoteSummaryValue catch-all
- Use curl_chrome131 (and fallback chain) instead of 'curl-impersonate --impersonate'
  The curl-impersonate-chrome package ships per-version binaries, not a generic binary
- Add Unknown(serde_json::Value) catch-all variant to QuoteSummaryValue
  Yahoo returns {} for empty fields and null/strings that broke deserialization
- Keep cookie jar flow: fc.yahoo.com (404 but writes A3 cookie) + getcrumb + quoteSummary
- Pass cookie header from jar to quoteSummary request via ureq

Live result: stocks fundamental/growth/valuation/risk/compare now working
BBCA: ROE 21.14% excellent, Net Margin 53.28% excellent, Growth mixed
2026-03-06 07:48:39 +00:00
Ciphercat
f89f4c90ce fix(yahoo): use curl-impersonate for crumb auth (TLS fingerprinting)
Yahoo Finance blocks standard ureq/rustls via TLS fingerprinting (JA3/JA4).
Reverse-engineered from yfinance source: they use curl_cffi with Chrome impersonation.

Fix:
- Fetch cookie via curl-impersonate from fc.yahoo.com
- Fetch crumb via curl-impersonate from query1.finance.yahoo.com/v1/test/getcrumb
  (correct URL: getcrumb, not getCrumb or csrfToken)
- Parse Netscape cookie jar format, send cookies as header to quoteSummary
- 401 retry: clear crumb + cookie jar, re-auth on next attempt
- Crumb validation: reject HTML, empty, rate-limit responses
- Add curl-impersonate-chrome to flake.nix devShell
2026-03-06 07:31:11 +00:00
Ciphercat
0dd71eb6d0 docs: update TODO.md — mark fundamental suite done, add crumb auth issue 2026-03-06 05:55:14 +00:00
Ciphercat
0d5b4b4755 feat(fundamental): add fundamental analysis suite (growth, valuation, risk, compare)
- Add Fundamentals type and MarketDataProvider::fundamentals() trait method
- Add Yahoo quoteSummary endpoint parser (/v10/finance/quoteSummary)
- Add analysis/fundamental.rs with exact signal thresholds ported from idx-mcp:
  - GrowthReport (revenue/earnings growth with signals)
  - ValuationReport (PE, PB, ROE, margin, EV/EBITDA with signals)
  - RiskReport (D/E, current ratio, ROA with signals)
  - FundamentalReport (composite with overall health signal)
- Wire CLI subcommands: stocks growth/valuation/risk/fundamental/compare
- Add table + JSON rendering for all report types
- Add mock fixture (quotesummary_bbca.json)
- 41 tests passing (22 unit + 19 integration)
- Known: Yahoo quoteSummary returns 401 from datacenter IPs (needs crumb auth)
2026-03-06 05:54:37 +00:00
Ciphercat
3e5869af67 docs: add TODO.md with project checklist and roadmap 2026-03-05 22:47:11 +00:00
Ciphercat
9182f25a01 feat(analysis): add technical analysis module and stocks technical command
- Add analysis module: SMA, EMA, RSI(14), MACD(12,26,9), volume ratio
- Add signal interpretation: bullish/bearish/neutral with consensus voting
- Wire up 'stocks technical <SYMBOL>' CLI subcommand
- Table output with colored signals + JSON output support
- Cache/offline/stale-cache fallback (same pattern as quote/history)
- Fetch 1 year of daily data for SMA200 coverage (~250 trading days)
- Add TechnicalReport, MacdSnapshot, VolumeSnapshot structs
- Add 4 new unit tests + 3 integration tests (30 total passing)
2026-03-05 22:46:32 +00:00
Ciphercat
9e0560f3c1 chore(release): add crate metadata for crates.io readiness v0.1.0 2026-03-05 19:36:29 +00:00
Ciphercat
bc74fdf7e2 feat(output): add 52-week range bar column to quote table 2026-03-05 19:36:06 +00:00
Ciphercat
6c0cdfc46a ci: add GitHub Actions workflow for fmt clippy test 2026-03-05 19:35:31 +00:00
Ciphercat
c00411ea80 docs: add MIT license for 2026 contributors 2026-03-05 19:35:06 +00:00
Ciphercat
eabd4f4ad7 cli: polish clap help text across commands 2026-03-05 19:34:47 +00:00
Ciphercat
6757fea2bb docs: add comprehensive README for v0.1 2026-03-05 19:32:14 +00:00
Ciphercat
f3cefaaaf4 Fix Yahoo schema handling, integer IDR prices, and resilience 2026-03-05 19:26:35 +00:00
Ciphercat
dc1de5b344 style: cargo fmt 2026-03-05 18:33:20 +00:00
Ciphercat
5da59c36c7 ci: convert prek.toml to .pre-commit-config.yaml (prek 0.3 compat) 2026-03-05 18:32:48 +00:00
Ciphercat
639ee4b041 test(api): add yahoo fixtures, mock-provider errors, and CLI integration coverage 2026-03-05 18:28:40 +00:00
Ciphercat
c0a3d744b2 feat(cache): add file cache, cache commands, and offline fallback 2026-03-05 18:28:32 +00:00
Ciphercat
d2fa081266 feat(config): implement config init/get/set/path commands 2026-03-05 18:28:24 +00:00
Ciphercat
2b5a1b28de docs: add AGENTS.md + CLAUDE.md symlink for agent-first development
- Project summary, stack, structure map
- Dev commands, verification, rules
- CLAUDE.md symlinked to AGENTS.md (works with any agent harness)
2026-03-05 18:00:29 +00:00
Ciphercat
2b28fcc9f9 feat: implement MVP foundation — quote, history, provider abstraction
- Cargo init with clap, ureq, serde, comfy-table, owo-colors, thiserror
- Module structure: cli/, api/, output/, cache, config, error
- MarketDataProvider trait abstraction (swappable providers)
- Yahoo Finance provider via query2 endpoint (no crumb needed)
  - Retry with exponential backoff + jitter on 429
  - chartPreviousClose fallback for change calculation
- Symbol resolution: BBCA → BBCA.JK
- Output layer: table (comfy-table + owo-colors) and JSON
- Config loading foundation (TOML + env + defaults)
- Commands: stocks quote, stocks history, version, completions
- 9 tests (unit + integration) with mock provider
- Verified: cargo build, clippy -D warnings, cargo test all green
2026-03-05 17:59:50 +00:00
Ciphercat
2174b42cff feat: implement idx-cli MVP foundation, provider abstraction, and core quote/history commands 2026-03-05 17:54:52 +00:00
Ciphercat
a4b8a1b64e dev: remove sqlite from flake (ownership DB moved to idx-api) 2026-03-05 17:26:43 +00:00
Ciphercat
4f46a4d787 dev: add prek to flake.nix devshell 2026-03-05 17:23:43 +00:00
Ciphercat
92e9bed9b6 ci: add prek hooks for pre-commit and pre-push
Pre-commit: trailing whitespace, EOF fixer, merge conflict check,
cargo fmt --check, cargo clippy -D warnings
Pre-push: cargo nextest run
2026-03-05 17:23:43 +00:00
Ciphercat
8c7c70a57a chore: move internal docs to docs-internal/ and gitignore
- SPEC.md, OWNERSHIP_FEATURE_DESIGN.md, research artifacts → docs-internal/
- gitignore docs-internal/ and research/ to keep strategy private
2026-03-05 16:30:48 +00:00
Ciphercat
d457c630c4 dev: add flake.nix and .envrc for Rust dev environment
- rust-overlay for stable toolchain + rust-src + rust-analyzer
- pkg-config, openssl, sqlite for reqwest + ownership DB
- cargo-watch, cargo-nextest for dev workflow
- direnv integration via .envrc
2026-03-05 16:23:49 +00:00
Ciphercat
919f38adbc chore: add .direnv and result to .gitignore 2026-03-05 16:23:48 +00:00
Ciphercat
1fe33aebc5 spec: add Agent Skills section
Inspired by Google Workspace CLI's skills/ directory pattern.
SKILL.md files teach AI agents how to use idx-cli commands —
plain markdown, framework-agnostic, composable workflows.
2026-03-05 16:19:49 +00:00
Ciphercat
e3fa777e1a research: add KSEI ownership data analysis and feature design
- Parse 73-page KSEI/IDX >1% ownership PDF (27-Feb-2026 snapshot)
- 7,257 ownership records across 955 tickers, 5,195 unique investors
- OWNERSHIP_FEATURE_DESIGN.md: SQLite schema, entity graph model, CLI commands,
  data pipeline, entity resolution strategy
- Raw analysis artifacts (extracted text, analysis JSON)
2026-03-05 16:19:49 +00:00
Ciphercat
e176f9bfb9 chore: add .gitignore for node_modules, target, and large research files 2026-03-05 16:19:49 +00:00
Ciphercat
b3b921044b initial: add SPEC.md with system design, project blueprint, and reference CLIs 2026-03-05 15:27:33 +00:00