Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Dubai property investment intelligence from open Dubai Land Department data.
Valuation, yield, risk and a cited, agent-written investment memo — on a 3D Dubai.
Built for SP Jain MAIB AI 217 (AI in Finance). Solo project by Krishna Mathur.
Information, not advice. YIELDMAP explains, compares and simulates. It does not recommend
that you buy, sell or finance anything, and it cannot execute a transaction of any kind.README 전문 보기 ↗Dubai property investment intelligence from open Dubai Land Department data. Valuation, yield, risk and a cited, agent-written investment memo — on a 3D Dubai.
Built for SP Jain MAIB AI 217 (AI in Finance). Solo project by Krishna Mathur.
Information, not advice. YIELDMAP explains, compares and simulates. It does not recommend that you buy, sell or finance anything, and it cannot execute a transaction of any kind.
Dubai recorded roughly 147,500 unit sales in 2025 and about 1.38 million tenancy contracts. The registry behind all of it is public, unit-level and daily — yet buyers and small investors still decide from broker claims and portal listings. YIELDMAP turns that registry into numbers you can check.
Nothing in this project is a hand-typed figure. Every value crossing the API is a Kpi object
carrying its sample size, as-of date, confidence, method id and the exact SQL that produced it.
Click any KPI tile and the query is right there. Cells with too few transactions say
"insufficient data" instead of showing a misleading number.
| What | Where | Status |
|---|---|---|
| Web app | https://yieldmap-krishnamathur008-1499s-projects.vercel.app | twenty tabs, live. Open it on a phone — the layout is built for one |
| Analytics API | https://yieldmap-api.onrender.com | free tier: sleeps after 15 minutes idle, so the first request takes about 50 seconds |
| API health | https://yieldmap-api.onrender.com/health | says which database is loaded and whether it is real or generated |
| Ingest job | Actions → Ingest DLD open data | nightly; probe and discovery reports land in docs/results/ |
| Continuous integration | Actions → CI | five jobs: python, web, docs, security, e2e |
| Notebook | docs/term4_yieldmap.ipynb | GitHub renders it with its charts |
The figures are currently generated, not real, and the site says so on every page. The Dubai
Land Department's open-data portal refuses automated clients from every network this project can
reach; docs/datasets.md records exactly what was attempted and what each host returned. The
stand-in is stamped SYNTHETIC in the database, in a banner on every page, and in every results
file, and a check in CI blocks it from reaching any submitted artefact. Point the ingest job at a
real drop and every number on the site changes; nothing else has to.
Answers on /ask and memos on /crew run on an offline fixture backend and are marked degraded
in the interface. That is the zero-cost default: setting GEMINI_API_KEY on the Render service
switches the free model tier on with no code change.
Every figure below is read from docs/results/, produced by the models in finance/.
They currently describe the labelled stand-in, not the Dubai registry — see
docs/datasets.md for why, and for how to load the real files.
| Model | Measured | Target |
|---|---|---|
| Hedonic valuation | 18.9% MAPE on a time-split holdout, against a 36.4% baseline — +48% skill, at the 19.4% noise floor | 12% MAPE, on real data |
| Repeat-sales index | 5,079 pairs over 144 months, 0 periods dropped as disconnected | reproduces direction of travel |
| Yield | median gross 7.12%, net 3.43%, gap 3.59%; 115 of 463 cells suppressed as too thin | net below gross always |
| Mortgage and DCF | 20% deposit case exact; levered 8.61% vs unlevered 5.75% at 3% growth | IRR matches a hand-computed case |
| Forecast | beats seasonal naive on 77/86 areas (90%), 10.1% vs 15.2% error | 60% of areas |
| Risk and anomalies | 1,738 of 120,346 flagged (1.44%); 86 areas scored | score in [0,100], monotone |
| Retrieval | recall@5 1.00, recall@1 0.87, MRR 0.91, faithfulness 1.00 over 30 cases in three languages — on a 117-chunk corpus, where recall@5 is easy and the rank measures are the informative ones | gated at 0.80 / 0.70 / 0.90 |
| Red team | 11/11 controls held against the OWASP ASI threat list | every attack fails to land |
| Cost | $0.00/month; the free tier binds at ~100 daily users, on embeddings before generation | stays free at course scale |
| Journey | 78 Playwright tests green on a desktop viewport and a Pixel 7, run in CI | the full journey, on a phone |
| Degraded mode | every route loaded with the API refusing: the ten that fetch on load show an error and a working retry, the six form pages stay usable, nothing crashes | never a blank page |
| Python | 1,025 tests, 14 skipped | — |
| Front end | 25 tests, including one that fails if a string renders in English under another locale | every key translated |
| Coverage | 83.9% of 6,676 statements; the 10 modules that are the sole mechanism behind a rule in CLAUDE.md are held to 85% and sit at 89–100% | 75% overall, 85% on those |
| Access control | writes need a token the API signed; the role is never something a caller sends | no credential, no write |
| Frame rate |
Reads are public. Writing a memo — the only endpoint that writes, and the only one that spends a model budget — needs an account:
uv run python -m api.auth hash 'a-password' # -> $argon2id$...
export AUTH_SECRET="$(python3 -c 'import secrets;print(secrets.token_urlsafe(48))')"
export YIELDMAP_USERS='[email protected]:analyst:$argon2id$...'
Set YIELDMAP_ENV=production and the service refuses to start without those, rather than running
in a state where tokens silently stop working on restart. GET /health reports whether
authentication is configured and whether memo storage is durable, so a deployment can be checked
from outside without reading its environment.
Optional: DATABASE_URL for durable memos (without it they go to a file store that a container
loses on restart), and SENTRY_DSN for error tracking. Neither is required to run.
| Document | What it is |
|---|---|
docs/viva_qa.md | Fifteen likely questions, answered from what the code says, each naming the file that backs it |
docs/demo_script.md | A timed three-minute run-through, with what to click and what to say |
docs/pitch.md | The one-page version |
docs/loading_real_data.md | How to replace the stand-in with the published files — one command, ten minutes |
docs/limits.md | What it costs, where the free tier stops, and what breaks first |
docs/runbook.md | What to do when something is wrong, written for whoever gets the alert |
docs/security.md | The OWASP ASI mapping and the red-team results, generated from the register and the last measured run |
docs/term4_yieldmap.ipynb | Every model, with its plots and the tables the report cites |
| docs/AI217_YIELDMAP_report.docx | The Term 4 report, generated from docs/results/ by scripts/build_report.py |
| docs/AI217_YIELDMAP_deck.pptx | Twelve slides with speaker notes, generated by scripts/build_deck.py |
| docs/REDEPLOY_RUNBOOK.md | Restore and redeploy the whole thing from a downloaded zip |
The report and the deck are generated rather than written, and both currently carry a draft
stamp: scripts/guard_synthetic.py blocks generated figures from reaching a submitted artefact,
and it blocks. Passing --draft is what allows generation, and it puts the label in three places a
reader cannot get past — a banner on the cover, a provenance column beside every model figure, and
a limitations section naming which numbers describe a stand-in. Load real data and regenerate: the
guard passes, and the provenance column disappears because it has nothing left to say.
uv sync # Python deps (3.12)
uv run pytest # Python tests
uv run ruff check . # lint
npm install && npm test # JS tests
External data is downloaded by GitHub Actions (.github/workflows/ingest.yml), not locally — see
CLAUDE.md for why. Data licences and retrieval dates are in docs/datasets.md; model choices and
their measured trade-offs are in docs/models.md; all measured numbers are in docs/results/.
Zero paid inference. The provider chain is local Ollama → Gemini free tier → Groq free tier, with request-count budgets and graceful degradation at every step. The Anthropic backend exists in the code and is switched off.
| 60fps desktop, 61fps on a Pixel 7 — measured in software rasterisation, so a floor |
| 60 / 30 |
| Accessibility | 0 violations across 7 pages, WCAG 2.1 AA, both viewports — was 7 serious | none serious |
| Page weight | 207–210 KB of JavaScript brotli-compressed on most routes, 292 KB on a chart page; three.js on none of them | gated at 340 KB, and at zero three.js |