Every BES pipeline I have inherited treats fund lifecycle as symmetric. New fund appears, you add a row to the product master, you extend the NAV feed, you accept the first buy orders. Fund disappears, you assume the mirror operation applies. It does not. Closure is not the inverse of inception — it is a fundamentally different class of event, and pipelines that were architected around the happy path of onboarding will crack in ways that only surface weeks later, usually during a HAYMER reconciliation or a EGM audit.
What Actually Happens When a Fund Closes
When the portföy yönetim şirketi decides to close or merge a fund — and this happens more often than product teams admit, especially with sub-scale funds under 50M TL AUM — a sequence fires that your pipeline was never asked to model:
- The fund receives a closure date from the SPK filing, usually 30 days out.
- Every participant holding units must be forcibly switched to a target fund, either chosen by the participant during the notice window or defaulted per the sözleşme rules.
- The last NAV is published, and then the ISIN is retired.
- The fund code remains in your historical tables forever, but it no longer resolves against any live feed.
- Every HAYMER submission, every GEV file, every EGM report that references the closed fund's historical positions must still reconcile — against a product that legally no longer exists.
That last point is where most pipelines fail silently.
The Dangling Pointer Problem
Your NAV table has a foreign key to your fund master. Your position table has a foreign key to your NAV table. Your daily valuation joins across both. When a fund closes, the naive approach is to mark the row is_active = 0 and move on. The next morning, your daily job runs, and every historical position that ever touched that fund now joins against a row your ORM filters out by default.
I have seen this exact bug in production three times across different BES operators. The symptoms are always the same:
- Historical performance reports show sudden gaps for participants who held the closed fund years ago.
- Reconciliation totals drift by amounts that look random until you trace them to a single retired ISIN.
- The HAYMER submission passes format validation but fails cross-check because the aggregate position report cites units under a fund code the regulator's own master no longer contains.
The fix is architectural, not tactical. Closed funds need to remain queryable as first-class entities with a distinct lifecycle state — closed_pending_switch, closed_reconciling, closed_archived — and every downstream join must be aware of which state applies at the reporting date, not the query date.
Forced Switch: The Event Your Position Ledger Wasn't Designed For
A forced switch is not a participant-initiated transaction. It has no signed instruction, no channel of origin, no user identifier in the audit trail. It is a bulk operation executed by the operator on behalf of thousands of participants simultaneously, and it must be recorded with a transaction type most legacy ledgers do not have.
In one migration I worked on, the source system had recorded 12 years of forced switches as ordinary FON_DEGISIM transactions with a synthetic user ID of SYSTEM. This looked harmless until we tried to reconstruct the participant's actual choice history for a complaint investigation. There was no way to distinguish a switch the participant requested from one imposed by fund closure. The regulator does distinguish, and so does the participant when they call.
Design the transaction type from day one:
FORCED_SWITCH_CLOSUREwith a mandatory reference to the closure decision document.- The target fund selection method: participant-chosen during notice window, default-applied, or migrated per merger clause.
- The NAV used for the switch, which is the closure NAV, not the trade date NAV.
HAYMER and GEV: Reconciling Against a Product That No Longer Exists
Here is where the pipeline burden compounds. HAYMER submissions are cumulative — they cite historical positions on reporting dates. If a participant held Fund A on 31 December of the previous year, and Fund A closed in March of the current year, your year-end HAYMER for the current year still needs to reference Fund A when computing carry-forward calculations, transfer histories, and getiri attribution.
GEV reporting is worse because it operates at product granularity. The moment a fund's ISIN is retired, GEV templates that were valid last quarter reject the row. You now have to submit historical data under a decommissioned product code, and the validation logic on the receiving end may or may not accommodate that depending on when EGM last updated their master.
Practical mitigations that actually work:
- Maintain a parallel fund master snapshot dated to each reporting period, not a single live master.
- Version every reference table that HAYMER or GEV touches, and let the submission job pin to the version valid on the reporting date.
- Never delete a fund from the master. Ever. Add closure metadata and freeze the row.
The Participant-Level Fallout
The operational failures are visible. The participant-level failures are quieter and take longer to surface. A participant who held a closed fund for six years will, at some point in the future, ask for a statement covering that period. If your statement engine cannot render the closed fund with its historical NAVs, its closure notice, and the switch that followed, you are going to have a call center problem and eventually a complaint that reaches SPK.
The statement engine must be able to say, in effect: on this date you held X units of a fund that closed on this date, was switched to this fund at this NAV, and here is the continuous performance line across both. Building that after the fact, from a pipeline that treated closure as a delete, is enormously expensive.
What to Build Before You Need It
If you are architecting a BES pipeline today, or refactoring one, treat fund closure as a first-class event with the same design attention you gave to fund inception:
- A closure workflow that spans the SPK notification, the participant notice window, the forced switch execution, and the post-closure archival state.
- Immutable historical fund records with lifecycle state, never a soft-delete flag masquerading as one.
- Regulatory submission jobs that pin to date-valid reference snapshots, not live masters.
- A dedicated forced-switch transaction type with regulatory provenance.
- Statement rendering that treats closed funds as valid historical entities.
Fund inception is a row insert. Fund closure is a distributed transaction that touches every layer of your platform, spans months of calendar time, and leaves permanent artifacts in every regulatory file you will ever submit. The pipelines that handle it well are the ones that stopped assuming symmetry a long time ago.