Dokumentation

Anwendungen

Zuletzt aktualisiert am 22. 12. 2021 von Mark Fric

Programmatische Änderung der Strategieparameter

Der ursprüngliche Antrag:

Gibt es eine Möglichkeit, die besten vorgeschlagenen Parameter auf die Strategie während einer durchgeführten Walk-Forward-Optimierung anzuwenden? (Ich möchte dies in meinem Workflow tun, um eine letzte OOS mit den besten Parametern für die letzte Periode auszuführen).

 

Das ist möglich, siehe Beispiel unten. Es wird als CustomAnalysis-Snippet erstellt, das nach Abschluss der WF-Optimierung ausgeführt werden kann.

Hier wird auch gezeigt, wie man generell Parameter programmatisch auf Strategien anwenden kann.

Da das Setzen von Parametern für die Strategie recht komplex ist, haben wir eine spezielle Hilfsklasse StrategyParametersHelper die in diesem Beispiel verwendet wird.

 

Benutzerdefiniertes Analyse-Snippet CAApplyOptimParams - das aktuelle Beispiel:

Paket SQ.CustomAnalysis;

import com.strategyquant.lib.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.strategyquant.tradinglib.*;
import com.strategyquant.tradinglib.optimization.ParametersSettings;
import com.strategyquant.tradinglib.optimization.WalkForwardMatrixResult;

import org.jdom2.Element;
import SQ.Utils.StrategyParametersHelper;

public class CAApplyOptimParams extends CustomAnalysisMethod {
    public static final Logger Log = LoggerFactory.getLogger("CAApplyOptimParams");

    //------------------------------------------------------------------------
    //------------------------------------------------------------------------
    //------------------------------------------------------------------------
    
    public CAApplyOptimParams() {
        super("CAApplyOptimParams", TYPE_FILTER_STRATEGY);
    }
    
    //------------------------------------------------------------------------
    
    @Override
    public boolean filterStrategy(String project, String task, String databankName, ResultsGroup rg) throws Exception {

        // WF-Ergebnis von Strategie abrufen (ResultsGroup)
        WalkForwardMatrixResult mwfResult = (WalkForwardMatrixResult) rg.mainResult().get(SettingsKeys.WalkForwardResult);
        if(mwfResult==null) {
            return true;
        }

        // liefert das gewählte WF-Ergebnis im Falle von WF Matrix
        WalkForwardResult bestWFResult = mwfResult.getWFResult(rg.getBestWFResultKey(), false);
        if(bestWFResult == null) {
            return true;
        }

        // Überprüfen, ob das WF-Ergebnis einige Perioden enthält
        if(bestWFResult.wfPeriods == null || bestWFResult.wfPeriods.size() <= 0) {
            return true;
        }

        // Auswahl der allerletzten Periode - es ist diejenige mit Parametern, die für die Zukunft verwendet werden soll
        WalkForwardPeriod lastPeriod = bestWFResult.wfPeriods.get(bestWFResult.wfPeriods.size()-1);

        String lastParameters = lastPeriod.testParameters;
        Log.info("Empfohlene zukünftige Parameter: {}", lastParameters);

        // dies prüft nur, ob wir symmetrische Variablen in der Strategie verwenden, oder getrennt für Long/Short
        Element lastSettings = XMLUtil.stringToElement(rg.getLastSettings());
        ParametersSettings parametersSettings = new ParametersSettings();
        parametersSettings.setFromXML(lastSettings, rg.getStrategyXml());
        boolean symmetricVariables = parametersSettings.symmetry;

        // neue Parameter mit Hilfe dieser Hilfsklasse setzen
        // Parameter sind im String lastParameters als Schlüssel=Werte durch Komma getrennt
        // zum Beispiel: "FirstPerod=28,SecondPeriod=34,Coef=3.45"
        StrategyParametersHelper.setParameters(rg, lastParameters, symmetricVariables, true);

        return true;
    }
}

 

StrategyParametersHelper Klasse:

Paket SQ.Utils;

import com.strategyquant.lib.SQTime;
import com.strategyquant.lib.XMLUtil;
import com.strategyquant.tradinglib.*;
import com.strategyquant.tradinglib.options.TradingOptionsList;
import com.strategyquant.tradinglib.propertygrid.IPGParameter;
import com.strategyquant.tradinglib.propertygrid.ParametersTableItemProperties; import com.strategyquant.tradinglib.propertygrid.ParametersTableItemProperties;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap; import java.util;
import java.util.List;

public class StrategyParametersHelper {
    public static final Logger Log = LoggerFactory.getLogger(StrategyParametersHelper.class);

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

    /**
     * Hilfsklasse zum Setzen von Parametern für die Strategie
     * @param rg - Strategie (ResultsGroup) zur Anwendung der Parameter
     * @param parameters - Parameter in String als Schlüssel=Werte durch Komma getrennt, Beispiel: "FirstPerod=28,SecondPeriod=34,Coef=3.45"
     * @param symmetricVariables - werden symmetrische Variablen verwendet?
     * @param modifyLastSettings - soll auch die letzte für diese Strategie gespeicherte Einstellung geändert werden?
     * @throws Exception
     */
    public static void setParameters(ResultsGroup rg, String parameters, boolean symmetricVariables, boolean modifyLastSettings) throws Exception {

        //Laden von XML und Aktualisieren von Variablen
        StrategyBase xmlS = StrategyBase.createXmlStrategy(rg.getStrategyXml());
        xmlS.transformToVariables(symmetricVariables);
        Variablen Variablen = xmlS.variables();

        String[] params = parameters.split(",");
        HashMap paramMap = new HashMap();

        for(int i=0; i<params.length; i++) {
            String[] values = params[i].split("=");
            paramMap.put(Werte[0], Werte[1]);
        }

        for(int a=0; a<variablen.size(); a++) {
            Variable Variable = variables.get(a);
            if(paramMap.containsKey(variable.getName())) {
                variable.setFromString(paramMap.get(variable.getName()));
            }
        }

        xmlS.transformToNumbers();

        rg.portfolio().addStrategyXml(xmlS.getStrategyXml());
        rg.specialValues().setString(StatsKey.OPTIMIZATION_PARAMETERS, parameters);

        if(modifyLastSettings){
            try {
                Element lastSettings = XMLUtil.stringToElement(rg.getLastSettings());
                Element elParams = lastSettings.getChild("Optionen").getChild("BuildTradingOptions").getChild("Params");
                List paramElems = elParams.getChildren("Param");

                List tradingOptions = TradingOptionsList.getInstance().getAvailableClasses();

                for(String paramName : paramMap.keySet()) {
                    boolean processed = false;

                    //wir müssen die richtige Handelsoption finden
                    for(int i=0; i<tradingOptions.size(); i++) {
                        if(verarbeitet) break;

                        TradingOption option = tradingOptions.get(i);
                        String optionClass = option.getClass().getSimpleName();
                        ArrayList optionParams = option.getParams();

                        //Die Parameter durchgehen und denjenigen mit dem passenden Namen finden
                        for(int z=0; z<optionParams.size(); z++) {
                            if(verarbeitet) break;

                            IPGParameter optionParam = optionParams.get(z);
                            String paramKey = optionParam.getKey();

                            if(!optionParam.getName().equals(paramName)) continue;

                            //jetzt das richtige Param-Element im Einstellungs-XML finden und seinen Wert aktualisieren
                            for(int s=0; s<paramElems.size(); s++) {
                                Element elParam = paramElems.get(s);
                                String elParamClass = elParam.getAttributeValue("className");
                                String elParamKey = elParam.getAttributeValue("key");

                                if(elParamClass != null && elParamKey != null && elParamClass.equals(optionClass) && elParamKey.equals(paramKey)) {
                                    String value = paramMap.get(paramName);

                                    if(optionParam.getType() == ParametersTableItemProperties.TYPE_TIME) {
                                        Wert = "" + SQTime.HHMMToMinutes(Integer.parseInt(Wert)) * 60;
                                    }

                                    elParam.setText(value);

                                    verarbeitet = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                rg.setLastSettings(XMLUtil.elementToString(lastSettings));
            }
            catch(Exception e){
                Log.error("Cannot apply trading options params to last settings", e);
            }
        }
    }
}

 

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

Abonnieren
Benachrichtigen Sie mich bei
2 Kommentare
Älteste
Neuestes Meistgewählt
Inline-Rückmeldungen
Alle Kommentare anzeigen
Emmanuel
23. 12. 2021 12:41 Uhr

Vielen Dank, das ist wirklich großartig !!!! Ich wusste nicht, wohin ich die StrategyParametersHelper Klasse, also klonte ich eine Funktion und nannte sie StrategyParametersHelper . es befindet sich im Funktionsordner. es sollte funktionieren

Emmanuel
23. 12. 2021 5:12 Uhr

Ich habe die Lösung gefunden, indem ich einfach die angehängte Datei importiert habe. Dieser Artikel ist ausgezeichnet !!! Er ist eine große Hilfe.
Vielen Dank für Ihre großartige Arbeit !!!!

Verwandte Beiträge