Case study · Web app
Yatırım Aklı
An AI-assisted portfolio tracker that explains what the numbers mean.
Portfolio trackers show numbers but not what they mean: a beginner sees a profit figure and has no idea how risky the portfolio is or how concentrated it has become.
Yatırım Aklı calculates returns and risk in code and has Gemini turn those metrics into a plain-language report. It began as a demo with known problems; I audited it, logged 42 issues and fixed them in order. The backend now passes 612 automated tests.
- 612 backend tests passing in CI, on a real PostgreSQL
- 42 logged issues, audited and fixed in order
- ~0.6 s until the first words of a streamed chat answer
- Year
- 2026
- Role
- Developer, end to end
- Team
- Built during my internship at Amasya Şeker
- Built with
- Links
01
The challenge
An investor who holds a dozen stocks across two currencies cannot easily tell how much of the portfolio sits in one sector or how volatile it is. Spreadsheets give the figures; they do not give the reading.
It was hard because the data is messy. Exchanges close on different days, Borsa Istanbul symbols need a suffix, London prices come in pence, positions are held in different currencies, and the free price source is slow and rate limited. An AI report is only worth reading if the numbers underneath are right.
Constraints
- Gemini’s free plan limits how many requests the app can make
- The app gives no investment advice, only readings of the user’s own data
02
My part
-
Designed and built the whole application: a FastAPI backend, a React interface and a PostgreSQL database, packaged with Docker Compose.
-
Audited the first version, logged every problem as a numbered issue and fixed them in dependency order, starting with a test base.
-
Built the finance engine with a time-weighted return, a covariance-based volatility, the Sharpe ratio and price series aligned by date across exchanges.
-
Added the Gemini assistant with portfolio and risk reports, a what-if simulator, rebalancing suggestions and a chat that streams over Server-Sent Events.
-
Secured sign-in with short-lived access tokens kept in memory and rotating refresh tokens in an httpOnly cookie, plus rate limits.
-
Made price alerts fire from a periodic server task, and gave the interface light and dark themes, Turkish and English, and checked text contrast.
03
Key decisions
-
One Gemini call per request, not a swarm of agents
- Chose
- Every AI feature makes a single call that receives the portfolio and its calculated metrics.
- Why
- The first description spoke of several cooperating agents, but the code never did that. I deleted the agent classes and corrected the README and the interface to match what the app really does. A single call is faster, cheaper and easier to debug.
-
Calculate on the server, let the model only interpret
- Chose
- Returns, volatility, Sharpe ratio, allocation and profit and loss are computed in code and handed to the model as facts.
- Why
- A language model should not do arithmetic, and a wrong figure in a report erodes trust faster than anything else. If Gemini fails, the user sees an honest error; no error text is ever saved as a report.
-
A time-weighted return instead of a simple one
- Chose
- Performance is measured as a time-weighted return from the trade history and daily closes, the method the GIPS standard uses.
- Why
- The old chart counted every purchase as a gain. For the same portfolio it showed +236%, while the time-weighted return is −3.74%.
04
Results
The application works end to end: portfolios and trades, profit and loss across currencies, performance against an index, risk metrics, alerts and the Gemini reports. In CI the backend passes 612 tests on a real PostgreSQL, the interface passes 38 component tests and 44 logic tests, and ESLint reports nothing.
It is still a prototype and not deployed yet. The production setup with HTTPS is ready, notifications stay inside the app, and currency moves are not yet part of profit and loss for foreign positions. These limits are written down in the repository.
- The full source is private; a public showcase repository holds the documentation, screenshots and selected code samples.
- The accessibility check covered both themes and both languages; all 8 findings were fixed.
Have a problem like this one?
Tell me what you are working on and I will get back to you.
kilichalit103@gmail.com