17. 5. 2022

5 4

Lecture des paramètres de stratégie, des variables, des règles et des blocs de construction en quelques étapes simples à l'aide de Xml

Grâce à un exemple précédent : https://strategyquant.com/doc/programming-for-sq/viewing-and-changing-strategy-parameters-version-2/Nous pouvons lire une stratégie et ses variables.

Cet exemple de code va plus loin en lisant le XML d'une stratégie, ses variables et ses règles.

 

1/ Aperçu d'une stratégie

  • Une stratégie Xml peut être lue avec le Fonction XMLUtil.elementToString(). 

Vous pouvez effectuer une analyse personnalisée XmlStrategyToFile ou XmlStrategyToFileSym (pour les stratégies symétriques) pour transformer n'importe quelle stratégie de votre banque de données à votre lecteur en un chemin de sortie comme "C:\NTemp"

Vous pouvez ensuite ouvrir ce fichier XML dans n'importe quel lecteur xml (comme https://jsonformatter.org/xml-editor par exemple).

Vous pouvez également lire un modèle, si vous chargez votre modèle dans la banque de données.

(Voir le projet personnalisé ci-joint StrategyToXmlFile et le fichier Xml d'une stratégie Stratégie 1.6.22(1)B)

 

  • Une stratégie comporte des règles et des variables :

Si vous ouvrez le Extension SQ.utils.BouillantVous y trouverez une structure similaire pour ouvrir une stratégie :

Dans "toBuildingBlocksName"Nous pouvons voir deux régions du code, Variables et règles ainsi que

 

2/ Nous utilisons Classe XMLUtil et l'élément JDOM

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

 

3/ Comment lire les variables de la stratégie

Une fois que nous avons obtenu le XML d'une stratégie, nous devons obtenir les valeurs de ses variables. Celles-ci peuvent être Booléen, Entierou Double.

Pour les obtenir, vous disposez de trois fonctions :

  • getVariableValueToBoolean
  • getVariableValueToInt
  • getVariableValueToDouble

 

À partir de ces fonctions, nous pouvons obtenir toutes les valeurs des variables d'une stratégie.

4/ Par exemple, nous pouvons obtenir une valeur de Stop loss ou une valeur de Profit Target à partir des paramètres de la stratégie et insérer les résultats dans une banque de données :

Avec cette extension, vous pouvez trouver une analyse personnalisée "CA_StrategySettings" ou "CA_StrategySettingsSym"(pour les stratégies symétriques)

Ces analyses personnalisées appellent SQ.utils.Bouillant et demander une valeur de Stop Loss ou une valeur de Profit Target à partir d'un signal :

@Override
public boolean filterStrategy(String project, String task, String databankName, ResultsGroup rg) throws Exception
{
    Bouillant BouilltParaObj1 = nouveau 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 ;
}

(Comme vous pouvez le voir dans le projet personnalisé ci-joint : StrategySettings)

Une fois que vous avez exécuté "CA_StrategySettings" analyse personnalisée ou "CA_StrategySettingsSym" analyse personnalisée , vous pouvez lire une valeur de stop loss ou une valeur d'objectif de profit à partir de n'importe quel paramètre de stratégie et mettre à jour votre banque de données avec les extraits suivants :

Voici la valeur de l'objectif de profit et la valeur de l'excédent de perte (Stop Loss Value) des paramètres de la stratégie.

 

 

5/ Comment lire la stratégie XML étape par étape

(de notre fonction toBuildingBlocksName dans SQ.Utils.Bouillant)

 

A/ Dans notre exemple, nous utilisons getStrategyBase pour obtenir le racine Élément d'une stratégie :

 

StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables) ;

Élément Strategie1 = strategyBase.getStrategyXml() ;

 

B/ A partir du Stratégie1 ÉlémentIl est en train de devenir un enfant spécifique Élément

 

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

ou

elParams = Strategie1.getChild("Strategy").getChild("Rules").getChild("Events") ; // aller à la section Règles du Xml de la stratégie

 

C/ De la elParams Élément, il obtient le éléments pour enfants à un Liste des éléments paramElems

 

List paramElems = elParams.getChildren() ;

 

D/ De Liste des éléments paramElems, vous pouvez obtenir chacun Élément et lire le Valeur du nœud en utilisant 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)) // Nous recherchons l'Id du TradingSignalName, nécessaire pour trouver la règle correspondante
    {
        SignalID = id ;
    }
}
E/ De Liste des éléments paramElems, vous pouvez obtenir chaque Valeur d'attribut d'un Élément :

 

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

 

F/ D'un élément à une chaîne 

Comme pour une stratégie, si vous voulez lire un élément et examiner sa structurevous pouvez utiliser la fonction XMLUtil.elementToString et l'envoyer dans un fichier.

String String1 = XMLUtil.elementToString(elParam) ;

 

6/ Application : Comment appeler cette fonction, comment l'utiliser .

Dans cet exemple, nous disposons d'extraits de colonnes DataBank pour appliquer cette fonction :

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

 

Cette fonction demande aux Building Blocks avec un groupe de résultats et a Nom du signal de trading. (LongEntrySignal, ShortEntrySignal, LongExitSignal, ShortExitSignal,...)

C'est très pratique car vous pouvez sélectionner un signal d'entrée long, ou un signal d'entrée court, ou un signal de sortie long ou court, ou tous ces signaux à la fois.

Vous pouvez même sélectionner n'importe quel nom de signal dans votre modèle.

Voici le code :

package 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 ;

// Créé en France par Emmanuel Bouillant-Evrard pour la communauté StrategyQuantX :)
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 {
        renvoie 0 ;
    }

    //------------------------------------------------------------------------
    
    @Override
    public String getValue(ResultsGroup results, String resultKey, byte direction, byte plType, byte sampleType) throws Exception
    {
        try
        {
            String StringTotal = "" ;
            Bouillant BouilltParaObj1 = nouveau Bouillant() ;
            String1 = BouilltParaObj1.toBuildingBlocksName(results,false, "LongEntrySignal",100) ; // 100 pour avoir le nom des Building blocks
            BouilltParaObj1 = nouveau Bouillant() ;
            String String2 = BouilltParaObj1.toBuildingBlocksName(results,false, "ShortEntrySignal",100) ;
 
            if (String1 == null || String2 == null) { return "";}

            int maxLength = (String1.length() < 100)?String1.length():100 ;
            Chaîne1 = Chaîne1.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 "" ; // "Erreur : " + e.getMessage() ;
        }
    }
}

 

7/ Les éléments constitutifs Nom de chaque stratégie dans la banque de données

 

8/ Le code de la fonction toBuildingBlocksName 

 

/**
     * Cette fonction lit le nom des variables, les règles, puis renvoie une chaîne de noms de Building Blocks.
     * @param strategyRG
     * @param symmetricVariables
     * @param TradingSignal
     * @return
     */
    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("Portefeuille filtré") || strName.startsWith("Portefeuille"))
            {
                return "" ;
            }
            StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables) ;
            
            Element Strategie1 = strategyBase.getStrategyXml() ;

            if (DebugMode){
            OutputPath = "C:\NTemp\"+nom de la chaîne+".txt" ;
            FileWriter myWriter = new FileWriter(OutputPath , true) ; }

            if (Strategie1 != null)
            {
                //#region ********************************************************* Variables **************************************************************************************
                String test4 = "" ;
                Element elParams = Strategie1.getChild("Strategy").getChild("Variables") ;
                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") ;
                            Chaîne valeur = XMLUtil.getNodeValue(elParam, "value") ;
                            String Type = XMLUtil.getNodeValue(elParam, "type") ;
                            VariableID.put(name, id) ;
                            VariableValues.put(name, value) ;
                            VariableType.put(name, Type) ;

                            if (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("nom + valeur : "+ test4 + "\r\n") ;
                            myWriter.write("VariableValues : "+ VariableValues.get(name) + "\r\n") ;
                            
                            test4 = XMLUtil.getNodeValue(elParam, "name") + " " + XMLUtil.getNodeValue(elParam, "type") ;
                            myWriter.write("nom + type : "+ test4 + "\r\n") ;
                            myWriter.write("VariableType : "+ VariableType.get(name) + "\r\n");}

                            if (name.equals(TradingSignalName)) // Nous recherchons l'Id du TradingSignalName, nécessaire pour trouver la règle correspondante
                            {
                                SignalID = id ;
                            }
                        }
                    }
                    if (DebugMode){
                    myWriter.close();}
                }
                //#endregion

                //#region ********************************************************* Rules ******************************************************************************************
                elParams = Strategie1.getChild("Strategy").getChild("Rules").getChild("Events") ; // aller à la section Rules du Xml de la stratégie
                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")) // Recherche la règle OnBarUpdate
                        {
                            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("Trading signals")) // Rechercher la règle des signaux de trading
                                {
                                    Element elParams4 = elParam3.getChild("signals") ;
                                    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)) // Recherche du TradingSignalName demandé à partir de son ID : SignalID
                                        {
                                            if (DebugMode){
                                            myWriter = new FileWriter(OutputPath , true) ;
                                            String String1 = XMLUtil.elementToString(elParam4) ;
                                            myWriter.write(String1) ;
                                            myWriter.close();}

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

                                            if (elParams5 != null) {
                                            String key = elParams5.getAttributeValue("key") ; // le nom
                                            if (!key.equals("Boolean")))
                                            {
                                                Element elParam5Temp = elParams5 ;
                                                Élément 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)
                                                {
                                                    StrategyName2 = strName ;
                                                    strategyBase = getStrategyBase(strategyRG, symmetricVariables) ;
                                                    Strategie1 = strategyBase.getStrategyXml() ;

                                                    OutputPath = "C:\NTempérature\N "+nom_de_la_stratégie+"B.txt" ;
                                                    FileWriter myWriter = new FileWriter(OutputPath , false) ;
                                                    String String1 = XMLUtil.elementToString(Strategie1) ;
                                                    myWriter.write(String1+"\r\n") ;
                                                    myWriter.close() ;
                                                }

                                                StringBuilder sb = new StringBuilder() ; // créer le nom des Building Blocks String
                                                if (ArrayListElemsAll.size()>=1))
                                                {
                                                    if (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:\NTemp\NtoBuildingBlocksName "+strName+".txt" ;
            FileWriter myWriter = new FileWriter(OutputPath , true) ;
            myWriter.write("Error : "+ strName +" "+ "\r\n") ;
            myWriter.write("Erreur : "+ e + "\N") ;
            StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables) ;
            Element Strategie1 = strategyBase.getStrategyXml() ;
            String String1 = XMLUtil.elementToString(Strategie1) ;
            myWriter.write(String1 + "\r\n") ;
            myWriter.close();}
            Log.error("Erreur toBuildingBlocksName", e) ;
            return "" ;
        }
    }

 

9/ Pour lire chaque Building Blocks, cet exemple utilise deux fonctions récursives : UpdateNodesValues et AddToList.

Ces fonctions recherchent chaque élément constitutif quelle que soit la structure XML de la stratégie.

Voici le 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/ Conclusion

En résumé, c'est simple, nous commençons généralement par lire la structure du fichier XML à partir du fichier XMLUtil.elementToString nous utilisons les fonctions ci-dessus (A,B,C,D,E).

Nous pouvons trouver d'autres fonctions si nécessaire à :

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

 

Source d'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

 

Un lecteur Xml utile :

https://jsonformatter.org/xml-editor

 

Je m'appelle Emmanuel Bouillant-Evrard, ingénieur spécialisé en finance. J'ai travaillé dans la recherche et le développement en finance aux Etats-Unis, au Canada et en France pendant 24 ans.

 

S'abonner
Notification pour
4 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
clonex / Ivan Hudec
7. 6. 2022 5:21 pm

excellent

innggo
8. 7. 2023 12:31 pm

Merci Emmanuel !

Jordanie
13. 11. 2023 7:24 am

Excellent travail