23. 2. 2026

5 4

一括検索と置換によるストラテジーの名前変更 – カスタム分析

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 just find 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

  1. Code Editor → New → Custom Analysis, name the file CARenameFindReplace
  2. Paste the code (below) and コンパイル.
  3. If needed, restart SQX.

How to use

  1. Custom Project → Task → カスタム分析. (Can also be run inside a databank from Databank > Tools > Run CA).
  2. イン Full databank analysis, 、選択 CARenameFindReplace and choose your Source databank.
  3. イン Input args enter one of:
    -
    Replace: old=>new
    Remove: old
    -
  4. 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.)
  5. 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");
    }
}

 

4 コメント
最古の
最新 最も投票された
ヴァンサン・オラン
2026年5月13日 午後9:20

こんにちは
コンパイルに失敗しました。3つのエラーがあります。
バージョン144かもしれません

関連記事