Documentação

Aplicações

Última atualização em 29. 9. 2022 por Mark Fric

Usando configurações de backtest em métricas de estratégia

Neste exemplo, veremos como podemos obter e usar as configurações atuais de backtest - como um exemplo de tamanho de spread - no cálculo das métricas de backtest (colunas de banco de dados).

 

Isto foi solicitado por um usuário - a pergunta exata foi como ele pode fazer com que a configuração de spread utilizada no teste de estratégia seja usada de volta para calcular uma nova métrica especial para a estratégia.

 

Modo 1 - no método DatabankColumn getValue()

Neste exemplo, você pode ver como ele pode funcionar em princípio. Podemos usar o método getLastSettings() de ResultadosGrupo que retornará uma String, que pode então ser transformada em elemento XML contendo a estrutura das configurações do backtest.

 

            String lastSettingsXml = resultados.getLastSettings();
            if(lastSettingsXml != null) {
                Elemento elSettings = XMLUtil.stringToElement(lastSettingsXml);

 

A estrutura XML da elSettings está além deste artigo, você pode rever o XML em seu arquivo .cfx de configuração de projeto ou arquivo de estratégia (.sqx).

Estes dois arquivos são arquivos ZIP que podem ser abertos usando WinZip ou WinRar e você pode então olhar para o ambiente do projeto definido ali.

A parte que nos interessa está aqui:

Queremos recuperar a propagação, e podemos fazê-lo assim:

Elemento elData = elSettings.getChild("Dados");
Elemento elSetups = elData.getChild("Setups");
Elemento elSetup = elSetups.getChild("Setups");
Elemento elChart = elSetup.getChild("Tabela");

spread duplo = Double.parseDouble(elChart.getAttributeValue("spread"));

Agora que nos espalhamos, podemos simplesmente exibi-lo, convertendo-o em String e devolvendo-o como resultado de nosso getValue() método - veja o código completo do snippet abaixo.

Note que também estamos usando resultados.valores especiais().getDouble() e .set() para "cache" o valor de spread recuperado - é para que não precisemos analisar o XML toda vez que esta métrica for computada. Desta forma, ele será analisado apenas uma vez por estratégia.

 

A desvantagem

O problema é que estamos usando um método especial Banco de dados ColumnColumn.getValue() e não o padrão DatabankColumnColumn.compute().

A diferença é que o método getValue() na coluna banco de dados é chamado quando o valor é exibido no SQ UI, APÓS a estratégia ter sido inserida no banco de dados, e ele retorna texto, não um número.

Este tipo de coluna de banco de dados não pode ser usado na filtragem e não pode ser usado no cálculo de outras colunas de banco de dados.

 

Fazemos isso desta forma porque no StrategyQuantX constrói antes do Build 136 Dev 5 (que é lançado em 3 de novembro de 2022) as últimas configurações foram salvas na estratégia no momento em que a estratégia foi adicionada ao banco de dados, depois que todas as suas métricas foram computadas.

Código completo do snippet:

pacote SQ.Colunas.Bancos de dados;

import com.strategyquant.lib.*;
import com.strategyquant.datalib.*;
import com.strategyquant.tradinglib.*;

importação org.jdom2.Element;

classe pública Spread1 estende Banco de DadosColuna {
    
    private static final String SpreadKey = "BacktestSpread";
    
    público Spread1() {
        super("Spread1", DatabankColumn.Text, ValueTypes.Minimize, 0, 0, 10000);

        setTooltip("Spread on which the test was made (as text)");
        setWidth(150);
        printsSpecialValue(true);
    }
    
  //------------------------------------------------------------------------

    @Override
    public String getValue(ResultadosResultadosResultados do grupo, resultado da StringKey, direção do byte, byte plType, byte sampleType) lança Exceção {
        tente {
            if(resultados.specialValues().containsKey(SpreadKey)) {
                return results.specialValues().getDouble(SpreadKey)+"";
            }
            
            String lastSettingsXml = resultados.getLastSettings();
            if(lastSettingsXml != null) {
                Elemento elSettings = XMLUtil.stringToElement(lastSettingsXml);
                Elemento elData = elSettings.getChild("Dados");
                Elemento elSetups = elData.getChild("Setups");
                Elemento elSetup = elSetups.getChild("Setups");
                Elemento elChart = elSetup.getChild("Tabela");

                spread duplo = Double.parseDouble(elChart.getAttributeValue("spread"));
                resultados.specialValues().set(SpreadKey, spread);

                retornar Double.toString(spread);
            }

        catch(Exceção e) } catch(Exceção e) {
            Log.error("Exc.", e);
        }
        
        retornar NOT_AVAILABLE;
    }
}

 

Caminho 2 - em DatabankColumn compute() método

Nota - este método funcionará apenas no SQX Build 136 Dev 5 (que é lançado em 3 de novembro de 2022) e posteriormente.

O princípio principal é o mesmo, nós só usamos compute() método para a coluna do banco de dados, que é chamado quando as métricas de estratégia são computadas. Isto significa que você poderá usar este valor na filtragem e poderá obter seu valor em outras colunas do banco de dados - você só precisa configurar a dependência adequada usando o método setDependencies().

Desta forma, o valor de spread é recuperado das últimas configurações de backtest, e armazenado em métricas.

 

Código completo do snippet:

pacote SQ.Colunas.Bancos de dados;

import com.strategyquant.lib.*;
import com.strategyquant.datalib.*;
import com.strategyquant.tradinglib.*;

importação org.jdom2.Element;

classe pública Spread2 estende Banco de DadosColuna {
    
  private static final String SpreadKey = "BacktestSpread";

    público Spread2() {
        super("Spread2",
          Decimal2, // formato de exibição de valores
          ValorTipos.Minimizar, // se o valor deve ser maximizado / minimizado / aproximado a um valor
          0, // valor-alvo se a aproximação foi escolhida
          0, // mínimo médio deste valor
          5); // máximo médio deste valor
        
    setWidth(80); // largura da coluna padrão em pixels
    
        setTooltip("Spread on which the test was made (as number)");
    }
  
  //------------------------------------------------------------------------

    @Override
    //public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) lança Exceção {
    Compute public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort, Result Result) lança Exceção {
    	
        tente {
      		if(resultado == nulo) {
        	    retornar -1;
      		}

      		ResultadosResultadosResultados do grupo = resultado.getResultadosGrupo();
      		if(resultados == nulo) {
        	    retorno -2;
      		}

            if(resultados.specialValues().containsKey(SpreadKey)) {
            retorno resultados.specialValues().getDouble(SpreadKey);
            }
            
            String lastSettingsXml = resultados.getLastSettings();
            if(lastSettingsXml == nulo) {
        	        retorno -3;
           	    }

            Elemento elSettings = XMLUtil.stringToElement(lastSettingsXml);
            Elemento elData = elSettings.getChild("Dados");
            Elemento elSetups = elData.getChild("Setups");
            Elemento elSetup = elSetups.getChild("Setups");
            Elemento elChart = elSetup.getChild("Tabela");
        
            spread duplo = Double.parseDouble(elChart.getAttributeValue("spread"));
            resultados.specialValues().set(SpreadKey, spread);
            
            spread de retorno;

        catch(Exceção e) } catch(Exceção e) {
        Log.error("Exc.", e);
        }
        
        retorno -4;
    }
}

 

 

 

Este artigo foi útil? O artigo foi útil O artigo não foi útil

Assine
Notificação de
0 Comentários
Feedbacks em linha
Ver todos os comentários