Documentación

Aplicaciones

Última actualización el 22. 12. 2021 por Mark Fric

Modificación programática de los parámetros de la estrategia

La petición original:

¿Existe alguna forma de aplicar los mejores parámetros sugeridos a la estrategia durante una Optimización Walk-Forward pasada? (Busco hacer esto en mi flujo de trabajo para ejecutar un último OOS con los mejores parámetros aplicados al último período)

 

Es posible, ver ejemplo abajo. Se hace como CustomAnalysis fragmento que se puede ejecutar después de la optimización WF está terminado.

Esto también demuestra cómo aplicar parámetros a la estrategia mediante programación en general.

Tenga en cuenta que el establecimiento de parámetros a la estrategia es bastante complejo, hemos creado una clase especial de ayuda StrategyParametersHelper que se utiliza en este ejemplo.

 

Fragmento de análisis personalizado CAApplyOptimParams - el ejemplo real:

paquete SQ.CustomAnalysis;

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

        // obtener resultado WF de la estrategia (ResultsGroup)
        WalkForwardMatrixResult mwfResult = (WalkForwardMatrixResult) rg.mainResult().get(SettingsKeys.WalkForwardResult);
        if(mwfResult==null) {
            return true;
        }

        // obtener el resultado WF elegido en caso de matriz WF
        WalkForwardResult bestWFResult = mwfResult.getWFResult(rg.getBestWFResultKey(), false);
        if(bestWFResult == null) {
            return true;
        }

        // verificar que el resultado WF tiene algunos periodos
        if(bestWFResult.wfPeriods == null || bestWFResult.wfPeriods.size() <= 0) {
            return true;
        }

        // elige el último periodo - es el que tiene los parámetros que se utilizarán en el futuro
        WalkForwardPeriod lastPeriod = bestWFResult.wfPeriods.get(bestWFResult.wfPeriods.size()-1);

        String lastParameters = lastPeriod.testParameters;
        Log.info("Parámetros futuros recomendados: {}", lastParameters);

        // esto sólo verifica si usamos variables simétricas en la estrategia, o separadas para Largo/Corto
        Elemento lastSettings = XMLUtil.stringToElement(rg.getLastSettings());
        ParametersSettings parametersSettings = new ParametersSettings();
        parametersSettings.setFromXML(lastSettings, rg.getStrategyXml());
        boolean symmetricVariables = parametersSettings.symmetry;

        // establecer nuevos parámetros utilizando esta clase de ayuda
        // los parámetros están en String lastParameters como keys=values separados por coma
        // por ejemplo "FirstPerod=28,SecondPeriod=34,Coef=3.45"
        StrategyParametersHelper.setParameters(rg, lastParameters, symmetricVariables, true);

        return true;
    }
}

 

StrategyParametersHelper clase:

paquete 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);

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

    /**
     * Clase auxiliar para aplicar parámetros a la estrategia
     * @param rg - estrategia (ResultsGroup) para aplicar parámetros
     * @param parameters - parámetros en String como keys=values separados por coma, ejemplo: "FirstPerod=28,SecondPeriod=34,Coef=3.45"
     * @param symmetricVariables - ¿se utilizan variables simétricas?
     * @param modifyLastSettings - ¿modificar también la última configuración almacenada para esta estrategia?
     * @throws Exception
     */
    public static void setParameters(ResultsGroup rg, String parameters, boolean symmetricVariables, boolean modifyLastSettings) throws Exception {

        //Cargar XML y actualizar 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<longitud.parámetros; i++) {
            String[] values = params[i].split("=");
            paramMap.put(valores[0], valores[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, parámetros);

        if(modifyLastSettings){
            try {
                Elemento 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 procesado = false;

                    //debemos encontrar la opción de negociación correcta
                    for(int i=0; i<tradingOptions.size(); i++) {
                        if(procesado) break;

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

                        //recorrer sus parámetros y encontrar el que coincida con el nombre
                        for(int z=0; z<optionParams.size(); z++) {
                            if(procesado) break;

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

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

                            //busque ahora el elemento Param correcto en el XML de configuración y actualice su valor
                            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(valor);

                                    procesado = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                rg.setLastSettings(XMLUtil.elementToString(lastSettings));
            }
            catch(Exception e){
                Log.error("No se pueden aplicar los parámetros de las opciones de negociación a la última configuración", e);
            }
        }
    }
}

 

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

Suscríbase a
Notificar a
2 Comentarios
Más antiguo
Más reciente Más votados
Feedbacks de Inline
Ver todos los comentarios
Emmanuel
23. 12. 2021 12:41 am

¡¡¡¡Gracias, esto es realmente impresionante !!!! Yo no dónde poner StrategyParametersHelper así que cloné una función y la llamé StrategyParametersHelper . está en la carpeta function. debería funcionar

Emmanuel
23. 12. 2021 5:12 am

Encontre la solucion !! solo importando el archivo adjunto . ¡¡¡Este articulo es excelente !!! Me esta ayudando mucho.
¡¡¡¡Muchas gracias por su impresionante trabajo !!!!

Puestos relacionados