[Quantproject-developers] QuantProject/b7_Scripts/TickerSelectionTesting/SimpleSelection RunSimpleSe
Brought to you by:
glauco_1
|
From: Marco M. <mi...@us...> - 2005-10-21 17:54:22
|
Update of /cvsroot/quantproject/QuantProject/b7_Scripts/TickerSelectionTesting/SimpleSelection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15209 Added Files: RunSimpleSelectionOpenToClose.cs RunSimpleSelection.cs EndOfDayTimerHandlerSimpleSelectionOpenToClose.cs EndOfDayTimerHandlerSimpleSelection.cs CandidatePropertiesForSimpleSelection.cs BestTickersScreenerOpenToClose.cs BestTickersScreener.cs Log Message: Added files for SimpleSelection script --- NEW FILE: EndOfDayTimerHandlerSimpleSelection.cs --- /* QuantProject - Quantitative Finance Library EndOfDayTimerHandlerSimpleSelection.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.Data.DataTables; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; namespace QuantProject.Scripts.TickerSelectionTesting.SimpleSelection { /// <summary> /// Base class for EndOfDayTimerHandlers for simple selection /// </summary> [Serializable] public class EndOfDayTimerHandlerSimpleSelection { protected DataTable eligibleTickers; protected string[] chosenTickers; protected string[] lastOrderedTickers; protected string tickerGroupID; protected int numberOfEligibleTickers; protected int numberOfTickersToBeChosen; protected int numDaysForOptimizationPeriod; protected Account account; protected ArrayList orders; protected string benchmark; //these two values have to be updated during //backtest, for minimizing commission amount, //according to broker's commission scheme protected double minPriceForMinimumCommission = 0; protected double maxPriceForMinimumCommission = 500; protected double targetReturn; protected PortfolioType portfolioType; public string[] LastOrderedTickers { get { return this.lastOrderedTickers; } } public int NumberOfEligibleTickers { get { return this.numberOfEligibleTickers; } } public Account Account { get { return this.account; } } public EndOfDayTimerHandlerSimpleSelection(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, Account account, string benchmark, double targetReturn, PortfolioType portfolioType) { this.tickerGroupID = tickerGroupID; this.numberOfEligibleTickers = numberOfEligibleTickers; this.numberOfTickersToBeChosen = numberOfTickersToBeChosen; this.numDaysForOptimizationPeriod = numDaysForOptimizationPeriod; this.account = account; this.benchmark = benchmark; this.orders = new ArrayList(); this.chosenTickers = new string[numberOfTickersToBeChosen]; this.lastOrderedTickers = new string[numberOfTickersToBeChosen]; this.targetReturn = targetReturn; this.portfolioType = portfolioType; } protected virtual void addOrderForTicker(string ticker ) { string tickerCode = GenomeManagerForEfficientPortfolio.GetCleanTickerCode(ticker); double cashForSinglePosition = this.account.CashAmount / this.numberOfTickersToBeChosen; long quantity = Convert.ToInt64( Math.Floor( cashForSinglePosition / this.account.DataStreamer.GetCurrentBid( tickerCode ) ) ); Order order; if(this.portfolioType == PortfolioType.OnlyShort || (this.portfolioType == PortfolioType.ShortAndLong && ticker != 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 virtual void closePosition( string ticker ) { this.account.ClosePosition( ticker ); } protected virtual void closePositions() { if(this.lastOrderedTickers != null) { foreach( string ticker in this.lastOrderedTickers) { for(int i = 0; i<this.account.Portfolio.Keys.Count; i++) { if(this.account.Portfolio[ticker]!=null) closePosition( ticker ); } } } } protected virtual void addChosenTickersToOrderList() { int idx = 0; foreach ( string ticker in this.chosenTickers ) { if(ticker != null) { this.addOrderForTicker( ticker ); this.lastOrderedTickers[idx] = GenomeManagerForEfficientPortfolio.GetCleanTickerCode(ticker); } idx++; } } protected bool openPositions_allChosenTickersQuotedAtCurrentDate() { bool returnValue = true; DateTime currentDate = this.Account.EndOfDayTimer.GetCurrentTime().DateTime; foreach(string ticker in this.chosenTickers) { if(ticker != null) { Quotes tickerQuotes = new Quotes(GenomeManagerForEfficientPortfolio.GetCleanTickerCode(ticker), currentDate, currentDate); if(tickerQuotes.Rows.Count == 0) //no quote available for the current ticker returnValue = false; } } return returnValue; } protected virtual void openPositions() { //add cash first if(this.orders.Count == 0 && this.account.Transactions.Count == 0) this.account.AddCash(17000); if(this.openPositions_allChosenTickersQuotedAtCurrentDate()) //all tickers have quotes at the current date, so orders can be filled { this.addChosenTickersToOrderList(); //execute orders actually foreach(object item in this.orders) this.account.AddOrder((Order)item); } } public virtual void MarketOpenEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { ; } public virtual void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { ; } public virtual void OneHourAfterMarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { ; } } // end of class } --- NEW FILE: BestTickersScreenerOpenToClose.cs --- /* QuantProject - Quantitative Finance Library BestTickersScreenerOpenToClose.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.Data; using QuantProject.Data.DataTables; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; namespace QuantProject.Scripts.TickerSelectionTesting.SimpleSelection { /// <summary> /// Class for tickers' selection without combination /// Open to close /// </summary> [Serializable] public class BestTickersScreenerOpenToClose : BestTickersScreener { public BestTickersScreenerOpenToClose(DataTable setOfInitialTickers, DateTime firstQuoteDate, DateTime lastQuoteDate, double targetPerformance, PortfolioType portfolioType): base(setOfInitialTickers, firstQuoteDate, lastQuoteDate, targetPerformance, portfolioType) { this.retrieveData(); } protected override float[] getArrayOfRatesOfReturn(string ticker) { Quotes tickerQuotes = new Quotes(ticker, this.firstQuoteDate, this.lastQuoteDate); return ExtendedDataTable.GetRatesOfReturnsFromColumns(tickerQuotes, "quClose", "quOpen"); } } } --- NEW FILE: CandidatePropertiesForSimpleSelection.cs --- /* QuantProject - Quantitative Finance Library CandidatePropertiesForSimpleSelection.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 QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.ADT.Statistics; namespace QuantProject.Scripts.TickerSelectionTesting.SimpleSelection { /// <summary> /// This is the class containing basic information /// for each candidate to be evaluated for the simple selection script /// </summary> [Serializable] public class CandidatePropertiesForSimpleSelection : CandidateProperties { private double targetPerformance; public CandidatePropertiesForSimpleSelection(string ticker, float[] arrayOfRatesOfReturn, double targetPerformance): base(ticker, arrayOfRatesOfReturn) { this.targetPerformance = targetPerformance; } public override void setFitness() { NormalDistribution normal = new NormalDistribution(BasicFunctions.SimpleAverage(this.ArrayOfRatesOfReturn), BasicFunctions.StdDev(this.ArrayOfRatesOfReturn)); this.fitness = 1-normal.GetProbability(this.targetPerformance); } } } --- NEW FILE: RunSimpleSelection.cs --- /* QuantProject - Quantitative Finance Library RunSimpleSelection.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.IO; using System.Collections; using System.Data; using System.Windows.Forms; using QuantProject.ADT; 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; namespace QuantProject.Scripts.TickerSelectionTesting.SimpleSelection { /// <summary> /// Base class for simple selection test /// The strategy simply chooses the tickers with the highest fitness, /// for short or long trading /// </summary> [Serializable] public class RunSimpleSelection { protected string tickerGroupID; protected int numberOfEligibleTickers; protected int numberOfTickersToBeChosen; protected int numDaysForOptimizationPeriod; protected ReportTable reportTable; protected EndOfDayDateTime startDateTime; protected EndOfDayDateTime endDateTime; protected IHistoricalQuoteProvider historicalQuoteProvider; protected EndOfDayTimerHandlerSimpleSelection endOfDayTimerHandler; protected Account account; protected IEndOfDayTimer endOfDayTimer; protected string benchmark; protected string scriptName; protected double targetReturn; protected PortfolioType portfolioType; protected DateTime startingTimeForScript; protected double maxRunningHours; //if MaxNumberOfHoursForScript has elapsed and the script //is still running, it will be stopped. public string[] LastOrderedTickers { get { return this.endOfDayTimerHandler.LastOrderedTickers; } } public PortfolioType TypeOfPortfolio { get { return this.portfolioType; } } public virtual string ScriptName { get{return this.scriptName;} set{this.scriptName = value;} } public DateTime TimerLastDate { get{return this.endOfDayTimer.GetCurrentTime().DateTime ;} } public RunSimpleSelection(string benchmark, DateTime startDate, DateTime endDate, PortfolioType portfolioType, double maxRunningHours) { this.startDateTime = new EndOfDayDateTime( startDate, EndOfDaySpecificTime.FiveMinutesBeforeMarketClose ); this.endDateTime = new EndOfDayDateTime( endDate, EndOfDaySpecificTime.OneHourAfterMarketClose ); this.benchmark = benchmark; this.ScriptName = "SimpleTestGeneric"; this.portfolioType = portfolioType; this.startingTimeForScript = DateTime.Now; this.maxRunningHours = maxRunningHours; //this.numIntervalDays = 3; } public RunSimpleSelection(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, string benchmark, DateTime startDate, DateTime endDate, double targetReturn, PortfolioType portfolioType, double maxRunningHours) { //this.progressBarForm = new ProgressBarForm(); this.tickerGroupID = tickerGroupID; this.numberOfEligibleTickers = numberOfEligibleTickers; this.numberOfTickersToBeChosen = numberOfTickersToBeChosen; this.numDaysForOptimizationPeriod = numDaysForOptimizationPeriod; this.reportTable = new ReportTable( "Summary_Reports" ); this.startDateTime = new EndOfDayDateTime( startDate, EndOfDaySpecificTime.FiveMinutesBeforeMarketClose ); this.endDateTime = new EndOfDayDateTime( endDate, EndOfDaySpecificTime.OneHourAfterMarketClose ); this.benchmark = benchmark; this.ScriptName = "SimpleTestGeneric"; this.targetReturn = targetReturn; this.portfolioType = portfolioType; this.startingTimeForScript = DateTime.Now; this.maxRunningHours = maxRunningHours; //this.numIntervalDays = 3; } #region Run protected virtual void run_initializeEndOfDayTimer() { //default endOfDayTimer this.endOfDayTimer = new IndexBasedEndOfDayTimer( this.startDateTime, this.benchmark ); } protected virtual void run_initializeAccount() { //default account with no commissions this.account = new Account( this.scriptName , this.endOfDayTimer , new HistoricalEndOfDayDataStreamer( this.endOfDayTimer , this.historicalQuoteProvider ) , new HistoricalEndOfDayOrderExecutor( this.endOfDayTimer , this.historicalQuoteProvider )); } protected virtual void run_initializeEndOfDayTimerHandler() { //always needs specific implementation in inherited classes; } protected virtual void run_initializeHistoricalQuoteProvider() { //always needs specific implementation in inherited classes; } protected void checkDateForReport_createDirIfNotPresent(string dirPath) { if(!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); } protected virtual void checkDateForReport(Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs) { if(endOfDayTimingEventArgs.EndOfDayDateTime.DateTime>=this.endDateTime.DateTime || DateTime.Now >= this.startingTimeForScript.AddHours(this.maxRunningHours)) //last date is reached by the timer or maxRunning hours //are elapsed from the time script started this.SaveScriptResults(); } public virtual void SaveScriptResults() { string fileName = "SimpleSelectionFrom"+this.numberOfEligibleTickers + "OptDays" + this.numDaysForOptimizationPeriod + "Portfolio" + this.numberOfTickersToBeChosen + "Target" + Convert.ToString(this.targetReturn) + Convert.ToString(this.portfolioType); string dirNameWhereToSaveReports = System.Configuration.ConfigurationSettings.AppSettings["ReportsArchive"] + "\\" + this.ScriptName + "\\"; string dirNameWhereToSaveTransactions = System.Configuration.ConfigurationSettings.AppSettings["TransactionsArchive"] + "\\" + this.ScriptName + "\\"; //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.checkDateForReport_createDirIfNotPresent(dirNameWhereToSaveTransactions); ObjectArchiver.Archive(this.account.Transactions, dirNameWhereToSaveTransactions + fileName + ".qPt"); // this.endOfDayTimer.Stop(); } protected virtual void run_initialize() { run_initializeHistoricalQuoteProvider(); run_initializeEndOfDayTimer(); run_initializeAccount(); run_initializeEndOfDayTimerHandler(); //run_initializeProgressHandlers(); } protected virtual void run_addEventHandlers() { this.endOfDayTimer.MarketClose += new MarketCloseEventHandler( this.checkDateForReport); //in inherited classes'override method: //add here TimerHandler's handlers to timer's events //example //this.endOfDayTimer.EVENT_NAME += // new EVENT_NAMEEventHandler( // this.endOfDayTimerHandler.EVENT_NAMEEventHandler); } public virtual void Run() { this.run_initialize(); this.run_addEventHandlers(); //this.progressBarForm.Show(); this.endOfDayTimer.Start(); } #endregion } } --- NEW FILE: BestTickersScreener.cs --- /* QuantProject - Quantitative Finance Library BestTickersScreener.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.Data; using QuantProject.Data.DataTables; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; namespace QuantProject.Scripts.TickerSelectionTesting.SimpleSelection { /// <summary> /// Base class for tickers' selection without combination /// </summary> [Serializable] public class BestTickersScreener { protected DataTable setOfTickers;//used only for keeping //the same signature for //protected retrieveData() method protected CandidatePropertiesForSimpleSelection[] setOfCandidates; protected DateTime firstQuoteDate; protected DateTime lastQuoteDate; protected double targetPerformance; protected PortfolioType portfolioType; //setOfInitialTickers has to contain the //ticker's symbol in the first column ! public BestTickersScreener(DataTable setOfInitialTickers, DateTime firstQuoteDate, DateTime lastQuoteDate, double targetPerformance, PortfolioType portfolioType) { this.setOfTickers = setOfInitialTickers; if ( setOfInitialTickers.Rows.Count == 0 ) throw new Exception( "setOfInitialTickers cannot be empty!" ); this.firstQuoteDate = firstQuoteDate; this.lastQuoteDate = lastQuoteDate; this.targetPerformance = targetPerformance; this.portfolioType = portfolioType; } //this protected method has to be called by inherited classes //(open to close or close to close) //only after all initializations provided //by their respective constructors protected void retrieveData() { this.setOfCandidates = new CandidatePropertiesForSimpleSelection[setOfTickers.Rows.Count]; for(int i = 0; i<setOfTickers.Rows.Count; i++) { string ticker = (string)setOfTickers.Rows[i][0]; this.setOfCandidates[i] = new CandidatePropertiesForSimpleSelection(ticker, this.getArrayOfRatesOfReturn(ticker), this.targetPerformance); } } //this protected method must be overriden by inherited classes //specifing the type of rates of return that have to //be analyzed protected virtual float[] getArrayOfRatesOfReturn(string ticker) { float[] returnValue = null; return returnValue; } private void setSetOfCandidates(bool longRatesOfReturn) { for(int i = 0; i<this.setOfCandidates.Length;i++) { this.setOfCandidates[i].LongRatesOfReturn = longRatesOfReturn; this.setOfCandidates[i].setFitness(); } Array.Sort(this.setOfCandidates); } private void getBestTickers_setReturnValueForOnlyLong(string[] returnValue) { this.setSetOfCandidates(true); for(int i = 0; i<returnValue.Length;i++) //the last items of the array are the best tickers for long trades returnValue[i] = this.setOfCandidates[this.setOfCandidates.Length - i - 1].Ticker; } private void getBestTickers_setReturnValueForOnlyShort(string[] returnValue) { this.setSetOfCandidates(true); for(int i = 0; i<returnValue.Length;i++) //the first items of the array are surely the best tickers for short trades returnValue[i] = "-" + this.setOfCandidates[i].Ticker; } /*OLD IMPLEMENTATION: HALF SHORT HALF LONG private void getBestTickers_setReturnValueForShortAndLong(string[] returnValue) { this.getBestTickers_setReturnValueForOnlyLong(returnValue); //the first half is for long tickers int numberOfTickersForShort = returnValue.Length / 2; for(int i = 0; i<numberOfTickersForShort;i++) returnValue[i] = "-" + this.setOfCandidates[i].Ticker; //the second half is for short tickers (if returnValue.Length is //odd, n° of short tickers = n° of long tickers - 1 } */ //new implementation tickers with highest fitness, //short or long private void getBestTickers_setReturnValueForShortAndLong(string[] returnValue) { CandidateProperties[] allTickersShortOrLong = new CandidateProperties[this.setOfCandidates.Length * 2]; int numOfTickers = this.setOfCandidates.Length; this.setSetOfCandidates(true); for(int i = 0; i<numOfTickers; i++) allTickersShortOrLong[i] = new CandidateProperties(this.setOfCandidates[i].Ticker, this.setOfCandidates[i].ArrayOfRatesOfReturn); this.setSetOfCandidates(false); for(int i = numOfTickers; i<numOfTickers*2; i++) allTickersShortOrLong[i] = new CandidateProperties("-" + this.setOfCandidates[i].Ticker, this.setOfCandidates[i].ArrayOfRatesOfReturn); Array.Sort(allTickersShortOrLong); for(int i = 0; i<returnValue.Length; i++) returnValue[i] = allTickersShortOrLong[i].Ticker; } /// <summary> /// It gets best tickers for trading /// If PortfolioType is ShortAndLong, half of numberOfTickers is for short and /// the remaining half for long. Tickers for short trading are signed! /// </summary> public string[] GetBestTickers(int numberOfTickers) { string[] returnValue = new string[numberOfTickers]; if(this.portfolioType == PortfolioType.OnlyLong) this.getBestTickers_setReturnValueForOnlyLong(returnValue); else if(this.portfolioType == PortfolioType.OnlyShort) this.getBestTickers_setReturnValueForOnlyShort(returnValue); else if(this.portfolioType == PortfolioType.ShortAndLong) this.getBestTickers_setReturnValueForShortAndLong(returnValue); return returnValue; } } } --- NEW FILE: RunSimpleSelectionOpenToClose.cs --- /* QuantProject - Quantitative Finance Library RunSimpleSelectionOpenToClose.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.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; namespace QuantProject.Scripts.TickerSelectionTesting.SimpleSelection { /// <summary> /// Script to buy at open and sell at close (within the same day) /// the tickers with the highest fitness, for short or long trade /// </summary> [Serializable] public class RunSimpleSelectionOpenToClose : RunSimpleSelection { protected int numDaysBetweenEachOptimization; public RunSimpleSelectionOpenToClose(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, string benchmark, DateTime startDate, DateTime endDate, double targetReturn, PortfolioType portfolioType, double maxRunningHours, int numDaysBetweenEachOptimization): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, benchmark, startDate, endDate, targetReturn, portfolioType, maxRunningHours) { this.ScriptName = "SimpleSelectionOpenToClose"; this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; } #region auxiliary overriden methods for Run /* delete remark delimitations for having ib commission protected override void run_initializeAccount() { this.account = new Account( this.ScriptName , this.endOfDayTimer , new HistoricalEndOfDayDataStreamer( this.endOfDayTimer , this.historicalQuoteProvider ) , new HistoricalEndOfDayOrderExecutor( this.endOfDayTimer , this.historicalQuoteProvider ), new IBCommissionManager()); } */ protected override void run_initializeEndOfDayTimerHandler() { this.endOfDayTimerHandler = new EndOfDayTimerHandlerSimpleSelectionOpenToClose(this.tickerGroupID, this.numberOfEligibleTickers, this.numberOfTickersToBeChosen, this.numDaysForOptimizationPeriod, this.account, this.benchmark, this.targetReturn, this.portfolioType, this.numDaysBetweenEachOptimization); } 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 public override void SaveScriptResults() { string fileName = "SimpleOTCDailySelectionFrom"+this.numberOfEligibleTickers + "OptDays" + this.numDaysForOptimizationPeriod + "Portfolio" + this.numberOfTickersToBeChosen + "Target" + Convert.ToString(this.targetReturn) + Convert.ToString(this.portfolioType); string dirNameWhereToSaveReports = System.Configuration.ConfigurationSettings.AppSettings["ReportsArchive"] + "\\" + this.ScriptName + "\\"; string dirNameWhereToSaveTransactions = System.Configuration.ConfigurationSettings.AppSettings["TransactionsArchive"] + "\\" + this.ScriptName + "\\"; //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.checkDateForReport_createDirIfNotPresent(dirNameWhereToSaveTransactions); ObjectArchiver.Archive(this.account.Transactions, dirNameWhereToSaveTransactions + fileName + ".qPt"); // this.endOfDayTimer.Stop(); } //necessary far calling RunEfficientPortfolio.Run() //in classes that inherit from this class public override void Run() { base.Run(); } } } --- NEW FILE: EndOfDayTimerHandlerSimpleSelectionOpenToClose.cs --- /* QuantProject - Quantitative Finance Library EndOfDayTimerHandlerSimpleSelectionOpenToClose.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.Data.DataTables; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; namespace QuantProject.Scripts.TickerSelectionTesting.SimpleSelection { /// <summary> /// Base class for EndOfDayTimerHandlers for simple selection /// </summary> [Serializable] public class EndOfDayTimerHandlerSimpleSelectionOpenToClose : EndOfDayTimerHandlerSimpleSelection { protected int numDaysBetweenEachOptimization; private int numDaysElapsedSinceLastOptimization; public EndOfDayTimerHandlerSimpleSelectionOpenToClose(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, Account account, string benchmark, double targetReturn, PortfolioType portfolioType, int numDaysBetweenEachOptimization): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, account, benchmark, targetReturn, portfolioType) { this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; this.numDaysElapsedSinceLastOptimization = 0; } public override void MarketOpenEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.openPositions(); } public override void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.closePositions(); } #region OneHourAfterMarketCloseEventHandler protected DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { /* SelectorByAverageRawOpenPrice selectorByOpenPrice = new SelectorByAverageRawOpenPrice(this.tickerGroupID, false, currentDate.AddDays(-this.numDaysForLiquidity), currentDate, this.numberOfEligibleTickers, this.minPriceForMinimumCommission, this.maxPriceForMinimumCommission, 0, 2); DataTable tickersByPrice = selectorByOpenPrice.GetTableOfSelectedTickers(); */ SelectorByGroup temporizedGroup = new SelectorByGroup(this.tickerGroupID, currentDate); SelectorByOpenCloseCorrelationToBenchmark lessCorrelatedFromTemporizedGroup = new SelectorByOpenCloseCorrelationToBenchmark(temporizedGroup.GetTableOfSelectedTickers(), this.benchmark,true, currentDate.AddDays(-this.numDaysForOptimizationPeriod ), currentDate, this.numberOfEligibleTickers); this.eligibleTickers = lessCorrelatedFromTemporizedGroup.GetTableOfSelectedTickers(); SelectorByQuotationAtEachMarketDay quotedAtEachMarketDayFromEligible = new SelectorByQuotationAtEachMarketDay( this.eligibleTickers, false, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers, this.benchmark); //SelectorByWinningOpenToClose winners = // new SelectorByWinningOpenToClose(quotedAtEachMarketDayFromMostLiquid.GetTableOfSelectedTickers(), // false, currentDate.AddDays(-2), // currentDate, this.numberOfEligibleTickers/4); //return winners.GetTableOfSelectedTickers(); //SelectorByOpenCloseCorrelationToBenchmark lessCorrelated = // new SelectorByOpenCloseCorrelationToBenchmark(quotedAtEachMarketDayFromEligible.GetTableOfSelectedTickers(), // this.benchmark, true, // currentDate.AddDays(-this.numDaysForLiquidity), // currentDate, this.numberOfEligibleTickers/2); return quotedAtEachMarketDayFromEligible.GetTableOfSelectedTickers(); //return lessCorrelated.GetTableOfSelectedTickers(); } protected virtual void setTickers(DateTime currentDate) { 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 { BestTickersScreenerOpenToClose OTCScreener = new BestTickersScreenerOpenToClose(setOfTickersToBeOptimized, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.targetReturn, this.portfolioType); this.chosenTickers = OTCScreener.GetBestTickers(this.numberOfTickersToBeChosen); } //else it will be buyed again the previous optimized portfolio //that's it the actual chosenTickers member } protected void oneHourAfterMarketCloseEventHandler_updatePrices() { //min price for minimizing commission amount //according to IB Broker's commission scheme this.minPriceForMinimumCommission = this.account.CashAmount/(this.numberOfTickersToBeChosen*100); this.maxPriceForMinimumCommission = this.maxPriceForMinimumCommission; //just to avoid warning message } /// <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.orders.Clear(); //this.oneHourAfterMarketCloseEventHandler_updatePrices(); if(this.numDaysElapsedSinceLastOptimization == this.numDaysBetweenEachOptimization - 1) { this.setTickers(endOfDayTimingEventArgs.EndOfDayDateTime.DateTime); //sets tickers to be chosen next Market Open event this.numDaysElapsedSinceLastOptimization = 0; } else { this.numDaysElapsedSinceLastOptimization++; } } #endregion } // end of class } |