Files
extractions-actions/README.md
T

16 KiB

extractions-actions

Routines PHP et script Bash permettant d'extraire automatiquement les cotations des actions composant le CAC 40, l'IBEX 35 et le Dow Jones, puis de les enregistrer dans MySQL.

Le projet utilise principalement :

  • PHP
  • PDO
  • MySQL
  • cURL
  • DOMDocument / DOMXPath
  • Bash
  • cron
  • Investing.com comme source des cotations

Le dépôt est disponible sur :

https://www.phie-st-julien.com/jfgiraud/extractions-actions


Fonctionnement général

Le système est organisé autour de deux tables principales :

indice
   │
   │ Référentiel des valeurs
   │
   ▼
Scripts PHP
   │
   │ Extraction Investing.com
   │
   ▼
cours_actions

La table indice constitue le référentiel de référence.

Les scripts récupèrent les informations de marché sur Investing.com mais utilisent les informations de la table indice pour conserver les données d'identification des valeurs :

  • nom
  • ISIN
  • symbole
  • indice

Les cotations sont enregistrées dans cours_actions.


Routines disponibles

Le dépôt contient actuellement quatre fichiers :

extractions-actions/
│
├── import_cac40.php
├── import_ibex35.php
├── import_dowjones.php
├── import_indices.sh
└── README.md

Le dépôt contient actuellement 4 commits et une branche main.


1. import_cac40.php

Routine d'importation des actions du CAC 40.

Source Investing.com :

https://www.investing.com/indices/france-40-components

Le script :

  1. se connecte à MySQL ;
  2. charge le référentiel CAC 40 depuis la table indice ;
  3. sélectionne uniquement les valeurs avec actif = 1 ;
  4. récupère la page Investing.com avec cURL ;
  5. analyse le HTML avec DOMDocument et DOMXPath ;
  6. identifie le tableau contenant les cotations ;
  7. récupère les données de marché ;
  8. fait correspondre les valeurs avec le référentiel MySQL ;
  9. enregistre les cotations dans cours_actions.

Le script vérifie également que le référentiel contient normalement 40 valeurs.


2. import_ibex35.php

Routine d'importation des actions de l'IBEX 35.

Source Investing.com :

https://www.investing.com/equities/spain

Le principe est identique à celui du CAC 40.

Le référentiel est chargé depuis :

indice

avec :

WHERE indice = 'IBEX35'
AND actif = 1

Les informations de cotation sont ensuite récupérées sur Investing.com.

Le script précise notamment que :

  • le nom Investing sert à retrouver la valeur dans indice ;
  • le symbole Investing n'est pas utilisé comme référence ;
  • le nom, l'ISIN et le symbole proviennent de indice ;
  • la table indice n'est pas modifiée ;
  • les dates sont générées en UTC.

3. import_dowjones.php

Routine d'importation des valeurs du Dow Jones Industrial Average.

Source Investing.com :

https://www.investing.com/equities/americas

Le script utilise également la table indice comme référentiel.

Seules les valeurs :

indice = 'DOWJONES'
AND actif = 1

sont prises en compte.

Le script effectue la correspondance sur le nom de la société.

Une particularité du traitement consiste à supprimer derived du nom provenant d'Investing.com lorsque nécessaire afin de permettre la correspondance avec le référentiel.


Identification des actions

Un principe important du projet est la séparation entre :

référentiel

indice

et :

source de cotation

Investing.com

Investing.com fournit principalement les informations de marché.

Le référentiel interne fournit les informations d'identification :

nom
isin
symbole
indice

Ainsi, une modification du symbole utilisé par Investing.com ne modifie pas automatiquement le référentiel interne.


Table indice

La table indice constitue le référentiel des valeurs.

Les principaux champs utilisés par les routines sont :

indice
nom
isin
symbole
actif

Exemple conceptuel :

indice    : CAC40
nom       : LVMH
isin      : FR0000121014
symbole    : MC
actif     : 1

Le champ :

actif

permet de préparer les changements de composition d'un indice sans modifier immédiatement les routines d'importation.

Une valeur peut ainsi être présente dans le référentiel mais ne pas être importée tant que :

actif = 0

Table cours_actions

Les cotations sont enregistrées dans :

cours_actions

Les champs utilisés par les routines comprennent :

indice
nom
isin
symbole
cours
plus_haut
plus_bas
variation
variation_pct
volume
date_cours
source

Le script CAC 40 utilise notamment une requête préparée sur ces colonnes.


Mise à jour des cotations

Les routines utilisent :

ON DUPLICATE KEY UPDATE

Cela permet de mettre à jour une cotation existante plutôt que de créer inutilement un doublon.

Les informations mises à jour comprennent notamment :

nom
isin
symbole
cours
plus_haut
plus_bas
variation
variation_pct
volume
date_cours
source

Ainsi, chaque nouvelle extraction actualise les informations correspondantes dans cours_actions.


Données extraites

Les routines récupèrent notamment :

Donnée Description
cours Dernier cours
plus_haut Plus haut
plus_bas Plus bas
variation Variation en valeur
variation_pct Variation en pourcentage
volume Volume
date_cours Date et heure de l'extraction
source Source de la cotation

Les valeurs numériques sont nettoyées et converties avant insertion dans MySQL.


Traitement des nombres

Les routines prennent en compte les formats rencontrés sur les pages de cotation.

Le traitement permet notamment de gérer :

  • espaces ;
  • espaces insécables ;
  • % ;
  • virgules décimales ;
  • points décimaux ;
  • suffixes K ;
  • suffixes M ;
  • suffixes B.

Exemple :

1.25K

est converti en :

1250

et :

2.5M

en :

2500000

Gestion des erreurs

Les routines vérifient notamment :

  • connexion MySQL ;
  • récupération HTTP ;
  • erreurs cURL ;
  • contenu HTML vide ;
  • présence du tableau recherché ;
  • structure du tableau ;
  • données non numériques ;
  • valeurs non trouvées dans le référentiel.

En cas d'échec, un message est écrit dans la sortie du script.

Pour le CAC 40, la page HTML récupérée peut également être sauvegardée dans :

/tmp/investing_cac40_error.html

lorsque le tableau attendu n'est pas trouvé.


import_indices.sh

Le script :

import_indices.sh

constitue le lanceur automatique des trois routines PHP.

Il permet d'éviter d'exécuter les imports lorsque les marchés concernés sont fermés.

Il utilise également un verrou flock afin d'empêcher plusieurs exécutions simultanées.


Protection contre les exécutions simultanées

Le script utilise :

LOCK="/var/run/import_indices.lock"

puis :

exec 9>"$LOCK"

if ! flock -n 9; then
    exit 0
fi

Ainsi, si une instance précédente est encore en cours, une nouvelle instance quitte immédiatement.

Cela est particulièrement important lorsque le script est appelé par cron toutes les minutes.


Journalisation

Les logs sont enregistrés dans :

/var/log/import_indices.log

Pour chaque import, le script écrit notamment :

DATE - DEBUT CAC40
DATE - FIN CAC40 (CODE)

Même principe pour :

IBEX35
DOW JONES

Le code retour PHP est conservé dans le journal.


Horaires d'exécution

Le script utilise le fuseau :

Europe/Paris
export TZ="Europe/Paris"

Il ne lance aucun import le week-end.

CAC 40

Fenêtre d'extraction :

09:00 → 17:30

IBEX 35

Fenêtre d'extraction :

09:00 → 17:30

Dow Jones

Fenêtre d'extraction :

15:30 → 22:00

Ces horaires sont contrôlés directement par import_indices.sh.


Fonctionnement avec cron

Le principe recommandé est de faire tourner le script Bash régulièrement, par exemple toutes les minutes :

* * * * * /var/www/extractions/import_indices.sh

Le script décide ensuite lui-même si un marché est ouvert.

Cela signifie que cron peut être lancé chaque minute sans provoquer d'import lorsque :

  • nous sommes le week-end ;
  • l'heure est en dehors des horaires prévus ;
  • une autre instance du script est déjà en cours.

Flux complet

                         CRON
                          │
                          ▼
                ┌─────────────────┐
                │ import_indices.sh│
                └────────┬────────┘
                         │
             ┌───────────┼───────────┐
             │           │           │
             ▼           ▼           ▼
          CAC 40       IBEX 35    DOW JONES
             │           │           │
             ▼           ▼           ▼
       Investing.com Investing.com Investing.com
             │           │           │
             └───────────┼───────────┘
                         │
                         ▼
                  Correspondance
                   avec `indice`
                         │
                         ▼
                  `cours_actions`
                         │
                         ▼
                     MySQL GF

Principe de sécurité des données

Les scripts ne modifient pas le référentiel indice.

Le référentiel est considéré comme la source interne de vérité pour :

ISIN
symbole
nom
indice

Les routines ont pour rôle de récupérer les cotations et de mettre à jour :

cours_actions

Cette séparation permet d'éviter qu'une modification de la page Investing.com ne vienne écraser les informations de référence.


Configuration MySQL

Les scripts utilisent actuellement la base :

GF

avec une connexion locale MySQL.

La configuration est présente au début de chaque routine PHP.

Exemple :

$dbHost = 'localhost';
$dbName = 'GF';
$dbUser = 'root';

Attention : le mot de passe MySQL ne doit pas être stocké en clair dans un dépôt Git.

Pour une installation de production, il est recommandé d'utiliser :

  • un fichier de configuration hors dépôt ;
  • des variables d'environnement ;
  • un utilisateur MySQL dédié avec les droits minimum nécessaires.

Dépendances PHP

Les routines utilisent notamment :

PDO
PDO_MySQL
cURL
DOMDocument
DOMXPath
mbstring

Les extensions PHP nécessaires doivent donc être installées sur le serveur.


Installation

Copier le projet dans le répertoire souhaité :

cd /var/www
git clone https://www.phie-st-julien.com/jfgiraud/extractions-actions.git

Rendre le script Bash exécutable :

chmod +x /var/www/extractions/import_indices.sh

Tester individuellement les routines :

php /var/www/extractions/import_cac40.php
php /var/www/extractions/import_ibex35.php
php /var/www/extractions/import_dowjones.php

Puis tester le lanceur :

/var/www/extractions/import_indices.sh

Vérification des logs

Consulter le journal :

tail -f /var/log/import_indices.log

Pour rechercher les erreurs :

grep -i "erreur" /var/log/import_indices.log

Pour voir les derniers imports :

tail -100 /var/log/import_indices.log

Vérification MySQL

Après une extraction, vérifier les dernières cotations :

SELECT *
FROM cours_actions
ORDER BY date_cours DESC
LIMIT 20;

Pour un indice donné :

SELECT *
FROM cours_actions
WHERE indice = 'CAC40'
ORDER BY date_cours DESC;

Pour l'IBEX 35 :

SELECT *
FROM cours_actions
WHERE indice = 'IBEX35'
ORDER BY date_cours DESC;

Pour le Dow Jones :

SELECT *
FROM cours_actions
WHERE indice = 'DOWJONES'
ORDER BY date_cours DESC;

Vérification du nombre de valeurs

CAC 40 :

SELECT COUNT(*)
FROM indice
WHERE indice = 'CAC40'
AND actif = 1;

IBEX 35 :

SELECT COUNT(*)
FROM indice
WHERE indice = 'IBEX35'
AND actif = 1;

Dow Jones :

SELECT COUNT(*)
FROM indice
WHERE indice = 'DOWJONES'
AND actif = 1;

Cela permet de détecter rapidement une modification de composition ou une valeur manquante.


Maintenance

Lorsqu'une entreprise entre ou sort d'un indice, la modification doit être effectuée dans :

indice

et non directement dans les routines PHP.

Le principe est :

Modification du référentiel
        ↓
indice
        ↓
Les routines utilisent automatiquement
le nouveau référentiel

Le champ actif permet notamment de préparer une modification future avant son activation.


Ajout d'un nouvel indice

Pour ajouter un nouvel indice, le principe consiste à :

  1. créer le référentiel dans indice ;
  2. ajouter une routine PHP dédiée ;
  3. identifier la page source ;
  4. adapter le parsing HTML ;
  5. utiliser le référentiel interne pour l'ISIN et le symbole ;
  6. écrire les cotations dans cours_actions ;
  7. ajouter la routine au script import_indices.sh ;
  8. définir les horaires de marché ;
  9. tester manuellement ;
  10. intégrer l'exécution dans cron.

Limites

Les routines dépendent de la structure HTML des pages Investing.com.

Une modification du site source peut donc nécessiter une adaptation du parsing :

DOMDocument
DOMXPath

Il est donc important de conserver les tests et les contrôles de cohérence présents dans les scripts.


Évolution prévue

Le projet peut progressivement intégrer :

  • Nasdaq-100 ;
  • S&P 500 ;
  • DAX ;
  • FTSE 100 ;
  • Euro Stoxx 50 ;
  • autres indices ;
  • détection automatique des changements de composition ;
  • gestion des jours fériés ;
  • contrôle automatique du nombre de valeurs ;
  • alertes en cas d'échec d'import ;
  • centralisation de la configuration MySQL ;
  • journalisation plus détaillée ;
  • surveillance du fonctionnement du cron.

Relation avec le site boursier

Les données produites par ce projet peuvent ensuite être utilisées par le site d'affichage des actions.

Le flux devient :

Investing.com
      │
      ▼
extractions-actions
      │
      ▼
MySQL
      │
      ├── indice
      │
      └── cours_actions
              │
              ▼
        Site boursier
              │
              ├── tableau des actions
              │
              └── bandeau défilant

Les routines d'extraction constituent donc la couche d'alimentation du système boursier.


Résumé

Composant Rôle
indice Référentiel des actions
import_cac40.php Extraction CAC 40
import_ibex35.php Extraction IBEX 35
import_dowjones.php Extraction Dow Jones
cours_actions Stockage des cotations
import_indices.sh Orchestration des imports
cron Déclenchement périodique
Investing.com Source des cotations
MySQL Base de données

Auteur

jfgiraud

Projet personnel de collecte et d'alimentation d'une base de données boursière.

Technologies :

PHP · MySQL · PDO · cURL · DOMXPath · Bash · cron