Antwort

Möglicher neuer Weg zur Randomisierung von Daten mit %change anstelle von %ATR

5 Antworten

bentra

Kunde, bbp_participant, community, sq-ultimate, 22 Antworten.

Profil besuchen

vor 3 Jahren #267915

Wie hier: https://roadmap.strategyquant.com/tasks/sq4_7233
und hier:  https://roadmap.strategyquant.com/tasks/sq4_7350
Die derzeitige Methode ist nicht perfekt, und einige Strategien können den Algo für die Zufallsdaten ausnutzen, während andere unter der Verzerrung dieses Tests leiden. Ich glaube, das liegt an der Art und Weise, wie ATR im Algo verwendet wird, kombiniert mit der Tatsache, dass die neue randomisierte Position immer auf dem nächsten ursprünglichen Datentick basiert (was einen zusätzlichen Revert-to-the-mean-Effekt hat und höhere x% von ATR die Volatilität erhöht).

In dieser neuen Methode randomisiere ich die % der Preisänderung anstelle von % der ATR und lasse den Preis einen neuen Weg einschlagen, so dass jeder Tick auf dem letzten Tick der randomisierten Daten basiert (wodurch sich der Preis langsam weit von den ursprünglichen Daten entfernt und der übermäßige Effekt der Rückkehr zum Mittelwert eliminiert wird). Dadurch sollte die Volatilität bei der Randomisierung der Daten erhalten bleiben, solange die %-Änderung angemessen ist.

Ich eröffne diesen Thread für die Diskussion und das Testen. Es ist eine Arbeit in progress zu dieser Zeit. Ich bin ziemlich unvertraut mit Java, so könnte ich eine Hand mit dem Code und mit dem Testen verwenden.

Ich hatte heute Zeit, daran zu arbeiten, und hier ist das, was ich bis jetzt habe, aber ihr solltet vielleicht später in diesem Thread nach neuen Versionen suchen, wenn wir Fortschritte machen und neue Versionen veröffentlichen.

 

 

 

 

 

Mögen alle deine Anzüge locker sitzen.


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

0

bentra

Kunde, bbp_participant, community, sq-ultimate, 22 Antworten.

Profil besuchen

vor 3 Jahren #267956

OK, es sieht so aus, als hätte ich den Fehler mit dem ersten Tick diesmal richtig behoben

 

/*
 * Copyright (c) 2017-2018, StrategyQuant - Alle Rechte vorbehalten.
 *
 * Der Code in dieser Datei wurde in dem guten Glauben erstellt, dass er korrekt ist und das tut, was er soll.
 * Wenn Sie einen Fehler in diesem Code gefunden haben ODER Sie einen Verbesserungsvorschlag haben ODER Sie möchten
 * Ihren eigenen Codeschnipsel in unsere Standardbibliothek aufnehmen möchten, kontaktieren Sie uns bitte unter:
 * https://roadmap.strategyquant.com
 *
 * Dieser Code kann nur innerhalb von StrategyQuant-Produkten verwendet werden.
 * Jeder Besitzer einer gültigen (kostenlosen, Test- oder kommerziellen) Lizenz für ein StrategyQuant-Produkt
 * darf diesen Code ohne Einschränkungen frei verwenden, kopieren, modifizieren oder davon abgeleitete Arbeiten erstellen,
 * in allen StrategyQuant-Produkten zu verwenden und seine Änderungen oder abgeleiteten Arbeiten
 * mit der StrategyQuant-Gemeinschaft zu teilen.
 *
 * DIE SOFTWARE WIRD OHNE MÄNGELGEWÄHR BEREITGESTELLT, OHNE JEGLICHE AUSDRÜCKLICHE ODER STILLSCHWEIGENDE GARANTIE,
 * EINSCHLIESSLICH, ABER NICHT BESCHRÄNKT AUF DIE GARANTIEN DER MARKTGÄNGIGKEIT, DER EIGNUNG FÜR EINEN BESTIMMTEN
 * ZWECK UND NICHTVERLETZUNG VON RECHTEN DRITTER. IN KEINEM FALL SIND DIE AUTOREN HAFTBAR FÜR JEGLICHE ANSPRÜCHE, SCHÄDEN
 * ODER ANDERE HAFTUNG, OB IN EINER KLAGE AUS VERTRAG, UNERLAUBTER HANDLUNG ODER ANDERWEITIG, DIE AUS,
 * AUS ODER IN VERBINDUNG MIT DER SOFTWARE ODER DER NUTZUNG ODER DEM SONSTIGEN UMGANG MIT DER SOFTWARE.
 *
 */
Paket 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>Achtung!</b>Wenn Sie diese Option wählen, werden die Robustheitstests mit der Genauigkeit des ausgewählten Zeitrahmens getestet, während die ursprüngliche Strategie mit der konfigurierten Genauigkeit getestet wird.<br/>Dies könnte aufgrund der unterschiedlichen Genauigkeit zu unterschiedlichen Ergebnissen zwischen der ursprünglichen Strategie und den Simulationen führen.<br/>Um dies zu vermeiden, verwenden Sie die Präzision von Selected Timeframe in Setings : Daten.")
public class RandomizeHistoryData2 extends MonteCarloRetest {
	public static final Logger Log = LoggerFactory.getLogger(RandomizeHistoryData2.class);
	
	//@Parameter(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: wir brauchen einige persistente Variablen, damit wir den Preis verfolgen können und er sich von den ursprünglichen Daten entfernen kann
	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: Ich don&#039;t sehen einen Punkt in der Wahrscheinlichkeit der Veränderung, lassen Sie einfach immer ändern jeden Tick, wird es viel glatter, jetzt, dass wir turfed ATR aus der Gleichung.

			// wir sollten diesen Preis ändern

			double ask = tickEvent.getAsk();
			double bid = tickEvent.getBid();
			double spread = ask - bid;
			double tickorgchange=0;
			long currentticktime = tickEvent.getTime();
			
			//bendedit: prüfen, ob erster Tick, wenn nicht, dann ursprünglichen Tickwechsel setzen.
			wenn (letzteTickzeit <= 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;
			}
			
		}
	}	

}

 

Mögen alle deine Anzüge locker sitzen.


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

0

bentra

Kunde, bbp_participant, community, sq-ultimate, 22 Antworten.

Profil besuchen

vor 3 Jahren #267958

Dieser funktioniert auf der b130

/*
 * Copyright (c) 2017-2018, StrategyQuant - Alle Rechte vorbehalten.
 *
 * Der Code in dieser Datei wurde in dem guten Glauben erstellt, dass er korrekt ist und das tut, was er soll.
 * Wenn Sie einen Fehler in diesem Code gefunden haben ODER Sie einen Verbesserungsvorschlag haben ODER Sie möchten
 * Ihren eigenen Codeschnipsel in unsere Standardbibliothek aufnehmen möchten, kontaktieren Sie uns bitte unter:
 * https://roadmap.strategyquant.com
 *
 * Dieser Code kann nur innerhalb von StrategyQuant-Produkten verwendet werden.
 * Jeder Besitzer einer gültigen (kostenlosen, Test- oder kommerziellen) Lizenz für ein StrategyQuant-Produkt
 * darf diesen Code ohne Einschränkungen frei verwenden, kopieren, modifizieren oder davon abgeleitete Arbeiten erstellen,
 * in allen StrategyQuant-Produkten zu verwenden und seine Änderungen oder abgeleiteten Arbeiten
 * mit der StrategyQuant-Gemeinschaft zu teilen.
 *
 * DIE SOFTWARE WIRD OHNE MÄNGELGEWÄHR BEREITGESTELLT, OHNE JEGLICHE AUSDRÜCKLICHE ODER STILLSCHWEIGENDE GARANTIE,
 * EINSCHLIESSLICH, ABER NICHT BESCHRÄNKT AUF DIE GARANTIEN DER MARKTGÄNGIGKEIT, DER EIGNUNG FÜR EINEN BESTIMMTEN
 * ZWECK UND NICHTVERLETZUNG VON RECHTEN DRITTER. IN KEINEM FALL SIND DIE AUTOREN HAFTBAR FÜR JEGLICHE ANSPRÜCHE, SCHÄDEN
 * ODER ANDERE HAFTUNG, OB IN EINER KLAGE AUS VERTRAG, UNERLAUBTER HANDLUNG ODER ANDERWEITIG, DIE AUS,
 * AUS ODER IN VERBINDUNG MIT DER SOFTWARE ODER DER NUTZUNG ODER DEM SONSTIGEN UMGANG MIT DER SOFTWARE.
 *
 */
Paket 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>Achtung!</b>Wenn Sie diese Option wählen, werden die Robustheitstests mit der Genauigkeit des ausgewählten Zeitrahmens getestet, während die ursprüngliche Strategie mit der konfigurierten Genauigkeit getestet wird.<br/>Dies könnte aufgrund der unterschiedlichen Genauigkeit zu unterschiedlichen Ergebnissen zwischen der ursprünglichen Strategie und den Simulationen führen.<br/>Um dies zu vermeiden, verwenden Sie die Präzision von Selected Timeframe in Setings : Daten.")
public class RandomizeHistoryData2 extends MonteCarloRetest {
	public static final Logger Log = LoggerFactory.getLogger(RandomizeHistoryData2.class);
	
	//@Parameter(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: wir brauchen einige persistente Variablen, damit wir den Preis verfolgen können und er sich von den ursprünglichen Daten entfernen kann
	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: Ich don&#039;t sehen einen Punkt in der Wahrscheinlichkeit der Veränderung, lassen Sie einfach immer ändern jeden Tick, wird es viel glatter, jetzt, dass wir turfed ATR aus der Gleichung.

			// wir sollten diesen Preis ändern

			double ask = tickEvent.getAsk();
			double bid = tickEvent.getBid();
			double spread = ask - bid;
			double tickorgchange=0;
			long currentticktime = tickEvent.getTime();
			
			//bendedit: prüfen, ob erster Tick, wenn nicht, dann ursprünglichen Tickwechsel setzen.
			wenn (letzteTickzeit <= 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;
		
	}	

}

Mögen alle deine Anzüge locker sitzen.


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

0

clonex / Ivan Hudec

Kunde, bbp_participant, community, sq-ultimate, Mitwirkender, Autor, Herausgeber, 271 Antworten.

Profil besuchen

vor 3 Jahren #267976

Hallo Bendex. Wir werden es mit einigen tausend Strategien testen und die Ergebnisse hier veröffentlichen. Danke für dieses Snippet,

0

bentra

Kunde, bbp_participant, community, sq-ultimate, 22 Antworten.

Profil besuchen

vor 3 Jahren #267979

Vielen Dank, ich bin besorgt über mögliche Differenzen auf verschiedenen Märkten, die möglicherweise auf Rundungen zurückzuführen sind. Auch die Auswirkungen der verschiedenen Zeitrahmen und Genauigkeiten.

Mögen alle deine Anzüge locker sitzen.


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

0

bentra

Kunde, bbp_participant, community, sq-ultimate, 22 Antworten.

Profil besuchen

vor 3 Jahren #268127

Die neue Version ist hier:
https://roadmap.strategyquant.com/tasks/sq4_7233
-Eventuelle Rundungsfehler behoben
-Standardeinstellung auf 40%

Jede Hilfe beim Testen ist willkommen, bitte senden Sie alle problematischen Konfigurationen/Strats an dieses Ticket.

Mögen alle deine Anzüge locker sitzen.


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

0

Ansicht von 5 Antworten - 1 bis 5 (von insgesamt 5)