Optimizations for CMTrend

This commit is contained in:
2025-04-21 18:03:07 -04:00
parent 53e84e765c
commit 14bd7651ca
9 changed files with 302 additions and 34 deletions

View File

@@ -167,20 +167,31 @@ namespace MarketData.DataAccess
if (null != sqlConnection) sqlConnection.Close();
}
}
public static TimeSeriesCollection GetEPS(String symbol,DateTime? maxDate=null)
/// <summary>
/// Retrieves a collection of timeseries for the given symbols with each symbol having the specified max asof and no more than maxSeries elements in the series
/// </summary>
/// <param name="symbols"></param>
/// <param name="maxDate"></param>
/// <param name="maxSeries"></param>
/// <returns></returns>
public static Dictionary<String,TimeSeriesCollection> GetEPS(List<String> symbols, DateTime maxDate,int maxSeries)
{
MySqlConnection sqlConnection = null;
MySqlDataReader sqlDataReader = null;
MySqlCommand sqlCommand = null;
TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
Dictionary<String,TimeSeriesCollection> timeSeriesCollection = new Dictionary<String,TimeSeriesCollection>();
String strQuery = null;
try
{
StringBuilder sb = new StringBuilder();
sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
if(null==maxDate)sb.Append("select symbol,asof,eps from fundamentals where symbol='").Append(symbol).Append("' order by asof desc");
else sb.Append("select symbol,asof,eps from fundamentals where symbol='").Append(symbol).Append("'").Append(" and asof<=").Append(SqlUtils.AddQuotes(SqlUtils.ToSqlDateTime(maxDate.Value))).Append(" order by asof desc");
sb.Append("SELECT B.symbol, B.asof, B.eps FROM ");
sb.Append("(SELECT symbol, asof, eps, ROW_NUMBER() OVER(PARTITION BY symbol ORDER BY asof desc) AS rownum FROM fundamentals ");
sb.Append($"WHERE symbol IN {SqlUtils.CreateInClause(symbols)} AND asof<={SqlUtils.ToSqlDate(maxDate,true)} )B ");
sb.Append($"WHERE B.rownum<={maxSeries}");
strQuery = sb.ToString(); ;
sqlCommand = new MySqlCommand(strQuery, sqlConnection);
sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
@@ -195,7 +206,11 @@ namespace MarketData.DataAccess
timeSeriesElement.Type = TimeSeriesElement.ElementType.OTHER;
timeSeriesElement.OtherType = "EPS";
if (double.IsNaN(timeSeriesElement.Value)) continue;
timeSeriesCollection.Add(timeSeriesElement);
if(!timeSeriesCollection.ContainsKey(timeSeriesElement.Symbol))
{
timeSeriesCollection.Add(timeSeriesElement.Symbol,new TimeSeriesCollection());
}
timeSeriesCollection[timeSeriesElement.Symbol].Add(timeSeriesElement);
}
return timeSeriesCollection;
}
@@ -210,7 +225,8 @@ namespace MarketData.DataAccess
if (null != sqlDataReader) {sqlDataReader.Close();sqlDataReader.Dispose();}
if (null != sqlConnection) sqlConnection.Close();
}
}
}
public static Fundamental GetFundamental(String symbol)
{
MySqlConnection sqlConnection = null;
@@ -384,6 +400,65 @@ namespace MarketData.DataAccess
if (null != sqlConnection) sqlConnection.Close();
}
}
/// <summary>
/// Retrieve latest MarketCap, PE, EBITDA, RevenuePerShare for all symbols with aasof being no more recent than the provided date
/// Given a tradeDate of 04/18/2025 this method might return a collection similar to below. The model returned is a subset of the fundamental
/// 07/15/2018 ^FTSE
/// 03/13/2019 ^GSPC
/// 04/17/2025 AA
/// </summary>
/// <param name="tradeDate">The as of date</param>
/// <returns></returns>
public static FundamentalsV2 GetFundamentalsMaxDateV2(DateTime tradeDate)
{
MySqlConnection sqlConnection = null;
MySqlDataReader sqlDataReader = null;
MySqlCommand sqlCommand=null;
String strQuery = null;
FundamentalsV2 fundamentals = new FundamentalsV2();
try
{
StringBuilder sb = new StringBuilder();
sqlConnection = SqlUtils.CreateMySqlConnection(MainDataSource.Instance.LocateDataSource("market_data"));
sb.Append("SELECT A.asof,A.symbol, A.market_cap,A.ebitda,A.pe,A.revenue_per_share FROM fundamentals A JOIN ");
sb.Append("(SELECT MAX(asof) asof,symbol FROM fundamentals WHERE asof<=").Append("'");
sb.Append(Utility.DateTimeToStringYYYYHMMHDD(tradeDate.Date));
sb.Append("'");
sb.Append(" GROUP BY symbol ORDER BY symbol ASC)B ");
sb.Append(" ON A.asof=B.asof AND A.symbol=B.symbol ");
strQuery = sb.ToString(); ;
sqlCommand = new MySqlCommand(strQuery, sqlConnection);
sqlCommand.CommandTimeout = SqlUtils.COMMAND_TIMEOUT;
sqlDataReader = sqlCommand.ExecuteReader();
while(sqlDataReader.Read())
{
FundamentalV2 fundamental = new FundamentalV2();
fundamental.AsOf = sqlDataReader.GetDateTime(0);
fundamental.Symbol = sqlDataReader.GetString(1);
if(!sqlDataReader.IsDBNull(2)) fundamental.MarketCap = sqlDataReader.GetDouble(2);
if(!sqlDataReader.IsDBNull(3)) fundamental.EBITDA = sqlDataReader.GetDouble(3);
if(!sqlDataReader.IsDBNull(4)) fundamental.PE = sqlDataReader.GetDouble(4);
if(!sqlDataReader.IsDBNull(5)) fundamental.RevenuePerShare = sqlDataReader.GetDouble(5);
if(!fundamentals.ContainsKey(fundamental.Symbol))fundamentals.Add(fundamental.Symbol,fundamental);
}
return fundamentals;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception);
return null;
}
finally
{
if(null!=sqlCommand)sqlCommand.Dispose();
if (null != sqlDataReader) {sqlDataReader.Close();sqlDataReader.Dispose();}
if (null != sqlConnection) sqlConnection.Close();
}
}
public static Fundamental GetFundamentalMaxDate(String symbol, DateTime asof)
{
MySqlConnection sqlConnection = null;