Analysieren Sie Strategie-XML, um Einstellungen, Variablen, Regeln und Parameter einschließlich Stop-Loss und Gewinnzielen für benutzerdefinierte Analysen und Automatisierungen zu extrahieren.
Dank der Dokumentation zum Anzeigen und Ändern von Strategieparametern können wir Strategievariablen auslesen.
Dieses Codebeispiel liest Strategie-XML, Variablen und Regeln aus.
1. Strategie-Übersicht
- Strategie-XML kann mit XMLUtil.elementToString() ausgelesen werden.
Führen Sie die benutzerdefinierte Analyse XmlStrategyToFile oder XmlStrategyToFileSym (symmetrische Strategien) aus, um Daten aus der Databank auf die Festplatte zu exportieren. Öffnen Sie XML-Dateien in einem beliebigen XML-Reader wie https://jsonformatter.org/xml-editor.

- Strategien besitzen Regeln und Variablen.

In der Erweiterung SQ.utils.Bouillant extension zeigt die Funktion toBuildingBlocksName zwei Bereiche: Variables und Rules.

2. XMLUtil-Klasse und JDOM-Element
XMLUtil API-Dokumentation
3. Auslesen von Strategievariablen
Variablenwerte abrufen:
- getVariableValueToBoolean
- getVariableValueToInt
- getVariableValueToDouble
4. Beispiel: Stop-Loss und Profit-Target extrahieren
Benutzerdefinierte Analyse CA_StrategySettings oder CA_StrategySettingsSym:

@Override
public boolean filterStrategy(String project, String task, String databankName, ResultsGroup rg) throws Exception
{
Bouillant BouilltParaObj1 = new Bouillant();
int IntTemp = BouilltParaObj1.getVariableValueToInt(rg, false,"LongProfitTarget");
rg.specialValues().set("CA_Long_ProfitTarget", IntTemp);
IntTemp = BouilltParaObj1.getVariableValueToInt(rg, false,"ShortProfitTarget");
rg.specialValues().set("CA_Short_ProfitTarget", IntTemp);
IntTemp = BouilltParaObj1.getVariableValueToInt(rg, false,"LongStopLoss");
rg.specialValues().set("CA_Long_StopLoss", IntTemp);
IntTemp = BouilltParaObj1.getVariableValueToInt(rg, false,"ShortStopLoss");
rg.specialValues().set("CA_Short_StopLoss", IntTemp);
IntTemp = BouilltParaObj1.getVariableValueToInt(rg, false,"LongTrailingStop");
rg.specialValues().set("CA_Long_TrailingStop", IntTemp);
IntTemp = BouilltParaObj1.getVariableValueToInt(rg, false,"ShortTrailingStop");
rg.specialValues().set("CA_Short_TrailingStop", IntTemp);
return true;
}


5. XML-Strategie Schritt für Schritt auslesen
A. Root-Element abrufen:
StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);
Element Strategie1 = strategyBase.getStrategyXml();
B. Bestimmtes untergeordnetes Element abrufen:
Element elParams = Strategie1.getChild("Strategy").getChild("Variables");
elParams = Strategie1.getChild("Strategy").getChild("Rules").getChild("Events");
C. Untergeordnete Elemente in Liste abrufen:
List<Element> paramElems = elParams.getChildren();
D. NodeValue auslesen:
for (i = 0; i < paramElems.size(); i++) {
Element elParam = paramElems.get(i);
String name = XMLUtil.getNodeValue(elParam,"name");
String id = XMLUtil.getNodeValue(elParam,"id");
}
E. AttributeValue abrufen:
String elParamKey = elParam.getAttributeValue("key");
F. Element in String umwandeln:
String String1 = XMLUtil.elementToString(elParam);
6. Anwendung: Aufrufen der Funktion

DataBank-Spalten-Snippet:
Bouillant BouilltParaObj1 = new Bouillant();
String StringTotal = BouilltParaObj1.toBuildingBlocksName(results,false, "LongEntrySignal",100);
Einstiegs-/Ausstiegssignale auswählen (LongEntrySignal, ShortEntrySignal, LongExitSignal, ShortExitSignal usw.).
package SQ.Columns.Databanks;
import SQ.Utils.Bouillant;
import com.strategyquant.lib.L;
import com.strategyquant.tradinglib.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StrategyBuildingBlocks extends DatabankColumn
{
public static final Logger Log = LoggerFactory.getLogger(StrategyBuildingBlocks.class);
public StrategyBuildingBlocks() {
super(L.tsq("Strategy Building Blocks"), DatabankColumn.Text, ValueTypes.Maximize, 0, 0, 1);
setWidth(1000);
}
@Override
public double getNumericValue(ResultsGroup results, String resultKey, byte direction, byte plType, byte sampleType) throws Exception {
return 0;
}
@Override
public String getValue(ResultsGroup results, String resultKey, byte direction, byte plType, byte sampleType) throws Exception
{
try
{
String StringTotal = "";
Bouillant BouilltParaObj1 = new Bouillant();
String String1 = BouilltParaObj1.toBuildingBlocksName(results,false, "LongEntrySignal",100);
BouilltParaObj1 = new Bouillant();
String String2 = BouilltParaObj1.toBuildingBlocksName(results,false, "ShortEntrySignal",100);
if (String1 == null || String2 == null) { return "";}
int maxLength = (String1.length() < 100)?String1.length():100;
String1 = String1.substring(0, maxLength);
maxLength = (String2.length() < 100)?String2.length():100;
String2 = String2.substring(0, maxLength);
if (!String1.equals("") && !String2.equals("")) {
StringTotal += String1 + "," + String2;
} else if (!String1.equals("")) {
StringTotal += String1;
} else if (!String2.equals("")) {
StringTotal += String2;
}
return StringTotal;
} catch(Exception e) {
Log.error("Error StrategyBuildingBlocks", e);
return "";
}
}
}
7. Namen der Bausteine (Building Blocks) in der DataBank

8. Funktion toBuildingBlocksName
Liest Variablen und Regeln aus, gibt die Namen der Bausteine (Building Blocks) zurück:
public String toBuildingBlocksName(ResultsGroup strategyRG, boolean symmetricVariables, String TradingSignalName, int breakdownLevelMax) throws Exception
{
try
{
String SignalID = "";
String strName = strategyRG.getName();
if(strName.startsWith("Filtered portfolio") || strName.startsWith("Portfolio")) { return ""; }
StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);
Element Strategie1 = strategyBase.getStrategyXml();
if (Strategie1 != null)
{
Element elParams = Strategie1.getChild("Strategy").getChild("Variables");
if (elParams != null)
{
List<Element> paramElems = elParams.getChildren();
VariableValues = new HashMap<String, String>();
VariableID = new HashMap<String, String>();
VariableType = new HashMap<String, String>();
for (int i = 0; i < paramElems.size(); i++)
{
Element elParam = paramElems.get(i);
if (elParam != null)
{
String name = XMLUtil.getNodeValue(elParam,"name");
String id = XMLUtil.getNodeValue(elParam,"id");
String value = XMLUtil.getNodeValue(elParam,"value");
String Type = XMLUtil.getNodeValue(elParam,"type");
VariableID.put(name, id);
VariableValues.put(name, value);
VariableType.put(name, Type);
if (name.equals(TradingSignalName)) { SignalID = id; }
}
}
}
elParams = Strategie1.getChild("Strategy").getChild("Rules").getChild("Events");
if (elParams != null)
{
List<Element> paramElems = elParams.getChildren();
for (int i = 0; i < paramElems.size(); i++)
{
Element elParam2 = paramElems.get(i);
if (elParam2 != null) {
String elParamKey2 = elParam2.getAttributeValue("key");
if (elParamKey2.equals("OnBarUpdate")) {
List<Element> paramElems3 = elParam2.getChildren();
for (int i2 = 0; i2 < paramElems3.size(); i2++) {
Element elParam3 = paramElems3.get(i2);
if (elParam3 != null) {
String elParamKey3 = elParam3.getAttributeValue("name");
if (elParamKey3.equals("Trading signals")) {
Element elParams4 = elParam3.getChild("signals");
List<Element> paramElems4 = elParams4.getChildren();
for (int i3 = 0; i3 < paramElems4.size(); i3++) {
Element elParam4 = paramElems4.get(i3);
if (elParam4 != null) {
String elParamKey4 = elParam4.getAttributeValue("variable");
if (elParamKey4.equals(SignalID)) {
Element elParams5 = elParam4.getChild("Item");
if (elParams5 != null) {
String key = elParams5.getAttributeValue("key");
if (!key.equals("Boolean")) {
ArrayListElemsAll = new ArrayList<Element>();
UpdateNodesValues(strategyRG, symmetricVariables, elParams5, breakdownLevelMax, 0);
AddToList(strategyRG, symmetricVariables, elParams5, breakdownLevelMax, 0);
StringBuilder sb = new StringBuilder();
if (ArrayListElemsAll.size()>=1) {
for (int i5 = 0; i5 < ArrayListElemsAll.size(); i5++) {
Element elParam6Temp = ArrayListElemsAll.get(i5);
if (elParam6Temp != null) {
String elParamKey8Temp = elParam6Temp.getAttributeValue("name");
sb.append(elParamKey8Temp);
sb.append(ParamDelimiter);
}
}
}
return sb.toString();
}
}
}
}
}
}
}
}
}
}
}
}
}
return "";
} catch (Exception e) {
Log.error("Error toBuildingBlocksName", e);
return "";
}
}
9. Rekursive Funktionen: UpdateNodesValues und AddToList
public void UpdateNodesValues(ResultsGroup strategyRG, boolean symmetricVariables, Element element, int breakdownLevelMax, int breakdownLevel) throws Exception
{
if (element != null) {
breakdownLevel++;
List<Element> element1 = element.getChildren();
for (int i = 0; i < element1.size(); i++) {
Element element11 = element1.get(i);
if (element11 != null) { UpdateNodesValues(strategyRG, symmetricVariables, element11, breakdownLevelMax, breakdownLevel); }
}
}
if (element != null) {
List<Element> listParams = element.getChildren("Param");
for (int i = 0; i < listParams.size(); i++) {
Element courant = listParams.get(i);
if (courant != null) {
String elParamKey5 = courant.getAttributeValue("key");
String elParamVariable3 = courant.getAttributeValue("variable");
if (elParamKey5.startsWith("#") && elParamVariable3=="true") {
String Temp1 = VariableValues.get(courant.getText());
if (Temp1 != null) { courant.setText(Temp1); }
}
}
}
}
}
public void AddToList(ResultsGroup strategyRG, boolean symmetricVariables, Element element, int breakdownLevelMax, int breakdownLevel) throws Exception
{
boolean Condition1 = false;
if (element != null) {
breakdownLevel++;
String elParamKey = element.getAttributeValue("key");
String categoryType = element.getAttributeValue("categoryType");
if (categoryType == null) { categoryType = ""; }
if (breakdownLevelMax < 100) { Condition1 = (elParamKey.equals("IsRising") || elParamKey.equals("IsFalling") || elParamKey.equals("IsLowerCount") || elParamKey.equals("IsGreaterCount") || elParamKey.equals("IsLower") || elParamKey.equals("IsLowerOrEqual") || elParamKey.equals("IsGreater") || elParamKey.equals("IsGreaterOrEqual") || elParamKey.equals("CrossesAbove") || elParamKey.equals("CrossesBelow") || elParamKey.startsWith("CBlock")); }
if (!Condition1) {
List<Element> element1 = element.getChildren();
for (int i = 0; i < element1.size(); i++) {
Element element11 = element1.get(i);
if (element11 != null) { AddToList(strategyRG, symmetricVariables, element11, breakdownLevelMax, breakdownLevel); }
}
}
List<Element> listParams = element.getChildren("Param");
if (listParams.size() >= 1 || Condition1) {
Element elementCopy = (Element)element.clone();
elParamKey = elementCopy.getAttributeValue("key");
listParams = elementCopy.getChildren("Param");
List<Element> listParamsBlock = element.getChildren("Block");
if (listParamsBlock.size() == 0 || Condition1) {
if ((listParams.size() == 1 && !elParamKey.equals("Number")) || !elParamKey.equals("Number")) {
if (breakdownLevel <= breakdownLevelMax) { ArrayListElemsAll.add(elementCopy); }
}
}
}
}
}
10. Fazit
Beginnen Sie mit dem Auslesen der XML-Struktur über XMLUtil.elementToString() und verwenden Sie anschließend die oben genannten Funktionen A–F. Mehr dazu finden Sie in der XMLUtil API-Dokumentation.
Referenzen: Strategieparameter anzeigen und ändern, W3Schools XML, Java JDOM Dokument parsen
Autor: Emmanuel Bouillant-Evrard, auf Finanzen spezialisierter Ingenieur mit 24 Jahren F&E-Erfahrung in den USA, Kanada und Frankreich.