Documentation

Applications

Dernière mise à jour le 29. 9. 2022 par Mark Fric

Utilisation des paramètres de backtest dans les métriques de stratégie

Dans cet exemple, nous allons voir comment nous pouvons obtenir et utiliser les paramètres actuels du backtest - par exemple la taille du spread - dans le calcul des métriques du backtest (colonnes de la banque de données).

 

Ceci a été demandé par un utilisateur - la question exacte était de savoir comment il pouvait obtenir le paramètre de spread utilisé dans le backtest de la stratégie afin de calculer une nouvelle métrique spéciale pour la stratégie.

 

Way 1 - dans la méthode getValue() de DatabankColumn

Dans cet exemple, vous pouvez voir comment cela peut fonctionner en principe. Nous pouvons utiliser la méthode getLastSettings() de Groupe de résultats qui renvoie une chaîne, qui peut ensuite être transformée en élément XML contenant la structure des paramètres du backtest.

 

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

 

La structure XML d'elSettings dépasse le cadre de cet article, vous pouvez consulter le XML dans le fichier .cfx de configuration de votre projet ou dans le fichier de stratégie (.sqx).

Ces deux fichiers sont des archives ZIP qui peuvent être ouvertes à l'aide de WinZip ou de WinRar. Vous pouvez ensuite consulter les paramètres du projet qui y sont définis.

La partie qui nous intéresse est ici :


Nous voulons récupérer l'écart, et nous pouvons le faire comme suit :

Élément elData = elSettings.getChild("Data") ;
Élément elSetups = elData.getChild("Setups") ;
Élément elSetup = elSetups.getChild("Setup") ;
Element elChart = elSetup.getChild("Chart") ;

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

Maintenant que nous avons la propagation, nous pouvons simplement l'afficher en la convertissant en chaîne de caractères et en la renvoyant comme résultat de notre fonction getValue() voir le code complet de l'extrait ci-dessous.

Notez que nous utilisons également des résultats.valeurs spéciales().getDouble() et .set() pour "mettre en cache" la valeur de l'écart récupéré - c'est pour que nous n'ayons pas à analyser le XML à chaque fois que cette métrique est calculée. De cette façon, il ne sera analysé qu'une seule fois par stratégie.

 

Les inconvénients

Le problème est que nous utilisons une méthode spéciale DatabankColumn.getValue() et non la norme DatabankColumn.compute().

La différence est que la méthode getValue() sur la colonne de la banque de données est appelée lorsque la valeur est affichée dans l'interface utilisateur de SQ, APRES que la stratégie ait été insérée dans la banque de données, et qu'elle renvoie du texte, et non un nombre.

Ce type de colonne de la banque de données ne peut pas être utilisé pour le filtrage et ne peut pas être utilisé pour le calcul d'autres colonnes de la banque de données.

 

Nous procédons ainsi car dans les versions de StrategyQuantX antérieures à la Build 136 Dev 5 (publiée le 3 novembre 2022), les derniers paramètres ont été enregistrés dans la stratégie au moment où celle-ci a été ajoutée à la banque de données, après que toutes ses mesures ont été calculées.

Code complet de l'extrait :

package 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("Écart sur lequel le test a été effectué (sous forme de texte)") ;
        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) ;
                Élément elData = elSettings.getChild("Data") ;
                Élément elSetups = elData.getChild("Setups") ;
                Élément 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("Exc.", e) ;
        }
        
        return NOT_AVAILABLE ;
    }
}

 

Méthode 2 - dans la méthode DatabankColumn compute()

Remarque - cette méthode ne fonctionnera qu'avec SQX Build 136 Dev 5 (publié le 3 novembre 2022) et les versions ultérieures.

Le principe de base est le même, nous n'utilisons que des calculer() pour la colonne de la banque de données, qui est appelée lorsque les mesures de la stratégie sont calculées. Cela signifie que vous pourrez utiliser cette valeur dans le filtrage et que vous pourrez obtenir sa valeur dans d'autres colonnes de la banque de données - il vous suffit de configurer la dépendance appropriée à l'aide de la méthode setDependencies().

De cette façon, la valeur de l'écart est récupérée à partir des derniers paramètres du backtest et stockée dans les métriques.

 

Code complet de l'extrait :

package 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 d'affichage de la valeur
          ValueTypes.Minimize, // si la valeur doit être maximisée / minimisée / approchée d'une valeur
          0, // valeur cible si l'approximation a été choisie
          0, // minimum moyen de cette valeur
          5) ; // moyenne du maximum de cette valeur
        
    setWidth(80) ; // largeur de colonne par défaut en pixels
    
        setTooltip("Largeur sur laquelle le test a été effectué (sous forme de nombre)") ;
    }
  
  //------------------------------------------------------------------------

    @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)) {
            return results.specialValues().getDouble(SpreadKey) ;
            }
            
            String lastSettingsXml = results.getLastSettings() ;
            if(lastSettingsXml == null) {
        	        return -3 ;
           	    }

            Element elSettings = XMLUtil.stringToElement(lastSettingsXml) ;
            Élément elData = elSettings.getChild("Data") ;
            Élément elSetups = elData.getChild("Setups") ;
            Élément elSetup = elSetups.getChild("Setup") ;
            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 ;
    }
}

 

 

 

Cet article a-t-il été utile ? L'article était utile L'article n'était pas utile

S'abonner
Notification pour
0 Commentaires
Commentaires en ligne
Afficher tous les commentaires