[Quantproject-developers] QuantProject/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOs
Brought to you by:
glauco_1
|
From: Marco M. <mi...@us...> - 2007-02-27 22:52:47
|
Update of /cvsroot/quantproject/QuantProject/b7_Scripts/TechnicalAnalysisTesting/Oscillators/FixedLevelOscillators/PortfolioValueOscillator/WeightedPVO/WeightedBalancedPVO In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv6633/WeightedPVO/WeightedBalancedPVO Added Files: RunWeightedBalancedPVO.cs GenomeManagerWeightedBalancedPVO.cs EndOfDayTimerHandlerWeightedBalancedPVO.cs Log Message: Added variations of Portfolio Value Oscillator strategy (some of these files have to be tested yet and will be re-written as soon as possible ...): - WeightedPVO: basic PVO (with thresholds); - weigthedBalancedPVO: the weighted PVO with 50% of portfolio invested in short positions and the remaining half in long ones; - biasedPVO: it is not simply chosen the genome with the highest fitness (as in the PVO base), but it is chosen the genome (from a given set of genomes with a good fitness) that has the highest degree of deviation from a threshold; - biasedPVO No Thresholds: as the biased, but the signal is just the highest gain or loss; - biasedOTC_PVONoThresholds: as the previous one, but with these differences: new positions are opened at market open, choosing the genome that opens with the highest gain or loss with respect to the last close All positions are closed at market close (at the moment ...tests are in progress ...) --- NEW FILE: EndOfDayTimerHandlerWeightedBalancedPVO.cs --- /* QuantProject - Quantitative Finance Library EndOfDayTimerHandlerWeightedBalancedPVO.cs Copyright (C) 2006 Marco Milletti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System; using System.Data; using System.Collections; using QuantProject.ADT; using QuantProject.Business.Financial.Accounting; using QuantProject.Business.Financial.Instruments; using QuantProject.Business.Financial.Ordering; using QuantProject.Business.Timing; using QuantProject.Business.Strategies; using QuantProject.Data; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.Data.DataTables; using QuantProject.ADT.Optimizing.Genetic; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.Scripts.WalkForwardTesting.LinearCombination; using QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator; namespace QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.WeightedPVO.WeightedBalancedPVO { /// <summary> /// Implements MarketOpenEventHandler and MarketCloseEventHandler /// These handlers contain the core strategy for the Portfolio Value /// Oscillator using different weights for tickers, in such a way that /// portfolio is invested for the 50% in long positions, /// and the other 50% in short positions (also with an odd number /// of tickers in portfolio) /// </summary> [Serializable] public class EndOfDayTimerHandlerWeightedBalancedPVO : EndOfDayTimerHandlerPVO { public EndOfDayTimerHandlerWeightedBalancedPVO(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, Account account, int generationNumberForGeneticOptimizer, int populationSizeForGeneticOptimizer, string benchmark, int numDaysForOscillatingPeriod, int minLevelForOversoldThreshold, int maxLevelForOversoldThreshold, int minLevelForOverboughtThreshold, int maxLevelForOverboughtThreshold, int divisorForThresholdComputation, bool symmetricalThresholds, bool overboughtMoreThanOversoldForFixedPortfolio, int numDaysBetweenEachOptimization, PortfolioType portfolioType, double maxAcceptableCloseToCloseDrawdown): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, account, generationNumberForGeneticOptimizer, populationSizeForGeneticOptimizer, benchmark, numDaysForOscillatingPeriod, minLevelForOversoldThreshold, maxLevelForOversoldThreshold, minLevelForOverboughtThreshold, maxLevelForOverboughtThreshold, divisorForThresholdComputation, symmetricalThresholds, overboughtMoreThanOversoldForFixedPortfolio, numDaysBetweenEachOptimization, portfolioType, maxAcceptableCloseToCloseDrawdown) { } protected override DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { SelectorByGroup temporizedGroup = new SelectorByGroup(this.tickerGroupID, currentDate); DataTable tickersFromGroup = temporizedGroup.GetTableOfSelectedTickers(); int numOfTickersInGroupAtCurrentDate = tickersFromGroup.Rows.Count; SelectorByAverageRawOpenPrice byPrice = new SelectorByAverageRawOpenPrice(tickersFromGroup,false,currentDate.AddDays(-30), currentDate, numOfTickersInGroupAtCurrentDate, 20,500, 0.0001,100); SelectorByLiquidity mostLiquidSelector = new SelectorByLiquidity(byPrice.GetTableOfSelectedTickers(), false,currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers); // SelectorByCloseToCloseCorrelationToBenchmark byCorrelationToBenchmark = // new SelectorByCloseToCloseCorrelationToBenchmark(mostLiquidSelector.GetTableOfSelectedTickers(), // "^GSPC",false, // currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, // this.numberOfEligibleTickers/2,false); // SelectorByQuotationAtEachMarketDay quotedAtEachMarketDayFromLastSelection = new SelectorByQuotationAtEachMarketDay(mostLiquidSelector.GetTableOfSelectedTickers(), false, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers, this.benchmark); return quotedAtEachMarketDayFromLastSelection.GetTableOfSelectedTickers(); } protected override void setTickers(DateTime currentDate, bool setGenomeCounter) { DataTable setOfTickersToBeOptimized = this.getSetOfTickersToBeOptimized(currentDate); if(setOfTickersToBeOptimized.Rows.Count > this.chosenTickers.Length*2) //the optimization process is meaningful only if the initial set of tickers is //larger than the number of tickers to be chosen { this.iGenomeManager = new GenomeManagerWeightedBalancedPVO(setOfTickersToBeOptimized, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfTickersToBeChosen, this.numDaysForOscillatingPeriod, this.minLevelForOversoldThreshold, this.maxLevelForOversoldThreshold, this.minLevelForOverboughtThreshold, this.maxLevelForOverboughtThreshold, this.divisorForThresholdComputation, this.symmetricalThresholds, this.overboughtMoreThanOversoldForFixedPortfolio, this.portfolioType); GeneticOptimizer GO = new GeneticOptimizer(this.iGenomeManager, this.populationSizeForGeneticOptimizer, this.generationNumberForGeneticOptimizer, this.seedForRandomGenerator); if(setGenomeCounter) this.genomeCounter = new GenomeCounter(GO); GO.MutationRate = 0.2; GO.Run(false); this.chosenTickers = ((GenomeMeaningPVO)GO.BestGenome.Meaning).Tickers; this.chosenTickersPortfolioWeights = ((GenomeMeaningPVO)GO.BestGenome.Meaning).TickersPortfolioWeights; this.currentOversoldThreshold = ((GenomeMeaningPVO)GO.BestGenome.Meaning).OversoldThreshold; this.currentOverboughtThreshold = ((GenomeMeaningPVO)GO.BestGenome.Meaning).OverboughtThreshold; this.addPVOGenomeToBestGenomes(GO.BestGenome,((GenomeManagerForEfficientPortfolio)this.iGenomeManager).FirstQuoteDate, ((GenomeManagerForEfficientPortfolio)this.iGenomeManager).LastQuoteDate, setOfTickersToBeOptimized.Rows.Count, this.numDaysForOscillatingPeriod, this.portfolioType, GO.GenerationCounter, this.currentOversoldThreshold, this.currentOverboughtThreshold); } //else it will be buyed again the previous optimized portfolio //that's it the actual chosenTickers member } } } --- NEW FILE: RunWeightedBalancedPVO.cs --- /* QuantProject - Quantitative Finance Library RunWeightedBalancedPVO.cs Copyright (C) 2006 Marco Milletti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System; using System.Collections; using System.Data; using QuantProject.ADT; using QuantProject.ADT.Optimizing.Genetic; using QuantProject.Business.DataProviders; using QuantProject.Business.Financial.Accounting; using QuantProject.Business.Financial.Accounting.Reporting; using QuantProject.Business.Financial.Instruments; using QuantProject.Business.Financial.Ordering; using QuantProject.Business.Scripting; using QuantProject.Business.Strategies; using QuantProject.Business.Testing; using QuantProject.Business.Timing; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.Presentation.Reporting.WindowsForm; using QuantProject.ADT.FileManaging; using QuantProject.Scripts.WalkForwardTesting.LinearCombination; namespace QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.WeightedPVO.WeightedBalancedPVO { /// <summary> /// Script that implements an oscillating strategy using weights for tickers, /// based on the classical technical indicator /// RelativeStrengthIndex - RSI /// </summary> [Serializable] public class RunWeightedBalancedPVO : RunEfficientPortfolio { protected int minLevelForOversoldThreshold; protected int maxLevelForOversoldThreshold; protected int minLevelForOverboughtThreshold; protected int maxLevelForOverboughtThreshold; protected int divisorForThresholdComputation; //to be used by the optimizer protected int numDaysBetweenEachOptimization; protected double maxAcceptableCloseToCloseDrawdown; protected int numDaysForOscillatingPeriod; protected bool symmetricalThresholds = false; protected bool overboughtMoreThanOversoldForFixedPortfolio = false; public RunWeightedBalancedPVO(string tickerGroupID, int maxNumOfEligibleTickersForOptimization, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, int generationNumberForGeneticOptimizer, int populationSizeForGeneticOptimizer, string benchmark, DateTime startDate, DateTime endDate, int numDaysForOscillatingPeriod, int minLevelForOversoldThreshold, int maxLevelForOversoldThreshold, int minLevelForOverboughtThreshold, int maxLevelForOverboughtThreshold, int divisorForThresholdComputation, bool symmetricalThresholds, bool overboughtMoreThanOversoldForFixedPortfolio, int numDaysBetweenEachOptimization, PortfolioType inSamplePortfolioType, double maxAcceptableCloseToCloseDrawdown, double maxRunningHours): base(tickerGroupID, maxNumOfEligibleTickersForOptimization, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, generationNumberForGeneticOptimizer, populationSizeForGeneticOptimizer, benchmark, startDate, endDate, 0.0, inSamplePortfolioType, maxRunningHours) { this.ScriptName = "PVO_SR_BalancedWeights_PriceSel"; this.minLevelForOversoldThreshold = minLevelForOversoldThreshold; this.maxLevelForOversoldThreshold = maxLevelForOversoldThreshold; this.minLevelForOverboughtThreshold = minLevelForOverboughtThreshold; this.maxLevelForOverboughtThreshold = maxLevelForOverboughtThreshold; this.divisorForThresholdComputation = divisorForThresholdComputation; this.symmetricalThresholds = symmetricalThresholds; this.overboughtMoreThanOversoldForFixedPortfolio = overboughtMoreThanOversoldForFixedPortfolio; this.maxAcceptableCloseToCloseDrawdown = maxAcceptableCloseToCloseDrawdown; this.numDaysForOscillatingPeriod = numDaysForOscillatingPeriod; this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; } #region auxiliary overriden methods for Run protected override void run_initializeEndOfDayTimerHandler() { this.endOfDayTimerHandler = new EndOfDayTimerHandlerWeightedBalancedPVO(this.tickerGroupID, this.numberOfEligibleTickers, this.numberOfTickersToBeChosen, this.numDaysForOptimizationPeriod, this.account, this.generationNumberForGeneticOptimizer, this.populationSizeForGeneticOptimizer, this.benchmark, this.numDaysForOscillatingPeriod, this.minLevelForOversoldThreshold, this.maxLevelForOversoldThreshold, this.minLevelForOverboughtThreshold, this.maxLevelForOverboughtThreshold, this.divisorForThresholdComputation, this.symmetricalThresholds, this.overboughtMoreThanOversoldForFixedPortfolio, this.numDaysBetweenEachOptimization, this.portfolioType, this.maxAcceptableCloseToCloseDrawdown); } protected override void run_initializeHistoricalQuoteProvider() { this.historicalQuoteProvider = new HistoricalAdjustedQuoteProvider(); } protected override void run_addEventHandlers() { this.endOfDayTimer.MarketClose += new MarketCloseEventHandler( this.endOfDayTimerHandler.MarketCloseEventHandler); this.endOfDayTimer.MarketClose += new MarketCloseEventHandler( this.checkDateForReport); this.endOfDayTimer.OneHourAfterMarketClose += new OneHourAfterMarketCloseEventHandler( this.endOfDayTimerHandler.OneHourAfterMarketCloseEventHandler); } public override void SaveScriptResults() { string fileName = DateTime.Now.Hour.ToString().PadLeft(2,'0') + "_" + DateTime.Now.Minute.ToString().PadLeft(2,'0') + "_" + this.scriptName + "OsDays_" + numDaysForOscillatingPeriod + "_From_" + this.tickerGroupID + "_" + this.numberOfEligibleTickers + "_DaysForOpt" + this.numDaysForOptimizationPeriod + "Tick" + this.numberOfTickersToBeChosen + "GenN°" + this.generationNumberForGeneticOptimizer + "PopSize" + this.populationSizeForGeneticOptimizer + Convert.ToString(this.portfolioType); string dirNameWhereToSaveReports = System.Configuration.ConfigurationSettings.AppSettings["ReportsArchive"] + "\\" + this.ScriptName + "\\"; string dirNameWhereToSaveTransactions = System.Configuration.ConfigurationSettings.AppSettings["TransactionsArchive"] + "\\" + this.ScriptName + "\\"; string dirNameWhereToSaveBestGenomes = System.Configuration.ConfigurationSettings.AppSettings["GenomesArchive"] + "\\" + this.ScriptName + "\\"; this.checkDateForReport_createDirIfNotPresent(dirNameWhereToSaveBestGenomes); OptimizationOutput optimizationOutput = new OptimizationOutput(); foreach(GenomeRepresentation genomeRepresentation in this.endOfDayTimerHandler.BestGenomes) optimizationOutput.Add(genomeRepresentation); ObjectArchiver.Archive(optimizationOutput, dirNameWhereToSaveBestGenomes + fileName + ".bgn"); //default report with numIntervalDays = 1 AccountReport accountReport = this.account.CreateReport(fileName,1, this.endOfDayTimer.GetCurrentTime(), this.benchmark, new HistoricalAdjustedQuoteProvider()); this.checkDateForReport_createDirIfNotPresent(dirNameWhereToSaveReports); ObjectArchiver.Archive(accountReport, dirNameWhereToSaveReports + fileName + ".qPr"); this.endOfDayTimer.Stop(); } #endregion } } --- NEW FILE: GenomeManagerWeightedBalancedPVO.cs --- /* QuantProject - Quantitative Finance Library GenomeManagerWeightedBalancedPVO.cs Copyright (C) 2006 Marco Milletti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System; using System.Data; using System.Collections; using QuantProject.ADT; using QuantProject.ADT.Statistics; using QuantProject.ADT.Optimizing.Genetic; using QuantProject.Data; using QuantProject.Data.DataTables; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.WeightedPVO; namespace QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.WeightedPVO.WeightedBalancedPVO { /// <summary> /// Implements what needed to use the Genetic Optimizer /// for finding the portfolio that best suites /// the Portfolio Value Oscillator strategy (with weights /// that balance the portfolio between long and short positions) /// </summary> [Serializable] public class GenomeManagerWeightedBalancedPVO : GenomeManagerWeightedPVO { private bool arePrecedingTickersOnlyLong(Genome genome, int genePositionOfCurrentTicker) { bool returnValue = true; for(int i = 0; i<genePositionOfCurrentTicker ; i++) { if(this.genePositionPointsToATicker(i) && genome.GetGeneValue(i) < 0 ) // current i points to a short ticker returnValue = false; } return returnValue; } private bool arePrecedingTickersOnlyShort(Genome genome, int genePositionOfCurrentTicker) { bool returnValue = true; for(int i = 0; i<genePositionOfCurrentTicker ; i++) { if(this.genePositionPointsToATicker(i) && genome.GetGeneValue(i) >= 0 ) // current i points to a long ticker returnValue = false; } return returnValue; } public GenomeManagerWeightedBalancedPVO(DataTable setOfInitialTickers, DateTime firstQuoteDate, DateTime lastQuoteDate, int numberOfTickersInPortfolio, int numDaysForOscillatingPeriod, int minLevelForOversoldThreshold, int maxLevelForOversoldThreshold, int minLevelForOverboughtThreshold, int maxLevelForOverboughtThreshold, int divisorForThresholdComputation, bool symmetricalThresholds, bool overboughtMoreThanOversoldForFixedPortfolio, PortfolioType inSamplePortfolioType) : base(setOfInitialTickers, firstQuoteDate, lastQuoteDate, numberOfTickersInPortfolio, numDaysForOscillatingPeriod, minLevelForOversoldThreshold, maxLevelForOversoldThreshold, minLevelForOverboughtThreshold, maxLevelForOverboughtThreshold, divisorForThresholdComputation, symmetricalThresholds, overboughtMoreThanOversoldForFixedPortfolio, inSamplePortfolioType) { } private bool getTickerWeight_currentIndexPointsToATickerOfTheSameSign( int[]genes, int currentIndexOfTicker, int tickerPositionForComparison ) { //return true iif both point to long tickers or both point to short tickers return (genes[currentIndexOfTicker] >= 0 && genes[tickerPositionForComparison] >= 0) || (genes[currentIndexOfTicker] < 0 && genes[tickerPositionForComparison] < 0); } protected override double getTickerWeight(int[] genes, int tickerPositionInGenes) { double totalOfWeightsForTickersOfTheSameSign = 0.0; for(int j = this.numOfGenesDedicatedToThresholds; j < genes.Length; j++) { if( this.numOfGenesDedicatedToThresholds == 2 && j%2==0 && this.getTickerWeight_currentIndexPointsToATickerOfTheSameSign(genes,j+1,tickerPositionInGenes) ) //ticker weight is contained in genes at even position when //thresholds are asymmetrical and current Index Points To A Ticker Of The Same Sign //0 has to be avoided ! totalOfWeightsForTickersOfTheSameSign += Math.Abs(genes[j]) + 1.0; else if ( this.numOfGenesDedicatedToThresholds == 1 && j%2!=0 && this.getTickerWeight_currentIndexPointsToATickerOfTheSameSign(genes,j+1,tickerPositionInGenes) ) //ticker weight is contained in genes at odd position when //thresholds are symmetrical and current Index Points To A Ticker Of The Same Sign //0 has to be avoided ! totalOfWeightsForTickersOfTheSameSign += Math.Abs(genes[j]) + 1.0; } return ( Math.Abs(genes[tickerPositionInGenes-1]) + 1.0 ) / ( 2 * totalOfWeightsForTickersOfTheSameSign ); } private int getNewGeneValue_getGeneValue(Genome genome, int genePosition) { int returnValue; int minValueForGene = genome.GetMinValueForGenes(genePosition); int maxValueForGene = genome.GetMaxValueForGenes(genePosition); if ( this.numOfGenesDedicatedToThresholds == 2 && this.overboughtMoreThanOversoldForFixedPortfolio && genePosition == 1 ) //genePosition points to overbought threshold, //dipendent from the oversold one such that the portfolio tends to be fix returnValue = Convert.ToInt32(Convert.ToDouble(genome.GetGeneValue(0)) * Convert.ToDouble(this.divisorForThresholdComputation) / (Convert.ToDouble(this.divisorForThresholdComputation) - Convert.ToDouble(genome.GetGeneValue(0)))); else if( genePosition == genome.Size - 1 && this.arePrecedingTickersOnlyLong(genome, genePosition) ) //genePosition points to the last ticker and the preceding ones //point only to long tickers. In this case it has to be produced //a value pointing to a short ticker returnValue = GenomeManagement.RandomGenerator.Next(minValueForGene,0); else if( genePosition == genome.Size - 1 && this.arePrecedingTickersOnlyShort(genome, genePosition) ) //genePosition points to the last ticker and the preceding ones //point only to short tickers. In this case it has to be produced //a value pointing to a long ticker returnValue = GenomeManagement.RandomGenerator.Next(0,maxValueForGene + 1); else // genePosition doesn't point to the last ticker // or it points to the last ticker but the preceding tickers // are not of the same sign returnValue = GenomeManagement.RandomGenerator.Next(minValueForGene, maxValueForGene + 1); return returnValue; } public override int GetNewGeneValue(Genome genome, int genePosition) { // in this implementation only new gene values pointing to tickers // must be different from the others already stored int returnValue = this.getNewGeneValue_getGeneValue(genome,genePosition); while( this.genePositionPointsToATicker(genePosition) && GenomeManipulator.IsTickerContainedInGenome( returnValue, genome, this.GetGenePositionsPointingToTickers(genome) ) ) //while in the given position has to be stored //a new gene pointing to a ticker and //the proposed returnValue points to a ticker //already stored in the given genome, at the given genePositionsPointingToTickers returnValue = this.getNewGeneValue_getGeneValue(genome,genePosition); return returnValue; } } } |