17. 5. 2022

5 4

Lesen von Strategieeinstellungen, Variablen, Regeln und Bausteinen in wenigen einfachen Schritten mit Xml

Dank eines früheren Beispiels : https://strategyquant.com/doc/programming-for-sq/viewing-and-changing-strategy-parameters-version-2/können wir eine Strategie und ihre Variablen lesen.

Dieses Codebeispiel geht noch einen Schritt weiter, indem es das XML einer Strategie, ihrer Variablen und ihrer Regeln liest.

 

1/ Überblick über eine Strategie

  • Eine Strategie Xml kann gelesen werden mit dem XMLUtil.elementToString() Funktion. 

Sie können eine benutzerdefinierte Analyse durchführen XmlStrategyToFile oder XmlStrategyToFileSym (für symmetrische Strategien), um eine beliebige Strategie aus Ihrer Datenbank auf Ihr Laufwerk in einen Ausgabepfad wie "C:\Temp"

Dann können Sie diese XML-Datei in einem beliebigen XML-Reader öffnen (z. B. https://jsonformatter.org/xml-editor zum Beispiel).

Sie können eine Vorlage auch lesen, wenn Sie Ihre Vorlage in Databank laden.

(Bitte beachten Sie das beigefügte Custom Project StrategyToXmlFile und das angehängte Xml einer Strategie Strategie 1.6.22(1)B)

 

  • A-Strategien haben Regeln und Variablen:

Wenn Sie die SQ.utils.Bouillant Erweiterungfinden Sie eine ähnliche Struktur zur Eröffnung einer Strategie:

In "toBuildingBlocksName"Funktion können wir zwei Bereiche des Codes sehen, Variablen und Regeln außerdem

 

2/ Wir verwenden XMLUtil-Klasse und JDOM Element

https://strategyquant.com/sqxapi/com/strategyquant/lib/XMLUtil.html

 

3/ Wie man Strategievariablen liest

Sobald wir das XML aus einer Strategie erhalten haben, müssen wir die Werte der Variablen abrufen. Sie können sein Boolesche, Integer, oder Doppelter.

Um sie zu erhalten, haben Sie drei Funktionen:

  • getVariableValueToBoolean
  • getVariableValueToInt
  • getVariableValueToDouble

 

Mit diesen Funktionen können wir beliebige Variablenwerte aus einer Strategie abrufen.

4/ Wir können zum Beispiel einen Stop-Loss-Wert oder einen Gewinnzielwert aus den Strategieeinstellungen abrufen und die Ergebnisse in eine Datenbank einfügen:

Mit dieser Erweiterung können Sie eine benutzerdefinierte Analyse finden "CA_StrategySettings" oder "CA_StrategySettingsSym" (für symmetrische Strategien)

Diese benutzerdefinierten Analysen rufen SQ.utils.Bouillant-Erweiterung und fordern Sie einen Stop-Loss-Wert oder einen Gewinnzielwert für ein Signal an:

@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;
}

(Wie Sie im beigefügten Custom Project sehen können: StrategySettings)

Sobald Sie den Befehl "CA_StrategySettings" individuelle Analyse oder "CA_StrategySettingsSym" individuelle Analyse , können Sie einen Stop-Loss-Wert oder einen Gewinnzielwert aus beliebigen Strategieeinstellungen auslesen und Ihre Datenbank mit den folgenden Schnipseln aktualisieren:

Hier sind der Gewinnzielwert und der Stop-Loss-Wert aus den Einstellungen der Strategie

 

 

5/ Wie man die XML-Strategie Schritt für Schritt liest

(aus unserer Funktion toBuildingBlocksName in SQ.Utils.Bouillant)

 

A/ Unser Beispiel verwendet getStrategyBase Funktion zum Abrufen der Wurzel Element einer Strategie:

 

StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);

Element Strategie1 = strategyBase.getStrategyXml();

 

B/ Aus dem Strategie1 Elementwird es immer ein bestimmtes Kind Element

 

Element elParams = Strategie1.getChild("Strategy").getChild("Variables");

oder

elParams = Strategie1.getChild("Strategie").getChild("Regeln").getChild("Ereignisse"); // zum Abschnitt "Regeln" der Strategie-Xml-Datei wechseln

 

C/ Aus dem elParams Elementerhält sie die Kinderelemente zu einer Liste der Elemente paramElems

 

List paramElems = elParams.getChildren();

 

D/ Von Liste der Elemente paramElems, können Sie erhalten. jede Element und lesen Sie die NodeValue durch die Verwendung von getNodeValue :

 

for (i = 0; i < paramElems.size(); i++)
{
    Element elParam = paramElems.get(i);

    String name = XMLUtil.getNodeValue(elParam, "name");
    String id = XMLUtil.getNodeValue(elParam, "id");

    if (name.equals(TradingSignalName)) // Wir suchen die Id des TradingSignalName, die notwendig ist, um die entsprechende Regel zu finden
    {
        SignalID = id;
    }
}
E/ Von Liste der Elemente paramElems, können Sie jede AttributWert eines Element :

 

String elParamKey = elParam.getAttributeValue("key");

 

F/ Von einem Element zu einer Zeichenkette 

Wie bei einer Strategie, wenn Sie ein Element lesen und seine Struktur betrachten wollenkönnen Sie die Funktion XMLUtil.elementToString und senden Sie sie in eine Datei.

String String1 = XMLUtil.elementToString(elParam);

 

6/ Anwendung : Wie man diese Funktion aufruft, wie man sie benutzt .

In diesem Beispiel haben wir DataBank Column Snippets, um diese Funktion anzuwenden:

Bouillant BouilltParaObj1 = new Bouillant();
String StringTotal = BouilltParaObj1.toBuildingBlocksName(results,false, "LongEntrySignal",100);

 

Diese Funktion fragt die Building Blocks mit eine Ergebnisgruppe und a TradingSignal Name. (LongEntrySignal, ShortEntrySignal, LongExitSignal, ShortExitSignal,...)

Das ist wirklich praktisch, denn Sie können ein Entry-Long- oder ein Entry-Short- oder ein Exit-Long- oder Short-Signal oder alle zusammen auswählen.

Sie können sogar einen beliebigen Signalnamen aus Ihrer Vorlage auswählen.

Hier ist der Code:

Paket SQ.Columns.Databanks;

import SQ.Utils.Bouillant;
import com.strategyquant.lib.L;
import com.strategyquant.tradinglib.*;
import com.strategyquant.tradinglib.optimization.WalkForwardMatrixResult;
import com.strategyquant.lib.ValuesMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// Erstellt in Frankreich von Emmanuel Bouillant-Evrard für die StrategyQuantX Community :)
public class StrategyBuildingBlocks extends DatabankColumn
{
    public static final Logger Log = LoggerFactory.getLogger(StrategyBuildingBlocks.class);

    public StrategyBuildingBlocks() {
        super(L.tsq("Strategiebausteine"), 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); // 100, um den Namen der Building Blocks zu haben
            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("Fehler StrategyBuildingBlocks", e);
            return ""; // "Fehler: " + e.getMessage();
        }
    }
}

 

7/ Die Bausteine Name der einzelnen Strategien in der DataBank

 

8/ Der Code der Funktion toBuildingBlocksName 

 

/**
     * Diese Funktion liest den Variablennamen, die Regeln und gibt dann einen String mit den Namen der Bausteine zurück.
     * @param strategyRG
     * @param symmetrischeVariablen
     * @param TradingSignal
     * @Rückgabe
     */
    public String toBuildingBlocksName(ResultsGroup strategyRG, boolean symmetricVariables, String TradingSignalName, int breakdownLevelMax) throws Exception
    {
        try
        {
            int i;
            String SignalID = "";
            String strName = strategyRG.getName();
            if(strName.startsWith("Gefiltertes Portfolio") || strName.startsWith("Portfolio"))
            {
                return "";
            }
            StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);
            
            Element Strategie1 = strategyBase.getStrategyXml();

            wenn (DebugMode){
            OutputPath = "C:\\Temp\\"+strName+".txt";
            FileWriter myWriter = new FileWriter(OutputPath , true); }

            if (Strategie1 != null)
            {
                //#region ********************************************************* Variables **************************************************************************************
                String test4 = "" ;
                Element elParams = Strategie1.getChild("Strategie").getChild("Variablen");
                if (elParams != null)
                {
                    List paramElems = elParams.getChildren();
                    
                    VariableValues = new HashMap();
                    VariableID = new HashMap();
                    VariableType = new HashMap();

                    for (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 Typ = XMLUtil.getNodeValue(elParam, "Typ");
                            VariableID.put(name, id);
                            VariableValues.put(name, value);
                            VariableType.put(name, Type);

                            wenn (DebugMode){
                            test4 = XMLUtil.getNodeValue(elParam, "name") + " " + XMLUtil.getNodeValue(elParam, "id");
                            myWriter.write("name + id : "+ test4 + "\r\n");
                            myWriter.write("VariableID : "+ VariableID.get(name) + "\r\n");

                            test4 = XMLUtil.getNodeValue(elParam, "name") + " " + XMLUtil.getNodeValue(elParam, "value");
                            myWriter.write("Name + Wert : "+ test4 + "\r\n");
                            myWriter.write("VariableValues : "+ VariableValues.get(name) + "\r\n");
                            
                            test4 = XMLUtil.getNodeValue(elParam, "name") + " " + XMLUtil.getNodeValue(elParam, "type");
                            myWriter.write("name + typ : "+ test4 + "\r\n");
                            myWriter.write("VariableType : "+ VariableType.get(name) + "\r\n");}

                            if (name.equals(TradingSignalName)) // Wir suchen die Id des TradingSignalName, die notwendig ist, um die entsprechende Regel zu finden
                            {
                                SignalID = id;
                            }
                        }
                    }
                    if (DebugMode){
                    myWriter.close();}
                }
                //#endregion

                //#region ********************************************************* Rules ******************************************************************************************
                elParams = Strategie1.getChild("Strategie").getChild("Regeln").getChild("Ereignisse"); // zum Abschnitt "Regeln" der Strategie-Xml-Datei wechseln
                if (elParams != null)
                {
                    List paramElems = elParams.getChildren();
                    for (i = 0; i < paramElems.size(); i++)
                    {
                        Element elParam2 = paramElems.get(i);

                        if (elParam2 != null) {
                        String elParamKey2 = elParam2.getAttributeValue("key");
                        if (elParamKey2.equals("OnBarUpdate")) // Sucht nach OnBarUpdate-Regel
                        {
                            List 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("Handelssignale")) // Suche nach Handelssignal-Regel
                                {
                                    Element elParams4 = elParam3.getChild("Signale");
                                    List 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)) // Suche nach dem angeforderten TradingSignalName anhand seiner ID : SignalID
                                        {
                                            wenn (DebugMode){
                                            myWriter = new FileWriter(OutputPath , true);
                                            String String1 = XMLUtil.elementToString(elParam4);
                                            myWriter.write(String1);
                                            myWriter.close();}

                                            Element elParams5 = elParam4.getChild("Item");
                                            
                                            wenn (DebugMode){
                                            myWriter = new FileWriter(OutputPath , true);
                                            String String1 = XMLUtil.elementToString(elParams5);
                                            myWriter.write(String1);
                                            myWriter.close();}

                                            if (elParams5 != null) {
                                            String key = elParams5.getAttributeValue("key"); // der Name
                                            if (!key.equals("Boolean"))
                                            {
                                                Element elParam5Temp = elParams5;
                                                Element elParam6Temp = elParams5;
                                                strName = strategyRG.getName();
                                                ArrayListElemsAll = new ArrayList();
                                                UpdateNodesValues(strategyRG, symmetricVariables, elParams5, breakdownLevelMax, 0);
                                                AddToList(strategyRG, symmetricVariables, elParams5, breakdownLevelMax, 0);
                                                if (!StrategyName2.equals(strName) && OutPutBlockMode)
                                                {
                                                    StrategieName2 = strName;
                                                    strategyBase = getStrategyBase(strategyRG, symmetricVariables);
                                                    Strategie1 = strategyBase.getStrategyXml();

                                                    OutputPath = "C:\\Temp\\"+strName+"B.txt";
                                                    FileWriter myWriter = new FileWriter(OutputPath , false);
                                                    String String1 = XMLUtil.elementToString(Strategie1);
                                                    myWriter.write(String1+"\r\n");
                                                    myWriter.close();
                                                }

                                                StringBuilder sb = new StringBuilder(); // Erstellen der Bausteine Name String
                                                if (ArrayListElemsAll.size()>=1)
                                                {
                                                    wenn (DebugMode){
                                                    myWriter = new FileWriter(OutputPath , true);
                                                    myWriter.write("ArrayListElemsAll.size() : "+ String.valueOf(ArrayListElemsAll.size()) + "\r\n");
                                                    String String1 = XMLUtil.elementToString(elParam5Temp);
                                                    myWriter.write(String1);
                                                    myWriter.close();}
                                                    for (int i5 = 0; i5 < ArrayListElemsAll.size(); i5++)
                                                    {
                                                        elParam6Temp = ArrayListElemsAll.get(i5);

                                                        if (elParam6Temp != null) {
                                                            String elParamKey8Temp = elParam6Temp.getAttributeValue("name"); // elParam6Temp.getAttributeValue("key");
                                                            sb.append(elParamKey8Temp);
                                                            sb.append(ParamDelimiter);
                                                        }
                                                    }
                                                }
                                                return sb.toString();
                                            }}
                                        }}
                                    }
                                }}
                            }
                        }}
                    }
                }
                //#endregion
            }

            return "";
        } catch (Exception e) {
            if (DebugMode2){
            String strName = strategyRG.getName();
            OutputPath = "C:\\Temp\\toBuildingBlocksName "+strName+".txt";
            FileWriter myWriter = new FileWriter(OutputPath , true);
            myWriter.write("Fehler : "+ strName +" "+ "\r\n");
            myWriter.write("Fehler : "+ e + "\r\n");
            StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);
            Element Strategie1 = strategyBase.getStrategyXml();
            String String1 = XMLUtil.elementToString(Strategie1);
            myWriter.write(String1 + "\r\n");
            myWriter.close();}
            Log.error("Fehler toBuildingBlocksName", e);
            return "";
        }
    }

 

9/ Um die einzelnen Bausteine zu lesen, werden in diesem Beispiel zwei rekursive Funktionen verwendet: UpdateNodesValues und AddToList.

Diese Funktionen suchen nach jedem Building Blocks, unabhängig von der XML-Struktur der Strategie.

Hier ist der Code:

   /**
    * Recursive function that read the Building Blocks Name from the Xml to update Nodes Values
    * @param strategyRG
    * @param symmetricVariables
    * @param Element
    * @param breakdownLevelMax
	 * @param breakdownLevel
    * @return
    */
   public void UpdateNodesValues(ResultsGroup strategyRG,  boolean symmetricVariables, Element element, int breakdownLevelMax, int breakdownLevel) throws Exception 
   {
       int i;
       if (element != null)
       {
           breakdownLevel = breakdownLevel + 1 ;
           List<Element> element1 = element.getChildren();
           if (element1.size() >= 1)
           {
               for (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");
           if (listParams.size() >= 1)
           {
               boolean VariableFounded = false;
               for (i = 0; i < listParams.size(); i++) 
               {
                   Element courant = listParams.get(i);
                   if (courant != null) 
                   {
                       String elParamKey5 = courant.getAttributeValue("key");					    			// the name
                       String elParamVariable3 = courant.getAttributeValue("variable");					    // the variable
                       if (elParamKey5.startsWith("#") && elParamVariable3=="true")
                       {
                           String Temp1 =  VariableValues.get(courant.getText());
                           String Temp2 =  courant.getText();
                           if (Temp1 != null)
                           {
                               courant.setText(Temp1);
                           }
                           VariableFounded = true;
                       }
                   }
               }
           }
       }
   }

   /**
    * Recursive function that read the Building Blocks Name from the Xml to the ArrayList : ArrayListElemsAll
    * @param strategyRG
    * @param symmetricVariables
    * @param Element
    * @param breakdownLevelMax
	 * @param breakdownLevel
    * @return
    */
   public void AddToList(ResultsGroup strategyRG,  boolean symmetricVariables, Element element, int breakdownLevelMax, int breakdownLevel) throws Exception 
   {
       int i;
       boolean Condition1 = false;
       if (element != null)
       {
           breakdownLevel = breakdownLevel + 1 ;

           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();
               if (element1.size() >= 1)
               {
                   for (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); 
                               }
                           }
                   }

                   if (breakdownLevel <= breakdownLevelMax && OutPutBlockMode)
                   {
                       String strName = strategyRG.getName();
                       OutputPath = "C:\\Temp\\"+strName+".txt";
                       FileWriter myWriter = new FileWriter(OutputPath , true); 
                       String String1 = XMLUtil.elementToString(elementCopy);
                       myWriter.write(String1+"\r\n");
                       myWriter.write("________________________________________________________________________________________________________________________________________________________________________________________________________________"+"\r\n");
                       myWriter.close();
                   }

           }
       }
   }

10/ Schlussfolgerung

Zusammenfassend lässt sich sagen, dass es sehr einfach ist, die Struktur der XML-Datei aus der XMLUtil.elementToString Funktion, dann verwenden wir die oben genannten Funktionen (A,B,C,D,E)

Weitere Funktionen finden wir bei Bedarf unter :

https://strategyquant.com/sqxapi/com/strategyquant/lib/XMLUtil.html

 

Quelle der Information :

https://strategyquant.com/doc/programming-for-sq/viewing-and-changing-strategy-parameters-version-2/

https://www.w3schools.com/xml/default.asp

https://strategyquant.com/sqxapi/com/strategyquant/lib/XMLUtil.html

https://www.tutorialspoint.com/java_xml/java_jdom_parse_document.htm

 

Ein nützlicher Xml-Reader :

https://jsonformatter.org/xml-editor

 

Mein Name ist Emmanuel Bouillant-Evrard, Ingenieur mit Spezialisierung auf Finanzen. Ich habe 24 Jahre lang in den USA, Kanada und Frankreich im Bereich Forschung und Entwicklung im Finanzwesen gearbeitet.

 

Abonnieren
Benachrichtigen Sie mich bei
4 Kommentare
Älteste
Neuestes Meistgewählt
Inline-Rückmeldungen
Alle Kommentare anzeigen
clonex / Ivan Hudec
7. 6. 2022 5:21 Uhr

ausgezeichnet

innggo
8. 7. 2023 12:31 Uhr

Danke, Emmanuel!

Jordanien
13. 11. 2023 7:24 Uhr

Großartige Arbeit geleistet