ドキュメント

アプリケーション

最終更新日:2021年12月22日(マーク・フリック)

プログラムによる戦略パラメータの変更

元のリクエスト

ウォークフォワード最適化(WFO)の過去の期間における推奨された最適なパラメータを、最終期間の最後のOOS(アウト・オブ・サンプル)実行に適用する方法はありますか?(最後の期間に最適なパラメータを適用して、最後のOOSを実行するワークフローに組み込みたいと考えています)

 

可能です。以下の例をご覧ください。これはWF最適化の完了後に実行できるCustomAnalysisスニペットとして作成されています。.

これはまた、プログラムによって戦略にパラメータを適用する方法全般を示すものでもあります。.

ストラテジーへのパラメータの設定はかなり複雑であるため、専用のヘルパー クラスを作成しました。 ストラテジーパラメータヘルパー この例で使用されています。.

 

カスタム分析スニペット CAApplyOptimParams – 実際の例:

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 {

        // get WF result from strategy (ResultsGroup)
        WalkForwardMatrixResult mwfResult = (WalkForwardMatrixResult) rg.mainResult().get(SettingsKeys.WalkForwardResult);
        if(mwfResult==null) {
            return true;
        }

        // get chosen WF result in case of WF Matrix
        WalkForwardResult bestWFResult = mwfResult.getWFResult(rg.getBestWFResultKey(), false);
        if(bestWFResult == null) {
            return true;
        }

        // verify that WF result has some periods
        if(bestWFResult.wfPeriods == null || bestWFResult.wfPeriods.size() <= 0) {
            return true;
        }

        // choose the very last period - it is the one with parameters to be used for future
        WalkForwardPeriod lastPeriod = bestWFResult.wfPeriods.get(bestWFResult.wfPeriods.size()-1);

        String lastParameters = lastPeriod.testParameters;
        Log.info("Recommended future params: {}", lastParameters);

        // this only verifies if we use symmetric variables in the strategy, or separate for Long/Short
        Element lastSettings = XMLUtil.stringToElement(rg.getLastSettings());
        ParametersSettings parametersSettings = new ParametersSettings();
        parametersSettings.setFromXML(lastSettings, rg.getStrategyXml());
        boolean symmetricVariables = parametersSettings.symmetry;

        // set new parameters using ths helper class
        // parameters are in String lastParameters as keys=values separated by comma
        // for example: "FirstPerod=28,SecondPeriod=34,Coef=3.45"
        StrategyParametersHelper.setParameters(rg, lastParameters, symmetricVariables, true);

        return true;
    }
}

 

ストラテジーパラメータヘルパー クラス

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

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

    /**
     * Helper class to set parameters to the strategy
     * @param rg - strategy (ResultsGroup) to apply parameters
     * @param parameters - parameters in String as keys=values separated by comma, example: "FirstPerod=28,SecondPeriod=34,Coef=3.45"
     * @param symmetricVariables - are symmetrical variables used?
     * @param modifyLastSettings - modify also last setting stored for this strategy?
     * @throws Exception
     */
    public static void setParameters(ResultsGroup rg, String parameters, boolean symmetricVariables, boolean modifyLastSettings) throws Exception {

        //Load XML and update variables
        StrategyBase xmlS = StrategyBase.createXmlStrategy(rg.getStrategyXml());
        xmlS.transformToVariables(symmetricVariables);
        Variables variables = xmlS.variables();

        String[] params = parameters.split(",");
        HashMap<String, String> 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<Element> paramElems = elParams.getChildren("Param");

                List<TradingOption> tradingOptions = TradingOptionsList.getInstance().getAvailableClasses();

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

                    //we must find the right trading option
                    for(int i=0; i<tradingOptions.size(); i++) {
                        if(processed) break;

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

                        //go through its params and find the one with matching name
                        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;

                            //now find the right Param element in settings XML and update its value
                            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);
            }
        }
    }
}

 

この記事は参考になりましたか? この記事は役に立った この記事は役に立たなかった

4 コメント
最古の
最新 最も投票された
エマニュエル
2021年12月23日 午後0:41

ありがとうございます、本当に素晴らしいです!!!!どこに置けばいいのか分かりませんでした ストラテジーパラメータヘルパー クラスの皆さん、関数をクローンして名前を付けました ストラテジーパラメータヘルパー . それはfunctionsフォルダの中にあります。動作するはずです。

エマニュエル
2021年12月23日 午前5:12

解決策が見つかりました!!添付ファイルをインポートするだけで大丈夫でした。この記事は素晴らしいです!!!非常に役立っています。.
素晴らしいお仕事ぶりを本当にありがとうございます!!!!

Drunksingha
2024年12月20日 午後1時12分

オプティマイザーセクションで順調に機能しており、現在カスタムワークフローでAutomaricRetestを使用してテスト中です…

Drunksingha
返信する  Drunksingha
2025年5月11日 午前11:43

18:29:22 WF : GRID: ストラテジー結果の処理中にエラーが発生しました – パラメータ設定を読み込めません。要素 ‘Optimization’ が見つかりません

バージョン142で

関連記事