Documentation

Applications

Dernière mise à jour le 23. 11. 2023 par Mark Fric

Exemple de plugin - une tâche complète de projet personnalisé

Cet article décrit le développement d'un plugin de tâches personnalisé complexe qui peut être utilisé dans un projet personnalisé dans StrategyQuant.

Note 1 - nous avons dû faire quelques changements dans la structure des classes pour permettre la création de plugins externes de ce type, et pour cette raison ce plugin ne fonctionnera qu'à partir de SQX Build 138.

Note 2 - nous n'avons que peu de documentation et d'exemples sur l'extension de SQX avec des plugins, c'est l'un d'entre eux. Cet exemple est destiné aux utilisateurs qui ont les connaissances nécessaires et qui sont capables de comprendre le code existant.

 

L'objectif

Développer une nouvelle tâche personnalisée dans StrategyQuant, y compris les paramètres complets.

Nous allons mettre en place un nouveau plugin de tâches personnalisé appelé Filtrer par corrélation.

 

Ne confondez pas ce plugin avec l'exemple de plugin du même nom qui existe déjà dans l'article ici : https://strategyquant.com/doc/programming-for-sq/filter-by-correlation-plugin-example/

Cet exemple plus ancien est un plugin plus simple qui met en œuvre une nouvelle action de banque de données.

Notre nouvel exemple consisterait à étendre cette idée et à mettre en œuvre un plugin de tâches complet.

 

Le résultat

Comme vous pouvez le voir ci-dessous, une nouvelle tâche nommée Filtrer par corrélation dans les tâches de projets personnalisés à choisir :

 

Et les paramètres de cette nouvelle tâche :

 

Cette tâche est très simple : elle compare les stratégies de Source avec les stratégies existantes dans les pays de l'Union européenne. Existants et copie ceux dont la corrélation est inférieure à la valeur autorisée dans la banque de données des Cible banque de données.

Cette tâche personnalisée (et toutes les autres) est en fait composée de deux plugins interdépendants :

TaskFilterByCorrelation

Plugin implémentant la tâche elle-même et les principales fonctionnalités, ainsi que l'interface utilisateur pour les paramètres simples - c'est celui que vous voyez dans l'onglet Progress pour cette tâche.

 

SettingsFilterByCorrelation

Plugin implémentant les paramètres complets de ce plugin, y compris l'interface utilisateur - c'est celle que vous voyez dans l'onglet Paramètres complets.

Tous les paramètres de cette tâche sont chargés à l'aide du plugin Settings.

 

Veuillez noter que ce type de plugin combine Java - pour la mise en œuvre du backend et des fonctionnalités - et JavaScript (AngularJS) pour la mise en œuvre du frontend.

 

Mesures générales nécessaires à la mise en œuvre du nouveau plugin de tâches

  1. Créer des plugins de tâches et de paramètres - parties Java et JS
  2. Créer un task.xml par défaut avec les paramètres des banques de données qui sont automatiquement créées + les paramètres par défaut dans le plugin Task

 

Toute nouvelle tâche que vous créez doit respecter les noms des paquets :
package com.strategyquant.plugin.Task.impl.XXXXXX
package com.strategyquant.plugin.Settings.impl.XXXXX

Où XXXXX est votre nom, SQX crée ensuite des dossiers pour que les noms des paquets correspondent :
TâcheXXXXXXXXXX
ParamètresXXXXXXXXX

Dans notre cas, les dossiers sont les suivants
TaskFilterByCorrelation
SettingsFilterByCorrelation

 

La meilleure approche pour créer votre propre plugin de tâches est la suivante :

  1. Faites une copie de nos deux exemples de plugins, changez les noms de classe et les chaînes de caractères dans le code de "FilterByCorrelation" par votre propre nom.
  2. Veillez à supprimer/ne pas copier les fichiers .jar respectifs lorsque vous copiez les exemples - les fichiers .jar seront créés lorsque vous compilerez votre propre plugin.
  3. Mise en œuvre de différentes méthodes de gestion des paramètres et de la fonctionnalité principale dans les plugins Task et Settings (Java)
  4. Implémentation d'une interface utilisateur différente dans les plugins Settings et Task - dans les fichiers .HTML et .JS

 

Importer des exemples de plugins dans votre SQX

Des exemples de plugins sont joints à cet article (en haut). Les deux plugins sont livrés dans deux archives différentes - .sxp et ZIP standard.

La version ZIP n'est pas destinée à l'importation, c'est juste pour la commodité - si quelqu'un veut jeter un coup d'œil aux fichiers sans les importer dans SQX.

 

L'importation de plugins à l'aide de .sxp est simple - ouvrez votre CodeEditor, allez dans Import choisissez, les deux fichiers .sxp - pour les deux plugins et cliquez sur OK.

 

Les plugins seront importés et vous devriez voir les nouveaux dossiers de plugins dans l'explorateur de fichiers :

Il vous suffit ensuite de redémarrer votre SQX pour que la nouvelle tâche soit disponible dans les projets personnalisés.

 

Plugin SettingsFilterByCorrelation

Nous allons d'abord décrire le plugin des paramètres. Il s'agit d'un plugin qui implémente les paramètres "complets", c'est-à-dire ceux qui apparaissent dans la fenêtre de l'application Paramètres complets onglet. L'interface utilisateur peut être différente et plus compliquée que les paramètres simples affichés dans l'onglet Progrès tabulation.

 

Nous allons à nouveau passer en revue tous les dossiers :

 

FilterByCorrelationCtrl.js

Contrôleur Angular pour ce plugin. La fonction principale du contrôleur est d'ajouter des variables (leurs valeurs) dans le scope et de les rendre ainsi disponibles dans le fichier HTML.

 

Dans les plugins de configuration, nous définissons l'ensemble de la configuration du FilterByCorrelationService :

$scope.config = FilterByCorrelationService.config ;

 

De plus, nous pouvons définir des variables supplémentaires, par exemple la liste des types de corrélation/périodes utilisés dans les zones de liste.

    $scope.correlationTypes = [] ;
    $scope.correlationPeriods = [] ;

    loadToArray($scope.correlationTypes, SQConstants.getConstants().correlationTypes) ;
    loadToArray($scope.correlationPeriods, SQConstants.getConstants().correlationPeriods) ;

 

Outre la définition des variables, ce contrôleur gère également le chargement et l'enregistrement des paramètres - quand ils doivent être enregistrés et quand ils sont lus.

 

Il existe une action du contrôleur settingsChanged() appelée à partir de HTML à chaque changement d'entrée, et cette méthode appelle ensuite FilterByCorrelationService.saveSettings() pour enregistrer les paramètres.

 

Le chargement des paramètres est déclenché par un événement SETTINGS_TAB_RELOAD qui est automatiquement appelée au démarrage de l'onglet ou lorsque vous passez d'un onglet à l'autre.

Le contrôleur des paramètres doit ajouter un récepteur à cet événement et, lorsqu'il basculera sur cet onglet de paramètres, il déclenchera cet événement qui appellera la fonction init() qui, à son tour, charge les paramètres actuels en appelant la méthode FilterByCorrelationService.loadSettings() ;

 

FilterByCorrelationService.js

Service pour ce filtre, gérant des choses telles que le chargement et l'enregistrement de données depuis/vers le backend, la définition de valeurs par défaut, etc.

Tous les services sont des instances singleton, c'est-à-dire qu'ils ne sont créés qu'une seule fois au démarrage de l'application.

Chaque service de paramétrage contient un objet config qui contient les paramètres de la tâche sélectionnée et les méthodes loadSettings/saveSettings.

 

Les paramètres xml actuels pour la tâche sélectionnée sont obtenus par appel :

var filteringObj = AppService.getCurrentTaskTabSettings("FilterByCorrelation") ;

 

Ensuite, nous pouvons lire la valeur du fichier xml :

instance.config.correlation.max = getNodeFloatValue(filteringObj, 'CorrMax', 0.3) ;

 

ou y inscrire des valeurs :

addNode('CorrMax', instance.config.correlation.max, filteringObj, xmlDoc) ;

 

Ainsi, dans le service, nous modifions directement le XML.

 

Veuillez noter que l'instance de service est unique et qu'elle est partagée entre le plugin Settings (interface utilisateur complète) et le plugin Task (interface utilisateur simple).

 

module.js

Enregistre le plugin dans l'interface utilisateur. Pour afficher le panneau de configuration complet, un plugin de type SettingsTab doit être enregistré.

Les attributs obligatoires du plugin sont les suivants

  • task - nom de la tâche pour laquelle il doit être affiché, dans ce cas "FilterByCorrelation". Si nous souhaitons afficher cet onglet de réglage également pour les tâches Build et Retest, il y aura "FilterByCorrelation,Build,Retest".
  • configElemName - nom du paramètre dans le fichier xml
  • templateUrl - le code html à afficher
  • controller - le contrôleur lié au code html de la définition templateUrl
  • dataItem - ID de l'onglet de configuration, doit avoir un nom unique parmi les onglets de l'onglet SettingsTab

 

d'autres paramètres tels que le titre, l'aide, l'URL d'aide, sont compréhensibles à partir du nom de l'attribut.

 

settings.html, styles.css

Fichier HTML contenant la définition des paramètres de l'interface utilisateur et la définition des styles CSS utilisés.

 

SettingsFilterByCorrelation.jar

Il s'agit d'un plugin déjà compilé. Vous ne le verrez pas dans votre propre plugin tant que vous ne l'aurez pas compilé - voir les instructions pour le faire plus tard.

 

SettingsFilterByCorrelation.java

Classe Java qui gère le backend de ce plugin. Elle implémente ISettingTabPlugin

L'interface et la méthode la plus importante sont readSettings() - qui lit les paramètres à partir du fichier XML fourni par l'interface utilisateur (paramètre elSettings), les analyse et les enregistre dans un objet de données sous les clés propres à ce plugin :

public void readSettings(String projectName, ISQTask task, Element elSettings, TaskSettingsData data) {
        Element elFiltering = null ;

        try {
            elFiltering = XMLUtil.getChildElem(elSettings, getSettingName()) ;
        } catch(Exception e){
            data.addError(getSettingName(), null, e.getMessage()) ;
            retour ;
        }
       
        try {
            Databank dbSource = ProjectConfigHelper.getDatabankByType(projectName, "Source", elSettings) ;
            Databank dbTarget = ProjectConfigHelper.getDatabankByType(projectName, "Target", elSettings) ;
            Databank dbExisting = ProjectConfigHelper.getDatabankByType(projectName, "Existing", elSettings) ;

            data.addParam(SettingsKeys.DatabankSource, dbSource) ;
            data.addParam(SettingsKeys.DatabankTarget, dbTarget) ;
            data.addParam("DatabankExisting", dbExisting) ;

            CorrelationSettings corr = new CorrelationSettings() ;
            corr.loadFromXml(elFiltering) ;

            data.addParam(SettingsKeys.Correlation, corr) ;

        } catch(Exception e){
            data.addError(getSettingName(), null, L.t("Cannot load FilterByCorrelation settings. ") + e.getMessage()) ;
        }
    }

 

Plugin TaskFilterByCorrelation

Comme indiqué ci-dessus, il s'agit du plugin "principal" qui met en œuvre la fonctionnalité. Ce plugin est également responsable de l'affichage des paramètres "simples" visibles dans l'onglet Progress.

 

Vous pouvez voir que le plugin se compose de plusieurs fichiers, y compris la structure des sous-dossiers. Nous allons les passer en revue un par un.

 

module.js

Enregistre le plugin dans l'interface utilisateur. Pour afficher les paramètres simples, il faut enregistrer un plugin de type "SimpleTaskSettings".

Les arguments obligatoires du plugin sont les suivants :

  • taskType - nom de la tâche à laquelle il se réfère
  • templateUrl - URL du fichier HTML contenant l'interface utilisateur - il s'agit de l'un des autres fichiers décrits ci-dessous
  • controller - le contrôleur qui sera connecté au modèle HTML - ce contrôleur est défini dans l'un des fichiers suivants

Son code JavaScript :

angular.module('app.settings').config(function(sqPluginProvider, SQEventsProvider) {
    sqPluginProvider.plugin("SimpleTaskSettings", 1, {
        taskType : 'FilterByCorrelation',
        templateUrl : '../../../plugins/TaskFilterByCorrelation/simpleSettings/simpleSettings.html',
        controller : 'SimpleFilterByCorrelationCtrl',
        getInfoPanels : function(xmlConfig, injector){
            var L = injector.get("L") ;
            var settingsPlugins = sqPluginProvider.getPlugins('SettingsTab') ;
            var groups = [
                {
                    title : L.tsq('Filtering options'),
                    settings : [
                        { name : L.tsq("Filtering"), value : getTaskInfoPanelSettings(xmlConfig, getItem(settingsPlugins, 'configElemName', "FilterByCorrelation")) }
                    ]
                }
            ] ;
           
            retourner les groupes ;
        }
    }) ;
}) ;

 

dossier simpleSettings

Contient l'interface utilisateur pour les réglages simples de ce plugin - il s'agit des mini-réglages qui sont affichés dans l'onglet Progress.

 

SimpleFilterByCorrelationCtrl.js et simpleSettings.html

Code HTML pour les paramètres et contrôleur Angular qui les gère. Le contrôleur de paramètres simple fonctionne de la même manière que le contrôleur de paramètres complet décrit ci-dessus, à une différence près : il n'a pas besoin d'implémenter quand charger les paramètres car cela est déjà fait dans le contrôleur de paramètres complet.

 

styles.css

Fichier pouvant contenir des styles utilisés dans l'interface utilisateur

 

task.xml

Paramètres par défaut de cette tâche. Vous pouvez voir que dans ce plugin, nous sauvegardons essentiellement :

  • 3 banques de données - Source, Cible, Existant
  • Paramètres de filtrage des corrélations

Comme décrit dans FilterByCorrelationService le service manipule directement le XML - il charge le XML à partir du backend et envoie le XML au backend pour enregistrer les modifications.

La structure par défaut des paramètres XML pour notre plugin est définie ici et dans la classe de service.

 

TaskFilterByCorrelation.jar

Il s'agit d'un plugin déjà compilé. Vous ne le verrez pas dans votre propre plugin tant que vous ne l'aurez pas compilé - voir les instructions pour le faire plus tard.

 

TaskFilterByCorrelation.java

Classe Java qui gère le backend de ce plugin. Comme il s'agit d'un plugin de tâche, il est étendu à partir de Tâche abstraite:

public class TaskFilterByCorrelation extends AbstractTask {

 

La méthode la plus importante est démarrer() - Il s'agit de la méthode qui est appelée lorsque vous cliquez sur le bouton Démarrer dans le projet personnalisé, et c'est là que la fonctionnalité principale est mise en œuvre :

    public void start() throws Exception {
        loadSettings() ;

 

au début, il charge les paramètres - cela charge les paramètres qui ont été préparés dans notre deuxième plugin SettingsFilterByCorrelation

Il met ensuite à jour le moteur de progression :

        progressEngine.setLogPrefix(taskLogPrefix) ;
        progressEngine.printToLog(L.t("Starting strategies filtering...")) ;
        progressEngine.start() ;

 

Le reste est la fonctionnalité principale : parcourir une à une les stratégies de la banque de données source, calculer leur corrélation et les copier dans la banque de données cible :

        ResultsGroup strategyCloned ;
        ArrayList results = databankSource.getRecords() ;

        this.totalCopied = 0 ;
        this.totalResults = results.size() ;

        for(int i=0 ; i<results.size() ; i++) {
            ResultsGroup strategy = results.get(i) ;
            String strategyName = strategy.getName() ;
           
            try {
                String dismissalMessage = checkCorrelation(strategy) ;
                if(dismissalMessage != null) {
                    progressEngine.printToLogDebug(L.t("%s skipped, %s", strategyName, dismissalMessage)) ;
                    increaseGlobalStats(false) ;
                   
                    continuer ;
                }
                //copie de la source vers la cible
                strategyCloned = strategy.clone() ;
                databankTarget.add(strategyCloned, true) ;
               
                progressEngine.printToLogDebug(L.t("%s copied, %s", strategyName, String.format("correlation < %.2f", correlation.maxCorrelation))) ;
               
                this.totalCopied++ ;
               
                increaseGlobalStats(true) ;
               
                progressEngine.checkPaused() ;
               
                if(progressEngine.isStopped()) {
                    break ;
                }
            }
            catch (OutOfMemoryError e) {
                project.onMemoryError(e) ;
                break ;
            }
        }
      
        databankTarget.updateBestResults() ;
       
        progressEngine.finish() ;

 

 

Compilation des plugins

Les deux plugins doivent être compilés pour que SQX puisse les charger. Cela peut être fait simplement dans Éditeur de codePour cela, il suffit de cliquer avec le bouton droit de la souris sur le dossier du plugin et de choisir Compiler le plugin dans le menu :

S'il n'y a pas d'erreur, le plugin sera compilé et un nouveau fichier sera créé avec le nom du plugin et le nom de l'utilisateur. .jar apparaîtra dans le dossier.

 

Veuillez noter que vous devez compiler les deux plugins. Ensuite, vous devez redémarrer SQX et vous devriez voir votre nouveau plugin dans les tâches du projet personnalisé.

Cet article a-t-il été utile ? L'article était utile L'article n'était pas utile

S'abonner
Notification pour
3 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
tnickel
26. 11. 2023 10:18 am

J'ai perdu cette fonction depuis longtemps. Je suis heureux maintenant. J'ai obtenu cette fonctionnalité et une description détaillée de la manière de mettre en œuvre mes propres tâches. Je suis heureux.

Jordanie
30. 11. 2023 12:55 pm

Excellent travail ! J'attends avec impatience cette fonctionnalité.

JOSE ANTONIO HERNANDEZ ROSALES
JOSE ANTONIO HERNANDEZ ROSALES
6. 2. 2024 1:12 pm

It’s great. A filter could be made that would choose the best ones in a specific bank. For example, before optimizing, choose the ten best for their stability and the best ten for their total profit…. Thanks

Postes connexes