17. 5. 2022

5 4

Leggere le impostazioni della strategia, le variabili, le regole e i blocchi di costruzione in pochi semplici passi utilizzando Xml.

Grazie ad un esempio precedente : https://strategyquant.com/doc/programming-for-sq/viewing-and-changing-strategy-parameters-version-2/, possiamo leggere una strategia e le sue variabili.

Questo esempio di codice si spinge oltre, leggendo l'XML di una strategia, le sue variabili e le sue regole.

 

1/ Panoramica di una strategia

  • Una strategia Xml può essere letta con il Funzione XMLUtil.elementToString(). 

È possibile eseguire un'analisi personalizzata XmlStrategiaPerFile o XmlStrategiaPerFileSym (per le strategie simmetriche) per trasformare qualsiasi strategia dalla banca dati all'unità in un percorso di uscita come "C:\Temp"

Poi si può aprire questo file XML in qualsiasi lettore xml (come ad esempio https://jsonformatter.org/xml-editor per esempio).

È possibile leggere anche un modello, se si carica il modello in Databank.

(Si veda l'allegato Progetto personalizzato StrategiaPerXmlFile e l'Xml allegato di una strategia Strategia 1.6.22(1)B)

 

  • Le strategie A hanno regole e variabili :

Se si apre la finestra Estensione SQ.utils.Bouillant, troverete una struttura simile per aprire una strategia:

In "toBuildingBlocksName", possiamo vedere due regioni del codice, Variabili e regole anche

 

2/ Stiamo utilizzando Classe XMLUtil e l'elemento JDOM

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

 

3/ Come leggere le variabili della strategia

Una volta ottenuto l'XML da una strategia, dobbiamo ottenere i valori delle sue variabili. Esse possono essere Booleano, Intero, o Doppio.

Per ottenerli, sono disponibili tre funzioni :

  • getVariableValueToBoolean
  • getVariableValueToInt
  • getVariableValueToDouble

 

Da queste funzioni si possono ottenere i valori di qualsiasi variabile di una strategia.

4/ Ad esempio, possiamo ottenere un valore di Stop loss o un valore di Profit Target dalle impostazioni della strategia e inserire i risultati in una banca dati:

Con questa estensione, è possibile trovare un'analisi personalizzata "CA_StrategySettings" o "CA_StrategySettingsSym" (per strategie simmetriche)

Queste analisi personalizzate chiameranno SQ.utils.Bouillant e richiedere un valore di Stop Loss o un valore di Profit Target da un segnale :

@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);
    restituire true;
}

(Come si può vedere nell'allegato Progetto personalizzato : StrategySettings)

Una volta eseguito "CA_StrategySettings" analisi personalizzata o "CA_StrategySettingsSym" analisi personalizzata , è possibile leggere un valore di stop loss o un valore di obiettivo di profitto da qualsiasi impostazione della strategia e aggiornare la banca dati con i seguenti snippet:

Ecco i valori di Profit Target e Stop Loss delle impostazioni della strategia.

 

 

5/ Come leggere la strategia XML passo dopo passo

(dalla nostra funzione toBuildingBlocksName in SQ.Utils.Bouillant)

 

A/ Il nostro esempio utilizza getStrategiaBase per ottenere la funzione Elemento radice di una strategia :

 

StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);

Element Strategie1 = strategyBase.getStrategyXml();

 

B/ Dal Strategia1 Elemento, sta diventando un bambino specifico Elemento

 

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

o

elParams = Strategie1.getChild("Strategy").getChild("Rules").getChild("Events"); // andare alla sezione Regole dell'Xml di Strategia

 

C/ Dal elParam Elemento, sta ottenendo il elementi per bambini a un Elenco degli elementi paramElementi

 

List paramElems = elParams.getChildren();

 

D/ Da Elenco degli elementi paramElementi, è possibile ottenere ciascuno Elemento e leggere il Valore del nodo utilizzando getNodeValue :

 

per (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)) // Cerchiamo l'id del TradingSignalName, necessario per trovare la regola corrispondente
    {
        SignalID = id;
    }
}
E/ Da Elenco degli elementi paramElementi, è possibile ottenere ogni AttributoValore di un Elemento :

 

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

 

F/ Da un elemento a una stringa 

Come nel caso di una strategia, se si vuole leggere un elemento e osservarne la strutturaè possibile utilizzare la funzione XMLUtil.elementToString e inviarlo a un file.

String1 = XMLUtil.elementToString(elParam);

 

6/ Applicazione: come chiamare questa funzione, come utilizzarla.

In questo esempio, abbiamo gli snippet delle colonne di DataBank per applicare questa funzione:

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

 

Questa funzione chiede ai Building Blocks con un Gruppo di risultati e un TradingSignal Nome. (LongEntrySignal, ShortEntrySignal, LongExitSignal, ShortExitSignal,...)

È davvero pratico perché è possibile selezionare un segnale di entrata lunga, un segnale di entrata corta, un segnale di uscita lunga o corta o tutti insieme.

È anche possibile selezionare il nome del segnale dal modello.

Ecco il codice :

pacchetto SQ.Columns.Databanks;

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

// Creato in Francia da Emmanuel Bouillant-Evrard per la comunità 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 {
        return 0;
    }

    //------------------------------------------------------------------------
    
    @Override
    public String getValue(ResultsGroup results, String resultKey, byte direction, byte plType, byte sampleType) throws Exception
    {
        try
        {
            StringTotal = "";
            Bouillant BouilltParaObj1 = new Bouillant();
            String1 = BouilltParaObj1.toBuildingBlocksName(results,false, "LongEntrySignal",100); // 100 per avere il nome dei blocchi di edifici
            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("Errore StrategyBuildingBlocks", e);
            return ""; // "Errore: " + e.getMessage();
        }
    }
}

 

7/ Gli elementi costitutivi Nome di ogni strategia nella banca dati

 

8/ Il codice della funzione toBuildingBlocksName 

 

/**
     * Questa funzione legge il nome delle variabili, le regole e restituisce una stringa di nomi di blocchi di costruzione.
     * @param strategiaRG
     * @param variabili simmetriche
     * @param TradingSignal
     * @Ritorno
     */
    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("Portafoglio filtrato") || strName.startsWith("Portafoglio"))
            {
                return "";
            }
            StrategyBase strategyBase = getStrategyBase(strategyRG, symmetricVariables);
            
            Element Strategie1 = strategyBase.getStrategyXml();

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

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

                    per (i = 0; i < paramElems.size(); i++)
                    {
                        Elemento 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(nome, id);
                            VariableValues.put(nome, valore);
                            VariableType.put(nome, Tipo);

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

                            test4 = XMLUtil.getNodeValue(elParam, "nome") + " " + XMLUtil.getNodeValue(elParam, "valore");
                            myWriter.write("nome + valore : "+ test4 + "\r\n");
                            myWriter.write("VariableValues : "+ VariableValues.get(name) + "\r\n");
                            
                            test4 = XMLUtil.getNodeValue(elParam, "nome") + " " + XMLUtil.getNodeValue(elParam, "tipo");
                            myWriter.write("nome + tipo : "+ test4 + "\r\n");
                            myWriter.write("VariableType : " + VariableType.get(name) + "\r\n");}

                            if (name.equals(TradingSignalName)) // Cerchiamo l'Id del TradingSignalName, necessario per trovare la regola corrispondente
                            {
                                SignalID = id;
                            }
                        }
                    }
                    se (DebugMode){
                    myWriter.close();}
                }
                //#endregion

                //#region ********************************************************* Rules ******************************************************************************************
                elParams = Strategie1.getChild("Strategy").getChild("Rules").getChild("Events"); // andare alla sezione Regole dell'Xml della Strategia
                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")) // Cerca la regola OnBarUpdate
                        {
                            List paramElems3 = elParam2.getChildren();
                            for (int i2 = 0; i2 < paramElems3.size(); i2++)
                            {
                                Elemento elParam3 = paramElems3.get(i2);
                                if (elParam3 != null) {
                                String elParamKey3 = elParam3.getAttributeValue("name");
                                if (elParamKey3.equals("Segnali di trading")) // Cerca la regola dei segnali di trading
                                {
                                    Element elParams4 = elParam3.getChild("signals");
                                    List paramElems4 = elParams4.getChildren();
                                    for (int i3 = 0; i3 < paramElems4.size(); i3++)
                                    {
                                        Elemento elParam4 = paramElems4.get(i3);
                                        if (elParam4 != null) {
                                        String elParamKey4 = elParam4.getAttributeValue("variabile");
                                        if (elParamKey4.equals(SignalID)) // Cerca il TradingSignalName richiesto dal suo ID : SignalID
                                        {
                                            se (DebugMode){
                                            myWriter = new FileWriter(OutputPath , true);
                                            String String1 = XMLUtil.elementToString(elParam4);
                                            myWriter.write(String1);
                                            myWriter.close();}

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

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

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

                                                StringBuilder sb = new StringBuilder(); // crea la stringa del nome del blocco di costruzione
                                                if (ArrayListElemsAll.size()>=1)
                                                {
                                                    se (DebugMode){
                                                    myWriter = new FileWriter(OutputPath , true);
                                                    myWriter.write("ArrayListElemsAll.size() : " + String.valueOf(ArrayListElemsAll.size()) + "\r\n");
                                                    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:\\Tempi\i}aBuildingBlocksName "+strName+".txt";
            FileWriter myWriter = new FileWriter(OutputPath , true);
            myWriter.write("Errore : "+ strName +" "+ "\r\n");
            myWriter.write("Errore : "+ 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("Errore toBuildingBlocksName", e);
            restituire "";
        }
    }

 

9/ Per leggere ogni blocco, questo esempio utilizza due funzioni ricorsive: UpdateNodesValues e AddToList.

Queste funzioni cercano ogni blocco di costruzione, qualunque sia la struttura XML della strategia.

Ecco il Codice :

   /**
    * 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/ Conclusione

In sintesi, è semplice, di solito si inizia leggendo la struttura del file XML dal file XMLUtil.elementToString si utilizzano le funzioni di cui sopra (A,B,C,D,E).

Se necessario, possiamo trovare altre funzioni a :

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

 

Fonte dell'informazione :

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 utile lettore Xml :

https://jsonformatter.org/xml-editor

 

Mi chiamo Emmanuel Bouillant-Evrard, ingegnere specializzato in finanza. Ho lavorato per 24 anni nella ricerca e nello sviluppo nel settore finanziario negli Stati Uniti, in Canada e in Francia.

 

Abbonarsi
Notificami
4 Commenti
Il più vecchio
Più recente I più votati
Feedback in linea
Visualizza tutti i commenti
clonex / Ivan Hudec
7. 6. 2022 5:21 pm

eccellente

innggo
8. 7. 2023 12:31 pm

Grazie Emmanuel !

Giordania
13. 11. 2023 7:24

Ottimo lavoro svolto