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
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
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 ! !!!