Sync up with changes from ARM64
This commit is contained in:
@@ -131,7 +131,6 @@ namespace MarketData.Generator.CMMomentum
|
||||
double gainLossClosedPositions=0.00;
|
||||
double exposure=0.00;
|
||||
double marketValue=0.00;
|
||||
// if(HolidayDA.IsMarketHoliday(currentDate)) continue;
|
||||
ModelPerformanceItem performanceItem=new ModelPerformanceItem();
|
||||
foreach(MarketData.Generator.CMMomentum.Position openPosition in openPositions)
|
||||
{
|
||||
|
||||
@@ -16,17 +16,26 @@ namespace MarketData.Generator.CMTrend
|
||||
public CMTCandidateGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
// *******************************************************************************************************************************************************************************
|
||||
// ******************************************************************* G E N E R A T E C A N D I D A T E - M A R C M I N E R V I N I ****************************************
|
||||
// *******************************************************************************************************************************************************************************
|
||||
public static CMTCandidate GenerateCandidate(String symbol,DateTime tradeDate,CMTParams cmtParams,List<String> symbolsHeld=null)
|
||||
public static CMTCandidate GenerateCandidate(
|
||||
String symbol,
|
||||
DateTime tradeDate,
|
||||
CMTParams cmtParams,
|
||||
FundamentalV2 fundamental,
|
||||
CompanyProfile companyProfile,
|
||||
List<DateTime> historicalDates,
|
||||
TimeSeriesCollection epsTimeSeries,
|
||||
TimeSeriesCollection profitMarginTimeSeries,
|
||||
List<String> symbolsHeld=null)
|
||||
{
|
||||
CMTCandidate cmtCandidate=new CMTCandidate();
|
||||
|
||||
try
|
||||
{
|
||||
// Check MarketCap
|
||||
Fundamental fundamental=FundamentalDA.GetFundamentalMaxDate(symbol,tradeDate);
|
||||
if(null==fundamental)
|
||||
{
|
||||
cmtCandidate.Violation=true;
|
||||
@@ -54,7 +63,6 @@ namespace MarketData.Generator.CMTrend
|
||||
return cmtCandidate;
|
||||
}
|
||||
// Equity check
|
||||
CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(symbol);
|
||||
if(null==companyProfile)
|
||||
{
|
||||
cmtCandidate.Violation=true;
|
||||
@@ -93,7 +101,7 @@ namespace MarketData.Generator.CMTrend
|
||||
cmtCandidate.Reason=String.Format("Insufficient pricing history, {0} days required.",PRICING_DAYS);
|
||||
return cmtCandidate;
|
||||
}
|
||||
// Current Price Check
|
||||
// Current Price Check. The current price must be equal to the trade date
|
||||
Price currentPrice=prices[0];
|
||||
if(currentPrice.Date.Date!=tradeDate.Date)
|
||||
{
|
||||
@@ -205,10 +213,7 @@ namespace MarketData.Generator.CMTrend
|
||||
// generate a 14 day standard RSI with 30 days of pricing data
|
||||
Prices rsiPrices=GBPriceCache.GetInstance().GetPrices(symbol,currentPrice.Date,30);
|
||||
RSICollection rsiCollection=RSIGenerator.GenerateRSI(rsiPrices);
|
||||
double rsi=rsiCollection[rsiCollection.Count-1].RSI;
|
||||
|
||||
// RSICollection rsiCollection=RSIGenerator.GenerateRSI(symbol,currentPrice.Date,30);
|
||||
// double rsi=rsiCollection[rsiCollection.Count-1].RSI;
|
||||
double rsi=rsiCollection[rsiCollection.Count-1].RSI;
|
||||
if(null==rsiCollection||0==rsiCollection.Count||rsi<cmtParams.MinRSI)
|
||||
{
|
||||
cmtCandidate.Violation=true;
|
||||
@@ -220,8 +225,6 @@ namespace MarketData.Generator.CMTrend
|
||||
// Trend #3 check : check required days of increasing 200 day moving averages
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
List<double> dma200List=new List<double>();
|
||||
DateTime historicalDate=dateGenerator.GenerateHistoricalDate(currentPrice.Date,cmtParams.DMA200Horizon+10);
|
||||
List<DateTime> historicalDates=PricingDA.GetPricingDatesBetween(historicalDate,currentPrice.Date);
|
||||
historicalDates=historicalDates.Take(cmtParams.DMA200Horizon).ToList();
|
||||
if(historicalDates.Count<cmtParams.DMA200Horizon)
|
||||
{
|
||||
@@ -324,7 +327,6 @@ namespace MarketData.Generator.CMTrend
|
||||
double epsSlope=double.NaN;
|
||||
if(companyProfile.IsEquity&&cmtParams.EPSCheck)
|
||||
{
|
||||
TimeSeriesCollection epsTimeSeries=FundamentalDA.GetEPS(symbol,currentPrice.Date);
|
||||
if(null==epsTimeSeries||epsTimeSeries.Count<3)
|
||||
{
|
||||
cmtCandidate.Violation=true;
|
||||
@@ -350,7 +352,6 @@ namespace MarketData.Generator.CMTrend
|
||||
// Trend#10 - My check - Increasing profit margin
|
||||
if(companyProfile.IsEquity&&cmtParams.ProfitMarginCheck)
|
||||
{
|
||||
TimeSeriesCollection profitMarginTimeSeries=IncomeStatementDA.GetProfitMarginMaxAsOf(symbol,currentPrice.Date,IncomeStatement.PeriodType.Quarterly);
|
||||
if(null==profitMarginTimeSeries||profitMarginTimeSeries.Count<3)
|
||||
{
|
||||
cmtCandidate.Violation=true;
|
||||
@@ -362,7 +363,7 @@ namespace MarketData.Generator.CMTrend
|
||||
minDate=profitMarginTimeSeries.Min(x => x.AsOf);
|
||||
maxDate=profitMarginTimeSeries.Max(x => x.AsOf);
|
||||
values=profitMarginTimeSeries.ToFloat();
|
||||
values=Numerics.Reverse(ref values);
|
||||
values=Numerics.Reverse(ref values); // because most recent date is in the lowest valued index bucket.
|
||||
profitMarginSlope=Numerics.Slope(values);
|
||||
if(profitMarginSlope<=0)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using MarketData.DataAccess;
|
||||
using Axiom.Interpreter;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.Utils;
|
||||
using System;
|
||||
@@ -20,13 +21,58 @@ namespace MarketData.Generator.CMTrend
|
||||
try
|
||||
{
|
||||
List<String> symbols=PricingDA.GetSymbols();
|
||||
|
||||
// Filter out symbols where we do not have a price on trade date
|
||||
Profiler profiler = new Profiler();
|
||||
Dictionary<String,DateTime> latestDates = PricingDA.GetLatestDates(symbols);
|
||||
symbols=symbols.Where(x => latestDates.ContainsKey(x) && latestDates[x].Date>=tradeDate.Date).ToList();
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded pricing dates in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch a subset of fundamentals where each fundamental.asof is no greater than tradeDate
|
||||
profiler.Reset();
|
||||
FundamentalsV2 fundamentals = FundamentalDA.GetFundamentalsMaxDateV2(tradeDate);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded fundamentals in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the Company Profiles
|
||||
profiler.Reset();
|
||||
Dictionary<String,CompanyProfile> companyProfiles = CompanyProfileDA.GetCompanyProfiles(symbols);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded company profiles in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the pricing dates required for 200 day moving average.
|
||||
profiler.Reset();
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
DateTime historicalDate=dateGenerator.GenerateHistoricalDate(tradeDate,cmtParams.DMA200Horizon+10);
|
||||
List<DateTime> historicalDates=PricingDA.GetPricingDatesBetween(historicalDate,tradeDate);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded moving average dates in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the EPS time series
|
||||
profiler.Reset();
|
||||
Dictionary<String,TimeSeriesCollection> epsTimeSeriesCollectionDictionary = FundamentalDA.GetEPS(symbols,tradeDate,3);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded EPS Time Series in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the profit margin time series
|
||||
profiler.Reset();
|
||||
Dictionary<String,TimeSeriesCollection> profitMarginTimeSeriesCollectionDictionary = IncomeStatementDA.GetProfitMarginMaxAsOf(symbols,tradeDate,3,IncomeStatement.PeriodType.Quarterly);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded Profit Margin Time Series in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
for(int index=0;index<symbols.Count;index++)
|
||||
{
|
||||
String symbol=symbols[index];
|
||||
if(0==(index%1000)) Console.WriteLine("Processing item {0} of {1}",index+1,symbols.Count);
|
||||
CMTCandidate cmtCandidate=CMTCandidateGenerator.GenerateCandidate(symbol,tradeDate,cmtParams,symbolsHeld);
|
||||
|
||||
FundamentalV2 fundamental = default;
|
||||
if(fundamentals.ContainsKey(symbol))fundamental=fundamentals[symbol];
|
||||
|
||||
CompanyProfile companyProfile = default;
|
||||
if(companyProfiles.ContainsKey(symbol))companyProfile = companyProfiles[symbol];
|
||||
|
||||
TimeSeriesCollection epsTimeSeriesCollection = default;
|
||||
if(epsTimeSeriesCollectionDictionary.ContainsKey(symbol))epsTimeSeriesCollection=epsTimeSeriesCollectionDictionary[symbol];
|
||||
|
||||
TimeSeriesCollection profitMarginTimeSeriesCollection = default;
|
||||
if(profitMarginTimeSeriesCollectionDictionary.ContainsKey(symbol))profitMarginTimeSeriesCollection=profitMarginTimeSeriesCollectionDictionary[symbol];
|
||||
|
||||
CMTCandidate cmtCandidate=CMTCandidateGenerator.GenerateCandidate(symbol,tradeDate,cmtParams,fundamental,companyProfile,historicalDates,epsTimeSeriesCollection,profitMarginTimeSeriesCollection,symbolsHeld);
|
||||
if(null==cmtCandidate) continue;
|
||||
if(cmtCandidate.Violation) cmtGeneratorResult.CMTCandidatesWithViolation.Add(cmtCandidate);
|
||||
else cmtGeneratorResult.CMTCandidates.Add(cmtCandidate);
|
||||
|
||||
@@ -137,7 +137,6 @@ namespace MarketData.Generator.CMTrend
|
||||
double gainLossClosedPositions=0.00;
|
||||
double exposure=0.00;
|
||||
double marketValue=0.00;
|
||||
// if(HolidayDA.IsMarketHoliday(currentDate)) continue;
|
||||
ModelPerformanceItem performanceItem=new ModelPerformanceItem();
|
||||
foreach(MarketData.Generator.CMTrend.Position openPosition in openPositions)
|
||||
{
|
||||
@@ -799,11 +798,58 @@ namespace MarketData.Generator.CMTrend
|
||||
List<CMTCandidate> violations=new List<CMTCandidate>();
|
||||
List<CMTCandidate> candidates=new List<CMTCandidate>();
|
||||
|
||||
// Filter out symbols where we do not have a price on trade date
|
||||
Profiler profiler = new Profiler();
|
||||
Dictionary<String,DateTime> latestDates = PricingDA.GetLatestDates(symbols);
|
||||
symbols=symbols.Where(x => latestDates.ContainsKey(x) && latestDates[x].Date>=analysisDate.Value.Date).ToList();
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded pricing dates in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
|
||||
// Prefetch a subset of fundamentals where each fundamental.asof is no greater than tradeDate
|
||||
profiler.Reset();
|
||||
FundamentalsV2 fundamentals = FundamentalDA.GetFundamentalsMaxDateV2(analysisDate.Value);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded fundamentals in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the company profiles
|
||||
profiler.Reset();
|
||||
Dictionary<String,CompanyProfile> companyProfiles = CompanyProfileDA.GetCompanyProfiles(symbols);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded company profiles in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the pricing dates required for 200 day moving average.
|
||||
profiler.Reset();
|
||||
DateGenerator dateGenerator = new DateGenerator();
|
||||
DateTime historicalDate=dateGenerator.GenerateHistoricalDate(analysisDate.Value,cmtParams.DMA200Horizon+10);
|
||||
List<DateTime> historicalDates=PricingDA.GetPricingDatesBetween(historicalDate,analysisDate.Value);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded moving average dates in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the EPS time series
|
||||
profiler.Reset();
|
||||
Dictionary<String,TimeSeriesCollection> epsTimeSeriesCollectionDictionary = FundamentalDA.GetEPS(symbols,analysisDate.Value,3);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded EPS Time Series in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
// Prefetch the profit margin time series
|
||||
profiler.Reset();
|
||||
Dictionary<String,TimeSeriesCollection> profitMarginTimeSeriesCollectionDictionary = IncomeStatementDA.GetProfitMarginMaxAsOf(symbols,analysisDate.Value,3,IncomeStatement.PeriodType.Quarterly);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,$"Loaded Profit Margin Time Series in {Utility.FormatNumber(profiler.End(),2)} (ms)");
|
||||
|
||||
for(int index=0;index<symbols.Count;index++)
|
||||
{
|
||||
String symbol=symbols[index];
|
||||
if(0==(index%500)) Console.WriteLine("GenerateCMTCandidates processing item {0} of {1}",index+1,symbols.Count);
|
||||
CMTCandidate cmtCandidate=CMTCandidateGenerator.GenerateCandidate(symbol,analysisDate.Value,cmtParams);
|
||||
|
||||
FundamentalV2 fundamental = default;
|
||||
if(fundamentals.ContainsKey(symbol))fundamental=fundamentals[symbol];
|
||||
|
||||
CompanyProfile companyProfile = default;
|
||||
if(companyProfiles.ContainsKey(symbol))companyProfile = companyProfiles[symbol];
|
||||
|
||||
TimeSeriesCollection epsTimeSeriesCollection = default;
|
||||
if(epsTimeSeriesCollectionDictionary.ContainsKey(symbol))epsTimeSeriesCollection=epsTimeSeriesCollectionDictionary[symbol];
|
||||
|
||||
TimeSeriesCollection profitMarginTimeSeriesCollection = default;
|
||||
if(profitMarginTimeSeriesCollectionDictionary.ContainsKey(symbol))profitMarginTimeSeriesCollection=profitMarginTimeSeriesCollectionDictionary[symbol];
|
||||
|
||||
CMTCandidate cmtCandidate=CMTCandidateGenerator.GenerateCandidate(symbol,analysisDate.Value,cmtParams,fundamental,companyProfile,historicalDates,epsTimeSeriesCollection,profitMarginTimeSeriesCollection);
|
||||
if(cmtCandidate.Violation) violations.Add(cmtCandidate);
|
||||
else candidates.Add(cmtCandidate);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,6 @@ namespace MarketData.Generator.Momentum
|
||||
double gainLossClosedPositions=0.00;
|
||||
double exposure=0.00;
|
||||
double marketValue=0.00;
|
||||
// if(HolidayDA.IsMarketHoliday(currentDate)) continue;
|
||||
ModelPerformanceItem performanceItem=new ModelPerformanceItem();
|
||||
foreach(MarketData.Generator.Momentum.Position openPosition in openPositions)
|
||||
{
|
||||
@@ -193,7 +192,8 @@ namespace MarketData.Generator.Momentum
|
||||
AllPositions.DisplayTopFive();
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, "************** T O P L O S S E R S *************");
|
||||
AllPositions.DisplayBottomFive();
|
||||
DisplayBalanceFromPositions();
|
||||
// DisplayBalanceFromPositions();
|
||||
DisplayLatestModelPerformance(paramPathSessionFileName);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("StartDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(StartDate)));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TradeDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(TradeDate)));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("AnalysisDate:{0}",Utility.DateTimeToStringMMHDDHYYYY(AnalysisDate)));
|
||||
@@ -591,6 +591,26 @@ namespace MarketData.Generator.Momentum
|
||||
// *********************************************************************************************************************************************************************
|
||||
// ************************************************************ E N D B U Y P O S I T I O N S ***********************************************
|
||||
// *********************************************************************************************************************************************************************
|
||||
private void DisplayLatestModelPerformance(String pathSessionFileName)
|
||||
{
|
||||
ModelPerformanceSeries performanceSeries=GetModelPerformance(pathSessionFileName);
|
||||
if(null==performanceSeries || 0==performanceSeries.Count)return;
|
||||
MDTrace.WriteLine("Date,Exposure,MarketValue,GainLossDoD,GainLoss,CumulativeGainLoss,R,(1+R),CumProd,CumProd-1,ClosedPositions");
|
||||
ModelPerformanceItem modelPerformanceItem = performanceSeries[performanceSeries.Count-1]; // get the last record
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\",\"{9}\",\"{10}\"",
|
||||
modelPerformanceItem.Date.ToShortDateString(),
|
||||
Utility.FormatCurrency(modelPerformanceItem.Exposure),
|
||||
Utility.FormatCurrency(modelPerformanceItem.MarketValue),
|
||||
Utility.FormatCurrency(modelPerformanceItem.GainLossDOD),
|
||||
Utility.FormatCurrency(modelPerformanceItem.GainLoss),
|
||||
Utility.FormatCurrency(modelPerformanceItem.CumulativeGainLoss),
|
||||
Utility.FormatNumber(modelPerformanceItem.R,4),
|
||||
Utility.FormatNumber(modelPerformanceItem.OnePlusR,4),
|
||||
Utility.FormatNumber(modelPerformanceItem.CumProd,4),
|
||||
Utility.FormatNumber(modelPerformanceItem.CumProdMinusOne,4),
|
||||
modelPerformanceItem.ClosedPositions));
|
||||
}
|
||||
|
||||
private void DisplayBalance()
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"*******************************************");
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MarketData.Generator.Momentum
|
||||
{
|
||||
public class RealtimeGainLoss
|
||||
{
|
||||
public double Exposure{get;set;}
|
||||
public double MarketValue{get;set;}
|
||||
public double GainLoss{get{return MarketValue-Exposure;}}
|
||||
public double GainLossPercent{get{return Exposure==0?0:(MarketValue-Exposure)/Exposure;}}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user