Syed Ahmer ShahSyed Ahmer ShahSyed Ahmer ShahSyed Ahmer ShahSyed Ahmer Shah — home
  1. …
  2. Engineering Logs
  3. The Engineering Logs
  4. MarketClock: A Trading Calendar That Shows Its Work
Part 17 of 19

MarketClock: A Trading Calendar That Shows Its Work

A case study on answering three questions a trading desk asks every morning, and refusing to answer when I couldn't prove the answer

Written by

Syed Ahmer Shah

Software Engineer

Oct 24, 20269 min read1,936 words—reading now▼
The MarketClock emblem beside a dark market page showing the New York Stock Exchange closed for the weekend, under the title MarketClock: a trading calendar that shows its work
Read this articlevoice
Markdown

Picture the first ten minutes of a trading desk's morning. Someone has an order to place in London and another in New York. Before anything else, three questions: is each exchange actually open today, does either one close early, and if we buy today, on which day does the money really change hands?

Most of the time the answers are boring. The trouble is the days they aren't. A holiday in one country but not the other. Christmas Eve, when New York closes at one in the afternoon. A trade on a Friday that can't settle until a holiday Monday has passed. Get one of those wrong and a payment arrives a day late, or a trade fails and someone spends the afternoon on the phone explaining why.

MarketClock is my answer to those three questions. It covers the 30 stock exchanges and financial markets in the open-source holidays library, from the NYSE and Nasdaq to London, Tokyo, Hong Kong and Frankfurt. It tells you whether a market is open right now, with a countdown to the close. It works out settlement dates across several markets at once. And it checks its own data against the calendars the exchanges publish themselves. I built all of it in October 2026, across 24 pull requests.

This is how it fits together, the parts that fought back, and the one rule that shaped everything.


#The rule: no answer without a source

The holidays library is excellent at one thing: knowing which days a market is closed. It's maintained by a large community and updated several times a year. I decided early that MarketClock would never keep its own copy of those dates. The library is the single source, and the app only asks it.

Everything else a trader needs, the library doesn't have. Trading hours. Early-close times. How many days a trade takes to settle in each country. Those had to come from somewhere else, and that's where most projects quietly start guessing.

So I wrote one rule into the project's instructions before writing any code: every fact that doesn't come from the library is stored with the link to the page it came from. A settlement cycle has a regulator's announcement behind it. A trading hour has the exchange's own page. If I couldn't open that page and read the fact myself, the fact didn't go in.

That rule cost me. Several exchange websites refuse automated visitors. A couple were down for maintenance the whole time I was building. One industry briefing I wanted to cite had moved, and its old link led nowhere. Each time, the honest move was the same: leave the market without that piece of data and say so on the page. A market with no confirmed hours shows "hours not on file" instead of a guess dressed up as an answer.

It also paid back. The settlement calculator can show you, under its answer, exactly which rule it used and a link to read it yourself.

The New York Stock Exchange page: closed for the weekend, opening Monday at 09:30, with trading hours and a link to their source
The New York Stock Exchange page: closed for the weekend, opening Monday at 09:30, with trading hours and a link to their source

#One place that knows what day it is

The second decision was where the date logic lives.

It lives in one small package of plain Python, with no web framework and no database in it. The API calls it, the calendar feeds call it, the status badges call it. None of them do date maths of their own. It has full branch coverage, which means a test exercises every path through it, and the build refuses any change that lowers that.

The reason is trust. If the market page worked out "trading day" one way and the settlement tool another, sooner or later they would disagree, and the person looking at both would stop believing either.

Inside that package, I leaned on the library rather than around it. When I needed "the next trading day", the library already had a function for it, tested against far more calendars than I'll ever check by hand. Every time I was tempted to write my own loop, I used theirs.

#The question that sounds simple: when does it settle?

When you buy a share, you don't own it the moment you click. The trade is agreed today, but the money and the shares actually swap a little later. In the United States that's one business day later, written T+1. In London today it's two, T+2.

Business days, though, are where it gets interesting. A day only counts if the market is open. And if your trade involves two markets, a day only counts if both are open.

Take an order placed on 23 December 2026 that touches both New York and London, on a two-day cycle. Christmas Eve counts: both markets are open, if only for the morning. Christmas Day doesn't. The 26th and 27th are a weekend. Monday the 28th, New York is open, but London is closed for Boxing Day, which moves to Monday because the 26th falls on a Saturday. So the second shared business day is Tuesday the 29th. Most people would have guessed the 28th.

The settlement calculator: a T+2 trade across New York and London on 23 December 2026 settles on Tuesday 29 December
The settlement calculator: a T+2 trade across New York and London on 23 December 2026 settles on Tuesday 29 December

There was one more twist. Settlement cycles change. The United States moved from T+2 to T+1 on 28 May 2024, and the UK plans to make the same move in October 2027. A tool that stores one number per country gets every older trade wrong, and back offices look at old trades all the time.

So each cycle is stored with the date it took effect. Ask about a trade from 2020 and MarketClock uses T+2. Ask about one from last week and it uses T+1. Leave the cycle out entirely and it picks the rule in force on that trade date and tells you where it found it.

#Is it open right now?

This sounds like the easiest question, and it was the one I rewrote the most.

"Now" is different in every market. When it's Friday night in New York, it's already Saturday morning in Tokyo. So MarketClock reads each exchange's date in its own time zone before asking anything else. Then it checks the day: weekend, holiday, half day or normal. Then the clock: before the open, during the session, after an early close.

The result is a small badge on every market page: "Open, closes in 2h 10m", or "Closed (holiday), opens Monday 09:30". The markets list shows the same thing for all 30 exchanges at once.

The part I'm proudest of is the case where it says less. For markets whose trading hours I couldn't confirm, the badge still knows a weekend from a working day, because that comes from the library. It just won't claim the market is open at 3 p.m. if it doesn't know when the session ends.

Also readOne Seat, Two Buyers: Race Conditions, IDOR and Keys in a Cinema Booking System
The Last Mango Problem: Race Conditions in a Real Marketplace

#Checking the library against the exchanges

If the whole app trusts one library, the obvious question is: how do we know the library is right?

So I built a data-quality page. I took the calendars the exchanges publish themselves, entered every closed day and early close with the date I read them, and compared them day by day with the library. Only whole years go in, because a half-published year would show false gaps.

The first three were the New York Stock Exchange for 2026 to 2028, Nasdaq for 2026 and the London Stock Exchange for 2027 and 2028. Sixty-six official days in all. Every one matched.

I'll admit that was slightly disappointing. I had half hoped to find a mistake and send the fix back to the library, which is how open source is supposed to work. But a clean result is still a result, and now there's a page that proves it, with the sources linked.

The data-quality page: the London Stock Exchange, Nasdaq and the New York Stock Exchange each marked as matching the exchange
The data-quality page: the London Stock Exchange, Nasdaq and the New York Stock Exchange each marked as matching the exchange

#Small things people actually use

Not everyone wants a website. Some people want the closures in the calendar they already live in, so every market has a calendar feed you can subscribe to in Google Calendar, Apple Calendar or Outlook. It always covers this year and next, so a subscription never quietly runs out.

There's a page per market per year, like "NYSE holidays 2027", and a yearly page that lists every exchange's closures side by side. There's a calculator for adding or counting business days. There's a small card other websites can embed to show whether a market is open. And there's a watchlist, kept only in your own browser, that can remind you, while the site is open in a tab, the day before a market you follow closes. Nothing about you is ever stored on a server, because there are no accounts to store it in.

A full year for one market: closures in red, early closes outlined and weekends shaded
A full year for one market: closures in red, early closes outlined and weekends shaded

#What I got wrong

My 3D globe froze the page. The home page has a rotating globe of exchange cities, and it looked lovely on my laptop. Then I ran a performance audit, which simulates a slower phone without a graphics chip. The globe was being drawn by the processor instead, and it blocked the page for over a minute. The fix was to draw a simple dotted sphere first and only load the real globe on large screens with a proper graphics chip, after the page has finished loading.

A fade-in made the page look slow. The big headlines slid in with a fade. Browsers don't count invisible text when they measure how fast a page appears, so the fade made the site look seconds slower than it was. The headlines now flip into place without fading.

My rate limit could be fooled. To stop anyone hammering the API, each visitor gets a number of requests per minute. My first version identified visitors by the first address in a header that the visitor can write themselves. Changing that header would have given anyone a fresh allowance. It now reads the last address, the one my own server adds.

I trusted a "helpful" library default. The validation library happily accepted a long number like 1782950400 as a date, because it's a valid timestamp for midnight. Nobody types that by accident, but an API that accepts it is an API that will surprise someone. Dates must now be written as year, month and day, and nothing else.

#By the numbers

  • 30 exchanges and markets, each with its own weekend
  • 66 official holiday dates checked against the library, all matching
  • 210 automated tests: 172 on the backend, 38 on the frontend
  • 100% branch coverage on the date logic
  • 24 pull requests, every one checked by CI and CodeQL before it merged

#What's next

The code is ready. MarketClock goes live in February 2027. After that, the work is mostly outside the code: more exchange calendars for the data-quality page as their websites become readable, trading hours for the markets that still say "not on file", and the first real trader telling me what I missed.

If I started again, I would write the rule about sources on day one, exactly as I did, and I would test on a slow phone from the first week instead of the last.

The source is on GitHub, and I wrote about settlement itself, for people who have never placed a trade, in The day the money moves.

Find me across the web.

Same person, every platform

Work & code

  • ASPortfolioahmershah.dev
  • LinkedInin/syedahmershah
  • GitHub@ahmershahdev
  • AWSAWS Builder Center@syedahmershah
  • Crunchbasesyed-ahmer-shah
  • LinkedIn · Companycompany/syedahmershah

Writing

  • Dev.tosyedahmershah
  • Medium@syedahmershah
  • Hashnode@syedahmershah
  • Substack@syedahmershah
  • HackerNoonu/syedahmershah
  • CLCoderLegionuser/syedahmershah

Reviews & listings

  • Google Knowledge PanelSyed Ahmer Shah
  • Google Business Profileg.page
  • ClClutch
  • TpTrustpilot
  • DRDesignRush
  • TBTechBehemoths

Social

  • YouTube@ahmershahdev
  • Instagram@ahmershahdev
  • TikTok@ahmershahdev
  • Facebookahmershahdev
  • X@ahmershahdev
#marketclock#casestudy#flask#nextjs#mysql#apidesign#softwarearchitecture#systemdesign
ShareXLinkedInRedditWhatsApp

← Previous in series

The Weekend Is Not a Constant

Next in series →

Cybersecurity Trends: Protecting Data in the Digital Age

On this page

  • The rule: no answer without a source
  • One place that knows what day it is
  • The question that sounds simple: when does it settle?
  • Is it open right now?
  • Checking the library against the exchanges
  • Small things people actually use
  • What I got wrong
  • By the numbers
  • What's next

The Engineering Logs

  1. 01The Edge Latency Lie: Solving Global Consistency
  2. 02Top 10 AI Tools Every Frontend Developer Should Know (2026 Guide)
  3. 03Change One Number. Take Everything.
  4. 04How Databases Work: From Tables to Query Execution
  5. 05The New Era of Software Engineering
  6. 06The Art of Object-Oriented Programming
  7. 07GleanGrid: Building a Pre-Order Marketplace for Farmers Markets
  8. 08The Last Mango Problem: Race Conditions in a Real Marketplace
  9. 09BookMyMovie: Building a Cinema Ticketing Platform
  10. 10One Seat, Two Buyers: Race Conditions, IDOR and Keys in a Cinema Booking System
  11. 11Zovita+: Building an Online Pharmacy That Adapts to Each Shopper
  12. 12The Discount That Knew You Were Hesitating: Rule-Based Personalisation in an Online Pharmacy
  13. 13RAG Retrieval Strategies on a 50k-Document Dataset: BM25 vs Dense vs Hybrid
  14. 14Inside the Database Stack
  15. 15HolidayOps: Building a Working Days API for 250 Countries
  16. 16The Weekend Is Not a Constant
  17. 17MarketClock: A Trading Calendar That Shows Its Work
  18. 17Cybersecurity Trends: Protecting Data in the Digital Age
  19. 18The Day the Money Moves

Up next

Keep reading.

All 57 articles→
  1. 01

    HolidayOps: Building a Working Days API for 250 Countries

    How I built HolidayOps on my own: a Django and React platform that tells payroll, HR and logistics teams whether any date is a working day in any country, with company calendars, iCal feeds, signed webhooks and a public site that needs no JavaScript.

    Oct 18, 20269 minThe Engineering Logs

  2. 02

    BookMyMovie: Building a Cinema Ticketing Platform

    How I built BookMyMovie on my own, a Laravel, React and MySQL cinema booking platform with live seat maps, trailers, QR e-tickets that work offline, online payments and an Urdu interface: stack, architecture, data model, design, SEO, security, what broke and what I would change.

    Sep 29, 202617 minThe Engineering Logs

  3. 03

    GleanGrid: Building a Pre-Order Marketplace for Farmers Markets

    How I designed and built GleanGrid on my own, a Laravel and React marketplace where Hyderabad's farmers publish weekly stock and customers reserve it, pay online or at the stall, and collect it: architecture, data model, payments, security and UX.

    Sep 27, 202615 minThe Engineering Logs

  4. 04

    Zovita+: Building an Online Pharmacy That Adapts to Each Shopper

    How I rebuilt Zovita+, an online pharmacy with 1,186 real medicines, a 3D symptom body map, personal offers, drug-interaction warnings, refill reminders, pharmacist-reviewed prescriptions, Urdu, and card or cash payments, on Laravel, React and MySQL: stack, data model, checkout locking, payments, admin, security, SEO, testing, what broke and what I'd change.

    Oct 2, 202622 minThe Engineering Logs

  5. 05

    The Day the Money Moves

    When you buy a share, you don't own it the moment you click. A plain-language story of trade settlement, T+1 and T+2, why holidays in two countries can push a payment back a day, and what building MarketClock taught me about dates that have a history.

    Oct 24, 20264 minThe Engineering Logs

  6. 06

    The Discount That Knew You Were Hesitating: Rule-Based Personalisation in an Online Pharmacy

    How Zovita+ turns browsing into personal discounts without a machine-learning model: one visitor key for guests and customers, interaction counters, six offer rules, one pricing function for the bag and the charge, offers locked and redeemed once at checkout, guest-to-account merging, A/B tests, and the edge cases that shaped it.

    Oct 2, 202610 minThe Engineering Logs

Available for new work · --:--:-- PKT

Have an idea?

sales@ahmershah.dev
Book a call WhatsApp +92 370 4831994

On this site

  • 01About
  • 02Education
  • 03Certificates
  • 04Skills
  • 05Projects
  • 06Experience
  • 07Services
  • 08Testimonials
  • 09Contact

Pages

  • Projects
  • Blog
  • Saved articles
  • RSS
  • Privacy Policy
  • Terms of Service
  • llms.txt

Elsewhere · official profiles

26 links

Professional

Work history, code and credentials.

  • in/syedahmershah
  • company/syedahmershah
  • @ahmershahdev
  • syed-ahmer-shah
  • syed-ahmer-shah
  • u/syedahmershah
  • @syedahmershah
  • AWS@syedahmershah

Coding & credentials

Problem solving, verified badges.

  • u/syedahmershah
  • syedahmershah
  • users/syedahmershah
  • learner/syedahmershah

Google & business

The official listings.

  • Google Business Profileg.page
  • Syed Ahmer Shah
  • syedahmershah
  • Beaconssyedahmershah
  • syedahmershah

Social (@ahmershahdev)

Build logs, clips, threads.

  • @ahmershahdev
  • @ahmershahdev
  • @ahmershahdev
  • ahmershahdev
  • @ahmershahdev
  • @bluesky.ahmershah.dev
  • ahmershahdev

Design

Interfaces and visuals.

  • syedahmershah
  • syedahmershah

Direct

  • sales@ahmershah.dev

    New projects & quotes

  • support@ahmershah.dev

    Support & help

  • syedahmershahofficial@gmail.com

    Personal

  • +92 370 4831994

    Phone · WhatsApp

  • Hyderabad, Sindh, Pakistan

    Remote-first · Asia/Karachi (UTC+5)

Resume ↗
SYED AHMER SHAH

© 2026 Syed Ahmer Shah. All rights reserved.

PrivacyTermsRSS
ahmershah.dev