Dokumentation

Anwendungen

Zuletzt aktualisiert am 29. 9. 2022 von Mark Fric

Verwendung von Backtest-Einstellungen in Strategiemetriken

In diesem Beispiel sehen wir uns an, wie wir aktuelle Backtest-Einstellungen - zum Beispiel die Größe des Spreads - bei der Berechnung von Backtest-Metriken (Datenbankspalten) abrufen und verwenden können.

 

Dies wurde von einem Benutzer angefordert - die genaue Frage war, wie er die im Strategie-Backtest verwendete Spread-Einstellung erhalten kann, um eine spezielle neue Metrik für die Strategie zu berechnen.

 

Weg 1 - in der Methode DatabankColumn getValue()

In diesem Beispiel können Sie sehen, wie es im Prinzip funktionieren kann. Wir können die Methode getLastSettings() von ErgebnisGruppe die einen String zurückgibt, der dann in ein XML-Element umgewandelt werden kann, das die Struktur der Backtest-Einstellungen enthält.

 

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

 

Die XML-Struktur von elSettings geht über diesen Artikel hinaus, Sie können die XML in Ihrer Projektkonfigurationsdatei (.cfx) oder Strategiedatei (.sqx) einsehen.

Bei beiden Dateien handelt es sich um ZIP-Archive, die mit WinZip oder WinRar geöffnet werden können, und Sie können die dort definierten Projekteinstellungen einsehen.

Der Teil, der uns interessiert, ist hier:


Wir wollen die Streuung abrufen, und das können wir so machen:

Element elData = elSettings.getChild("Daten");
Element elSetups = elData.getChild("Setups");
Element elSetup = elSetups.getChild("Einrichtung");
Element elChart = elSetup.getChild("Chart");

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

Jetzt, wo wir eine Ausbreitung haben, können wir sie einfach anzeigen, indem wir sie in eine Zeichenkette umwandeln und sie als Ergebnis unserer getValue() Methode - siehe den vollständigen Code des nachstehenden Ausschnitts.

Beachten Sie, dass wir auch Ergebnisse verwenden.specialValues().getDouble() und .set(), um den abgerufenen Streuungswert zu "cachen" - damit wir die XML-Datei nicht jedes Mal parsen müssen, wenn diese Metrik berechnet wird. Auf diese Weise wird sie nur einmal pro Strategie geparst.

 

Der Nachteil

Das Problem ist, dass wir eine spezielle Methode verwenden DatenbankSpalte.getValue() und nicht der Standard DatenbankSpalte.berechnen().

Der Unterschied besteht darin, dass die Methode getValue() für die Datenbankspalte aufgerufen wird, wenn der Wert in der SQ UI angezeigt wird, NACHDEM die Strategie in die Datenbank eingefügt wurde, und sie gibt Text und keine Zahl zurück.

Diese Art von Datenbankspalte kann nicht zum Filtern und zur Berechnung von anderen Datenbankspalten verwendet werden.

 

Wir machen das so, weil in StrategyQuantX-Builds vor Build 136 Dev 5 (das am 3. November 2022 veröffentlicht wurde) die letzten Einstellungen in der Strategie gespeichert wurden, als die Strategie zur Datenbank hinzugefügt wurde, nachdem alle Metriken berechnet worden waren.

Vollständiger Code des Snippets:

Paket SQ.Columns.Databanks;

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

import 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, auf dem der Test durchgeführt wurde (als Text)");
        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("Einrichtung");
                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("Exc.", e);
        }
        
        return NOT_AVAILABLE;
    }
}

 

Weg 2 - in der Methode DatabankColumn compute()

Hinweis: Diese Methode funktioniert nur in SQX Build 136 Dev 5 (das am 3. November 2022 veröffentlicht wird) und später.

Das Grundprinzip ist das gleiche, wir verwenden nur Berechnen() Methode für die Datenbankspalte, die aufgerufen wird, wenn die Strategiemetrik berechnet wird. Das bedeutet, dass Sie diesen Wert bei der Filterung verwenden können und dass Sie seinen Wert in anderen Datenbankspalten abrufen können - Sie müssen nur die richtige Abhängigkeit mit der Methode setDependencies() konfigurieren.

Auf diese Weise wird der Spread-Wert aus den letzten Backtest-Einstellungen abgerufen und in den Metriken gespeichert.

 

Vollständiger Code des Snippets:

Paket SQ.Columns.Databanks;

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

import org.jdom2.Element;

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

    public Spread2() {
        super("Spread2",
          DatabankColumn.Decimal2, // Format der Wertanzeige
          ValueTypes.Minimize, // ob Wert maximiert / minimiert / auf einen Wert angenähert werden soll
          0, // Zielwert, falls Annäherung gewählt wurde
          0, // durchschnittliches Minimum dieses Wertes
          5); // durchschnittliches Maximum dieses Wertes
        
    setWidth(80); // Standardspaltenbreite in Pixel
    
        setTooltip("Streuung, an der der Test durchgeführt wurde (als Zahl)");
    }
  
  //------------------------------------------------------------------------

    @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(ergebnisse == null) {
        	    return -2;
      		}

            if(results.specialValues().containsKey(SpreadKey)) {
            return 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("Einrichtung");
            Element elChart = elSetup.getChild("Chart");
        
            double spread = Double.parseDouble(elChart.getAttributeValue("spread"));
            results.specialValues().set(SpreadKey, spread);
            
            return spread;

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

 

 

 

War dieser Artikel hilfreich? Der Artikel war nützlich Der Artikel war nicht nützlich

Abonnieren
Benachrichtigen Sie mich bei
0 Kommentare
Inline-Rückmeldungen
Alle Kommentare anzeigen