[Quantproject-developers] QuantProject/b7_Scripts/TickerSelectionTesting EndOfDayTimerHandlerCTC.cs,
Brought to you by:
glauco_1
|
From: Marco M. <mi...@us...> - 2005-01-30 19:53:29
|
Update of /cvsroot/quantproject/QuantProject/b7_Scripts/TickerSelectionTesting In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3550/b7_Scripts/TickerSelectionTesting Modified Files: GenomeManagerForEfficientCTOPortfolio.cs GenomeManagerForEfficientPortfolio.cs RunEfficientCTOPortfolio.cs Added Files: EndOfDayTimerHandlerCTC.cs EndOfDayTimerHandlerCTO.cs GenomeManagerForEfficientCTCPortfolio.cs RunEfficientCTCPortfolio.cs Removed Files: EndOfDayTimerHandler.cs RunEfficientPortfolio.cs Log Message: New structure for the classes that make up script for the efficient portfolio. Now, the genomeManagers (for close to open and close to close portfolio) for the genetic optimizer derive from a common base class GenomeManagerForTheEfficientPortfolio. Handlers and Runs have been renamed. --- NEW FILE: EndOfDayTimerHandlerCTO.cs --- /* QuantProject - Quantitative Finance Library EndOfDayTimerHandlerCTO.cs Copyright (C) 2003 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.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.ADT.Optimizing.Genetic; namespace QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios { /// <summary> /// Implements MarketOpenEventHandler, /// TwoMinutesBeforeMarketCloseEventHandler and OneHourAfterMarketCloseEventHandler /// These handlers contain the core strategy for the efficient close to open portfolio! /// </summary> public class EndOfDayTimerHandlerCTO { private DataTable eligibleTickers; private string[] chosenTickers; //private string[] lastChosenTickers; private string tickerGroupID; private int numberOfEligibleTickers; private int numberOfTickersToBeChosen; private int generationNumberForGeneticOptimizer; private Account account; private ArrayList orders; public int NumberOfEligibleTickers { get { return this.numberOfEligibleTickers; } } public Account Account { get { return this.account; } } public EndOfDayTimerHandlerCTO(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, Account account, int generationNumberForGeneticOptimizer) { this.tickerGroupID = tickerGroupID; this.numberOfEligibleTickers = numberOfEligibleTickers; this.numberOfTickersToBeChosen = numberOfTickersToBeChosen; this.account = account; this.generationNumberForGeneticOptimizer = generationNumberForGeneticOptimizer; this.orders = new ArrayList(); this.chosenTickers = new string[numberOfTickersToBeChosen]; //this.lastChosenTickers = new string[numberOfTickersToBeChosen]; } #region MarketOpenEventHandler private void marketOpenEventHandler_orderChosenTickers_addToOrderList_forTicker( string ticker ) { double cashForSinglePosition = this.account.CashAmount / this.numberOfTickersToBeChosen; long quantity = Convert.ToInt64( Math.Floor( cashForSinglePosition / this.account.DataStreamer.GetCurrentBid( ticker ) ) ); Order order = new Order( OrderType.MarketBuy, new Instrument( ticker ) , quantity ); this.orders.Add(order); } private void marketOpenEventHandler_orderChosenTickers_addToOrderList() { foreach ( string ticker in this.chosenTickers ) { if(ticker != null) marketOpenEventHandler_orderChosenTickers_addToOrderList_forTicker( ticker ); } } private void marketOpenEventHandler_orderChosenTickers() { this.marketOpenEventHandler_orderChosenTickers_addToOrderList(); } /// <summary> /// Handles a "Market Open" event. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> public void MarketOpenEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { if(this.orders.Count == 0 && this.account.Transactions.Count == 0) this.account.AddCash(15000); this.marketOpenEventHandler_orderChosenTickers(); foreach(object item in this.orders) { this.account.AddOrder((Order)item); } } #endregion #region MarketCloseEventHandler private void marketCloseEventHandler_closePosition( string ticker ) { this.account.ClosePosition( ticker ); } private void marketCloseEventHandler_closePositions() { if(this.chosenTickers != null) { foreach( string ticker in this.chosenTickers) { for(int i = 0; i<this.account.Portfolio.Keys.Count; i++) { if(this.account.Portfolio[ticker]!=null) marketCloseEventHandler_closePosition( ticker ); } } } } public void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.marketCloseEventHandler_closePositions(); } #endregion #region OneHourAfterMarketCloseEventHandler private DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { TickerSelector mostLiquid = new TickerSelector(SelectionType.Liquidity, false, this.tickerGroupID , currentDate.AddDays(-45), currentDate, this.numberOfEligibleTickers); this.eligibleTickers = mostLiquid.GetTableOfSelectedTickers(); TickerSelector quotedInEachMarketDayFromMostLiquid = new TickerSelector( this.eligibleTickers, SelectionType.QuotedInEachMarketDay, false, "", currentDate.AddDays(-45),currentDate, this.numberOfEligibleTickers); quotedInEachMarketDayFromMostLiquid.MarketIndex = "^MIBTEL"; return quotedInEachMarketDayFromMostLiquid.GetTableOfSelectedTickers(); } private void setTickers(DateTime currentDate) { //this.lastChosenTickers = this.chosenTickers; DataTable setOfTickersToBeOptimized = this.getSetOfTickersToBeOptimized(currentDate); if(setOfTickersToBeOptimized.Rows.Count >= this.chosenTickers.Length) //the optimization process is possible only if the initial set of tickers is //as large as the number of tickers to be chosen { IGenomeManager genManEfficientCTOPortfolio = new GenomeManagerForEfficientCTOPortfolio(setOfTickersToBeOptimized, currentDate.AddDays(-30), currentDate, this.numberOfTickersToBeChosen, 1, 0.005); GeneticOptimizer GO = new GeneticOptimizer(genManEfficientCTOPortfolio); //GO.KeepOnRunningUntilConvergenceIsReached = true; GO.GenerationNumber = this.generationNumberForGeneticOptimizer; GO.Run(false); this.chosenTickers = (string[])GO.BestGenome.Meaning; //this.lastChosenTickers = this.chosenTickers; } //else it will be buyed again the previous optimized portfolio //that's it the actual chosenTickers member } /// <summary> /// Handles a "One hour after market close" event. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> public void OneHourAfterMarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.setTickers(endOfDayTimingEventArgs.EndOfDayDateTime.DateTime); //sets tickers to be chosen next Market Open event this.orders.Clear(); } #endregion } } --- EndOfDayTimerHandler.cs DELETED --- --- NEW FILE: RunEfficientCTCPortfolio.cs --- /* QuantProject - Quantitative Finance Library RunEfficientCTCPorfolio.cs Copyright (C) 2003 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; namespace QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios { /// <summary> /// Script to buy at close and sell at close /// after a specified number of market days /// the efficient portfolio /// The efficient portfolio's generation rules /// (contained in the EndOfDayTimerHandler) are: /// - choose the most liquid tickers; /// - choose only tickers quoted at each market day /// during a given previous interval of days; /// - choose the most efficient portfolio among these tickers /// </summary> [Serializable] public class RunEfficientCTCPorfolio : Script { private ReportTable reportTable; private EndOfDayDateTime startDateTime; private EndOfDayDateTime endDateTime; private int numIntervalDays;// number of days for the equity line graph private IHistoricalQuoteProvider historicalQuoteProvider = new HistoricalAdjustedQuoteProvider(); //private ProgressBarForm progressBarForm; private EndOfDayTimerHandlerCTC endOfDayTimerHandler; private Account account; private IEndOfDayTimer endOfDayTimer; public RunEfficientCTCPorfolio() { //this.progressBarForm = new ProgressBarForm(); this.reportTable = new ReportTable( "Summary_Reports" ); this.startDateTime = new EndOfDayDateTime( new DateTime( 2003 , 1 , 1 ) , EndOfDaySpecificTime.MarketOpen ); this.endDateTime = new EndOfDayDateTime( new DateTime( 2003 , 1 , 31 ) , EndOfDaySpecificTime.MarketClose ); this.numIntervalDays = 3; //for report } #region Run private void run_initializeEndOfDayTimer() { this.endOfDayTimer = new IndexBasedEndOfDayTimer( this.startDateTime, "^MIBTEL" ); } private void run_initializeAccount() { this.account = new Account( "EfficientCloseToClosePortfolio" , this.endOfDayTimer , new HistoricalEndOfDayDataStreamer( this.endOfDayTimer , this.historicalQuoteProvider ) , new HistoricalEndOfDayOrderExecutor( this.endOfDayTimer , this.historicalQuoteProvider ) ); } private void run_initializeEndOfDayTimerHandler() { this.endOfDayTimerHandler = new EndOfDayTimerHandlerCTC("STOCKMI",70,5,3,this.account,10); } /* private void inSampleNewProgressEventHandler( Object sender , NewProgressEventArgs eventArgs ) { this.progressBarForm.ProgressBarInSample.Value = eventArgs.CurrentProgress; this.progressBarForm.ProgressBarInSample.Refresh(); } private void run_initializeProgressHandlers() { this.endOfDayTimerHandler.InSampleNewProgress += new InSampleNewProgressEventHandler( this.inSampleNewProgressEventHandler ); } */ #region oneHourAfterMarketCloseEventHandler /* private void oneHourAfterMarketCloseEventHandler_handleProgessBarForm( IEndOfDayTimer endOfDayTimer ) { long elapsedDays = Convert.ToInt64( ((TimeSpan)( endOfDayTimer.GetCurrentTime().DateTime - this.startDateTime.DateTime )).TotalDays ); long totalDays = Convert.ToInt64( ((TimeSpan)( this.endDateTime.DateTime - this.startDateTime.DateTime )).TotalDays ); if ( Math.Floor( elapsedDays / totalDays * 100 ) > Math.Floor( ( elapsedDays - 1 ) / totalDays * 100 ) ) // a new out of sample time percentage point has been elapsed this.progressBarForm.ProgressBarOutOfSample.Value = Convert.ToInt16( Math.Floor( elapsedDays / totalDays * 100 ) ); } public void oneHourAfterMarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.oneHourAfterMarketCloseEventHandler_handleProgessBarForm( ( IEndOfDayTimer )sender ); if ( ( ( IEndOfDayTimer )sender ).GetCurrentTime().DateTime > this.endDateTime.DateTime ) { // the simulation has reached the ending date this.account.EndOfDayTimer.Stop(); this.progressBarForm.Close(); } } */ #endregion private void checkDateForReport(Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs) { Report report; if(endOfDayTimingEventArgs.EndOfDayDateTime.DateTime>=this.endDateTime.DateTime ) { this.endOfDayTimer.Stop(); report = new Report( this.account , this.historicalQuoteProvider ); report.Show("CTC_Portfolio" , this.numIntervalDays , this.endDateTime , "^MIBTEL" ); //ObjectArchiver.Archive(this.account, "CtcPortfolioAccount.qP","C:\\"); } } public override void Run() { //old script //this.run_FindBestPortfolioForNextTrade(); run_initializeEndOfDayTimer(); run_initializeAccount(); run_initializeEndOfDayTimerHandler(); //run_initializeProgressHandlers(); this.endOfDayTimer.MarketOpen += new MarketOpenEventHandler( this.endOfDayTimerHandler.MarketOpenEventHandler); this.endOfDayTimer.MarketClose += new MarketCloseEventHandler( this.endOfDayTimerHandler.MarketCloseEventHandler); this.endOfDayTimer.MarketClose += new MarketCloseEventHandler( this.checkDateForReport); //this.endOfDayTimer.OneHourAfterMarketClose += //new OneHourAfterMarketCloseEventHandler( //this.endOfDayTimerHandler.OneHourAfterMarketCloseEventHandler ); //this.endOfDayTimer.OneHourAfterMarketClose += //new OneHourAfterMarketCloseEventHandler( //this.oneHourAfterMarketCloseEventHandler ); //this.progressBarForm.Show(); this.endOfDayTimer.Start(); } #endregion } } --- RunEfficientPortfolio.cs DELETED --- --- NEW FILE: EndOfDayTimerHandlerCTC.cs --- /* QuantProject - Quantitative Finance Library EndOfDayTimerHandlerCTC.cs Copyright (C) 2003 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.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.ADT.Optimizing.Genetic; namespace QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios { /// <summary> /// Implements MarketOpenEventHandler and MarketCloseEventHandler /// These handlers contain the core strategy for the efficient close to close /// portfolio (with a given days of life)! /// </summary> [Serializable] public class EndOfDayTimerHandlerCTC { private DataTable eligibleTickers; private string[] chosenTickers; private string[] lastChosenTickers; private string tickerGroupID; private int numberOfEligibleTickers; private int numberOfTickersToBeChosen; private int numDaysOfPortfolioLife; private int daysCounter; private int generationNumberForGeneticOptimizer; private Account account; private ArrayList orders; public int NumberOfEligibleTickers { get { return this.numberOfEligibleTickers; } } public Account Account { get { return this.account; } } public EndOfDayTimerHandlerCTC(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysOfPortfolioLife, Account account, int generationNumberForGeneticOptimizer) { this.tickerGroupID = tickerGroupID; this.numberOfEligibleTickers = numberOfEligibleTickers; this.numberOfTickersToBeChosen = numberOfTickersToBeChosen; this.numDaysOfPortfolioLife = numDaysOfPortfolioLife; this.daysCounter = 0; this.account = account; this.generationNumberForGeneticOptimizer = generationNumberForGeneticOptimizer; this.orders = new ArrayList(); this.chosenTickers = new string[numberOfTickersToBeChosen]; this.lastChosenTickers = new string[numberOfTickersToBeChosen]; } #region MarketOpenEventHandler private DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { TickerSelector mostLiquid = new TickerSelector(SelectionType.Liquidity, false, this.tickerGroupID , currentDate.AddDays(-90), currentDate, this.numberOfEligibleTickers); this.eligibleTickers = mostLiquid.GetTableOfSelectedTickers(); TickerSelector quotedInEachMarketDayFromMostLiquid = new TickerSelector( this.eligibleTickers, SelectionType.QuotedInEachMarketDay, false, "", currentDate.AddDays(-90),currentDate, this.numberOfEligibleTickers); quotedInEachMarketDayFromMostLiquid.MarketIndex = "^MIBTEL"; return quotedInEachMarketDayFromMostLiquid.GetTableOfSelectedTickers(); } private void setTickers(DateTime currentDate) { 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 { IGenomeManager genManEfficientCTCPortfolio = new GenomeManagerForEfficientCTCPortfolio(setOfTickersToBeOptimized, currentDate.AddDays(-90), currentDate, this.numberOfTickersToBeChosen, this.numDaysOfPortfolioLife, 0.01); GeneticOptimizer GO = new GeneticOptimizer(genManEfficientCTCPortfolio); //GO.KeepOnRunningUntilConvergenceIsReached = true; GO.GenerationNumber = this.generationNumberForGeneticOptimizer; GO.Run(false); this.chosenTickers = (string[])GO.BestGenome.Meaning; } //else it will be buyed again the previous optimized portfolio //that's it the actual chosenTickers member } /// <summary> /// Handles a "Market Open" event. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> public void MarketOpenEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { if(this.daysCounter == 0 || this.daysCounter == this.numDaysOfPortfolioLife - 1) //at next close it will be time to open a new portfolio { this.setTickers(endOfDayTimingEventArgs.EndOfDayDateTime.DateTime); //sets tickers to be chosen at next close this.orders.Clear(); } } #endregion #region MarketCloseEventHandler private void marketCloseEventHandler_orderChosenTickers_addToOrderList_forTicker(string ticker) { double cashForSinglePosition = this.account.CashAmount / this.numberOfTickersToBeChosen; long quantity = Convert.ToInt64( Math.Floor( cashForSinglePosition / this.account.DataStreamer.GetCurrentBid( ticker ) ) ); Order order = new Order( OrderType.MarketBuy, new Instrument( ticker ) , quantity ); this.orders.Add(order); } private void marketCloseEventHandler_orderChosenTickers_addToOrderList() { int idx = 0; foreach ( string ticker in this.chosenTickers ) { this.lastChosenTickers[idx] = ticker; if(ticker != null) marketCloseEventHandler_orderChosenTickers_addToOrderList_forTicker( ticker ); idx++; } } private void marketCloseEventHandler_orderChosenTickers() { this.marketCloseEventHandler_orderChosenTickers_addToOrderList(); } private void marketCloseEventHandler_openPositions() { if(this.orders.Count == 0 && this.account.Transactions.Count == 0) this.account.AddCash(15000); this.marketCloseEventHandler_orderChosenTickers(); foreach(object item in this.orders) { this.account.AddOrder((Order)item); } } private void marketCloseEventHandler_closePosition( string ticker ) { this.account.ClosePosition( ticker ); } private void marketCloseEventHandler_closePositions() { if(this.lastChosenTickers != null) { foreach( string ticker in this.lastChosenTickers) { for(int i = 0; i<this.account.Portfolio.Keys.Count; i++) { if(this.account.Portfolio[ticker]!=null) marketCloseEventHandler_closePosition( ticker ); } } } } public void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.daysCounter++; if(this.daysCounter == this.numDaysOfPortfolioLife) //it's time to change portfolio { this.marketCloseEventHandler_closePositions(); this.marketCloseEventHandler_openPositions(); this.daysCounter = 0; } } #endregion } } --- NEW FILE: GenomeManagerForEfficientCTCPortfolio.cs --- /* QuantProject - Quantitative Finance Library GenomeManagerForEfficientCTCPortfolio.cs Copyright (C) 2003 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.Statistics; using QuantProject.ADT.Optimizing.Genetic; using QuantProject.Data; using QuantProject.Data.DataTables; namespace QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios { /// <summary> /// Class to find efficient /// portfolios based on tickers' CloseToClose rates (adjusted values), /// using the GeneticOptimizer /// </summary> public class GenomeManagerForEfficientCTCPortfolio : GenomeManagerForEfficientPortfolio { public GenomeManagerForEfficientCTCPortfolio(DataTable setOfInitialTickers, DateTime firstQuoteDate, DateTime lastQuoteDate, int numberOfTickersInPortfolio, int numDaysOfPortfolioLife, double targetPerformance) : base(setOfInitialTickers, firstQuoteDate, lastQuoteDate, numberOfTickersInPortfolio, numDaysOfPortfolioLife, targetPerformance) { } public override object Decode(Genome genome) { string[] arrayOfTickers = new string[genome.Genes().Length]; int indexOfTicker; for(int index = 0; index < genome.Genes().Length; index++) { indexOfTicker = (int)genome.Genes().GetValue(index); arrayOfTickers[index] = (string)this.setOfTickers.Rows[indexOfTicker][0]; } return arrayOfTickers; } protected override float[] getArrayOfRatesOfReturn(string ticker) { Quotes tickerQuotes = new Quotes(ticker, this.firstQuoteDate, this.lastQuoteDate); float[] allAdjValues = ExtendedDataTable.GetArrayOfFloatFromColumn(tickerQuotes, "quAdjustedClose"); float[] ratesOfReturns = new float[allAdjValues.Length/this.numDaysOfPortfolioLife + 1]; int i = 0; //index for ratesOfReturns array for(int idx = 0; idx + this.numDaysOfPortfolioLife < allAdjValues.Length; idx += this.numDaysOfPortfolioLife ) { ratesOfReturns[i] = allAdjValues[idx+this.numDaysOfPortfolioLife]/ allAdjValues[idx] - 1; i++; } return ratesOfReturns; } } } Index: RunEfficientCTOPortfolio.cs =================================================================== RCS file: /cvsroot/quantproject/QuantProject/b7_Scripts/TickerSelectionTesting/RunEfficientCTOPortfolio.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** RunEfficientCTOPortfolio.cs 15 Jan 2005 10:56:03 -0000 1.9 --- RunEfficientCTOPortfolio.cs 30 Jan 2005 19:53:11 -0000 1.10 *************** *** 70,74 **** //private ProgressBarForm progressBarForm; ! private EndOfDayTimerHandler endOfDayTimerHandler; private Account account; --- 70,74 ---- //private ProgressBarForm progressBarForm; ! private EndOfDayTimerHandlerCTO endOfDayTimerHandler; private Account account; *************** *** 81,88 **** this.reportTable = new ReportTable( "Summary_Reports" ); this.startDateTime = new EndOfDayDateTime( ! new DateTime( 2000 , 1 , 1 ) , EndOfDaySpecificTime.FiveMinutesBeforeMarketClose ); this.endDateTime = new EndOfDayDateTime( ! new DateTime( 2000 , 12 , 31 ) , EndOfDaySpecificTime.OneHourAfterMarketClose ); ! this.numIntervalDays = 7; } #region Run --- 81,88 ---- this.reportTable = new ReportTable( "Summary_Reports" ); this.startDateTime = new EndOfDayDateTime( ! new DateTime( 2002 , 1 , 1 ) , EndOfDaySpecificTime.FiveMinutesBeforeMarketClose ); this.endDateTime = new EndOfDayDateTime( ! new DateTime( 2002 , 1 , 20 ) , EndOfDaySpecificTime.OneHourAfterMarketClose ); ! this.numIntervalDays = 2; } #region Run *************** *** 97,101 **** IGenomeManager genManEfficientCTOPortfolio = new GenomeManagerForEfficientCTOPortfolio(tickers,firstDate, ! lastDate, 6, 0.005, 0.05); GeneticOptimizer GO = new GeneticOptimizer(genManEfficientCTOPortfolio); //GO.KeepOnRunningUntilConvergenceIsReached = true; --- 97,101 ---- IGenomeManager genManEfficientCTOPortfolio = new GenomeManagerForEfficientCTOPortfolio(tickers,firstDate, ! lastDate, 6,1, 0.005); GeneticOptimizer GO = new GeneticOptimizer(genManEfficientCTOPortfolio); //GO.KeepOnRunningUntilConvergenceIsReached = true; *************** *** 124,128 **** private void run_initializeEndOfDayTimerHandler() { ! this.endOfDayTimerHandler = new EndOfDayTimerHandler("STOCKMI",70,6,this.account,7); } /* --- 124,128 ---- private void run_initializeEndOfDayTimerHandler() { ! this.endOfDayTimerHandler = new EndOfDayTimerHandlerCTO("STOCKMI",70,5,this.account,10); } /* Index: GenomeManagerForEfficientPortfolio.cs =================================================================== RCS file: /cvsroot/quantproject/QuantProject/b7_Scripts/TickerSelectionTesting/GenomeManagerForEfficientPortfolio.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** GenomeManagerForEfficientPortfolio.cs 1 Dec 2004 22:40:03 -0000 1.1 --- GenomeManagerForEfficientPortfolio.cs 30 Jan 2005 19:53:11 -0000 1.2 *************** *** 32,57 **** namespace QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios { ! /// <summary> ! /// This class implements IGenomeManager, in order to find efficient ! /// portfolios based on the comparison of adjustedClose values for each ! /// portfolio's ticker ! /// at the beginning and at the end of a specified interval of days, using the ! /// GeneticOptimizer ! /// </summary> public class GenomeManagerForEfficientPortfolio : IGenomeManager { ! private int genomeSize; ! private int minValueForGenes; ! private int maxValueForGenes; ! ! private int intervalLength; ! ! private DataTable setOfTickers; ! private DateTime firstQuoteDate; ! private DateTime lastQuoteDate; ! private double targetPerformance; ! private double targetStdDev; ! private double variance; ! private double rateOfReturn; //IGenomeManager implementation for properties --- 32,52 ---- namespace QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios { ! /// <summary> ! /// This is the base class implementing IGenomeManager, in order to find ! /// efficient portfolios using the GeneticOptimizer ! /// </summary> public class GenomeManagerForEfficientPortfolio : IGenomeManager { ! protected int genomeSize; ! protected int minValueForGenes; ! protected int maxValueForGenes; ! ! protected DataTable setOfTickers; ! protected DateTime firstQuoteDate; ! protected DateTime lastQuoteDate; ! protected int numDaysOfPortfolioLife; ! protected double targetPerformance; ! protected double variance; ! protected double rateOfReturn; //IGenomeManager implementation for properties *************** *** 82,105 **** } ! public GenomeManagerForEfficientPortfolio(int intervalLengthInDays, ! DataTable setOfInitialTickers, ! DateTime firstQuoteDate, ! DateTime lastQuoteDate, ! int numberOfTickersInPortfolio, ! double targetPerformance, ! double targetStdDev) { this.setOfTickers = setOfInitialTickers; ! this.intervalLength = intervalLengthInDays; ! //arrayOfRatesOfReturn contains the rates of return computed for the given interval in days if(!this.setOfTickers.Columns.Contains("ArrayOfRatesOfReturn")) ! this.setOfTickers.Columns.Add("ArrayOfRatesOfReturn", System.Type.GetType("System.Array")); this.firstQuoteDate = firstQuoteDate; this.lastQuoteDate = lastQuoteDate; ! this.targetPerformance = targetPerformance; ! this.targetStdDev = targetStdDev; this.genomeSize = numberOfTickersInPortfolio; ! //each genes is the index for the setOfTickers table this.minValueForGenes = 0; this.maxValueForGenes = this.setOfTickers.Rows.Count - 1; --- 77,98 ---- } ! public GenomeManagerForEfficientPortfolio( DataTable setOfInitialTickers, ! DateTime firstQuoteDate, ! DateTime lastQuoteDate, ! int numberOfTickersInPortfolio, ! int numDaysOfPortfolioLife, ! double targetPerformance) { this.setOfTickers = setOfInitialTickers; ! if(!this.setOfTickers.Columns.Contains("ArrayOfRatesOfReturn")) ! this.setOfTickers.Columns.Add("ArrayOfRatesOfReturn", System.Type.GetType("System.Array")); this.firstQuoteDate = firstQuoteDate; this.lastQuoteDate = lastQuoteDate; ! this.targetPerformance = targetPerformance; this.genomeSize = numberOfTickersInPortfolio; ! this.numDaysOfPortfolioLife = numDaysOfPortfolioLife; ! //each genes is the index for the setOfTickers table this.minValueForGenes = 0; this.maxValueForGenes = this.setOfTickers.Rows.Count - 1; *************** *** 108,125 **** } ! public double GetFitnessValue(Genome genome) { ! //parameters used to balance the rate of return against variance ! double a=2.5, b=2.0; ! double portofolioVariance = this.getPortfolioVariance(genome.Genes()); double portfolioRateOfReturn = this.getPortfolioRateOfReturn(genome.Genes()); ! this.variance = portofolioVariance; this.rateOfReturn = portfolioRateOfReturn; ! //double returnValue = System.Math.Pow(((this.targetStdDev*this.targetStdDev)/portofolioVariance),a)* ! //System.Math.Pow((portfolioRateOfReturn/this.targetPerformance),b); ! ! double returnValue = System.Math.Pow(((this.targetStdDev*this.targetStdDev)/portofolioVariance),a)* ! System.Math.Pow(System.Math.Max(0.0,(portfolioRateOfReturn/this.targetPerformance)),b); return returnValue; } --- 101,115 ---- } ! public virtual double GetFitnessValue(Genome genome) { ! double returnValue; ! double portfolioVariance = this.getPortfolioVariance(genome.Genes()); double portfolioRateOfReturn = this.getPortfolioRateOfReturn(genome.Genes()); ! this.variance = portfolioVariance; this.rateOfReturn = portfolioRateOfReturn; ! NormalDistribution normal = new NormalDistribution(portfolioRateOfReturn, Math.Sqrt(portfolioVariance)); ! //returnValue = normal.GetProbability(this.targetPerformance*0.5,this.targetPerformance*1.5); ! returnValue = 1 - normal.GetProbability(this.targetPerformance); return returnValue; } *************** *** 151,166 **** // the new value has to be different from all the other genes of the genome int newValueForGene = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, ! genome.MaxValueForGenes +1); int genePositionToBeMutated = GenomeManagement.RandomGenerator.Next(genome.Size); while(genome.HasGene(newValueForGene)) { newValueForGene = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, ! genome.MaxValueForGenes +1); } GenomeManagement.MutateOneGene(genome, mutationRate, ! genePositionToBeMutated, newValueForGene); } ! public object Decode(Genome genome) { string sequenceOfTickers = ""; --- 141,156 ---- // the new value has to be different from all the other genes of the genome int newValueForGene = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, ! genome.MaxValueForGenes +1); int genePositionToBeMutated = GenomeManagement.RandomGenerator.Next(genome.Size); while(genome.HasGene(newValueForGene)) { newValueForGene = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, ! genome.MaxValueForGenes +1); } GenomeManagement.MutateOneGene(genome, mutationRate, ! genePositionToBeMutated, newValueForGene); } ! public virtual object Decode(Genome genome) { string sequenceOfTickers = ""; *************** *** 172,181 **** returnValue = sequenceOfTickers; returnValue += "(rate: " + this.RateOfReturn + " std: " + ! System.Math.Sqrt(this.Variance) + ")"; return returnValue; } // end of implementation of IGenomeManager ! private double getPortfolioVariance(int[] tickerIdx) { double sumOfVariances = this.getSumOfVariances(tickerIdx); --- 162,171 ---- returnValue = sequenceOfTickers; returnValue += "(rate: " + this.RateOfReturn + " std: " + ! System.Math.Sqrt(this.Variance) + ")"; return returnValue; } // end of implementation of IGenomeManager ! protected double getPortfolioVariance(int[] tickerIdx) { double sumOfVariances = this.getSumOfVariances(tickerIdx); *************** *** 185,189 **** } ! private double getSumOfVariances(int[] tickerIdx) { double returnValue = 0; --- 175,179 ---- } ! protected double getSumOfVariances(int[] tickerIdx) { double returnValue = 0; *************** *** 197,201 **** } ! private double getSumOfCovariances(int[] tickerIdx) { double returnValue = 0; --- 187,191 ---- } ! protected double getSumOfCovariances(int[] tickerIdx) { double returnValue = 0; *************** *** 219,223 **** } ! private void retrieveData() { foreach(DataRow row in this.setOfTickers.Rows) --- 209,213 ---- } ! protected void retrieveData() { foreach(DataRow row in this.setOfTickers.Rows) *************** *** 228,238 **** } } ! private float[] getArrayOfRatesOfReturn(string ticker) { Quotes tickerQuotes = new Quotes(ticker, this.firstQuoteDate, this.lastQuoteDate); float[] allAdjValues = ExtendedDataTable.GetArrayOfFloatFromColumn(tickerQuotes, "quAdjustedClose"); ! float[] ratesOfReturns = new float[allAdjValues.Length/this.intervalLength + 1]; int i = 0; //index for ratesOfReturns array for(int idx = 0; idx + this.intervalLength < allAdjValues.Length; idx += this.intervalLength ) { --- 218,234 ---- } } + //this protected method can be overriden by inherited classes + //which can specify the type of rates of return ! //in this basic implementation rates of returns ! //are based on daily close to close ! protected virtual float[] getArrayOfRatesOfReturn(string ticker) { Quotes tickerQuotes = new Quotes(ticker, this.firstQuoteDate, this.lastQuoteDate); float[] allAdjValues = ExtendedDataTable.GetArrayOfFloatFromColumn(tickerQuotes, "quAdjustedClose"); ! //float[] ratesOfReturns = new float[allAdjValues.Length/this.intervalLength + 1]; ! float[] ratesOfReturns = new float[allAdjValues.Length]; int i = 0; //index for ratesOfReturns array + /* for(int idx = 0; idx + this.intervalLength < allAdjValues.Length; idx += this.intervalLength ) { *************** *** 241,244 **** --- 237,248 ---- i++; } + */ + for(int idx = 0; idx < allAdjValues.Length; idx++) + { + ratesOfReturns[i] = allAdjValues[idx+1]/ + allAdjValues[idx] - 1; + i++; + } + return ratesOfReturns; } *************** *** 247,257 **** ! private double getPortfolioRateOfReturn(int[] tickerIdx) { double returnValue = 0; ! foreach(int idx in tickerIdx) ! { ! returnValue += BasicFunctions.SimpleAverage((float[])this.setOfTickers.Rows[idx]["ArrayOfRatesOfReturn"]); ! } //the investement is assumed to be equally divided return (returnValue/this.GenomeSize); --- 251,261 ---- ! protected double getPortfolioRateOfReturn(int[] tickerIdx) { double returnValue = 0; ! foreach(int idx in tickerIdx) ! { ! returnValue += BasicFunctions.SimpleAverage((float[])this.setOfTickers.Rows[idx]["ArrayOfRatesOfReturn"]); ! } //the investement is assumed to be equally divided return (returnValue/this.GenomeSize); Index: GenomeManagerForEfficientCTOPortfolio.cs =================================================================== RCS file: /cvsroot/quantproject/QuantProject/b7_Scripts/TickerSelectionTesting/GenomeManagerForEfficientCTOPortfolio.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** GenomeManagerForEfficientCTOPortfolio.cs 14 Dec 2004 21:25:45 -0000 1.2 --- GenomeManagerForEfficientCTOPortfolio.cs 30 Jan 2005 19:53:10 -0000 1.3 *************** *** 37,157 **** /// GeneticOptimizer /// </summary> ! public class GenomeManagerForEfficientCTOPortfolio : IGenomeManager { - private int genomeSize; - private int minValueForGenes; - private int maxValueForGenes; - - private DataTable setOfTickers; - private DateTime firstQuoteDate; - private DateTime lastQuoteDate; - private double targetPerformance; - private double targetStdDev; - private double variance; - private double rateOfReturn; - - //IGenomeManager implementation for properties - public int GenomeSize - { - get{return this.genomeSize;} - } - - public int MinValueForGenes - { - get{return this.minValueForGenes;} - } - public int MaxValueForGenes - { - get{return this.maxValueForGenes;} - } - //end of implementation for properties - - public double Variance - { - get{return this.variance;} - } - - public double RateOfReturn - { - get{return this.rateOfReturn;} - } - public GenomeManagerForEfficientCTOPortfolio(DataTable setOfInitialTickers, ! DateTime firstQuoteDate, ! DateTime lastQuoteDate, ! int numberOfTickersInPortfolio, ! double targetPerformance, ! double targetStdDev) { - this.setOfTickers = setOfInitialTickers; - if(!this.setOfTickers.Columns.Contains("ArrayOfCloseToOpenRates")) - this.setOfTickers.Columns.Add("ArrayOfCloseToOpenRates", System.Type.GetType("System.Array")); - this.firstQuoteDate = firstQuoteDate; - this.lastQuoteDate = lastQuoteDate; - this.targetPerformance = targetPerformance; - this.targetStdDev = targetStdDev; - this.genomeSize = numberOfTickersInPortfolio; - //each genes is the index for the setOfTickers table - this.minValueForGenes = 0; - this.maxValueForGenes = this.setOfTickers.Rows.Count - 1; - this.retrieveData(); - } - - public double GetFitnessValue(Genome genome) - { - //parameters used to balance the rate of return against variance - //double a=2.5, b=2.0; - double portofolioVariance = this.getPortfolioVariance(genome.Genes()); - double portfolioRateOfReturn = this.getPortfolioRateOfReturn(genome.Genes()); - this.variance = portofolioVariance; - this.rateOfReturn = portfolioRateOfReturn; - NormalDistribution normal = new NormalDistribution(portfolioRateOfReturn, Math.Sqrt(portofolioVariance)); - double returnValue = normal.GetProbability(this.targetPerformance*0.5,this.targetPerformance*1.5); - //double returnValue = System.Math.Pow(((this.targetStdDev*this.targetStdDev)/portofolioVariance),a)* - //System.Math.Pow(System.Math.Max(0.0,(portfolioRateOfReturn/this.targetPerformance)),b); - return returnValue; - } - - public Genome[] GetChilds(Genome parent1, Genome parent2) - { - return GenomeManagement.MixGenesWithoutDuplicates(parent1, parent2); - } - - public int GetNewGeneValue(Genome genome) - { - // in this implementation new gene values must be different from - // the others already stored in the given genome - int returnValue = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, - genome.MaxValueForGenes + 1); - while(genome.HasGene(returnValue)) - { - returnValue = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, - genome.MaxValueForGenes + 1); - } - - return returnValue; } - - public void Mutate(Genome genome, double mutationRate) - { - // in this implementation only one gene is mutated - // the new value has to be different from all the other genes of the genome - int newValueForGene = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, - genome.MaxValueForGenes +1); - int genePositionToBeMutated = GenomeManagement.RandomGenerator.Next(genome.Size); - while(genome.HasGene(newValueForGene)) - { - newValueForGene = GenomeManagement.RandomGenerator.Next(genome.MinValueForGenes, - genome.MaxValueForGenes +1); - } - GenomeManagement.MutateOneGene(genome, mutationRate, - genePositionToBeMutated, newValueForGene); - } ! public object Decode(Genome genome) { --- 37,62 ---- /// GeneticOptimizer /// </summary> ! public class GenomeManagerForEfficientCTOPortfolio : GenomeManagerForEfficientPortfolio { public GenomeManagerForEfficientCTOPortfolio(DataTable setOfInitialTickers, ! DateTime firstQuoteDate, ! DateTime lastQuoteDate, ! int numberOfTickersInPortfolio, ! int numDaysOfPortfolioLife, ! double targetPerformance) ! :base(setOfInitialTickers, ! firstQuoteDate, ! lastQuoteDate, ! numberOfTickersInPortfolio, ! numDaysOfPortfolioLife, ! targetPerformance) { } ! public override object Decode(Genome genome) { *************** *** 177,236 **** return returnValue; */ - - } - // end of implementation of IGenomeManager - - private double getPortfolioVariance(int[] tickerIdx) - { - double sumOfVariances = this.getSumOfVariances(tickerIdx); - double sumOfCovariances = this.getSumOfCovariances(tickerIdx); - double returnValue = sumOfVariances + sumOfCovariances; - return returnValue; - } - - private double getSumOfVariances(int[] tickerIdx) - { - double returnValue = 0; - double tickerCoeff = 1.0/this.genomeSize; - foreach(int idx in tickerIdx) - { - returnValue += BasicFunctions.Variance((float[])this.setOfTickers.Rows[idx]["ArrayOfCloseToOpenRates"]); - } - returnValue = returnValue * tickerCoeff * tickerCoeff; - return returnValue; } ! ! private double getSumOfCovariances(int[] tickerIdx) ! { ! double returnValue = 0; ! float[] ticker_i; ! float[] ticker_j; ! double tickerCoeff = 1/this.genomeSize; ! for(int i = 0; i<this.genomeSize ; i++) ! { ! ticker_i = (float[])this.setOfTickers.Rows[i]["ArrayOfCloseToOpenRates"]; ! for(int j = 0 ; j<this.genomeSize ; j++) ! { ! if(j != i) ! { ! ticker_j = (float[])this.setOfTickers.Rows[j]["ArrayOfCloseToOpenRates"]; ! returnValue += BasicFunctions.CoVariance(ticker_i, ticker_j); ! } ! } ! } ! returnValue = returnValue * tickerCoeff * tickerCoeff; ! return returnValue; ! } ! ! private void retrieveData() ! { ! foreach(DataRow row in this.setOfTickers.Rows) ! { ! float[] arrayOfCTORates = this.getArrayOfCTORates((string)row[0]); ! row["ArrayOfCloseToOpenRates"] = arrayOfCTORates; ! } ! } ! ! private float[] getArrayOfCTORates(string ticker) { Quotes tickerQuotes = new Quotes(ticker, this.firstQuoteDate, this.lastQuoteDate); --- 82,88 ---- return returnValue; */ } ! ! protected override float[] getArrayOfRatesOfReturn(string ticker) { Quotes tickerQuotes = new Quotes(ticker, this.firstQuoteDate, this.lastQuoteDate); *************** *** 238,253 **** } - - - private double getPortfolioRateOfReturn(int[] tickerIdx) - { - double returnValue = 0; - foreach(int idx in tickerIdx) - { - returnValue += (BasicFunctions.SimpleAverage((float[])this.setOfTickers.Rows[idx]["ArrayOfCloseToOpenRates"]) - 1); - } - //the investement is assumed to be equally divided - return (returnValue/this.GenomeSize); - } } --- 90,93 ---- |