[Quantproject-developers] QuantProject/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOs
Brought to you by:
glauco_1
Update of /cvsroot/quantproject/QuantProject/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOscillators/PortfolioValueOscillator In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv7110/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOscillators/PortfolioValueOscillator Modified Files: EndOfDayTimerHandlerPVO.cs GenomeManagerPVO.cs RunPVO.cs Log Message: Several changes applied to the classes implementing the Portfolio Value Oscillator strategy (the most important one relates to the use of ReturnsManager) Index: GenomeManagerPVO.cs =================================================================== RCS file: /cvsroot/quantproject/QuantProject/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOscillators/PortfolioValueOscillator/GenomeManagerPVO.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** GenomeManagerPVO.cs 3 Jan 2007 23:20:14 -0000 1.3 --- GenomeManagerPVO.cs 14 Jan 2008 23:07:02 -0000 1.4 *************** *** 24,27 **** --- 24,28 ---- using System.Data; using System.Collections; + using QuantProject.ADT; using QuantProject.ADT.Statistics; *************** *** 29,32 **** --- 30,39 ---- using QuantProject.Data; using QuantProject.Data.DataTables; + using QuantProject.Business.DataProviders; + using QuantProject.Business.Timing; + using QuantProject.Business.Strategies; + using QuantProject.Business.Strategies.ReturnsManagement; + using QuantProject.Business.Strategies.ReturnsManagement.Time; + using QuantProject.Business.Strategies.TickersRelationships; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; *************** *** 41,60 **** public class GenomeManagerPVO : GenomeManagerForEfficientPortfolio { ! private int minLevelForOversoldThreshold; ! private int maxLevelForOversoldThreshold; ! private int minLevelForOverboughtThreshold; ! private int maxLevelForOverboughtThreshold; ! private int divisorForThresholdComputation; ! private bool symmetricalThresholds = false; ! private bool overboughtMoreThanOversoldForFixedPortfolio = false; ! private int numOfGenesDedicatedToThresholds; ! private double currentOversoldThreshold = 0.0; ! private double currentOverboughtThreshold = 0.0; ! private int numDaysForOscillatingPeriod; ! ! private double[] portfolioValues;//the values for each unit, invested ! //at the beginning of the optimization period, ! //throughout the period itself ! private void genomeManagerPVO_checkParametersForThresholdsComputation() { --- 48,66 ---- public class GenomeManagerPVO : GenomeManagerForEfficientPortfolio { ! protected int minLevelForOversoldThreshold; ! protected int maxLevelForOversoldThreshold; ! protected int minLevelForOverboughtThreshold; ! protected int maxLevelForOverboughtThreshold; ! protected int divisorForThresholdComputation; ! protected bool symmetricalThresholds = false; ! protected bool overboughtMoreThanOversoldForFixedPortfolio = false; ! protected int numOfGenesDedicatedToThresholds; ! protected double currentOversoldThreshold = 0.0; ! protected double currentOverboughtThreshold = 0.0; ! protected int numDaysForOscillatingPeriod; ! protected ReturnsManager returnsManager; ! protected CorrelationProvider correlationProvider;//used for experimental ! //tests using 2 tickers and PearsonCorrelationCoefficient as fitness ! private void genomeManagerPVO_checkParametersForThresholdsComputation() { *************** *** 86,90 **** bool symmetricalThresholds, bool overboughtMoreThanOversoldForFixedPortfolio, ! PortfolioType inSamplePortfolioType) : base(setOfInitialTickers, --- 92,97 ---- bool symmetricalThresholds, bool overboughtMoreThanOversoldForFixedPortfolio, ! PortfolioType inSamplePortfolioType, ! string benchmark) : base(setOfInitialTickers, *************** *** 93,97 **** numberOfTickersInPortfolio, 0.0, ! inSamplePortfolioType) --- 100,105 ---- numberOfTickersInPortfolio, 0.0, ! inSamplePortfolioType, ! benchmark) *************** *** 110,114 **** numOfGenesDedicatedToThresholds = 2; this.genomeManagerPVO_checkParametersForThresholdsComputation(); ! this.retrieveData(); } --- 118,140 ---- numOfGenesDedicatedToThresholds = 2; this.genomeManagerPVO_checkParametersForThresholdsComputation(); ! this.setReturnsManager(firstQuoteDate , lastQuoteDate); ! } ! ! protected virtual void setReturnsManager(DateTime firstQuoteDate, ! DateTime lastQuoteDate) ! { ! EndOfDayDateTime firstEndOfDayDateTime = ! new EndOfDayDateTime(firstQuoteDate, ! EndOfDaySpecificTime.MarketClose); ! EndOfDayDateTime lastEndOfDayDateTime = ! new EndOfDayDateTime(lastQuoteDate, ! EndOfDaySpecificTime.MarketClose); ! this.returnsManager = ! new ReturnsManager( new CloseToCloseIntervals( ! firstEndOfDayDateTime, ! lastEndOfDayDateTime, ! this.benchmark, ! this.numDaysForOscillatingPeriod), ! new HistoricalAdjustedQuoteProvider() ); } *************** *** 193,231 **** #endregion ! ! protected override float[] getArrayOfRatesOfReturn(string ticker) ! { ! float[] returnValue = null; ! Quotes tickerQuotes = new Quotes(ticker, this.firstQuoteDate, this.lastQuoteDate); ! tickerQuotes.RecalculateCloseToCloseRatios(); ! returnValue = QuantProject.ADT.ExtendedDataTable.GetArrayOfFloatFromColumn(tickerQuotes, ! Quotes.AdjustedCloseToCloseRatio); ! for(int i = 0; i<returnValue.Length; i++) ! returnValue[i] = returnValue[i] - 1.0f; ! ! this.numberOfExaminedReturns = returnValue.Length; ! ! return returnValue; ! } ! //starting from this.numDaysForOscillatingPeriod day, ! //it computes for each day ahead the value of the ! //portfolio opened numDaysForOscillatingPeriod days ago ! private double[] getPortfolioMovingValues() ! { ! double[] returnValue = new double[this.portfolioRatesOfReturn.Length]; ! double[] valuesInOscillatingPeriod = new double[this.numDaysForOscillatingPeriod]; ! valuesInOscillatingPeriod[0] = 1.0; ! for(int i = this.numDaysForOscillatingPeriod; i<returnValue.Length; i++) { ! for(int j = 1; ! j < this.numDaysForOscillatingPeriod; j++) ! valuesInOscillatingPeriod[j] = ! valuesInOscillatingPeriod[j - 1] + ! valuesInOscillatingPeriod[j - 1] * ! this.portfolioRatesOfReturn[i-this.numDaysForOscillatingPeriod+j]; ! returnValue[i-1] = valuesInOscillatingPeriod[this.numDaysForOscillatingPeriod -1]; } return returnValue; ! } private void getFitnessValue_setCurrentThresholds(Genome genome) --- 219,261 ---- #endregion ! ! ! #region getStrategyReturns ! ! private float[] getStrategyReturns_getReturnsActually( ! float[] plainReturns) ! { ! ! float[] returnValue = new float[plainReturns.Length]; ! returnValue[0] = 0; //a the very first day the ! //strategy return is equal to 0 because no position ! //has been entered ! float coefficient = 0; ! for(int i = 0; i < returnValue.Length - 1; i++) { ! if( plainReturns[i] >= (float)this.currentOverboughtThreshold ) ! //portfolio has been overbought ! coefficient = -1; ! else if( plainReturns[i] <= - (float)this.currentOversoldThreshold ) ! //portfolio has been oversold ! coefficient = 1; ! //else the previous coeff is kept or, if no threshold has been ! //reached, then no positions will be opened (coefficient = 0) ! returnValue[i + 1] = coefficient * plainReturns[i + 1]; } return returnValue; ! ! //return plainReturns; ! } ! ! protected override float[] getStrategyReturns() ! { ! float[] plainReturns = this.weightedPositionsFromGenome.GetReturns( ! this.returnsManager); ! return this.getStrategyReturns_getReturnsActually(plainReturns); ! } ! ! #endregion ! private void getFitnessValue_setCurrentThresholds(Genome genome) *************** *** 241,249 **** } ! private int getFitnessValue_getDaysOnTheMarket(double[] equityLine) { int returnValue = 0; ! foreach(double equityReturn in equityLine) ! if(equityReturn != 0.0) //the applied strategy gets positions on the market returnValue++; --- 271,279 ---- } ! protected int getFitnessValue_getDaysOnTheMarket() { int returnValue = 0; ! foreach(float strategyReturn in this.strategyReturns) ! if(strategyReturn != 0) //the applied strategy gets positions on the market returnValue++; *************** *** 251,315 **** return returnValue; } ! ! //fitness is a sharpe-ratio based indicator for the equity line resulting ! //from applying the strategy ! public override double GetFitnessValue(Genome genome) { ! double returnValue = -1.0; ! this.portfolioRatesOfReturn = this.getPortfolioRatesOfReturn(genome.Genes()); ! this.portfolioValues = this.getPortfolioMovingValues(); ! this.getFitnessValue_setCurrentThresholds(genome); ! double[] equityLine = this.getFitnessValue_getEquityLineRates(); ! double fitness = Double.NaN; ! if(this.getFitnessValue_getDaysOnTheMarket(equityLine) > ! equityLine.Length / 2) ! //if the genome represents a portfolio that stays on the market ! //at least half of the theoretical days ! fitness = AdvancedFunctions.GetSharpeRatio(equityLine); ! if(!double.IsNaN(fitness) && !double.IsInfinity(fitness)) ! returnValue = fitness; ! ! return returnValue; } ! private double[] getFitnessValue_getEquityLineRates() { ! double[] returnValue = new double[this.PortfolioRatesOfReturn.Length]; ! double coefficient = 0.0; ! for(int i = 0; i<this.PortfolioRatesOfReturn.Length - 1;i++) ! { ! if(this.portfolioValues[i] >= ! 1.0 + this.currentOverboughtThreshold) ! //portfolio is overbought ! coefficient = -1.0; ! else if(this.portfolioValues[i] <= ! 1.0 - this.currentOversoldThreshold && ! this.portfolioValues[i] > 0.0) ! //portfolio is oversold ! coefficient = 1.0; ! ! returnValue[i + 1] = ! coefficient * this.PortfolioRatesOfReturn[i + 1]; ! } ! return returnValue; } ! ! protected override double getTickerWeight(int[] genes, int tickerPositionInGenes) { ! return 1.0/(genes.Length - this.numOfGenesDedicatedToThresholds); } ! ! protected override double[] getPortfolioRatesOfReturn(int[] genes) { ! double[] returnValue = new double[this.numberOfExaminedReturns]; ! for(int i = 0; i<returnValue.Length; i++) ! { ! for(int j=this.numOfGenesDedicatedToThresholds; j<genes.Length; j++)//the first numOfGenesDedicatedToThresholds are for thresholds ! returnValue[i] += ! this.getPortfolioRatesOfReturn_getRateOfTickerToBeAddedToTheArray(genes,j,i); ! } ! return returnValue; } public override object Decode(Genome genome) { --- 281,348 ---- return returnValue; } ! ! private double getFitnessValue_calculate_calculateActually() { ! return this.AverageOfStrategyReturns/Math.Sqrt(this.VarianceOfStrategyReturns); ! //return Math.Sqrt(this.VarianceOfStrategyReturns); } ! ! protected override double getFitnessValue_calculate() { ! double returnValue = -1.0; ! if(this.getFitnessValue_getDaysOnTheMarket() > ! this.strategyReturns.Length / 2) ! //if the genome represents a portfolio that stays on the market ! //at least half of the theoretical days ! returnValue = ! this.getFitnessValue_calculate_calculateActually(); ! return returnValue; } ! ! protected string getFitnessValue_getFirstTickerFromGenome(Genome genome) { ! GenomeMeaningPVO genomeMeaning = (GenomeMeaningPVO)genome.Meaning; ! return genomeMeaning.Tickers[0]; } ! protected string getFitnessValue_getSecondTickerFromGenome(Genome genome) { ! GenomeMeaningPVO genomeMeaning = (GenomeMeaningPVO)genome.Meaning; ! return genomeMeaning.Tickers[1]; } + + //fitness is a sharpe-ratio based indicator for the equity line resulting + //from applying the strategy + public override double GetFitnessValue(Genome genome) + { + //OLD CLASSICAL IMPLEMENTATION (sharpeRatio applied to strategyReturns) + // this.getFitnessValue_setCurrentThresholds(genome); + // return base.GetFitnessValue(genome); + //NEW implementation: fitness is just the pearson correlation + //applied to two tickers. This kind of fitness is only valid + //for experimental tests with 2-tickers portfolios + double returnValue = -2.0; + if(this.correlationProvider == null) + this.correlationProvider = new CloseToCloseCorrelationProvider( + QuantProject.ADT.ExtendedDataTable.GetArrayOfStringFromColumn(this.setOfTickers, 0), + this.returnsManager, 0.0001f, 0.5f); + string firstTicker = this.getFitnessValue_getFirstTickerFromGenome(genome); + string secondTicker = this.getFitnessValue_getSecondTickerFromGenome(genome); + if( ( firstTicker.StartsWith("-") && !secondTicker.StartsWith("-") ) || + ( secondTicker.StartsWith("-") && !firstTicker.StartsWith("-") ) ) + //tickers have to be opposite in sign + { + double correlationIndex = correlationProvider.GetPearsonCorrelation( + SignedTicker.GetTicker(firstTicker), + SignedTicker.GetTicker(secondTicker) ); + if(correlationIndex < 0.96) + // if correlation index is not too high to be + // probably originated by the same instrument + returnValue = correlationIndex; + } + return returnValue; + } + public override object Decode(Genome genome) { *************** *** 326,338 **** this.decode_getTickerCodeForLongOrShortTrade(geneForTicker); } if(this.symmetricalThresholds) ! meaning = new GenomeMeaningPVO( ! arrayOfTickers, Convert.ToDouble(genome.Genes()[0])/Convert.ToDouble(this.divisorForThresholdComputation), Convert.ToDouble(genome.Genes()[0])/Convert.ToDouble(this.divisorForThresholdComputation), this.numDaysForOscillatingPeriod); else ! meaning = new GenomeMeaningPVO( ! arrayOfTickers, Convert.ToDouble(genome.Genes()[0])/Convert.ToDouble(this.divisorForThresholdComputation), Convert.ToDouble(genome.Genes()[1])/Convert.ToDouble(this.divisorForThresholdComputation), --- 359,376 ---- this.decode_getTickerCodeForLongOrShortTrade(geneForTicker); } + + double[] arrayOfWeights = ExtendedMath.ArrayOfAbs( + WeightedPositions.GetBalancedWeights(new SignedTickers(arrayOfTickers), + this.returnsManager) ); + if(this.symmetricalThresholds) ! meaning = new GenomeMeaningPVO(arrayOfTickers, ! arrayOfWeights, Convert.ToDouble(genome.Genes()[0])/Convert.ToDouble(this.divisorForThresholdComputation), Convert.ToDouble(genome.Genes()[0])/Convert.ToDouble(this.divisorForThresholdComputation), this.numDaysForOscillatingPeriod); else ! meaning = new GenomeMeaningPVO(arrayOfTickers, ! arrayOfWeights, Convert.ToDouble(genome.Genes()[0])/Convert.ToDouble(this.divisorForThresholdComputation), Convert.ToDouble(genome.Genes()[1])/Convert.ToDouble(this.divisorForThresholdComputation), Index: RunPVO.cs =================================================================== RCS file: /cvsroot/quantproject/QuantProject/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOscillators/PortfolioValueOscillator/RunPVO.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** RunPVO.cs 27 Feb 2007 22:19:51 -0000 1.4 --- RunPVO.cs 14 Jan 2008 23:07:02 -0000 1.5 *************** *** 61,64 **** --- 61,65 ---- protected int numDaysBetweenEachOptimization; protected double maxAcceptableCloseToCloseDrawdown; + protected double minimumAcceptableGain; protected int numDaysForOscillatingPeriod; protected bool symmetricalThresholds = false; *************** *** 80,83 **** --- 81,85 ---- int numDaysBetweenEachOptimization, PortfolioType inSamplePortfolioType, double maxAcceptableCloseToCloseDrawdown, + double minimumAcceptableGain, double maxRunningHours): base(tickerGroupID, maxNumOfEligibleTickersForOptimization, *************** *** 97,100 **** --- 99,103 ---- this.overboughtMoreThanOversoldForFixedPortfolio = overboughtMoreThanOversoldForFixedPortfolio; this.maxAcceptableCloseToCloseDrawdown = maxAcceptableCloseToCloseDrawdown; + this.minimumAcceptableGain = minimumAcceptableGain; this.numDaysForOscillatingPeriod = numDaysForOscillatingPeriod; this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; *************** *** 119,123 **** this.overboughtMoreThanOversoldForFixedPortfolio, this.numDaysBetweenEachOptimization, ! this.portfolioType, this.maxAcceptableCloseToCloseDrawdown); } --- 122,127 ---- this.overboughtMoreThanOversoldForFixedPortfolio, this.numDaysBetweenEachOptimization, ! this.portfolioType, this.maxAcceptableCloseToCloseDrawdown, ! this.minimumAcceptableGain); } Index: EndOfDayTimerHandlerPVO.cs =================================================================== RCS file: /cvsroot/quantproject/QuantProject/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOscillators/PortfolioValueOscillator/EndOfDayTimerHandlerPVO.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** EndOfDayTimerHandlerPVO.cs 23 Sep 2007 22:07:57 -0000 1.7 --- EndOfDayTimerHandlerPVO.cs 14 Jan 2008 23:07:02 -0000 1.8 *************** *** 30,36 **** --- 30,41 ---- using QuantProject.Business.Timing; using QuantProject.Business.Strategies; + using QuantProject.Business.Strategies.ReturnsManagement; + using QuantProject.Business.Strategies.ReturnsManagement.Time; + using QuantProject.Business.DataProviders; + using QuantProject.Business.Strategies.TickersRelationships; using QuantProject.Data; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; + //using QuantProject.Data.Selectors.ByLinearDipendence; using QuantProject.Data.DataTables; using QuantProject.ADT.Optimizing.Genetic; *************** *** 57,60 **** --- 62,66 ---- protected double currentOverboughtThreshold; protected double maxAcceptableCloseToCloseDrawdown; + protected double minimumAcceptableGain; protected DateTime lastCloseDate; protected IGenomeManager iGenomeManager; *************** *** 64,67 **** --- 70,74 ---- protected bool symmetricalThresholds; protected bool overboughtMoreThanOversoldForFixedPortfolio; + protected HistoricalAdjustedQuoteProvider historicalQuoteProvider; public EndOfDayTimerHandlerPVO(string tickerGroupID, int numberOfEligibleTickers, *************** *** 80,84 **** bool overboughtMoreThanOversoldForFixedPortfolio, int numDaysBetweenEachOptimization, ! PortfolioType portfolioType, double maxAcceptableCloseToCloseDrawdown): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, account, --- 87,92 ---- bool overboughtMoreThanOversoldForFixedPortfolio, int numDaysBetweenEachOptimization, ! PortfolioType portfolioType, double maxAcceptableCloseToCloseDrawdown, ! double minimumAcceptableGain): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, account, *************** *** 97,100 **** --- 105,109 ---- this.overboughtMoreThanOversoldForFixedPortfolio = overboughtMoreThanOversoldForFixedPortfolio; this.maxAcceptableCloseToCloseDrawdown = maxAcceptableCloseToCloseDrawdown; + this.minimumAcceptableGain = minimumAcceptableGain; this.stopLossConditionReached = false; this.currentAccountValue = 0.0; *************** *** 104,107 **** --- 113,117 ---- this.portfolioHasBeenOverbought = false; this.portfolioHasBeenOversold = false; + this.historicalQuoteProvider = new HistoricalAdjustedQuoteProvider(); } *************** *** 114,142 **** #region MarketCloseEventHandler ! protected void marketCloseEventHandler_updateStopLossCondition() ! { ! this.previousAccountValue = this.currentAccountValue; ! this.currentAccountValue = this.account.GetMarketValue(); ! if( (this.currentAccountValue - this.previousAccountValue)/ ! this.previousAccountValue < -this.maxAcceptableCloseToCloseDrawdown ) ! this.stopLossConditionReached = true; ! else ! this.stopLossConditionReached = false; ! } ! ! protected virtual double getCurrentChosenWeightedPositionsValue(IndexBasedEndOfDayTimer timer) { double returnValue = 999.0; try { ! DateTime initialDate = ! (DateTime)timer.IndexQuotes.Rows[timer.CurrentDateArrayPosition - this.numDaysForOscillatingPeriod + 2]["quDate"]; ! //so to replicate exactly in sample scheme, where only numOscillatingDay - 1 returns ! //are computed ! DateTime finalDate = ! (DateTime)timer.IndexQuotes.Rows[timer.CurrentDateArrayPosition]["quDate"]; ! returnValue = ! this.chosenWeightedPositions.GetCloseToCloseReturn( initialDate, ! finalDate) + 1.0; } catch(MissingQuotesException ex) --- 124,144 ---- #region MarketCloseEventHandler ! protected virtual double getCurrentChosenWeightedPositionsReturn(IndexBasedEndOfDayTimer timer) { double returnValue = 999.0; try { ! DateTime firstDayOfOscillatingPeriod = ! (DateTime)timer.IndexQuotes.Rows[timer.CurrentDateArrayPosition - this.numDaysForOscillatingPeriod]["quDate"]; ! DateTime today = ! (DateTime)timer.IndexQuotes.Rows[timer.CurrentDateArrayPosition]["quDate"]; ! ReturnsManager returnsManager = new ReturnsManager(new CloseToCloseIntervals( ! new EndOfDayDateTime(firstDayOfOscillatingPeriod, ! EndOfDaySpecificTime.MarketClose) , ! new EndOfDayDateTime(today, ! EndOfDaySpecificTime.MarketClose) , ! this.benchmark , this.numDaysForOscillatingPeriod ) , ! this.historicalQuoteProvider ); ! returnValue = this.chosenWeightedPositions.GetReturn(0,returnsManager); } catch(MissingQuotesException ex) *************** *** 149,179 **** private void marketCloseEventHandler_reverseIfNeeded(IndexBasedEndOfDayTimer timer) { ! double currentChosenWeightedPositionsTickersValue = ! this.getCurrentChosenWeightedPositionsValue(timer); ! if(currentChosenWeightedPositionsTickersValue != 999.0) ! //currentChosenTickersValue has been properly computed { ! if(this.portfolioType == PortfolioType.ShortAndLong) ! //it is possible to reverse positions ! { ! if(currentChosenWeightedPositionsTickersValue >= 1.0 + currentOverboughtThreshold && ! this.portfolioHasBeenOversold) ! //open positions derive from an overSold period but now ! //an the overbought threshold has been reached ! { ! this.reversePositions(); ! this.portfolioHasBeenOversold = false; ! this.portfolioHasBeenOverbought = true; ! } ! if(currentChosenWeightedPositionsTickersValue <= 1.0 - currentOversoldThreshold && ! this.portfolioHasBeenOverbought) ! //open positions derive from an overSold period but now ! //an the overbought threshold has been reached ! { ! this.reversePositions(); ! this.portfolioHasBeenOversold = true; ! this.portfolioHasBeenOverbought = false; ! } ! } } } --- 151,181 ---- private void marketCloseEventHandler_reverseIfNeeded(IndexBasedEndOfDayTimer timer) { ! double currentChosenWeightedPositionsReturn = ! this.getCurrentChosenWeightedPositionsReturn(timer); ! if(currentChosenWeightedPositionsReturn != 999.0 && ! this.portfolioType == PortfolioType.ShortAndLong) ! //currentChosenWeightedPositionsReturn has been ! //properly computedand it is possible to reverse positions { ! if(currentChosenWeightedPositionsReturn >= currentOverboughtThreshold && ! this.portfolioHasBeenOversold) ! //open positions derive from an overSold period but now ! //the overbought threshold has been reached ! { ! this.reversePositions(); ! this.portfolioHasBeenOversold = false; ! this.portfolioHasBeenOverbought = true; ! this.previousAccountValue = this.account.GetMarketValue(); ! } ! if(currentChosenWeightedPositionsReturn <= - currentOversoldThreshold && ! this.portfolioHasBeenOverbought) ! //open positions derive from an overBought period but now ! //the overSold threshold has been reached ! { ! this.reversePositions(); ! this.portfolioHasBeenOversold = true; ! this.portfolioHasBeenOverbought = false; ! this.previousAccountValue = this.account.GetMarketValue(); ! } } } *************** *** 183,192 **** if(this.account.CashAmount == 0.0 && this.account.Transactions.Count == 0) this.account.AddCash(15000); ! double currentChosenWeightedPositionsValue = ! this.getCurrentChosenWeightedPositionsValue(timer); ! if(currentChosenWeightedPositionsValue != 999.0) //currentChosenTickersValue has been properly computed { ! if(currentChosenWeightedPositionsValue >= 1.0 + currentOverboughtThreshold && this.portfolioType == PortfolioType.ShortAndLong) { --- 185,194 ---- if(this.account.CashAmount == 0.0 && this.account.Transactions.Count == 0) this.account.AddCash(15000); ! double currentChosenWeightedPositionsReturn = ! this.getCurrentChosenWeightedPositionsReturn(timer); ! if(currentChosenWeightedPositionsReturn != 999.0) //currentChosenTickersValue has been properly computed { ! if(currentChosenWeightedPositionsReturn >= currentOverboughtThreshold && this.portfolioType == PortfolioType.ShortAndLong) { *************** *** 198,201 **** --- 200,204 ---- this.portfolioHasBeenOverbought = true; this.portfolioHasBeenOversold = false; + this.previousAccountValue = this.account.GetMarketValue(); } catch(Exception ex) *************** *** 208,219 **** } } ! else if (currentChosenWeightedPositionsValue <= 1.0 - currentOversoldThreshold) { AccountManager.OpenPositions( this.chosenWeightedPositions, ! this.account ); this.portfolioHasBeenOverbought = false; this.portfolioHasBeenOversold = true; } ! } } --- 211,223 ---- } } ! else if (currentChosenWeightedPositionsReturn <= - currentOversoldThreshold) { AccountManager.OpenPositions( this.chosenWeightedPositions, ! this.account ); this.portfolioHasBeenOverbought = false; this.portfolioHasBeenOversold = true; + this.previousAccountValue = this.account.GetMarketValue(); } ! } } *************** *** 221,231 **** { if(this.stopLossConditionReached || ! this.numDaysElapsedSinceLastOptimization + 1 == this.numDaysBetweenEachOptimization ) { AccountManager.ClosePositions(this.account); - //a new optimization is needed, now - this.chosenWeightedPositions = null; - //when positions are closed, these parameters - //have to be reset to false this.portfolioHasBeenOverbought = false; this.portfolioHasBeenOversold = false; --- 225,232 ---- { if(this.stopLossConditionReached || ! this.takeProfitConditionReached || ! this.numDaysElapsedSinceLastOptimization + 1 == this.numDaysBetweenEachOptimization ) { AccountManager.ClosePositions(this.account); this.portfolioHasBeenOverbought = false; this.portfolioHasBeenOversold = false; *************** *** 233,240 **** } public override void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { ! //this.marketCloseEventHandler_updateStopLossCondition(); this.marketCloseEventHandler_closePositionsIfNeeded(); if(this.chosenWeightedPositions != null) --- 234,261 ---- } + protected virtual void marketCloseEventHandler_updateStopLossAndTakeProfitConditions() + { + //this.previousAccountValue has been set at opening positions + this.currentAccountValue = this.account.GetMarketValue(); + double portfolioGainOrLoss = (this.currentAccountValue - this.previousAccountValue) + /this.previousAccountValue; + + if( portfolioGainOrLoss <= -this.maxAcceptableCloseToCloseDrawdown ) + { + this.stopLossConditionReached = true; + this.takeProfitConditionReached = false; + } + else if (portfolioGainOrLoss >= this.minimumAcceptableGain) + + { + this.stopLossConditionReached = false; + this.takeProfitConditionReached = true; + } + } + public override void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { ! this.marketCloseEventHandler_updateStopLossAndTakeProfitConditions(); this.marketCloseEventHandler_closePositionsIfNeeded(); if(this.chosenWeightedPositions != null) *************** *** 247,251 **** this.marketCloseEventHandler_reverseIfNeeded((IndexBasedEndOfDayTimer)sender); } - } --- 268,271 ---- *************** *** 253,258 **** #region OneHourAfterMarketCloseEventHandler ! ! protected virtual DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { --- 273,277 ---- #region OneHourAfterMarketCloseEventHandler ! protected virtual DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { *************** *** 262,269 **** SelectorByAverageRawOpenPrice byPrice = ! new SelectorByAverageRawOpenPrice(tickersFromGroup,false,currentDate.AddDays(-30), currentDate, numOfTickersInGroupAtCurrentDate, ! 20,500, 0.0001,100); SelectorByLiquidity mostLiquidSelector = --- 281,288 ---- SelectorByAverageRawOpenPrice byPrice = ! new SelectorByAverageRawOpenPrice(tickersFromGroup,false,currentDate.AddDays(-15), currentDate, numOfTickersInGroupAtCurrentDate, ! 30,3000, 0.0001,100); SelectorByLiquidity mostLiquidSelector = *************** *** 283,288 **** false, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers, this.benchmark); ! ! return quotedAtEachMarketDayFromLastSelection.GetTableOfSelectedTickers(); //for debug // SelectorByQuotationAtEachMarketDay quotedAtEachMarketDayFromLastSelection = --- 302,330 ---- false, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers, this.benchmark); ! // SelectorByMaxLinearDipendence dipendentTickers = ! // new SelectorByMaxLinearDipendence(quotedAtEachMarketDayFromLastSelection.GetTableOfSelectedTickers(), ! // currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, ! // this.numberOfEligibleTickers/2,2,1000, this.benchmark); ! // return dipendentTickers.GetTableOfSelectedTickers(); ! ! // DataTable quotedAtEachMarketDay = ! // quotedAtEachMarketDayFromLastSelection.GetTableOfSelectedTickers(); ! // ! // CloseToCloseCorrelationProvider correlationProvider = ! // new CloseToCloseCorrelationProvider( ! // QuantProject.ADT.ExtendedDataTable.GetArrayOfStringFromColumn( ! // quotedAtEachMarketDay, 0 ), ! // currentDate.AddDays(-this.numDaysForOptimizationPeriod), ! // currentDate,1,0.005,this.benchmark); ! ! // SelectorByCloseToCloseCorrelationToBenchmark byCorrelationToBenchmark = ! // new SelectorByCloseToCloseCorrelationToBenchmark( ! // quotedAtEachMarketDayFromLastSelection.GetTableOfSelectedTickers(), ! // this.benchmark, false, ! // currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, ! // this.numberOfEligibleTickers / 2, false); ! // return byCorrelationToBenchmark.GetTableOfSelectedTickers(); ! ! return quotedAtEachMarketDayFromLastSelection.GetTableOfSelectedTickers(); //for debug // SelectorByQuotationAtEachMarketDay quotedAtEachMarketDayFromLastSelection = *************** *** 334,338 **** this.symmetricalThresholds, this.overboughtMoreThanOversoldForFixedPortfolio, ! this.portfolioType); GeneticOptimizer GO = new GeneticOptimizer(this.iGenomeManager, this.populationSizeForGeneticOptimizer, --- 376,380 ---- this.symmetricalThresholds, this.overboughtMoreThanOversoldForFixedPortfolio, ! this.portfolioType,this.benchmark); GeneticOptimizer GO = new GeneticOptimizer(this.iGenomeManager, this.populationSizeForGeneticOptimizer, *************** *** 341,345 **** if(setGenomeCounter) this.genomeCounter = new GenomeCounter(GO); ! GO.MutationRate = 0.2; GO.Run(false); --- 383,387 ---- if(setGenomeCounter) this.genomeCounter = new GenomeCounter(GO); ! GO.MutationRate = 0.1; GO.Run(false); |