Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
코스타 블랑카·칼리다·델 솔 신축 매물, 할인·수익·시공사 품질로 점수 매겨 저가 매물 먼저 보여줍니다
Every new-build on the Costa Blanca, Cálida and del Sol, scored on discount-to-market, yield and developer quality. The underpriced ones, surfaced first.
금융TypeScript · PLpgSQLGitHub @HenrikKolstad온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Property intelligence for the Spanish coast. Scores every new-build on discount-to-market, rental yield and developer quality, refreshed by autonomous daily jobs. Live at avenaterminal.com.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Daily observation of the Spanish coastal new-build market — what was listed, what moved, and what quietly disappeared.
Live: avenaterminal.com · Open data: /open-data · mirror · CC BY 4.0 · DOI 10.5281/zenodo.19520064
Spanish coastal new-build listing data is ephemeral. A unit is listed, repriced two or three times, and then vanishes from the feed — sold, withdrawn, or quietly reshuffled by the developer. No public registry records any of that at listing level. Once a listing changes, its previous state is gone.
The Spanish land registry publishes transactions, but with a long lag, no listing identity, and no asking price — so it cannot answer the question that actually matters to a buyer: was this unit reduced before it sold, and by how much?
So this system writes that history down, once a day, and never stops. The value is not the code — it is the fact that the series exists and cannot be backfilled. A competitor starting today is 70 days behind permanently, and money will not close the gap.
Measured 2026-10-13. These are derived live from the database by
scripts/capability-stats.ts, which refuses to emit zeros rather than report a
failed read as an empty result.
| Observation days, unbroken | 70 (2026-08-05 → 2026-10-13) |
| Units observed | 2,287 |
| Price moves recorded | 657 |
| Delistings (absorption) | 276 |
| Relistings | 42 |
| Live book | 2,039 across 69 towns |
Depth is measured as distinct prices per unit, never as row count. An earlier version of this pipeline wrote ~394,000 rows that contained zero price changes — a capped write loop re-inserting the same frozen snapshot nightly. Row counts in this domain lie; the genuine series starts the day the pipeline was repointed at the live feed.
Listing XML feed (~98 MB)
└─ parse-feed.js fingerprints the payload, refuses a short read
└─ public/data.json the book, committed nightly
├─ pricing-history cron → price_snapshots (per ref, per day)
│ → sold_properties (delisting ledger)
└─ build-open-dataset.ts → public/open-data/* → public mirror
Two things in that chain are worth more than the rest:
The diff is gated. Delisting and price-move detection only runs against a
prior snapshot no older than four days, and only when the two books overlap by
at least 50%. A broken feed therefore cannot mass-flag 2,000 units as sold. The
gate reports trusted_prior: false and writes nothing rather than writing
something plausible.
The scheduler is not trusted. GitHub's cron landed its 05:10 slot between 06:15 and 06:43 for five consecutive nights, and the upstream feed intermittently refuses GitHub Actions egress entirely (a fresh runner 43 minutes later gets straight through). A conditional backstop workflow with 37 tests covers both. It has since carried the capture through a 21-day unattended stretch and an 8-day one with zero missed nights.
scripts/avm-backtest.ts, re-measured on every change, committed to
public/model-stats.json:
| metric | value |
|---|---|
| Median absolute error | 15.82% |
| MAPE | 21.81% |
| RMSE | 43.28% |
| Within ±10% | 34.2% |
| Within ±20% | 59.5% |
| n | 2,039 |
Both caveats are published alongside every figure, because without them the numbers are not true:
This section exists because the site previously claimed "±3% RMSE on backtest" with no backtest in existence. Building one produced a worse number and exposed a real model bug. A defensible 15.82% is worth more than an invented 3%.
Every serious outage here has had one shape: a missing or failed value silently becoming a zero, so a broken system looks like a working one with nothing to report.
Real instances, all fixed:
parse-feed downloaded 0 MB, threw, and exited 0 — a green check on a dead feed.catch stored an empty result, overwriting a
healthy ~33% measured rate with a fabricated 0.00% for six days.if (!error) count += chunk and took the prior snapshot
as the global max date, discarding it whenever that max was today — so any
re-run diffed against nothing and reported price_moves: 0 while real moves
went unlogged.createClient(process.env.URL!, ...) at module top level.
The ! is a lie when the variable is absent. Production had the vars, so every
preview deployment broke — and the signal that a branch was broken was itself
broken.success on every run for 57 consecutive days while
transmitting nothing, because the no-op branch returned a bare 200.So the house rules are: a failed read returns null, never 0; a published
count is derived, never a literal; an absent credential throws instead of
falling back; and a run that did nothing says skipped, not success.
Several tests assert the bug, not just the fix — test-hf-push-reporting.ts
includes the exact pre-fix payload and asserts it still derives to success, so
the test demonstrably catches the regression rather than only documenting the
repair.
All four must pass before anything reaches main:
npx tsc --noEmit # clean
npx tsx scripts/test-concierge.ts # all pass
npx tsx scripts/avm-backtest.ts # median error must not regress
npm run build:preview-sim # full build with every secret UNSET
The last one exists because production has environment variables that preview deployments do not, so a green production build proves nothing about a branch.
npm install
export FEED_URL="<listing feed URL>" # required; no fallback, throws if unset
node parse-feed.js # refresh public/data.json
npm run dev
FEED_URL is a credential — the feed has no other authentication — so it lives
in the environment and never in the source.
Next.js (App Router) · TypeScript strict · Tailwind v4 · Vercel · Supabase · 65 scheduled jobs · GitHub Actions for the capture path.
Code: see repository. Data under public/open-data/: CC BY 4.0 — free to
use with attribution to Avena Terminal (avenaterminal.com).