Dokumentation

Anwendungen

Zuletzt aktualisiert am 10. 8. 2022 von Mark Fric

Programmatische Änderung der Aufgabenkonfiguration

Wichtiger Hinweis - dieses Beispiel funktioniert nur in Build 136 oder höher

In diesem Artikel zeigen wir Ihnen, wie Sie die Konfiguration von Aufgaben in Ihrem benutzerdefinierten Projekt programmatisch ändern können, indem Sie das Snippet Benutzerdefinierte Analyse verwenden.

Die Idee ist, dass Sie eine Schleife im benutzerdefinierten Projekt-Workflow erstellen und ein CA-Snippet als eine der Aufgaben haben, die die Einstellungen einer anderen Build/Retest/Optimierungsaufgabe(n) im Projekt mit jeder Schleife ändert.

Auf diese Weise können Sie z.B. die Strategien auf gleitende Datenbereiche neu testen oder optimieren.

Wir werden dies wieder als CustomAnalysis-Snippet implementieren, die Implementierung erfolgt in processDatabank() Methode.

 

Wie es auf der UI aussieht

Im folgenden Screenshot sehen Sie ein einfaches Projekt, das aus nur zwei Aufgaben besteht:

  1. CustomAnalysis-Aufgabe - sie führt unser neues CA-Snippet aus, das den Datumsbereich der nächsten "Build strategies"-Aufgabe ändert
  2. Build strategies task - dies ist die Aufgabe, deren Einstellungen durch unser CA-Snippet geändert werden

Dies ist nur ein primitives Beispiel - eine Demonstration dessen, was getan werden kann.

Dieses benutzerdefinierte Beispielprojekt ist diesem Artikel beigefügt.

 

Schauen wir uns nun unser Ca-Snippet an, das dies tut.

 

Projekt und Aufgabe(n) erhalten

So erhalten Sie Ihr aktuelles Projekt und die gewünschte(n) Aufgabe(n):

public ArrayList processDatabank(String project, String task, String databankName, ArrayList databankRG) throws Exception {

    // aktuelles Projekt ermitteln
    SQProject sqProject = ProjectEngine.get(project);

    // Aufgabe nach Name abrufen
    ISQTask buildTask = sqProject.getTaskByName("Strategien erstellen");
    if(buildTask == null) {
        throw new Exception("Eine solche Aufgabe existiert nicht!");
    }
    // alternativ können Sie sqProject.getTasks() verwenden, um eine Liste aller Aufgaben zu erhalten
    // und sie durchgehen, um die gewünschte Aufgabe zu finden

 

Konfiguration von der Aufgabe abrufen

Die aktuelle Konfiguration dieser Aufgabe zu erhalten ist wieder einfach - Sie müssen nur getConfig() Methode der Aufgabe:

// So erhalten Sie die XML-Aufgabeneinstellungen auf die neue Art (SQ 136 oben)
// Es gibt ein JDOM XML Element mit der vollständigen Aufgabenkonfiguration zurück
Element elConfig = buildTask.getConfig();

// Erstellen Sie eine neue Konfiguration, indem Sie sie klonen - es ist wichtig, einen Klon zu erstellen,
// sonst wird die neue Konfiguration nicht übernommen
Element elNewConfig = elConfig.clone();

 

Beachten Sie, dass getConfig() wird ein JDOM-Element zurückgeben, das die XML-Datei der Aufgabenkonfiguration enthält. Wir müssen es in ein neues Element klonen, um es zu ändern.

Die XML-Struktur der Aufgabe geht über den Rahmen dieses Artikels hinaus, aber Sie können die XML-Konfiguration jeder Aufgabe leicht sehen, wenn Sie sie in .cfx Format, oder Sie können einen Blick werfen auf /Benutzer/Projekte/Ihr_Projekt/project.cfx

.cfx-Datei ist ein ZIP-Archiv und kann normalerweise geöffnet werden mit WinZip oder WinRar.

Wenn Sie sie öffnen, werden Sie sehen, dass sie für jede Aufgabe im Projekt eine eigene XML-Datei enthält.

Sie können Siehe um die genaue Struktur der Aufgaben-XML zu sehen.

 

Etwas in der Taskkonfiguration ändern

Es hängt davon ab, was Sie wollen, Sie können alles im XML ändern - solange es noch eine gültige XML-Struktur für eine bestimmte Aufgabe ist.

In unserem Beispiel holen wir uns das erste -Element - in dem die Symboleinstellungen für den Haupt-Backtest gespeichert sind - und ändern die Daten von - bis.

// jetzt alles in der neuen Konfiguration ändern
Element data = XMLUtil.getChildElem(elNewConfig, "Daten");
Element setups = data.getChild("Setups");
List setupList = setups.getChildren("Setup");

if (setupList.size() > 0) {
    Element firstSetup = (Element) setupList.get(0);

    DateTimeFormatter formatter = DateTimeFormat.forPattern("jjjj.MM.tt");

    firstSetup.setAttribute("dateFrom", SQTime.formatDate(SQTime.toLong(2007, 1, 1), formatter));
    firstSetup.setAttribute("dateTo",SQTime.formatDate(SQTime.toLong(2017, 1, 1), formatter));
}

 

Alternative zur Änderung der Konfiguration durch Laden aus einer vorbereiteten Datei

Es gibt noch eine andere Möglichkeit, eine andere Konfiguration auf eine Aufgabe anzuwenden - Sie können sie zunächst als Datei vorbereiten und sie dann einfach in das Element in unserem Snippet laden:

// alternativ können Sie die neue Aufgabenkonfiguration aus einer vorbereiteten Datei laden
Element elNewConfig = XMLUtil.fileToXmlElement(new File("c:/BuildTask2009_2019.xml"));

 

Anwenden der Konfiguration auf eine Aufgabe

er letzte Schritt ist die Anwendung der Konfiguration auf eine Aufgabe, dies geschieht durch den einfachen Aufruf setConfig() Methode

// Die geänderte Konfiguration auf die Aufgabe anwenden
buildTask.setConfig(elNewConfig, true);

 

Dadurch wird die geänderte Konfiguration auf eine bestimmte Aufgabe angewendet, die sie dann verwendet.

Es wird alles funktionieren, das einzige Problem ist, dass diese Änderung nur im Hintergrund durchgeführt wird, Sie werden Ihre Änderung nicht in der Benutzeroberfläche sehen.

Wenn Sie sie auch in der Benutzeroberfläche sehen wollen, müssen Sie noch einen Schritt tun, um die Projektkonfiguration zu aktualisieren:

// Dies benachrichtigt die Benutzeroberfläche, um die geänderte Konfiguration zu laden und auf die Benutzeroberfläche anzuwenden.
// Ohne dies würde es immer noch funktionieren, aber Sie werden die Änderungen nicht in der UI sehen
JSONObject jsonData = new JSONObject().put("projectConfig", sqProject.toJSON());
DataToSend dataToSend = new DataToSend(WebSocketConst.UpdateProject, jsonData);
SQWebSocketManager.addToDataQueue(dataToSend, SQConst.CODE_TASKMANAGER);

 

 

Vollständiger Code des CAChangeTaskConfig-Snippets:

Paket SQ.CustomAnalysis;

import com.strategyquant.lib.SQTime;
import com.strategyquant.lib.XMLUtil;
import com.strategyquant.lib.constants.SQConst;
import com.strategyquant.tradinglib.CustomAnalysisMethod; import com.strategyquant.tradinglib.CustomAnalysisMethod;
import com.strategyquant.tradinglib.ResultsGroup; import com.strategyquant.tradinglib.ResultsGroup;
import com.strategyquant.tradinglib.project.ProjectEngine;
import com.strategyquant.tradinglib.project.SQProject; import com.strategyquant.tradinglib.project.SQProject;
import com.strategyquant.tradinglib.project.websocket.DataToSend;
import com.strategyquant.tradinglib.project.websocket.SQWebSocketManager;
import com.strategyquant.tradinglib.project.websocket.WebSocketConst;
import com.strategyquant.tradinglib.taskImpl.ISQTask;
import org.jdom2.Element;
import org.joda.time.format.DateTimeFormat;
importieren org.joda.time.format.DateTimeFormatter;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class CAChangeTaskConfig extends CustomAnalysisMethod {

    //------------------------------------------------------------------------
    //------------------------------------------------------------------------
    //------------------------------------------------------------------------

    public CAChangeTaskConfig() {
        super("CAChangeTaskConfig", TYPE_PROCESS_DATABANK);
    }

    //------------------------------------------------------------------------

    @Override
    public ArrayList processDatabank(String project, String task, String databankName, ArrayList databankRG) throws Exception {

        // aktuelles Projekt ermitteln
        SQProject sqProject = ProjectEngine.get(project);

        // Aufgabe nach Name abrufen
        ISQTask buildTask = sqProject.getTaskByName("Strategien erstellen");
        if(buildTask == null) {
            throw new Exception("Eine solche Aufgabe existiert nicht!");
        }
        // alternativ können Sie sqProject.getTasks() verwenden, um eine Liste aller Aufgaben zu erhalten
        // und sie durchgehen, um die gewünschte Aufgabe zu finden


        // So erhält man das XML der Aufgabeneinstellungen auf die neue Art (SQ 136 up)
        // Es gibt ein JDOM XML Element mit der vollständigen Aufgabenkonfiguration zurück
        Element elConfig = buildTask.getConfig();
        // Erstellen Sie eine neue Konfiguration, indem Sie sie klonen - es ist wichtig, einen Klon zu erstellen,
        // sonst wird die neue Konfiguration nicht übernommen
        Element elNewConfig = elConfig.clone();

        // Ändern Sie nun alles in der neuen Konfiguration
        Element data = XMLUtil.getChildElem(elNewConfig, "Daten");
        Element setups = data.getChild("Setups");
        List setupList = setups.getChildren("Setup");

        if (setupList.size() > 0) {
            Element firstSetup = (Element) setupList.get(0);

            DateTimeFormatter formatter = DateTimeFormat.forPattern("jjjj.MM.tt");

            firstSetup.setAttribute("dateFrom", SQTime.formatDate(SQTime.toLong(2007, 1, 1), formatter));
            firstSetup.setAttribute("dateTo",SQTime.formatDate(SQTime.toLong(2017, 1, 1), formatter));
        }

        // alternativ kann die neue Taskkonfiguration aus einer vorbereiteten Datei geladen werden
        //Element elNewConfig = XMLUtil.fileToXmlElement(new File("c:/BuildTask2009_2019.xml"));

        // Die geänderte Konfiguration auf die Aufgabe anwenden
        buildTask.setConfig(elNewConfig, true);

        // Dies benachrichtigt die Benutzeroberfläche, um die geänderte Konfiguration zu laden und sie auf die Benutzeroberfläche anzuwenden.
        // Ohne dies würde es immer noch funktionieren, aber Sie werden die Änderungen nicht in der UI sehen
        JSONObject jsonData = new JSONObject().put("projectConfig", sqProject.toJSON());
        DataToSend dataToSend = new DataToSend(WebSocketConst.UpdateProject, jsonData);
        SQWebSocketManager.addToDataQueue(dataToSend, SQConst.CODE_TASKMANAGER);

        return databankRG;
    }
}

 

 

 

 

 

 

 

 

 

War dieser Artikel hilfreich? Der Artikel war nützlich Der Artikel war nicht nützlich

Abonnieren
Benachrichtigen Sie mich bei
1 Kommentar
Älteste
Neuestes Meistgewählt
Inline-Rückmeldungen
Alle Kommentare anzeigen
Emmanuel
10. 8. 2022 1:26 Uhr

Vielen Dank! Eine ausgezeichnete Idee!

Verwandte Beiträge