Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Kawach - a shield for your money. A private, offline personal finance app; everything stays on your phone.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Manual entry, categories, a dashboard (net position, things needing
attention, upcoming bills), statement import for three issuers so far, a
Transactions screen for categorizing and editing anything, and an Accounts
screen that projects your next credit card bill from spend since the last
import. Works fully offline once installed.README 전문 보기 ↗Manual entry, categories, a dashboard (net position, things needing attention, upcoming bills), statement import for three issuers so far, a Transactions screen for categorizing and editing anything, and an Accounts screen that projects your next credit card bill from spend since the last import. Works fully offline once installed.
js/parsers/hdfc-bank-savings.js - HDFC Bank savings statements, the
mailed/emailed "combined statement" templatejs/parsers/hdfc-bank-savings-netbanking.js - the same HDFC savings
account, but the self-service "Statement of Account" export from
NetBanking - a completely different template (2-digit years, an extra
reference-number column, no explicit "0.00" for whichever of
withdrawal/deposit didn't happen, so direction is inferred from how the
running balance moved rather than which column has a value). The same
bank can export more than one statement layout depending on where you
downloaded it from - each one needs its own parser, they aren't
interchangeable even for the identical account.js/parsers/hdfc-credit-card.js - HDFC Bank credit card statements (any
co-branded card on HDFC's own template - Swiggy, Rewards, UPI RuPay, etc.)js/parsers/icici-amazon-pay-credit-card.js - ICICI Bank Amazon Pay cardEach new statement template needs its own parser module added to
js/parsers/registry.js, even when it's the same bank and account you've
already got a parser for. Give me a real statement PDF and I'll build it the
same way - parse, then verify the totals reconcile against the statement's
own figures (not just the closing balance - counts and sums per direction
too) before trusting it.
The Add screen lets you log a manual entry against any account, not just
Cash - including a credit card, before that month's statement even exists.
When you later import that card's statement, js/reconciliation.js matches
statement rows against your manual entries (same account, amount, and date
within 3 days): a match replaces the manual entry with the statement's own
data (keeping whatever category you'd already set), and anything left
unmatched shows up in two places - manual entries the statement didn't
confirm are listed on the import screen so you can double-check them, and
statement rows you hadn't logged by hand are just new transactions to
categorize in Transactions. This is how you catch recurring auto-payments you
forgot about.
Every card account has a billingCycleDay (the day of month its statement
closes) - set automatically from the first statement you import, or by hand
from the Accounts screen (tap "Set billing cycle day"). js/billing-cycle.js
uses it to figure out the currently-open cycle even before any statement
exists for that card, so manual entries you log right after getting a card
still land in the right cycle for the spend projection.
When both a bank and a card statement are imported, a debit in the bank
account paying off the card bill and a matching "payment received" credit
in the card account both represent the same money moving - not two separate
expenses. js/transfers.js auto-flags same-amount pairs within 5 days
across accounts as transfers, and Summary excludes them from spend totals.
You can flag/unflag any transaction by hand from the Transactions screen.
js/merchant-rules.js extracts a handful of "significant" words from a
description (stripping payment-gateway noise like PAY*/PTM*/RSP*,
value-date/ref boilerplate, and generic connector words) and matches on
word overlap rather than one exact key. That's what lets PAY*SWIGGY FOODBANGALORE, PTM*SWIGGY INBANGALORE, and SwiggyBENGALURU all hit the
same rule even though the same merchant shows up differently across payment
gateways. It can't unify a merchant whose statement name shares literally no
words with the one you categorized (e.g. Swiggy trading as "BUNDL
TECHNOLOGIES" for some orders) - that needs a hand-curated alias table,
which isn't built.
js/recurring.js scans debit history for the same merchant recurring
roughly monthly (25-36 days apart) at a roughly stable amount (within 15%),
and surfaces detected bills with a projected next due date. Detections are
upserted into the recurring store, so dismissing one ("Not recurring")
sticks - it won't get re-flagged next time the dashboard recomputes this.
It's a heuristic, not a guarantee: needs at least 2 occurrences, and a
brand-new bill won't show up until its second charge.
js/anomalies.js flags two things among this month's debits: a spend at a
merchant meaningfully larger than that merchant's own history (average +
2 standard deviations, or 1.5x average, whichever is higher), and a
first-ever spend at a new merchant above ₹1,000. Both thresholds are
arbitrary starting points in the source file, not tuned against real data -
adjust them if they're too noisy or too quiet for how you actually spend.
ES modules need a real server, not double-clicking index.html. From this
folder:
py -m http.server 5173
Then open http://localhost:5173 in a browser.
Same as Signal: push this folder to a GitHub repo and enable Pages on it
(Settings → Pages → deploy from the main branch, root folder). Then open
that URL on your phone and use "Add to Home Screen" to install it as a PWA.
sw.js caches the app shell so it works offline. Every time a file changes,
bump the CACHE_NAME constant at the top of sw.js (e.g. v1 → v2) or
your phone will keep showing the old cached version after you reload.
The data model says account type is bank|card. Phase 1 seeds a default
Cash account with type: "cash" so manual entries have somewhere to
attach - this is a small extension beyond the original spec, done because
manual entries need an account and there's no cash type otherwise.
Symbol is set in js/config.js (CURRENCY_SYMBOL), defaults to ₹. All
amounts are formatted through js/format.js, which uses Intl.NumberFormat
with the en-IN locale so large numbers group the Indian way (₹12,34,567.89)
instead of the Western way (₹1,234,567.89).
Card statements carry the two numbers that actually matter - total amount
due and payment due date - so both parsers extract them and store them on
the account (statementDue, statementMinDue, statementDueDate). The
Accounts screen leads with what's owed and how many days are left, colouring
it when it's due within three days or overdue; the dashboard sums unpaid
bills into "Card bills due". Unbilled spend since the last statement is
shown underneath as the secondary number, because it isn't owed yet.
"Mark as paid" is manual - the app can't reliably tell whether a bank debit was for this specific card. Importing a newer statement supersedes the old bill and resets the flag automatically.
js/backup.js exports every store as JSON, encrypted with AES-GCM using a
key derived from your passphrase (PBKDF2-SHA256, 210k iterations, random
salt and IV per file). The file is useless without the passphrase - there is
no recovery path, by design. Restore replaces everything. Both live under
the ⚙ button in the header.
This is the only thing standing between you and total data loss: everything lives in one browser's IndexedDB, so clearing site data or losing the phone wipes it.
Re-importing a statement you've already loaded would silently double every row, so the import screen compares incoming rows against existing statement-sourced transactions on that account (same date, amount, direction and description), flags the matches, warns that the period overlaps a previous import, and offers to skip them - checked by default. Every import is also undoable from ⚙ → Import history, which deletes exactly the transactions that came from that batch. Manual entries an import replaced don't come back, and the confirm says so.
A bank account's balance is a snapshot: the last imported statement's own
closing balance and date (account.knownBalance / knownBalanceDate),
adjusted forward by anything dated after that. It reads "Balance unknown"
until you import at least one statement for that account.
js/vendor/pdf.min.js and pdf.worker.min.js are pdf.js, downloaded once
and committed here so the app never calls out to a CDN at runtime (per the
no-third-party-calls privacy rule). Password-protected PDFs are supported -
enter the password in the Import screen; it's held in memory only for that
one parse and never written to storage.