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

239 lines
9.2 KiB
C#

using System;
using System.Collections.Generic;
using MarketData.MarketDataModel;
using MarketData.DataAccess;
using MarketData.Numerical;
using MarketData.Utils;
namespace MarketData.Generator
{
public class MovingAverageGenerator
{
public static readonly int DayCount200=200;
public static readonly int DayCount100=100;
public static readonly int DayCount55=55;
public static readonly int DayCount50=50;
public static readonly int DayCount21=21;
public static readonly int DayCount5=5;
private MovingAverageGenerator()
{
}
public static MovingAverages GenerateMovingAverages(String symbol,int dayCount=180)
{
try
{
Dictionary<DateTime, DMAPrice> ma200ByDate = new Dictionary<DateTime, DMAPrice>();
Dictionary<DateTime, DMAPrice> ma100ByDate = new Dictionary<DateTime, DMAPrice>();
Dictionary<DateTime, DMAPrice> ma55ByDate = new Dictionary<DateTime, DMAPrice>();
Dictionary<DateTime, DMAPrice> ma21ByDate = new Dictionary<DateTime, DMAPrice>();
Dictionary<DateTime, DMAPrice> ma5ByDate = new Dictionary<DateTime, DMAPrice>();
if (null == symbol) return null;
String companyName = PricingDA.GetNameForSymbol(symbol);
DateGenerator dateGenerator = new DateGenerator();
DateTime startDate = dateGenerator.GetPrevBusinessDay(DateTime.Now);
Prices prices = PricingDA.GetPrices(symbol, startDate, dayCount);
if (null == prices || 0 == prices.Count)
{
MDTrace.WriteLine(LogLevel.DEBUG,"No prices for symbol '" + symbol + "'");
return null;
}
Price latestPrice = prices[0];
DMAPrices ma200= GenerateMovingAverage(prices, DayCount200);
DMAPrices ma100 = GenerateMovingAverage(prices, DayCount100);
DMAPrices ma55 = GenerateMovingAverage(prices, DayCount55);
DMAPrices ma21 = GenerateMovingAverage(prices, DayCount21);
DMAPrices ma5 = GenerateMovingAverage(prices, DayCount5);
for (int index = 0; index < ma200.Count; index++) ma200ByDate.Add(ma200[index].Date,ma200[index]);
for (int index = 0; index < ma100.Count; index++) ma100ByDate.Add(ma100[index].Date, ma100[index]);
for (int index = 0; index < ma55.Count; index++) ma55ByDate.Add(ma55[index].Date, ma55[index]);
for (int index = 0; index < ma21.Count; index++) ma21ByDate.Add(ma21[index].Date, ma21[index]);
for (int index = 0; index < ma5.Count; index++) ma5ByDate.Add(ma5[index].Date, ma5[index]);
MovingAverages movingAverages = new MovingAverages();
movingAverages.ThruDate = prices[0].Date;
movingAverages.FromDate = prices[prices.Count - 1].Date;
for (int index = 0; index < prices.Count; index++)
{
Price price = prices[index];
DMAPrice ma200Price = null;
DMAPrice ma100Price = null;
DMAPrice ma55Price = null;
DMAPrice ma21Price = null;
DMAPrice ma5Price = null;
if (ma55ByDate.ContainsKey(price.Date)) ma55Price=ma55ByDate[price.Date];
if (ma21ByDate.ContainsKey(price.Date)) ma21Price = ma21ByDate[price.Date];
if (ma5ByDate.ContainsKey(price.Date)) ma5Price = ma5ByDate[price.Date];
if(ma200ByDate.ContainsKey(price.Date))ma200Price = ma200ByDate[price.Date];
if(ma100ByDate.ContainsKey(price.Date)) ma100Price = ma100ByDate[price.Date];
MovingAverageElement movingAverageElement = new MovingAverageElement();
movingAverageElement.Symbol = price.Symbol;
movingAverageElement.Date = price.Date;
movingAverageElement.Close = price.Close;
movingAverageElement.High = price.High;
movingAverageElement.Low = price.Low;
movingAverageElement.MA200 = null==ma200Price?double.NaN:ma200Price.AVGPrice;
movingAverageElement.MA100 = null == ma100Price ? double.NaN : ma100Price.AVGPrice;
movingAverageElement.MA55 = null==ma55Price?double.NaN:ma55Price.AVGPrice;
movingAverageElement.MA21 = null==ma21Price?double.NaN:ma21Price.AVGPrice;
movingAverageElement.MA5 = null==ma5Price?double.NaN:ma5Price.AVGPrice;
movingAverages.Add(movingAverageElement);
}
return movingAverages;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception);
return null;
}
}
public static DMAValues GenerateMovingAverage(DMAValues values,int dayCount)
{
try
{
DMAValues dmaValues = new DMAValues();
for (int index = 0; index < values.Count; index++)
{
DMAValue value = values[index];
DMAValue dmaValue = new DMAValue();
dmaValue.Date = value.Date;
float[] pricesArray = values.GetValues(index, dayCount);
if (null == pricesArray) break;
dmaValue.MAValue = Numerics.Mean(ref pricesArray);
dmaValue.Value = value.Value;
if (double.IsNaN(dmaValue.MAValue)) continue;
dmaValues.Add(dmaValue);
}
return dmaValues;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception);
return null;
}
}
public static DMAPrices GenerateExponentialMovingAverage(Prices prices,int dayCount)
{
try
{
if(null==prices||prices.Count<dayCount+1)return null; // (i.e.) a 20 day ExponentialMovingAverage requires 21 days of data
double smoothing=2.00/((double)dayCount+1.00);
DMAPrices emaPrices=new DMAPrices();
DMAPrices smaPrices=GenerateMovingAverage(prices,dayCount);
if(null==smaPrices||smaPrices.Count<dayCount)return null;
smaPrices=new DMAPrices(smaPrices.Top(dayCount));
for(int index=0;index<smaPrices.Count;index++)
{
DMAPrice smaPrice=smaPrices[index]; // where yesterday is at index+1
DMAPrice emaPrice=new DMAPrice();
if(0==index)
{
emaPrice.Symbol=smaPrice.Symbol;
emaPrice.Date=smaPrice.Date;
emaPrice.AVGPrice=smaPrice.AVGPrice;
emaPrices.Add(emaPrice);
}
else
{
DMAPrice prevEMA=emaPrices[emaPrices.Count-1];
emaPrice.Symbol=smaPrice.Symbol;
emaPrice.Date=smaPrice.Date;
emaPrice.AVGPrice=(smaPrice.AVGPrice*(smoothing/(1.00+dayCount)))+(prevEMA.AVGPrice*(1.00-(smoothing/(1.00+dayCount))));
emaPrices.Add(emaPrice);
}
}
return emaPrices;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception);
return null;
}
}
/// <summary>Generates a dayCount moving average given prices.</summary>
public static DMAPrices GenerateMovingAverage(Prices prices, int dayCount)
{
try
{
DMAPrices dmaPrices = new DMAPrices();
for (int index = 0; index < prices.Count; index++)
{
Price price = prices[index];
DMAPrice dmaPrice = new DMAPrice();
dmaPrice.Symbol = price.Symbol;
dmaPrice.Date = price.Date;
float[] pricesArray = prices.GetPrices(index, dayCount);
if (null == pricesArray) break;
dmaPrice.AVGPrice = Numerics.Mean(ref pricesArray);
if (double.IsNaN(dmaPrice.AVGPrice)) continue;
dmaPrice.CurrentPrice = price.Close;
dmaPrices.Add(dmaPrice);
}
return dmaPrices;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception);
return null;
}
}
public static DMAPrices GenerateMovingMinsOnLow(Prices prices, int dayCount)
{
try
{
DMAPrices dmaPrices = new DMAPrices();
for (int index = 0; index < prices.Count; index++)
{
Price price = prices[index];
DMAPrice dmaPrice = new DMAPrice();
dmaPrice.Symbol = price.Symbol;
dmaPrice.Date = price.Date;
float[] pricesArray = prices.GetPricesLow(index, dayCount);
if (null == pricesArray) break;
dmaPrice.MinPrice = Numerics.Min(ref pricesArray);
if (double.IsNaN(dmaPrice.MinPrice)) continue;
dmaPrice.CurrentPrice = price.Low;
dmaPrices.Add(dmaPrice);
}
return dmaPrices;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
return null;
}
}
public static DMAPrices GenerateMovingMaxOnHigh(Prices prices, int dayCount)
{
try
{
DMAPrices dmaPrices = new DMAPrices();
for (int index = 0; index < prices.Count; index++)
{
Price price = prices[index];
DMAPrice dmaPrice = new DMAPrice();
dmaPrice.Symbol = price.Symbol;
dmaPrice.Date = price.Date;
float[] pricesArray = prices.GetPricesHigh(index, dayCount);
if (null == pricesArray) break;
dmaPrice.MaxPrice = Numerics.Max(ref pricesArray);
if (double.IsNaN(dmaPrice.MaxPrice)) continue;
dmaPrice.CurrentPrice = price.High;
dmaPrices.Add(dmaPrice);
}
return dmaPrices;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
return null;
}
}
}
}