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
Conteúdo da página
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