165 lines
7.5 KiB
C#
165 lines
7.5 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Eremex.AvaloniaUI.Charts;
|
|
using MarketData.MarketDataModel;
|
|
using MarketData.MarketDataModel.GainLoss;
|
|
using MarketData.Numerical;
|
|
using MarketData.Utils;
|
|
using PortfolioManager.DataSeriesViewModels;
|
|
|
|
namespace PortfolioManager.Models
|
|
{
|
|
public class GainLossModel
|
|
{
|
|
private GainLossModel()
|
|
{
|
|
}
|
|
|
|
public static CompositeDataSource Empty()
|
|
{
|
|
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
{
|
|
DataAdapter = new SortedDateTimeDataAdapter()
|
|
};
|
|
return compositeDataSource;
|
|
}
|
|
|
|
public static CompositeDataSource Price(Price price)
|
|
{
|
|
if (null == price) return Empty();
|
|
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
|
sortedDateTimeDataAdapter.Add(price.Date, price.Close);
|
|
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
{
|
|
DataAdapter = sortedDateTimeDataAdapter
|
|
};
|
|
return compositeDataSource;
|
|
}
|
|
|
|
// public static CompositeDataSource CreateCompositeDataSource(DateTime xSource, double ySource)
|
|
// {
|
|
// if (Utility.IsEpoch(xSource)) return Empty();
|
|
// SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
|
// sortedDateTimeDataAdapter.Add(xSource, ySource);
|
|
// CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
// {
|
|
// DataAdapter = sortedDateTimeDataAdapter
|
|
// };
|
|
// return compositeDataSource;
|
|
// }
|
|
|
|
// This is the active gain/loss as number or percent.
|
|
public static CompositeDataSource GainLoss(ModelPerformanceSeries gainLossList, bool useGainLoss)
|
|
{
|
|
if (null == gainLossList) return Empty();
|
|
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
|
foreach (ModelPerformanceItem modelPerformanceItem in gainLossList)
|
|
{
|
|
sortedDateTimeDataAdapter.Add(modelPerformanceItem.Date, useGainLoss ? modelPerformanceItem.CumulativeGainLoss : modelPerformanceItem.CumProdMinusOne * 100.00);
|
|
}
|
|
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
{
|
|
DataAdapter = sortedDateTimeDataAdapter
|
|
};
|
|
return compositeDataSource;
|
|
}
|
|
|
|
// This is the active gain/loss as number or percent.
|
|
public static CompositeDataSource GainLoss(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
|
{
|
|
if (null == gainLossList) return Empty();
|
|
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
|
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
|
foreach (GainLossCompoundModel gainLossCompoundModel in sortedCollection)
|
|
{
|
|
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, useGainLoss ? gainLossCompoundModel.ActiveGainLoss : gainLossCompoundModel.ActiveGainLossPercent);
|
|
}
|
|
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
{
|
|
DataAdapter = sortedDateTimeDataAdapter
|
|
};
|
|
return compositeDataSource;
|
|
}
|
|
|
|
// This is the total gain loss as number or percent
|
|
public static CompositeDataSource TotalGainLoss(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
|
{
|
|
if (null == gainLossList) return Empty();
|
|
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
|
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
|
foreach (GainLossCompoundModel gainLossCompoundModel in sortedCollection)
|
|
{
|
|
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, useGainLoss ? gainLossCompoundModel.TotalGainLoss : gainLossCompoundModel.TotalGainLossPercent);
|
|
}
|
|
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
{
|
|
DataAdapter = sortedDateTimeDataAdapter
|
|
};
|
|
return compositeDataSource;
|
|
}
|
|
|
|
// This is the least squares composite data source based on the active gain/loss
|
|
public static CompositeDataSource LeastSquares(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
|
{
|
|
if (null == gainLossList) return Empty();
|
|
LeastSquaresResult leastSquaresResult = LeastSquaresFit(gainLossList, useGainLoss);
|
|
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
|
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
|
|
|
for (int index = 0; index < sortedCollection.Count; index++)
|
|
{
|
|
GainLossCompoundModel gainLossCompoundModel = sortedCollection[index];
|
|
int leastSquaresIndex = (leastSquaresResult.LeastSquares.Length - 1) - index;
|
|
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, leastSquaresResult.LeastSquares[leastSquaresIndex]);
|
|
}
|
|
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
{
|
|
DataAdapter = sortedDateTimeDataAdapter
|
|
};
|
|
return compositeDataSource;
|
|
}
|
|
|
|
// This is the least squares composite data source based on the active gain/loss
|
|
public static CompositeDataSource TotalLeastSquares(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
|
{
|
|
if (null == gainLossList) return Empty();
|
|
LeastSquaresResult leastSquaresResult = TotalLeastSquaresFit(gainLossList, useGainLoss);
|
|
GainLossCompoundModelCollection sortedCollection = new GainLossCompoundModelCollection(gainLossList.OrderBy(x => x.Date).ToList());
|
|
SortedDateTimeDataAdapter sortedDateTimeDataAdapter = new SortedDateTimeDataAdapter();
|
|
|
|
for (int index = 0; index < sortedCollection.Count; index++)
|
|
{
|
|
GainLossCompoundModel gainLossCompoundModel = sortedCollection[index];
|
|
int leastSquaresIndex = (leastSquaresResult.LeastSquares.Length - 1) - index;
|
|
sortedDateTimeDataAdapter.Add(gainLossCompoundModel.Date, leastSquaresResult.LeastSquares[leastSquaresIndex]);
|
|
}
|
|
CompositeDataSource compositeDataSource = new CompositeDataSource()
|
|
{
|
|
DataAdapter = sortedDateTimeDataAdapter
|
|
};
|
|
return compositeDataSource;
|
|
}
|
|
|
|
// ***************************************** C A L C U L A T O R S **********************************
|
|
|
|
// This is the LeastSquares fit based on the active gain/loss
|
|
public static LeastSquaresResult LeastSquaresFit(GainLossCompoundModelCollection gainLossList, bool useGainLoss)
|
|
{
|
|
double[] values = null;
|
|
if (useGainLoss) values = (from GainLossCompoundModel gainLoss in gainLossList select gainLoss.ActiveGainLoss).ToList().ToArray();
|
|
else values = (from GainLossCompoundModel gainLoss in gainLossList select gainLoss.ActiveGainLossPercent).ToList().ToArray();
|
|
LeastSquaresResult leastSquaresResult = Numerics.LeastSquares(values);
|
|
return leastSquaresResult;
|
|
}
|
|
|
|
// This is the LeastSquares fit based on the total gain/loss
|
|
public static LeastSquaresResult TotalLeastSquaresFit(GainLossCompoundModelCollection gainLossList,bool useGainLoss)
|
|
{
|
|
double[] values=null;
|
|
if(useGainLoss)values=(from GainLossCompoundModel gainLoss in gainLossList select gainLoss.TotalGainLoss).ToList().ToArray();
|
|
else values=(from GainLossCompoundModel gainLoss in gainLossList select gainLoss.TotalGainLossPercent).ToList().ToArray();
|
|
LeastSquaresResult leastSquaresResult=Numerics.LeastSquares(values);
|
|
return leastSquaresResult;
|
|
}
|
|
}
|
|
} |