Files
marketdata/MarketDataLib/Generator/ModelGenerators/EdgeRatioGenerator.cs
2024-02-22 14:52:53 -05:00

90 lines
3.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using MarketData.MarketDataModel;
using MarketData.Utils;
using MarketData.DataAccess;
using MarketData.Numerical;
using MarketData.Cache;
namespace MarketData.Generator.ModelGenerators
{
public class EdgeRatioGenerator
{
private EdgeRatioGenerator()
{
}
public static EdgeRatioResult CalculateEdgeRatio(String symbol,DateTime purchaseDate,double purchasePrice,DateTime asOf)
{
EdgeRatioResult edgeRatioResult=new EdgeRatioResult();
DateGenerator dateGenerator=new DateGenerator();
DateTime lastBusinesDate=dateGenerator.GetPrevBusinessDay(asOf);
Dictionary<DateTime,TrueRangeResult> trueRangeResults=new Dictionary<DateTime,TrueRangeResult>();
double[] mae=null;
double[] mfe=null;
double[] atr=null;
try
{
List<DateTime> seriesDates=dateGenerator.GenerateHistoricalDates(purchaseDate,asOf);
mae=new double[seriesDates.Count];
mfe=new double[seriesDates.Count];
atr=new double[seriesDates.Count];
double sumMAEPlusATR=0.00;
double sumMFEPlusATR=0.00;
double averageMAE=0.00;
double averageMFE=0.00;
asOf=dateGenerator.GetPrevBusinessDay(asOf);
for(int index=0;index<seriesDates.Count;index++)
{
DateTime seriesDate=seriesDates[index];
Price seriesPrice=null;
if(seriesDate.Date.Equals(lastBusinesDate.Date))seriesPrice=PricingDA.GetPrice(symbol,seriesDate); // ensure we always get a hot price for last business date, other price may originate from cache
else seriesPrice=GBPriceCache.GetInstance().GetPrice(symbol,seriesDate);
if(null==seriesPrice)
{
edgeRatioResult.Message=String.Format("Price not available for {0} on {1}",symbol,seriesDate.ToShortDateString());
return edgeRatioResult;
}
mfe[index]=(seriesPrice.High-purchasePrice)<0.00?0.00:(seriesPrice.High-purchasePrice);
mae[index]=(purchasePrice-seriesPrice.Low)<0.00?0.00:(purchasePrice-seriesPrice.Low);
atr[index]=TrueRangeGenerator.GenerateAverageTrueRange(symbol,seriesDate).AverageTrueRange;
}
for(int index=0;index<seriesDates.Count;index++)
{
sumMAEPlusATR+=(mae[index]+atr[index]);
sumMFEPlusATR+=(mfe[index]+atr[index]);
}
averageMAE=sumMAEPlusATR/(double)seriesDates.Count;
averageMFE=sumMFEPlusATR/(double)seriesDates.Count;
edgeRatioResult.EdgeRatio=averageMFE/averageMAE;
edgeRatioResult.Success=true;
edgeRatioResult.Message=String.Format("EdgeRatio for {0} purchased on {1} @ {2} from {3} -> {4}",symbol,purchaseDate.ToShortDateString(),Utility.FormatCurrency(purchasePrice),purchaseDate.ToShortDateString(),asOf.ToShortDateString());
return edgeRatioResult;
}
catch(Exception exception)
{
edgeRatioResult.Message=exception.ToString();
return edgeRatioResult;
}
}
}
public class EdgeRatioResult
{
public EdgeRatioResult()
{
Success=false;
EdgeRatio=double.NaN;
Message=null;
}
public double EdgeRatio{get;set;}
public bool Success{get;set;}
public String Message{get;set;}
}
}