Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 37 additions & 7 deletions .github/workflows/versement.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ jobs:
incr = [l.rstrip("\n") for l in f if l.strip()]

refus = []
quarantaine: dict[str, list[str]] = {}
if tete != entete:
refus.append(f"en-têtes différents : {tete!r} vs {entete!r}")

Expand Down Expand Up @@ -331,15 +332,17 @@ jobs:
valeur = float(cloture)
if valeur <= 0:
absurdes.append(f"{date} {ticker} {valeur}")
quarantaine.setdefault(date, []).append(
f"clôture {valeur} sur {ticker}")
veille = derniers.get(ticker)
if veille:
ecart = valeur / veille - 1
if abs(ecart) > 0.0751:
hors.append(f"{date} {ticker} {ecart:+.2%}")
derniers[ticker] = valeur
if absurdes:
refus.append(f"{len(absurdes)} clôtures nulles ou négatives : "
+ ", ".join(absurdes[:5]))
print(f"{len(absurdes)} clôtures nulles ou négatives : "
+ ", ".join(absurdes[:5]))

# LA SÉANCE REPUBLIÉE, ET J'EN AI VERSÉ UNE. Le 6 août 2026 a été
# « rattrapé » par rapatriement, et les 47 lignes obtenues étaient
Expand Down Expand Up @@ -374,10 +377,10 @@ jobs:
repetees = sum(1 for t, v, c in valeurs
if derniers_volumes.get(t) == (v, c))
if repetees >= 0.9 * len(valeurs):
refus.append(
f"séance {date} : {repetees}/{len(valeurs)} valeurs au "
"volume ET au cours identiques à leur séance "
"précédente — séance republiée, pas une séance neuve")
quarantaine.setdefault(date, []).append(
f"{repetees}/{len(valeurs)} valeurs au volume ET au "
"cours identiques à leur séance précédente — séance "
"republiée, pas une séance neuve")

# LA LIMITE DE ±7,5 % EST DÉCRITE, JAMAIS OPPOSÉE, et ce n'est pas
# de la mollesse — c'est ce que le projet a MESURÉ. Sur l'archive,
Expand All @@ -400,15 +403,42 @@ jobs:
f"({', '.join(hors[:5])}) — décrites, pas opposées. "
"« brvm qualite » les range par cause probable.")

# DEUX NIVEAUX DE REFUS, ET LE DEUXIÈME EST NÉ D'UN DÉFAUT RÉEL.
#
# `refus` porte ce qui met en cause l'incrément ENTIER : en-têtes
# différents, lignes déjà présentes, lignes antérieures sur des
# séances connues. Ce sont des signaux de dysfonctionnement, pas
# des données douteuses, et rien ne doit s'écrire.
#
# `quarantaine` porte les séances individuellement suspectes. Le
# tout ou rien s'y montrait ruineux : le 6 août republié dort dans
# un artefact pendant trente jours, et il aurait bloqué CHAQUE
# versement suivant — la bonne séance du jour refusée avec lui, le
# pipeline arrêté par une seule donnée fautive que personne n'a le
# temps de retirer. On écarte donc la séance, et on verse le reste.
if refus:
print("VERSEMENT REFUSÉ :")
print("VERSEMENT REFUSÉ EN BLOC :")
for motif in refus:
print(f" - {motif}")
print("\nL'incrément part dans le journal ; à verser à la main "
"après examen.")
sortie(applique="false", motif="controle")
raise SystemExit(0)

if quarantaine:
print("SÉANCES ÉCARTÉES, le reste est versé :")
for date, motifs in sorted(quarantaine.items()):
for motif in motifs:
print(f" - {date} : {motif}")
avant = len(incr)
incr = [l for l in incr if cle(l)[0] not in quarantaine]
print(f" {avant - len(incr)} lignes retirées de l'incrément.")
if not incr:
print("\nRien ne subsiste : l'incrément part dans le "
"journal, à examiner.")
sortie(applique="false", motif="quarantaine")
raise SystemExit(0)

# LA GARANTIE N'EST PLUS « ÇA S'AJOUTE EN QUEUE » : combler un trou
# insère au milieu. Ce qui doit rester vrai, et qui est vérifié
# ici, c'est que la fusion est triée, qu'elle ne perd aucune ligne
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,14 @@ ressusciter 38 séances fantômes — tri préservé, aucune clôture nulle ou
négative, et **aucune séance republiée**. Un seul contrôle qui tombe
annule le versement.

**Une séance douteuse n'arrête pas les autres.** Ce qui met en cause
l'incrément entier — en-têtes, lignes déjà présentes, lignes antérieures
sur une séance connue — bloque tout : ce sont des signaux de
dysfonctionnement. Une séance individuellement suspecte, elle, est
**écartée seule** et le reste est versé. Le tout ou rien s'est montré
ruineux : un artefact fautif vit trente jours, et il aurait bloqué chaque
versement suivant — la bonne séance du jour refusée avec lui.

La séance republiée mérite son nom : le 6 août 2026, rattrapé par
rapatriement, est revenu avec les 47 cours et les 47 volumes du 7 — la
même séance sous une autre date. Versée, elle a mis toutes les variations
Expand Down
Loading