MarketPulse

A personal tool, built with AI-assisted coding, that fetches the free-market dollar, Tether, gold, gold coins, PAXG and bitcoin prices every 5 minutes, computes each one's premium over its intrinsic value, and shows the cheapest way to hold dollar value today. Few, numeric alerts; everything else goes into a 9 a.m. Telegram digest.

Why I built it

My priority is protecting savings against the rial's inflation, not quick profit. The recurring question was: buy Tether or dollars today? 18-carat gold, a gold coin or PAXG? Each time I multiplied and divided the ounce, dollar and Tether prices on a calculator to compare the premiums.

I also didn't want to check prices every hour. MarketPulse does those manual calculations every 5 minutes, messages me only when something matters, and keeps the rest for 9 a.m.

Features

  • Cheapest way to buy gold: 18-carat gold, the Emami, Bahar, half and quarter coins and PAXG are ranked by price per gram of pure gold: how many grams $100 buys today on each route.
  • Cash or Tether: Tether's premium over the free-market dollar; negative means Tether is the cheaper way to hold dollars.
  • Gold and coin premiums: intrinsic value from the world ounce price and the free-market dollar, with each coin's official weight and fineness.
  • Bitcoin regime: daily, after the candle closes: SMA200 and RSI(14) map to four states. PAXG gets a simple SMA50/SMA200 trend.
  • Edge-triggered price alerts: a rule fires once when a threshold is crossed and stays silent until the price comes back.
  • Anti-spam: quiet hours from 23:00 to 08:00, at most 5 messages a day and one per asset every 6 hours; the rest goes into the 9 a.m. digest.
  • Stale data never alerts: if a source doesn't respond, the last price is shown marked "stale" and no alert is built from it.

Today, cheapest route and alerts (real prices)

Architecture

Deliberately simple: one web app, one database, one worker.

  • App on a server in Iran: ASP.NET Core 10 MVC, EF Core and SQL Server on Plesk/IIS, with two BackgroundServices: price fetching every 5 minutes, and a daily job for the regime and the digest. The UI is a right-to-left PWA (Razor + Tailwind) with every asset served from its own server.
  • Cloudflare Worker as the only way out: LBank prices and candles, and sending to Telegram. Local sources (Wallex, TGJU) are read directly from the server.

Problems solved

  • Iranian host, foreign APIs: a server inside Iran can't reach LBank or Telegram, and Iranian exchanges block foreign IPs. Only foreign traffic goes through the Worker.
  • A Worker that isn't an open proxy: only a few fixed routes and symbols, with a shared key in a header. The Telegram bot token lives only inside the Worker, and every rejection path has a unit test.
  • Every other connection failed: from the Iranian server, every second call to the Worker failed because DNS rotated between several Cloudflare IPs. The fix: IPv4 only, three seconds per IP, start from the last healthy IP, and one safe retry (a Telegram message is not repeated after a timeout, so it does not arrive twice).
  • Time and calendar: everything is stored in UTC and converted to Tehran time and the Persian calendar only for display. The LBank daily candle closes at 19:30 Tehran time, and the candle still forming is left out of the calculations.
  • Correct numbers, with tests: premiums were checked against a hand calculation on one day's real prices, and RSI and SMA200 against an independent calculation on the same 260 candles. Each source's real response is stored as a test fixture.

Status and limits

A personal, single-user tool with no public sign-up; a read-only demo is at /live. It places no trades and connects to no exchange account. Buy/sell costs and liquidity per route are configurable estimates. It is rule-based and educational, not investment advice.