[Quantproject-developers] QuantProject/b7_Scripts/TechnicalAnalysisTesting/TrendFollowing/OTC_CTOTr
Brought to you by:
glauco_1
Update of /cvsroot/quantproject/QuantProject/b7_Scripts/TechnicalAnalysisTesting/TrendFollowing/OTC_CTOTrendFollower In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv7029/b7_Scripts/TechnicalAnalysisTesting/TrendFollowing/OTC_CTOTrendFollower Added Files: EndOfDayTimerHandlerOTC_CTOTrendFollower.cs RunEfficientOTC_CTOTrendFollower.cs Log Message: Added strategy based on the hypothesis that portofolios optimized with respect to the Open to Close and Close to Open strategy follow an upward trend for some days ahead (out of sample) --- NEW FILE: EndOfDayTimerHandlerOTC_CTOTrendFollower.cs --- /* QuantProject - Quantitative Finance Library EndOfDayTimerHandlerOTC_CTOTrendFollower.cs Copyright (C) 2007 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.Strategies; using QuantProject.Business.Timing; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.ADT.Optimizing.Genetic; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; namespace QuantProject.Scripts.TechnicalAnalysisTesting.TrendFollowing.OTC_CTOTrendFollower { /// <summary> /// Implements MarketOpenEventHandler, /// TwoMinutesBeforeMarketCloseEventHandler and OneHourAfterMarketCloseEventHandler /// These handlers contain the core strategy for the efficient close to open portfolio! /// </summary> [Serializable] public class EndOfDayTimerHandlerOTC_CTOTrendFollower : EndOfDayTimerHandler { protected int seedForRandomGenerator; private double stopLossLevel; private double accountValueAtOpeningPositions; public EndOfDayTimerHandlerOTC_CTOTrendFollower(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, Account account, int generationNumberForGeneticOptimizer, int populationSizeForGeneticOptimizer, string benchmark, double targetReturn, double stopLossLevel, PortfolioType portfolioType, int numDaysBetweenEachOptimization): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, account, generationNumberForGeneticOptimizer, populationSizeForGeneticOptimizer, benchmark, targetReturn, portfolioType) { this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; this.numDaysElapsedSinceLastOptimization = 0; this.seedForRandomGenerator = ConstantsProvider.SeedForRandomGenerator; this.stopLossLevel = stopLossLevel; } /// <summary> /// Handles a "Market Open" event. /// </summary> /// <param name="sender"></param> /// <param name="eventArgs"></param> public override void MarketOpenEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { if(this.account.Transactions.Count == 0) this.account.AddCash(15000); if(this.account.Portfolio.Count == 0) { AccountManager.OpenPositions(this.chosenWeightedPositions, this.account); this.accountValueAtOpeningPositions = this.account.GetMarketValue(); } } private void marketCloseEventHandler_updateTakeProfitCondition() { if( (this.currentAccountValue - this.accountValueAtOpeningPositions)/ this.accountValueAtOpeningPositions > this.targetReturn ) this.takeProfitConditionReached = true; else this.takeProfitConditionReached = false; } private void marketCloseEventHandler_updateStopLossCondition() { if( (this.currentAccountValue - this.accountValueAtOpeningPositions)/ this.accountValueAtOpeningPositions < -this.stopLossLevel ) this.stopLossConditionReached = true; else this.stopLossConditionReached = false; } public override void MarketCloseEventHandler( Object sender , EndOfDayTimingEventArgs endOfDayTimingEventArgs ) { this.currentAccountValue = this.account.GetMarketValue(); this.marketCloseEventHandler_updateStopLossCondition(); this.marketCloseEventHandler_updateTakeProfitCondition(); if( (this.numDaysElapsedSinceLastOptimization == this.numDaysBetweenEachOptimization - 1) || this.stopLossConditionReached || this.takeProfitConditionReached ) AccountManager.ClosePositions(this.account); } #region OneHourAfterMarketCloseEventHandler protected DataTable getSetOfTickersToBeOptimized(DateTime currentDate) { SelectorByGroup temporizedGroup = new SelectorByGroup(this.tickerGroupID, currentDate); DataTable tickersFromGroup = temporizedGroup.GetTableOfSelectedTickers(); SelectorByLiquidity mostLiquid = new SelectorByLiquidity(tickersFromGroup, false,currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers); SelectorByQuotationAtEachMarketDay quotedAtEachMarketDayFromMostLiquid = new SelectorByQuotationAtEachMarketDay(mostLiquid.GetTableOfSelectedTickers(), false, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfEligibleTickers, this.benchmark); SelectorByAverageRawOpenPrice byPrice = new SelectorByAverageRawOpenPrice(quotedAtEachMarketDayFromMostLiquid.GetTableOfSelectedTickers(), false,currentDate.AddDays(-30), currentDate, this.numberOfEligibleTickers, 20); DataTable tickersByPrice = byPrice.GetTableOfSelectedTickers(); SelectorByOpenCloseCorrelationToBenchmark tickersLessCorrelatedToBenchmark = new SelectorByOpenCloseCorrelationToBenchmark(tickersByPrice, "^GSPC",true, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, tickersByPrice.Rows.Count/2); return tickersLessCorrelatedToBenchmark.GetTableOfSelectedTickers(); } protected virtual void setTickers(DateTime currentDate, bool setGenomeCounter) { DataTable setOfTickersToBeOptimized = this.getSetOfTickersToBeOptimized(currentDate); if(setOfTickersToBeOptimized.Rows.Count > this.numberOfTickersToBeChosen*2) //the optimization process is possible only if the initial set of tickers is //as large as the number of tickers to be chosen { IGenomeManager genManEfficientOTCPortfolio = new GenomeManagerForEfficientOTCCTOPortfolio(setOfTickersToBeOptimized, currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, this.numberOfTickersToBeChosen, this.targetReturn, this.portfolioType); GeneticOptimizer GO = new GeneticOptimizer(genManEfficientOTCPortfolio, this.populationSizeForGeneticOptimizer, this.generationNumberForGeneticOptimizer, this.seedForRandomGenerator); if(setGenomeCounter) this.genomeCounter = new GenomeCounter(GO); GO.CrossoverRate = 0.0; GO.MutationRate = 0.70; GO.Run(false); this.addGenomeToBestGenomes(GO.BestGenome,currentDate.AddDays(-this.numDaysForOptimizationPeriod), currentDate, setOfTickersToBeOptimized.Rows.Count); this.chosenWeightedPositions = new WeightedPositions( ((GenomeMeaning)GO.BestGenome.Meaning).TickersPortfolioWeights, new SignedTickers( ((GenomeMeaning)GO.BestGenome.Meaning).Tickers) ); } //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.seedForRandomGenerator++; //this.oneHourAfterMarketCloseEventHandler_updatePrices(); if( (this.numDaysElapsedSinceLastOptimization == this.numDaysBetweenEachOptimization - 1) || this.account.Portfolio.Count == 0 ) //it is time to optimize again or //portfolio is empty { this.setTickers(endOfDayTimingEventArgs.EndOfDayDateTime.DateTime, false); //sets tickers to be chosen next Market Open event this.numDaysElapsedSinceLastOptimization = 0; } else { this.numDaysElapsedSinceLastOptimization++; } } #endregion } } --- NEW FILE: RunEfficientOTC_CTOTrendFollower.cs --- /* QuantProject - Quantitative Finance Library RunEfficientOTC_CTOTrendFollower.cs Copyright (C) 2007 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.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.Business.Financial.Accounting.Slippage; using QuantProject.Data.DataProviders; using QuantProject.Data.Selectors; using QuantProject.Scripts.TickerSelectionTesting.EfficientPortfolios; using QuantProject.Presentation.Reporting.WindowsForm; namespace QuantProject.Scripts.TechnicalAnalysisTesting.TrendFollowing.OTC_CTOTrendFollower { /// <summary> /// Script that aims to anticipate the growing trend /// of a portfolio using the OTC_CTO indicator /// In other words: if a portfolio, in sample, has a /// a good performance with the OTC_CTO strategy, then it should /// gain also (we hope ...) out of sample /// </summary> [Serializable] public class RunEfficientOTC_CTOTrendFollower : RunEfficientPortfolio { protected int numDaysBetweenEachOptimization; private double stopLossLevel; public RunEfficientOTC_CTOTrendFollower(string tickerGroupID, int numberOfEligibleTickers, int numberOfTickersToBeChosen, int numDaysForOptimizationPeriod, int generationNumberForGeneticOptimizer, int populationSizeForGeneticOptimizer, string benchmark, DateTime startDate, DateTime endDate, double targetReturn, double stopLossLevel, PortfolioType portfolioType, double maxRunningHours, int numDaysBetweenEachOptimization): base(tickerGroupID, numberOfEligibleTickers, numberOfTickersToBeChosen, numDaysForOptimizationPeriod, generationNumberForGeneticOptimizer, populationSizeForGeneticOptimizer, benchmark, startDate, endDate, targetReturn, portfolioType, maxRunningHours) { //this.ScriptName = "OTC_CTOTrendFollowerSharpeRatioNoCoeff"; this.ScriptName = "OTC_CTOTrendFollowerSharpeRatioWithCoeffOnlyMutation"; this.numDaysBetweenEachOptimization = numDaysBetweenEachOptimization; this.stopLossLevel = stopLossLevel; } // delete remark delimitations for having ib commission // and a fixed percentage calculation of slippage 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 FixedPercentageSlippageManager(this.historicalQuoteProvider, // this.endOfDayTimer,0.08)), ); //new IBCommissionManager()); } protected override void run_initializeEndOfDayTimerHandler() { this.endOfDayTimerHandler = new EndOfDayTimerHandlerOTC_CTOTrendFollower(this.tickerGroupID, this.numberOfEligibleTickers, this.numberOfTickersToBeChosen, this.numDaysForOptimizationPeriod, this.account, this.generationNumberForGeneticOptimizer, this.populationSizeForGeneticOptimizer, this.benchmark, this.targetReturn, this.stopLossLevel, 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 ); } //necessary far calling RunEfficientPortfolio.Run() //in classes that inherit from this class public override void Run() { base.Run(); } } } |