Ranks building blocks by performance across multiple databanks to find the most profitable components for your instruments. Analyzes entry/exit signals and key metrics to optimize strategy construction.
1/ What's new in this version
• Building Blocks names instead of variables for easier Out Of Sample analysis
• Analyzes Entry and Exit signals
• Select by signal name: Entry/Exit, Long/Short
• Supports templating with multiple signals
• Creates statistics per databank and lists Building Blocks in C:\temp\
• Generates random groups for each databank for precise Out Of Sample selection
• Creates portfolio of trades from OOS filter selection
• Expandable to 10+ StrategyQuant metrics
2/ Installation
• In CodeEditor: Import "SQExtension RankStratsParameters 15052022 V2 04" and "SQExtension_SortinoRatio"
• Compile and Restart SQX
• Create folder C:\Temp\ with subdirectories: C:\Temp\Results P1, etc. (unzip Directories.rar)
• Import Custom projects:
– "I 1176 Bouillant Research Custom Project EURUSD Ent 1i Ex 1i I" (creates strategies)
– "I 1177 Bouillant Analysis Custom Project" (analyzes if >20000 strategies)
– "I 1177 Bouillant Analysis Plus Custom Project" (analyzes if <20000 strategies)

3/ Testing Building Blocks
Create strategies in custom analysis, analyze Long Entry, Short Entry, Long Exit, Short Exit from Out Of Sample results in another custom analysis.

4/ Building Block Performance
Over 21 years Out Of Sample on 3 instruments, some Building Blocks yield $4959 net profit while others show -$4977 loss per year.


5/ Single Databank Analysis
• Add Custom Analysis Task to Custom Project
• Select "RankStrategiesParameters"
• Select source Databank (e.g., P1R)
• Run task
• Enter 1 as number of DataBanks
• Enter 10 as minimum strategies per Building Block (higher is better)

6/ Multi-Databank Analysis
Analyzes multiple Databanks sequentially, selects Building Blocks per criteria for each period.

7/ Multiple Databanks Setup
Download workflow "I 1172 USDCHF H1 10YP1" (10-year In Sample, 1-year Out Of Sample, H1 timeframe, 7 periods).
Configure databank names:
String DatabankName1 = "P1 R";
String DatabankName2 = "P2 R";
String DatabankName3 = "P3 R";
String DatabankName4 = "P4 R";
String DatabankName5 = "P5 R";
String DatabankName6 = "P6 R";
String DatabankName7 = "P7 R";
For workflow: enter 7 databanks, 10 minimum strategies per block, 1 for portfolio, 2 for Net Profit filter, enter threshold amount.
8/ Results Improvement
EURUSD without filter:

USDCHF without filter:

EURUSD with filter:

USDCHF with filter:

Net profit filter avoided 2020 losses. Test with multiple metrics (Sharpe Ratio, Ulcer Index) and random groups for better results.
9/ Code Overview
Collapse by #Region for structure:

package SQ.CustomAnalysis;
import com.strategyquant.lib.*;
import java.util.ArrayList;
import com.strategyquant.datalib.*;
import com.strategyquant.tradinglib.*;
import com.strategyquant.tradinglib.PlTypes;
import com.strategyquant.tradinglib.project.ProjectEngine;
import com.strategyquant.tradinglib.results.SpecialValues;
import com.strategyquant.datalib.TradingException;
import com.strategyquant.lib.SQTime;
import com.strategyquant.lib.ValuesMap;
import com.strategyquant.lib.XMLUtil;
import java.util.Arrays;
import java.util.Collections;
import java.lang.String;
import com.strategyquant.tradinglib.results.stats.comparator.OrderComparatorByOpenTime;
import SQ.Utils.Bouillant;
import com.strategyquant.lib.L;
import com.strategyquant.tradinglib.optimization.WalkForwardMatrixResult;
import com.strategyquant.lib.ValuesMap;
import java.io.File;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.FileWriter;
import java.util.Scanner;
import javax.swing.JOptionPane;
import java.io.FileNotFoundException;
import java.io.*;
import org.jdom2.*;
import org.jdom2.output.*;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.Document;
import java.io.StringReader;
import java.util.*;
import java.io.IOException;
import org.jdom2.Attribute;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Duration;
import java.time.Instant;
import java.sql.Timestamp;
public class RankStratsParametersV1 extends CustomAnalysisMethod
{
public static final Logger Log = LoggerFactory.getLogger(RankStratsParametersV1.class);
static Boolean DebugMode = false;
static FileWriter FilterWriterTmp;
public RankStratsParametersV1()
{
super("RankStrategiesParameters", TYPE_PROCESS_DATABANK);
}
@Override
public boolean filterStrategy(String project, String task, String databankName, ResultsGroup rg) throws Exception
{
return true;
}
@Override
public ArrayList<ResultsGroup> processDatabank(String project, String task, String databankName, ArrayList<ResultsGroup> databankRG) throws Exception
{
try
{
//#region Init
String LongEntrySignal= "LongEntrySignal";
String ShortEntrySignal= "ShortEntrySignal";
String LongExitSignal= "LongExitSignal";
String ShortExitSignal= "ShortExitSignal";
String stratMetric1= "ProfitFactor";
String stratMetric2 = "NetProfit";
String stratMetric3 = "SharpeRatio";
String stratMetric4 = "UlcerIndex";
String stratMetric5 = "SortinoRatio";
String stratMetric6 = "WinningPct";
String stratMetric7 = "ReturnDDRatio";
String stratMetric8 = "RExpectancy";
String stratMetric9 = "AnnualPctReturnDDRatio";
String stratMetric10 = "Drawdown";
String stratMetric11 = "NumberOfTrades";
//#endregion
String OutputPath1 = "C:\\Temp\\";
String input;
input = (String)JOptionPane.showInputDialog(null, "How many DataBanks are you analysing?", "Analysis Settings", JOptionPane.QUESTION_MESSAGE, null, null, 7);
int NbDataBanks = Integer.parseInt(input);
if (NbDataBanks < 1) {NbDataBanks = 1;}
if (NbDataBanks > 12) {NbDataBanks = 12;}
NbDataBanks = NbDataBanks + 1;
input = (String)JOptionPane.showInputDialog(null,"Enter minimum strategies per Building block", "Analysis Settings", JOptionPane.QUESTION_MESSAGE, null, null, 10);
int minimum = Integer.parseInt(input);
if (minimum <= 0) { minimum = 1 ; }
// Process databanks and create statistics
// [Core processing logic for building block analysis]
return databankRG;
}
catch (Exception e)
{
Log.error("Error RankStratsParametersV1", e);
return databankRG;
}
}
}
Sources:
https://strategyquant.com/doc/programming-for-sq/changing-strategy-parameters-programmatically/
https://strategyquant.com/doc/programming-for-sq/viewing-and-changing-strategy-parameters-version-2/