hugo-relie/content/fr/posts/firefly-action-management/index.md

6.7 KiB

title date draft
Gérer son épargne en action sous Firefly 2023-12-19T20:10:42+02:00 true

Problématique

Gestion du portefeuille

Valeur d'une action

Comme énoncé précédemment, la valeur d'un portefeuille d'actions dépend de la composition de ce portefeuille (donc de quelles actions et en quelle quantité), et de la valeur unitaire de chacune de ces actions.

Cette valeur unitaire est définie par les marchés financiers et varie continuellement. On considère que la valeur d'une action est le prix du dernier ordre d'achat passé pour cette action sur les marchés financiers.

{{< callout type="example" >}} Considérons la valeur "MSCI World" (un ETF trackant les valeurs des plus grosses entreprises dans le monde entier). Au 10 décembre, les marchés financiers s'ouvrent avec la valeur de 27.13€ par part pour cette valeur. à 9h05, une personne passe un ordre d'achat de 15 actions au prix de 27.17€. Dès que cet ordre est exécuté, on considère que l'action "MSCI World" a la valeur de 27.17€ par action. {{< /callout >}}

Dans mon cas, je n'ai absolument pas besoin d'une mise à jour rapide des valeurs, une mise à jour quotidienne est largement suffisante pour mes besoins, et une mise à jour hebdomadaire pourrait même convenir à vrai dire.

J'ai choisi donc de considérer pour chaque action, sa valeur au moment de la cloture des marchés (17h). Mais comment calculer cette valeur ?

Obtenir la valeur d'une action

À la recherche d'une API

Pour le reste de cet article, je considèrerai l'action "MSCI Monde" en titre d'exemple. Avec un navigateur, on arrive facilement à obtenir les informations que l'on veut :

Cependant, il s'agit d'information destinées à un visionnage humain, aucune API n'est publiquement disponible pour obtenir ces informations de façon automatisée.

En faisant des recherches sur le sujet, je me heurte rapidement à deux problèmes :

  • soit je trouve des services gratuits, mais limités, soit en quantité d'appels (5 appels par jour par exemple) soit en fonctionnalités (pas d'ETF)
  • soit je trouve des services... chers. De l'ordre d'au moins plusieurs dizaines d'euros par mois, ce qui est complètement en dehors du cadre d'un projet de ce type.

De plus, la majorité des API disponibles sont basées sur les marchés américains. Étant dans des marchés européens, il est encore plus difficile d'obtenir les informations voulues.

Scraping d'Euronext

Finalement, la solution la plus simple revient à faire du scraping d'un site pertinent (cela expose aux protections anti-bot, mais je n'en ai pas vu sur le site d'Euronext que j'ai décidé d'utiliser, et le volume de requêtes est en pratique très faible).

Mon point de départ est la fiche d'une action: prenons notre habituel MSCI world.

Toutes les valeurs intéressantes se trouvent sur un bandeau de la fiche de la valeur. Ici il s'agit du dernier cours traité de 27.188€.

Bandeau des valeurs de l'action MSCI world sur le site Euronext

En observant le contenu de la page web, on obtient d'ailleurs ceci :

<div class="col text-ui-grey-0 font-weight-bold data-header-cash ">
    <div class="lastprice_min_height  pb-1 ">
        <span class="data-50 " id="header-instrument-currency"></span>
        <span class="data-60" id="header-instrument-price">27,188</span>
    </div>
</div>

Il suffirait donc de faire un petit script de scraping accédant à l'élément possédant l'id #header-instrument-price pour obtenir directement la valeur voulue. Mais on peut faire encore mieux en observant les requêtes AJAX effectués depuis le navigateur.

Une requête en particulier est intéressante, puisqu'elle interroge la route https://live.euronext.com/intraday_chart/getChartData/FR0011869353-XPAR/intraday et renvoie un tableau JSON ayant la forme suivante (le tableau est tronqué, mais contient plus de 1000 éléments):

[
    {"time":"2023-12-12 17:29","price":26.879999999999999,"volume":11},
    {"time":"2023-12-13 09:04","price":26.974,"volume":1888},
    ...
    {"time":"2023-12-19 17:35","price":27.187999999999999,"volume":32}
]

Chaque ligne du tableau contient un ordre d'achat passé au cours de la journée. La valeur intéressante correspond à la dernière ligne de ce tableau : il s'agit du dernier ordre passé, et correspond donc exactement à la valeur affichée sur la fiche de la valeur, et est donc la valeur que l'on souhaite obtenir.

À partir de là, la fonction Python suivante est suffisante pour obtenir la valeur d'une action donnée

EURONEXT_BASE_URL = "https://live.euronext.com/intraday_chart/getChartData"


class StoredAction(NamedTuple):
    name: str
    value: float
    date: str


class Action(NamedTuple):
    name: str
    code: str


def get_last_value_for_action(action: Action) -> StoredAction:
    url = f"{EURONEXT_BASE_URL}/{action.code}/intraday"
    resp = requests.get(url)
    resp_json = resp.json()
    if len(resp_json) < 1:
        raise ValueError("Empty list of values")
    last_value = resp_json[-1]
    try:
        return StoredAction(
            name=action.name,
            value=last_value["price"],
            date=last_value["time"],
        )
    except KeyError as exc:
        raise ValueError("Invalid format for response") from exc

Il suffit de trouver le code associé à l'action voulue. Je le trouve à partir de l'URL de la fiche produit de l'action cherchée. Dans notre exemple, il s'agit de https://live.euronext.com/fr/product/etfs/fr0011869353-xpar/lyxor-msci-wor-pea/ewld. Le code est donc fr0011869353-xpar.

{{< callout type="warning" >}} De façon surprenante, la deuxième partie du code est sensible à la casse et doit être en majuscules :

  • fr0011869353-xpar ne renverra aucun résultat
  • fr0011869353-XPAR renverra le résultat attendu
  • FR0011869353-XPAR renverra aussi le résultat attendu
  • FR0011869353-xpar ne renverra aucun résultat {{< /callout >}}

À partir de ces éléments, il m'est donc possible de calculer la valeur de mon portefeuille à partir de son contenu. Il me reste deux questions à résoudre :

  • comment stocker le contenu de ce portefeuille, et le mettre à jour à chaque fois que j'achète une action ? (ou vend)
  • comment mettre à jour la valeur totale de mon portefeuille telle qu'elle apparaît sur FireflyIII ?

Lien avec Firefly