Analysez le XML des stratégies pour extraire les paramètres, les variables, les règles et les critères incluant stop loss et objectifs de profit pour une analyse personnalisée et l'automatisation.
Grâce à la documentation sur l'affichage et la modification des paramètres de stratégie, nous pouvons lire les variables de stratégie.
Cet exemple de code lit le XML, les variables et les règles de la stratégie.
1. Présentation de la stratégie
- Le XML de stratégie peut être lu avec XMLUtil.elementToString().
Exécutez Custom Analysis XmlStrategyToFile ou XmlStrategyToFileSym (stratégies symétriques) pour exporter de Databank vers le disque. Ouvrez les fichiers XML dans n’importe quel lecteur XML comme https://jsonformatter.org/xml-editor.

- Les stratégies comportent des règles et des variables.

Dans l'extension SQ.utils.Bouillant, la fonction toBuildingBlocksName affiche deux zones : Variables et Règles.

2. Classe XMLUtil et JDOM Element
Documentation de l'API XMLUtil
3. Lecture des variables de stratégie
Obtenir les valeurs des variables :
- getVariableValueToBoolean
- getVariableValueToInt
- getVariableValueToDouble
4. Exemple : extraire le Stop Loss et le Profit Target
Analyse personnalisée CA_StrategySettings ou 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. Lecture pas à pas de la stratégie XML
A. Obtenir l'élément racine :
StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);
Element Strategie1 = strategyBase.getStrategyXml();
B. Obtenir un élément enfant spécifique :
Element elParams = Strategie1.getChild("Strategy").getChild("Variables");
elParams = Strategie1.getChild("Strategy").getChild("Rules").getChild("Events");
C. Obtenir les éléments enfants dans une List :
List<Element> paramElems = elParams.getChildren();
D. Lire NodeValue :
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. Obtenir AttributeValue :
String elParamKey = elParam.getAttributeValue("key");
F. Convertir l'Element en String :
String String1 = XMLUtil.elementToString(elParam);
6. Application : appel de la fonction

Extrait de code pour colonne DataBank :
Bouillant BouilltParaObj1 = new Bouillant();
String StringTotal = BouilltParaObj1.toBuildingBlocksName(results,false, "LongEntrySignal",100);
Sélectionnez les signaux d'entrée/sortie (LongEntrySignal, ShortEntrySignal, LongExitSignal, ShortExitSignal, etc.).
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. Noms des blocs de construction (Building Blocks) dans la DataBank

8. Fonction toBuildingBlocksName
Lit les variables et les règles, renvoie les noms des blocs de construction :
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. Fonctions récursives : UpdateNodesValues et 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. Conclusion
Commencez par lire la structure XML avec XMLUtil.elementToString(), puis utilisez les fonctions A-F ci-dessus. En savoir plus dans la documentation de l'API XMLUtil.
Références : Affichage et modification des paramètres de stratégie, W3Schools XML, Java JDOM Parse Document
Auteur : Emmanuel Bouillant-Evrard, ingénieur spécialisé en finance avec 24 ans d'expérience en R&D aux États-Unis, au Canada et en France.