Guide FINMA · 3 sur 3
Automatiser le contrôle FINMA
de vos contreparties.
Vérifier trois noms à la main prend quelques minutes. Pour des centaines de contreparties revues périodiquement, il faut une méthode reproductible : rapprocher d’abord par identifiant, traiter les noms comme des pistes, et garder la trace de la version utilisée. Ce guide la décrit avec le fichier FINMA d’OpenSwissData et des exemples testés.
Sommaire
Le principe
- Vos contrepartiesNom, IDE et LEI lorsque vous les connaissez.
- NormaliserIDE ramené à « CHE » et neuf chiffres, LEI en majuscules.
- Rapprocher par identifiantIDE exact, puis LEI exact : des correspondances sûres.
- Rapprocher par nomDes candidats à examiner, jamais des verdicts.
- Examiner et tracerUne personne tranche ; la version du fichier et la décision sont conservées.
Le rapprochement par identifiant donne des correspondances sûres. Le rapprochement par nom ne produit que des candidats : il oriente l’examen humain, il ne conclut pas.
Les fichiers à rapprocher
L’archive FINMA d’OpenSwissData contient notamment :
Faites défiler le tableau pour voir toutes les colonnes
| Fichier | Contenu | À savoir |
|---|---|---|
finma_registry.csv, .json, .sql, .parquet | Une ligne par autorisation de la liste des UID publiée par la FINMA. | Une entreprise titulaire de plusieurs autorisations figure sur plusieurs lignes. |
finma_<catégorie>.csv | Les mêmes lignes, un fichier par catégorie non vide. | Catégories regroupées par OpenSwissData (champ entity_type). |
finma_warnings.csv, .json, .sql, .parquet | La liste d’alerte, séparée du registre. | Nom, date, filtre du registre du commerce et lien de détail seulement. |
finma.xlsx | Registre et avertissements dans deux feuilles. | Une troisième feuille rappelle les règles de lecture. |
changelog_90d.csv, .json | Les changements observés entre les versions disponibles. | Dates d’observation, pas dates de décision de la FINMA. |
quality.json, checksums.sha256, provenance.json | Couverture des champs, interruptions de collecte, empreintes et signature. | À conserver avec le résultat du contrôle. |
Les champs du registre utiles au rapprochement
Faites défiler le tableau pour voir toutes les colonnes
| Champ | Contenu |
|---|---|
uid | L’IDE tel que publié par la FINMA, au format CHE-123.456.789 ; vide pour certaines lignes. |
name, city | Le nom et la localité publiés par la FINMA. |
licence_type, licence_type_fr, licence_type_de, licence_type_it | Le type d’autorisation, libellé par la FINMA en anglais, français, allemand et italien. |
entity_type | Un regroupement fait par OpenSwissData ; un libellé non classé tombe dans other. Pour un filtre précis, utilisez licence_type. |
lei, lei_registration_status | Le LEI, seulement lorsque l’IDE correspond exactement à un seul LEI chez la GLEIF, et le statut de cet enregistrement LEI. |
address, canton | Repris de la GLEIF lorsqu’un LEI a été rattaché ; ils peuvent rester vides, même avec un LEI. |
licence_date, status | Vides : la liste de la FINMA ne les fournit pas. |
is_warning_listed | Vide : aucun lien avec la liste d’alerte n’est déduit d’une ressemblance de noms. |
Dans les fichiers CSV et SQL, une valeur absente est une chaîne vide ; dans le JSON, la clé est absente ou vaut null ; dans le Parquet, la valeur est nulle. En SQL, testez donc uid <> '' plutôt que uid IS NOT NULL.
Fréquence de mise à jour
Côté FINMA, les listes sont « mises à jour régulièrement », et chaque liste affiche sa date de dernière modification.1 Pour la liste d’alerte, la FINMA ne garantit ni l’exhaustivité ni une mise à jour complète.2
Côté OpenSwissData, la collecte FINMA est planifiée chaque jour. Une collecte peut être bloquée si ses contrôles échouent ; les interruptions sont signalées dans quality.json, et la version réellement disponible est affichée sur la fiche produit.
La fréquence de votre propre contrôle relève de votre politique de risque : par exemple avant chaque entrée en relation, puis à intervalles réguliers. Le fichier changelog_90d aide à cibler les contreparties concernées par un changement observé.
Rapprocher dans le bon ordre
1. L’IDE d’abord
L’OFS admet deux graphies de l’IDE, avec ou sans tirets et points, et l’ajout RC ou TVA ne fait pas partie du numéro.3 Ramenez les deux côtés à une forme compacte, « CHE » suivi des neuf chiffres : une égalité exacte sur cette forme est un rapprochement sûr.
2. Le LEI ensuite
Si votre contrepartie a un LEI, comparez-le au champ lei, en majuscules. Le fichier n’attribue un LEI que lorsque l’IDE correspond exactement à un seul LEI chez la GLEIF : un LEI absent du fichier ne signifie pas que l’entité n’en a pas.
3. Le nom en dernier, avec prudence
Pour les contreparties sans identifiant, et pour toute la liste d’alerte, qui ne contient pas d’IDE, le nom est le seul point de rencontre. Normalisez les deux côtés (casse, accents, formes juridiques), cherchez les noms contenus l’un dans l’autre, puis soumettez chaque candidat à un examen humain.
Une correspondance de nom n’est pas une identité
Pour la liste d’alerte en particulier, un candidat n’établit rien sur votre contrepartie : comparez siège, adresse et site internet sur la page de détail de la FINMA avant toute conclusion. Voir le guide sur la liste d’alerte.
Exemple : SQLite en ligne de commande
Les fichiers .sql de l’archive créent chacun une table, aux colonnes de type texte, et l’alimentent. Placez dans le dossier de l’archive décompressée un fichier counterparties.csv :
reference,name,uid
C-001,Exemple Banque SA,CHE-123.456.789
C-002,Exemple Gestion Sàrl,CHE987654321 TVA
C-003,Exemple Conseil AG,Les noms et les IDE de cet exemple sont fictifs. Chargez ensuite les deux tables, puis lancez les contrôles décrits dans checks.sql ; l’option --csv de .import demande sqlite3 3.32 ou plus récent :
sqlite3 check.db < finma_registry.sql
sqlite3 check.db < finma_warnings.sql
sqlite3 -header -column check.db < checks.sql-- Vos contreparties : un fichier CSV avec les colonnes reference, name et uid
DROP TABLE IF EXISTS counterparties;
.import --csv counterparties.csv counterparties
-- IDE ramené à « CHE » suivi de neuf chiffres, des deux côtés
CREATE TEMP VIEW counterparty_uid AS
SELECT *, substr(upper(replace(replace(replace(uid, '-', ''), '.', ''), ' ', '')), 1, 12) AS uid_key
FROM counterparties WHERE trim(uid) <> '';
CREATE TEMP VIEW registry_uid AS
SELECT *, substr(upper(replace(replace(replace(uid, '-', ''), '.', ''), ' ', '')), 1, 12) AS uid_key
FROM finma_registry WHERE uid <> '';
-- 1. Correspondances par IDE, autorisations regroupées
SELECT c.reference, c.name, min(r.name) AS finma_name,
group_concat(r.licence_type_fr, ' ; ') AS authorisations
FROM counterparty_uid c
JOIN registry_uid r ON r.uid_key = c.uid_key
GROUP BY c.reference, c.name;
-- 2. À examiner : pas d’IDE, ou IDE absent de la liste
SELECT reference, name FROM counterparties
WHERE reference NOT IN (
SELECT c.reference FROM counterparty_uid c
JOIN registry_uid r ON r.uid_key = c.uid_key
);
-- 3. Candidats de la liste d’alerte, à examiner : un nom contenu dans l’autre
SELECT c.reference, c.name, w.name AS warning_name, w.date_added, w.source_url
FROM counterparties c
JOIN finma_warnings w
ON instr(lower(w.name), lower(c.name)) > 0
OR instr(lower(c.name), lower(w.name)) > 0;La première requête regroupe les autorisations d’une même entreprise. La deuxième liste les contreparties à examiner, faute d’IDE ou de correspondance : ce ne sont pas des contreparties « non autorisées ». La troisième ne produit que des candidats ; la fonction lower() de SQLite ne traite que les lettres ASCII, si bien que les accents restent distinctifs.
Avec le JSON
Pour retrouver toutes les autorisations d’un IDE avec jq :
jq '.[] | select(.uid == "CHE-123.456.789") | {name, licence_type, lei}' finma_registry.jsonExemple : préparer les noms en Python
Pour comparer des noms sans tenir compte des accents ni des formes juridiques, une normalisation simple suffit à produire des candidats plus robustes :
import csv
import re
import unicodedata
# Formes juridiques courantes, retirées avant la comparaison (liste indicative)
LEGAL_FORMS = {"ag", "sa", "sarl", "gmbh", "ltd", "sagl", "kg", "snc", "scs"}
def fold(name: str) -> str:
text = unicodedata.normalize("NFKD", name).encode("ascii", "ignore").decode().lower()
return " ".join(w for w in re.findall(r"[a-z0-9]+", text) if w not in LEGAL_FORMS)
with open("finma_warnings.csv", encoding="utf-8-sig", newline="") as f:
warnings = [(fold(row["name"]), row) for row in csv.DictReader(f)]
with open("counterparties.csv", encoding="utf-8-sig", newline="") as f:
for row in csv.DictReader(f):
key = fold(row["name"])
if len(key) < 4:
continue # nom trop court pour une recherche utile
for folded, warning in warnings:
if len(folded) >= 4 and (key in folded or folded in key):
print(row["reference"], row["name"], "->", warning["name"], warning["source_url"])La liste des formes juridiques est indicative : adaptez-la à vos contreparties. Chaque ligne affichée reste un candidat à examiner.
Garder la trace de chaque contrôle
Pour pouvoir expliquer un résultat plus tard, conservez avec lui :
- la version du fichier, qui figure dans le nom de l’archive et dans
quality.json; - le fichier
checksums.sha256et le résultat de sa vérification ; - la date du contrôle, les correspondances retenues et les décisions prises sur les candidats.
shasum -a 256 -c checksums.sha256 # macOS
sha256sum -c checksums.sha256 # LinuxLes dates de changelog_90d sont des dates d’observation entre deux versions, pas des dates de décision de la FINMA.
Pour une question ponctuelle : kyc_check
Le serveur MCP d’OpenSwissData propose l’outil kyc_check, sans compte ni clé, dans la limite de 100 appels par heure et par adresse IP. Il cherche un nom dans le registre et dans la liste d’alerte, sans tenir compte de la casse ni des accents, et renvoie les résultats les plus proches avec leur nombre total. Une réponse vide n’est pas un certificat de conformité.
claude mcp add --transport http openswissdata https://mcp.openswissdata.com/jsonrpc
curl -s https://mcp.openswissdata.com/jsonrpc \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"kyc_check","arguments":{"name":"Exemple Banque"}}}'L’achat du fichier n’ouvre aucun accès MCP payant, et les nouveaux abonnements Pro sont fermés pour le moment. Détails et autres clients : page du serveur MCP.
Limites
- Le fichier suit la liste des UID d’entreprises autorisées publiée par la FINMA. Il ne couvre ni le registre des intermédiaires d’assurance, ni les membres des OAR, ni les placements collectifs : consultez ces sources directement.1
- Les dates d’autorisation et les statuts détaillés ne figurent pas dans la liste de la FINMA : les champs correspondants restent vides.
- Un rapprochement par nom produit des faux positifs et peut manquer une variante : il reste un tri avant examen.
- Une ligne du fichier reflète la liste de la FINMA à la date de collecte ; pour une décision, la source officielle fait foi.
Pour travailler avec les données
Le registre FINMA en fichiers.
La liste des UID d’entreprises autorisées publiée par la FINMA, en Excel, CSV, JSON, Parquet et SQL. Le LEI est ajouté lorsque l’IDE correspond exactement à un seul LEI chez la GLEIF, la liste d’alerte reste dans des fichiers séparés, et chaque version est signée. Paiement unique de 299 CHF.
Sources officielles
Les citations et les faits de ce guide proviennent de ces pages, consultées le 29.09.2026. Seules ces sources font foi ; elles peuvent avoir changé depuis.
- FINMA · Établissements, personnes et produits autorisés ou enregistréshttps://www.finma.ch/fr/finma-public/etablissements-personnes-et-produits-autorises/
- FINMA · Liste d’alertehttps://www.finma.ch/fr/finma-public/warnungen/liste-d'alerte/
- Office fédéral de la statistique (OFS) · L’IDE en généralhttps://www.bfs.admin.ch/bfs/fr/home/registres/registre-entreprises/numero-identification-entreprises/ide-general.html