Documentación

Aplicaciones

Última actualización el 23. 11. 2023 por Mark Fric

Plugin de ejemplo: una tarea de proyecto personalizada completa

Este artículo es una descripción del desarrollo de un complejo plugin de tareas personalizadas que se puede utilizar dentro de un proyecto personalizado en StrategyQuant.

Nota 1 - hemos tenido que hacer algunos cambios en la estructura de clases para permitir la creación de plugins externos de este tipo, y debido a esto este plugin sólo funcionará a partir de SQX Build 138 y posteriores.

Nota 2 - sólo tenemos documentación y ejemplos limitados sobre la extensión de SQX con plugins, este es uno de ellos. Este ejemplo está destinado a los usuarios que tienen el conocimiento y son capaces de entender el código existente.

 

El objetivo

Para desarrollar una nueva tarea personalizada en StrategyQuant incluyendo la configuración completa.

Implementaremos un nuevo plugin de tareas personalizadas llamado Filtrar por correlación.

 

Por favor, no confunda esto con el plugin de ejemplo ya existente con el mismo nombre en el artículo aquí: https://strategyquant.com/doc/programming-for-sq/filter-by-correlation-plugin-example/

Este ejemplo más antiguo es un plugin más simple que implementa una nueva acción de banco de datos.

Nuestro nuevo ejemplo consistiría en ampliar esta idea e implementar un plugin de tareas completo.

 

El resultado

Como se puede ver a continuación - una nueva tarea llamada Filtro por correlación en los proyectos personalizados tareas para elegir:

 

Y los ajustes de esta nueva tarea:

 

Esta tarea realiza un trabajo sencillo: compara estrategias de Fuente banco de datos con las estrategias existentes en Existente banco de datos y copia los que tienen una correlación inferior a la permitida en Objetivo banco de datos.

Esta (y todas) las tareas personalizadas se componen en realidad de dos plugins interdependientes:

TaskFilterByCorrelation

Plugin que implementa la tarea en sí y la funcionalidad principal, además de la interfaz de usuario para la configuración simple - es el que se ve en la pestaña Progress para esta tarea.

 

AjustesFiltroPorCorrelación

Plugin que implementa la configuración completa de este plugin, incluida la interfaz de usuario: es la que se ve en la pestaña Configuración completa.

Todos los ajustes de esta tarea se cargan utilizando este plugin de Ajustes.

 

Tenga en cuenta que este tipo de plugin combina Java -para la implementación del backend y la funcionalidad- y JavaScript (AngularJS) para la implementación del frontend.

 

Pasos generales necesarios para implantar un nuevo complemento de tareas

  1. Crear plugins de Tareas y Ajustes - ambas partes java y JS
  2. Crear task.xml por defecto con los ajustes de los bancos de datos que se crean automáticamente + ajustes por defecto en el plugin Task.

 

Cualquier tarea nueva que crees debe respetar los nombres de los paquetes:
paquete com.strategyquant.plugin.Task.impl.XXXXXX
paquete com.strategyquant.plugin.Settings.impl.XXXXX

Donde XXXXX es su nombre, SQX crea carpetas para que los nombres de los paquetes coincidan:
TareaXXXXXXXXXX
AjustesXXXXXXXXX

En nuestro caso las carpetas son:
TaskFilterByCorrelation
AjustesFiltroPorCorrelación

 

El mejor enfoque a la hora de crear su propio plugin de tareas sería:

  1. Haga una copia de nuestros dos plugins de ejemplo, cambie los nombres de las clases y las cadenas en el código de "FilterByCorrelation" a su propio nombre
  2. Asegúrate de borrar/no copiar los respectivos archivos .jar al copiar los ejemplos - los archivos .jar se crearán cuando compiles tu propio plugin.
  3. Implementación de la gestión de diferentes configuraciones y funcionalidad principal en los plugins Task y Settings (Java)
  4. Implementación de una interfaz de usuario diferente en los plugins Ajustes y Tareas, tanto en archivos .HTML como .JS.

 

Importación de plugins de ejemplo a su SQX

Los plugins de ejemplo se adjuntan a este artículo (en la parte superior). Ambos plugins vienen en dos archivos diferentes - .sxp y ZIP estándar.

La versión ZIP no es para importar, es sólo por conveniencia - si alguien quiere echar un vistazo a los archivos sin importarlos a SQX.

 

Importar plugins usando .sxp es simple - abra su CodeEditor, vaya a Importar elija, ambos archivos .sxp - para ambos plugins y haga clic en OK.

 

Los plugins se importarán y debería ver las nuevas carpetas de plugins en el explorador de archivos:

Después de esto, sólo tiene que reiniciar su SQX para ver la nueva tarea disponible en Proyectos personalizados.

 

Plugin SettingsFilterByCorrelation

Primero describiremos el plugin de configuración. Se trata de un plugin que implementa los ajustes "completos", es decir, los que aparecen en la ventana Ajustes completos pestaña. Puede tener una interfaz de usuario diferente y más complicada que la configuración sencilla que se muestra en la pestaña Progreso ficha.

 

Una vez más vamos a ir a través de todos los archivos:

 

FilterByCorrelationCtrl.js

Controlador Angular para este plugin. La función principal del controlador es añadir variables (sus valores) en el ámbito y así hacerlos disponibles en el archivo HTML.

 

En los plugins de configuración establecemos toda la configuración de FilterByCorrelationService:

$scope.config = FilterByCorrelationService.config;

 

Además, podemos establecer algunas variables adicionales, por ejemplo, la lista de tipos de correlación/períodos utilizados en los cuadros de lista.

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

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

 

Además de ajustar las variables, este controlador también se encarga de cargar/guardar los ajustes: cuándo deben guardarse y cuándo deben leerse.

 

Existe una acción de controlador settingsChanged() llamado desde HTML en cada cambio de entrada, y este método llama entonces a FilterByCorrelationService.saveSettings() para guardar los ajustes.

 

La carga de los ajustes se activa mediante un evento SETTINGS_TAB_RELOAD que se ejecuta automáticamente al iniciar la pestaña o al cambiar a esta pestaña desde otra.

El controlador de ajustes tiene que añadir un oyente a este evento y al cambiar a esta pestaña de ajustes activará este evento que llamará al comando init() que, a su vez, carga la configuración actual llamando a FilterByCorrelationService.loadSettings();

 

FilterByCorrelationService.js

Servicio para este filtro, que se encarga de cosas como cargar y guardar datos desde/hacia el backend, establecer valores por defecto, etc.

Todos los servicios son instancias singleton, se crean una sola vez cuando se inicia la aplicación.

Cada servicio de configuración contiene un objeto config que contiene la configuración de la tarea seleccionada en ese momento y los métodos loadSettings/saveSettings.

 

La configuración xml actual para la tarea seleccionada se obtiene mediante llamada:

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

 

Entonces podemos leer el valor de xml:

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

 

o escribir valores en él:

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

 

Así que en el servicio cambiamos directamente el XML.

 

Tenga en cuenta que la instancia de servicio es sólo una, compartida entre el plugin de Configuración (interfaz de usuario de configuración completa) y el plugin de Tareas (interfaz de usuario de configuración simple).

 

módulo.js

Registra el plugin en la interfaz de usuario. Para mostrar el panel de configuración completo, debe registrarse un complemento del tipo SettingsTab.

Los atributos obligatorios del plugin son:

  • task - nombre de la tarea para la que debe mostrarse, en este caso "FilterByCorrelation". Si queremos mostrar esta pestaña de configuración también para la tarea Build y Retest, habrá 'FilterByCorrelation,Build,Retest'
  • configElemName - nombre de la configuración en xml
  • templateUrl - qué html mostrar
  • controlador - qué controlador está vinculado al html de la definición templateUrl
  • dataItem - ID pestaña de configuración, debe tener un nombre único entre las pestañas SettingsTab

 

otros ajustes como title, help, helpUrl, son comprensibles a partir del nombre del atributo.

 

settings.html, styles.css

Archivo HTML que contiene la definición UI de los ajustes y la definición CSS de los estilos utilizados.

 

SettingsFilterByCorrelation.jar

Este es un plugin ya compilado. No lo verá en su propio plugin hasta que lo compile - vea las instrucciones sobre cómo hacerlo más adelante.

 

SettingsFilterByCorrelation.java

Clase Java que maneja el backend para este plugin. Implementa ISettingTabPlugin

Interfaz y el método más importante es readSettings() - que lee la configuración del XML proporcionado por la interfaz de usuario (parámetro elSettings), lo analiza y lo guarda en un objeto de datos con las claves exclusivas de este complemento:

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

        try {
            elFiltering = XMLUtil.getChildElem(elSettings, getSettingName());
        } catch(Exception e){
            data.addError(getSettingName(), null, e.getMessage());
            return;
        }
       
        try {
            Banco de datos dbSource = ProjectConfigHelper.getDatabankByType(projectName, "Source", elSettings);
            Databank dbTarget = ProjectConfigHelper.getDatabankByType(projectName, "Target", elSettings);
            Banco de datos 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("No se puede cargar la configuración de FilterByCorrelation. ") + e.getMessage());
        }
    }

 

Plugin TaskFilterByCorrelation

Como se ha dicho anteriormente, este es el plugin "principal" que implementa la funcionalidad. Este plugin también es responsable de mostrar los ajustes "simples" visibles en la pestaña Progress.

 

Puedes ver que el plugin consta de varios archivos, incluyendo la estructura de subcarpetas. Vamos a ir a través de ellos uno por uno.

 

módulo.js

Registra el plugin en la interfaz de usuario. Para mostrar los ajustes simples tiene que registrar un plugin de tipo "SimpleTaskSettings".

Los argumentos obligatorios del plugin son:

  • taskType - nombre de la tarea a la que se refiere
  • templateUrl - URL del archivo HTML que contiene la interfaz de usuario - es uno de los otros archivos descritos a continuación
  • controlador - qué controlador se conectará a la plantilla HTML - de nuevo este controlador se define en uno de los siguientes archivos

Su código JavaScript:

angular.module('app.settings').config(function(sqPluginProvider, SQEventsProvider) {
    sqPluginProvider.plugin("SimpleTaskSettings", 1, {
        taskType: 'FilterByCorrelation',
        templateUrl: '../../../plugins/TaskFilterByCorrelation/simpleSettings/simpleSettings.html',
        controlador: 'SimpleFilterByCorrelationCtrl',
        getInfoPanels: function(xmlConfig, injector){
            var L = injector.get("L");
            var settingsPlugins = sqPluginProvider.getPlugins('SettingsTab');
            var groups = [
                {
                    title: L.tsq('Opciones de filtrado'),
                    configuración: [
                        { name : L.tsq("Filtrado"), value : getTaskInfoPanelSettings(xmlConfig, getItem(settingsPlugins, 'configElemName', "FilterByCorrelation")) }
                    ]
                }
            ];
           
            devolver grupos;
        }
    });
});

 

carpeta simpleSettings

Contiene la interfaz de usuario para la configuración simple de este plugin - es la mini-configuración que se muestra en la pestaña Progress.

 

SimpleFilterByCorrelationCtrl.js y simpleSettings.html

Código HTML para la configuración y controlador Angular que lo maneja. El controlador de configuración simple funciona igual que el controlador de configuración completo descrito anteriormente, con una diferencia: no necesita implementar cuándo cargar la configuración porque esto ya se hace en el controlador de configuración completo.

 

estilos.css

Archivo que puede contener estilos utilizados en la interfaz de usuario

 

tarea.xml

Configuración por defecto de esta tarea. Se puede ver que en este plugin que, básicamente, guardar:

  • 3 bancos de datos - Fuente, Objetivo, Existente
  • Ajustes del filtro de correlación

Como se describe en Servicio FilterByCorrelation descripción, el servicio manipula el XML directamente: carga XML desde el backend y envía XML al backend para guardar los cambios.

La estructura por defecto de la configuración XML para nuestro plugin se define aquí y en la clase de servicio.

 

TaskFilterByCorrelation.jar

Este es un plugin ya compilado. No lo verá en su propio plugin hasta que lo compile - vea las instrucciones sobre cómo hacerlo más adelante.

 

TaskFilterByCorrelation.java

Clase Java que maneja el backend para este plugin. Debido a que es un plugin de tareas, se extiende desde Tarea abstracta:

public class TareaFiltroPorCorrelación extends TareaAbstracta {

 

El método más importante es iniciar() - este es el método que se llama cuando se hace clic en el botón Inicio en el proyecto personalizado, y aquí es donde se implementa la funcionalidad principal:

    public void start() lanza Excepción {
        loadSettings();

 

al principio carga ajustes - esto carga ajustes que fueron preparados en nuestro segundo plugin AjustesFiltroPorCorrelación

A continuación, actualiza el motor de progreso:

        progressEngine.setLogPrefix(taskLogPrefix);
        progressEngine.printToLog(L.t("Iniciando filtrado de estrategias..."));
        progressEngine.start();

 

Y el resto es la funcionalidad principal: recorrer una a una las estrategias de la base de datos de origen, calcular su correlación y copiarlas en la base de datos de destino:

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

        this.totalCopiado = 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(estrategia);
                if(dismissalMessage != null) {
                    progressEngine.printToLogDebug(L.t("%s omitido, %s", strategyName, dismissalMessage));
                    increaseGlobalStats(false);
                   
                    continuar;
                }
                //copiar del origen al destino
                strategyCloned = strategy.clone();
                databankTarget.add(estrategiaClonada, true);
               
                progressEngine.printToLogDebug(L.t("%s copiado, %s", strategyName, String.format("correlación < %.2f", correlación.maxCorrelación)));
               
                this.totalCopied++;
               
                increaseGlobalStats(true);
               
                progressEngine.checkPaused();
               
                if(progressEngine.isStopped()) {
                    break;
                }
            }
            catch (OutOfMemoryError e) {
                project.onMemoryError(e);
                break;
            }
        }
      
        databankTarget.updateBestResults();
       
        progressEngine.finish();

 

 

Compilación de plugins

Ambos plugins tienen que ser compilados para que SQX pueda cargarlos. Esto se puede hacer simplemente en Editor de código, basta con hacer clic con el botón derecho del ratón en la carpeta del plugin y elegir Compilar plugin del menú:

Si no hay errores, el plugin se compilará y se creará un nuevo archivo con el nombre del plugin y la extensión .jar aparecerá en la carpeta.

 

Ten en cuenta que tienes que compilar ambos plugins. Luego tienes que reiniciar SQX y deberías ver tu nuevo plugin en las tareas personalizadas del proyecto.

¿Le ha resultado útil este artículo? El artículo era útil El artículo no era útil

Suscríbase a
Notificar a
3 Comentarios
Más antiguo
Más reciente Más votados
Feedbacks de Inline
Ver todos los comentarios
tnickel
26. 11. 2023 10:18

Me perdí esta función hace mucho tiempo. Ahora estoy contento. Tengo esta función y una descripción superior de cómo implementar tareas propias. Estoy contento.

Jordan
30. 11. 2023 12:55 pm

Muy buen trabajo. Espero con impaciencia esta función, gracias.

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

Puestos relacionados