From 90c4acb55a11c682a7717e858e93d47aef184dfa Mon Sep 17 00:00:00 2001 From: Sean Date: Mon, 31 Mar 2025 15:23:18 -0400 Subject: [PATCH] Optimizations --- .../MarketDataLib/DataAccess/PortfolioDA.cs | 43 +++++++ .../MarketDataLib/DataAccess/PricingDA.cs | 49 ++++++++ .../GainLoss/GainLossSummaryItemCollection.cs | 116 +++++++++++------- 3 files changed, 162 insertions(+), 46 deletions(-) diff --git a/MarketData/MarketDataLib/DataAccess/PortfolioDA.cs b/MarketData/MarketDataLib/DataAccess/PortfolioDA.cs index 69ff829..35c558b 100755 --- a/MarketData/MarketDataLib/DataAccess/PortfolioDA.cs +++ b/MarketData/MarketDataLib/DataAccess/PortfolioDA.cs @@ -139,6 +139,48 @@ namespace MarketData.DataAccess if(null!=sqlTransaction) sqlTransaction.Dispose(); } } + + public static Dictionary HasStopLimit(List symbols) + { + MySqlConnection sqlConnection=null; + MySqlDataReader sqlDataReader=null; + MySqlCommand sqlCommand=null; + Dictionary hasStopLimit = new Dictionary(); + + try + { + StringBuilder sb=new StringBuilder(); + if(null==symbols) return null; + sqlConnection=SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data")); + sb.Append("select symbol, count(*) from stoplimits "); + sb.Append("where symbol in "); + sb.Append(SqlUtils.CreateInClause(symbols)); + sb.Append(" and active=1 group by 1"); + String strQuery=sb.ToString(); + sqlCommand=new MySqlCommand(strQuery,sqlConnection); + sqlCommand.CommandTimeout=SqlUtils.COMMAND_TIMEOUT; + sqlDataReader=sqlCommand.ExecuteReader(); + while(sqlDataReader.Read()) + { + String symbol = sqlDataReader.GetString(0); + symbol = symbol.ToUpper(); + hasStopLimit.Add(symbol, true); + } + return hasStopLimit; + } + catch(Exception exception) + { + MDTrace.WriteLine(LogLevel.DEBUG,exception); + return null; + } + finally + { + if(null!=sqlCommand) sqlCommand.Dispose(); + if(null!=sqlDataReader) sqlDataReader.Close(); + if(null!=sqlConnection) sqlConnection.Close(); + } + } + public static bool HasStopLimit(String symbol) { MySqlConnection sqlConnection=null; @@ -153,6 +195,7 @@ namespace MarketData.DataAccess sqlConnection=SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("portfolio_data")); sb.Append("select count(*) from stoplimits "); sb.Append("where symbol='").Append(symbol).Append("'"); + sb.Append(" and active=1"); strQuery=sb.ToString(); sqlCommand=new MySqlCommand(strQuery,sqlConnection); sqlCommand.CommandTimeout=SqlUtils.COMMAND_TIMEOUT; diff --git a/MarketData/MarketDataLib/DataAccess/PricingDA.cs b/MarketData/MarketDataLib/DataAccess/PricingDA.cs index 065ce33..da4bf35 100755 --- a/MarketData/MarketDataLib/DataAccess/PricingDA.cs +++ b/MarketData/MarketDataLib/DataAccess/PricingDA.cs @@ -10,6 +10,7 @@ namespace MarketData.DataAccess { public class PricingDA { + public static readonly int ForwardLookingDays = 90; private PricingDA() { } @@ -628,6 +629,52 @@ namespace MarketData.DataAccess if (null != sqlConnection) sqlConnection.Close(); } } + + public static Dictionary GetNamesForSymbols(List symbols) + { + MySqlConnection sqlConnection = null; + MySqlDataReader sqlDataReader = null; + MySqlCommand sqlCommand=null; + String strQuery = null; + Dictionary dictionary = new Dictionary(); + + try + { + StringBuilder sb = new StringBuilder(); + sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data")); + sb.Append("select symbol, company from securitymaster where symbol in "); + sb.Append(SqlUtils.CreateInClause(symbols)); + sb.Append(";"); + strQuery = sb.ToString(); ; + sqlCommand = new MySqlCommand(strQuery, sqlConnection); + sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT; + sqlDataReader = sqlCommand.ExecuteReader(); + while (sqlDataReader.Read()) + { + String symbol = sqlDataReader.GetString(0); + String companyName = sqlDataReader.GetString(1); + if(null==companyName || null==symbol)continue; + companyName=companyName.ToUpper(); + symbol = symbol.ToUpper(); + if(dictionary.ContainsKey(symbol))continue; + dictionary.Add(symbol,companyName); + } + return dictionary; + } + catch (Exception exception) + { + MDTrace.WriteLine(LogLevel.DEBUG,exception); + MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Query was {0}",strQuery)); + return null; + } + finally + { + if(null!=sqlCommand)sqlCommand.Dispose(); + if (null != sqlDataReader) sqlDataReader.Close(); + if (null != sqlConnection) sqlConnection.Close(); + } + } + public static String GetNameForSymbol(String symbol) { MySqlConnection sqlConnection = null; @@ -1117,6 +1164,7 @@ namespace MarketData.DataAccess // Get prices starting at "startDate" and "days" number of days going into future public static Prices GetPricesForward(String symbol,DateTime startDate,int days) { + Profiler profiler = new Profiler(); MySqlConnection sqlConnection=null; MySqlDataReader sqlDataReader=null; MySqlCommand sqlCommand=null; @@ -1166,6 +1214,7 @@ namespace MarketData.DataAccess if(null!=sqlCommand) sqlCommand.Dispose(); if(null!=sqlDataReader) sqlDataReader.Close(); if(null!=sqlConnection) sqlConnection.Close(); + MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[GetPricesForward] Done, took {0}(ms)",profiler.End())); } } public static Prices GetPricesOnOrBefore(String symbol,DateTime startDate) diff --git a/MarketData/MarketDataLib/MarketDataModel/GainLoss/GainLossSummaryItemCollection.cs b/MarketData/MarketDataLib/MarketDataModel/GainLoss/GainLossSummaryItemCollection.cs index 6cff020..4f34039 100755 --- a/MarketData/MarketDataLib/MarketDataModel/GainLoss/GainLossSummaryItemCollection.cs +++ b/MarketData/MarketDataLib/MarketDataModel/GainLoss/GainLossSummaryItemCollection.cs @@ -19,66 +19,89 @@ namespace MarketData.MarketDataModel.GainLoss } public GainLossSummaryItemCollection(PortfolioTrades portfolioTrades,ITotalGainLossGenerator gainLossGenerator,IActiveGainLossGenerator activeGainLossGenerator,DateTime? maxDateRef=null) { - List symbols=portfolioTrades.Symbols; + Profiler profiler = new Profiler(); - if(null==gainLossGenerator || null==activeGainLossGenerator)return; - - foreach(String symbol in symbols) + try { - PortfolioTrades portfolioTradesSymbol=portfolioTrades.FilterSymbol(symbol); - GainLossCollection gainLossCollection=activeGainLossGenerator.GenerateGainLoss(portfolioTradesSymbol,maxDateRef); + List symbols=portfolioTrades.Symbols; + if(null==gainLossGenerator || null==activeGainLossGenerator)return; - TotalGainLossCollection totalGainLossCollection=gainLossGenerator.GenerateTotalGainLoss(portfolioTradesSymbol,maxDateRef); - GainLossCompoundModelCollection gainLossCompoundModelCollection=new GainLossCompoundModelCollection(gainLossCollection,totalGainLossCollection); + Dictionary companyNames = PricingDA.GetNamesForSymbols(symbols); + Dictionary stopLimits = PortfolioDA.HasStopLimit(symbols); - if(1>gainLossCompoundModelCollection.Count) continue; - GainLossSummaryItem gainLossSummaryItem=new GainLossSummaryItem(); - gainLossSummaryItem.Date=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].Date; - gainLossSummaryItem.Symbol=symbol; - gainLossSummaryItem.CompanyName=PricingDA.GetNameForSymbol(symbol); - gainLossSummaryItem.CurrentGainLoss=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].ActiveGainLoss; - double previousGainLoss=1==gainLossCompoundModelCollection.Count?0.00:gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-2].ActiveGainLoss; - gainLossSummaryItem.PreviousGainLoss=previousGainLoss; - gainLossSummaryItem.Change=gainLossSummaryItem.CurrentGainLoss-gainLossSummaryItem.PreviousGainLoss; - if(1==gainLossCollection.Count) gainLossSummaryItem.ChangePercent=0.00; - else + foreach(String symbol in symbols) { - double currentMarketValue=gainLossCollection[gainLossCollection.Count-1].Exposure+gainLossCollection[gainLossCollection.Count-1].GainLoss; - double previousMarketValue=gainLossCollection[gainLossCollection.Count-2].Exposure+gainLossCollection[gainLossCollection.Count-2].GainLoss; - if(0.00==previousMarketValue) gainLossSummaryItem.ChangePercent=0.00; - else gainLossSummaryItem.ChangePercent=((currentMarketValue-previousMarketValue)/previousMarketValue)*100; - if(gainLossSummaryItem.CurrentGainLoss<0&&gainLossSummaryItem.PreviousGainLoss<0) - { // if current gainloss is negative and previous gainloss is negative then show change percent as a further dip into negative (i.e.) make sure sign is negative - if(Math.Abs(gainLossSummaryItem.CurrentGainLoss)>Math.Abs(gainLossSummaryItem.PreviousGainLoss)) gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00; - } - else if(gainLossSummaryItem.CurrentGainLoss<0&&gainLossSummaryItem.PreviousGainLoss>0) + PortfolioTrades portfolioTradesSymbol=portfolioTrades.FilterSymbol(symbol); + GainLossCollection gainLossCollection=activeGainLossGenerator.GenerateGainLoss(portfolioTradesSymbol,maxDateRef); + + TotalGainLossCollection totalGainLossCollection=gainLossGenerator.GenerateTotalGainLoss(portfolioTradesSymbol,maxDateRef); + GainLossCompoundModelCollection gainLossCompoundModelCollection=new GainLossCompoundModelCollection(gainLossCollection,totalGainLossCollection); + + if(1>gainLossCompoundModelCollection.Count) continue; + GainLossSummaryItem gainLossSummaryItem=new GainLossSummaryItem(); + gainLossSummaryItem.Date=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].Date; + gainLossSummaryItem.Symbol=symbol; + if(companyNames.ContainsKey(symbol)) { - gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00; + gainLossSummaryItem.CompanyName=companyNames[symbol]; } - else if(gainLossSummaryItem.CurrentGainLoss>0&&gainLossSummaryItem.PreviousGainLoss>0) +// gainLossSummaryItem.CompanyName=PricingDA.GetNameForSymbol(symbol); + gainLossSummaryItem.CurrentGainLoss=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].ActiveGainLoss; + double previousGainLoss=1==gainLossCompoundModelCollection.Count?0.00:gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-2].ActiveGainLoss; + gainLossSummaryItem.PreviousGainLoss=previousGainLoss; + gainLossSummaryItem.Change=gainLossSummaryItem.CurrentGainLoss-gainLossSummaryItem.PreviousGainLoss; + if(1==gainLossCollection.Count) gainLossSummaryItem.ChangePercent=0.00; + else { - if(gainLossSummaryItem.CurrentGainLossMath.Abs(gainLossSummaryItem.PreviousGainLoss)) gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00; + } + else if(gainLossSummaryItem.CurrentGainLoss<0&&gainLossSummaryItem.PreviousGainLoss>0) + { + gainLossSummaryItem.ChangePercent=Math.Abs(gainLossSummaryItem.ChangePercent)*-1.00; + } + else if(gainLossSummaryItem.CurrentGainLoss>0&&gainLossSummaryItem.PreviousGainLoss>0) + { + if(gainLossSummaryItem.CurrentGainLoss symbols=portfolioTrades.Symbols; + + Dictionary stopLimits = PortfolioDA.HasStopLimit(symbols); + foreach(String symbol in symbols) { PortfolioTrades portfolioTradesSymbol=portfolioTrades.FilterSymbol(symbol); @@ -125,7 +148,8 @@ namespace MarketData.MarketDataModel.GainLoss { if(!portfolioTrades.HasOpenPositions(symbol)) continue; } - gainLossSummaryItem.HasStopLimit=PortfolioDA.HasStopLimit(symbol); + gainLossSummaryItem.HasStopLimit = stopLimits.ContainsKey(symbol); +// gainLossSummaryItem.HasStopLimit=PortfolioDA.HasStopLimit(symbol); Add(gainLossSummaryItem); } GainLossSummaryItemCollection gainLossSummaryCollection=new GainLossSummaryItemCollection((from GainLossSummaryItem gainLossSummaryItem in this orderby gainLossSummaryItem.Date descending,gainLossSummaryItem.Change descending,gainLossSummaryItem.Symbol descending select gainLossSummaryItem).ToList());