using System; using System.Linq; using Eremex.AvaloniaUI.Charts; using MarketData.MarketDataModel; using MarketData.MarketDataModel.GainLoss; using MarketData.Numerical; 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(); // CompositeDataSource compositeDataSource; // var xData = new EnumerableDataSource(new DateTime[]{price.Date}); // xData.SetXMapping(x => (x.Ticks / 10000000000.0)); // var yData = new EnumerableDataSource(new double[]{price.Close}); // yData.SetYMapping(y => y); // compositeDataSource = xData.Join(yData); // return compositeDataSource; return Empty(); } // 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; } } }