Documentation

Applications

Dernière mise à jour le 22. 12. 2021 par Mark Fric

Modification programmatique des paramètres de la stratégie

La demande initiale :

Existe-t-il un moyen d'appliquer les meilleurs paramètres suggérés à la stratégie lors d'une Optimisation Walk-Forward passée ? (Je cherche à faire cela dans mon flux de travail pour exécuter un dernier OOS avec les meilleurs paramètres appliqués à la dernière période).

 

C'est possible, voir l'exemple ci-dessous. Il s'agit d'un snippet CustomAnalysis qui peut être exécuté une fois l'optimisation WF terminée.

Cela montre également comment appliquer des paramètres à la stratégie par le biais d'un programme en général.

Notez que la définition des paramètres de la stratégie est assez complexe, nous avons créé une classe d'aide spéciale StrategyParametersHelper qui est utilisé dans cet exemple.

 

Extrait d'analyse personnalisé CAApplyOptimParams - l'exemple concret :

package 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 {

        // obtient le résultat WF de la stratégie (ResultsGroup)
        WalkForwardMatrixResult mwfResult = (WalkForwardMatrixResult) rg.mainResult().get(SettingsKeys.WalkForwardResult) ;
        if(mwfResult==null) {
            return true ;
        }

        // obtient le résultat WF choisi dans le cas d'une matrice WF
        WalkForwardResult bestWFResult = mwfResult.getWFResult(rg.getBestWFResultKey(), false) ;
        if(bestWFResult == null) {
            return true ;
        }

        // vérifier que le résultat WF comporte des périodes
        if(bestWFResult.wfPeriods == null || bestWFResult.wfPeriods.size() <= 0) {
            return true ;
        }

        // choisir la toute dernière période - c'est celle qui contient les paramètres à utiliser à l'avenir
        WalkForwardPeriod lastPeriod = bestWFResult.wfPeriods.get(bestWFResult.wfPeriods.size()-1) ;

        String lastParameters = lastPeriod.testParameters ;
        Log.info("Paramètres futurs recommandés : {}", lastParameters) ;

        // ceci ne vérifie que si nous utilisons des variables symétriques dans la stratégie, ou séparées pour Long/Short
        Element lastSettings = XMLUtil.stringToElement(rg.getLastSettings()) ;
        ParametersSettings parametersSettings = new ParametersSettings() ;
        parametersSettings.setFromXML(lastSettings, rg.getStrategyXml()) ;
        boolean symmetricVariables = parametersSettings.symmetry ;

        // définir de nouveaux paramètres à l'aide de la classe d'aide
        // les paramètres sont dans la chaîne lastParameters sous forme de clés=valeurs séparées par une virgule
        // par exemple : "FirstPerod=28,SecondPeriod=34,Coef=3.45"
        StrategyParametersHelper.setParameters(rg, lastParameters, symmetricVariables, true) ;

        return true ;
    }
}

 

StrategyParametersHelper classe :

paquet 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 org.jdom2.Element ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;

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

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

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

    /**
     * Classe d'aide pour définir les paramètres de la stratégie
     * @param rg - stratégie (ResultsGroup) pour appliquer les paramètres
     * @param parameters - paramètres dans une chaîne de caractères sous forme de clés=valeurs séparées par une virgule, exemple : "FirstPerod=28,SecondPeriod=34,Coef=3.45"
     * @param symmetricVariables - les variables symétriques sont-elles utilisées ?
     * @param modifyLastSettings - modifie-t-il également le dernier paramètre enregistré pour cette stratégie ?
     * @throws Exception
     */
    public static void setParameters(ResultsGroup rg, String parameters, boolean symmetricVariables, boolean modifyLastSettings) throws Exception {

        /Charge de XML et mise à jour des variables
        StrategyBase xmlS = StrategyBase.createXmlStrategy(rg.getStrategyXml()) ;
        xmlS.transformToVariables(symmetricVariables) ;
        Variables variables = 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(values[0], values[1]) ;
        }

        for(int a=0 ; a<variables.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("Options").getChild("BuildTradingOptions").getChild("Params") ;
                List paramElems = elParams.getChildren("Param") ;

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

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

                    //nous devons trouver la bonne option de négociation
                    for(int i=0 ; i<tradingOptions.size() ; i++) {
                        if(processed) break ;

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

                        //se promène dans ses paramètres et trouve celui qui a le nom correspondant
                        for(int z=0 ; z<optionParams.size() ; z++) {
                            if(processed) break ;

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

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

                            //retrouve maintenant le bon élément Param dans le XML des paramètres et met à jour sa valeur
                            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) {
                                        value = "" + SQTime.HHMMToMinutes(Integer.parseInt(value)) * 60 ;
                                    }

                                    elParam.setText(value) ;

                                    processed = true ;
                                    break ;
                                }
                            }
                        }
                    }
                }

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

 

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

S'abonner
Notification pour
2 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
Emmanuel
23. 12. 2021 12:41 am

Merci, c'est vraiment génial ! !!! Je ne savais pas où mettre StrategyParametersHelper j'ai donc cloné une fonction que j'ai nommée StrategyParametersHelper . il se trouve dans le dossier function. il devrait fonctionner

Emmanuel
23. 12. 2021 5:12 am

J'ai trouvé la solution en important le fichier ci-joint. Cet article est excellent ! Il m'aide beaucoup.
Merci beaucoup pour votre travail formidable ! !!!

Postes connexes