CashCast
Every bank branch is guessing how much cash it needs next week. Most guess high — because running out is worse than wasting. CashCast stops the guessing.
// the problem
“A branch manager orders cash based on last week and a gut feeling. She always adds 20% extra — because running dry is a customer service disaster. That extra 20% sits in a vault earning nothing.”
Every branch and ATM needs cash restocked regularly, and most over-order to be safe. One widely quoted estimate puts idle vault cash at $4.2 billion a year across the industry (I have not verified it). That cash earns nothing while it sits there, which has a real cost when interest rates are high.
The reason banks over-order is simple: there's no system to predict demand accurately at the branch level. Cash demand isn't random — it spikes on paydays, falls on cold rainy days, surges before holidays, and follows a clear weekly pattern. All of that is in the transaction history. CashCast reads it.
problem → numbers (quoted from the project README, not independently checked)
// how it works
1. Turn each date into useful clues
From the date and recent history, the model gets 17 clues: day of week, day of month, whether it is a Friday, a payday (the 1st and 15th) or the day before one, withdrawals a week and two weeks earlier, and recent averages. Days are encoded in a circle so that Sunday sits next to Monday instead of at the far end.
2. One simple model per branch
Each branch gets its own model, trained on 730 days of history (the oldest 80%) and checked against the newest 20%. I used a simple, fast model type (ridge regression) that copes well when clues overlap. Its average error on that held-back 20% feeds the confidence score on the dashboard.
3. Spot unusual days
After training, the model predicts the whole history and looks at its misses: days when reality was far from the prediction. Those unusual spikes or drops are flagged as markers on the dashboard and in the order table.
4. Forecast + order recommendation
A 14-day forecast with a range around it, wider for branches with bumpier demand. The recommended order is the top of that range plus 10%, rounded to the nearest $1,000. This replaces the flat 20% buffer with one that changes every day.
// ML pipeline per branch
example screen: BRK-001, generated data
MAPE
8.4%
Confidence
91.6%
Anomalies
4
Idle saved
$2.1K/wk
// what operators actually see
- →6 branch health cards show vault level, forecast confidence, and anomaly status at a glance — no login required to check if a branch is about to run low
- →Click any branch card to pull up 90 days of history overlaid with the 14-day forecast and shaded confidence band — one chart, no pivot tables
- →Weekly demand pattern bar chart shows which days are heavy (Friday, paydays) vs light (Sunday) — so order schedules can be timed better
- →Order recommendation table gives a specific dollar amount per day for the next 7 days, with confidence percentage, instead of 'last week +20%'
- →A plain-English summary of the outlook (above or below normal, peak day, idle cash risk), written by simple rules in the code rather than an AI model
- →Anomaly flags appear on both the chart (X markers) and a dedicated panel — unusual demand days are visible before they cause a gap
// ops dashboard (sample numbers on generated data)
Branch Intelligence Dashboard
Plotly.js + FastAPI — branch health cards, 14-day forecast with confidence bands, per-branch order recommendations, anomaly flags, AI narrative
Branches
6
Avg MAPE
9.1%
Total Rec
$867K
Horizon
14d
Anomalies
2
High Risk
1
// 14-day demand forecast — BRK-01 Downtown (with confidence band)
// per-branch order recs
// AI narrative — BRK-01
“14-day demand +18% above 90d median. Peak Thu Mar-19 at $52K. 1 anomaly flagged Mar-11.”
// branch health overview
BRK-01
$312K
healthy
BRK-02
$198K
healthy
BRK-03
$87K
low
BRK-04
$445K
healthy
BRK-05
$52K
risk
BRK-06
$231K
healthy