Documentação

Aplicações

Última atualização em 24. 5. 2022 por Mark Fric

Estratégia de testes de retrocesso programático, incluindo testes de robustez

Este artigo é uma continuação do artigo anterior Execução programática de testes estratégicos de retaguarda.

 

Ele mostrará como executar o backktest programático, desta vez incluindo verificações cruzadas selecionadas (testes de robustez). O princípio do backtest programático é o mesmo, não vamos explicá-lo novamente aqui.

Explicaremos apenas as coisas novas.

 

Usando processDatabank() para executar o backktest de uma estratégia

Assim como no exemplo anterior, usaremos o snippet CustomAnalysis e seu método processDatabank(). Aqui escolheremos a primeira estratégia a partir do banco de dados e faremos testes de backtest + robustez sobre ela.

O código do método processDatabank() é:

//------------------------------------------------------------------------

@Override
public ArrayList processDatabank(String project, String task, String databankName, ArrayList databankRG) lança Exceção {
    if(databankRG.size() == 0) {
        banco de dados de retornoRG;
    }

    // obter a primeira estratégia em banco de dados para realizar o reteste
    ResultsGroup strategyToRetest = databankRG.get(0);

    //------------------------------------
    // CONFIGURAÇÃO PRINCIPAL DE RETAGUARDA
    ResultadosResultado do grupoRG = runMainBacktest(strategyToRetest);

    //------------------------------------
    // VERIFICAÇÕES CRUZADAS
    runAndSaveCrossChecks(backtestResultRG, strategyToRetest.getName());

    // obter detalhes do resultado do teste de retorno
    int trades = backtestResultRG.portfolio().stats(Directions.Both, PlTypes.Money, SampleTypes.FullSample).getInt(StatsKey.NUMBER_OF_TRADES);
    double profit = backtestResultRG.portfolio().stats(Directions.both, PlTypes.Percent, SampleTypes.FullSample).getDouble(StatsKey.NET_PROFIT);

    // fazer algo com novos resultados retroativos
    // ResultsGroup agora contém o backtest principal + todas as verificações cruzadas configuradas.
    // veja em: https://strategyquant.com/doc/programming-for-sq/working-with-resultsgroup/
    // sobre como obter os resultados individuais


    // aqui nós apenas salvaremos a estratégia recém testada para o banco de dados alvo
    Banco de dados alvoDatabank = ProjectEngine.get(projeto).getDatabanks().get("Resultados");

    targetDatabank.add(backtestResultRG, true);

    banco de dados de retornoRG;
}

 

Você pode ver que temos ali dois submétodos:

  • runMainBacktest() irá executar o principal backtest da estratégia e produzir ResultadosGrupo com o resultado do backtest. Este método é o mesmo que no exemplo original e não será explicado aqui
  • runAndSaveCrosschecks() fará as verificações cruzadas especificadas e as colocará todas no mesmo ResultadosGrupo objeto como resultado separado

Em seguida, ele salvará este novo resultado em um banco de dados alvo.

 

 

Configuração de checagens cruzadas

Os crosschecks no SQX são implementados como plugins, e cada crosscheck tem um método runTest() que será executada com uma verificação cruzada da estratégia.

Assim, quando tivermos as verificações cruzadas configuradas, podemos simplesmente chamar este método em cada verificação cruzada que quisermos realizar.

A criação / configuração do crosscheck é o desafio aqui, ele é feito em um submétodo configureCrosschecks() - este método retorna uma série de verificações cruzadas, que são então executadas uma a uma.

 

Há mais maneiras de criar configurações de crosscheck, mas a mais fácil tanto para programação como para uso normal é simplesmente deixá-las serem criadas a partir do formato XML que a SQX está armazenando. Este é o método que estamos usando aqui.

 

O código de configureCrosschecks() método e alguns submétodos:

   //------------------------------------------------------------------------

   private ArrayList configureCrosschecks() lança Exceção {
       ArrayList crossChecks = novo ArrayList();

       crossChecks.add( createFromXml("c:\\\RetestWithHigherPrecision.xml") );
       crossChecks.add( createFromXml("c::\MonteCarloManipulation.xml") );
       crossChecks.add( createFromXml("c:\\\MonteCarloRetest.xml") ); crossChecks.add( createFromXml("c:\MonteCarloRetest.xml") );

       Retornar crossChecks;
   }

   //------------------------------------------------------------------------

   private ICrossCheck createFromXml(String xmlFile) throws Exception {
       Element elXml = XMLUtil.fileToXmlElement(novo arquivo(xmlFile));

       String ccName = elXml.getName();

       ICrossCheck crossCheck = getCrossCheckPlugin(ccName);
       if(crossCheck != nulo) {
           crossCheck.readSettings(elXml, null);
       }
       senão {
           lançar nova Exceção ("Não é possível encontrar o plugin de verificação cruzada '" + ccName + "'");
       }

       retorno crossCheck;
   }

   //------------------------------------------------------------------------

   private ICrossCheck getCrossCheckPlugin(String name) {
       ArrayList plugins = SQPluginManager.getPlugins(ICrossCheck.class);

       for(int i=0; i<plugins.size(); i++) {
           if(plugins.get(i).getSettingName().equalals(name)) {
               retornar plugins.get(i).clone(null);
           }
       }

       devolução nula;
   }

 

Você pode ver que a configuração do crosscheck é criada pelo método createFromXml() que recebe um arquivo XML como parâmetro. Este arquivo XML é a definição da verificação cruzada dada.

O método obterá primeiro um clone do plugin para a respectiva verificação cruzada, chamando getCrossCheckPlugin(pluginName)e então ele simplesmente chama readSettings(xml) sobre o objeto para inicializá-lo com configurações de XML.

Depois disso, o objeto de configuração do crosscheck está pronto para ser executado.

 

Em nosso exemplo, estamos criando três crosschecks:

  • Reteste com um prazo mais longo
  • Manipulação de Monte Carlo com alguns métodos selecionados
  • Monte Carlo retestando com métodos selecionados

Temos um arquivo XML separado com configuração para cada um deles.

 

Como preparar o arquivo de configuração XML crosscheck

A abordagem mais fácil é usar o SQX UI para configurar as configurações exatas na verificação cruzada que você deseja usar no projeto Builder ou Retester.

Em seguida, salvar todo o projeto Builder/Retester em um arquivo .cfx. Este arquivo como uma extensão .cfx, mas é um arquivo ZIP padrão que você pode abrir no programa WinZip ou WinRar.

Dentro do arquivo você encontrará config.xml - este é o documento XML que contém as configurações para todo o projeto.

Encontre aqui a seção <CrossChecks> e daí copiar e colar o XML de verificação cruzada que você deseja em um arquivo separado que você carregará mais tarde em nosso snippet de análise personalizada.

 

Um exemplo de arquivo RetestWithHigherPrecision.xml:

2
    3
  
  
    
      
        
          
        
        =" />
        
          
        
      
      
        
          
        
        =" />
        
          
        
      
      
        
          
        
        <Valor do comparador="

 

Um exemplo do arquivo MonteCarloManipulation.xml:

resampling
        
      
      
        
          10
        
      
    
    10
    false

 

Um exemplo do arquivo MonteCarloRetest.xml:

20
          10
          20
          10
          true
        
      
      
        
          40
        
      
      
        
          0.0
          10.0
        
      
      
        
          0.0
          5.0
        
      
      
        
          1.0
          5.0
        
      
      
        
          100
        
      
      
        
          10
          20
          true
        
      
      
        
          10
          20
          true
          true
          false
          true
          true
          true
          true
          true
          false
          false
          true
        
      
    
    10
    false
    -1

 

 

 

Execução de verificações cruzadas

Quando tivermos os objetos de configuração do crosscheck prontos, executaremos os crosschecks simplesmente chamando seus runTest() método.

Código:

private void runAndSaveCrossChecks(ResultsGroup mainResultado principal do grupo, String strategyName) lança Exceção {
    ArrayList crossChecks = configureCrosschecks();

    StopPauseEngine stopPauseEngine = novo StopPauseEngine();

    for(int i=0; i<crossChecks.size(); i++) {

        ICrossCheck crossCheck = crossChecks.get(i);
        crossCheck.setStopPauseEngine(stopPauseEngine);

        tente {
            Log.info(String.format("Running cross check %s for %s...", crossCheck.getName(), strategyName));

            boolean ccResult = crossCheck.runTest(mainResult, i, globalATR, null, true, null, strategyName);

            if(!ccResultado) {
                // descomentar se você quiser parar de executar outras verificações cruzadas se uma delas não passar
                // caso contrário, todas as verificações cruzadas são feitas na estratégia
                //retorno;
            }

        catch(Exceção e) } catch(Exceção e) {
            Log.error("Exceção de verificação cruzada: "+e.getMessage(), e);
        }
    }
}

 

Executando este trecho de análise personalizada

Quando você compila e executa este trecho, o resultado é o seguinte. Ele pega a primeira estratégia do banco de dados, faz o backtest do homem e as 3 verificações cruzadas que configuramos nele e o salva como um novo resultado no banco de dados.

Você pode ver que o novo resultado contém também os resultados de Monte Carlo

 

 

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

Assine
Notificação de
1 Comentário
Mais antigo
Novidades Mais Votados
Feedbacks em linha
Ver todos os comentários
Emmanuel
25. 5. 2022 12:37 pm

Excelente !!!! isto será muito útil
Obrigado

Postos relacionados