[Quantproject-developers] QuantProject/b7_Scripts/TickerSelectionTesting/OTC_CTO/OTC_CTO_EOD OTC_C
Brought to you by:
glauco_1
|
From: Marco M. <mi...@us...> - 2011-01-16 19:38:29
|
Update of /cvsroot/quantproject/QuantProject/b7_Scripts/TickerSelectionTesting/OTC_CTO/OTC_CTO_EOD In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv30008/OTC_CTO/OTC_CTO_EOD Added Files: OTC_CTO_EODMain.cs OTC_CTO_EODStrategy.cs Log Message: Added script files for the OTC_CTO_EndOfDay strategy --- NEW FILE: OTC_CTO_EODMain.cs --- /* QuantProject - Quantitative Finance Library OTC_CTO_EODMain.cs Copyright (C) 2010 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.Collections.Generic; using System.IO; using QuantProject.ADT; using QuantProject.ADT.Statistics.Combinatorial; using QuantProject.ADT.FileManaging; using QuantProject.ADT.Timing; using QuantProject.Business.DataProviders; using QuantProject.Data.DataProviders.Bars.Caching; using QuantProject.Business.Strategies; using QuantProject.Business.Financial.Accounting.AccountProviding; using QuantProject.Business.Strategies.Eligibles; using QuantProject.Business.Strategies.EquityEvaluation; using QuantProject.Business.Strategies.InSample; using QuantProject.Business.Strategies.InSample.InSampleFitnessDistributionEstimation; using QuantProject.Business.Strategies.Logging; using QuantProject.Business.Strategies.Optimizing.Decoding; using QuantProject.Business.Strategies.Optimizing.GenomeManagers; using QuantProject.Business.Strategies.Optimizing.FitnessEvaluation; using QuantProject.Business.Strategies.ReturnsManagement; using QuantProject.Business.Strategies.ReturnsManagement.Time; using QuantProject.Business.Strategies.ReturnsManagement.Time.IntervalsSelectors; using QuantProject.Business.Timing; using QuantProject.Presentation; //using QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.InSampleChoosers; //using QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.Decoding; //using QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.FitnessEvaluators; using QuantProject.Scripts.TickerSelectionTesting.OTC.InSampleChoosers; using QuantProject.Scripts.General; using QuantProject.Scripts.General.Logging; using QuantProject.Scripts.General.Reporting; using QuantProject.Scripts.General.Strategies.Optimizing.FitnessEvaluation; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.Scripts.TickerSelectionTesting.OTC; using QuantProject.Scripts.TickerSelectionTesting.OTC.InSampleChoosers.Genetic; using QuantProject.Scripts.TickerSelectionTesting.OTC.InSampleChoosers.BruteForce; namespace QuantProject.Scripts.TickerSelectionTesting.OTC_CTO.OTC_CTO_EOD { /// <summary> /// Entry point for the OTC_CTO_EODMain. If any strategy /// parameter had to be changed, this is the place where it should /// be done /// </summary> public class OTC_CTO_EODMain : BasicScriptForBacktesting { private int numberOfPortfolioPositions; private PortfolioType portfolioType; private int maxNumberOfEligiblesToBeChosen; private Benchmark benchmark; private DateTime firstDateTime; private DateTime lastDateTime; List<Time> dailyTimes;//intraday times for barCache and Timer private Time nearToOpeningTimeFrom; private Time nearToOpeningTimeTo; private Time nearToClosingTimeFrom; private Time nearToClosingTimeTo; private HistoricalMarketValueProvider historicalMarketValueProviderForInSample; private HistoricalMarketValueProvider historicalMarketValueProviderForOutOfSample; private HistoricalMarketValueProvider historicalMarketValueProviderForTheBackTester; private Timer timerForBackTester; private GenomeManagerType genomeManagerType; #region main public OTC_CTO_EODMain() { this.numberOfPortfolioPositions = 3; // this.benchmark = new Benchmark( "CCE" ); this.portfolioType = PortfolioType.ShortAndLong;//filter for out of sample this.genomeManagerType = GenomeManagerType.ShortAndLong;//filter for the genetic chooser this.benchmark = new Benchmark( "ENI.MI" ); this.firstDateTime = new DateTime( 2001 , 1 , 1 ); this.lastDateTime = new DateTime( 2008 , 12, 31 ); //this.stepInMinutesForTimer = 1; // this.dailyTimes = Time.GetIntermediateTimes(new Time("09:30:00"), // new Time("16:00:00"), // this.stepInMinutesForTimer); this.dailyTimes = new List<Time>(); this.dailyTimes.Add(new Time("09:30:00")); this.dailyTimes.Add(new Time("16:00:00")); this.nearToOpeningTimeFrom = new Time("09:30:00"); this.nearToOpeningTimeTo = new Time("09:35:00"); this.nearToClosingTimeFrom = new Time("15:55:00"); this.nearToClosingTimeTo = new Time("16:00:00"); this.historicalMarketValueProviderForInSample = // new HistoricalRawQuoteProvider(); new HistoricalAdjustedQuoteProvider(); this.historicalMarketValueProviderForOutOfSample = // this.getHistoricalBarProvider(); this.historicalMarketValueProviderForInSample; // new HistoricalRawQuoteProvider(); this.historicalMarketValueProviderForTheBackTester = this.historicalMarketValueProviderForOutOfSample; //new HistoricalBarProvider( //new SimpleBarCache( intervalFrameInSeconds, //BarComponent.Open ) ); //ricordarsi di togliere - mettere //commento nel gestore evento tempo this.timerForBackTester = new IndexBasedEndOfDayTimer( this.firstDateTime, this.lastDateTime, this.benchmark.Ticker); // new IndexBasedHistoricalTimer(this.benchmark.Ticker, // this.firstDateTime, // this.lastDateTime , // this.dailyTimes, // this.intervalFrameInSeconds); } #endregion main #region eligiblesSelector protected override IEligiblesSelector getEligiblesSelector() { this.maxNumberOfEligiblesToBeChosen = 50; // string tickersGroupId = "SP500"; string tickersGroupId = "STOCKMI"; bool temporizedGroup = true; int numDaysForAverageRawOpenPriceComputation = 10; double minPrice = 0.50; double maxPrice = 200; // int maxNumberOfMostLiquidTickersToBeChosen = 150; // int numDaysForVolatility = 10; // IEligiblesSelector eligiblesSelector = // new ByPriceMostLiquidQuotedAtEachDateTime( // tickersGroupId , temporizedGroup , // maxNumberOfEligiblesToBeChosen , // numDaysForAverageRawOpenPriceComputation , // minPrice , maxPrice, intervalFrameInSeconds , // this.benchmark.Ticker ); // // IEligiblesSelector eligiblesSelector = // new ByPriceMostLiquidLessVolatileOTCAlwaysQuoted( // tickersGroupId , temporizedGroup , // maxNumberOfEligiblesToBeChosen , // maxNumberOfMostLiquidTickersToBeChosen , // numDaysForAverageRawOpenPriceComputation , // numDaysForVolatility , // minPrice , maxPrice ); IEligiblesSelector eligiblesSelector = new ByPriceMostLiquidAlwaysQuoted( tickersGroupId , temporizedGroup , maxNumberOfEligiblesToBeChosen , numDaysForAverageRawOpenPriceComputation , minPrice , maxPrice ); // IEligiblesSelector eligiblesSelector = // new ByPriceLessVolatileOTCAlwaysQuoted( // tickersGroupId , temporizedGroup , // maxNumberOfEligiblesToBeChosen , // numDaysForAverageRawOpenPriceComputation , // minPrice , maxPrice ); // eligiblesSelector = // new DummyEligibleSelector(); // return eligiblesSelector; } #endregion eligiblesSelector #region inSampleChooser protected override IInSampleChooser getInSampleChooser() { // Combination combinations; // if(this.genomeManagerType == GenomeManagerType.ShortAndLong || // this.genomeManagerType == GenomeManagerType.OnlyMixed) // combinations = new Combination(-this.maxNumberOfEligiblesToBeChosen, this.maxNumberOfEligiblesToBeChosen - 1, this.numberOfPortfolioPositions); // else // combinations = new Combination(0, this.maxNumberOfEligiblesToBeChosen - 1, this.numberOfPortfolioPositions); // // int numberOfBestTestingPositionsToBeReturned = // (int)combinations.TotalNumberOfCombinations; int numberOfBestTestingPositionsToBeReturned = 50; // parameters for the genetic optimizer double crossoverRate = 0.85; double mutationRate = 0.02; double elitismRate = 0.001; int populationSizeForGeneticOptimizer = 10000; int generationNumberForGeneticOptimizer = 30; int seedForRandomGenerator = QuantProject.ADT.ConstantsProvider.SeedForRandomGenerator; IDecoderForTestingPositions decoderForTestingPositions = new BasicDecoderForOTCPositions(); IFitnessEvaluator fitnessEvaluator = // new OTCFitnessEvaluator( new SharpeRatio() ); new OTCCTOFitnessEvaluator( new SharpeRatio() ); // new DummyRandomFitnessEvaluator(); // IInSampleChooser inSampleChooser = // new OTCIntradayGeneticChooser(numberOfBestTestingPositionsToBeReturned, // 1 , balancedWeightsOnVolatilityBase, // minimumAbsoluteReturnValue , maximumAbsoluteReturnValue, this.benchmark.Ticker); ADT.ConstantsProvider.AmountOfVariableWeightToBeAssignedToTickers = 0.40; IInSampleChooser inSampleChooser = new OTCEndOfDayGeneticChooser(this.numberOfPortfolioPositions, numberOfBestTestingPositionsToBeReturned, benchmark, decoderForTestingPositions , this.genomeManagerType , fitnessEvaluator , historicalMarketValueProviderForInSample, crossoverRate, mutationRate, elitismRate , populationSizeForGeneticOptimizer, generationNumberForGeneticOptimizer, seedForRandomGenerator); // new OTCEndOfDayGeneticChooserWithWeights(this.numberOfPortfolioPositions, numberOfBestTestingPositionsToBeReturned, // benchmark, // this.genomeManagerType , // fitnessEvaluator , // historicalMarketValueProviderForInSample, crossoverRate, // mutationRate, elitismRate , populationSizeForGeneticOptimizer, // generationNumberForGeneticOptimizer, seedForRandomGenerator); // IInSampleChooser inSampleChooser = // new OTCEndOfDayBruteForceChooser(this.portfolioType, // this.numberOfPortfolioPositions, // numberOfBestTestingPositionsToBeReturned, // this.benchmark, decoderForTestingPositions , fitnessEvaluator, // historicalMarketValueProviderForInSample); // //office // inSampleChooser = // new PVOChooserFromSavedBackTestLog( // @"C:\Utente\MarcoVarie\Vari\qP\LogArchive\2009_01_05_13_40_28_PVOIntraday_from_2006_01_01_to_2007_12_31_annlRtrn_17,84_maxDD_4,52\2009_01_05_13_40_28_PVOIntraday_from_2006_01_01_to_2007_12_31_annlRtrn_17,84_maxDD_4,52.qpL", // numberOfBestTestingPositionsToBeReturned); //home // inSampleChooser = // new PVOChooserFromSavedBackTestLog( // @"C:\Utente\MarcoVarie\Vari\qP\LogArchive\2009_01_01_18_57_36_PVOIntraday_from_2006_01_01_to_2007_12_31_annlRtrn_17.11_maxDD_3.80\2009_01_01_18_57_36_PVOIntraday_from_2006_01_01_to_2007_12_31_annlRtrn_17.11_maxDD_3.80.qpL", // numberOfBestTestingPositionsToBeReturned); return inSampleChooser; } #endregion inSampleChooser #region strategy protected override IStrategyForBacktester getStrategyForBacktester() { //int inSampleDays = 90; int inSampleDays = 90; int numDaysBetweenEachOptimization = 5; int numDaysBeforeCurrentDateForRetrievingInSampleData = 1; int minNumOfEligiblesForValidOptimization = 10; //disabilitato il controllo della fitness double minimumNumberOfStdDevForSignificantFitness = 0.0; double maximumNumberOfStdDevForSignificantFitness = 0.0; int sampleLengthForFitnessDistributionEstimation = 150; //disabilitato il controllo della fitness IInSampleFitnessDistributionEstimator estimator = new BasicInSampleFitnessDistributionEstimator(); GeneticChooser geneticChooserForEstimator = new OTCEndOfDayGeneticChooser(this.numberOfPortfolioPositions, 50, this.benchmark, new BasicDecoderForOTCPositions(), this.genomeManagerType , new OTCCTOFitnessEvaluator( new SharpeRatio() ) , historicalMarketValueProviderForInSample, 0.85, 0.01, 0.001 , 100, 0, QuantProject.ADT.ConstantsProvider.SeedForRandomGenerator); double stopLoss = 0.015; double takeProfit = 0.03; object[] daysForPlayingTheStrategy = new object[5]{ DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday}; IStrategyForBacktester strategyForBacktester // = new PVO_OTCStrategyLessCorrelated(eligiblesSelector ,inSampleChooser , // inSampleDays , benchmark , numDaysBetweenEachOptimization , // oversoldThreshold , overboughtThreshold , historicalQuoteProvider); // = new OTC_CTO_EODStrategy(eligiblesSelector , minNumOfEligiblesForValidOptimization, inSampleChooser , inSampleDays , benchmark , numDaysBetweenEachOptimization , numDaysBeforeCurrentDateForRetrievingInSampleData, historicalMarketValueProviderForInSample, historicalMarketValueProviderForOutOfSample, this.dailyTimes, this.nearToOpeningTimeFrom, this.nearToOpeningTimeTo, this.nearToClosingTimeFrom, this.nearToClosingTimeTo, stopLoss , takeProfit, this.portfolioType, geneticChooserForEstimator, minimumNumberOfStdDevForSignificantFitness, maximumNumberOfStdDevForSignificantFitness, estimator, sampleLengthForFitnessDistributionEstimation, daysForPlayingTheStrategy); // ((OTCIntradayStrategy)strategyForBacktester).FindPositionsForToday( // new DateTime(2009,9,1), new DateTime(2009,8,28) ); return strategyForBacktester; } #endregion strategy #region backTester protected override EndOfDayStrategyBackTester getEndOfDayStrategyBackTester() { string backTestId = "OTC_CTO_EODStrategy"; IAccountProvider accountProvider; accountProvider = new SimpleAccountProvider(); // accountProvider = // new FixedCommissionsAndSlippageAccountProvider(5.0, 0.0); // double fixedPercentageSlippage = 0.05; // accountProvider = // new InteractiveBrokerAccountProvider(fixedPercentageSlippage); double cashToStart = 10000; double maxRunningHours = 15; EndOfDayStrategyBackTester endOfDayStrategyBackTester = new EndOfDayStrategyBackTester( backTestId , this.timerForBackTester, this.strategyForBacktester , this.historicalMarketValueProviderForTheBackTester , accountProvider , firstDateTime , lastDateTime , this.benchmark , cashToStart , maxRunningHours ); return endOfDayStrategyBackTester; } #endregion backTester #region getHistoricalBarProvider #region getBarCache // private IBarCache getBarCache() // { // IBarCache barCache = new DailyBarCache( this.intervalFrameInSeconds , dailyTimes ); // return barCache; // } #endregion getBarCache // private HistoricalBarProvider getHistoricalBarProvider() // { // IBarCache barCache = getBarCache(); // HistoricalBarProvider historicalBarProvider = // new HistoricalBarProvider( barCache ); // return historicalBarProvider; // } #endregion getHistoricalBarProvider protected override string getCustomSmallTextForFolderName() { return "OTC_CTO_EODStrategy"; } protected override string getPathForTheMainFolderWhereScriptsResultsAreToBeSaved() { string pathForTheMainFolderWhereScriptsResultsAreToBeSaved = System.Configuration.ConfigurationManager.AppSettings["LogArchive"]; return pathForTheMainFolderWhereScriptsResultsAreToBeSaved; } protected override string getFullPathFileNameForMain() { string returnValue; string fullPathFileNameForMainAtHome = @"C:\Quant\QuantProject\b7_Scripts\TickerSelectionTesting\OTC_CTO\OTC_CTO_EOD\OTC_CTO_EODMain.cs"; if( File.Exists(fullPathFileNameForMainAtHome) ) returnValue = fullPathFileNameForMainAtHome; else returnValue = @"C:\Utente\MarcoVarie\Vari\qP\QuantProject\b7_Scripts\TickerSelectionTesting\OTC_CTO\OTC_CTO_EOD\OTC_CTO_EODMain.cs"; return returnValue; } } } --- NEW FILE: OTC_CTO_EODStrategy.cs --- /* QuantProject - Quantitative Finance Library OTC_CTO_EODStrategy.cs Copyright (C) 2010 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 System.Collections.Generic; using System.IO; using QuantProject.ADT; using QuantProject.ADT.Statistics; using QuantProject.ADT.Histories; using QuantProject.ADT.Messaging; using QuantProject.ADT.Timing; 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.Business.Strategies.InSample; using QuantProject.Business.Strategies.InSample.InSampleFitnessDistributionEstimation; using QuantProject.Business.Strategies.OutOfSample; using QuantProject.Business.Strategies.Logging; using QuantProject.Business.Strategies.ReturnsManagement; using QuantProject.Business.Strategies.ReturnsManagement.Time; using QuantProject.Business.DataProviders; using QuantProject.Business.Strategies.TickersRelationships; using QuantProject.Business.Strategies.Eligibles; using QuantProject.Business.Strategies.Optimizing.Decoding; using QuantProject.Data; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.Data.DataTables; using QuantProject.ADT.Optimizing.Genetic; using QuantProject.Scripts.TechnicalAnalysisTesting.Oscillators.FixedLevelOscillators.PortfolioValueOscillator.InSampleChoosers; using QuantProject.Scripts.TickerSelectionTesting.OTC; using QuantProject.Scripts.TickerSelectionTesting.OTC.InSampleChoosers; using QuantProject.Scripts.TickerSelectionTesting.OTC.InSampleChoosers.Genetic; using QuantProject.Scripts.TickerSelectionTesting.OTC.InSampleChoosers.BruteForce; using QuantProject.Scripts.TickerSelectionTesting.OTC.OTC_Intraday; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.Scripts.WalkForwardTesting.LinearCombination; namespace QuantProject.Scripts.TickerSelectionTesting.OTC_CTO.OTC_CTO_EOD { /// <summary> /// Implements the open to close - clos to open strategy (buy a portfolio at open /// and sell it at close and then reverse positions during night) /// using EOD quotes and reducing at minimum the number /// of trades required for playing it /// </summary> [Serializable] public class OTC_CTO_EODStrategy : IStrategyForBacktester { public event NewLogItemEventHandler NewLogItem; public event NewMessageEventHandler NewMessage; //initialized by the constructor protected int inSampleDays; protected int numDaysBetweenEachOptimization; protected int numDaysBeforeCurrentDateForRetrievingInSampleData; protected IInSampleChooser inSampleChooser; protected GeneticChooser geneticChooserForFitnessDistributionEstimator; protected double numberOfMinStdDeviationForOpeningPositions; protected double numberOfMaxStdDeviationForOpeningPositions; protected IEligiblesSelector eligiblesSelector; protected IInSampleFitnessDistributionEstimator estimator; protected int sampleLength; protected Benchmark benchmark; protected HistoricalMarketValueProvider historicalMarketValueProviderForInSample; protected HistoricalMarketValueProvider historicalMarketValueProviderForOutOfSample; //initialized after constructor's call protected int numDaysElapsedSinceLastOptimization; protected ReturnsManager returnsManager; protected TestingPositions[] chosenOTCPositions; //chosen in sample by the chooser or passed //directly by the user using a form: //these are the positions to test out of sample protected PortfolioType portfolioType; protected DateTime lastOptimizationDateTime; protected Account account; public Account Account { get { return this.account; } set { this.account = value; } } private int minimumNumberOfEligiblesForValidOptimization; // private bool optimalPositionsHaveBeenUpdated; protected int idxForBestPositionsCompatibleWithPortfolioType; protected EligibleTickers currentEligibles; protected bool stopLossConditionReached; protected bool takeProfitConditionReached; protected double maxOpeningLengthInMinutes; protected Time lastEntryTime; protected Time lastProfitOrLossTime; protected List<Time> openingTimesForAvailableBars; protected Time nearToOpeningTimeFrom; protected Time nearToOpeningTimeTo; protected Time nearToClosingTimeFrom; protected Time nearToClosingTimeTo; protected double currentAccountValue; protected double previousAccountValue; protected double stopLoss; protected double takeProfit; protected object[] daysForPlayingTheStrategy; protected Portfolio currentCTOPortfolio; protected Portfolio currentOTCPortfolio; private string description_GetDescriptionForChooser() { if(this.inSampleChooser == null) return "NoChooserDefined"; else return this.inSampleChooser.Description; } private Time getLastEventTimeWithCachedBars() { return this.openingTimesForAvailableBars[openingTimesForAvailableBars.Count - 1]; } private Time getFirstEventTimeWithCachedBars() { return this.openingTimesForAvailableBars[0]; } public string Description { get { string description = "OTC_CTO_EODStrategy"; return description; } } public bool StopBacktestIfMaxRunningHoursHasBeenReached { get { return true; } } private void otc_cto_EODStrategy_commonInitialization(IEligiblesSelector eligiblesSelector, int minimumNumberOfEligiblesForValidOptimization, int inSampleDays, Benchmark benchmark, int numDaysBetweenEachOptimization, int numDaysBeforeCurrentDateForRetrievingInSampleData, HistoricalMarketValueProvider historicalMarketValueProviderForInSample, HistoricalMarketValueProvider historicalMarketValueProviderForOutOfSample, List<Time> openingTimesForAvailableBars, Time nearToOpeningTimeFrom, Time nearToOpeningTimeTo, Time nearToClosingTimeFrom, Time nearToClosingTimeTo, double stopLoss, double takeProfit, PortfolioType portfolioType, GeneticChooser geneticChooserForFitnessDistributionEstimator, double numberOfMinimumStdDeviationForOpeningPositions, double numberOfMaxStdDeviationForOpeningPositions, IInSampleFitnessDistributionEstimator estimator, int sampleLength, object[] daysForPlayingTheStrategy) { this.eligiblesSelector = eligiblesSelector; this.minimumNumberOfEligiblesForValidOptimization = minimumNumberOfEligiblesForValidOptimization; this.inSampleDays = inSampleDays; this.benchmark = benchmark; this.idxForBestPositionsCompatibleWithPortfolioType = 0; this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; this.numDaysBeforeCurrentDateForRetrievingInSampleData = numDaysBeforeCurrentDateForRetrievingInSampleData; this.historicalMarketValueProviderForInSample = historicalMarketValueProviderForInSample; this.historicalMarketValueProviderForOutOfSample = historicalMarketValueProviderForOutOfSample; this.openingTimesForAvailableBars = openingTimesForAvailableBars; this.nearToOpeningTimeFrom = nearToOpeningTimeFrom; this.nearToOpeningTimeTo = nearToOpeningTimeTo; this.nearToClosingTimeFrom = nearToClosingTimeFrom; this.nearToClosingTimeTo = nearToClosingTimeTo; this.stopLoss = stopLoss; this.takeProfit = takeProfit; this.portfolioType = portfolioType; this.geneticChooserForFitnessDistributionEstimator = geneticChooserForFitnessDistributionEstimator; this.numberOfMinStdDeviationForOpeningPositions = numberOfMinimumStdDeviationForOpeningPositions; this.numberOfMaxStdDeviationForOpeningPositions = numberOfMaxStdDeviationForOpeningPositions; this.estimator = estimator; this.sampleLength = sampleLength; this.daysForPlayingTheStrategy = daysForPlayingTheStrategy; } public OTC_CTO_EODStrategy(IEligiblesSelector eligiblesSelector, int minimumNumberOfEligiblesForValidOptimization, IInSampleChooser inSampleChooser, int inSampleDays, Benchmark benchmark, int numDaysBetweenEachOptimization, int numDaysBeforeCurrentDateForRetrievingInSampleData, HistoricalMarketValueProvider historicalMarketValueProviderForInSample, HistoricalMarketValueProvider historicalMarketValueProviderForOutOfSample, List<Time> openingTimesForAvailableBars, Time nearToOpeningTimeFrom, Time nearToOpeningTimeTo, Time nearToClosingTimeFrom, Time nearToClosingTimeTo, double stopLoss, double takeProfit, PortfolioType portfolioType, GeneticChooser geneticChooserForFitnessDistributionEstimator, double numberOfMinimumStdDeviationForOpeningPositions, double numberOfMaxStdDeviationForOpeningPositions, IInSampleFitnessDistributionEstimator estimator, int sampleLength, object[] daysForPlayingTheStrategy) { this.inSampleChooser = inSampleChooser; this.otc_cto_EODStrategy_commonInitialization(eligiblesSelector, minimumNumberOfEligiblesForValidOptimization, inSampleDays, benchmark, numDaysBetweenEachOptimization, numDaysBeforeCurrentDateForRetrievingInSampleData, historicalMarketValueProviderForInSample, historicalMarketValueProviderForOutOfSample, openingTimesForAvailableBars, nearToOpeningTimeFrom, nearToOpeningTimeTo, nearToClosingTimeFrom, nearToClosingTimeTo, stopLoss, takeProfit, portfolioType, geneticChooserForFitnessDistributionEstimator, numberOfMinimumStdDeviationForOpeningPositions, numberOfMaxStdDeviationForOpeningPositions, estimator, sampleLength, daysForPlayingTheStrategy); } public OTC_CTO_EODStrategy(IEligiblesSelector eligiblesSelector, TestingPositions[] chosenOTCPositions, Benchmark benchmark, HistoricalMarketValueProvider historicalMarketValueProviderForInSample, HistoricalMarketValueProvider historicalMarketValueProviderForOutOfSample, List<Time> openingTimesForAvailableBars, double stopLoss, double takeProfit, PortfolioType portfolioType, GeneticChooser geneticChooserForFitnessDistributionEstimator, double numberOfMinimumStdDeviationForOpeningPositions, double numberOfMaxStdDeviationForOpeningPositions, IInSampleFitnessDistributionEstimator estimator, int sampleLength, object[] daysForPlayingTheStrategy) { this.chosenOTCPositions = chosenOTCPositions; this.otc_cto_EODStrategy_commonInitialization(eligiblesSelector, 5, 5, benchmark, numDaysBetweenEachOptimization, 0, historicalMarketValueProviderForInSample, historicalMarketValueProviderForOutOfSample, openingTimesForAvailableBars, nearToOpeningTimeFrom, nearToOpeningTimeTo, nearToClosingTimeFrom, nearToClosingTimeTo, stopLoss, takeProfit, portfolioType, geneticChooserForFitnessDistributionEstimator, numberOfMinimumStdDeviationForOpeningPositions, numberOfMaxStdDeviationForOpeningPositions, estimator, sampleLength, daysForPlayingTheStrategy); } private bool allTickersAreExchanged(DateTime dateTime, string[] tickers) { bool returnValue = true; try{ for( int i = 0; i < tickers.Length; i++ ) { if(!this.historicalMarketValueProviderForOutOfSample.WasExchanged( tickers[i], dateTime ) ) { returnValue = false; i = tickers.Length; //exit from for } } } catch(Exception ex){ string forBreakpoint = ex.Message; forBreakpoint = forBreakpoint + ""; returnValue = false; } return returnValue; } private bool allTickersAreExchangedInTheLastFiveMinutelyBars(DateTime fromDateTime, string[] tickers) { bool returnValue = true; Time lastFiveMinutelyBarTime = this.openingTimesForAvailableBars[this.openingTimesForAvailableBars.Count-1].AddMinutes(-5); try{ for( int i = 0; i < tickers.Length; i++ ) { Bars currentTickerBars = new Bars(tickers[i], Time.GetDateTimeFromMerge(fromDateTime, lastFiveMinutelyBarTime), Time.GetDateTimeFromMerge(fromDateTime, this.openingTimesForAvailableBars[this.openingTimesForAvailableBars.Count-1]), 60); if( currentTickerBars.Rows.Count < 1 ) { returnValue = false; i = tickers.Length; //exit from for } } } catch(Exception ex){ string forBreakpoint = ex.Message; forBreakpoint = forBreakpoint + ""; returnValue = false; } return returnValue; } #region newDateTimeEventHandler_closePositions private void newDateTimeEventHandler_closePositions(Time currentDailyTime) { if( allTickersAreExchanged( this.now(), AccountManager.GetTickersInOpenedPositions(this.account) ) ) { AccountManager.ClosePositions( this.account ); this.lastEntryTime = new Time("00:00:00"); } } #endregion newDateTimeEventHandler_closePositions private bool newDateTimeEventHandler_openPositions_bestFitnessIsSignificantlyHigh() { bool returnValue = false; double average, stdDev; if( this.geneticChooserForFitnessDistributionEstimator != null && this.estimator != null ) { average = estimator.GetAverage(this.geneticChooserForFitnessDistributionEstimator, this.currentEligibles, this.returnsManager, 100); stdDev = Math.Sqrt(estimator.GetVariance(this.geneticChooserForFitnessDistributionEstimator, this.currentEligibles, this.returnsManager, 100)); double bestFitness = this.chosenOTCPositions[idxForBestPositionsCompatibleWithPortfolioType].FitnessInSample; double minNumOfStdDev = this.numberOfMinStdDeviationForOpeningPositions; double maxNumOfStdDev = this.numberOfMaxStdDeviationForOpeningPositions; returnValue = bestFitness >= (average + minNumOfStdDev * stdDev) && bestFitness <= (average + maxNumOfStdDev * stdDev); } return returnValue; } #region newDateTimeEventHandler_openCTOPortfolio private void newDateTimeEventHandler_openCTOPortfolio(Time currentDailyTime) { if( this.chosenOTCPositions != null && this.allTickersAreExchanged( this.now(), this.chosenOTCPositions[0].WeightedPositions.SignedTickers.Tickers) // && // this.newDateTimeEventHandler_openPositions_bestFitnessIsSignificantlyHigh() // && this.newDateTimeEventHandler_openPositions_isTheRightDay() ) // && // this.allTickersAreExchangedInTheLastFiveMinutelyBars( this.now(), this.chosenOTCPositions[idxForBestPositionsCompatibleWithPortfolioType].WeightedPositions.SignedTickers.Tickers ) // ) { try { WeightedPositions oppositeWeightedPositions = this.chosenOTCPositions[0].WeightedPositions.Opposite; AccountManager.OpenPositions( oppositeWeightedPositions, this.account ); this.currentCTOPortfolio = this.account.Portfolio; this.lastEntryTime = currentDailyTime; this.previousAccountValue = this.account.GetMarketValue(); } catch(Exception ex) { string forBreakpoint = ex.Message; forBreakpoint = forBreakpoint + ""; } } } #endregion newDateTimeEventHandler_openCTOPortfolio #region newDateTimeEventHandler_openOTCPortfolio private void newDateTimeEventHandler_openOTCPortfolio(Time currentDailyTime) { if( this.chosenOTCPositions != null && this.allTickersAreExchanged( this.now(), this.chosenOTCPositions[0].WeightedPositions.SignedTickers.Tickers) ) { try { this.currentOTCPortfolio = new Portfolio(); foreach(Position position in this.currentCTOPortfolio.Values) { Position newOTCPosition = new Position(position.Instrument, - 2 * position.Quantity); OrderType orderTypeForNewOTCPosition; if(position.IsLong) orderTypeForNewOTCPosition = OrderType.MarketSellShort; else//position.IsShort orderTypeForNewOTCPosition = OrderType.MarketBuy; Order order = new Order(orderTypeForNewOTCPosition, position.Instrument, 2 * Math.Abs(position.Quantity)); this.account.AddOrder(order); this.currentOTCPortfolio.Add(position.Instrument.Key, newOTCPosition); } this.lastEntryTime = currentDailyTime; this.previousAccountValue = this.account.GetMarketValue(); } catch(Exception ex) { string forBreakpoint = ex.Message; forBreakpoint = forBreakpoint + ""; } } } #endregion newDateTimeEventHandler_openOTCPortfolio #region newDateTimeEventHandler_closeOTCPortfolio private void newDateTimeEventHandler_closeOTCPortfolio(Time currentDailyTime) { if( this.currentOTCPortfolio != null && this.allTickersAreExchanged( this.now(), this.chosenOTCPositions[0].WeightedPositions.SignedTickers.Tickers) ) { try { foreach(Position position in this.currentOTCPortfolio.Values) { OrderType orderTypeForClosingOTCPosition; if(position.IsLong) orderTypeForClosingOTCPosition = OrderType.MarketSellShort; else//position.IsShort orderTypeForClosingOTCPosition = OrderType.MarketBuy; Order order = new Order(orderTypeForClosingOTCPosition, position.Instrument, Math.Abs(position.Quantity)); this.account.AddOrder(order); } this.currentOTCPortfolio = null; this.previousAccountValue = this.account.GetMarketValue(); } catch(Exception ex) { string forBreakpoint = ex.Message; forBreakpoint = forBreakpoint + ""; } } } #endregion newDateTimeEventHandler_closeOTCPortfolio #region newDateTimeEventHandler_closeBothPortfolios private void newDateTimeEventHandler_closeBothPortfolios(Time currentDailyTime) { if( allTickersAreExchanged( this.now(), AccountManager.GetTickersInOpenedPositions(this.account) ) ) { try { AccountManager.ClosePositions( this.account ); this.lastEntryTime = new Time("00:00:00"); this.currentOTCPortfolio = null; this.currentCTOPortfolio = null; } catch(Exception ex) { string forBreakpoint = ex.Message; forBreakpoint = forBreakpoint + ""; } } } #endregion newDateTimeEventHandler_closeBothPortfolios #region newDateTimeEventHandler_updateStopLossAndTakeProfitConditions protected virtual void newDateTimeEventHandler_updateStopLossAndTakeProfitConditions(Time currentDailyTime) { //this.previousAccountValue has been set at opening positions this.stopLossConditionReached = false; this.takeProfitConditionReached = false; this.lastProfitOrLossTime = new Time("00:00:00"); if(this.account.Portfolio.Count > 0) { try{ this.currentAccountValue = this.account.GetMarketValue(); double portfolioGainOrLoss = (this.currentAccountValue - this.previousAccountValue) /this.previousAccountValue; if(!double.IsInfinity(portfolioGainOrLoss) && portfolioGainOrLoss <= -this.stopLoss ) { this.stopLossConditionReached = true; this.lastProfitOrLossTime = currentDailyTime; } else if (!double.IsInfinity(portfolioGainOrLoss) && portfolioGainOrLoss >= this.takeProfit ) { this.takeProfitConditionReached = true; this.lastProfitOrLossTime = currentDailyTime; } } catch(Exception ex) {string forBreakpoint = ex.Message; forBreakpoint = forBreakpoint + "";} } } #endregion newDateTimeEventHandler_updateStopLossAndTakeProfitConditions public virtual void NewDateTimeEventHandler( Object sender , DateTime dateTime ) { Time currentTime = new Time( dateTime ); bool nearToOpeningTime = currentTime >= this.nearToOpeningTimeFrom && currentTime <= this.nearToOpeningTimeTo; bool nearToClosingTime = currentTime >= this.nearToClosingTimeFrom && currentTime <= this.nearToClosingTimeTo; // this.newDateTimeEventHandler_updateStopLossAndTakeProfitConditions(currentTime); // bool timeToProfitOrToStopLoss = this.takeProfitConditionReached || // this.stopLossConditionReached; if( this.account.Portfolio.Count > 0 && nearToOpeningTime ) this.newDateTimeEventHandler_openOTCPortfolio(currentTime); if( this.account.Portfolio.Count > 0 && nearToClosingTime ) { if( this.optimalTestingPositionsAreToBeUpdated() ) { this.newDateTimeEventHandler_closeBothPortfolios(currentTime); this.updateTestingPositions( dateTime ); this.lastOptimizationDateTime = this.now(); } else this.newDateTimeEventHandler_closeOTCPortfolio(currentTime); } if( this.account.Portfolio.Count == 0 && nearToClosingTime ) this.newDateTimeEventHandler_openCTOPortfolio(currentTime); } #region FindPositionsForToday // private double[] findPositionsForToday_writePositionsToLogFile_getFitnesses(TestingPositions[] positionsToWrite) // { // int numOfValidFitnesses = 0; // double[] validFitnesses; // for(int i=0; i<positionsToWrite.Length; i++) // if( positionsToWrite[i] != null && // !double.IsInfinity(positionsToWrite[i].FitnessInSample) && // !double.IsNaN(positionsToWrite[i].FitnessInSample) && // positionsToWrite[i].FitnessInSample != double.MinValue ) // numOfValidFitnesses++; // // validFitnesses = new double[numOfValidFitnesses]; // int addedValidFitnesses = 0; // for(int i=0; i<positionsToWrite.Length; i++) // if( positionsToWrite[i] != null && // !double.IsInfinity(positionsToWrite[i].FitnessInSample) && // !double.IsNaN(positionsToWrite[i].FitnessInSample) && // positionsToWrite[i].FitnessInSample != double.MinValue ) // { // validFitnesses[addedValidFitnesses] = positionsToWrite[i].FitnessInSample; // addedValidFitnesses++; // } // return validFitnesses; // } private void findPositionsForToday_writePositionsToLogFile(DateTime today, EligibleTickers eligibles, TestingPositions[] positionsToWrite) { double averageRandomFitness = estimator.GetAverage(this.geneticChooserForFitnessDistributionEstimator, this.currentEligibles, this.returnsManager, this.sampleLength); double stdDevForRandomFitness = Math.Sqrt(estimator.GetVariance(this.geneticChooserForFitnessDistributionEstimator, this.currentEligibles, this.returnsManager, this.sampleLength)); string pathFile = System.Configuration.ConfigurationManager.AppSettings["LogArchive"] + "\\PositionsForOTCStrategyOn" + today.Day.ToString() + "_" + today.Month.ToString() + "_" + today.Year.ToString() + ".txt"; StreamWriter w = File.AppendText(pathFile); w.WriteLine ("\n----------------------------------------------\r\n"); w.Write("\r\nPositions for OTC Strategy on date: {0}\r", today.ToLongDateString() ); w.Write("\r\nNum days for optimization {0}\r", this.inSampleDays.ToString()); w.Write("\r\nEligibles: {0}\r", eligibles.Count.ToString() ); w.WriteLine ("\n----------------------------------------------"); // for(int i = 0; i<positionsToWrite.Length; i++) if(positionsToWrite[i] != null && positionsToWrite[i].FitnessInSample != double.MinValue) w.WriteLine("\n{0}-Positions: {1} --> fitness {2}", i.ToString(), positionsToWrite[i].WeightedPositions.Description, positionsToWrite[i].FitnessInSample.ToString() ); w.WriteLine ("\n\n----------------------------------------------"); w.WriteLine ("\n\nBest testing positions is {0}", this.idxForBestPositionsCompatibleWithPortfolioType.ToString()); w.Write("\r\nAverage random fitness (sample: {0}): {1}\r", this.sampleLength.ToString(), averageRandomFitness.ToString() ); w.Write("\r\nStandard deviation for random fitness: {0}\r", stdDevForRandomFitness.ToString()); w.Write("\r\nAverage + min num of std deviation ({0}) is: {1}\r", this.numberOfMinStdDeviationForOpeningPositions.ToString() , (averageRandomFitness + this.numberOfMinStdDeviationForOpeningPositions * stdDevForRandomFitness).ToString()); w.Write("\r\nAverage + max num of std deviation ({0}) is: {1}\r", this.numberOfMaxStdDeviationForOpeningPositions.ToString() , (averageRandomFitness + this.numberOfMaxStdDeviationForOpeningPositions * stdDevForRandomFitness).ToString()); // Update the underlying file. w.Flush(); w.Close(); } public void FindPositionsForToday(DateTime today, DateTime lastMarketDay) { History history = this.benchmark.GetEndOfDayHistory( HistoricalEndOfDayTimer.GetMarketOpen( lastMarketDay.AddDays( -this.inSampleDays ) ) , HistoricalEndOfDayTimer.GetMarketClose( lastMarketDay ) ); this.currentEligibles = this.eligiblesSelector.GetEligibleTickers(history); this.updateReturnsManager(history.FirstDateTime, history.LastDateTime); if( ( this.eligiblesSelector is DummyEligibleSelector && this.inSampleChooser != null ) || ( this.currentEligibles.Count > this.minimumNumberOfEligiblesForValidOptimization && this.inSampleChooser != null ) ) { this.chosenOTCPositions = (TestingPositions[])inSampleChooser.AnalyzeInSample(this.currentEligibles, this.returnsManager); // this.updateTestingPositions_updateIdxForBestPositionsCompatibleWithPortfolioType(); this.findPositionsForToday_writePositionsToLogFile(today, this.currentEligibles, this.chosenOTCPositions); this.chosenOTCPositions = null; } } #endregion FindPositionsForToday #region UpdateTestingPositions // private void updateTestingPositions_updateIdxForBestPositionsCompatibleWithPortfolioType() // { // for(int i = 0; i<this.chosenOTCPositions.Length; i++) // { // if(this.chosenOTCPositions[i] != null && // ( (this.chosenOTCPositions[i].BothLongAndShortPositions && // (this.portfolioType == PortfolioType.ShortAndLong || this.portfolioType == PortfolioType.OnlyMixed) ) || // (this.chosenOTCPositions[i].OnlyLongPositions && this.portfolioType == PortfolioType.OnlyLong) || // (this.chosenOTCPositions[i].OnlyShortPositions && this.portfolioType == PortfolioType.OnlyShort) ) ) // { // this.idxForBestPositionsCompatibleWithPortfolioType = i; // i = this.chosenOTCPositions.Length;//exit from for // } // } // } protected void updateTestingPositions(DateTime currentDateTime) { History history = this.benchmark.GetEndOfDayHistory( HistoricalEndOfDayTimer.GetMarketOpen( currentDateTime.AddDays( -this.inSampleDays ) ) , HistoricalEndOfDayTimer.GetMarketClose( currentDateTime.AddDays(-this.numDaysBeforeCurrentDateForRetrievingInSampleData) ) ); this.currentEligibles = this.eligiblesSelector.GetEligibleTickers(history); this.updateReturnsManager(history.FirstDateTime, history.LastDateTime); if( ( this.eligiblesSelector is DummyEligibleSelector && this.inSampleChooser != null ) || ( this.currentEligibles.Count > this.minimumNumberOfEligiblesForValidOptimization && this.inSampleChooser != null ) ) { this.chosenOTCPositions = (TestingPositions[])inSampleChooser.AnalyzeInSample(this.currentEligibles, this.returnsManager); // this.updateTestingPositions_updateIdxForBestPositionsCompatibleWithPortfolioType(); this.logOptimizationInfo(this.currentEligibles); } } private bool optimalTestingPositionsAreToBeUpdated() { bool areToBeUpdated = false; if(this.inSampleChooser != null) { DateTime dateTimeForNextOptimization = this.lastOptimizationDateTime.AddDays( this.numDaysBetweenEachOptimization ); areToBeUpdated = ( ( ( this.account.Portfolio.Count == 0 ) && ( ( this.lastOptimizationDateTime == DateTime.MinValue ) ) ) || ( this.now() >= dateTimeForNextOptimization ) ); } return areToBeUpdated; } // private void newDateTimeEventHandler_updateTestingPositions( // DateTime dateTime ) // { // if ( this.optimalTestingPositionsAreToBeUpdated() ) // { // this.updateTestingPositions( dateTime ); // this.lastOptimizationDateTime = this.now(); // } // } #endregion UpdateTestingPositions private DateTime now() { return this.account.Timer.GetCurrentDateTime(); } protected virtual void updateReturnsManager(DateTime firstDateTime, DateTime lastDayDateTime) { ReturnIntervals returnIntervals = // new DailyOpenToCloseIntervals( firstDateTime, lastDayDateTime, // this.benchmark.Ticker ); new OpenToCloseCloseToOpenIntervals( firstDateTime, lastDayDateTime, this.benchmark.Ticker ); this.returnsManager = new ReturnsManager( returnIntervals , this.historicalMarketValueProviderForInSample); } private OTCIntradayLogItem getLogItem( EligibleTickers eligibleTickers ) { OTCIntradayLogItem logItem = new OTCIntradayLogItem(this.now(), this.inSampleDays); logItem.BestOTCPositionsInSample = this.chosenOTCPositions; logItem.NumberOfEligibleTickers = eligibleTickers.Count; logItem.Fitness = this.chosenOTCPositions[idxForBestPositionsCompatibleWithPortfolioType].FitnessInSample; logItem.Generation = ((IGeneticallyOptimizable)this.chosenOTCPositions[idxForBestPositionsCompatibleWithPortfolioType]).Generation; logItem.Tickers = this.chosenOTCPositions[idxForBestPositionsCompatibleWithPortfolioType].HashCodeForTickerComposition; return logItem; } private void raiseNewLogItem( EligibleTickers eligibleTickers ) { OTCIntradayLogItem logItem = this.getLogItem( eligibleTickers ); NewLogItemEventArgs newLogItemEventArgs = new NewLogItemEventArgs( logItem ); this.NewLogItem( this , newLogItemEventArgs ); } private void notifyMessage( EligibleTickers eligibleTickers ) { string message = "Number of Eligible tickers: " + eligibleTickers.Count; NewMessageEventArgs newMessageEventArgs = new NewMessageEventArgs( message ); if ( this.NewMessage != null ) this.NewMessage( this , newMessageEventArgs ); } private void logOptimizationInfo( EligibleTickers eligibleTickers ) { if(eligibleTickers.Count > 0) this.raiseNewLogItem( eligibleTickers ); this.notifyMessage( eligibleTickers ); } } } |