Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
LLM이 수치를 만들지 않는 로컬 우선 주식 리서치, 질문은 파이썬 메트릭 계획으로 변환·모델은 결과만 서술·모든 주장 재검증
Local-first equity research where the LLM never produces a number. Questions compile to a typed plan of Python metrics; the model only narrates results it did not compute, and every claim is re-verifi
금융Python · TypeScriptGitHub @karanmjpinto온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Local-first equity research where the LLM never produces a number. Questions compile to a typed plan of Python metrics; the model only narrates results it did not compute, and every claim is re-verified against a frozen snapshot.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Local-first equity research where the language model never produces a number.
-orange.svg)
To make AI-generated investment research checkable.
The goal is not a smarter model. It is a harness around the model good enough that its
output can be checked, repeated and argued with — so when an answer is wrong you can see
which part was wrong, and fix the method rather than the number.
Four commitments follow from that. They are enforced in code, not asserted in a
document, and they are what to hold this project to:README 전문 보기 ↗Local-first equity research where the language model never produces a number.
Live landing page · Architecture · Contributing
To make AI-generated investment research checkable.
The goal is not a smarter model. It is a harness around the model good enough that its output can be checked, repeated and argued with — so when an answer is wrong you can see which part was wrong, and fix the method rather than the number.
Four commitments follow from that. They are enforced in code, not asserted in a document, and they are what to hold this project to:
unverifiable — the one thing worse than an unchecked number is an unchecked number
wearing a tick.The intended user is one person doing their own research who wants to disagree with a machine on the evidence — not a system that decides for them.
Most AI research tools hand a language model a pile of financial data and ask for a verdict. That makes every figure in the answer a token prediction — the P/E ratio, the drawdown, the conviction score. The output reads perfectly plausibly whether or not the arithmetic happened, and you cannot tell which from the prose.
This project compiles the question into a typed program, computes every figure in plain Python, and lets the model write only over results it did not produce.
flowchart LR
Q([Question]) --> P[Planner]
P --> D[Typed plan]
D --> E[Executor]
E --> N[Narrator]
N --> H[Harness]
H --> R([Recorded run])
P -.- Pn["picks metrics from a fixed<br/>catalog — never sees a value"]
E -.- En["plain Python computes<br/>every number"]
N -.- Nn["writes prose over computed<br/>results, no arithmetic"]
H -.- Hn["re-checks every numeric claim<br/>against the snapshot"]
The model appears twice, in two narrow roles. A planner chooses what to measure
from a fixed catalog and is shown no values. A narrator is shown only computed
values, under an explicit no-arithmetic rule. When the plan computes a conviction
score it overwrites whatever the narrator wrote, and says so in
harness_overrides.
Then a deterministic pass re-reads the finished thesis, extracts each numeric claim,
and compares it against the snapshot. Claims it cannot map are reported
unverifiable — never as passing.
| Numbers you can check | Every figure traces to a registered Python metric, not to the model. |
| Runs you can replay | Each analysis stores its snapshot, prompts, model parameters and output. Re-run it later against the same frozen data. |
| Drift you can see | runs/compare sets nondeterminism_detected when identical inputs reach different conclusions — the signal that an eval built on them would be measuring noise. |
| Sources you can trace | Providers disagree on split adjustment, fiscal alignment and currency. Every fetch records who answered, whether it was cached, and how the payload verified. |
| No API keys | Ollama serves the model locally, market data comes from keyless providers by default, and the book is a SQLite file you own. |
Prerequisites: uv, Node 20+, and Ollama.
git clone https://github.com/karanmjpinto/mjresearch.git
cd mjresearch/ai-hedge-fund
ollama pull qwen3:30b
cp .env.example .env
./start.sh
start.sh brings up the API on :8000 and the UI on :5173, waits for the API
before opening the browser, and stops both on Ctrl-C. It warns rather than fails
if Ollama is down — everything except AI research still works.
Then open http://localhost:5173.
cd ai-hedge-fund
cp .env.example .env # set OLLAMA_MODEL to a name from `ollama list`
uv sync --extra dev
uv run uvicorn hedge_fund.api.main:app --reload # :8000
cd frontend && npm install && npm run dev # :5173
Run a second instance beside one that is already bound — the UI proxy follows the API port automatically:
./start.sh --api-port 8010 --ui-port 5174
Both instances share ./data/fund.db, so two backends at once write to the same book.
One-off data check from the terminal:
uv run check-data AAPL
qwen3:30b is a mixture-of-experts model — ~30B total parameters but only ~3B active
per token, so it reasons far better than a small dense model at comparable speed.
Smaller models tend to write theses that cite none of the computed values. The harness
catches that and flags narrative_grounded: false, but a capable model avoids it in
the first place.
Prefer a hosted API? uv sync --extra openai, then set LLM_PROVIDER=openai,
OPENAI_API_KEY and LLM_MODEL.
POST /api/research/plan compiles a question into a DAG
of deterministic metrics, executes it, then narrates over the results. Node values
are content-addressed, so re-running an edited plan recomputes only what changed.suspect_convergence rather than reading as confirmation — the failure mode being
managed is agreement, not disagreement.uv sync --extra sentiment is installed; degrades to enabled: false otherwise../data/fund.db — trades, cash, splits, dividends, manual edits.SEC_USER_AGENT.When an analysis comes out wrong, the durable lesson is usually the method, not the
number. POST /api/methodology stores a portable correction that later runs apply.
Notes containing prices, amounts or scores are rejected — a stored number would be
replayed onto runs where it is no longer true. GET /api/methodology/applicable shows
exactly what would enter a prompt right now, and each run records which notes shaped it.
The whole stack is exposed as an MCP server with thirteen tools — research_ticker,
plan_research, list_metrics, get_market_data, get_sec_filings, get_peers,
run_backtest_tool, optimize_portfolio, describe_research_graph, list_runs,
get_run, compare_runs, teach_methodology.
{
"mcpServers": {
"mjresearch": {
"command": "uv",
"args": ["run", "hedge-fund-mcp"],
"cwd": "/absolute/path/to/mjresearch/ai-hedge-fund"
}
}
}
Restart the client, then ask it to "research NVDA with the committee" or "run a golden cross backtest on AAPL for 3 years" and it will invoke the tools directly.
This section carries the same weight as the one above it. A research tool that oversells its certainty is worse than one that states plainly what it cannot do.
LLM_TEMPERATURE=0.0,
LLM_SEED=7) and every input is recorded, but providers do not guarantee identical
output. Moving arithmetic out of the model narrows this — it does not eliminate it.The published site at karanmjpinto.github.io/mjresearch is the landing page only. The backend is deliberately not hosted: the API has no authentication and full write access to the portfolio, so putting it on the public internet would expose the book and its trade endpoints to anyone with the URL. The model is local too, so a hosted instance would have no AI research regardless.
App routes on the published site show the commands to run it locally. Everything real — portfolio, data, model — stays on your machine.
Railway deployment instructions live in ai-hedge-fund/README.md.
.
├── ai-hedge-fund/ # the application
│ ├── src/hedge_fund/ # FastAPI backend, agents, quant, data, MCP server
│ ├── frontend/ # React + Vite + Tailwind UI
│ ├── tests/ # pytest suite
│ ├── docs/architecture.md # full design document
│ └── README.md # operational detail: env vars, API reference, Railway
├── .github/workflows/ # CI, GitHub Pages deploy
└── LICENSE
Full API reference, the complete environment-variable table, and deployment detail are
in ai-hedge-fund/README.md. The design rationale is in
ai-hedge-fund/docs/architecture.md.
cd ai-hedge-fund
uv run pytest -q # 304 tests
CI runs Ruff, pytest, a frontend build, and a design review on every push and PR.
Issues and pull requests are welcome — see CONTRIBUTING.md for the development setup and what makes a change easy to merge. Security reports go through SECURITY.md, not the public tracker.
The investor-persona and committee/portfolio-manager ideas are inspired by the
educational multi-agent design in virattt/ai-hedge-fund
(MIT). This is an independent codebase, not a fork; the system prompts are original text.
See ai-hedge-fund/third_party/ATTRIBUTION.md
for the full attribution.
MIT © karanmjpinto