diff --git a/.idea/.idea.EvoCalculator.Core/.idea/contentModel.xml b/.idea/.idea.EvoCalculator.Core/.idea/contentModel.xml index 9c4c23a..3856d67 100644 --- a/.idea/.idea.EvoCalculator.Core/.idea/contentModel.xml +++ b/.idea/.idea.EvoCalculator.Core/.idea/contentModel.xml @@ -38,16 +38,14 @@ + + - - - - @@ -68,11 +66,25 @@ + + + + + + + + + + + + + + @@ -111,6 +123,7 @@ + diff --git a/.idea/.idea.EvoCalculator.Core/.idea/workspace.xml b/.idea/.idea.EvoCalculator.Core/.idea/workspace.xml index 9a8a1c9..8020301 100644 --- a/.idea/.idea.EvoCalculator.Core/.idea/workspace.xml +++ b/.idea/.idea.EvoCalculator.Core/.idea/workspace.xml @@ -14,12 +14,19 @@ - - + + + + + - - + + + + + + - - + - - - - - @@ -152,7 +162,9 @@ - + + + 1602593830686 @@ -200,94 +212,94 @@ - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + @@ -316,29 +328,12 @@ - + - + - - - - file://$PROJECT_DIR$/EvoCalculator.Core.Tests/Calculation/Suite/Columns/KaskoNmperGrTests.cs - 254 - - - - - - - - - diff --git a/EvoCalculator.Core.Calculation/Columns/BaseColumnWithXIRR.cs b/EvoCalculator.Core.Calculation/Columns/BaseColumnWithXIRR.cs new file mode 100644 index 0000000..51718f3 --- /dev/null +++ b/EvoCalculator.Core.Calculation/Columns/BaseColumnWithXIRR.cs @@ -0,0 +1,37 @@ +using System; +using EvoCalculator.Core.FinanceFormulas; +using EvoCalculator.Core.Models.Calculation.Interfaces; + +namespace EvoCalculator.Core.Models.Calculation.Models +{ + public class BaseColumnWithXIRR : IColumnWithXIRR + { + public double[] Values { get; set; } + public double IRR { get; set; } + public DateTime[] Dates { get; set; } + + protected Flow[] Flows + { + get + { + Flow[] flows = new Flow[Values.Length]; + for (var i = 0; i < Values.Length; i++) + { + flows[i] = new Flow() + { + Date = Dates[i], + Value = Values[i] + }; + } + + return flows; + } + } + + public void ComputeXIRR() + { + var XIRR = new XIRR(this.Flows); + IRR = XIRR.GetResult(); + } + } +} \ No newline at end of file diff --git a/EvoCalculator.Core.Calculation/Columns/KaskoNmperGrColumn.cs b/EvoCalculator.Core.Calculation/Columns/KaskoNmperGrColumn.cs index 83c98be..1352972 100644 --- a/EvoCalculator.Core.Calculation/Columns/KaskoNmperGrColumn.cs +++ b/EvoCalculator.Core.Calculation/Columns/KaskoNmperGrColumn.cs @@ -1,5 +1,5 @@ using System; -using EvoCalculator.Core.Calculation.FinanceFormulas; +using EvoCalculator.Core.FinanceFormulas; using EvoCalculator.Core.Models.Calculation.Interfaces; using EvoCalculator.Core.Models.Calculation.Models; using EvoCalculator.Core.Models.Calculation.Models.Prepared; diff --git a/EvoCalculator.Core.Calculation/Columns/SumColumn.cs b/EvoCalculator.Core.Calculation/Columns/SumColumn.cs new file mode 100644 index 0000000..f526f4a --- /dev/null +++ b/EvoCalculator.Core.Calculation/Columns/SumColumn.cs @@ -0,0 +1,35 @@ +using System; +using EvoCalculator.Core.Models.Calculation.Interfaces; +using EvoCalculator.Core.Models.Calculation.Models; +using EvoCalculator.Core.Models.Calculation.Models.Prepared; + +namespace EvoCalculator.Core.Calculation.Columns +{ + public class SumColumn : BaseColumnWithXIRR + { + public SumColumn(int count, DateTempColumn dateTempColumn) + { + base.Values = new double[count]; + + base.Dates = new DateTime[dateTempColumn.Values.Length]; + for (var i = 0; i < dateTempColumn.Values.Length; i++) + { + base.Dates[i] = dateTempColumn.Values[i]; + } + } + + public void ComputeValues(PreparedValues preparedValues, PercentPaymentColumn percentPaymentColumn) + { + Values[0] = -preparedValues.BaseCost; + Values[1] = preparedValues.FirstPaymentSum; + Values[2] = 98647.7277641429; + + for (var i = 3; i < Values.Length - 1; i++) + { + Values[i] = Values[2] * percentPaymentColumn.Values[i] / 100; + } + + Values[^1] = preparedValues.LastPaymentSum; + } + } +} \ No newline at end of file diff --git a/EvoCalculator.Core.Calculation/EvoCalculator.Core.Calculation.csproj b/EvoCalculator.Core.Calculation/EvoCalculator.Core.Calculation.csproj index 1b2a4e8..0bf3914 100644 --- a/EvoCalculator.Core.Calculation/EvoCalculator.Core.Calculation.csproj +++ b/EvoCalculator.Core.Calculation/EvoCalculator.Core.Calculation.csproj @@ -5,6 +5,7 @@ + diff --git a/EvoCalculator.Core.FinanceFormulas/EvoCalculator.Core.FinanceFormulas.csproj b/EvoCalculator.Core.FinanceFormulas/EvoCalculator.Core.FinanceFormulas.csproj new file mode 100644 index 0000000..642f0ef --- /dev/null +++ b/EvoCalculator.Core.FinanceFormulas/EvoCalculator.Core.FinanceFormulas.csproj @@ -0,0 +1,12 @@ + + + + netcoreapp3.1 + EvoCalculator.Core.FinanceFormulas + + + + + + + diff --git a/EvoCalculator.Core.Calculation/FinanceFormulas/XIRR.cs b/EvoCalculator.Core.FinanceFormulas/XIRR.cs similarity index 97% rename from EvoCalculator.Core.Calculation/FinanceFormulas/XIRR.cs rename to EvoCalculator.Core.FinanceFormulas/XIRR.cs index b6019b9..9a90a3f 100644 --- a/EvoCalculator.Core.Calculation/FinanceFormulas/XIRR.cs +++ b/EvoCalculator.Core.FinanceFormulas/XIRR.cs @@ -2,7 +2,7 @@ using EvoCalculator.Core.Models.Calculation.Interfaces; using EvoCalculator.Core.Models.Calculation.Models; -namespace EvoCalculator.Core.Calculation.FinanceFormulas +namespace EvoCalculator.Core.FinanceFormulas { public class XIRR : IFinanceFormula { diff --git a/EvoCalculator.Core.Calculation/FinanceFormulas/XNPV.cs b/EvoCalculator.Core.FinanceFormulas/XNPV.cs similarity index 91% rename from EvoCalculator.Core.Calculation/FinanceFormulas/XNPV.cs rename to EvoCalculator.Core.FinanceFormulas/XNPV.cs index 05138d1..3c4e483 100644 --- a/EvoCalculator.Core.Calculation/FinanceFormulas/XNPV.cs +++ b/EvoCalculator.Core.FinanceFormulas/XNPV.cs @@ -3,7 +3,7 @@ using System.Linq; using EvoCalculator.Core.Models.Calculation.Interfaces; using EvoCalculator.Core.Models.Calculation.Models; -namespace EvoCalculator.Core.Calculation.FinanceFormulas +namespace EvoCalculator.Core.FinanceFormulas { public class XNPV : IFinanceFormula { diff --git a/EvoCalculator.Core.Models/Calculation/Interfaces/IColumnWithXIRR.cs b/EvoCalculator.Core.Models/Calculation/Interfaces/IColumnWithXIRR.cs new file mode 100644 index 0000000..61a64c4 --- /dev/null +++ b/EvoCalculator.Core.Models/Calculation/Interfaces/IColumnWithXIRR.cs @@ -0,0 +1,12 @@ +using System; +using EvoCalculator.Core.Models.Calculation.Models; + +namespace EvoCalculator.Core.Models.Calculation.Interfaces +{ + public interface IColumnWithXIRR : IColumn + { + public double IRR { get; set; } + public DateTime[] Dates { get; set; } + public void ComputeXIRR(); + } +} \ No newline at end of file diff --git a/EvoCalculator.Core.Tests/Calculation/Suite/Columns/SumColumnTest.cs b/EvoCalculator.Core.Tests/Calculation/Suite/Columns/SumColumnTest.cs new file mode 100644 index 0000000..ee44e30 --- /dev/null +++ b/EvoCalculator.Core.Tests/Calculation/Suite/Columns/SumColumnTest.cs @@ -0,0 +1,182 @@ +using System; +using EvoCalculator.Core.Calculation.Columns; +using EvoCalculator.Core.Models.Calculation.Models.Prepared; +using Xunit; + +namespace EvoCalculator.Core.Tests.Calculation.Suite.Columns +{ + public class SumColumnTest + { + [Fact] + public void SumColumnTest1() + { + var preparedValues = + new PreparedValues() + { + BaseCost = 2842960.70661055, + FirstPaymentSum = 636000, + Nmper = 30, + LastPaymentSum = 25440 + }; + + + var percentPaymentColumn = new PercentPaymentColumn(preparedValues.Nmper + 1) + { + Values = new[] + { + 0.00, + 0.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 100.00, + 0.00, + } + }; + + var dateTempColumn = new DateTempColumn() + { + Values = new[] + { + new DateTime(2018, 10, 31), + new DateTime(2018, 10, 31), + new DateTime(2018, 11, 30), + new DateTime(2018, 12, 31), + new DateTime(2019, 1, 31), + new DateTime(2019, 2, 28), + new DateTime(2019, 3, 31), + new DateTime(2019, 4, 30), + new DateTime(2019, 5, 31), + new DateTime(2019, 6, 30), + new DateTime(2019, 7, 31), + new DateTime(2019, 8, 31), + new DateTime(2019, 9, 30), + new DateTime(2019, 10, 31), + new DateTime(2019, 11, 30), + new DateTime(2019, 12, 31), + new DateTime(2020, 1, 31), + new DateTime(2020, 2, 29), + new DateTime(2020, 3, 31), + new DateTime(2020, 4, 30), + new DateTime(2020, 5, 31), + new DateTime(2020, 6, 30), + new DateTime(2020, 7, 31), + new DateTime(2020, 8, 31), + new DateTime(2020, 9, 30), + new DateTime(2020, 10, 31), + new DateTime(2020, 11, 30), + new DateTime(2020, 12, 31), + new DateTime(2021, 1, 31), + new DateTime(2021, 2, 28), + new DateTime(2021, 3, 31), + new DateTime(2021, 4, 30), + new DateTime(2021, 5, 31), + new DateTime(2021, 6, 30), + new DateTime(2021, 7, 31), + new DateTime(2021, 8, 31), + new DateTime(2021, 9, 30), + new DateTime(2021, 10, 31), + new DateTime(2021, 11, 30), + new DateTime(2021, 12, 31), + new DateTime(2022, 1, 31), + new DateTime(2022, 2, 28), + new DateTime(2022, 3, 31), + new DateTime(2022, 4, 30), + new DateTime(2022, 5, 31), + new DateTime(2022, 6, 30), + new DateTime(2022, 7, 31), + new DateTime(2022, 8, 31), + new DateTime(2022, 9, 30), + new DateTime(2022, 10, 31), + new DateTime(2022, 11, 30), + new DateTime(2022, 12, 31), + new DateTime(2023, 1, 31), + new DateTime(2023, 2, 28), + new DateTime(2023, 3, 31), + new DateTime(2023, 4, 30), + new DateTime(2023, 5, 31), + new DateTime(2023, 6, 30), + new DateTime(2023, 7, 31), + new DateTime(2023, 8, 31), + new DateTime(2023, 9, 30), + new DateTime(2023, 10, 31), + new DateTime(2023, 11, 30), + new DateTime(2023, 12, 31), + new DateTime(2024, 1, 31), + new DateTime(2024, 2, 29), + new DateTime(2024, 3, 31), + } + }; + + var sumColumn = new SumColumn(preparedValues.Nmper + 1, dateTempColumn); + sumColumn.ComputeValues(preparedValues, percentPaymentColumn); + + + var expected = new[] + { + -2842960.70661055, + 636000, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 98647.7277641429, + 25440, + }; + + var values = sumColumn.Values; + Assert.Equal(expected, values); + + + sumColumn.ComputeXIRR(); + Assert.InRange(sumColumn.IRR, 0.220325, 0.220327); + } + } +} \ No newline at end of file diff --git a/EvoCalculator.Core.Tests/Calculation/Suite/FinanceFormulasTests.cs b/EvoCalculator.Core.Tests/Calculation/Suite/FinanceFormulasTests.cs index eb258a9..022f0ab 100644 --- a/EvoCalculator.Core.Tests/Calculation/Suite/FinanceFormulasTests.cs +++ b/EvoCalculator.Core.Tests/Calculation/Suite/FinanceFormulasTests.cs @@ -1,6 +1,6 @@ using System; using System.Linq; -using EvoCalculator.Core.Calculation.FinanceFormulas; +using EvoCalculator.Core.FinanceFormulas; using EvoCalculator.Core.Models.Calculation.Models; using Xunit; using Xunit.Abstractions; diff --git a/EvoCalculator.Core.sln b/EvoCalculator.Core.sln index 70828bb..b994140 100644 --- a/EvoCalculator.Core.sln +++ b/EvoCalculator.Core.sln @@ -10,6 +10,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EvoCalculator.Core.Models", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EvoCalculator.Core.Constants", "EvoCalculator.Core.Constants\EvoCalculator.Core.Constants.csproj", "{A2774317-9EC4-425C-B63F-C5255BE2E5E2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EvoCalculator.Core.FinanceFormulas", "EvoCalculator.Core.FinanceFormulas\EvoCalculator.Core.FinanceFormulas.csproj", "{57FC4E65-3E6B-4C10-8792-58639D068F71}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,5 +38,9 @@ Global {A2774317-9EC4-425C-B63F-C5255BE2E5E2}.Debug|Any CPU.Build.0 = Debug|Any CPU {A2774317-9EC4-425C-B63F-C5255BE2E5E2}.Release|Any CPU.ActiveCfg = Release|Any CPU {A2774317-9EC4-425C-B63F-C5255BE2E5E2}.Release|Any CPU.Build.0 = Release|Any CPU + {57FC4E65-3E6B-4C10-8792-58639D068F71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57FC4E65-3E6B-4C10-8792-58639D068F71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57FC4E65-3E6B-4C10-8792-58639D068F71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57FC4E65-3E6B-4C10-8792-58639D068F71}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal