一括検索と置換によるストラテジーの名前変更 – カスタム分析
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).
— 機能
-
Runs as a カスタム分析 (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 コンパイル.
- If needed, restart SQX.
— How to use
- Custom Project → Task → カスタム分析. (Can also be run inside a databank from Databank > Tools > Run CA).
- イン Full databank analysis, 、選択 CARenameFindReplace and choose your Source databank.
- イン 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.
コード
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 – このスニペットはビルド143で完全に動作するようになりました。実行後にデータバンクの再読み込みボタンをクリックするだけです。.
警告!このコードを使用しないでください。記事を削除できません。SQX UI内のストラテジーの名前は変更されますが、なぜかWindowsエクスプローラー上のストラテジーファイルが削除されてしまいます!修正方法を知っている方がいれば、アップデートできるように共有してください。.
更新 – このコメントは無効になりました。無視してください。.
こんにちは
コンパイルに失敗しました。3つのエラーがあります。
バージョン144かもしれません