Import : traitements et conversions
Cette page est la référence de tout ce que la solution fait des fichiers d’une situation : comment chaque fichier et chaque colonne sont lus, convertis (dates, nombres, taux, bases, sens, devises, fréquences), complétés par défaut ou déduits, et ce qui est signalé, rejeté, ignoré ou écarté. Elle décrit le format Fichiers Crédit Logement (CREDIT_LOGEMENT), le seul disponible aujourd’hui.
Elle complète, sans les répéter, Import d’une situation ALM (les écrans et la composition d’une situation), Import Crédit Logement (le mapping livré et les choix propres aux extractions du Crédit Logement) et Configuration client (le fichier de mapping). Les valeurs complétées par défaut sont toutes reprises, avec l’avertissement qui les signale, dans les Règles de valeurs par défaut.
Comment lire cette page. Chaque section se termine par une mention Source qui nomme les classes du code où la règle est appliquée (risk-app et ses bibliothèques, dont risk-import), pour pouvoir tenir la page à jour. Une affirmation qui n’a pas pu être vérifiée dans le code est marquée (à confirmer). Les noms de colonnes donnés en exemple sont ceux du mapping livré mapping-credit-logement.json ; un autre mapping peut nommer d’autres colonnes, les règles restent les mêmes.
1. La chaîne de traitement
Tout l’import se fait dans risk-app : la lecture des fichiers, leur conversion et leurs contrôles sont ceux de la bibliothèque risk-import (com.mla.reglab:risk-import), le code de lecture qu’utilisait auparavant le moteur de calcul. Le moteur (risk-engine) ne reçoit plus aucun fichier : il calcule chaque run à partir de son entrée, que risk-app assemble au lancement (Entrée d’un run).
| Étape | Où | Ce qui est fait | Ce qui est refusé |
|---|---|---|---|
| 1. Dépôt | risk-app | Import par archive : chaque archive déposée devient une tâche d’import. Import guidé : chaque fichier est rangé dans son emplacement. Le fichier est enregistré dans le stockage objet (§1.6). | Fichier vide ; archive qui n’est pas un zip (contenu détecté sur les octets, pas sur le nom) ; fichier guidé dont le contenu n’est pas celui de l’emplacement (§1.1). |
| 2. Décompression | risk-app | L’archive est décompressée avec des limites (§1.2). | Archive trop grosse, trop d’entrées, trop compressée, trop imbriquée. |
| 3. Rôle de chaque fichier | risk-app (risk-import) |
Rôle donné par la demande d’import : emplacement de l’import guidé, situation.json ou fileRoles de l’API (§1.3). |
Fichier d’un rôle obligatoire non déclaré : l’import échoue (IMP-061). |
| 4. Contrôle fichier par fichier (import guidé) | risk-app (risk-import), pendant le dépôt |
Chaque fichier est lu seul avec la configuration client, dans la requête même du dépôt : la réponse porte son statut définitif, ses anomalies et son résumé (§1.4). | Rien n’est importé à ce stade. |
| 5. Import | risk-app (risk-import), en tâche de fond |
Ordre : contexte d’évaluation (courbes) → classification → flux préfixés → opérations → balance → postes modélisés. La tâche d’import en donne l’avancement (§1.5). | Voir les causes d’échec ci-dessous. |
| 6. Contrôles de cohérence | risk-app (risk-import) |
Validation du portefeuille, des opérations et du contexte (§10, type ConstraintViolation). |
Rien : l’objet en défaut est conservé, l’anomalie est son seul signal. |
| 7. Enregistrement | risk-app | Contexte, portefeuille et opérations sont enregistrés ensemble. | Échec d’enregistrement : la tâche passe FAIL. |
Échec ou succès. Un import n’échoue (FAIL) que sur un problème qui empêche de construire la situation : archive vide ou illisible, arrêté absent de la demande (IMP-059), configuration sans classification ou sans modèles d’écoulement (IMP-055), fichier d’un rôle obligatoire non déclaré (IMP-061), index d’actualisation absent, fichier de taux ou de balance illisible, format des données inconnu. Une ligne rejetée, elle, ne fait pas échouer l’import : la situation est terminée avec des anomalies ERROR, et le nombre d’opérations importées le montre.
Le contrôle fichier par fichier de l’import guidé ne voit pas tout : il ne classe pas les opérations (la classification n’est pas lue avec elles), ne connaît pas les courbes ni la date d’arrêté, et ne lance pas les contrôles de cohérence de l’étape 6. Un fichier Valide peut donc encore produire, à l’import, des opérations rejetées faute de compte dans la classification, ou des anomalies ConstraintViolation.
Source : risk-app ImportService, ImportDraftService ; risk-import SituationImport, DataImportHelper, CLDataImporter.
1.1 Contrôles au dépôt
| Contrôle | Import par archive | Import guidé |
|---|---|---|
| Fichier vide | Tâche FAIL « is empty » |
Refusé (400) |
| Type détecté sur le contenu | Doit être un zip | model : JSON (text/plain ou application/json) et un objet JSON ; classification, flux préfixés : classeur .xlsx ; courbes, balance, opérations : .xlsx ou texte. Un .xls (ancien format Excel) est refusé. |
| Nom du fichier | — | Refusé si son nom le ferait prendre pour un autre fichier : un nom contenant model_ ou classification hors de l’emplacement correspondant. |
| Nom d’entrée dans l’archive envoyée | Tel que déposé | model et classification reçoivent le préfixe model_ ou classification_ s’ils ne le portent pas ; les autres gardent leur nom. Deux fichiers de même nom ne coexistent pas : le second remplace le premier. |
| Index d’actualisation | Doit être une clé de compoundCurve, une valeur de indexes, ou une clé de indexes (remplacée par sa valeur) ; sinon refus (400) avant tout envoi |
Idem, au moment de la saisie et de nouveau au lancement |
| Classification et modèles d’écoulement | Lus dans la version choisie de la configuration client ; un classification… ou un model_… de l’archive est ignoré (IMP-056) |
Idem : l’import guidé n’a plus d’emplacement pour eux |
| Informations de la situation | Données avec la requête (referenceDate, pivotCurrency, portfolioName, portfolioReference) ; un info_*.json de l’archive est ignoré (IMP-060) |
Saisies dans le formulaire, enregistrées sur le brouillon ; pas d’emplacement de fichier |
La taille maximale d’un envoi n’est pas fixée dans le code des applications mais dans leur configuration déployée (à confirmer).
Source : risk-app ImportService, ImportDraftService, ImportFileRole, DiscountFactorIndexes, ClassificationWorkbookService.
1.2 Décompression
risk-app décompresse avec les limites suivantes :
| Limite | Valeur | Message |
|---|---|---|
| Taille totale décompressée | 1 Gio | Archive rejected: its content inflates past the … -byte limit. |
| Taille d’une entrée | 512 Mio | Archive rejected: entry '…' inflates past the … -byte limit per entry. |
| Nombre d’entrées | 10 000 | Archive rejected: it holds more than … entries. |
| Taux de compression d’une entrée | 100 fois sa taille compressée (au-delà d’1 Mio) (seuil exact à confirmer) | Archive rejected: entry '…' inflates more than … times its compressed size. |
| Archives imbriquées | 3 niveaux | Archive rejected: '…' nests archives more than … level(s) deep. |
- Une archive contenue dans l’archive est décompressée à son tour (ses fichiers deviennent des fichiers de la situation), sauf un paquet de rapport XBRL (
META-INF/reportPackage.json). Un.xlsx, détecté comme classeur, n’est pas décompressé. - Les répertoires sont ignorés ; le nom d’un fichier garde son chemin dans l’archive.
- Le type de chaque fichier est détecté sur son contenu (bibliothèque Tika), pas sur son extension.
- Sont écartés : les fichiers dont le nom contient
~,.ds_storeou_macos(sans tenir compte de la casse), c’est-à-dire les fichiers temporaires d’Office et les métadonnées macOS.
Source : utils-library FileUtils, UnzipLimits ; risk-import DataImportHelper.
1.3 Rôle de chaque fichier
| Rôle | Import guidé | Archive déposée à l’écran | Archive envoyée par l’API |
|---|---|---|---|
| Informations de la situation | Formulaire | Formulaire (après dépôt) ; situation.json pour une archive complète |
Requête ; situation.json pour une archive complète |
| Modèle d’écoulement | — | Ignoré : vient de la configuration client (IMP-056) | Idem |
| Classification | — | Ignoré : vient de la configuration client (IMP-056) | Idem |
| Courbes, balance, flux préfixés | Emplacement | Emplacement, après dépôt ; files de situation.json pour une archive complète |
fileRoles de la requête (nom exact de l’entrée) ; files de situation.json pour une archive complète |
| Opérations | Emplacement | Tous les autres fichiers | fileRoles.TRANSACTIONS, et tout fichier non listé |
Dans une archive, tout fichier qui n’est pas reconnu est lu comme un fichier d’opérations : un Lisez-moi.txt ou un export en trop produit des anomalies de lecture sur ce fichier. Les noms de fichiers ne disent plus rien de leur rôle, hors model_ et classification : la balance, les flux préfixés et les courbes doivent être déclarés.
Source : risk-import DataImportHelper.buildDataModel.
1.4 Contrôle d’un fichier au dépôt
Le dépôt d’un fichier de l’import guidé (POST /api/v1/import/tasks/{id}/files?role=…) le contrôle dans la requête même : risk-app le lit seul avec la configuration client du brouillon et répond avec son statut définitif, VALID ou INVALID (à l’écran Valide ou n anomalie(s)), ses anomalies, le résumé de son contenu et la date du contrôle. Il n’y a plus d’attente : le résultat est connu quand le dépôt se termine. Seul un fichier déposé avant cette version peut encore porter le statut PENDING (Vérification…) : il est contrôlé à son tour à la réouverture du brouillon et au lancement de l’import.
Le chargement d’un classeur de classification dans la configuration client est contrôlé de la même façon : la réponse au dépôt porte le résultat de la lecture (statut PARSED, EMPTY ou UNREADABLE, message, anomalies), et l’enregistrement dans la configuration reste une seconde étape, possible pendant 2 heures après la lecture.
Source : risk-app ImportDraftService, ClassificationWorkbookService ; risk-import FileCheck, ClassificationParse.
1.5 La tâche d’import
Lancer l’import (bouton Lancer l'import de l’import guidé, POST /api/v1/import/tasks/{id}/submit, ou dépôt d’une archive) répond aussitôt : la tâche passe IN_PROGRESS (en cours). L’import se déroule ensuite en tâche de fond dans risk-app ; la tâche se termine DONE (terminé) ou FAIL (échec) avec ses anomalies, et une notification l’annonce. Quitter l’écran n’interrompt pas l’import. Plusieurs imports peuvent se dérouler en même temps (3 à la fois, les suivants attendent leur tour).
Un redémarrage de l’application pendant un import le laisse en cours sans qu’il reprenne. Si une tâche reste en cours anormalement longtemps, signalez-la au support.
L’écran suit la tâche en relisant son statut toutes les 3 secondes jusqu’à DONE ou FAIL (GET /api/v1/import/tasks/{id}?detailed=false : statut, nombre d’erreurs, message d’échec). Un outil qui appelle l’API fait de même.
Source : risk-app ImportService.
1.6 Stockage des fichiers déposés
L’archive et les fichiers de l’import guidé sont enregistrés dans le stockage objet (S3) du tenant, sous alm/<tenant>/imports/<tâche d'import>/<objet>/<nom du fichier>, à côté des runs (alm/<tenant>/runs/<run>/, voir Entrée d’un run). Ils y sont relus pour l’import, pour le téléchargement de l’archive complète de la situation, et supprimés avec la tâche d’import ou par la purge des brouillons. Chaque dépôt crée son propre objet (le segment <objet>) : un fichier remplacé par un autre de même nom, ou une archive recomposée à la nouvelle soumission d’un brouillon rouvert, ne réutilise jamais l’objet précédent. Les fichiers déposés avant cette version restent en base de données et se lisent de la même façon.
Source : risk-app ImportFileStore.
1.7 Classification à l’import et au lancement d’un run
La classification (§5) est appliquée deux fois :
- à l’import : chaque opération reçoit son compte et son classement (§5.4), avec les anomalies
CLSqui en découlent ; c’est ce que montrent le portefeuille et le journal des anomalies de la situation ; - au lancement d’un run : risk-app reclasse chaque opération du portefeuille, avec le même classificateur de
risk-import, au moment d’assembler l’entrée du run, avec la configuration client que porte cette entrée, selon les mêmes règles qu’à l’import (famille de produit, seconde jambe, rôle de couverture). Un deal ajouté ou modifié dans la situation depuis l’import est ainsi classé comme s’il avait été importé. Un deal sansInstrument Typeet sans lignehistogarde le classement qu’il a déjà.
Source : risk-app CashFlowGenerationService.runInputOf, DealReclassification ; risk-import CLClassificationEngine.
2. Règles communes
2.1 Classeurs Excel
- Seul le format
.xlsx(Office Open XML) est lu. Le classeur est lu en flux, sans être chargé en mémoire ; en cas d’échec de cette lecture, il est relu en mémoire. - Une cellule numérique au format date est lue comme une date ; une autre cellule numérique comme un nombre ; une cellule texte comme du texte ; un booléen comme un booléen.
- Une formule donne sa valeur calculée, mais une formule qui produit une date arrive comme un nombre (le numéro de série Excel) : les opérations le convertissent (§2.3), les autres fichiers non.
- Une ligne entièrement vide est sautée partout, sans anomalie.
- Choix de l’onglet : voir chaque fichier. Quand plusieurs onglets conviennent, ils sont départagés par ordre alphabétique de leur nom, jamais par leur position dans le classeur.
Source : poi-library ExcelStreamingReader ; risk-import CLDataImporter, CLCurveImporter.
2.2 Nombres
Les montants, nominaux et taux des opérations, et les montants de la balance, sont lus ainsi (les courbes et les flux préfixés ont leur propre règle, voir leurs sections) :
| Écriture | Valeur | Remarque |
|---|---|---|
| Cellule numérique Excel | telle quelle | |
1500.25, 1500,25 |
1 500,25 | un seul séparateur : c’est le séparateur décimal |
1 234,56, 1 234.56 |
1 234,56 | espaces de milliers, y compris insécables (U+00A0, U+202F, U+2009) |
1.234,56, 1,234.56 |
1 234,56 | les deux séparateurs : le plus à droite est décimal |
1.234 ou 1,234 |
1,234 | un seul séparateur suivi de trois chiffres reste décimal |
1.234.567, 1,234,567 |
1 234 567 | séparateurs de milliers répétés, sans décimale |
4.5621405013E8, 4,56E8 |
456 214 050,13… | notation scientifique |
-12,5, +12,5 |
signé | signe en tête uniquement ; (12,5) ou 12,5- ne sont pas des nombres |
| vide | absent | jamais lu comme 0 (voir chaque colonne) |
autre (1 234,5,6, n/a) |
rejet | '…' is not a number |
Source : risk-import BaseImporter.parseDouble, TransactionParser.parseDouble.
2.3 Dates
Chaque fichier a sa propre règle :
| Fichier | Cellule date Excel | Texte accepté | Date illisible |
|---|---|---|---|
| Opérations | oui ; aussi un nombre (numéro de série, système 1900) | yyyy-MM-dd, dd/MM/yyyy, MM/dd/yyyy, dd-MM-yyyy, MM-dd-yyyy, yyyyMMdd, dd.MM.yyyy, yyyy/MM/dd, dd/MM/yy, MM/dd/yy, dd-MM-yy, MM-dd-yy, dd.MM.yy, essayés dans cet ordre |
rejet de l’opération (Cannot parse '<clé>' with value '…') |
| Balance | oui (avant le 31/12/1910 : absente) | ddMMyyyy uniquement (30062025) |
rejet de la ligne |
| Courbes (CSV) | — | dd/MM/yyyy HH:mm uniquement |
ligne ignorée, avertissement |
| Courbes (Excel) | oui, obligatoire | — | l’import échoue (§6) |
| Flux préfixés | oui | yyyy-MM-dd uniquement |
ligne écartée, erreur |
| Date de référence de la situation | — | yyyy-MM-dd (formulaire ou requête) |
refusée avant l’import |
Règles propres aux opérations :
01/02/2025est le 1er février :dd/MMest essayé avantMM/dd, qui ne sert que si le jour dépasse 12.- Une année sur deux chiffres est lue entre 2000 et 2099 : une date du XXᵉ siècle doit s’écrire sur quatre.
- Une date texte ou numéro de série antérieure au 01/01/1950 est lue comme absente (c’est le cas d’une formule vide,
1899-12-30) ; une vraie cellule date antérieure est conservée. - Une date absente sur une colonne obligatoire n’empêche pas l’import de l’opération, mais produit une anomalie
ConstraintViolation(§10).
Les cellules date Excel sont converties dans le fuseau du serveur, celui dans lequel Excel les a construites : le jour lu est le jour affiché.
Source : risk-import TransactionParser.parseDate, BaseImporter.parseDate, CLCurveImporter, CLDataImporter.buildCashFlows.
2.4 Taux et pourcentages
Tous les taux des fichiers sont des pourcentages (2,40 pour 2,40 %) et sont divisés par 100 à la lecture :
| Fichier | Colonnes (clés de mapping) |
|---|---|
| Opérations | interestRate, interestMargin, liquidityMargin, commercialMargin (prêts, comptes à terme) ; couponRate, couponMarginRate (titres) ; interestRate, rateLeg1 (pensions) ; payBaseRate, recBaseRate, payMargin, recMargin (swaps) |
| Courbes | offer |
| Flux préfixés | 7ᵉ colonne (taux) |
Ne sont pas des taux : les taux du modèle d’écoulement (model_*.json), déjà décimaux (0.015 pour 1,5 %).
Source : risk-import LoanParser, TermDepositParser, SecurityTransactionParser, RepoParser, SwapParser, CLCurveImporter, CLDataImporter.
2.5 Fréquences et ténors
| Valeur lue | Fréquences de paiement et de révision (opérations) |
|---|---|
MONTHLY |
mois |
QUARTERLY |
trimestre |
SEMI ANNUAL |
semestre |
ANNUAL |
année |
AT MATURITY, NONE |
à l’échéance |
| autre | paiement : rejet de l’opération (Cannot parse 'Frequency' …) ; révision : laissée vide, message INFO |
Les valeurs sont comparées exactement (majuscules, une espace) ; les sections frequency et rateType du mapping ne sont pas lues (Configuration client). Une fréquence de paiement vide vaut une année sur un prêt ou un compte à terme, et reste vide sur un titre ou une jambe de swap (ce qui produit une anomalie ConstraintViolation).
Les ténors d’index (colonnes mappées sous payIndexTenor, rateBasisTenor, payRateBasisTenor, recRateBasisTenor) sont normalisés avant comparaison : O/N, ON, OVERNIGHT, OVER NIGHT → 1D ; <n> D|DAY(S)|W|WEEK(S)|M|MONTH(S)|Y|YEAR(S) (au plus trois chiffres, points et tirets ignorés) → nD, nW, nM, une année valant 12 mois (1Y = 12M = 1 YEAR). Toute autre valeur n’est pas un ténor : la clé sans ténor s’applique (§7.7).
Les fréquences des flux préfixés et les maturités des courbes ont leur propre écriture (voir §6 et §8).
Source : risk-import TransactionParser.parseFrequency, TransactionParser.normaliseTenor.
2.6 Bases de calcul
| Produit | Colonne | Règle |
|---|---|---|
| Prêt, compte à terme | payConvention |
valeur cherchée telle quelle dans rateBase ; vide → rateBase.default ; absente de la table → rejet (Cannot parse 'RateBase' …) |
| Titre | dayConvention |
idem |
| Pension | interestConvention |
idem |
| Jambe de swap | payDaysConvention / recDaysConvention (facultatives) |
1. valeur de rateBase (hors default) ; 2. écriture usuelle ; 3. convention de marché ; jamais de rejet (§7.6) |
La valeur de rateBase doit être une base du moteur : EXACT_EXACT, EXACT_365, EXACT_360, ABB_30_360 (Cadre de calcul, §1.6).
Source : risk-import TransactionParser.parseBase, SwapParser.resolveDayCount.
2.7 Sens et signes
L’import enregistre chaque opération BUY ou SELL ; c’est ce sens, avec le produit, qui donne le signe des flux (Cadre de calcul, §1.10).
| Produit | BUY signifie |
Source du sens |
|---|---|---|
| Prêt | prêt accordé (actif) | nature : INVESTMENT → BUY, BORROWING → SELL ; sinon déduit du type d’instrument |
| Compte à terme | dépôt reçu (passif) | nature : INVESTMENT → SELL, BORROWING → BUY ; sinon déduit |
| Titre | titre acheté | nature : INVESTMENT → BUY, BORROWING → SELL ; sinon déduit du type d’instrument |
| Pension | prise en pension (prêt d’espèces) | nature : INVESTMENT → BUY, BORROWING → SELL ; sinon déduit du type d’instrument |
| Swap | — | toujours BUY ; le côté de chaque jambe vient de son préfixe (pay payée, rec reçue) |
| Poste de balance modélisé | — | toujours BUY ; le signe est celui du montant de la balance |
La comparaison ignore la casse ; la déduction du type d’instrument, propre à chaque produit, est décrite dans Import Crédit Logement. Une valeur qui n’est ni INVESTMENT ni BORROWING, ou une cellule vide sur un type d’instrument qui ne dit pas le sens, donne BUY avec un avertissement (TRX-024 à TRX-027) ; l’opération n’est jamais rejetée pour son sens.
Source : risk-import TransactionParser.parseDirection, TransactionParser.parseTransactionType, SwapParser, CLDataImporter.buildModelTransactions.
2.8 Devises
| Objet | Devise |
|---|---|
| Prêt, compte à terme, titre, swap | La colonne nommée currency (casse ignorée, donc aussi Currency), sans espaces autour ; EUR si la colonne manque ou si la cellule est vide. Une valeur qui n’est pas un code ISO 4217 rejette l’opération (Currency '…' is not an ISO-4217 code). |
| Pension | toujours EUR (la colonne est contrôlée mais pas utilisée) |
| Poste de balance modélisé | toujours EUR |
| Courbe du fichier de taux | colonne currency du fichier |
| Courbe composée, courbe de spread de liquidité | EUR |
Situation (pivotCurrency) |
valeur saisie à l’écran ou donnée par la requête, 3 caractères au plus |
Pour que la colonne serve, le mapping doit associer la clé currency à currency (c’est le cas du mapping livré) : l’import range la devise retenue sous ce nom avant de lire l’opération.
Source : risk-import CLDataImporter.currencyOf, CLDataImporter.checkCurrency, RepoParser, CLCurveImporter.
2.9 Références, contreparties, étiquettes
- Référence :
<préfixe>_<numéro d'opération>, avecLO(prêt),TD(compte à terme),SE(titre),RE(pension),SW(swap). Un numéro lu dans une cellule numérique perd sa partie décimale (6443.0→6443). L’unicité n’est pas contrôlée : deux lignes de même numéro donnent deux opérations de même référence. - Postes modélisés :
<PRODUIT>_<référence de la stratégie>_<compte>, par exempleACCOUNTING_291200**_29120005. - Contrepartie : la valeur de la colonne ; vide →
DEFAULT_NAME. Elle est créée de typeRETAIL, notéeA. Les postes modélisés ont la contrepartieDEFAULT, de typeCORPORATE. - Étiquettes (
tags) : pour chaque colonne listée (nom comparé sans casse), sa valeur est recopiée. Une cellule vide d’un classeur fait rejeter la ligne (Tag column '<colonne>' is blank., Import Crédit Logement). - Données brutes : la ligne lue est conservée telle quelle avec l’opération (onglet
Transaction Datade la situation), y compris les colonnes non mappées.
Source : risk-import TransactionParser.getReference, TransactionParser.findOrCreateCounterparty, CLDataImporter.parseTransaction, CLDataImporter.buildModelTransactions.
3. Informations de la situation
L’arrêté ne vient plus d’un info_*.json : il est saisi à l’écran d’import, lu dans le situation.json d’une archive complète, ou donné dans la requête de l’API. risk-app l’enregistre sur la tâche et le donne à l’import.
| Champ | Lecture | Si absent ou vide |
|---|---|---|
| client | celui de la configuration client ; plus saisi | — |
portfolioName |
texte, 100 caractères au plus | avertissement ; nom default_name (IMP-030) |
portfolioReference |
texte, 100 caractères au plus, et moins selon le client (voir ci-dessous) | avertissement ; référence default_reference (IMP-029) |
referenceDate |
date yyyy-MM-dd ; date d’arrêté et d’évaluation |
l’import échoue (IMP-059) |
discountFactorIndex |
une clé de compoundCurve ou une valeur de indexes ; une clé de indexes devient sa valeur |
l’import échoue (IMP-059) |
pivotCurrency |
texte, 3 caractères au plus | l’import échoue (IMP-059) |
- Les longueurs sont contrôlées dès la réception : le formulaire ou la requête est refusé (erreur 400 sur le champ), par exemple « portfolioName is 101 characters long, at most 100 are allowed. ».
- La référence du contexte,
[<client> - <referenceDate>] Context <portfolioReference>, tient en 100 caractères : le client de la configuration etportfolioReferenceréunis en ont donc 76 au plus (61 pour la référence avec le clientcredit logement). Une archive envoyée par l’API qui dépasse donne une tâcheFAIL(IMP-007). - Par l’API, une archive sans
situation.jsondonne aussi le rôle de ses fichiers :"fileRoles": {"RATE_CURVES": ["RT_indices.txt"], "ACCOUNTING": ["COMPTA.xlsx"], "CASHFLOWS": ["cashflows.xlsx"]}, par nom exact d’entrée ; un fichier non listé est un fichier d’opérations. - L’index d’actualisation retenu doit nommer une courbe du contexte (sans tenir compte de la casse) ; sinon une anomalie
ERRORMissingCurve(CRV-018) le signale : aucun autre index ne le remplace, et au calcul chaque flux postérieur à la date d’arrêté reste sans facteur d’actualisation.
Source : risk-app ImportService, ImportDraftService, ImportInfoLimits ; risk-import DataImportHelper, ImportDataModel, CLDataImporter.buildContextModel.
4. Modèle d’écoulement (model_*.json)
| Clé | Contenu |
|---|---|
outflowStrategies[] |
Liste des stratégies. @type : LinearOutflowStrategy, BucketOutflowStrategy ou ScriptOutflowStrategy ; un autre type rend le fichier illisible. |
…productName |
Produit de la stratégie ; mis en majuscules pour la référence du poste (accounting → ACCOUNTING). |
…reference |
Préfixe de compte suivi d’étoiles (291200**) ; les étoiles sont retirées pour la comparaison. |
…rate |
Taux du poste, en décimal : type (FIXED/FLOATING), value, spread, index, base, interestMode (SIMPLE/COMPOUND). |
…frequency, …timeHorizon |
Loi linéaire : fréquence (MONTH, QUARTER, SEMESTER, YEAR, AT_MATURITY) et horizon (6Y). |
…curve |
Loi par buckets : maturité → part. |
…language, …scriptName, …function |
Loi par script. |
…strategyType |
Origines (vue contractuelle, comportementale) auxquelles la loi s’applique. |
balanceSheetEvolutionStrategy |
Facultatif : ConstantBalanceSheetStrategy (rollHorizon), GrowthBalanceSheetStrategy (rollHorizon, annualGrowthPct), RunOffBalanceSheetStrategy. |
Le sens de ces lois est décrit dans Bilan constant et comportemental.
4.1 Rattachement des lignes de balance
- Chaque ligne de la balance est rattachée à une seule stratégie : celle dont le préfixe (référence sans étoiles) est le plus long préfixe de son compte. Une ligne que plusieurs préfixes couvrent fait l’objet d’un avertissement nommant la stratégie retenue.
- Deux stratégies au même préfixe : la première listée s’applique, les autres sont ignorées, avec un avertissement.
- Une ligne qu’aucun préfixe ne couvre n’est pas modélisée, sans anomalie.
- Chaque ligne rattachée devient une opération : produit « solde comptable », montant de la ligne (signe compris) en EUR, libellé du compte sans espaces autour, loi et taux de la stratégie, date de transaction et de règlement = date d’arrêté, sens
BUY. - Son compte de classification est le préfixe de la stratégie, pas le compte de la ligne (Import Crédit Logement) ; s’il ne figure pas une fois exactement dans
mapping_compta, la ligne est écartée en erreur.
Source : risk-model OutflowStrategyModel ; risk-import CLDataImporter.assignOutflowStrategies, CLDataImporter.buildModelTransactions, CLClassificationEngine.
5. Classification (classification*.xlsx)
Ce classeur se charge dans la section Classification de la configuration client, qui en exporte un au même format ; l’import lit la classification dans la configuration. Les règles ci-dessous sont celles de sa lecture.
Trois onglets, cherchés par leur nom exact. mapping_compta et mapping_compta_irrbb sont obligatoires (sinon : erreur nommant les onglets présents, et aucune opération n’est classée) ; histo est facultatif.
5.1 Onglet mapping_compta : comptes
Deux lignes d’en-tête ; les données commencent à la troisième ligne. Les colonnes sont lues par position.
| Col. | En-tête (classeur généré) | Lecture | En cas de problème |
|---|---|---|---|
| A | Poste Comptable |
cellule numérique, partie entière ; ou texte fait de lettres puis de chiffres (H96…), tel quel |
autre texte (un numéro au format Texte) → ligne écartée (ERROR, ClassCastException, CLS-009) |
| B | Bilan |
côté : Actif, A, Asset → actif ; Passif, P, L, Liability → passif ; HB, Hors bilan → hors bilan (casse ignorée, sans espace superflu) |
vide → ligne ignorée (WARNING) ; autre valeur → ligne écartée (ERROR) |
| C | Contrepartie |
texte | vide → ligne ignorée (WARNING) |
| D | Map |
non lue | |
| E | Operation Financiere |
booléen | |
| F | Actif Modelise |
booléen | |
| G | Gross Carrying Amount |
booléen | |
| H | Nominal |
booléen | |
| I | EVE |
booléen | |
| J | MNI |
booléen | |
| K | Sensible Taux |
booléen | |
| L | Signe |
entier ; vide → 0 | texte non numérique → ligne écartée |
| M | MV |
booléen |
Booléens : vide, false, 0, no, n, non → faux ; true, 1, yes, y, oui, o, x → vrai (casse ignorée) ; un nombre est vrai s’il est positif ; tout autre texte écarte la ligne en erreur.
La catégorie d’un compte est la chaîne <Bilan> <Contrepartie>, formée des cellules telles qu’écrites ; c’est elle qui est cherchée dans mapping_compta_irrbb.
5.2 Onglet mapping_compta_irrbb : catégories
Une ligne d’en-tête ; données à partir de la deuxième ligne.
| Col. | En-tête | Lecture | En cas de problème |
|---|---|---|---|
| A | Map |
catégorie <Bilan> <Contrepartie>, texte, comparée exactement à celle de mapping_compta |
|
| B | FINREP |
nom d’une ligne FINREP du moteur (A_LOANS_AND_ADVANCES…), casse respectée |
inconnu → WARNING, la catégorie n’a pas de code FINREP |
| C | Row Code (facultative, repérée par son en-tête) |
numéro de ligne J 02.00 (270, 270.0, "0270") |
différent du code FINREP choisi → la ligne est rejetée (ERROR) |
| D | Hedge Role (facultative) |
MACRO, MICRO, INDEX, NONE, UNSPECIFIED (casse ignorée) |
autre → WARNING, rôle non précisé |
Contrôle de côté : une catégorie d’actif (Bilan Actif…) rattachée à une ligne FINREP de passif (L_…), ou l’inverse, est rejetée en erreur ; ses opérations n’ont pas de code FINREP et sortent de tout le reporting. Les catégories hors bilan et les lignes FINREP sans côté (OFF_BS_…, OTHER_DERIVATIVES) ne sont pas comparées.
Une catégorie de mapping_compta sans ligne ici fait l’objet d’un avertissement, avec son nombre de comptes ; ses opérations seront exclues de tout le reporting, totaux du J 01.00 compris (avertissement MissingClassification).
Le rôle de couverture n’est appliqué qu’aux opérations classées sur une ligne de dérivés (A_DERIVATIVE_HEDGING…, L_DERIVATIVE_HEDGING…, OTHER_DERIVATIVES) : UNSPECIFIED si la catégorie ne dit rien ; toute autre opération a le rôle NONE.
5.3 Onglet histo : compte de chaque opération
Une ligne d’en-tête (N° histo, Poste comptable, Instrument / Line ID).
| Col. | Lecture | En cas de problème |
|---|---|---|
| A | numéro d’opération, cellule numérique | non numérique → ligne écartée (ERROR) |
| B | compte, cellule numérique | non numérique → ligne écartée (ERROR) ; compte absent de mapping_compta → ligne ignorée (WARNING) |
| C | libellé, pour mémoire | non lu |
Une opération listée deux fois sur le même compte : avertissement. Sur deux comptes différents : erreur, et l’opération prend le compte du mapping instrumentAccounts.
5.4 Compte et classement d’une opération
| Objet | Compte retenu |
|---|---|
| Poste de balance modélisé | préfixe de sa stratégie |
Opération présente dans histo |
compte de histo (numéro d’opération = référence sans son préfixe) |
| Autre opération | règle instrumentAccounts de la configuration (Compte comptable des opérations) : type d’instrument (Instrument Type, comparé sans casse ni espaces autour), puis sous-famille, puis famille (valeur du mapping products, security pour le fichier des titres) |
| Opération qu’aucune règle ne couvre | aucun compte : importée sans classement |
Un compte exact doit figurer exactement une fois dans mapping_compta ; un compte étoilé (9431**) doit couvrir au moins un compte, et tous ceux qu’il couvre doivent avoir la même ligne FINREP. Sinon, une ligne de balance modélisée est rejetée (Mapping for 'Classification' 'account' and reference '…' is missing) ; une opération est importée sans classement. Chaque fichier d’opérations signale, par un avertissement Classification / Account, ses opérations sans compte (par type d’instrument) et celles dont le compte ne peut pas être classé (avec la raison).
Une classification illisible (classeur corrompu, onglet manquant : CLS-003, CLS-004) ne rejette aucune opération : les opérations et les lignes de balance modélisées sont importées sans ligne FINREP, et leurs flux sont calculés (CLS-002, CLS-018). Corrigez le classeur et réimportez pour les classer.
Source : risk-import CLDataImporter.buildClassification, CLDataImporter.buildHistoAccounts, CLDataImporter.hedgeRoleOf, CLClassificationEngine, DataMapper ; risk-app ClassificationAccountSheet, ClassificationCategorySheet, ClassificationHistoSheet.
6. Courbes de taux
Le fichier est accepté en classeur Excel ou en texte (.csv, .txt). Le format de chaque colonne est donné dans Import d’une situation ALM ; voici comment il est lu.
| Fichier texte | Classeur Excel | |
|---|---|---|
| Séparateur, encodage | ; uniquement ; UTF-8, marque BOM tolérée |
— |
| En-tête | première ligne | première ligne d’au moins 8 cellules remplies de l’onglet retenu |
| Onglet | — | celui dont l’en-tête porte les cinq colonnes ; s’il y en a plusieurs, le premier par ordre alphabétique (avertissement) ; s’il n’y en a aucun, le premier onglet par ordre alphabétique |
| Lignes lues | toutes | seulement celles d’au moins 8 cellules remplies ; les autres sont ignorées sans anomalie |
| Noms de colonnes | offer, ratedate, currency, ratename, timeband, en minuscules, exacts |
idem ; une colonne manquante → erreur, aucune courbe lue |
offer |
nombre, virgule ou point décimal, sans séparateur de milliers ; ÷ 100 | cellule numérique ÷ 100, ou texte comme en CSV |
ratedate |
dd/MM/yyyy HH:mm ; l’heure est ignorée |
cellule date obligatoire |
timeband |
voir ci-dessous | idem |
| Ligne invalide | ignorée, avertissement Unable to parse index… |
cellule manquante ou valeur invalide : ignorée, avertissement |
timeband : ACTUAL → 0 jour (point spot) ; OVERNIGHT → 1 jour ; <n> WEEK(S), <n> MONTH(S), <n> YEAR(S) (casse ignorée, une espace) → n semaines, mois, années. Autre → ligne ignorée.
6.1 Construction des courbes
- Une courbe par couple (
ratename, date de cotation) : un fichier qui couvre un mois de cotations donne autant de courbes par index que de jours. Deux points de même maturité dans une même courbe : le dernier lu l’emporte, sans anomalie. - Chaque point est marqué swap si le nom de l’index contient
SWAP(casse ignorée), monétaire sinon ; la cotation (ZEROouPAR) vient decurveQuotations(Configuration client). - La période de refixation d’un index se lit dans son nom :
ESTR,EONIAouO/N→ 1 jour ;12M/1Y→ 12 mois ;6M,3M,1M→ 6, 3, 1 mois ; sinon aucune (le moteur supposera 3 mois, avec un avertissement au calcul). - Une courbe datée à plus de 50 jours de la date d’arrêté, avant ou après, fait l’objet d’un avertissement.
- Une courbe de spread de liquidité nulle (
LIQUIDITY_SPREAD, EUR, points 1 jour, 1 mois, 10 ans) est toujours ajoutée. - Contrôle du mapping : chaque valeur de
indexeset chaque courbe élémentaire decompoundCurvedoit exister dans le fichier (casse et espaces superflus ignorés) ; sinon erreur sur le fichier de taux, qui nomme les libellés concernés.
Une erreur imprévue pendant la lecture (type de fichier non reconnu, ratedate texte dans un classeur…) fait échouer l’import : Unable to build the evaluation context from '<fichier>'.
6.2 Courbes composées
Pour chaque entrée de compoundCurve ("DISCOUNT_EUR": {"1d": "ESTR", "1Y": "EURIBOR", "100y": "ESTR SWAP"}) :
- les seuils (
1d,1Y,100y…) sont triés du plus court au plus long ; - pour chaque seuil, la courbe élémentaire retenue est celle dont la date de cotation est la plus proche de la date d’arrêté (la plus récente lors du contrôle d’un fichier seul) ;
- elle apporte ses points de maturité inférieure ou égale au seuil ; un point de même maturité apporté par un seuil plus long remplace le précédent ;
- la courbe composée prend le nom de l’entrée, la devise EUR et la date d’arrêté ;
- si une courbe élémentaire manque, la courbe composée n’est pas construite (l’erreur est portée par le contrôle du mapping) ;
- un seuil fautif laisse la courbe composée de côté avec une erreur
CompoundCurve, dont l’objet est le nom de la courbe :Compound curve '<nom>' is not built: its threshold '<clé>' is not a tenor such as 3m or 10y.,… its threshold '<clé>' names no index., ou… its thresholds '<clé>' and '<clé>' are the same tenor.(1yet1Y). Tout autre échec se litCompound curve '<nom>' is not built: <cause>.
Source : risk-import CLCurveImporter, RateCurveHelper.determineFixingPeriod.
7. Opérations
7.1 Lecture des fichiers
Fichier texte (.csv, .txt) |
Classeur Excel | |
|---|---|---|
| Séparateur, encodage | ; uniquement ; UTF-8, marque BOM tolérée ; guillemets à la norme CSV |
— |
| En-tête | première ligne ; noms exacts, espaces compris | dans chaque onglet, la première ligne de plus de 5 cellules remplies ; les lignes au-dessus sont sautées |
| Onglets lus | — | ceux dont l’en-tête porte Instrument Type ; les autres sont ignorés (avertissement si l’onglet a un en-tête, information sinon) ; aucun onglet de ce type → erreur |
| Fin de lecture | une ligne malformée arrête la lecture du fichier, les lignes déjà lues sont gardées, une erreur dit où | |
| Synthèse | Imported n lines from m par fichier (INFO), ou …: k line(s) rejected (ERROR) |
idem, par onglet |
Une colonne nommée par une clé obligatoire du mapping doit exister dans le fichier, même vide ; sinon chaque ligne est rejetée (Record does not contain field '…'). Une clé facultative peut manquer au mapping comme au fichier. Une ligne rejetée produit deux anomalies : la cause, sur la référence de l’opération quand elle est connue, et Cannot import the transaction at row <n> of sheet '<onglet>' of '<fichier>' (ou line <n>) avec la ligne brute.
7.2 Choix du produit
- La valeur de la colonne
Instrument Typeest cherchée exactement dans la sectionproductsdu mapping. - Un fichier dont le nom contient
securities(casse ignorée) est lu comme des titres, quelle que soit la valeur : la colonne y porte l’ISIN. - Le produit doit être
loan,term_deposit,security,repoouswap.nantissementn’a pas de lecteur : la ligne est rejetée. Une valeur absente deproductsrejette la ligne (Cannot parse 'ProductMapping' with value '…'). Une valeur deproductsqui n’est aucun des produits du moteur la rejette aussi :Instrument type '<type>' is mapped to product '<valeur>', which is not a product of the engine (expected one of […]).UnInstrument Typevide la rejette avec'Instrument Type' is blank, so the deal cannot be matched to a product.Le produit, donc le préfixe, n’étant pas encore connu, ces deux anomalies sont localisées sur<fichier> / Deal Number <numéro>. - Ordre des contrôles d’une ligne : produit, lecture des colonnes, devise, étiquettes, puis (à l’import seulement) classement.
Dans les tableaux ci-dessous, Obl. indique une clé obligatoire du mapping ; « vide » désigne une cellule vide ou absente. Une cellule vide sur une colonne obligatoire n’est pas un rejet en soi : selon la colonne, elle donne une valeur par défaut, un rejet, ou une anomalie ConstraintViolation sur une opération conservée.
7.3 Prêts et comptes à terme (loan, term_deposit)
| Clé | Colonne CL | Obl. | Lecture | Si vide / invalide |
|---|---|---|---|---|
reference |
Deal Number |
oui | référence LO_… / TD_… |
|
instrumentType |
Instrument Type |
oui | contient Capitalise (casse ignorée) → intérêts composés ; sur un compte à terme, coupon unique à l’échéance |
vide → rejet (Instrument type (column '…') is blank, so whether its interest is capitalised cannot be read.) |
counterparty |
Counterparty |
oui | §2.9 | DEFAULT_NAME |
currency |
currency |
oui | §2.8 | EUR |
dealDate |
Deal Date |
oui | date de transaction | ConstraintViolation |
settlementDate |
Settlement Date |
oui | date de début | ConstraintViolation (prêt) |
maturityDate |
Effective Maturity Date |
oui | échéance | ConstraintViolation |
callDate |
DateCall |
oui | date de call | aucun call |
nominal |
Original Face Value |
oui | nombre | ConstraintViolation ; non numérique → rejet |
remainingNominal |
Remaining Face Value |
non | encours retenu à la place du nominal, 0 compris ; écart de plus de 0,005 → avertissement | nominal d’origine |
rateType |
Fixed or Floating |
oui | FIXED / FLOATING, casse ignorée |
autre → rejet (Rate type '…' (column '…') is neither 'Fixed' nor 'Floating'.) ; vide → rejet (Rate type (column '…') is blank; it must be 'Fixed' or 'Floating'.) |
interestRate |
Interest Rate |
oui | % ÷ 100 ; sur un taux variable, 0 = fixing inconnu (taux lu sur la courbe) | vide : pas de taux |
interestMargin |
Interest Rate Margin |
oui | % ÷ 100 → spread | pas de spread |
payIndex |
Basis |
oui | libellé de taux → index (§7.7) | taux sans index |
payIndexTenor |
Basis Rate Frequency Time Band |
non | ténor (§2.5) | clé sans ténor |
payConvention |
Days Convention |
oui | base (§2.6) | rateBase.default ; inconnue → rejet |
paymentFrequency |
Payment Frequency |
oui | §2.5 | année ; inconnue → rejet |
reviewFrequency |
Review Frequency |
non | taux variable seulement ; enregistrée, pas encore utilisée | inconnue → vide, INFO |
nature |
(absente de la vue IRRBB_MM) |
non | sens (§2.7) | déduit du type d’instrument |
liquidityMargin, commercialMargin |
— | non | prêt seulement ; % ÷ 100 | spread de liquidité du contexte |
liquidityCurveIndex |
— | non | prêt seulement ; résolu comme un libellé de taux | aucun |
Source : risk-import LoanParser, TermDepositParser, TransactionParser.
7.4 Titres (security)
| Clé | Colonne CL | Obl. | Lecture | Si vide / invalide |
|---|---|---|---|---|
reference |
Deal Number |
oui | référence SE_… |
|
isin |
Instrument Type |
oui | ISIN | |
nature |
Borrow or Invest |
oui | INVESTMENT → BUY, BORROWING → SELL |
déduit du type d’instrument, sinon BUY (§2.7) |
counterparty |
Counterparty Name |
oui | DEFAULT_NAME |
|
currency |
currency |
oui | §2.8 | EUR |
dealDate |
Deal Date |
oui | date de transaction | ConstraintViolation |
settlementDate |
Settlement Date |
oui | date de règlement et de début | ConstraintViolation |
maturityDate |
Effective Maturity Date |
oui | échéance | ConstraintViolation |
callDate, issuerCallDate |
DateCall, DtCallEmet |
non | la première renseignée ; les deux et différentes → la plus proche, avec avertissement | aucun call |
nominal |
Original Face Value |
oui | nombre | ConstraintViolation |
remainingNominal |
Remaining Face Value |
non | encours retenu, avec avertissement en cas d’écart | nominal d’origine |
rateType |
Fixed or Floating |
oui | FIXED / FLOATING, casse ignorée |
autre ou vide → rejet |
couponRate |
Coupon Rate |
oui | % ÷ 100 → taux du titre fixe | 0 %, avertissement si le titre est fixe |
couponMarginRate |
Coupon Margin Rate |
oui | % ÷ 100 → marge du titre variable | 0 %, avertissement si le titre est variable |
rateBasis |
Basis |
oui | libellé de taux → index | taux sans index |
rateBasisTenor |
Basis Rate Frequency Time Band |
non | ténor | clé sans ténor |
dayConvention |
Convention de calcul |
oui | base | rateBase.default ; inconnue → rejet |
frequency |
Coupon Frequency |
oui | §2.5 | ConstraintViolation ; inconnue → rejet |
reviewFrequency |
Review Frequency |
non | comme les prêts | |
rate, marginRate, issuer, entity, product |
divers | non | non lues (gardées dans les données brutes) |
Pour couponRate et couponMarginRate, une valeur non numérique vaut 0 % comme une cellule vide, au lieu de rejeter le titre ; une colonne absente du fichier rejette en revanche chaque ligne.
Source : risk-import SecurityTransactionParser, TransactionParser.
7.5 Pensions (repo)
| Clé | Colonne CL | Obl. | Lecture | Si vide / invalide |
|---|---|---|---|---|
reference |
Deal Number |
oui | référence RE_… |
|
instrumentType |
Instrument Type |
oui | conservé sur le produit | ConstraintViolation |
nature |
Borrowing Investing (deux espaces) |
oui | INVESTMENT → BUY (prise en pension), BORROWING → SELL |
déduit du type d’instrument, sinon BUY (§2.7) |
counterparty |
Counterparty |
oui | DEFAULT_NAME |
|
panier |
Panier |
oui | ISIN du panier | |
dealDate, settlementDate, maturityDate |
Deal Date, Settlement Date, Effective Maturity Date |
oui | dates | ConstraintViolation |
callDate |
DateCall |
non | date de dénouement en vue comportementale | aucun call |
interestRate |
Interest Rate |
oui | % ÷ 100, taux fixe, intérêts simples, spread 0 | pas de taux |
rateLeg1 |
Interest Rate Leg 1 |
oui | % ÷ 100, même base | pas de taux |
interestConvention |
Interest Days Convention |
oui | base des deux taux | rateBase.default ; inconnue → rejet |
originalFaceValue |
Original Face Value |
oui | nominal | montant vide |
leg2FaceValue |
Leg Two Original Face Value |
oui | nominal de la jambe 2 | montant vide |
interestAmount |
Interest Amount |
oui | montant d’intérêts | montant vide |
Tous les montants d’une pension sont en EUR.
Source : risk-import RepoParser, TransactionParser.
7.6 Swaps (swap)
Une jambe payée (préfixe pay) et une jambe reçue (préfixe rec), lues avec les mêmes règles ; le tableau nomme les clés pay….
| Clé | Colonne CL | Obl. | Lecture | Si vide / invalide |
|---|---|---|---|---|
reference |
Deal Number |
oui | référence SW_… |
|
counterparty |
Counterparty |
oui | DEFAULT_NAME |
|
currency |
currency |
oui | devise des deux jambes | EUR |
nominal |
Original Face Value |
oui | nominal des deux jambes ; l’encours restant n’est pas lu | ConstraintViolation |
settlementDate, maturityDate |
Settlement Date, Effective Maturity Date |
oui | début et échéance | ConstraintViolation |
dealDate |
Deal Date |
non | date de transaction | date de règlement |
callDate |
DateCall |
non | aucun call | |
payBaseRate |
Pay base rate |
oui | % ÷ 100 ; taux fixe, ou dernier fixing pour information | vide → rejet (The pay leg has no base rate: column '…' is blank.) ; non numérique → rejet (Cannot parse 'payBaseRate'…) |
payMargin |
Pay margin |
oui | % ÷ 100 → spread | pas de spread |
payRateBasis |
Pay Rate Basis |
oui | libellé de taux → index | jambe fixe (si pas de type) |
payRateBasisTenor |
Pay Rate Basis Freq Time Band |
non | ténor | clé sans ténor |
payRateType |
Pay Fixed/Floating |
non | FIXED / FLOATING (casse ignorée) décide du type |
autre ou vide : variable si un libellé de taux est donné, fixe sinon |
payFrequency |
Pay Frequency |
oui | §2.5 | ConstraintViolation ; inconnue → rejet |
payDaysConvention |
Days Convention |
non | voir ci-dessous | convention de marché |
payReviewFrequency |
Pay Review Frequency |
non | comme les prêts | |
pay1stPaymentDate |
Pay 1st Payment Date |
non | contrôle seulement : écart de plus de 4 jours avec l’échéancier → avertissement |
Type de la jambe : déclarée variable sans libellé → valorisée à son taux actuel, avertissement ; déclarée fixe avec un libellé → fixe, libellé conservé pour information, avertissement. L’échéancier est construit à rebours depuis l’échéance, toujours en intérêts simples.
Base de la jambe, dans cet ordre (Import Crédit Logement) :
- une valeur de
rateBase, saufdefault, et sauf une règle de jour ouvré ; - une écriture usuelle, comparée après passage en majuscules,
ACTUAL→ACT, espaces et parenthèses retirés :30/360,30E/360,30U/360,360/360,BONDBASIS,EUROBONDBASIS→ 30/360 ;ACT/360,A/360,A360→ ACT/360 ;ACT/365,ACT/365F,ACT/365FIXED,A/365,A365→ ACT/365 ;ACT/ACT,ACT/ACTISDA,ACT/ACTICMA,A/A→ ACT/ACT ; - sinon la convention de marché : jambe fixe en EUR → 30/360 ; jambe variable en EUR dont le libellé cite EURIBOR, €STR (
ESTR,ESTER,IESTR,IESTER,€STR,EURO SHORT-TERM RATE) ou EONIA (EURO OVERNIGHT INDEX AVERAGE) → ACT/360 ; autre →rateBase.default.
Est une règle de jour ouvré toute valeur contenant FOLLOWING, PRECEDING ou BUSINESS DAY, ou valant exactement ACTUAL DATE, UNADJUSTED ou NO ADJUSTMENT. Chaque fichier dit une fois combien de jambes ont pris la convention de marché, et pourquoi.
Source : risk-import SwapParser, TransactionParser, CLDataImporter.reportDayCountFallbacks.
7.7 Résolution des libellés de taux
Pour un libellé de taux (Basis, Pay Rate Basis…) :
- avec un ténor reconnu, une clé
libellé|ténordeindexes(libellé exact, ténor normalisé) ; - sinon la clé
libelléexacte ; - sinon le libellé n’est pas mappé : l’opération est conservée avec un avertissement, et :
- taux fixe : rien ne change ;
- taux variable dont le libellé est le nom d’une courbe du fichier (casse ignorée) : cette courbe ;
- sinon : pas d’index, l’opération est valorisée à son taux actuel et ne réagit pas aux chocs.
Lors du contrôle d’un fichier seul, les courbes ne sont pas connues : seul l’avertissement est émis. Le libellé d’origine reste toujours enregistré sur le taux.
Source : risk-import TransactionParser.lookupIndex.
8. Flux préfixés
| Règle | |
|---|---|
| Format | classeur .xlsx uniquement |
| Onglet | celui qui contient une cellule Deal No ou action_dt (casse ignorée) ; plusieurs → le premier par ordre alphabétique, avertissement ; aucun → le premier onglet, avertissement, données lues à partir de la 3ᵉ ligne |
| Données | à partir de la ligne qui suit l’en-tête ; colonnes lues par position |
| Ligne invalide | écartée, erreur nommant la ligne |
| Fichier illisible | erreur ; l’import continue sans préfixing, avec une anomalie Missing par fichier d’opérations |
| Col. | Contenu | Lecture |
|---|---|---|
| 1 | numéro d’opération | cellule numérique → partie entière ; texte tel quel |
| 2 | instrument | texte |
| 3 | base (index) | texte |
| 4 | fréquence du taux de base | <n> <unité>, unité contenant year, month, week ou day (3 months) ; texte vide accepté (pas de fréquence) ; autre → ligne écartée |
| 5 | composante | texte |
| 6 | date de fixation | cellule date, ou texte yyyy-MM-dd |
| 7 | taux | % ÷ 100 ; nombre au point décimal |
Une cellule absente (vide dans le classeur) dans l’une des sept colonnes écarte la ligne (déduit du code).
Au calcul, une ligne s’applique à l’opération dont la référence, coupée au premier _, a ce numéro pour deuxième partie ; elle ne s’applique que jusqu’à date de fixation + fréquence — sans fréquence, elle ne s’applique jamais. Plusieurs lignes pour une même opération : erreur, aucune n’est utilisée (§4.5 de la méthodologie).
Source : risk-import CLDataImporter.buildCashFlows, RateCurveHelper, PrefixingLines.
9. Balance comptable
| Classeur Excel | Fichier texte (.txt, .csv) |
|
|---|---|---|
| Où | onglet i1-balance (absent → l’import échoue) ; ligne 1 = en-tête |
pas d’en-tête : la première ligne est une ligne de compte |
| Séparateur | — | le plus fréquent de ;, tabulation, ,, \| sur la première ligne (à égalité, dans cet ordre) |
| Encodage | — | UTF-8 |
| Colonnes | A date, B compte, C libellé, D montant | 1 compte, 2 libellé, 3 montant, 4 date ; les suivantes sont ignorées ; une ligne plus courte est complétée de cellules vides |
| Compte | cellule numérique → entier ; texte (H96…) tel quel ; vide → ligne écartée |
tel quel |
| Libellé | texte ; vide → ligne écartée | texte, espaces autour retirés à la modélisation |
| Montant | §2.2 ; vide → ligne écartée | idem |
| Date | cellule date, vide, ou texte ddMMyyyy ; autre → ligne écartée |
texte ddMMyyyy obligatoire ; vide ou autre → ligne écartée |
| Autre extension | l’import échoue |
Une ligne écartée est signalée avec son numéro et son contenu brut. Les lignes de balance ne deviennent des opérations que si une stratégie du modèle d’écoulement les couvre (§4.1).
Un fichier texte enregistré en « UTF-8 avec BOM » garde la marque BOM devant le premier compte, qui ne commence alors plus par le préfixe d’une stratégie et n’est pas modélisé, sans anomalie (déduit du code). Enregistrez la balance en UTF-8 sans BOM.
Source : risk-import CLDataImporter.parseAccountingData, DataImportHelper.readTxtFile, DataImportHelper.detectSeparator, BaseImporter.
10. Anomalies émises à l’import
Le type est celui du filtre Code ou type du journal des anomalies. Chaque anomalie porte aussi un code, décrit dans la Référence des anomalies : domaines IMP, VAL, CRV, TRX, CLS et BAL pour l’import, émises par risk-app, pour la plupart par la bibliothèque risk-import (Service émetteur).
| Type | Niveau | Émise quand |
|---|---|---|
Upload |
ERROR |
archive vide, qui n’est pas un zip, ou refusée (risk-app) |
BadContent |
ERROR |
archive ou fichier JSON illisible, limite de décompression dépassée |
MissingInput |
ERROR |
fichier obligatoire introuvable, nom déclaré vide |
UnknownDataFormat |
ERROR |
aucun lecteur pour le format de la configuration |
Missing |
ERROR |
donnée indispensable absente (client, pivotCurrency, flux préfixés illisibles…), répétée pour chaque fichier d’opérations |
Index |
WARNING / ERROR |
courbe à plus de 50 jours de l’arrêté (WARNING) ; index du mapping absent du fichier de taux, index d’actualisation non mappé (ERROR) |
RateCurveParsing |
WARNING / ERROR |
ligne de courbe ignorée, plusieurs onglets de courbes (WARNING) ; colonne de courbe manquante (ERROR) |
CompoundCurve |
ERROR |
courbe composée impossible à construire |
MissingCurve |
ERROR |
l’index d’actualisation ne désigne aucune courbe du contexte |
EvaluationContext, Accounting |
ERROR |
fichier de taux ou de balance illisible : l’import échoue |
Accounting / AccountType |
WARNING |
comptes de la balance que ni la classification ni accountingMapping ne type, par classe (nombre, solde) |
Classification |
WARNING / ERROR |
ligne ou onglet de classification (§5), opérations sans compte (§5.4) |
CashFlows |
WARNING / ERROR |
flux préfixés (§8) |
Parsing |
WARNING / ERROR |
valeur illisible (Cannot parse '…' with value '…'), coupon vide d’un titre, deux dates de call |
Mapping |
INFO / WARNING / ERROR |
libellé de taux non mappé, sens par défaut, encours différent, compte de classification manquant |
Import |
INFO / WARNING / ERROR |
fichier d’opérations illisible, onglet ignoré, lecture interrompue |
ImportTransaction |
ERROR |
ligne d’opération rejetée, avec la ligne brute |
ImportSynthesis |
INFO / ERROR |
bilan Imported n lines from m de chaque fichier ou onglet |
Direction, DayCount |
WARNING |
sens déduits, bases par défaut, une fois par fichier |
ConstraintViolation |
ERROR |
valeur obligatoire manquante sur une opération, le portefeuille ou le contexte ; l’objet est conservé |
UnexpectedError |
ERROR |
erreur imprévue ; l’import échoue |
Persistence |
ERROR |
risk-app n’a pas pu enregistrer le résultat |
Toute opération rejetée pour une cause que l’import sait nommer termine son message par The deal is not imported., sur la référence de l’opération. Une opération rejetée par une erreur imprévue garde le message générique Cannot parse a transaction of '<fichier>': …, sur le fichier.
Source : risk-import SituationImport, DataImportHelper, CLDataImporter, CLCurveImporter, TransactionParser ; risk-app ImportService.
11. Limites connues
- Un seul format :
CREDIT_LOGEMENT. Les vuesIRRBB_MM,Swaps_IRRBB,Securities_IRRBBetREPOsont les seules lues ; les nantissements (NANT-…) sont rejetés. - Numéros d’opération : un numéro lu dans une cellule numérique est converti en entier 32 bits ; au-delà de 2 147 483 647 il est faussé, et ses décimales sont perdues (même règle dans l’onglet
histo). Les doublons ne sont pas détectés. Un numéro contenant_ne peut pas être rapproché d’un flux préfixé. - Courbes en Excel : une ligne de moins de 8 cellules remplies est ignorée sans anomalie ; un classeur qui ne porte que les cinq colonnes requises ne donne aucune courbe. Le fichier texte n’a pas cette limite.
- Devise des pensions et des postes modélisés : toujours EUR.
- Fréquence de révision : enregistrée mais pas utilisée ; le taux variable est révisé à chaque échéance de paiement.
- Sections
frequencyetrateTypedu mapping : non lues. - Date de la balance : obligatoire et au format
ddMMyyyydans un fichier texte, alors qu’elle ne sert pas au calcul (à confirmer). - Contrôle fichier par fichier : sans classification, sans courbes, sans date d’arrêté et sans contrôles de cohérence (§1).
- Mapping de production : les extractions réelles et leur mapping de production ne sont pas dans le dépôt ; cette page décrit les règles du code, valables quel que soit le mapping, et les colonnes du mapping livré.