17. 5. 2022

5 4

Leitura de configurações estratégicas, variáveis, regras e blocos de construção em poucas etapas fáceis usando Xml

Graças a um exemplo anterior : https://strategyquant.com/doc/programming-for-sq/viewing-and-changing-strategy-parameters-version-2/Podemos ler uma estratégia e suas variáveis.

Este exemplo de código vai um passo adiante ao ler o XML de uma estratégia, suas variáveis e suas regras.

 

1/ Visão geral de uma estratégia

  • Uma Estratégia Xml pode ser lida com o Função XMLUtil.elementToString(). 

Você pode executar uma análise personalizada XmlStrategyToFile ou XmlStrategyToFileSym (para estratégias simétricas) para transformar qualquer estratégia de seu banco de dados para sua unidade em um caminho de saída como "C:\Temp

Então você pode abrir este arquivo XML em qualquer leitor de xml (como https://jsonformatter.org/xml-editor por exemplo).

Você também pode ler um modelo, se você carregar seu modelo no Banco de Dados.

(Consulte o Projeto Personalizado em anexo StrategyToXmlFile e o anexo Xml de uma estratégia Estratégia 1.6.22(1)B)

 

  • As Estratégias têm regras e Variáveis :

Se você abrir o SQ.utils.Bouillant extensãoVocê encontrará uma estrutura semelhante para abrir uma estratégia:

Em "toBuildingBlocksName", podemos ver duas regiões do código , Variáveis e Regras também

 

2/ Estamos usando Classe XMLUtil e Elemento JDOM

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

 

3/ Como ler as variáveis da estratégia

Uma vez, obtemos o XML de uma Estratégia, temos que obter seus valores variáveis. Eles podem ser Booleano, Inteiroou Duplo.

Para obtê-los, você tem três funções :

  • getVariableValueToBoolean
  • getVariableValueToInt
  • getVariableValueToDouble

 

A partir destas funções, podemos obter quaisquer valores variáveis a partir de uma estratégia.

4/ Por exemplo, podemos obter um valor Stop Loss ou um valor Alvo de Lucro a partir das configurações da estratégia e inserir os resultados em um banco de dados:

Com esta extensão, você pode encontrar uma Análise Personalizada "CA_EstratégiaSettings" ou "CA_StrategySettingsSym" (para estratégias simétricas)

Estas análises personalizadas chamarão SQ.utils.Bouillant extensão e solicitar um valor de Stop Loss ou um valor Alvo de Lucro de um sinal :

@Override
filtro booleano públicoEstratégia (projeto String, tarefa String, banco de dados StringName, ResultsGroup rg) lança Exceção
{
    Bouillant BouilltParaObj1 = novo Bouillant();
    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;
}

(Como você pode ver no Projeto Personalizado em anexo : EstratégiaSettings)

Uma vez que você corre "CA_EstratégiaSettingsanálise personalizada ou "CA_StrategySettingsSymanálise personalizada , você pode ler um valor de stop loss ou um valor-alvo de lucro a partir de qualquer configuração estratégica e atualizar seu banco de dados com os seguintes trechos :

Aqui estão o Valor Alvo de Lucro e o Valor de Stop Loss da estratégia Configurações

 

 

5/ Como ler a estratégia XML passo a passo

(de nossa função aBuildingBlocksName em SQ.Utils.Bouillant)

 

A/ Nosso exemplo é a utilização de getStrategyBase função para obter a Elemento raiz de uma estratégia :

 

StrategyBase StrategyBase = getStrategyBase(strategyRG, symmetricVariables);

Element Strategie1 = strategyBase.getStrategyXml();

 

B/ Do Estratégia1 Elementoestá recebendo uma criança específica Elemento

 

Element elParams = Strategie1.getChild("Estratégia").getChild("Variáveis");

ou

elParams = Strategie1.getChild("Estratégia").getChild("Regras").getChild("Eventos"); // ir para a seção Regras da Estratégia Xml

 

C/ Do elParams Elementoestá recebendo o elementos infantis a um Lista de Elementos paramElems

 

Lista paramElems = elParams.getChildren();

 

D/ De Lista de Elementos paramElems, você pode obter cada Elemento e leia o NodeValue usando getNodeValue :

 

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

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

    se (name.equals(TradingSignalName)) // Nós pesquisamos o Id do TradingSignalName, necessário para encontrar a regra correspondente
    {
        SignalID = id;
    }
}
E/ De Lista de Elementos paramElems, você pode obter cada AtributoValor de um Elemento :

 

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

 

F/ De um Elemento a uma Corda 

Como para uma estratégia, se você quiser ler um Elemento e olhar para sua estruturavocê pode usar a função XMLUtil.elementToString e enviá-lo para um arquivo.

String String1 = XMLUtil.elementToString(elParam);

 

6/ Aplicação : Como chamar esta função, como utilizá-la .

Com este exemplo, temos trechos da coluna DataBank para aplicar esta função:

Bouillant BouilltParaObj1 = novo Bouillant();
String StringTotal = BouilltParaObj1.toBuildingBlocksName(resultados,false, "LongEntrySignal",100);

 

Esta função é pedir aos blocos de construção com um Grupo de Resultados e um Nome TradingSignal. (LongEntrySignal, ShortEntrySignal, LongExitSignal, ShortExitSignal,...)

É realmente prático porque você pode selecionar uma Entrada Longa, ou uma Entrada Curta, ou um sinal de Saída Longa ou Curta, ou todos eles juntos

Você pode até mesmo selecionar qualquer nome de sinal de seu modelo.

Aqui está o código :

pacote SQ.Colunas.Bancos de dados;

importação 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;
importar org.slf4j.LoggerFactory;

// Criado na França por Emmanuel Bouillant-Evrard para a comunidade StrategyQuantX :)
classe pública StrategyBuildingBlocks amplia Banco de DadosColuna
{
    logger final estático público = LoggerFactory.getLogger(StrategyBuildingBlocks.class);

    público StrategyBuildingBlocks() {
        super(L.tsq("Strategy Building Blocks"), DatabankColumn.Text, ValueTypes.Maximize, 0, 0, 1);

        setWidth(1000);
    }
    
    //------------------------------------------------------------------------

    @Override
    público duplo getNumericValue(ResultadosResultadosResultados do grupo, String resultKey, byte direction, byte plType, byte sampleType) lança Exceção {
        retornar 0;
    }

    //------------------------------------------------------------------------
    
    @Override
    public String getValue(ResultadosResultadosResultados do grupo, resultado da StringKey, direção do byte, byte plType, byte sampleType) lança Exceção
    {
        tente
        {
            String StringTotal = "";
            Bouillant BouilltParaObj1 = novo Bouillant();
            String String1 = BouilltParaObj1.toBuildingBlocksName(results,false, "LongEntrySignal",100); // 100 para ter o nome de Building blocks
            BouilltParaObj1 = novo Bouillant();
            String String2 = BouilltParaObj1.toBuildingBlocksName(resultados,falso, "ShortEntrySignal",100);
 
            if (String1 == nulo || String2 == nulo) { retornar "";}

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

            se (!String1.equals("") && !String2.equals("""))
            {
                StringTotal += String1 + "," + String2;
            }
            senão se (!String1.equals("""))
            {
                StringTotal += String1;
            }
            senão se (!String2.equals("""))
            {
                StringTotal += String2;
            }
            retornar StringTotal;

        catch(Exceção e)
        {
            Log.error("Error StrategyBuildingBlocks", e);
            retornar ""; // "Erro: " + e.getMessage();
        }
    }
}

 

7/ Os blocos de construção Nome de cada estratégia no DataBank

 

8/ O código de função toBuildingBlocksName 

 

/**
     * Esta função lê o nome das variáveis, as regras e depois retorna um nome String of Building Blocks.
     * @param strategyRG
     * @param symmetricVariables
     * @param TradingSignal
     * @retorno
     */
    Public String toBuildingBlocksName(ResultsGroup strategyRG, boolean symmetricVariables, String TradingSignalName, int breakdownLevelMax) lança Exceção
    {
        tente
        {
            int i;
            String SignalID = "";
            String stringName = strategyRG.getName();
            if(strName.startsWith("Filtered portfolio") || strName.startsWith("Portfolio"))
            {
                retornar "";
            }
            StrategyBase StrategyBase = getStrategyBase(strategyRG, symmetricVariables);
            
            Element Strategie1 = strategyBase.getStrategyXml();

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

            se (Strategie1 != nulo)
            {
                //#region ********************************************************* Variables **************************************************************************************
                String test4 = "" ;
                Element elParams = Strategie1.getChild("Estratégia").getChild("Variáveis");
                se (elParams != nulo)
                {
                    Lista paramElems = elParams.getChildren();
                    
                    Valores Variáveis = novo HashMap();
                    VariableID = novo HashMap();
                    VariableType = novo HashMap();

                    para (i = 0; i < paramElems.size(); i++)
                    {
                        Element elParam = paramElems.get(i);
                        se (elParam != nulo)
                        {
                            String name = XMLUtil.getNodeValue(elParam, "nome");
                            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");

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

                            se (name.equals(TradingSignalName)) // Nós pesquisamos o Id do TradingSignalName, necessário para encontrar a regra correspondente
                            {
                                SignalID = id;
                            }
                        }
                    }
                    se (DebugMode){
                    myWriter.close();}
                }
                //#endregion

                //#region ********************************************************* Rules ******************************************************************************************
                elParams = Strategie1.getChild("Estratégia").getChild("Regras").getChild("Eventos"); // ir para a seção Regras da Estratégia Xml
                se (elParams != nulo)
                {
                    Lista paramElems = elParams.getChildren();
                    para (i = 0; i < paramElems.size(); i++)
                    {
                        Element elParam2 = paramElems.get(i);

                        se (elParam2 != nulo) {
                        String elParamKey2 = elParam2.getAttributeValue("chave");
                        if (elParamKey2.equals("OnBarUpdate")) // Procura a regra OnBarUpdate
                        {
                            Lista paramElems3 = elParam2.getChildren();
                            para (int i2 = 0; i2 < paramElems3.size(); i2++)
                            {
                                Element elParam3 = paramElems3.get(i2);
                                se (elParam3 != nulo) {
                                String elParamKey3 = elParam3.getAttributeValue("nome");
                                if (elParamKey3.equals("Trading signals")) // Procure a regra Trading signals
                                {
                                    Element elParams4 = elParam3.getChild("sinais");
                                    Lista paramElems4 = elParams4.getChildren();
                                    for (int i3 = 0; i3 < paramElems4.size(); i3++)
                                    {
                                        Element elParam4 = paramElems4.get(i3);
                                        se (elParam4 != nulo) {
                                        String elParamKey4 = elParam4.getAttributeValue("variável");
                                        if (elParamKey4.equals(SignalID)) // Procure o TradingSignalName solicitado em seu ID : SignalID
                                        {
                                            se (DebugMode){
                                            myWriter = novo FileWriter(OutputPath , true);
                                            String String1 = XMLUtil.elementToString(elParam4);
                                            myWriter.write(String1);
                                            myWriter.close();}

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

                                            se (elParams5 != nulo) {
                                            String key = elParams5.getAttributeValue("chave"); // o nome
                                            se (!key.equals("Boolean"))
                                            {
                                                Element elParam5Temp = elParams5;
                                                Elemento elParam6Temp = elParams5;
                                                strName = strategyRG.getName();
                                                ArrayListElemsAll = novo ArrayList();
                                                UpdateNodesValues(strategyRG, symmetricVariables, elParams5, breakdownLevelMax, 0);
                                                AddToList(strategyRG, symmetricVariables, elParams5, breakdownLevelMax, 0);
                                                if (!StrategyName2.equals(strName) && OutPutBlockMode)
                                                {
                                                    StrategyName2 = strName;
                                                    strategyBase = getStrategyBase(strategyRG, symmetricVariables);
                                                    StrategyBase1 = strategyBase.getStrategyXml();

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

                                                StringBuilder sb = novo StringBuilder(); // criar os Blocos de Construção Nome String
                                                if (ArrayListElemsAll.size()>=1)
                                                {
                                                    se (DebugMode){
                                                    myWriter = novo 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);

                                                        se (elParam6Temp != nulo) {
                                                            String elParamKey8Temp = elParam6Temp.getAttributeValue("nome"); // elParam6Temp.getAttributeValue("chave");
                                                            sb.append(elParamKey8Temp);
                                                            sb.append(ParamDelimiter);
                                                        }
                                                    }
                                                }
                                                devolver alguém aoString();
                                            }}
                                        }}
                                    }
                                }}
                            }
                        }}
                    }
                }
                //#endregion
            }

            retornar "";
        captura (Exceção e) {
            se (DebugMode2){
            String stringName = strategyRG.getName();
            OutputPath = "C:\Temp paraBuildingBlocksName "+strName+".txt";
            FileWriter myWriter = novo FileWriter(OutputPath , true);
            myWriter.write("Error : "+ strName +" "+" "+ "\r");
            myWriter.write("Erro : "+ e + "\r\n");
            StrategyBase StrategyBase = getStrategyBase(strategyRG, symmetricVariables);
            Element Strategie1 = strategyBase.getStrategyBaseXml();
            String String1 = XMLUtil.elementToString(Strategie1);
            myWriter.write(String1 + "\r\n");
            myWriter.close();}
            Log.error("Error toBuildingBlocksName", e);
            retornar "";
        }
    }

 

9/ Para ler cada bloco de construção, este exemplo está usando duas funções recursivas : UpdateNodesValues e AddToList.

Estas funções estão procurando por cada bloco de construção qualquer que seja a estrutura XML da estratégia.

Aqui está o Código :

   /**
    * 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/ Conclusão

Em resumo, é simples, normalmente começamos lendo a estrutura do arquivo XML a partir do XMLUtil.elementToString então estamos usando as funções acima (A,B,C,D,E)

Podemos encontrar mais funções, se necessário, em :

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

 

Fonte de informações :

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

 

Um leitor de Xml útil :

https://jsonformatter.org/xml-editor

 

Meu nome é Emmanuel Bouillant-Evrard, Engenheiro especializado em Finanças. Trabalhei em Pesquisa e Desenvolvimento em Finanças nos EUA, Canadá e França durante 24 anos.

 

Assine
Notificação de
4 Comentários
Mais antigo
Novidades Mais Votados
Feedbacks em linha
Ver todos os comentários
clonex / Ivan Hudec
7. 6. 2022 5:21 pm

excelente

innggo
8. 7. 2023 12:31 pm

Obrigado, Emmanuel!

Jordânia
13. 11. 2023 7:24 am

Excelente trabalho