[Quantproject-developers] QuantProject/b7_Scripts/TickerSelectionTesting/TestingOTCTypes/BruteForce
Brought to you by:
glauco_1
|
From: Marco M. <mi...@us...> - 2006-09-17 21:37:22
|
Update of /cvsroot/quantproject/QuantProject/b7_Scripts/TickerSelectionTesting/TestingOTCTypes/BruteForceOptimization In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv31050/b7_Scripts/TickerSelectionTesting/TestingOTCTypes/BruteForceOptimization Added Files: RunEfficientOTCTypesBruteForce.cs OTCBruteForceOptimizableParametersManager.cs EndOfDayTimerHandlerOTCTypesBruteForce.cs Log Message: Added the OTC - CTO strategy using a brute force optimizer. --- NEW FILE: OTCBruteForceOptimizableParametersManager.cs --- /* QuantProject - Quantitative Finance Library OTCBruteForceOptimizableParametersManager.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 QuantProject.ADT.Optimizing.BruteForce; using QuantProject.ADT.Statistics.Combinatorial; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; namespace QuantProject.Scripts.TickerSelectionTesting.TestingOTCTypes.BruteForceOptimization { /// <summary> /// This class implements IBruteForceOptimizableParametersManager, /// in order to find the best portfolio with respect /// to the OTC - CTO (open to close - close to open) strategy. /// Weights are NOT used in this implementation /// </summary> public class OTCBruteForceOptimizableParametersManager : IBruteForceOptimizableParametersManager { private Combination portfolioCombination; private int numberOfPortfolioPositions; private GenomeManagerForEfficientOTCCTOPortfolio otcCtoGenomeManager; private DataTable eligibleTickersForPortfolioPositions; public OTCBruteForceOptimizableParametersManager( DataTable eligibleTickersForPortfolioPositions , DateTime firstOptimizationDate , DateTime lastOptimizationDate , int numberOfPortfolioPositions ) { this.eligibleTickersForPortfolioPositions = eligibleTickersForPortfolioPositions; this.numberOfPortfolioPositions = numberOfPortfolioPositions; this.portfolioCombination = new Combination( - eligibleTickersForPortfolioPositions.Rows.Count , eligibleTickersForPortfolioPositions.Rows.Count - 1 , numberOfPortfolioPositions ); this.otcCtoGenomeManager = new GenomeManagerForEfficientOTCCTOPortfolio( eligibleTickersForPortfolioPositions , firstOptimizationDate , lastOptimizationDate , numberOfPortfolioPositions , 0.0, PortfolioType.ShortAndLong); } public bool MoveNext() { return this.portfolioCombination.MoveNext(); } public void Reset() { this.portfolioCombination.Reset(); } #region Current public object Current { get { return this.getCurrent(); } } private object getCurrent() { int[] currentValues = new int[ this.portfolioCombination.Length ]; for ( int i = 0 ; i < this.portfolioCombination.Length ; i ++ ) currentValues[ i ] = this.portfolioCombination.GetValue( i ); BruteForceOptimizableParameters bruteForceOptimizableParameters = new BruteForceOptimizableParameters( currentValues , this ); return bruteForceOptimizableParameters; } #endregion public object Decode( BruteForceOptimizableParameters bruteForceOptimizableItem ) { return this.otcCtoGenomeManager.Decode(bruteForceOptimizableItem); } public double GetFitnessValue( BruteForceOptimizableParameters bruteForceOptimizableItem ) { return this.otcCtoGenomeManager.GetFitnessValue(bruteForceOptimizableItem); } } } --- NEW FILE: EndOfDayTimerHandlerOTCTypesBruteForce.cs --- /* QuantProject - Quantitative Finance Library EndOfDayTimerHandlerOTCTypesBruteForce.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.Business.Strategies; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.ADT.Optimizing.Genetic; using QuantProject.ADT.Optimizing.BruteForce; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; namespace QuantProject.Scripts.TickerSelectionTesting.TestingOTCTypes.BruteForceOptimization { /// <summary> /// Implements MarketOpenEventHandler, /// MarketCloseEventHandler and OneHourAfterMarketCloseEventHandler /// These handlers run all the /// OTC strategy types after a common optimization, for testing purposes /// </summary> [Serializable] public class EndOfDayTimerHandlerOTCTypesBruteForce : EndOfDayTimerHandler { private int numDaysBetweenEachOptimization; private int numDaysElapsedSinceLastOptimization; private int seedForRandomGenerator; private Account[] accounts; private string[,] lastOrderedTickersForTheAccount; int numOfClosesWithOpenPositionsFor2DaysStrategy; public EndOfDayTimerHandlerOTCTypesBruteForce(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, string benchmark, int numDaysBetweenEachOptimization, Account[] accounts): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, 1, 100, benchmark, 0.0, PortfolioType.ShortAndLong) { this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; this.numDaysElapsedSinceLastOptimization = 0; this.seedForRandomGenerator = ConstantsProvider.SeedForRandomGenerator; this.accounts = accounts; this.lastOrderedTickersForTheAccount = new string[this.accounts.Length, this.numberOfTickersToBeChosen]; } private void openPositionsForTheAccountWhenPortfolioIsEmpty(int accountNumber) { if(this.accounts[accountNumber].Portfolio.Count == 0) { this.orders.Clear(); this.addChosenTickersToOrderListForTheGivenAccount(accountNumber); for(int i = 0; i<this.orders.Count;i++) { this.accounts[accountNumber].AddOrder((Order)this.orders[i]); this.lastOrderedTickersForTheAccount[accountNumber, i] = SignedTicker.GetTicker(((Order)this.orders[i]).Instrument.Key); } } } protected void addOrderForTickerForTheGivenAccount(int tickerPosition, int accountNumber ) { string tickerCode = GenomeManagerForEfficientPortfolio.GetCleanTickerCode(this.chosenTickers[tickerPosition]); double cashForSinglePosition = this.accounts[accountNumber].CashAmount * this.chosenTickersPortfolioWeights[tickerPosition]; long quantity = Convert.ToInt64( Math.Floor( cashForSinglePosition / this.accounts[accountNumber].DataStreamer.GetCurrentBid( tickerCode ) ) ); Order order; if(this.portfolioType == PortfolioType.OnlyShort || (this.portfolioType == PortfolioType.ShortAndLong && this.chosenTickers[tickerPosition] != tickerCode)) order = new Order( OrderType.MarketSellShort, new Instrument( tickerCode ) , quantity ); else order = new Order( OrderType.MarketBuy, new Instrument( tickerCode ) , quantity ); this.orders.Add(order); } protected void addChosenTickersToOrderListForTheGivenAccount(int accountNumber) { for( int i = 0; i<this.chosenTickers.Length; i++) { if(this.chosenTickers[i] != null) this.addOrderForTickerForTheGivenAccount( i, accountNumber ); } } private void closePositionsForTheAccount(int accountNumber) { string ticker; if(this.accounts[accountNumber].Portfolio.Count >0) { for(int j = 0; j<this.numberOfTickersToBeChosen; j++) { ticker = this.lastOrderedTickersForTheAccount[accountNumber, j]; if( ticker != null) { if(this.accounts[accountNumber].Portfolio[ticker]!=null) this.accounts[accountNumber].ClosePosition(ticker); } } } } private void marketCloseEventHandler_reversePositionsForTheAccount(int accountNumber) { this.closePositionsForTheAccount(accountNumber); SignedTicker.ChangeSignOfEachTicker(this.chosenTickers); try { this.openPositionsForTheAccountWhenPortfolioIsEmpty(accountNumber); } catch(Exception ex) { ex = ex; } finally { SignedTicker.ChangeSignOfEachTicker(this.chosenTickers); } } /// <summary> /// Handles a "Market Open" event. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> public override void MarketOpenEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { for(int i = 0; i<this.accounts.Length; i++) { //add cash first for each account if(this.orders.Count == 0 && this.accounts[i].Transactions.Count == 0) this.accounts[i].AddCash(30000); if(i<=1)//daily classical and multiday this.openPositionsForTheAccountWhenPortfolioIsEmpty(i); if(i==2)//for the CTO OTC { this.closePositionsForTheAccount(i); this.openPositionsForTheAccountWhenPortfolioIsEmpty(i); } if(i==3)//for the CTO, no position is opened //at market open. Any open position is closed, instead this.closePositionsForTheAccount(i); } } public override void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { if(this.accounts[1].Portfolio.Count > 0) numOfClosesWithOpenPositionsFor2DaysStrategy++; for(int i=0; i<this.accounts.Length; i++) { if(i==0)//OTC daily account this.closePositionsForTheAccount(i); if(i==1)//OTC 2 days { if(this.numOfClosesWithOpenPositionsFor2DaysStrategy == 2) { this.closePositionsForTheAccount(i); this.numOfClosesWithOpenPositionsFor2DaysStrategy = 0; } } if(i>=2)//for the OTC-CTO and CTO this.marketCloseEventHandler_reversePositionsForTheAccount(i); } } #region OneHourAfterMarketCloseEventHandler protected DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { SelectorByGroup temporizedGroup = new SelectorByGroup(this.tickerGroupID, currentDate); DataTable tickersFromGroup = temporizedGroup.GetTableOfSelectedTickers(); SelectorByAverageRawOpenPrice byPrice = new SelectorByAverageRawOpenPrice(tickersFromGroup,false,currentDate, currentDate.AddDays(-30), tickersFromGroup.Rows.Count, 20,500, 0.0001,100); SelectorByLiquidity mostLiquidSelector = new SelectorByLiquidity(byPrice.GetTableOfSelectedTickers(), false,currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers); SelectorByQuotationAtEachMarketDay quotedAtEachMarketDayFromMostLiquid = new SelectorByQuotationAtEachMarketDay(mostLiquidSelector.GetTableOfSelectedTickers(), false, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers, this.benchmark); return quotedAtEachMarketDayFromMostLiquid.GetTableOfSelectedTickers(); } private double[] setTickers_getWeights(string[] tickers) { double[] returnValue = new double[tickers.Length]; for(int i = 0;i<tickers.Length; i++) returnValue[i] = 1.0/tickers.Length; return returnValue; } protected virtual void setTickers(DateTime currentDate, bool setGenomeCounter) { DataTable setOfTickersToBeOptimized = this.getSetOfTickersToBeOptimized(currentDate); if(setOfTickersToBeOptimized.Rows.Count > this.chosenTickers.Length*2) //the optimization process is possible only if the initial set of tickers is //as large as the number of tickers to be chosen { OTCBruteForceOptimizableParametersManager otcBruteForceParamManager = new OTCBruteForceOptimizableParametersManager( setOfTickersToBeOptimized, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate,this.chosenTickers.Length); BruteForceOptimizer BFO = new BruteForceOptimizer(otcBruteForceParamManager); BFO.Run(); this.chosenTickers = ((GenomeMeaning)otcBruteForceParamManager.Decode(BFO.BestParameters)).Tickers; //this.setTickers_getChosenTickers(BFO.BestParameters); this.addGenomeToBestGenomes(BFO.BestParameters,this.chosenTickers, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate,setOfTickersToBeOptimized.Rows.Count); this.chosenTickersPortfolioWeights = this.setTickers_getWeights(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 override void OneHourAfterMarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.seedForRandomGenerator++; this.orders.Clear(); if(this.numDaysElapsedSinceLastOptimization == this.numDaysBetweenEachOptimization - 1) { this.setTickers(endOfDayTimingEventArgs.EndOfDayDateTime.DateTime, false); //sets tickers to be chosen at next Market Open event this.numDaysElapsedSinceLastOptimization = 0; } else { this.numDaysElapsedSinceLastOptimization++; } } #endregion } } --- NEW FILE: RunEfficientOTCTypesBruteForce.cs --- /* QuantProject - Quantitative Finance Library RunEfficientOTCTypesBruteForce.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.ADT.Optimizing.BruteForce; using QuantProject.ADT.FileManaging; 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.Business.Financial.Accounting.Commissions; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.Presentation.Reporting.WindowsForm; using QuantProject.Scripts.WalkForwardTesting.LinearCombination; namespace QuantProject.Scripts.TickerSelectionTesting.TestingOTCTypes.BruteForceOptimization { /// <summary> /// Script to test OTC daily, OTC multiday and OTC - CTO /// all together with one brute force optimization and 3 accounts (each for /// each type of strategy) /// </summary> [Serializable] public class RunEfficientOTCTypesBruteForce : RunEfficientPortfolio { protected int numDaysBetweenEachOptimization; private Account[] accounts; public RunEfficientOTCTypesBruteForce(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, string benchmark, DateTime startDate, DateTime endDate, double maxRunningHours, int numDaysBetweenEachOptimization): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, 1,100, benchmark, startDate, endDate, 0.0, PortfolioType.ShortAndLong, maxRunningHours) { this.ScriptName = "OTC_SR_PriceSelBruteForce"; this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; this.accounts = new Account[4]; } #region auxiliary overriden methods for Run protected override void run_initializeAccount() { for(int i = 0; i<this.accounts.Length; i++) { this.accounts[i] = new Account( this.ScriptName, this.endOfDayTimer , new HistoricalEndOfDayDataStreamer( this.endOfDayTimer , this.historicalQuoteProvider ) , new HistoricalEndOfDayOrderExecutor( this.endOfDayTimer , this.historicalQuoteProvider )); } } protected override void run_initializeEndOfDayTimerHandler() { this.endOfDayTimerHandler = new EndOfDayTimerHandlerOTCTypesBruteForce(this.tickerGroupID, this.numberOfEligibleTickers, this.numberOfTickersToBeChosen, this.numDaysForOptimizationPeriod, this.benchmark, this.numDaysBetweenEachOptimization, this.accounts); } protected override void run_initializeHistoricalQuoteProvider() { //this.historicalQuoteProvider = new HistoricalRawQuoteProvider(); this.historicalQuoteProvider = new HistoricalAdjustedQuoteProvider(); } protected override void run_addEventHandlers() { 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 ); } #endregion //necessary far calling RunEfficientPortfolio.Run() //in classes that inherit from this class public override void Run() { base.Run(); } public override void SaveScriptResults() { string fileName = "From"+this.numberOfEligibleTickers + "OptDays" + this.numDaysForOptimizationPeriod + "Portfolio" + this.numberOfTickersToBeChosen + "BruteForce"; string dirNameWhereToSaveAccounts = System.Configuration.ConfigurationSettings.AppSettings["AccountsArchive"] + "\\" + this.ScriptName + "\\"; string dirNameWhereToSaveTransactions = System.Configuration.ConfigurationSettings.AppSettings["TransactionsArchive"] + "\\" + this.ScriptName + "\\"; string dirNameWhereToSaveBestGenomes = System.Configuration.ConfigurationSettings.AppSettings["GenomesArchive"] + "\\" + this.ScriptName + "\\"; this.checkDateForReport_createDirIfNotPresent(dirNameWhereToSaveAccounts); this.checkDateForReport_createDirIfNotPresent(dirNameWhereToSaveTransactions); this.checkDateForReport_createDirIfNotPresent(dirNameWhereToSaveBestGenomes); for(int i = 0; i<this.accounts.Length; i++) { ObjectArchiver.Archive(accounts[i], dirNameWhereToSaveAccounts + fileName + "#" + i.ToString() + ".qPa"); ObjectArchiver.Archive(this.accounts[i].Transactions, dirNameWhereToSaveTransactions + fileName + "#" + i.ToString() + ".qPt"); } OptimizationOutput optimizationOutput = new OptimizationOutput(); foreach(GenomeRepresentation genomeRepresentation in this.endOfDayTimerHandler.BestGenomes) optimizationOutput.Add(genomeRepresentation); ObjectArchiver.Archive(optimizationOutput, dirNameWhereToSaveBestGenomes + fileName + ".bgn"); this.endOfDayTimer.Stop(); } } } |