Itération 0.1 : Squelette de l’Interface Graphique

Comme on a déjà pas mal parlé de l’interface graphique et qu’on commence à avoir une bonne idée de ce qu’on veut, je pense que cette itération est le moment de créer le squelette sur lequel les autres packages pourront se reposer pour afficher des vues.

Phase d’inception :

L’Interface c’est principalement un moniteur d’informations et une télécommande qui permet d’envoyer des actions à faire, des informations ou encore des évènements.

Et tout comme l’application entière cette Vue Globale est divisée en plusieurs parties. Chacune d’entre elle offrant une panoplie d’informations et d’outils permettant de contrôler et agir sur l’application.

Par exemple on aura la vue des charts qui va afficher les données d’un marché, et on aura la vue des actions permettant d’afficher des sous vues différentes dont par exemple la sélection du marché à afficher, ou la vue qui permettra de configurer un indicateur à afficher, etc..

Reprenons le schéma que j’avais fait dans un précédent article, avec quelques modifications :

  1. APPLICATION_TITLE : On a la vue globale, la Fenêtre, avec son titre et des boutons de contrôle (réduire, plein écran et fermer).
  2. PRIMARY_MENU : Le menu global de l’application
  3. CHARTS_WIDGET_VIEW : La vue des Charts, celle où seront affiché les graphiques des données de marchés et d’indicateurs.
  4. ACTIONS_WIDGET_VIEW : La vue des Actions, celle où seront affiché les sous vue d’actions possible (formulaire, informations, menu d’action, etc..)
  5. STATUS_BAR : La barre de status qui permettra d’afficher le statut de l’application et de ce qu’il s’y passe en permanence.

Le Primary Menu :

Devrait pouvoir fournir des accès à des outils globaux ou des actions globales (par exemple un CTRL+Z, les copier/coller, etc.), des vues de configurations globales à l’application par exemple la configuration des clé d’authentification aux différentes plateformes.

Le Top Menu Chart :

Conteneur de bouton d’action de menu lié à la Chart Widget, il devra pouvoir fournir des actions, des routes vers des vues, des événements lié au Chart Widget.

Par exemple, nous voulons ajouter un indicateur à notre Chart, il devrait pouvoir y avoir un bouton pour ça. Ce bouton ouvrirait une vue de configuration dans l’Actions Widget

Chart Widget Views :

Conteneur de vues des Charts. Que ce soit les données des marchés (Candles et indicateurs directement sur les candles), les données d’indicateurs dans des sous Widgets, etc.

Actions Widget Views

Conteneur de vues des Actions. Recevra les vues des actions à entreprendre sur l’application. Par exemple, on voudrait configurer un indicateur pour un marché, le formulaire se retrouvera dedans.
On voudrait configurer les accès utilisateur à une plateforme, on voudrait avoir la vue sur le formulaire de prise de position, on voudrait avoir la vue de configuration d’un pattern, ou une configuration d’intelligence artificielle, toutes ces vues se retrouveront là.

Actions Menu Widget Views :

Conteneur de bouton d’actions de menu lié à la vue Actions Menu, pour avoir accès rapidement à des vues de configuration, par exemple la prise de position sur un marché. Ou quand on veut pouvoir voir un autre marché sur une autre plateforme, etc. 

Phase d’Élaboration :

Première chose qu’on peut constater c’est que le squelette est principalement composé de conteneurs de widget. Il faut donc pouvoir permettre aux packages d’ajouter des widget à chaque conteneur. Que ce soit pour les montrer tout de suite ou pour les montrer plus tard.

Ensuite il faudra que chaque partie puisse communiquer et agir de concert avec les autres vues et le reste de l’application.

Pour cela, j’ai décidé d’utiliser le pattern Médiateur (ou Mediator en anglais). C’est un des design pattern standard qu’on retrouve un peu partout. Grosso merdo il permet à des participants de se transmettre des messages et d’écouter des canaux de communication. 

Les participants ici seront de différents type, container, widget, et package. Chacun ayant un rôle précis à jouer.

Mediator :

Le médiateur peut enregistrer des participants dans une liste interne. Chaque participants s’adresse au médiateur pour lui demander d’envoyer un message à un ou plusieurs autres participants.
Le médiateur se charge donc de parcourir la liste et de trouver tous les participants sélectionné par l’auteur du message et leur transmettre celui-ci. 

C’est un algorithme assez simple qu’on peut illustrer dans un use case comme ceci :

Après cette vue simpliste on doit pouvoir y apporter quelques améliorations. Par exemple il pourrait être intéressant pour un participant d’écouter un canal d’événement. 

Pour ce faire il suffit de rajouter un tableau dans lequel chaque participant pourra s’inscrire sur des nom de canaux d’événements.
Cette inscription sur l’event introduit directement la méthode à exécuter lorsque l’événement se produit.
On pourrait même aller encore plus loin et définir des action qui pourrait se passer avant et/ou après l’événement défini, mais ça je verrais plus tard si l’application l’exige.

Le schéma de use case se transformerait en ceci :

Il suffit de rajouter une méthode d’enregistrement à un événement et de rajouter un lien d’inclusion dans la méthode send pour définir qu’envoyer un message inclus d’envoyer l’événement aussi et d’exécuter la méthode fournie par le Subscriber Three.

Package :

Le Package est un participant qui doit pouvoir envoyer et recevoir des messages venant du médiateur afin de pouvoir communiquer avec les autres participants.
Par exemple, il doit pouvoir envoyer des messages de mise à jours de données sur un canal, cela permet à toutes les vues de se mettre à jour on les inscrit sur ce canal.

Dans un autre sens, le Package peut s’inscrire sur un ou plusieurs canaux d’événements lui permettant de savoir si un bouton à été cliqué, si un formulaire à été envoyé, etc..

Enfin, et c’est le point important de cette partie, c’est le package qui inscrit les vues et les widget dont il a besoin dans chaque container. Chaque action sera donc directement inscrite et liée au package. Cela veut dire aussi que chaque canaux d’événement sera créé au moment de la création d’une action et lié à cette action.

Container :

Un Container est un objet qu’on construira pour qu’il puisse contenir des Vues (Vues qu’on appelera aussi Widget). 

L’idée du Container c’est d’être une classe qu’on puisse modifier en fonction de nos besoins. Par exemple, si on veut construire un menu d’action, on étendra un container et on y ajoutera des méthode spécifiques aux menus. 

Même chose pour un container censé contenir différentes vues (par exemple la vue Charts ou la vue Action).

Widgets :

Un/une widget, c’est une vue de un ou plusieurs éléments. Par exemple, un bouton est un widget, tout comme un formulaire complet avec ses bouton, ses input, etc. est un widget aussi.

Les Widget devront donc être contenu dans les Container. 

Phase de Construction :

Cette itération devient quand même bien fournie, comme on entre dans la phase de construction, je pense qu’il est intéressant d’ouvrir une nouvelle série d’itérations dans notre itération actuelle la 0.1

On va donc se lancer dans la construction du médiator et des différentes classes abstraites pour préparer le terrain aux futurs itérations 0.1.x .

Premièrement on va créer notre nouveau Package UI avec son fichier __init__.py, dedans on y mettra les bases du package d’Interface Utilisateur.

UI\__init__.py

from Core import *

class UIPackage(AbstractPackage):
    def __init__(self, root_app):
        AbstractPackage.__init__(self, root_app, 'UI')

        self.mediator = Mediator()

    def add_ui_subscriber(self, subscriber_class, name):
        self.mediator.register(subscriber_class, name)

On importe la classe abstraite des Package et on étant notre class UIPackage avec, comme on l’a fait avec le package State dans le dernier article.

J’inclus déjà le médiateur et une méthode qui permet d’ajouter un subscriber au médiateur car toute l’idée de ce médiateur est centrée sur la gestion de l’interface graphique et de la communication qu’elle peut avoir avec les autres Package.

Maintenant qu’on a notre classe de Package, on va écrire le Mediator, toujours dans le même fichier d’ailleurs.

UI\__init__.py

from Core import *
SEND_TO_ALL = "All"


class Mediator:
    def __init__(self):
        self.subscribers = {}

    def register(self, ui_subscriber_class, name):
        subscriber = ui_subscriber_class(self, name)
        self.subscribers[subscriber.name] = subscriber
        return self.subscribers[subscriber.name]

    def send(self, message, sender, receiver=SEND_TO_ALL):
        if receiver == SEND_TO_ALL:
            for sub in self.subscribers:
                self.subscribers[sub].receive(message, sender)
        elif isinstance(receiver, list):
            for sub in sender:
                self.subscribers[sub].receive(message, sender)
        elif isinstance(receiver, str):
            self.subscribers[sender].receive(message, sender)

# ...

Donc pour faire simple, pour enregistrer un participant on envoie simplement une classe de participant, le médiateur se chargera d’en faire une instance lui même (qu’il renverra aussi tôt).

Ensuite, pour envoyer un message, le médiateur doit recevoir un message à envoyer, une instance de participants qui envoie le message et un ou plusieurs nom de participant. Si aucun récepteur n’est défini, on envoi le message à tout le monde.

Maintenant qu’on a notre Médiateur on peut construire notre classe abstraite à étendre pour construire d’autre classe de participants.

UI\__init__.py

class AbstractUISubscriber:
    def __init__(self, name, mediator):
        self.mediator = mediator
        self.name = name

    def send(self, message, receiver=SEND_TO_ALL):
        self.mediator.send(message, self, receiver)

    def receive(self, sender, message):
        try:
            method = getattr(self, f'{message.method_name}Action')
            method(sender, **message.params)
        except AttributeError as error:
            print(error)

La structure est simple, la classe doit recevoir le nom du participant et le médiateur en paramètres.
Elle se servira du Médiateur pour envoyer des messages et le médiateur se servira d’elle pour recevoir des messages.

Maintenant qu’on est prêt à accueillir les participants dans un médiateur, on va pouvoir passer à la suite et ouvrir une nouvelle série d’itérations pour construire les différents type de participant, package, container et widget dans un prochain article !

J’espère en tout cas que cet article aura été enrichissant pour vous. Merci encore pour l’attention que vous portez à mon projet 😉
Comme à chaque fois, n’hésitez pas à vous inscrire et poster des commentaires !

Remise en question et développement d’une première Architecture

Au fil des quelques articles je me suis senti bloqué par un manque de recul. Je pensais pouvoir établir plein de Use Case, les relier entre eux et voir une architecture sortir d’elle même des schémas. 

A mon avis, c’était une erreur de penser comme ça. Du coup, j’ai pris un peu de recul et je me suis penché sur l’architecture globale que pourrait prendre l’application, et voilà ce que ça donne sous forme d’un schéma :

Pour l’instant, c’est la vision globale de l’architecture que j’ai dans ma tête. L’application est construite sur 4 couches :

  1. Le Root Application, c’est l’instance de notre application, chaque package doit y être enregistré et instancié correctement. Il permettra à tous d’interagir entre eux.
    Chaque package n’aura qu’à appeler celui ou ceux dont il a besoin.
  2. L’Interface Graphique, qui sert à recevoir les commandes et les actions de l’utilisateur via les périphériques (clavier, souris, etc.). L’interface graphique (ou UI pour User Interface) est un des package interne, mais je voulais la voir à part pour pouvoir différencier le Frontend du Backend.
  3. Les Packages Internes, c’est la partie Backend de l’application, tout ce qui se fait en coulisses. Chaque package est connecté au Médiateur qui leur permettra d’être en communication avec tous les autres dès que le besoin s’en fait sentir. 
  4. Package Externes, ce sont des packages déjà existants dont on a besoin pour ne pas avoir à tout créer “from scratch” comme on dit, et surtout pour pouvoir profiter d’outil open source d’une qualité qu’on ne pourrait pas fournir nous même.

Petite remise en question

A vrai dire, je pense que j’ai alourdi les chose en allant directement faire des use case, et des schéma de différents packages alors même que je ne les avaient pas décrit et réfléchi plus que ça. Je pense même que nous venons de finir les phases d’inception et d’élaboration du projet dans son Itération 0.

On a décrit globalement le projet et je savais déjà que le projet est faisable (Phase d’Inception), on a schématisé la première architecture, les différentes composantes de l’application et on a un cahier des charges global, on sait vers où on va (Phase d’Élaboration).

Nous entrons donc en phase de Construction et nous allons pouvoir commencer nos différentes itérations pour la création des différents packages dont nous avons besoin.

Itération 0.0 : Le RootApplication – Phase d’inception

Le Root Application, c’est l’instance de notre application, chaque package doit y être enregistré et instancié correctement. Il permettra à tous d’interagir entre eux.
Chaque package n’aura qu’à appeler celui ou ceux dont il a besoin.

Je rajouterais que le Root Application c’est également ce qui va nous permettre de lancer et initialiser tout le système, donc c’est lui qui va définir comment les choses sont démarrée et quand.

Comme les choses sont assez simples, les phases d’inception et d’élaboration sont relativement vite passée.

J’ai défini les objectifs du RootApplication, j’ai défini sa structure et je me suis également permis de définir une structure de base à étendre pour les Packages. Structure que je rend abstraite car elle n’a pas besoin d’être instanciée elle même.

Enfin je décris les différentes actions possibles avec le RootApplication.

Nous avons une structure, un comportement, il n’y a plus qu’à construire tout ça. Et devinez quoi, je vais enfin pouvoir taper un peu de code nondidju !! xD

Premièrement on va créer notre classe RootApplication.

main.py

import sys


class RootApplication:
    def __init__(self):
        self.packages = {}

        self.register_package("State")
        self.register_package("Exchanges")
        self.register_package("Database")
        self.register_package("HistoricData")
        self.register_package("AI")
        self.register_package("UI")

        self.instantiate_package()

    @staticmethod
    def __import__(package_name):
        try:
            package = __import__(package_name)
            main_class = getattr(package, f'{package_name}Package')
            return main_class
        except ModuleNotFoundError:
            print(f"{package_name} does not exist")
        except:
            print("Unexpected error :", sys.exc_info()[0])

    def register_package(self, package_name):
        package_class = self.__import__(package_name)
        package = package_class(self)
        self.packages[package.name] = package

    def instantiate_package(self):
        for package in self.packages:
            self.packages[package].instantiate()

    def require(self, package_name):
        try:
            return self.packages[package_name]
        except KeyError:
            print(f"Package Error : [{package_name}] is not Registred")
        except:
            print("Unexpected error :", sys.exc_info()[0])

Évidemment si on essaye de créer une instance de RootApplication on obtiendra des erreurs du type : « State Package does not exist ».
Normal, on a pas encore créé nos packages. Ceci dit on peut déjà créer les première classes de nos packages pour continuer la logique de notre.
Pour se faire, on va d’abord créer notre classe abstraite pour avoir des méthodes commune à tous les packages :

Core\__init__.py

class AbstractPackage:
    def __init__(self, root_app, name):
        self.root_app = root_app
        self.name = name
        print(f'[{self.name}] is Registered')

    def instantiate(self):
        print(f'Instantiation of {self.name}')

    def require(self, package_name):
        return self.root_app.require(package_name)

Le code est très simple, lors de la création de n’importe quel package qui étend cette classe, il pourra accéder à la méthode « require » et il pourra aussi lancer la méthode « instantiate » qui permettra de lancer la configuration des packages.

Maintenant qu’on a notre classe abstraite, on va pouvoir l’utiliser pour tous les packages. Chaque package devra donc contenir une classe nommée de manière standard : NomDeClasse + Package (NomDeClassePacakge).
Créons directement le Package State et tapons le code de la classe directement dans le fichier __init__.py :

State\__init__.py

from Core import *


class StatePackage(AbstractPackage):
    def __init__(self, root_app):
        AbstractPackage.__init__(self, root_app, 'State')

Et voilà, on a une classe de Package de base, connectée au RootApplication directement depuis lequel elle peut charger d’autres packages instanciés.
Tout ce petit code permet donc à nos packages de se charger les uns et les autres et d’avoir accès aux méthodes de chacun.

On a désormais notre logique d’échange et de communication entre packages. Il manque quelque chose c’est une série de tests unitaires que je devrais rajouter prochainement. Les tests unitaires sont super importants pour savoir si l’évolution de notre application se fait sans conséquence sur le code déjà écrit.

Voilà, c’est la fin de cet article, et comme vous l’avez vu, on a bouclé assez rapidement une itération. On va pouvoir travailler sur les autres dès les prochains articles. Comme quoi, une petite remise en question, ça aide toujours 😉

Merci pour l’intérêt que vous portez à mon projet, n’hésitez surtout pas à vous inscrire et ajouter des commentaires critiques et/ou constructif 🙂

A bientôt !

Inception, la suite des Use Case

Maintenant qu’on sait comment manipuler les use case de manière basique, concentrons nous sur une base simple d’interface graphique sur laquelle on pourra s’appuyer pour faire le reste des use case. Et surtout, une base qui puisse nous permettre d’ajouter facilement les fonctionnalité au fur et à mesure du développement.

Avant de me lancer dans le reste de l’article je voudrais préciser que le développement UX (pour User eXperience) c’est une discipline vraiment à part et que je risque fortement de faire des erreur de débutant à ce niveau.
Je vais me concentrer sur ce qui me parait logique et/ou intuitif, il se peut donc que des modifications radicales interviennent dans le futur si je me rend compte que j’ai fait de la merde.

Comme vous pouvez le voir, j’ai essayé de faire très simple. Je me suis inspiré d’interfaces que j’ai déjà pu voir, et en général les app ou les site web traitant des charts se présentent de cette façon.

Ce qui est important à garder à l’esprit, c’est le but simple et succint de cette application :

“Pouvoir faire du Trading en étant soutenu par une IA qu’on peut entraîner à tout moment.”

Listons les éléments :

  1. PRIMARY_MENU : “Fichiers, Editions, Outils, etc.”, menu principal de l’application. On y trouvera des accès aux configurations de l’application, gestion des outils, et certainement plein d’autre choses plus “globale”.
  2. TOP_ACTIONS_AND_TOOLS_MENU_BAR : Menu iconique, permettant d’accéder aux actions et outils qui peuvent agir directement sur la vue “CHARTS_WIDGET_VIEW”. L’intérêt de ce menu est de faciliter l’accès aux outils dont aurait besoin le trader. Par exemple, on pourrait y voir un bouton “INDICATEURS” permettant d’avoir accès à la liste des indicateurs.
    Il pourrait y avoir également des boutons pour configurer et sauvegarder des informations sur l’état de la vue (la plateforme, le marché, la timeframe, etc.).
  3. CHARTS_WIDGET_VIEW : Vue centrale qui affiche les graphiques de marchés selon l’état actuel de l’application.
  4. ACTIONS_WIDGET_VIEW : Vue latérale qui affiche des formulaire de configuration, qui donne accès à des actions selon le ou les outils sélectionnés actuellement.
    Par exemple, on peut ouvrir l’outil “Trade” et avoir un formulaire qui permet de configurer et exécuter une prise de position.
    Ou encore cette vue pourrait afficher par exemple un formulaire de configuration d’un nouveau indicateur à ajouter à la vue centrale.
  5. STATUS_BAR : Doit afficher des messages simple d’informations concernant l’ensemble de l’application.

Pour tout vous dire, vu mon petit background de dev web, au départ je partais sur l’idée d’avoir plusieurs “pages” dans l’application, mais je me suis vite rendu compte que ça ne faciliterait absolument rien et que ce genre de configuration en “page”.
Ici on développe un projet d’application orientée “Desktop” donc on a accès à tout directement, plus besoin de penser l’application en succession de pages mais bien en succession “d’état d’application”. Si je sélectionne l’outil “Tracer une Ligne”, je change “l’état” de mon application, tout comme dans Paint quand vous utilisez l’outil Rectangle plutôt que l’outil Sélection.

Il faut qu’on puisse sélectionner nos outils facilement et exécuter des actions de manière fluide. Par exemple, vous êtes en Live Trading et vous repérez un pattern que vous incluez dans votre stratégie, c’est donc le moment de prendre une image de ce pattern et de l’ajouter aux images pour l’entraînement de votre IA. 

Il paraît beaucoup plus simple et intuitif de cliquer sur un bouton “Pattern Modeler” (par exemple) que de passer sur une autre page dans votre application pour prendre cette image. 

Commençons par le début : Le lancement de l’application et son interface graphique

Quand l’utilisateur lance l’application en cliquant sur son raccourci, il faut qu’on puisse établir les différentes étapes par lesquelles l’application doit passer.

En schéma ça donne quelque chose comme ça :

  1. Lancement de l’application
  2. On Initialise “l’état de l’application”, qu’on nommera “Application State”.
  3. On lance l’UI (User Interface) (qui détient une relation inclusive avec l’action précédente, il faut que le State soit défini avant de lancer l’interface graphique)
  4. On charge les différents Widgets principaux (les Widgets sont des cadres, indépendants les un des autres, qui contiennent des éléments graphique dans une interface graphique).

Lorsque l’application est lancée, on veut avoir une application vierge, on va donc devoir définir ce qui doit s’afficher par défaut dans chaque Widget.

Chacun ira chercher son State (son “état”) dans le State Globale de l’application. Les state seront relativement simple, une simple liste d’autres Widget à contenir ou non.

Exemple avec le Top Menu Actions : Ce menu est destiné à recevoir tous les boutons d’actions pour exécuter des méthodes sur les Widget Actions et Widget Charts. 

Rappelez vous l’exemple avec le bouton de dessin d’une ligne ou d’un rectangle.

Imaginons un bouton nous permettant de gérer des Indicateurs, en cliquant dessus d’abord un formulaire de configuration apparaîtrait dans le Widget Actions une fois rempli et accepté, le fait de cliquer sur “Ajouter Indicateur” dans le formulaire, cela aurait pour effet d’impacter les configurations d’indicateur sur la vue Widget Charts et cela ajouterais l’indicateur de manière visuelle, que ce soit directement sur le chandelier ou dans un cadre ajouté automatiquement dans la vue. 

En interne évidemment il y aurait d’autres exécutions d’algorithmes, par exemple le calcul de l’indicateur, un chargement éventuel de données supplémentaire, etc. 

Tout ce que la vue Widget Charts ferait c’est se mettre à jour quand on sait qu’on a calculé tout ce qu’il faut. Cette mise à jour se ferait simplement en exploitant les données qui se trouvent dans le State de la vue. 

Autre exemple avec la vue Widget Charts :

Par défaut, si l’utilisateur clic sur les charts il ne se passe rien. Si l’utilisateur laisse son clic enfoncé il pourrait étendre une zone de sélection par exemple.

En fait il y a deux évènement successifs, quand on presse le bouton de la souris et quand on le relâche.
On peut parler d’état du bouton de souris, s’il est enfoncé ou non.

Ensuite, en parlant de l’état de la vue widget charts, la vue va contrôler l’état de la souris et vérifier son propre état, l’état de la barre de menu actions et voir quel bouton est sélectionné.

Si l’outil “Dessiner une ligne est sélectionné”, la vue dessinera une ligne. Si l’outil “modeler un pattern” est sélectionné, chaque clic sélectionnera (ou désélectionnera si elle l’est déjà) une bougie par exemple.

Des Widgets indépendants mais une communication via le State Global

Donc comme vous l’aurez compris, les widgets sont indépendant les uns des autres, mais communiquent entre eux via le State Global de l’application et agissent de manière différentes en fonction de l’état de l’application et des autres widgets.

Pourquoi commencer par l’interface graphique ?

Il y a une chose que j’ai toujours trouvé relativement compliqué c’est arriver à séparer ce qu’on voit, ce avec quoi on peut interagir directement (appelé Front End), et ce qu’il se passe en coulisse, ce qu’on ne voit pas (appelé le Back End).

Il y a du backend et du frontend un peu partout, tout dépend à quel niveau on se met.

Ce qui est important c’est de savoir faire communiquer toutes les parties d’une application de manière fluide et permettre à chacune de ces parties d’application d’être indépendantes des autres un maximum pour qu’elles puissent être mise à jour indépendamment des autres.

L’interface graphique est une des grandes parties de l’application qu’on va devoir définir et développer dans un Module ou un Package. 

Module/Package qui devra être chargé et qui devra pouvoir s’intégrer dans une logique de communication interne à l’application.

Ce dernier schéma représente la construction de l’interface graphique. L’acteur primaire c’est notre Application.

Même si on ne l’a pas encore défini, j’ai rajouté l’Application State comme module, mais je crois qu’on peut le voir comme un acteur externe dans notre cas, chose que je ne maîtrise malheureusement pas encore x)

Je ne sais pas encore si je peux utiliser les schémas de cette manière, mais étant donné qu’il n’y a pas de méthodologie précise dans leurs utilisation, je m’autorise une petite utilisation personnelle.

Je me rend compte que l’article commence à être fouilli car beaucoup de choses sont abordées (autant par écrit que dans ma tête) et comme je voudrais garder le côté “Keep it simple”, je pense que je vais m’arrêter ici et approfondir encore dans le prochain article.

J’espère que je ne me répète pas trop et que je ne tourne pas trop en rond. Je cherche encore la/les bonnes manières de faire, celles qui me parlent le plus.

Merci d’avoir lu cet article, hésitez pas à vous inscrire et commenter l’article si ça vous dit !

A bientôt dans un prochain article 😀

Définition des cas d’utilisation

Nous voilà dans notre première phase de listing de cas d’utilisation et je dis première parce qu’il va y en avoir pas mal à mon avis.

En commençant la préparation du projet et de ma démarche telle que je vous la présente, j’avais déjà tenté de créer quelques petits visuels possibles de l’application. Voilà un exemple avec une potentielle vue de gestion de téléchargement de données historiques :

Alors, soyez rassurés je ne vais pas du tout afficher les choses comme ça, j’ai déjà d’autres idées et je compte vous montrer d’autres visuels un peu plus user friendly, mais prenons ce visuel pour avoir quelques premiers cas d’utilisation possibles.

On peut déjà lister ceux-ci :

  • Voir la liste des Plateformes d’échange
  • Sélectionner une plateforme d’échange
  • Voir la liste des marchés d’une plateforme d’échange
  • Sélectionner un marché d’une plateforme
  • Voir la liste des timeframes disponible d’un marché d’une plateforme
  • Sélectionner une timeframe
  • Lancer le Téléchargement 

Voici ce que ça donne sur un schéma UML. Notre acteur primaire est le Trader et notre application c’est le Système avec lequel l’acteur primaire interagit.

Maintenant il est important de pouvoir définir ce que ces actions et interactions impliquent, soit de manière optionnelle, soit de manière inclusive.

Vous allez voir que beaucoup de choses vont être interconnectées.

Détailler les cas d’utilisation

Nous sommes en phase d’Inception, donc notre travail c’est de détailler ce que chaque action implique pour savoir ce qu’il faudra créer et développer.

Prenons comme exemple le use case “Voir la liste des plateformes” :

Si on veut pouvoir “Voir” la liste des plateformes cela implique qu’on ait accès à cette liste. Cette action inclut donc qu’on télécharge/charge la liste des plateformes et dans le diagramme cela s’afficherait comme ceci :

On crée un autre use case et on établi une relation inclusive entre les deux. La position et le sens de la flèche détermine quel use case inclus l’autre.
Du coup, on avance d’un pas en avant, on sait que charger la liste des plateformes sera une action à détailler, ce sera un futur Use Case à définir. Mais comment est-ce que je sais si je dois le définir maintenant ou plus tard ?

Dans notre cas, notre Acteur interagit avec l’interface graphique de l’application et non pas avec le coeur de l’application lui même. Cette interface fait partie intégrante de notre application, mais pour garder les choses simple, je ne vais pas détailler cela maintenant.

De relation en relation, on remarque que chaque action est dépendante des autres pour cette situation ci.

Si on veut “Sélectionner” une plateforme, on devrait pouvoir “Voir” cette liste et donc “Charger” cette liste. Même chose pour la liste des marchés d’une plateforme. Ainsi de relation en relation, on va pouvoir déterminer chaque cas d’utilisation suffisamment en détail pour générer d’autre besoins et d’autre cas d’utilisation qu’on détaillera et qu’on développera dans d’autre itération du projet.

Et voilà ce que ça donnerait en bout de course (en ajoutant le use case du lancement du téléchargement) :

Chaque fonctionnalité décrite par les use case qu’on vient de créer appartient à notre Système. Elles interagissent entre elles dans un même cadre, la gestion des Données Historiques. On peut dès lors se demander si le Système dans lequel on évolue pourrait être intégré dans un package qui englobe toutes ces fonctionnalités.

Je ne vais pas lister toutes les fonctionnalités ici, cet article sert à introduire notamment la schématisation des Cas d’Utilisation. Ceci dit lors de l’Élaboration nous aurons la possibilité d’organiser toutes les fonctionnalités en différents packages capables d’interagir entre eux.
Un package rassemble un ensemble de fonctionnalités ayant une base commune, c’est une sorte de Système dans le Système.

D’ailleurs, dans les itérations suivantes on pourra décrire plus en détail chaque package, l’Élaboration nous permettra de savoir quel package on doit créer pour répondre à nos besoins.

Pour donner un exemple simple, lorsque le téléchargement des données historiques est lancé, une des étape de l’algorithme est de sauvegarder les données en base de données. Il faudra donc un package capable d’exécuter des requêtes, créer des bases de données, les configurer, créer des tables, etc… 

Dans les prochains articles je ferai la liste des fonctionnalités en repartant comme aujourd’hui d’une base visuelle de l’interface graphique afin d’avoir un support intéressant sur lequel on peut s’appuyer pour visualiser le fonctionnement de l’application.

Merci d’avoir lu cet article jusqu’au bout, j’espère que cela vous aura plu. 

Si vous avez des questions ou des suggestions, n’hésitez pas à vous inscrire et poster des commentaires !

A la prochaine !

Itération Principale N°0 : Phase d’Inception

N’étant pas encore vraiment habitué au Processus Unifié, il se peut fortement que je fasse des erreurs d’interprétation et d’utilisation de ce concept. Donc pour les puristes, ne m’en voulez pas trop fort :p

Rappelons qu’une itération est composée de 4 phases, l’Inception, l’Élaboration, la Construction et la Transition.

Etant donné qu’un projet est une succession d’itérations organisées en poupée russe, pour moi la couche principale d’itération est forcément la succession des versions majeurs d’un projet. Et il me paraît logique de commencer les itération par “ 0 “, car avant d’avoir une version “1”, on passe par le développement entier d’une itération. Une fois l’itération finie et le projet livré, on peut prétendre être en version 1.

Un système de versioning ?

Cela nous permettra d’écrire un versionning sous forme d’itérations successive, comme “0.10.5” qui se lirait : “Nous sommes dans l’itération 5, de l’itération 10 de l’itération principale 0”. 

Il pourrait être intéressant de garder également un suivi des Phase sur chaque numérotage d’itération via un pointage alphabétique “a, b, c, d” pour chaque phase d’itération, par exemple : “0c.10c.5a” 

Mais j’ai peur que cela devienne trop compliqué et qui plus est, ça me pose une question importante, à partir de quel moment je sais qu’il faut que je divise une itération en sous itérations ?
De manière plutôt logique, je me vois faire ça pendant la phase d’Élaboration ou de Construction. Le mieux serait de le faire pendant l’élaboration pour savoir exactement ce qu’on a à faire pendant la construction. Cela dit, pendant la Construction on peut se retrouver face à des choix qui nous demanderont peut-être de subdiviser une partie de projet en sous itération pour rendre les choses plus faciles à gérer.

Peut-être faudra t-il alors juste se laisser la possibilité de le faire et dans l’Élaboration et dans la Construction en fonction du besoin. Voir savoir faire les deux, pendant l’Élaboration prévoir les futurs sous itération et pendant la Construction, créer ces itérations.

Enfin, je pense qu’il est peut-être inutile de préciser la phase des couches supérieures. Lors de release ou simplement via Git, un simple versioning : “0.10.5c” pourrait faire l’affaire.

Hé bien chers amis, débutons notre toute première itération principale et sa première phase, l’Inception.

Phase d’Inception :

“La Phase d’Inception, consiste à évaluer le projet, on y détermine des cas d’utilisation et un premier brouillon d’architecture.
On modélise les processus métier et on gère les exigences du projet.”

Evaluation du Projet

En terme d’évaluation je pense que j’ai déjà passé assez de temps ces derniers mois pour savoir si le projet était faisable ou non. Tout ce que j’ai pu chercher, tester et apprendre me servira donc pour établir les cas d’utilisations et notre premier brouillon d’architecture.

Déterminer les cas d’utilisations 

Les cas d’utilisation détaillent le/les comportement(s) du système étudié sous la forme d’une liste d’actions et d’interactions entre l’acteur et le système (voir entre différentes actions).

Le cas d’utilisation décrit les exigences fonctionnelles entre le système et l’acteur, il doit donc être succinct et ne concerner que cette relation.

Vue d’une relation entre un acteur primaire et un use case dans un système (schématisé en UML)

Dans notre cas un acteur peut-être un Trader par exemple, mais lorsqu’il s’agit d’aller plus en profondeur dans les itération, les acteurs pourront être des systèmes. On pourrait donner comme exemple une interaction entre un gestionnaire de base de données et un gestionnaire de téléchargement de données historiques.

Il est donc clair qu’en détaillant les premiers cas d’utilisation, on ne fera que survoler les sujets et on ira détailler chaque action et chaque interaction dans des itérations plus profondes si le besoin s’en fait sentir.

Comment connaître les cas d’utilisation et savoir les définir ?

Dans un premier temps je pense qu’il est important de définir les limites de l’application, savoir faire la liste des fonctionnalités globales. Un peu comme si on se présentait à un client et qu’on lui demandait ce qu’il veut, le client va nous dire “je voudrais ça, ça, et ceci et ça”, il le dira sans avoir aucune connaissances en développement, ce sera donc une première vision “naïve” du projet.

On va pouvoir définir une première fois ce qu’on attend de l’application, qui sont les utilisateurs visés (ceux qu’on appellera les Acteurs Primaires), avec qui ou quoi ils vont interagir, etc.

Description globale du projet :

J’aimerais développer une application qui puisse apporter un soutien, une aide au travail quotidien du Trader. Cette aide, ce soutien serait fourni par des outils graphiques, un calcul d’indicateurs, un espace de test de stratégie avec des données historiques de marché.

L’intérêt majeur de l’application serait de permettre au Trader de configurer et entraîner une IA sur différentes stratégies et pattern, afin de l’utiliser pour dans un premier temps offrir une aide à la décision et dans un second temps gérer une automatisation de prise de position, voir une gestion d’un wallet complet.


L’application devrait pouvoir permettre au Trader effectuer des opérations sur un maximum de plateformes d’échange de crypto-monnaies. Il devrait pouvoir avoir des informations de ses comptes sur ces plateformes, avoir des informations sur l’état de ses wallets et l’état de ses prises de position.

Cela implique de lui fournir des outils graphiques de CandleStick ainsi que des outils de configuration et d’affichage d’Indicateurs en fonction des données de marché demandées par le Trader sur les plateformes disponibles.

L’application doit pouvoir gérer un espace de test de stratégie. Le Trader doit donc pouvoir télécharger et gérer des données historiques de n’importe quelle plateforme.
Il doit pouvoir avoir accès à une Fake Plateforme pour faire des fausses opérations et pouvoir tester ses stratégies de manière manuelle.

L’intérêt majeur de l’application se trouverait dans la configuration et la gestion d’une IA créée et entraînée par le Trader.
Il doit donc pouvoir d’abord avoir un espace lui permettant de créer des configuration d’IA et de Réseaux de Neurones. Cela permettra à tout un chacun d’avoir des configuration et modèle d’IA différent.
Enfin le Trader doit pouvoir avoir accès à des outils graphiques lui permettant de modéliser des données d’entraînements de stratégies pour son/ses IA et lancer des sessions de visualisation d’entraînement pour tester ses configurations et modèles.

Dans un premier temps les différentes configurations et modèles d’IA ne devraient être utilisées que de manière indépendante les unes des autres.
Mais dans un deuxième temps il serait très intéressant de pouvoir définir un réseau de petite IA permettant au Trader de traiter différentes phases de traitement de données et de décisions.

Cette application n’est pas faites pour être un outil magique, le Trader devra pouvoir fournir lui même des connaissances afin de pouvoir correctement configurer, définir ses modèles, utiliser ses indicateurs et construire ses stratégies.

En aucun cas l’application ne doit apporter toutes les solutions, c’est une application qui sert de support de travail et d’aide à la prise de décision, pas gagner de l’argent magique.

Ecriture des Uses Cases :

En y réfléchissant un peu, on va vite se rendre compte que la première liste de cas d’utilisations va certainement être assez longue. Et qu’il faudra faire un tri dans tout ça, voir ce qui est cohérent et voir ce qui ne l’est pas.

Ce qu’il faudra retenir, c’est que je devrais faire des cas d’utilisation entre le Trader et le système “Application”. C’est à dire, en passant par l’interface graphique, chose que nous n’avons bien évidemment pas encore abordé haha.

Je propose donc que les Uses cases soient l’objet du prochain article parce que je vais avoir besoin de préparer le terrain !

En tout cas, encore un grand merci à ceux et celles qui me lisent, j’espère que cela vous plait. N’hésitez surtout pas à vous inscrire et laisser des commentaires 😉

A bientôt !

PS : Je ferai mes schéma UML via l’application en ligne draw.io, elle est gratuite, assez propre et propose toute une panoplie d’outil de schématisation de projet, dont les outils UML.

Vous pouvez la trouver là : https://www.draw.io/

Organisation et structure de Projet

Maintenant que le projet est introduit, que les motivations sont expliquées, on va pouvoir commencer à entrer dans le vif du sujet.

Avoir un langage commun : UML

Etant donné la nature Open Source du projet et qu’à terme j’aimerais pouvoir accueillir des contributions de manière sereine, je pense qu’il est important d’installer des bases solides d’organisation. Cela permettra à tout le monde d’être sur la même longueur d’onde.

Pour cela je voudrais maximiser l’utilisation du langage UML (Unified Modeling Language) et du Processus Unifié

L’important pour moi la dedans est de pouvoir intégrer un processus de développement structuré en différentes phases. Mais également de permettre à tout un chacun, surtout les non développeurs qui n’y connaissent rien en code, de pouvoir suivre l’évolution du développement en ayant un support lisible et compréhensible pour eux.

UML est un langage schématique que n’importe qui peut facilement apprendre et comprendre et il peut être utilisé dans tous les domaines, même ceux n’ayant rien avoir avec l’informatique.

Le Processus Unifié comprend 4 phases distinctes :

  1. La Phase d’Inception, consiste à évaluer le projet, on y détermine des cas d’utilisation et un premier brouillon d’architecture.
    On modélise les processus métier et on gère les exigences du projet.
  2. La Phase d’Élaboration, consiste à construire l’architecture du système. En fin de cette phase on doit connaître les exigences du projet de manière définitive.
    Dans cette phase on gère les exigences du projet, on analyse et on conceptualise.
  3. La Phase de Construction, consiste au développement logiciel de l’architecture de notre programme qu’on a défini pendant la phase d’élaboration.
    Principalement on analyse, on développe, on implémente et on test.
  4. La Phase de Transition, consiste à déployer l’application et à former l’utilisateur.

Le Processus Unifié divise le projet en une multitude d’itérations afin de ne pas avoir à gérer un projet trop énorme d’une seule traite. En gros chaque itération représente un projet dans le projet et chaque itération peut elle même être divisée en différentes itération si le besoin s’en fait sentir.

Chaque itération est parcourue par les 4 phases du processus unifié, cela nous donne un chemin simple à suivre avec des étapes bien précises qui dit qui fait quoi et quand.
Une fois toutes les itérations effectuées, le projet est fini et livrable.

Le Processus Unifié me permettra de savoir où j’en suis, quel est le travail à faire et quelle sera la prochaine étape.
Enfin UML me permettra d’avoir un langage commun avec ceux et celles qui suivent le projet et qui auront envie de prendre le temps d’apprendre le langage (ou qui le connaissent déjà d’ailleurs).

Organiser les échanges d’idées et de code avec les Design Pattern :

Certain(e)s d’entre vous sont des développeur/euses et vous m’avez déjà même proposé de pouvoir contribuer au projet en fournissant des idées ou même des portions de code.

L’échange d’idée sera évidemment encouragé, ça c’est certains. Surtout que je ne suis pas un Trader vraiment acharné, je n’ai certainement pas la science infuse. Il sera donc très intéressant d’avoir des idées venant de Trader confirmé par exemple.

L’échange de code sera au début restreint, par exemple si vous remarquez un ou plusieurs bug, des erreurs d’algorithme ou autre. Restreint parce que j’aimerais pouvoir fournir une base de travail commune solide, mettre ça en place à plusieurs ça peut vite être compliqué quand on est pas habitué à gérer un projet informatique de bout en bout.

Donc pour encourager le partage de code, il faut également qu’on puisse être sur la même longueur d’onde et moi le premier.
Je vais donc maximiser l’utilisation de Design Pattern connus. Ils sont très bien documentés et ont l’avantage d’avoir été éprouvés. Ils pourront apporter je pense régulièrement des solutions élégantes pendant le développement.

Connaître et intégrer les Design permet de parler d’une partie de code sans devoir connaître l’intégralité de l’algorithme et devoir le décrire en entier.
Cela devrait alléger les discussions.

Voilà, c’était un article plus court pour aujourd’hui car je travail d’ors et déjà sur les premier schéma UML et la division du projet en plusieurs premiere grosses itérations que je détaillerai dans un futur article.

J’espère que la lecture vous aura plu, n’hésitez pas évidemment à mettre un commentaire si vous le voulez 😉

PS : Voici quelques sources d’apprentissage pour ceux/celles qui en ont envie :

UML

Cours OpenClassRoom sur UML : https://openclassrooms.com/fr/courses/2035826-debutez-l-analyse-logicielle-avec-uml

Livre – “UML 2.5” aux édition ENI :
https://www.editions-eni.fr/livre/uml-2-5-initiation-exemples-et-exercices-corriges-5e-edition-9782409024085

J’utilise principalement ce bouquin pour apprendre progressivement l’UML (j’ai la 4ème édition par contre).

Design Patterns

Livre – “Design Patterns en Java” aux édition ENI :
https://www.editions-eni.fr/livre/design-patterns-en-java-les-23-modeles-de-conception-descriptions-et-solutions-illustrees-en-uml-2-et-java-4e-edition-9782409012815

Site web : Refactoring.Guru
https://refactoring.guru/ 

(A voir absolument, explique bien et est bien illustré, très agréable à lire)

Site web : Geek for Geeks
https://www.geeksforgeeks.org/python-design-patterns/

Site Web : Tutorial Point :
https://www.tutorialspoint.com/python_design_patterns/index.htm

CryDer – Introduction

Il y a quelques mois, je me suis lancé dans la recherche et le développement d’outils qui pourraient me permettre de soutenir un travail de ce que j’appel un Crypto Trader, un mec qui trade des crypto monnaies quoi.

J’ai fait tous mes premiers travaux avec ce que je connaissais, c’est à dire Javascript et NodeJS. L’idée était assez simple, trouver des voies d’investigations qui me permettraient de déléguer le travail d’analyse de graphiques à une machine. 

Je me suis donc lancé corps et âme dans l’apprentissage du développement d’une Intelligence Artificielle. Et à vrai dire c’était assez naïf au départ, je partais sur un idéal d’une IA qui apprendrait par renforcement parce que mes recherches me permettaient de réaliser des exercices simples assez prometteur. Imaginez, une IA qui lit des données historique qui fait des fake positions et qui apprend toute seule de ses erreurs, le rêve.
Non, c’est beaucoup trop complexe à réaliser tout seul x)

J’ai bossé un moyen de pouvoir gérer et afficher des chandeliers de données, avec la gestion d’indicateurs calculé à partir des données récoltée. Je pouvais reprendre mes recherche sur la création d’un moteur 2D sur Javascript plutôt sympa.

Je me suis vite confronté à des problèmes de performance que Javascript et NodeJS ne pouvaient pas vraiment régler sauf en apprenant à aller encore plus profondément en apprenant la gestion des Shaders et l’utilisation des cartes graphique, boulot beaucoup trop lourd à mon goût et trop complexe sur NodeJS. Enfin, question développement Desktop, même en utilisant ElectronJS, ça devenait vraiment vite compliqué comparé à ce que peuvent faire des Java ou Python.

Du coup, j’ai bouffé une formation rapide sur Python pour intégrer la syntaxe et commencer à rechercher des Packages intéressants qui me permettraient de réaliser tout ce que j’avais déjà fait sur Javascript et NodeJS.

Et me voilà, avec tout un projet en tête, beaucoup de choses à faire et partager.

Ce qu’une IA n’est pas

Bon, on va tout de suite quitter les idées naïves et idéales qui font rêver d’une IA qui apprend toute seule juste en recevant les données OHLCV des 200 dernières périodes sur une timeframe de 5 minutes.

Oui, il est possible de faire des choses “impressionnantes” avec des données déjà existantes. Par exemple, prenez le cours du Bitcoin, coupez les données en deux, d’un côté vous avez 70% des données qui vont servir d’entraînement, les 30% restant serviront de données de test, pour voir l’efficacité de l’apprentissage.

Créez un modèle d’IA avec Tensorflow et passez toutes vos données dans la moulinette. Au final, l’IA arrivera à prédire les 30% de données de test.
Ce qui est, je vous l’accorde, vraiment impressionnant quand on voit ça comme résultat :

Sauf qu’en faite, c’est trompeur. L’apprentissage de l’IA se fait par essai erreur grosso merdo (j’expliquerai ça plus en détail dans un autre article). Le but de l’IA ici c’est d’arriver au meilleur score de prédiction, donc pour chaque données à prédire elle va s’adapter aux données auxquelles elle peut faire référence indirectement. Ces données servent de points de comparaison pour l’apprentissage, donc forcément il y a un moment où on arrive à un résultat pas dégueulasse du tout. Mais ces données existent déjà ! Elle n’ont pas à être “prédites”.

Mais une fois qu’on travail avec des données qui n’existe pas, qu’on utilise le modèle de l’IA en live, tout part en sucette presque directement. La raison en est très simple, on ne peut pas prédire ce qui n’existe pas avec autant de précision parce qu’il existe autant de scénario qu’il existe de trader qui vont chacun prendre une décision unique de leur côté.

Votre IA pourra certainement prédire certains coup de manière précises, mais vous ne serrez pas à l’abris des “imprévus”, et on sait tous que les marchés en sont rempli.

Si un mec vous propose une app qui peut soit-disant prédire l’avenir des marchés, barrez vous en courant, c’est de l’arnaque.

Comment profiter de la puissance d’une IA ?

Passé le côté rêveur et naïf, je me suis demandé : “Bon, ok, mais il y a clairement des trucs à faire, quid des données existantes ? Si mon IA peut lire ces données, elle peut donc détecter des patterns si je le lui apprend ?!”

Prenez par exemple les IA de reconnaissance d’image, en fonction des données de pixels qu’on leur suggère on peut leur apprendre à reconnaître vraiment facilement des objets.

Il y a des applications amusantes qui se sont développée comme les App de reconnaissance de fleur, vous prenez une photo d’une fleur, vous la soumettez à l’application et celle ci vous donne le nom et la description de la fleur.

Chaque fleur à sa forme précise, sa couleur, ses spécificités reconnaissables parce qu’elles sont organisées en pattern. Une rose est une rose parce que sa forme et ses couleurs sont reconnaissable.

Les marchés, c’est pareil, les données brutes OHLCV permettent d’identifier déjà beaucoup de choses parce qu’on peut en dégager des patterns. Ces données sont des images fixes des marchés desquelles on peut tirer des observations : C’est une tendance haussière, il va falloir vendre parce que la tendance faibli et n’a pas su faire un dernier plus haut creux, on est dans un Bottom et on attend le 3ème plus haut creux, etc..

Nos observations servent à prendre des décisions, une IA entraînée le fera 100 fois mieux parce que c’est une machine.

Un exemple simple c’est l’effet balancier, si on montre plusieurs set de données de ce type à notre IA:

Elle saura finir par reconnaître à quel moment il peut être intéressant d’acheter et donner une target précise.

Si on décompose l’évolution complète d’un Double Bottom, on peut déterminer chaque étape et déterminer si le pattern va fail ou pas, déterminer un stop et une ou plusieurs target potentielle pour peu qu’on lui ait présenté suffisamment de situations.

L’ensemble des images données à l’IA ne seront pas sous forme de pixels mais sous forme de tableau de données OHLCV.

Et on a pas encore imaginé ce qu’on pouvait faire avec des données d’indicateur comme le RSI, la MACD, les EMA, etc… 

Avec un apprentissage et un modèle adéquat, une IA peut être d’un soutien vraiment important lors de prise de décisions sur les marchés. Et ça, c’est notre premier objectif de développement et le premier objectif de CryDer.

Oublier la magie, focus sur la connaissance

Avant de me lancer sur tout ça, j’ai passé quelques mois à suivre Crypto Fanta, j’avais déjà abordé un peu les marchés tout seul, mais sans jamais savoir vraiment si j’étais dans le bon ou non. J’ai donc suivi sa formation, je me suis documenté, créé un trading plan, j’ai trade un moment, j’ai réussi des trades, j’en ai raté beaucoup plus. 

Mon principal point faible était mon manque de gestion de mes émotions et mon attitude trop greedy. Mes analyses n’étaient pas forcément mauvaises, mais je partais trop dans tous les sens et changeais d’avis par impatience et parce que je laissais mon ego prendre le dessus.

Il m’arrivait parfois d’entrer dans des états d’esprit où je devais réussir des trade comme par magie, je perdais complètement toute forme de rationalité.

Du coup, j’ai arrêté de le Trading parce que cela devenait ridicule de perdre sans pouvoir remédier à ces soucis. 

Mais, cela ne veut pas dire que j’ai arrêté de chercher et ce projet est une réponse à mes faiblesses. Comme on dit, on fait avec ce qu’on a.

Aujourd’hui, j’ai envie d’apporter 2 solutions concrètes à mes points faibles :

  1. Avoir un outil graphique me permettant de parcourir les données historique et ajouter des “images” dans une base de données sur laquelle l’IA va pouvoir s’entraîner.
  2. Pouvoir avoir une IA qui me donne des informations visuelles sur les charts me permettant d’avoir une vue plus générale et plus lisible. Affichage des pattern, affichage de moment clé comme des retournement, etc…

L’IA deviendrait un outil de confirmation de mes décisions et allégerait le poids de mon mental et mes angoisses.

Créer un outil graphique permet de ne pas devoir faire de l’encodage massif et facilite le travail, mais surtout, partager cet outil me permettrait en tant que développeur Open Source de fournir mes compétences aux trader qui le désirent sans forcément avoir à leur dire quoi faire en terme de trading. L’outil resterait flexible et demanderait à chacun de se former soit même au Trading pour pouvoir utiliser correctement l’outil.

On oublie donc totalement l’idée de l’IA qui fait tout pour nous et on se concentre sur nos connaissances et nos stratégies personnelles et les transmettre à notre IA pour qu’elle les applique avec une rigueur de machine.

Proposer un outil Open Source et gratuit

Quand je faisais mes recherches et que je parlais de mon projet autour de moi, on m’a demandé si j’allais le vendre. 

J’y ai pensé et effectivement, c’est le genre d’outil qu’on peut vendre assez cher s’il est bien fait. 

Mais il est important de rappeler quelque chose, étant donné que je me suis lancé seul sur ce projet, il y a énormément de travail à faire.
Il serait impossible pour moi de maintenir des dizaines de gros packages majeurs internes à l’application et surtout il existe déjà tellement de solutions pour des questions ou des problématiques qui se posent déjà quand on réfléchit à l’application. Tous sont open source. 

Par exemple, le simple package TA-Lib qui propose le calcul d’un grand nombre d’indicateur, c’est quelque chose qu’il m’aurait été impossible à faire tout seul.

Ou la gestion de tableau de données géré par Pandas, ou la création de Charts qu’on peut modifier à souhaits, ou encore le package pour la création de l’IA, etc…, etc…

Énormément d’outils sont déjà fait, mon désire c’est de pouvoir les intégrer tous dans une application cohérentes qui remplit ses objectifs. Pas de faire une machine qui fait le café et qui mine du bitcoin en même temps. Je veux rester simple, léger et flexible.

Connaissant un poil le monde du trading, je sais à quel point les Traders sont attachés à leur stratégies personnelles et ne désirent pas les partager.
Un des objectif, comme je l’ai dit plus haut, c’est de fournir un outil capable d’établir des modèles d’apprentissage pour l’IA. Chaque trader aurait donc le loisir de développer ses stratégies personnelles en fonction de ses connaissance en Trading et pourra les garder pour lui/elle.

Au delà du fait que j’utilise beaucoup de package Open Source, je désire aussi rester dans cet état d’esprit, mon but n’est pas de devenir millionnaire en vendant des produit à prix d’or. Je suis un créatif, j’ai besoin de passer énormément de temps à chercher, tester, produire des trucs qui ne voit finalement pas le jour. Me planter, découvrir, apprendre, etc..

Le jour où je n’aurais plus l’envie, les moyens ou le temps d’entretenir le projet, je ne doute pas qu’il sera repris par un autre passionné.

En abordant le Trading je croyais naïvement pouvoir faire un peu d’argent, l’équivalent d’un salaire d’ouvrier, pour pouvoir vivre tranquillement et continuer mon mode de vie de créatif librement. 

Me placer comme personnage utile aux Trader et leur fournir un outil intéressant me permettrait peut-être d’être soutenu correctement, autant intellectuellement en partageant des idées sur comment l’application devrait fonctionner, que financièrement si certains décident de faire des dons.

Comment cela devrait se passer maintenant ?

Voilà, vous venez de lire une longue introduction à ce projet. Entrons un peu dans le concret maintenant. 

Y a t-il déjà des productions concrètes ?

Il y a des parties d’applications, des tests que j’ai fait, il y a des tentative de développement d’IA, de constructions d’applications chacune différentes qui creuse plus un sujet qu’un autre. Par exemple j’ai déjà une portion de code qui me permet de télécharger les données historique OHLCV de n’importe quel marchés de crypto depuis n’importe quelle plateforme.

Quelle est la suite tout prochainement ?

J’ai commencé l’écriture d’un document d’analyse du projet pour rassembler toutes les idées et les découverte que j’ai fait ces 6 derniers mois.
A vrai dire c’est la première fois que je me lance vraiment dans un projet de cette ampleur, et même si cela devrait prendre du temps je veux pouvoir le faire de manière organisée et structurée. Donc, avant de taper quoi que ce soit de plus comme code j’ai vraiment envie de construire et alimenter tout un dossier d’analyse pour ne pas être perdu en cours de route et finir par abandonner le projet parce que je n’avais pas assez approfondi les choses sur papier.

Je compte utiliser, entre autre, la schématisation UML pour décrire le projet.

Quels sont les packages que tu as repéré/sélectionné pour le projet ?

  1. PonyORM : C’est un package de gestion de base de données, un Object Relation Mapper. Ca facilite grandement l’écriture de code exploitant une ou plusieurs base de données. Pour les BDD je compte utiliser Sqlite3.
    Site : https://ponyorm.org/
  2. CCXT Python : CCXT est une librairie qui fournit une API permettant de se connecter à un nombre assez large de plateforme d’échange de crypto et y effectuer des actions comme charger des données de marchés ou effectuer des opération comme prendre position, acheter, vendre, etc..
    Github : https://github.com/ccxt/ccxt
  3. Tensorflow : Une librairie dédiée à la création d’Intelligence Artificielle et tout ce qui est lié au machine learning.
    Je n’ai aucunement l’intention de créer moi même ce genre d’outil, ce serait beaucoup trop complexe. J’ai pu en faire des simple, mais une librairie aussi grosse fournit des outils beaucoup plus puissant.
    Site : https://www.tensorflow.org/
  4. PyQT5 : Librairie Python qui permet d’utiliser le puissant framework QT, je l’utiliserai pour créer et gérer toutes les fenêtres de l’application.
    Github Libraire Python : https://riverbankcomputing.com/software/pyqt
    Site QT : https://www.qt.io/
  5. Matplotlib et MPLFinance : Python regorge de package ultra puissant permettant de gérer des données et effectuer des opération mathématique dessus.
    MPLFinance me permettra de gérer les charts graphiques autant pour pouvoir faire du live trading que pour pouvoir modéliser les image de pattern à donner à l’IA pour qu’elle apprenne.
    Github : https://github.com/matplotlib/mplfinance
  6. TA-Lib Python : TA-Lib est indispensable au projet, cette librairie fourni des centaines d’indicateurs, momentum, candle pattern, overlap, volatilité, etc..
    Des trucs que j’aurais été incapable de faire tout seul.
    Il existe d’autre librairie mais TA-Lib est pour moi la plus complète à ce jour.
    Son seul soucis c’est d’être uniquement en 32bit (mais on passera au dessus).
    Site: http://mrjbq7.github.io/ta-lib/
    Github Librarie Python : https://github.com/mrjbq7/ta-lib 

Va tu ouvrir un Github pour le projet ?

Oui c’est déjà fait et ça se trouve là : https://github.com/Morgiver/cryder

Y a t-il un moyen de te suivre pour se tenir au courant de l’évolution du projet ?

Oui, je suis présent sur différents réseaux sociaux et je compte publier les avancements dessus :

Je met ma chaîne Youtube en premier car je risque fortement de reprendre des live matinaux que je dédiais justement à la programmation.

Merci d’avoir lu cette introduction jusqu’au bout, c’est un début pour moi.
A bientôt en live ou dans d’autres articles !

N’hésitez pas à vous inscrire et taper des commentaire pour me dire ce que vous pensez de tout ça !