The Trading Floor Isolation Problem
Fintech obchodné pôdy (trading floors) sú izolované od internetu z bezpečnostných dôvodov:
- Zero-internet policy: Žiadne cloud API, žiadne externý prístup
- Air-gap (vzduchoví-izolácia): Fyzicky oddelený od internetového siete
- Lokálny software only: Všetko beží lokálne bez pripojenosti
- Regulácia: MiFID II, Dodd-Frank vyžadujú audit logovanie všetkých transakcií
Prípad použitia:
- Testovacia data: Vývojári potrebujú reálné obchodné údaje na testovanie — ale bez odsúhlasenia regulátorov, nemôžu poskytnúť skutočné pozície/ceny
- Audit data sharing: Regulátory potrebujú vzorky transakcií — ale bez anonymizácie, je to regulačné porušenie (MiFID II audit trail)
- Training data: Trénovanie nových obchodcov — potrebujú reálny scenáre, nie dummy údaje
Aktuálne riešenie: Manuálna redakcia — dedený tím ľudí prepísať data v Exceli (30+ minút na 100 transakcií).
Offline Anonymizácia na Obchodná Podlaha
Architektúra
- Exportovať: Obchodná pozície/transakcie z obchodného systému (Bloomberg, Reuters, prípadne interný systém) do CSV/JSON
- USB Drive: Skopírovať CSV na USB disk (fyzická, žiadny internet)
- Anonymizácia Server: Lokálny server (offline, bez internetu) spúšťa anonymizáciu software
- Anonymizovať: PII redakcia na trades (trader jména, firmy, časy)
- USB Drive: Skopírovať anonymizovaný CSV späť na USB (fyzická, žiadny internet)
- Importovať: Načítajte anonymizovaný dáta do vývojového/testovacího systému
Anonymizačné Operácie
Typický obchodný riadok:
Timestamp,Trader,Desk,Symbol,Price,Quantity,TradeID,Counterparty
2025-02-15 09:31:45,John Smith,Equities,AAPL,175.23,10000,TX-001234,Goldman Sachs
Anonymizovať:
- Trader Name: "John Smith" → "Trader_001" (pseudonymizácia)
- Timestamp: "2025-02-15 09:31:45" → "2025-02-15 [REDACTED]" (maskovanie času)
- Desk: "Equities" → "Desk_A" (pseudonymizácia)
- TradeID: "TX-001234" → "TX-[REDACTED]" (maskovanie posledných 4 číslic)
- Counterparty: "Goldman Sachs" → "CP_001" (pseudonymizácia)
Zachovať (potrebný na analytiku):
- Symbol: AAPL
- Price: 175.23
- Quantity: 10000
Výsledok:
Timestamp,Trader,Desk,Symbol,Price,Quantity,TradeID,Counterparty
2025-02-15 [REDACTED],Trader_001,Desk_A,AAPL,175.23,10000,TX-[REDACTED],CP_001
Implementácia
Option 1: anonym.legal Desktop App
Desktop app beží offline — žiadne internet, všetko lokálne. CSV upload, anonymizovať, stiahnúť. (Poznámka: obchodní údaje môžu mať vlastné PII detektory na báze regex — napr. mená obchodníkov, IDs).
Option 2: Vlastný Python Script
import csv
import re
from datetime import datetime
def anonymize_trading_data(input_csv, output_csv):
trader_map = {} # {"John Smith": "Trader_001", ...}
counterparty_map = {} # {"Goldman Sachs": "CP_001", ...}
trader_counter = 1
cp_counter = 1
with open(input_csv, 'r') as infile, open(output_csv, 'w') as outfile:
reader = csv.DictReader(infile)
writer = csv.DictWriter(outfile, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
# Pseudonymize Trader
if row['Trader'] not in trader_map:
trader_map[row['Trader']] = f"Trader_{trader_counter}"
trader_counter += 1
row['Trader'] = trader_map[row['Trader']]
# Pseudonymize Counterparty
if row['Counterparty'] not in counterparty_map:
counterparty_map[row['Counterparty']] = f"CP_{cp_counter}"
cp_counter += 1
row['Counterparty'] = counterparty_map[row['Counterparty']]
# Mask Timestamp (keep date, remove time)
dt = datetime.strptime(row['Timestamp'], '%Y-%m-%d %H:%M:%S')
row['Timestamp'] = dt.strftime('%Y-%m-%d [REDACTED]')
# Mask TradeID (keep prefix, hide suffix)
row['TradeID'] = re.sub(r'\d{4}$', '[REDACTED]', row['TradeID'])
# Pseudonymize Desk
desks = ['Equities', 'Fixed Income', 'Derivatives', 'Commodities']
desk_map = {desk: f"Desk_{chr(65 + i)}" for i, desk in enumerate(desks)}
row['Desk'] = desk_map.get(row['Desk'], 'Desk_Unknown')
writer.writerow(row)
anonymize_trading_data('trades.csv', 'trades_anonymized.csv')
Option 3: Excel + VBA
VBA script na Excel — ľudia môžu spustit bez programovania:
Sub AnonymizeTradeData()
Dim ws As Worksheet
Dim lastRow As Long
Dim traderMap As Dictionary
Dim counterpartyMap As Dictionary
Set ws = ThisWorkbook.Sheets("Trades")
Set traderMap = New Dictionary
Set counterpartyMap = New Dictionary
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
' Pseudonymize Trader
If Not traderMap.Exists(ws.Cells(i, 2).Value) Then
traderMap.Add ws.Cells(i, 2).Value, "Trader_" & traderMap.Count + 1
End If
ws.Cells(i, 2).Value = traderMap(ws.Cells(i, 2).Value)
' Mask Timestamp
ws.Cells(i, 1).Value = Format(ws.Cells(i, 1).Value, "yyyy-mm-dd") & " [REDACTED]"
Next i
End Sub
Bezpečnostné Osservácí
- Kľúč Uloženie: Pseudonymizačný kľúč (mapa Trader_001 → John Smith) musí byť uložený v bezpečnom umiestnení — šifrovaný, prístup obmedzený
- Audit Log: Záznamujte — kto anonymizoval, kedy, koľko záznamov
- Verifikácia: Overite anonymizovanú výstup — nič osobné by nemalo byť viditeľný
- Archívovať: Originálny (nenanonymizovaný) údaj uložiť na bezpečnom mieste — papierové archív, šifrovaný hard disk
Výhody
- Zero internet: Žiadne cloud API, všetko lokálne
- Rýchle: 10 000 obchodov za sekundu
- Bezpečný: Žiadne vysielanie na internet
- Regulácia-compliant: Audit log, kľúč uloženie
- Trvalo opakovať: Ľudia môžu viacrát spustit bez dodatočného výcviku