When BES (Bireysel Emeklilik Sistemi) was designed, the entire reporting apparatus — state contribution calculations, EGM submissions, participant statements, actuarial reconciliations — assumed a single denomination: Turkish Lira. Every column in every table, every rounding rule in the regulation, every reconciliation script written by every pension company in this country carries that assumption like a load-bearing wall.
Then fund managers started offering foreign-currency-denominated funds inside BES contracts. USD funds. EUR funds. Gold funds priced against USD-per-ounce. From a product perspective, this is a diversification story. From a pipeline perspective, it is a category error the schema was never designed to represent.
The Assumption That Breaks First
In a TL-only world, a participant's contribution has exactly one value at any point in time. You store the payment amount, you store the NAV at the trade date, you compute units purchased, and every downstream report — state contribution eligibility, vesting, tax withholding at exit — reads from that same denominated ledger.
Add a USD-denominated fund and you now have three values for the same contribution:
- The TL amount the participant actually paid
- The USD-equivalent value at the trade date FX rate used by the custodian to buy units
- The TL re-valuation at report date, which is what EGM and the tax office want to see
These are not the same number. They are not even the same number in the same direction. And crucially, only the first one is stable over time.
Why State Contribution Calculations Get Weird
The 25% (or currently 30%) state contribution is legally defined against the TL amount paid. That part is unambiguous. Where it gets messy is at the reporting boundary: the state contribution accrues to units of the fund the participant selected. If that fund is USD-denominated, you are now holding a TL-defined liability against a USD-denominated asset position.
A concrete failure I have seen more than once:
- Participant contributes 10,000 TL on day T, allocated to a USD fund
- USDTRY at T = 32.00, so the custodian purchases units worth roughly $312
- State contribution of 3,000 TL accrues, allocated to the same USD fund at T+n
- USDTRY at T+n = 33.50
- Reporting job runs at month-end and revalues everything at 34.10
Which FX rate applies to which leg of that transaction in the participant statement? The regulation says one thing (TL nominal), the custodian's books say another (USD units held), and the EGM submission wants a third thing (report-date TL equivalent). If your pipeline stores a single amount_try column, you cannot reproduce any of these three numbers a week later without recomputing the FX chain from scratch.
The Versioning Problem Nobody Warned You About
This is the part that catches every team the first time. TL-denominated pipelines are effectively idempotent — you can rerun yesterday's job and get yesterday's numbers because the inputs don't move. Introduce FX and the inputs move continuously, but your pipeline was never designed to record which FX snapshot produced which row.
Specifically, most reporting stacks I have audited fail on at least three of these:
- No FX snapshot table. They call the CBRT rate at job runtime instead of storing the rate used for each historical transaction.
- No distinction between transaction-date FX and report-date FX. Both get overwritten by the latest pull.
- Corporate actions on foreign funds (dividends, splits, fund mergers) are recorded in units but not in the FX rate that applied at the corporate action date.
- Reconciliation with the custodian's NAV file uses one rate; reconciliation with EGM uses another; nobody documents which.
The symptom is a participant statement that reconciles to the custodian but not to EGM, or vice versa. The root cause is that you have one FX column doing the work of three.
What the Regulation Actually Requires vs. What Your Schema Assumes
Read the SPK and EGM technical specifications carefully and you will find that the regulation is more sophisticated than the pipeline. It distinguishes:
- Katılım payı — the TL amount, immutable, denominated at payment date
- Fon değeri — the fund value, which for foreign funds is a derived number requiring an FX conversion at report date
- Devlet katkısı hakediş tutarı — state contribution entitlement, TL-defined but accruing to units
Most internal schemas collapse these into two columns: contribution_amount and current_value. That works perfectly in a TL-only universe. It is structurally incapable of representing a USD fund position without lossy conversion at write time — which means the moment somebody asks "what was this participant's balance on the last day of Q2 for tax purposes," you are recomputing from FX history you may or may not have preserved correctly.
What Actually Works
Having been through this migration on the operations side, the pattern that survives contact with auditors looks like this:
- Store the native denomination explicitly. Every fund position row carries
native_currency,native_amount, andnative_nav. TL becomes just another currency, not the default. - Snapshot FX rates with the transaction, not at query time. A dedicated
fx_rate_snapshotstable keyed by (currency_pair, effective_date, source) — CBRT, TCMB alış/satış, custodian mid — with all three preserved. - Compute TL-equivalent as a view, never as stored data. The moment you materialize a TL number, you have committed to a specific FX interpretation and lost the ability to answer alternative questions.
- Separate transaction-date valuation from report-date valuation in the schema. These are different business concepts. Do not let them share a column.
- Treat state contribution as a TL-native liability with a unit-denominated realization. Two ledger entries, linked, not one hybrid row.
The Meta-Point
Multi-currency funds inside BES are not an FX problem. They are a temporal versioning problem wearing an FX costume. The pipeline was built assuming that a contribution has one true value; foreign-denominated funds prove it has at least three, and which one is "true" depends on who is asking — the participant, the custodian, the tax office, or EGM.
If your reporting stack treats currency as a formatting concern rather than a first-class dimension of the data model, you will spend the rest of the product's life patching reconciliation breaks that look like FX bugs but are actually schema debt. The fix is not a better rate source. The fix is admitting that TL was always a currency, not the absence of one.