Documentazione

Applicazioni

Ultimo aggiornamento il 29. 9. 2022 da Mark Fric

Utilizzo delle impostazioni di backtest nelle metriche della strategia

In questo esempio vedremo come ottenere e utilizzare le impostazioni attuali del backtest - ad esempio la dimensione dello spread - nel calcolo delle metriche del backtest (colonne della banca dati).

 

Questo è stato richiesto da un utente: la domanda esatta era come ottenere l'impostazione dello spread utilizzata nel backtest della strategia per calcolare una nuova metrica speciale per la strategia.

 

Modo 1 - nel metodo DatabankColumn getValue()

In questo esempio si può vedere come può funzionare in linea di principio. Possiamo utilizzare il metodo getLastSettings() di Gruppo di risultati che restituirà una stringa, che può essere trasformata in un elemento XML contenente la struttura delle impostazioni del backtest.

 

            String lastSettingsXml = results.getLastSettings();
            if(lastSettingsXml != null) {
                Element elSettings = XMLUtil.stringToElement(lastSettingsXml);

 

La struttura XML di elSettings esula da questo articolo; potete consultare l'XML nel file .cfx di configurazione del progetto o nel file di strategia (.sqx).

Entrambi i file sono archivi ZIP che possono essere aperti con WinZip o WinRar e si può quindi esaminare l'impostazione del progetto definita lì.

La parte che ci interessa è qui:

<Commissioni

Vogliamo recuperare lo spread e possiamo farlo in questo modo:

Elemento elData = elSettings.getChild("Data");
Element elSetups = elData.getChild("Setup");
Element elSetup = elSetups.getChild("Setup");
Element elChart = elSetup.getChild("Chart");

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

Ora che abbiamo lo spread, possiamo semplicemente visualizzarlo convertendolo in String e restituendolo come risultato del nostro metodo getValue() si veda il codice completo dello snippet qui sotto.

Si noti che stiamo utilizzando anche i risultati.valori speciali().getDouble() e .set() per "mettere in cache" il valore di spread recuperato, in modo da non dover analizzare l'XML ogni volta che viene calcolata questa metrica. In questo modo verrà analizzato solo una volta per strategia.

 

Lo svantaggio

Il problema è che stiamo utilizzando un metodo speciale DatabankColumn.getValue() e non lo standard DatabankColumn.compute().

La differenza è che il metodo getValue() sulla colonna della banca dati viene richiamato quando il valore viene visualizzato nell'interfaccia utente di SQ, DOPO che la strategia è stata inserita nella banca dati, e restituisce un testo, non un numero.

Questo tipo di colonna della banca dati non può essere utilizzata per il filtraggio e per il calcolo di altre colonne della banca dati.

 

Questo perché nelle versioni di StrategyQuantX precedenti alla Build 136 Dev 5 (rilasciata il 3 novembre 2022) le ultime impostazioni venivano salvate nella strategia nel momento in cui questa veniva aggiunta alla banca dati, dopo che tutte le sue metriche erano state calcolate.

Codice completo dello snippet:

pacchetto SQ.Columns.Databanks;

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

importare org.jdom2.Element;

public class Spread1 extends DatabankColumn {
    
    private static final String SpreadKey = "BacktestSpread";
    
    public Spread1() {
        super("Spread1", DatabankColumn.Text, ValueTypes.Minimize, 0, 0, 10000);

        setTooltip("Spread su cui è stato effettuato il test (come testo)");
        setWidth(150);
        printsSpecialValue(true);
    }
    
  //------------------------------------------------------------------------

    @Override
    public String getValue(ResultsGroup results, String resultKey, byte direction, byte plType, byte sampleType) throws Exception {
        try {
            if(results.specialValues().containsKey(SpreadKey)) {
                return results.specialValues().getDouble(SpreadKey)+"";
            }
            
            String lastSettingsXml = results.getLastSettings();
            if(lastSettingsXml != null) {
                Element elSettings = XMLUtil.stringToElement(lastSettingsXml);
                Element elData = elSettings.getChild("Data");
                Element elSetups = elData.getChild("Setups");
                Element elSetup = elSetups.getChild("Setup");
                Element elChart = elSetup.getChild("Chart");

                double spread = Double.parseDouble(elChart.getAttributeValue("spread"));
                results.specialValues().set(SpreadKey, spread);

                return Double.toString(spread);
            }

        } catch(Exception e) {
            Log.error("Ecc.", e);
        }
        
        return NOT_AVAILABLE;
    }
}

 

Modo 2 - nel metodo DatabankColumn compute()

Nota: questo metodo funziona solo con SQX Build 136 Dev 5 (rilasciato il 3 novembre 2022) e successivi.

Il principio principale è lo stesso, utilizziamo solo calcolo() per la colonna della banca dati, che viene richiamata quando vengono calcolate le metriche della strategia. Ciò significa che sarà possibile utilizzare questo valore nel filtraggio e ottenere il suo valore in altre colonne della banca dati: è sufficiente configurare la dipendenza appropriata utilizzando il metodo setDependencies().

In questo modo il valore dello spread viene recuperato dalle impostazioni dell'ultimo backtest e memorizzato nelle metriche.

 

Codice completo dello snippet:

pacchetto SQ.Columns.Databanks;

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

importare org.jdom2.Element;

public class Spread2 extends DatabankColumn {
    
  private static final String SpreadKey = "BacktestSpread";

    public Spread2() {
        super("Spread2",
          DatabankColumn.Decimal2, // formato di visualizzazione del valore
          ValueTypes.Minimize, // se il valore deve essere massimizzato / minimizzato / approssimato a un valore
          0, // valore target se è stata scelta l'approssimazione
          0, // minimo medio di questo valore
          5); // massimo medio di questo valore
        
    setWidth(80); // larghezza predefinita della colonna in pixel
    
        setTooltip("Diffusione su cui è stato effettuato il test (come numero)");
    }
  
  //------------------------------------------------------------------------

    @Override
    //public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) throws Exception {
    public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort, Result result) throws Exception {
    	
        try {
      		if(result == null) {
        	    return -1;
      		}

      		ResultsGroup results = result.getResultsGroup();
      		if(results == null) {
        	    return -2;
      		}

            if(results.specialValues().containsKey(SpreadKey)) {
            restituisce results.specialValues().getDouble(SpreadKey);
            }
            
            String lastSettingsXml = results.getLastSettings();
            if(lastSettingsXml == null) {
        	        return -3;
           	    }

            Element elSettings = XMLUtil.stringToElement(lastSettingsXml);
            Element elData = elSettings.getChild("Data");
            Element elSetups = elData.getChild("Setups");
            Element elSetup = elSetups.getChild("Setup");
            Element elChart = elSetup.getChild("Chart");
        
            double spread = Double.parseDouble(elChart.getAttributeValue("spread"));
            results.specialValues().set(SpreadKey, spread);
            
            restituire spread;

        } catch(Exception e) {
        Log.error("Ecc.", e);
        }
        
        return -4;
    }
}

 

 

 

Questo articolo è stato utile? L'articolo è stato utile L'articolo non è stato utile

Abbonarsi
Notificami
0 Commenti
Feedback in linea
Visualizza tutti i commenti