|
| 1 | +--- |
| 2 | +name: Singapore HDB Resale Analysis |
| 3 | +description: Builds a buy/don’t-buy assessment for a Singapore HDB target area or block using the latest public resale transactions, with comps, trend slices, lease profile, and caveats. |
| 4 | +license: MIT |
| 5 | +metadata: |
| 6 | + category: Research |
| 7 | +--- |
| 8 | + |
| 9 | +### Prerequisites |
| 10 | + |
| 11 | +#### Setup: `use-agently` |
| 12 | + |
| 13 | +This workflow requires the `use-agently` skill and CLI. Set this up if you haven't already. |
| 14 | + |
| 15 | +```bash |
| 16 | +npx skills add https://github.com/agentlyhq/use-agently --skill use-agently |
| 17 | +npm install -g use-agently@latest |
| 18 | +use-agently init |
| 19 | +use-agently doctor |
| 20 | +``` |
| 21 | + |
| 22 | +#### Verify balance |
| 23 | + |
| 24 | +```shell |
| 25 | +use-agently balance |
| 26 | +``` |
| 27 | + |
| 28 | +Fund your wallet with USDC on Base if the balance is zero — agent calls require funds. All commands are dry-run by default. Add --pay to authorize payment. |
| 29 | + |
| 30 | +When the workflow is complete, run `use-agently balance` again, always report how much was spent. |
| 31 | + |
| 32 | +#### Variables look like this `${TARGET_AREA_OR_BLOCK}` |
| 33 | + |
| 34 | +If any of the variables used in the workflow are not defined (excluding the first `${TARGET_AREA_OR_BLOCK}`), |
| 35 | +BEFORE you run the workflow, always ask the initiator for the value for each unique variable. |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +# Singapore HDB Resale Analysis |
| 40 | + |
| 41 | +Target area or block: **${TARGET_AREA_OR_BLOCK}** |
| 42 | +Optional filters: room type = `${ROOM_TYPE_FILTER}` (e.g., 3 ROOM, 4 ROOM), storey range = `${STOREY_RANGE_FILTER}` (e.g., 01 TO 03), minimum remaining lease (years) = `${MIN_REMAINING_LEASE_YEARS}` (default 0), lookback months = `${LOOKBACK_MONTHS}` (default 24). |
| 43 | + |
| 44 | +You are a Singapore HDB resale analyst. Your job is to fetch the latest HDB resale transactions from data.gov.sg, filter to the target area or specific block, apply optional filters, compute comps and trends, then produce a clear buy/don’t-buy style recommendation with rationale and caveats. |
| 45 | + |
| 46 | +## Phase 0: Pick the right data-fetch tool & pull the dataset |
| 47 | + |
| 48 | +- First, search for an HTTP GET/CSV-capable agent: `use-agently search "HTTP request CSV JSON GET"` and pick an agent that supports unauthenticated HTTPS GET with query parameters (common name: **HTTP Request**). Inspect its tool schema before use: `use-agently mcp tools --uri <chosen-agent-uri>`. |
| 49 | +- Target dataset: `https://data.gov.sg` dataset id **d_8b84c4ee58e3cfc0ece0d773c8ca6abc** (HDB resale transactions). Use two-step fetch to stay robust: |
| 50 | + 1) Metadata: GET `https://data.gov.sg/api/3/action/package_show?id=d_8b84c4ee58e3cfc0ece0d773c8ca6abc` to discover the `resource_id` for the resale transactions (CSV/JSON). Select the resource with fields like `town`, `block`, `street_name`, `flat_type`, `storey_range`, `resale_price`, `floor_area_sqm`, `remaining_lease`, `lease_commence_date`, `month`. |
| 51 | + 2) Data: Paginate via `https://data.gov.sg/api/3/action/datastore_search` using the discovered `resource_id`, `limit=5000`, and `offset` pagination until no more records. Keep only rows within the last `${LOOKBACK_MONTHS}` months (default 24). Cache the raw JSON to avoid re-fetching. |
| 52 | +- If the dataset is temporarily unavailable, surface the HTTP status and retry guidance; otherwise proceed. |
| 53 | + |
| 54 | +## Phase 1: Normalize and prepare filters |
| 55 | + |
| 56 | +- Normalize string fields to uppercase and trim (town, block, street_name, flat_type, storey_range). |
| 57 | +- Parse `month` into a proper date; derive `month_start`. |
| 58 | +- Derive `price_per_sqm = resale_price / floor_area_sqm`. |
| 59 | +- Expand `storey_range` into `storey_low` and `storey_high` (e.g., "04 TO 06" → 4, 6). |
| 60 | +- Compute `remaining_lease_years` from `remaining_lease` (when provided) or `lease_commence_date` + 99 - current year (explicitly assume the standard 99-year HDB lease). |
| 61 | +- Identify whether `${TARGET_AREA_OR_BLOCK}` looks block-level (contains a number or matches `<block> <street>`) vs area-level (matches `town` or `street_name` substring). Store both interpretations. |
| 62 | + |
| 63 | +## Phase 2: Apply location + optional filters |
| 64 | + |
| 65 | +- Location filter: |
| 66 | + - **Block-level path:** match records where `block + street_name` contains `${TARGET_AREA_OR_BLOCK}` (case-insensitive), allowing minor spacing differences; keep exact block matches preferred. |
| 67 | + - **Area-level path:** match records where `town` or `street_name` contains `${TARGET_AREA_OR_BLOCK}`. |
| 68 | +- Optional filters (only apply when provided): |
| 69 | + - `flat_type == ${ROOM_TYPE_FILTER}`. |
| 70 | + - `storey_low/high` overlaps `${STOREY_RANGE_FILTER}` if given. |
| 71 | + - `remaining_lease_years >= ${MIN_REMAINING_LEASE_YEARS}`. |
| 72 | +- Keep a sibling "area baseline" cohort (same town, same lookback) to benchmark block-level pricing against the broader area. |
| 73 | +- If the filtered cohort has fewer than 8 records, warn about data sparsity and broaden by +12 months (but note the widened window). |
| 74 | + |
| 75 | +## Phase 3: Build comps and trend slices |
| 76 | + |
| 77 | +- Compute for both the **focus cohort** (block or area match) and **area baseline**: |
| 78 | + - Median and 25th/75th percentile `resale_price` and `price_per_sqm`. |
| 79 | + - 6-month and 12-month median `price_per_sqm` to show direction (MoM/YoY slope if enough points). |
| 80 | + - Volume: transactions per month (mean, last 3 months). |
| 81 | + - Dispersion: IQR of `price_per_sqm`; flag if IQR > 20% of median (heuristic noise threshold—tune if market volatility is unusually high/low). |
| 82 | + - Lease profile: median `remaining_lease_years`, share < 60 years, youngest/oldest leases. |
| 83 | +- Select 8–12 best comps: closest in `price_per_sqm` and same `flat_type`; include `month`, `block`, `street_name`, `flat_type`, `storey_range`, `price_per_sqm`, `resale_price`, `remaining_lease_years`. |
| 84 | + |
| 85 | +## Phase 4: Heuristics for recommendation |
| 86 | + |
| 87 | +- Establish quick signals: |
| 88 | + - **Lease risk:** flag if median `remaining_lease_years` < 60 or any comps < 50. |
| 89 | + - **Pricing vs area:** compare focus median `price_per_sqm` to area baseline; flag if > +12% (expensive premium) or < -8% (discount). These asymmetric bands are heuristics that reflect willingness to pay a small premium for the right stack—adjust if you have better local priors. |
| 90 | + - **Trend:** if 6-month median < 12-month median by >5%, call out softening; if rising >5%, call out momentum. |
| 91 | + - **Volume:** if < 3 transactions per recent quarter, warn about liquidity. |
| 92 | + - **Dispersion:** high IQR → note heterogeneity or data noise. |
| 93 | +- Output one of: **"Buy / Good value"**, **"Proceed with caution"**, or **"Avoid / overpriced"**, and state the 2–3 strongest drivers. |
| 94 | + |
| 95 | +## Phase 5: Assemble the report |
| 96 | + |
| 97 | +Structure the final report as markdown: |
| 98 | + |
| 99 | +1. **Recommendation & confidence** — label, 2-sentence rationale, key pro/con bullets. |
| 100 | +2. **Inputs & filters** — echo `${TARGET_AREA_OR_BLOCK}`, filters applied, lookback window, data last refreshed timestamp. |
| 101 | +3. **Price snapshot** — median/25th/75th `price_per_sqm` and `resale_price` for focus vs area baseline (table). |
| 102 | +4. **Trend slice** — 6m vs 12m `price_per_sqm`, direction arrows. |
| 103 | +5. **Comps table** — 8–12 rows with `month`, `block/street`, `flat_type`, `storey_range`, `remaining_lease_years`, `resale_price`, `price_per_sqm`, link back to source row id if provided. |
| 104 | +6. **Lease profile** — distribution, % under 60 years, notes on flats nearing 99-year cap. |
| 105 | +7. **Caveats** — data gaps, low volume warnings, any widening of lookback to satisfy minimum sample. |
| 106 | +8. **Next steps** — what to validate offline (on-site checks, renovation state, facing/stack specifics). |
| 107 | + |
| 108 | +Render the final markdown via [Markdown by Agently](https://use-agently.com/agents/eip155:8453/erc8004:0x8004a169fb4a3325136eb29fa0ceb6d2e539a432/25330) using its `render_markdown` tool (confirm input schema with `use-agently mcp tools --uri eip155:8453/erc8004:0x8004a169fb4a3325136eb29fa0ceb6d2e539a432/25330`). Invoke with `markdown` = full report and, if supported, `title` = `HDB Resale Analysis for ${TARGET_AREA_OR_BLOCK}`. |
0 commit comments