Rename Strategies with Batch Find & Replace – Custom Analysis
Ideal if you want to quickly create clean, informative names across a whole databank – this Custom Analysis snippet lets you batch rename strategies in StrategyQuant X using simple find → replace (or just find → remove).
— What it does
-
Runs as a Custom Analysis (Full databank analysis).
-
Input args accepts
find=>replace or justfind to remove. -
Renames in place in the selected Source databank.
-
Literal, case-sensitive match. Supports
\n,\t,\r. -
Great for mass cleaning: trim prefixes/suffixes, remove words, standardize symbols/timeframes/directions.
— How to install
- Code Editor → New → Custom Analysis, name the file
CARenameFindReplace - Paste the code (below) and Compile.
- If needed, restart SQX.
— How to use
- Custom Project → Task → Custom Analysis. (Can also be run inside a databank from Databank > Tools > Run CA).
- In Full databank analysis, select CARenameFindReplace and choose your Source databank.
- In Input args enter one of:
-
Replace: old=>new
Remove: old
- - Enable 'Filter by results of custom analysis' to rename the original strategies. (If you disable this, the strategies will be duplicated and only the duplicates renamed, leaving the originals untouched.)
- Run. All strategy names in the Source databank are updated.
— Examples
- Remove the word “Strategy ” (with trailing space):
Strategy => - Convert SQX auto-name to a formatted label:
Strategy =>XAUUSD_H1_L_ - Strip dots after a prefix pass:
.=>
Tip: Run multiple passes for multi-step formatting (e.g., add a prefix, then strip characters, then add a suffix). Consider duplicating the databank first if you want an easy rollback.
Code:
package SQ.CustomAnalysis;
import com.strategyquant.tradinglib.*;
import com.strategyquant.tradinglib.project.ProjectEngine;
import com.strategyquant.tradinglib.project.SQProject;
import java.util.ArrayList;
import java.util.HashSet;
public class CARenameFindReplace extends CustomAnalysisMethod {
public CARenameFindReplace() {
super("CARenameFindReplace", TYPE_PROCESS_DATABANK);
}
@Override
public boolean filterStrategy(String project, String task, String databankName, ResultsGroup rg) throws Exception {
return true;
}
@Override
public ArrayList processDatabank(
String project,
String task,
String databankName,
ArrayList databankRG) throws Exception {
// Read single Input args string
String raw = getInputArgs();
if (raw == null) raw = "";
raw = raw.trim();
// No args -> do nothing
if (raw.isEmpty()) {
return databankRG;
}
// Parse: "find=>replace" OR just "find" (remove)
String find, repl;
int arrow = raw.indexOf("=>");
if (arrow >= 0) {
find = raw.substring(0, arrow);
repl = raw.substring(arrow + 2);
} else {
find = raw;
repl = "";
}
find = unescape(find);
repl = unescape(repl);
// If find is empty, do nothing (prevents accidental rename-all)
if (find.isEmpty()) {
return databankRG;
}
SQProject prj = ProjectEngine.get(project);
Databank db = prj.getDatabanks().get(databankName);
// Snapshot of originals to avoid ConcurrentModificationException
ArrayList snapshot = new ArrayList<>(databankRG);
// Track existing names so we can avoid collisions if needed
HashSet usedNames = new HashSet<>();
for (ResultsGroup rg : snapshot) {
if (rg.getName() != null) usedNames.add(rg.getName());
}
// 1) Create renamed clones (no db.add inside the iteration)
ArrayList clonesToAdd = new ArrayList<>();
for (ResultsGroup rg : snapshot) {
String oldName = rg.getName();
if (oldName == null) continue;
String newName = oldName.replace(find, repl);
// Only duplicate if name changes
if (!newName.equals(oldName)) {
// Avoid exact-name collisions (optional safety)
String finalName = makeUniqueName(newName, usedNames);
ResultsGroup newRg = rg.clone();
newRg.setName(finalName);
clonesToAdd.add(newRg);
usedNames.add(finalName);
}
}
// 2) Add clones after iteration (safe)
for (ResultsGroup newRg : clonesToAdd) {
db.add(newRg, true);
}
// Return the newly created strategies (mirrors SQX RenameStrategies behaviour)
return clonesToAdd;
}
private static String makeUniqueName(String baseName, HashSet used) {
if (!used.contains(baseName)) return baseName;
int i = 2;
while (true) {
String candidate = baseName + "_" + i;
if (!used.contains(candidate)) return candidate;
i++;
}
}
private static String unescape(String s) {
if (s == null) return "";
return s.replace("\\n", "\n")
.replace("\\t", "\t")
.replace("\\r", "\r");
}
}
UPDATE – this snippet is now fully working in Build 143, you just need to click the reload databanks button after running it.
Warning! Do not use this code. I cannot delete the article. It renames the strategies inside the SQX UI, but it somehow deletes the strategy file in Windows explorer! If anyone knows how to fix it, please share so I can update it.
UPDATE – This comment is now invalid. Please ignore.
Hi
Compilation failed for me. 3 errors
Maybe version 144