Skip to content

Latest commit

 

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Horizon

Horizon

Your balance, and what it is about to do next.

A native macOS menu bar app that reads your Investec account and forecasts where your balance is heading, with the reasoning shown.


macOS Swift SwiftUI License

Download · Report an issue


Most banking apps tell you what already happened. Horizon tells you what happens next. One glance, about two seconds: current balance, future balance, and what caused the change.

Horizon lives in the menu bar as a gauge ring and your live balance. Click it and the whole product is one popover. Every screenshot below is the real app, running against Investec's shared sandbox account rather than anyone's own money.



The balance, at a glance

Balance screen

The number you actually came for sits at the top, with a one word read on it: comfortable, getting tight, or low buffer. That word is not decoration, it comes from your projected minimum balance compared to your monthly commitments.

The three rings are the whole month compressed:

  • Buffer is how much of today's balance survives to the lowest point of the forecast. 36% means the dip takes roughly two thirds of it.
  • Payday counts down to the next income Horizon detected, and fills as the pay cycle progresses.
  • Spent is this month against what a normal month looks like for you. It turns red past 90%, which is the useful moment to know.

This month switches between the month total and a per day average, so "R19 360 spent" becomes "R968 a day versus a typical R579". The daily view is usually the one that explains the month.

Two things banks routinely blur, spelled out here instead:

  • Money spent but not posted. Card purchases sit as an authorisation for days, and some merchants only claim theirs in a weekly batch. Investec leaves these out of the transactions feed unless asked, so Horizon asks, and counts them. The headline is what is really yours once everything in flight lands, not what has merely cleared.
  • Credit that is not your money. On an account with a facility the headline is what you actually hold, which can be negative, with a line underneath saying how far into the facility you are and how much is still spendable. The forecast measures its buffer against the bottom of the facility rather than against zero.

Below it, the forecast curve and where it lands in 30 days.


Where the balance is heading

The ladder is the forecast in four numbers. Today, a week out, a fortnight, a month. If it only tells you one thing, it is whether the line goes up or down.

Financial outlook names the lowest point and the date it happens, because a month end balance can look healthy while the third week quietly goes to nothing. The projected minimum is the number that actually decides whether a purchase is safe.

What if? re runs the whole forecast with one thing changed and redraws the curve, with the original left behind as a dashed ghost line so you can see the difference rather than being told it. Spending R3 000 today, a salary landing three days late, cutting back 30%.

The comparison tracks the projected minimum, not the end balance. A late salary leaves the 30 day endpoint identical while making the dip much worse, so comparing endpoints would tell you it costs nothing, which is wrong.

The question mark opens the full arithmetic behind the number.

Future balance

Every month, then every day

Month cubes

A cube per month, showing what moved across it. The figure is signed, because a month is a change and not a balance: green gained, red used.

Hover one and the line above answers the question you actually had, which is what you were left with when the month ended. There is no historical balance endpoint, so that number is reconstructed by winding the transaction feed back off today's figure.

Months that are not finished cannot be reported as fact, so they carry a tilde and the hover splits the two halves apart: what has gone so far, and what is still expected. Months older than the transaction feed say so rather than quietly repeating the oldest balance Horizon happens to know.

Press a month and it opens into a cube per day.

  • Red is money out, green is money in.
  • Filled dots already happened. Hollow dots are expected, so the rest of the month is visibly a prediction rather than a fact.
  • Today is ringed in your accent colour.

Hover a day for what it used or gained. Press one and it opens below with the total and every line item, tagged where something is still pending or only expected.

This is the view that answers "why was last week so expensive" faster than a list of transactions ever does.

Day cubes and detail

Make it yours

Background follows the system, or you can pin it to light or dark.

Accent colour has six options. This is applied to the whole interface, including the forecast curve and the gauges.

Auto refresh picks how often Horizon pulls from Investec, from 5 to 60 minutes. There is also a refresh button in the header for right now.

Lock when closed puts Touch ID, or your login password, in front of the window. The menu bar opens on a single click, so this is what stops someone reading your balance off an unlocked laptop. It asks as the window opens and locks again as it closes, and it keeps the balance out of the menu bar too, since guarding the window while printing the number above it would protect nothing.

Balance includes credit is for accounts that report one figure with the overdraft already counted in. Tell Horizon the size of the facility and it subtracts it, leaving what is actually yours, and the forecast then measures how close you are to the bottom of the facility instead of to zero.

Account shows which account is connected, whether it is your own or the shared sandbox, and how many transactions the forecast was built from.

Disconnecting wipes the credentials out of the Keychain and returns the app to onboarding.

Settings

Connecting, and locking it down

Welcome

Choosing an account

IP allowlist step

Two ways in: the shared Investec sandbox to try it out, or your own account with keys from Investec Online, then Manage, then Investec Developer. Horizon ships with no credentials of any kind, so the sandbox route points you at Investec's documentation and asks you to paste their published test keys yourself.

There is no production or sandbox switch to get wrong. Your keys are treated as production, and if Investec rejects them there Horizon retries the sandbox host automatically.

Restrict the key to your IP is the step worth doing. Investec can limit an API key to specific addresses, so a leaked key is useless from anywhere else. Horizon looks up the public address this Mac appears as, gives you a copy button, and walks through where the setting lives. It also warns you about the catch: a changing address, a hotspot or a VPN will lock you out until the allowlist is updated.

When a connection fails, Horizon explains it instead of showing a status code. A 403 leads with the allowlist as the likely cause and offers your IP right there in the error.



How the forecast works

No black box. Every figure traces back to a step in ForecastEngine.swift:

  1. Start from the current available balance.
  2. Find recurring payments and income. A merchant only counts once it has fired three or more times on a steady interval (5 to 45 days). Regularity is scored, so a debit order sails through while noisy card spending at the same shop fails the test and is ignored. Without this, buying coffee often makes coffee a "subscription".
  3. Estimate everyday spending as the average non recurring outflow over 60 days.
  4. Lay the recurring events onto a calendar across the next 30 days.
  5. Add the estimated daily spend on top.
  6. Walk day by day to get a projected balance for every day.
  7. Find the lowest point, the number that actually matters.
  8. Surface the assumptions and any risks.

Scenarios re run the same pipeline with the event list nudged, so a scenario is always explainable in the same terms as the base forecast.

Which Investec data it uses

Investec Private Banking API, read only:

  • GET /za/pb/v1/accounts
  • GET /za/pb/v1/accounts/{id}/balance
  • GET /za/pb/v1/accounts/{id}/transactions

OAuth2 client credentials (Basic auth plus x-api-key, scope=accounts). Sandbox serves the token and the data from openapisandbox.investec.com; production serves both from openapi.investec.com. Mixing the two is the classic way to get an auth failure that looks like an empty account.

Horizon never calls a payment or transfer endpoint. Being native, it talks to Investec directly, so there is no proxy and no browser in the path.

What it assumes, and where it can be wrong
  • Recurring payments continue at their detected amount and cadence.
  • Everyday spending resembles the last 60 days on average.
  • The next salary lands on its detected cadence. Horizon predicts by interval rather than by calendar day, so a payday can drift a day or two.
  • One account is forecast at a time.

Forecasts are projections, not guarantees. The interface says projected and expected, never "you will have".


Security

  • Keys live in the macOS Keychain. Never in the app bundle, never on disk in the clear, never in this repo.
  • Read only. Horizon has no code path that moves money.
  • IP allowlisting is offered during setup so the key only works from your device.
  • The only request to anything other than Investec is the public IP lookup on the allowlist screen, which sends no account data.

Build it yourself

Requires macOS 14 or later and the Swift toolchain (Xcode or the Command Line Tools).

git clone https://github.com/Nevvyboi/Horizon.git
cd Horizon
./scripts/bundle.sh
open build/Horizon.app

scripts/bundle.sh builds a release binary with Swift Package Manager and wraps it in a proper .app. It is an agent app, so it lives only in the menu bar with no Dock icon and no entry in the app switcher.

Note that the build is ad hoc signed. macOS ties Keychain access to the code signature, so each rebuild will ask for Keychain permission again. A real signing identity removes that.


How it is put together

Sources/Horizon/
  HorizonApp.swift        MenuBarExtra entry point
  AppState.swift          loading, refreshing, scenario building, error reporting
  InvestecClient.swift    OAuth2 and the read only endpoints
  ForecastEngine.swift    recurring detection and the projection
  Keychain.swift          credential storage
  Unlock.swift            Touch ID and the locked window
  PublicIP.swift          the address to allowlist
  Models.swift            the shared shapes, including the balance arithmetic
  Money.swift             rand and date formatting
  Theme.swift             accent themes, appearance and stored settings
  GaugeMark.swift         the mark, drawn rather than shipped as artwork
  Components.swift        gauges, the forecast chart, shared rows
  RootView.swift          the balance screen and the screen switch
  FutureView.swift        the forecast, scenarios and the timeline
  ActivityCalendar.swift  the month and day cubes
  SettingsView.swift      settings
  OnboardingView.swift    connecting an account

What it will not do

  • Move money. No payments, transfers or trades. Read only, always.
  • Give financial advice. Scenarios are calculations, not recommendations.
  • Store your credentials anywhere but the Keychain.
  • Pretend a projection is a promise.

Licence

MIT. See LICENSE.

About

Your balance, and what it is about to do next. A native macOS menu bar app that forecasts where your Investec balance is heading.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages