Répondre

Nouvelle méthode possible pour randomiser les données avec %change au lieu de %ATR

5 réponses

bentra

Client, bbp_participant, community, sq-ultimate, 22 réponses.

Visiter le profil

il y a 3 ans #267915

Comme indiqué ici : https://roadmap.strategyquant.com/tasks/sq4_7233
et ici :  https://roadmap.strategyquant.com/tasks/sq4_7350
La méthode actuelle n'est pas parfaite et certaines stratégies peuvent exploiter l'algo de randomisation des données historiques alors que d'autres souffrent du biais de ce test. Je pense que cela est dû à la façon dont l'ATR est utilisé dans l'algo et au fait que la nouvelle position aléatoire est toujours basée sur le prochain tick de données d'origine (ce qui aura un effet supplémentaire de retour à la moyenne et un x% de l'ATR plus élevé augmentera la volatilité).

Dans cette nouvelle méthode, je randomise les % de changement de prix au lieu des % d'ATR et je permets au prix de définir un nouveau chemin de sorte que chaque tick soit basé sur le dernier tick des données randomisées (permettant au prix de s'éloigner lentement des données originales, éliminant ainsi l'effet excessif de retour à la moyenne). Cela devrait maintenir la volatilité tout en randomisant les données tant que le changement de % est raisonnable.

J'ouvre ce fil de discussion et d'essai. Il s'agit pour l'instant d'un travail en cours. Je ne suis pas très familier avec Java et j'aurais donc besoin d'un coup de main pour le code et les tests.

J'ai eu le temps de travailler dessus aujourd'hui et voici ce que j'ai pour l'instant, mais vous voudrez peut-être vérifier les nouvelles versions plus tard dans ce fil de discussion au fur et à mesure que nous progressons et que nous publions de nouvelles versions.

 

 

 

 

 

Que tous vos ajustements soient amples.


https://www.darwinex.com/darwin/SUG.4.2/

0

bentra

Client, bbp_participant, community, sq-ultimate, 22 réponses.

Visiter le profil

il y a 3 ans #267956

OK, on dirait que j'ai corrigé le bug de la première tique correctement cette fois-ci.

 

/*
 * Copyright (c) 2017-2018, StrategyQuant - Tous droits réservés.
 *
 * Le code dans ce fichier a été fait en toute bonne foi qu'il est correct et fait ce qu'il doit.
 * Si vous avez trouvé un bug dans ce code OU si vous avez une suggestion d'amélioration OU si vous voulez inclure
 * votre propre extrait de code dans notre bibliothèque standard, veuillez nous contacter à l'adresse suivante :
 * https://roadmap.strategyquant.com
 *
 * Ce code ne peut être utilisé qu'avec les produits StrategyQuant.
 * Tout propriétaire d'une licence valide (gratuite, d'essai ou commerciale) d'un produit StrategyQuant
 * est autorisé à utiliser, copier, modifier ou faire un travail dérivé de ce code sans limitations,
 * pour être utilisé dans tous les produits StrategyQuant et de partager ses modifications ou travaux dérivés
 * avec la communauté StrategyQuant.
 *
 * LE LOGICIEL EST FOURNI "TEL QUEL", SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE,
 * Y COMPRIS, MAIS SANS S'Y LIMITER, LES GARANTIES DE QUALITÉ MARCHANDE, D'ADÉQUATION À UN USAGE PARTICULIER ET DE NON-CONTREFAÇON.
 * D'ADÉQUATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS LES AUTEURS NE POURRONT ETRE TENUS RESPONSABLES DE TOUTE RECLAMATION, DE TOUT DOMMAGE
 * LES AUTEURS NE PEUVENT EN AUCUN CAS ÊTRE TENUS RESPONSABLES D'UNE QUELCONQUE RÉCLAMATION, D'UN QUELCONQUE DOMMAGE OU D'UNE QUELCONQUE RESPONSABILITÉ, QUE CE SOIT DANS LE CADRE D'UNE ACTION CONTRACTUELLE, DÉLICTUELLE OU AUTRE, DÉCOULANT,
 * LES AUTEURS NE PEUVENT EN AUCUN CAS ÊTRE TENUS RESPONSABLES DE TOUTE RÉCLAMATION, DE TOUT DOMMAGE OU DE TOUTE AUTRE RESPONSABILITÉ, QUE CE SOIT DANS LE CADRE D'UNE ACTION CONTRACTUELLE, DÉLICTUELLE OU AUTRE, DÉCOULANT DU LOGICIEL OU DE SON UTILISATION.
 *
 */
package SQ.MonteCarlo.Retest ;

import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;

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

@ClassConfig(name="Randomize history data", display="Randomize history data v2.0, with max price change #MaxChange# % of PRICE")
@Help("<b>Remarque !</b>Si vous choisissez cette option, les tests de robustesse seront testés avec la précision de l'horizon sélectionné, tandis que la stratégie originale sera testée avec la précision configurée.<br/>Cela peut entraîner des différences de résultats entre la stratégie originale et les simulations en raison d'une précision différente.<br/>Pour éviter cela, utilisez la précision Selected Timeframe dans Setings : Data")
public class RandomizeHistoryData2 extends MonteCarloRetest {
	public static final Logger Log = LoggerFactory.getLogger(RandomizeHistoryData2.class) ;
	
	//@Paramètre(name="Probability change price", defaultValue="20", minValue=1, maxValue=100, step=1)
	//public int Probability ;
	
	@Parameter(name="Max change price", defaultValue="10", minValue=1, maxValue=100, step=1)
	public int MaxChange ;
	
	private int barsProcessed = 0 ;
	private double atrValue = 0 ;
	private int atrPeriod = 14 ;
	
	private int relativeMaxChange = -1 ;
	
	
	//bendedit : nous avons besoin de variables persistantes pour pouvoir suivre le prix et lui permettre de s'éloigner des données d'origine
	private double lastbid=0 ;
	private double lastorgbid=0 ;
	private long lastticktime=0 ;
	
	
	//------------------------------------------------------------------------
	//------------------------------------------------------------------------
	//------------------------------------------------------------------------

	public RandomizeHistoryData2() {
		super(MonteCarloTestTypes.ModifyData) ;
	}
	
	//------------------------------------------------------------------------

	public void modifyData(IRandomGenerator rng, TickEvent tickEvent, double globalATR) {
		//double dblProbability = ((double) Probability/ 100.0d) ;
		
			
		//if(rng.probability(dblProbability)) {
			// bendedit : I don&#039;t see a point in probability of change, let let just always change every tick, it will be much smoother now that we turfed ATR from the equation.

			// nous devrions changer ce prix

			double ask = tickEvent.getAsk() ;
			double bid = tickEvent.getBid() ;
			double spread = ask - bid ;
			double tickorgchange=0 ;
			long currentticktime = tickEvent.getTime() ;
			
			//bendedit : vérifier si c'est le premier tick, si ce n'est pas le cas, définir le changement de tick d'origine.
			if (lastticktime <= currentticktime && lastticktime!=0) {
				//bendedit: calculate the price change from last original tick to the current tick from original data
				tickorgchange=bid-lastorgbid;
				//debug("MC price randomizer", "tickorgchange is: "+tickorgchange);
				//debug("MC price randomizer", "time is: "+currentticktime);
				//debug("MC price randomizer", "last time is: "+lastticktime);
				//debug("MC price randomizer", "EOL");
			} else { //bendedit: in case of first tick there is no change.
				lastbid=bid;
				tickorgchange=0;
			}
			
			//bendedit:set last original data bid in to variable before we change bid, we only need it to calculate the price change next time.
			lastorgbid=bid;
			
			//bendedit:store the ticktime.
			lastticktime = currentticktime;

			
			int change;
			
			if(relativeMaxChange <= 0) {
				change = rng.nextInt(MaxChange);
			} else {
				change = rng.nextInt(relativeMaxChange);
			}
			
			double dblChange = ((double) change)/ 10000.0d; 
			//bendedit: Modding every tick and allowing price to move far away from original data therefore we need to use much smaller adjustments.
			//bendedit: I chose a percent of a percent

			//bendedit: changed from using ATR to just use tick price change of original data.
			double priceChange = tickorgchange * dblChange;
			
			
			//bendedit: set the working bid relative to the last bid instead of itself
			//bid = (rng.nextInt(2) == 0 ? bid + priceChange : bid - priceChange);
			bid = (rng.nextInt(2) == 0 ? lastbid + tickorgchange + priceChange : lastbid + tickorgchange - priceChange);
			
			tickEvent.setBid(bid);
			tickEvent.setAsk(bid + spread);
			
			//bendedit:set last bid in to variable for next time.
			lastbid = bid; 

			
		//}
	}

	//------------------------------------------------------------------------
	
	public void initSettings(SettingsMap settings) {
		super.initSettings(settings);
		
		// compute relative Max Change according to chart TF and precision
		ChartSetup chartSetup = (ChartSetup) settings.get(SettingsKeys.BacktestChart);
		if(chartSetup != null) {
			int testPrecision = chartSetup.getTestPrecision();
			
			if(testPrecision == Precisions.SelectedTF) {
				// do nothing for selected TF precision
				relativeMaxChange = MaxChange;
				return;
			}
			
			// it is higher precision, set MaxChange to 1/3 of the value
			// because the change is applied o every minute bar / tick we have to lower the MaxChange 
			// so that the resulting full bar in target timeframe (for example H1) isn&#039;t changed too much
			
			//bendedit: Hopefully we don&#039;t need this adjustment anymore since we aren&#039;t using globalATR which is inflated by higher timeframes. deviding by 3 arbitrarily was suspect anyways. If we still need to adjust, I&#039;ll hopefully find a better way.
			//bendedit: Now that we are doing change % instead of atr %, we may not need any further adjustments relative to precision or TF. Turned off this equalizer for now.
			//relativeMaxChange = MaxChange / 3;
			relativeMaxChange = MaxChange;
			if(relativeMaxChange <= 0) {
				relativeMaxChange = 1;
			}
			
		}
	}	

}

 

Que tous vos ajustements soient amples.


https://www.darwinex.com/darwin/SUG.4.2/

0

bentra

Client, bbp_participant, community, sq-ultimate, 22 réponses.

Visiter le profil

il y a 3 ans #267958

Celui-ci fonctionne sur le b130

/*
 * Copyright (c) 2017-2018, StrategyQuant - Tous droits réservés.
 *
 * Le code dans ce fichier a été fait en toute bonne foi qu'il est correct et fait ce qu'il doit.
 * Si vous avez trouvé un bug dans ce code OU si vous avez une suggestion d'amélioration OU si vous voulez inclure
 * votre propre extrait de code dans notre bibliothèque standard, veuillez nous contacter à l'adresse suivante :
 * https://roadmap.strategyquant.com
 *
 * Ce code ne peut être utilisé qu'avec les produits StrategyQuant.
 * Tout propriétaire d'une licence valide (gratuite, d'essai ou commerciale) d'un produit StrategyQuant
 * est autorisé à utiliser, copier, modifier ou faire un travail dérivé de ce code sans limitations,
 * pour être utilisé dans tous les produits StrategyQuant et de partager ses modifications ou travaux dérivés
 * avec la communauté StrategyQuant.
 *
 * LE LOGICIEL EST FOURNI "TEL QUEL", SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE,
 * Y COMPRIS, MAIS SANS S'Y LIMITER, LES GARANTIES DE QUALITÉ MARCHANDE, D'ADÉQUATION À UN USAGE PARTICULIER ET DE NON-CONTREFAÇON.
 * D'ADÉQUATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS LES AUTEURS NE POURRONT ETRE TENUS RESPONSABLES DE TOUTE RECLAMATION, DE TOUT DOMMAGE
 * LES AUTEURS NE PEUVENT EN AUCUN CAS ÊTRE TENUS RESPONSABLES D'UNE QUELCONQUE RÉCLAMATION, D'UN QUELCONQUE DOMMAGE OU D'UNE QUELCONQUE RESPONSABILITÉ, QUE CE SOIT DANS LE CADRE D'UNE ACTION CONTRACTUELLE, DÉLICTUELLE OU AUTRE, DÉCOULANT,
 * LES AUTEURS NE PEUVENT EN AUCUN CAS ÊTRE TENUS RESPONSABLES DE TOUTE RÉCLAMATION, DE TOUT DOMMAGE OU DE TOUTE AUTRE RESPONSABILITÉ, QUE CE SOIT DANS LE CADRE D'UNE ACTION CONTRACTUELLE, DÉLICTUELLE OU AUTRE, DÉCOULANT DU LOGICIEL OU DE SON UTILISATION.
 *
 */
package SQ.MonteCarlo.Retest ;

import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;

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

@ClassConfig(name="Randomize history data", display="Randomize history data v2.0, with max change #MaxChange# % of TICK PRICE CHANGES")
@Help("<b>Remarque !</b>Si vous choisissez cette option, les tests de robustesse seront testés avec la précision de l'horizon sélectionné, tandis que la stratégie originale sera testée avec la précision configurée.<br/>Cela peut entraîner des différences de résultats entre la stratégie originale et les simulations en raison d'une précision différente.<br/>Pour éviter cela, utilisez la précision Selected Timeframe dans Setings : Data")
public class RandomizeHistoryData2 extends MonteCarloRetest {
	public static final Logger Log = LoggerFactory.getLogger(RandomizeHistoryData2.class) ;
	
	//@Paramètre(name="Probability change price", defaultValue="20", minValue=1, maxValue=100, step=1)
	//public int Probability ;
	
	@Parameter(name="Max change price", defaultValue="10", minValue=1, maxValue=100, step=1)
	public int MaxChange ;
	
	private int barsProcessed = 0 ;
	private double atrValue = 0 ;
	private int atrPeriod = 14 ;
	
	private int relativeMaxChange = -1 ;
	
	
	//bendedit : nous avons besoin de variables persistantes pour pouvoir suivre le prix et lui permettre de s'éloigner des données d'origine
	private double lastbid=0 ;
	private double lastorgbid=0 ;
	private long lastticktime=0 ;
	
	
	//------------------------------------------------------------------------
	//------------------------------------------------------------------------
	//------------------------------------------------------------------------

	public RandomizeHistoryData2() {
		super(MonteCarloTestTypes.ModifyData) ;
	}
	
	//------------------------------------------------------------------------

	public void modifyData(IRandomGenerator rng, TickEvent tickEvent, double globalATR) {
		//double dblProbability = ((double) Probability/ 100.0d) ;
		
			
		//if(rng.probability(dblProbability)) {
			// bendedit : I don&#039;t see a point in probability of change, let let just always change every tick, it will be much smoother now that we turfed ATR from the equation.

			// nous devrions changer ce prix

			double ask = tickEvent.getAsk() ;
			double bid = tickEvent.getBid() ;
			double spread = ask - bid ;
			double tickorgchange=0 ;
			long currentticktime = tickEvent.getTime() ;
			
			//bendedit : vérifier si c'est le premier tick, si ce n'est pas le cas, définir le changement de tick d'origine.
			if (lastticktime <= currentticktime && lastticktime!=0) {
				//bendedit: calculate the price change from last original tick to the current tick from original data
				tickorgchange=bid-lastorgbid;
				//debug("MC price randomizer", "tickorgchange is: "+tickorgchange);
				//debug("MC price randomizer", "time is: "+currentticktime);
				//debug("MC price randomizer", "last time is: "+lastticktime);
				//debug("MC price randomizer", "EOL");
			} else { //bendedit: in case of first tick there is no change.
				lastbid=bid;
				tickorgchange=0;
			}
			
			//bendedit:set last original data bid in to variable before we change bid, we only need it to calculate the price change next time.
			lastorgbid=bid;
			
			//bendedit:store the ticktime.
			lastticktime = currentticktime;

			
			int change;
			
			if(relativeMaxChange <= 0) {
				change = rng.nextInt(MaxChange);
			} else {
				change = rng.nextInt(relativeMaxChange);
			}
			
			double dblChange = ((double) change)/ 10000.0d; 
			//bendedit: Modding every tick and allowing price to move far away from original data therefore we need to use much smaller adjustments.
			//bendedit: I chose a percent of a percent

			//bendedit: changed from using ATR to just use tick price change of original data.
			double priceChange = tickorgchange * dblChange;
			
			
			//bendedit: set the working bid relative to the last bid instead of itself
			//bid = (rng.nextInt(2) == 0 ? bid + priceChange : bid - priceChange);
			bid = (rng.nextInt(2) == 0 ? lastbid + tickorgchange + priceChange : lastbid + tickorgchange - priceChange);
			
			tickEvent.setBid(bid);
			tickEvent.setAsk(bid + spread);
			
			//bendedit:set last bid in to variable for next time.
			lastbid = bid; 

			
		//}
	}

	//------------------------------------------------------------------------
	
	public void initSettings(SettingsMap settings) {
		super.initSettings(settings);
		
		// compute relative Max Change according to chart TF and precision
		ChartSetup chartSetup = (ChartSetup) settings.get(SettingsKeys.BacktestChart);
		if(chartSetup != null) {
			int testPrecision = chartSetup.getTestPrecision();
			
			if(testPrecision == Precisions.SelectedTF) {
				// do nothing for selected TF precision
				relativeMaxChange = MaxChange;
				return;
			}
			
			// it is higher precision, set MaxChange to 1/3 of the value
			// because the change is applied o every minute bar / tick we have to lower the MaxChange 
			// so that the resulting full bar in target timeframe (for example H1) isn&#039;t changed too much
			
			//bendedit: Hopefully we don&#039;t need this adjustment anymore since we aren&#039;t using globalATR which is inflated by higher timeframes. deviding by 3 arbitrarily was suspect anyways. If we still need to adjust, I&#039;ll hopefully find a better way.
			//bendedit: Now that we are doing change % instead of atr %, we may not need any further adjustments relative to precision or TF. Turned off this equalizer for now.
			//relativeMaxChange = MaxChange / 3;
			relativeMaxChange = MaxChange;
			if(relativeMaxChange <= 0) {
				relativeMaxChange = 1;
			}
			
		}
	}
	//------------------------------------------------------------------------
	
	/**
	 * Clones this MC retest object
	 *
	 * @return the clone
	 * @throws Exception the exception
	 */
	@Override
	public RandomizeHistoryData2 getClone() throws Exception {
		RandomizeHistoryData2 mc = new RandomizeHistoryData2();
		mc.MaxChange = this.MaxChange;
		
		return mc;
		
	}	

}

Que tous vos ajustements soient amples.


https://www.darwinex.com/darwin/SUG.4.2/

0

clonex / Ivan Hudec

Client, bbp_participant, communauté, sq-ultimate, contributeur, auteur, éditeur, 271 réponses.

Visiter le profil

il y a 3 ans #267976

Bonjour Bendex. Nous allons le tester sur quelques milliers de stratégies et publier les résultats ici. Merci pour cet extrait,

0

bentra

Client, bbp_participant, community, sq-ultimate, 22 réponses.

Visiter le profil

il y a 3 ans #267979

Merci beaucoup, je suis préoccupé par les différences potentielles sur les différents marchés, peut-être à cause des arrondis. Je suis également préoccupé par les effets des différents délais et précisions.

Que tous vos ajustements soient amples.


https://www.darwinex.com/darwin/SUG.4.2/

0

bentra

Client, bbp_participant, community, sq-ultimate, 22 réponses.

Visiter le profil

il y a 3 ans #268127

La nouvelle version est ici :
https://roadmap.strategyquant.com/tasks/sq4_7233
-Correction d'éventuelles erreurs d'arrondi
-réglage par défaut sur 40%

Toute aide pour tester est appréciée, merci de poster tout problème de configuration/strat dans ce ticket.

Que tous vos ajustements soient amples.


https://www.darwinex.com/darwin/SUG.4.2/

0

Affichage de 5 réponses de 1 à 5 (sur un total de 5)