尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证HK Interest Calculator: simple interest at the HK Judiciary judgment debt rate or HSBC prime rate
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Hong Kong finance calculators on one page: interest on debts (a web version of the Interest Calculator.xlsm workbook), mortgages, present value / IRR / time value of money, and inflation by the official CPI. Rates and CPI are updated daily.
You can choose one of three rates:查看完整 README ↗Live: https://app.kevinlhc.com/interestcal/
Hong Kong finance calculators on one page: interest on debts (a web version of the Interest Calculator.xlsm workbook), mortgages, present value / IRR / time value of money, and inflation by the official CPI. Rates and CPI are updated daily.
You can choose one of three rates:
Judgment debt rate, as published by the HK Judiciary. This is the default.
HSBC best lending (prime) rate, taken from HKMA Monthly Statistical Bulletin table 6.4.1. You can add a spread over prime, e.g. prime + 2%. The rates are cross-checked daily against HSBC's own prime rate page, which lists the current rate and the last 5 changes:
US prime rate (Interest tab), the "Bank prime loan" rate in the Federal Reserve's H.15 release: the rate posted by most of the top 25 US banks. You can add a spread. Choosing it switches the currency to USD (US$) unless you've picked one in Advanced settings. The history since 2000 comes from the Fed's full H.15 data file (series RIFSPBLP_N.B); the daily update reads the release page, which shows the last five business days, and adds any change.
Fixed rate, e.g. 8% p.a., for contract rates not tied to a published rate.
Mortgage tab: equal monthly instalments on HK bank conventions.
n=250), and a drawdown date; instalments fall due on the drawdown day each month.Each published rate applies from its effective date up to, but not including, the next rate's effective date.
The start date earns interest and the end date does not. For example, 1 Jan → 2 Jan is 1 day at the rate effective on 1 Jan.
Interest for each period is principal × rate × days ÷ year days. The results table shows this formula for every row. The rounding option sets whether the total is the sum of unrounded amounts (the default) or of amounts already rounded to cents. Rounding is half away from zero, the same as Excel's ROUND.
The year days depend on the day count basis you choose:
| Basis | Year days | Notes |
|---|---|---|
| Actual/Actual (default) | 366 in a leap year, 365 otherwise | Periods are split at 1 January so each day uses its own year's count (ISDA style). This is the convention the HK courts use. |
| Actual/365 Fixed | always 365 | |
| Actual/360 | always 360 |
The latest published rate keeps applying after its effective date.
Days before the earliest published rate earn no interest, and the page shows a warning when that happens. The earliest rates are currently 1 Jul 2000 for the judgment rate and 5 May 1971 for prime.
Prime rates change on any date, not just at quarter starts, and the same rules apply. Some dates in the HKMA table record only a deposit-rate change; those rows are dropped, so every row kept is a real prime change.
| Path | Purpose |
|---|---|
site/calc.js | The calculation, a pure function ported from the VBA macro. test/excel-parity.test.mjs checks it against a line-by-line port of the workbook's macro: the workbook's last saved result, its 104 judgment rates (all on the site, unchanged), and 6,000+ random and edge cases (leap years, year ends, rate changes, HK$0.01 to about HK$1bn), which must agree to the cent |
site/index.html, app.js, style.css | Static web UI. Amounts are shown as xxx,xxx.xx, and a spread is shown as base + spread = rate. |
site/interest-text.js | Interest tab wording: rate and setting names, each period's working and note, the daily interest text (no page access, so it's unit-tested) |
site/cash-flows.js | Interest tab cash flows: payment and principal-added rows |
site/interest-exports.js | Interest tab downloads: Word, PDF and Excel |
site/export-xlsx.js | Excel export. The Calculation sheet has live formulas (days, base + spread, principal × rate × days ÷ year days, totals). The Rates sheet has the source URL and the rates used. |
site/vendor/xlsx.mini.min.js | SheetJS 0.20.3 mini build (Apache-2.0), loaded only when you click Download Excel. It's copied from node_modules/xlsx/dist/. |
site/saved.js | Saved calculations (browser storage) |
site/export-docx.js | Word export. Writes the .docx (a zip of a few XML files) directly, so it needs no library. |
site/export-pdf.js, site/vendor/jspdf*.js | PDF report, using jsPDF 4 and jsPDF-AutoTable 5 (both MIT). They load only when you click Download PDF and are copied from node_modules. |
site/rates.json | Judgment debt rates scraped from the Judiciary site |
site/hibor.json, hibor-3m.json | 1-month and 3-month HIBOR fixings since 1996: history from the HKMA API, and the recent days HKMA hasn't republished yet from HKAB, which sets them each business day at 11:15 HKT (a few days overlap, as a cross-check). fills in older history in small batches, saving after each one (rerun it to carry on). The daily update merges in recent fixings and fetches a few older pages per run until the history reaches 1996. Every download has a time limit, and the job is capped at 20 minutes. These are optional sources: an outage only logs a warning. |
The website has no build step. SheetJS is used by the rate updater to read the HKMA .xls file, and by the page's Excel export through the vendored build. You need Node 20 or later to run the tests and the updater.
npm install # install dev tools (SheetJS, jsPDF, Playwright)
npm test # unit tests: calculation, parsers, exports, vendored libraries
npm run test:e2e # browser tests (desktop Chrome + iPhone Safari engine); first run: npx playwright install chromium webkit
npm run fetch-rates # refresh both rate files
npm run vendor # re-copy the export libraries into site/vendor after updating them
npm start # serve site/ at http://127.0.0.1:4173 (no dependencies)
The browser tests check the page itself: the sample calculation, shared links, no recalculation before Calculate, the fixed rate, field layout (one height, no overlap, no sideways scrolling, including on iPhone), rate sorting, and the three downloads. Every deploy runs them first, so a broken page is not published.
Dependabot opens a weekly pull request when jsPDF, jsPDF-AutoTable, Playwright or a GitHub Action has a new version. On those PRs the test workflow re-copies the updated libraries into site/vendor and runs all tests; merge when it's green. SheetJS (xlsx) is installed from cdn.sheetjs.com, which Dependabot can't track. To update it, change the version in package.json, then run npm install && npm run vendor.
main branch.main deploys the site. A daily schedule (11:15 HKT, when HKAB publishes the HIBOR fixing) re-fetches both rate sources, commits any change and redeploys only when something changed. You can also start it manually from the Actions tab, and a manual run always redeploys.If either source changes its layout, validation stops that source from overwriting good data. The other source still updates, and the workflow is marked as failed so GitHub emails you.
?tab=mortgage&...), and PDF / Excel downloads.Present value tab (labelled PV): the value today of amounts due on future dates, at one discount rate.
XIRR (Microsoft's example gives 37.336253%, as Excel does). If more than one rate works (cash flows that switch between paid and received more than once), it shows the one closest to 0% and lists the others. Switching back to Present value starts from the rate found.(1 + rate ÷ periods a year)^(−n). With yearly periods this is Excel's NPV (whose first value is T+1) and IRR (whose first value is T0): Microsoft's examples give 1,188.44, −2.1% and 8.7%, as in Excel. An IRR by periods is quoted a year (the rate a period × periods a year) and a period, plus the yearly rate with compounding. Links carry tm=p&pl=quarter, with the period number in place of the date.(1 + rate ÷ m)^(−m × years) for m compounding periods a year; daily (1 + rate ÷ year days)^(−days); continuous e^(−rate × years); none 1 ÷ (1 + rate × years). Years = days ÷ 365 (or 360); under Actual/Actual, the days in each calendar year ÷ 365 or 366, added up.100,000.00 ÷ (1 + 5.000%)^(731 ÷ 365). Rows keep full precision; only the totals are rounded to cents.XNPV with the valuation date as its first date.DATE(...)), with the totals as SUMs.?tab=pv&v=...&r=...&cf=date,amount,description; a repeating one is rf=date,amount,every,times,description, and s=irr solves for the rate), and Recent and Saved like the other tabs.Time Value of Money calculator (PV tab, switch at the top: Cash flows | Time Value of Money; N, I/Y, PV, PMT, FV): the financial-calculator equation, as on a BA II Plus or HP 12C. Choose what to solve for and fill in the other four.
PV (1+i)^N + PMT (1 + i·due) ((1+i)^N − 1) ÷ i + FV = 0, where i = (1 + rate ÷ C/Y)^(C/Y ÷ P/Y) − 1, so compounding can differ from payments (e.g. half-yearly compounding, monthly payments); payments can be at the start of each period. N comes from logs; I/Y is found numerically and closest to 0%.?tab=pv&m=tvm&ts=pmt&py=12&n=30&r=5&pv=1000000&fv=0), Recent and Saved.Inflation tab: what an amount at one time is worth at another by the Hong Kong Composite Consumer Price Index from the Census and Statistics Department, table 510-60001, through its open data API.
(CPI ratio)^(1 ÷ years) − 1 (a year counting from its middle), and the CPI at each end.scripts/update-cpi.mjs (run by npm run fetch-rates, or on its own) downloads the whole series, checks it (500+ months, no gaps, plausible figures, each full year's average of the months matching C&SD's yearly index, latest month no more than 4 months old) and rewrites site/cpi.json when it changes. The page only uses it on this tab, so an outage is a warning and the saved figures stay.?tab=inflation&a=100&in=2000&w=now; months as 2000-01; now keeps following the latest month; older f / t / d=back links still open), Recent and Saved.Advanced settings (collapsed by default, so the basic form stays simple):
Day count basis (Actual/Actual by default) and rounding (round the total only, by default).
Days counted (next to the dates, not under Advanced settings): End date included (the default, and usually how it is counted in court: both the start and end dates earn interest), or End date not included (as in Excel and the original workbook: the start date earns interest, the end date doesn't). With the end date included each period shows its last day counted (1 January to 31 March is 90 days), the same start and end date is one day, and the downloads follow (in Excel, days = end − start + 1).
Calculation rows: Detailed (each published rate), the default, with a row for each published rate (even when a quarter repeats the same rate), payment and new year; or Combined (per rate period), which combines consecutive rows at the same rate, including rows split only by a republished rate, a new year (Actual/Actual), a payment, principal added or compounding, and shows the working as one sum, e.g. 100,000.00 × 8.000% × (184 ÷ 365 + 182 ÷ 366). Totals don't change. The downloads follow the same choice; in Excel a combined row is one live formula summing its pieces.
Compounding: None (simple interest, the default), monthly, quarterly, yearly, daily or continuous.
principal × ((1 + rate ÷ year days)^days − 1) within each period.principal × (e^(rate × days ÷ year days) − 1) within each period.Results compare the compounded interest with the same calculation as simple interest. On a compounding date, interest is added to principal first, then principal added later, then payments.
Switch to a different rate from a date: e.g. prime + 1% before judgment, then the judgment rate after. The new rate (judgment, prime + spread, or fixed) applies from the switch date. Rows show each period's own rate, and the rates-used list labels each rate with its kind. Optionally, the interest accrued up to the switch date can be added to the principal (Interest before the change: Add to principal), so the new rate is charged on both; off by default.
Currency: HKD by default, USD by default for the US prime rate; or RMB, the other G10 currencies (EUR, JPY, GBP, CHF, CAD, AUD, NZD, SEK, NOK) or any symbol you type. Amounts on the page and in every download use its symbol (HK$, US$, CN¥, €, JP¥, £, C$, A$, NZ$; codes for CHF, SEK and NOK). Once chosen, it doesn't change with the rate.
Cash flows: principal added later and payments received sit together in a collapsible Cash flows pane, which shows a count (e.g. "1 principal added, 2 payments") while closed and opens by itself for a link that has any.
Principal added later: further principal such as costs, each with a date, an amount and an optional description. From its date, each amount joins the principal and earns interest at the same rate. On a day with both, the principal is added before any payment, so the payment can clear it. Amounts dated outside the calculation period are ignored with a warning.
Icon and link preview: a calculator icon for browser tabs and the iPhone home screen, plus a preview card (title, description, image) when the link is shared. After changing site/favicon.svg or the preview wording, run npm run images.
Partial payments: add any number of payments (date + amount). Choose how they're applied:
Interest stays simple either way: unpaid interest never earns interest. A payment on a date counts from that day. Payments before the start date, or on or after the end date, are ignored with a warning, and any overpayment is flagged. The results show a payments table and the outstanding principal plus unpaid interest. The exports include these too; in Excel, each period's interest uses that period's principal as a live formula.
Daily interest thereafter: principal × the rate in force on the end date ÷ that day's year days. Under Actual/Actual it shows two figures, ÷ 365 for a normal year and ÷ 366 for a leap year, on the page and in every download. Use it for wording like "…plus HK$219.18 per day until payment". It appears on the page and in the Word, PDF and Excel files; in Excel it's a live formula.
Downloads (every tab with files): Download [Word | PDF | Excel] (Mortgage and PV: PDF | Excel), each a one-click download, with [Copy link | Save] beside it (below on a phone).
Download PDF: downloads a report straight away (built in the browser with jsPDF): inputs, results, the formula for each period, the rates used, and the sources as named, clickable links. No raw URLs are printed.
Sortable rate table: click Effective date or Rate to sort; click again to reverse. The PDF and Excel exports use the same order.
Shareable link: the inputs are stored in the page address (e.g. ?src=prime&p=1000000&from=2026-01-01&to=2026-09-30&basis=act%2Fact&round=total&spread=1). Copy link copies it.
Excel export: the Excel file uses live formulas and has a second sheet with the rate sources.
Word export: the interest schedule as a table worded like a statutory demand, one row per period: "(i) Interest on the sum of HK$… at the rate of …% per annum from … to … (n days)", the working ("(i.e. principal × rate × days ÷ 365 = amount)") and the amount, then the total, a summary (principal, any principal added or payments, interest, total amount due at the end date) and the daily interest from the end date until payment. Ready to paste into a court document.
Today's rates in the header: under "Rates updated as at…", the judgment debt rate, HSBC prime, US prime, and 1-month and 3-month HIBOR, each in the same style: name, rate in force today (3 decimals, or more when published with more, like HIBOR's 5) and the date it applies from.
Word calculation inputs: the Word file starts with a "Calculation inputs" block (rate, principal, dates, day count, rounding and any compounding or cash flows) above the table, so it explains itself when sent on.
Word source note: the Word file ends with a short note naming where the rates came from and when they were checked, e.g. "Source of rates: HK Judiciary: interest rates on judgment debts (as at 5 October 2026)." There's none for a fixed rate.
Recent calculations: the last 5 calculations you ran (any tab) are kept automatically in a "Recent calculations" list, in your browser only; open one, save it to keep it, or clear the list ("Clear recent calculations"; saved calculations stay). The sample run when the page opens isn't recorded.
Help: a "?" next to each Advanced setting, "Apply payments to" and the End date shows a short explanation; tap again to hide it.
Saved calculations: Save (on either tab) keeps the calculation's link and a name in your browser's local storage, never uploaded. The Saved calculations card lists them, newest first: rename, open or delete. Up to 50 are kept.
Rounding: Total rounds only the total (rows are added unrounded); Per row rounds each row of the table to cents first. The second option makes the rows add up exactly to the total.
scripts/backfill-hibor.mjssite/mortgage.js, mortgage-app.js, mortgage-export.js | Mortgage calculation, tab and exports |
site/tvm.js, tvm-app.js | Time Value of Money calculator: N, I/Y, PV, PMT, FV (PV tab) |
site/inflation.js, inflation-app.js, cpi.json | Inflation tab and the HK Composite CPI history (C&SD) |
scripts/parse-cpi.mjs, update-cpi.mjs | CPI download, checks and site/cpi.json writer, run by the daily update |
site/pv.js, pv-app.js, pv-export.js | Present value calculation, tab and downloads. test/pv-export.test.mjs runs the Excel formulas for every compounding and day count basis and checks they give the page's figures |
site/shared.js, tabs.js | Helpers shared by the tabs; tab switching |
site/ui-motion.js | The sliding highlight on segmented controls and the open/close animation of collapsible sections (off with Reduce Motion) |
site/prime-rates.json | HSBC prime rates parsed from the HKMA spreadsheet |
site/us-prime-rates.json | US prime rate changes since 2000 (Federal Reserve H.15) |
scripts/fetch-rates.mjs | Fetches and validates both sources, and rewrites a JSON file only when its rates change |
scripts/parse-judiciary.mjs, parse-prime.mjs, parse-hsbc.mjs, parse-usprime.mjs | Parsers for each source, plus the HSBC cross-check |
test/ | Tests, including the workbook's saved example (HK$135,436.48, 24 Nov 2025 → 20 Apr 2026 = HK$4,434.64) |
.github/workflows/pages.yml | Refreshes the rates daily and deploys to GitHub Pages |