add finance functions

This commit is contained in:
Chika 2020-10-13 15:42:42 +03:00
parent 098bfa5cd1
commit 67169eeec5
11 changed files with 391 additions and 29 deletions

View File

@ -38,6 +38,10 @@
<e p="EvoCalculator.Core.Calculation" t="IncludeRecursive">
<e p="bin" t="ExcludeRecursive" />
<e p="EvoCalculator.Core.Calculation.csproj" t="IncludeRecursive" />
<e p="FinanceFormulas" t="Include">
<e p="XIRR.cs" t="Include" />
<e p="XNPV.cs" t="Include" />
</e>
<e p="obj" t="ExcludeRecursive">
<e p="Debug" t="Include">
<e p="netcoreapp3.1" t="Include">
@ -47,12 +51,17 @@
</e>
</e>
<e p="EvoCalculator.Core.Models" t="IncludeRecursive">
<e p="API" t="Include">
<e p="bin" t="ExcludeRecursive" />
<e p="Calculation" t="Include">
<e p="Interfaces" t="Include">
<e p="IFinanceFormula.cs" t="Include" />
</e>
<e p="Models" t="Include">
<e p="FlowValues.cs" t="Include" />
<e p="Request" t="Include" />
<e p="Response" t="Include" />
</e>
<e p="bin" t="ExcludeRecursive" />
<e p="Calculation" t="Include" />
</e>
<e p="EvoCalculator.Core.Models.csproj" t="IncludeRecursive" />
<e p="obj" t="ExcludeRecursive">
<e p="Debug" t="Include">
@ -71,6 +80,12 @@
<e p="EvoCalculator.Core.sln" t="IncludeFlat" />
<e p="EvoCalculator.Core.Tests" t="IncludeRecursive">
<e p="bin" t="ExcludeRecursive" />
<e p="Calculation" t="Include">
<e p="Controllers" t="Include" />
<e p="Suite" t="Include">
<e p="FinanceFormulasTests.cs" t="Include" />
</e>
</e>
<e p="EvoCalculator.Core.Tests.csproj" t="IncludeRecursive" />
<e p="obj" t="ExcludeRecursive">
<e p="Debug" t="Include">

View File

@ -14,16 +14,17 @@
</component>
<component name="ChangeListManager">
<list default="true" id="2c3b0650-5589-43d4-b4b7-2979612bb30f" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Calculation/EvoCalculator.Core.Calculation.csproj" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Models/EvoCalculator.Core.Models.csproj" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Tests/EvoCalculator.Core.Tests.csproj" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Calculation/FinanceFormulas/XIRR.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Calculation/FinanceFormulas/XNPV.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Models/Calculation/Interfaces/IFinanceFormula.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Models/Calculation/Models/FlowValues.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.Tests/Calculation/Suite/FinanceFormulasTests.cs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/EvoCalculator.Core.sln.DotSettings.user" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.EvoCalculator.Core/.idea/contentModel.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.EvoCalculator.Core/.idea/contentModel.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.EvoCalculator.Core/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.EvoCalculator.Core/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core.sln" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core.sln" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core/Controllers/WeatherForecastController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core/Controllers/v1/WeatherForecastController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core/EvoCalculator.Core.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core/EvoCalculator.Core.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core/Startup.cs" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core/Startup.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core/WeatherForecast.cs" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core.Models/Weather/WeatherForecast.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core.Calculation/EvoCalculator.Core.Calculation.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core.Calculation/EvoCalculator.Core.Calculation.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core.Models/EvoCalculator.Core.Models.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core.Models/EvoCalculator.Core.Models.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/EvoCalculator.Core.Tests/EvoCalculator.Core.Tests.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/EvoCalculator.Core.Tests/EvoCalculator.Core.Tests.csproj" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -33,6 +34,10 @@
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/9D995D4A-0EBE-4A93-85A6-BE06CB7C70EE/f6/ada9c10c/FactAttribute.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/9152434B-0FAC-463B-87F2-DD9AF798817F/2e/201d3c41/Assert.cs" root0="SKIP_HIGHLIGHTING" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
@ -40,11 +45,21 @@
<option value="$PROJECT_DIR$/EvoCalculator.Core.Calculation/Class1.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Class1.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core/Controllers/WeatherForecastController.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Weather/WeatherForecast.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core/Startup.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core/Controllers/v2/WeatherForecastController.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core/Controllers/v3/WeatherForecastController.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Interfaces/IWeatherForecast.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Weather/WeatherForecast.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Weather/Interfaces/IWeatherForecast.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core/Controllers/v1/WeatherForecastController.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Tests/Controllers/WeatherForecastControllerTests.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Calculation/FinanceFormulas.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Calculation/IFinanceFormula.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Calculation/Interfaces/IFinanceFormula.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Models/Calculation/Models/FlowValues.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Calculation/FinanceFormulas/XNPV.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Tests/Calculation/Suite/FinanceFormulasTests.cs" />
<option value="$PROJECT_DIR$/EvoCalculator.Core.Calculation/FinanceFormulas/XIRR.cs" />
</list>
</option>
</component>
@ -58,9 +73,12 @@
</component>
<component name="PropertiesComponent">
<property name="ASKED_ADD_EXTERNAL_FILES" value="true" />
<property name="DebuggerViewTab_PTCS_FirstProportionKey" value="0.34995976" />
<property name="DebuggerViewTab_PTCS_LastProportionKey" value="0.30008045" />
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="nodejs_package_manager_path" value="npm" />
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.IDE.editor.colors" />
<property name="vue.rearranger.settings.migration" value="true" />
</component>
<component name="RunManager" selected=".NET Launch Settings Profile.EvoCalculator.Core">
@ -103,14 +121,15 @@
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1602504351800</updated>
<workItem from="1602504354370" duration="3857000" />
<workItem from="1602504354370" duration="6573000" />
<workItem from="1602584653395" duration="7652000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="UnityProjectConfiguration" hasMinimizedUI="null" />
<component name="UnityProjectConfiguration" hasMinimizedUI="false" />
<component name="UnityUnitTestConfiguration" currentTestLauncher="NUnit" />
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
@ -122,6 +141,7 @@
</entry>
</map>
</option>
<option name="oldMeFiltersMigrated" value="true" />
</component>
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
@ -136,29 +156,117 @@
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="734" y="355" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602508288549" />
<state width="2517" height="185" key="GridCell.Tab.0.bottom" timestamp="1602508304223">
<state width="411" height="464" key="DebuggerActiveHint" timestamp="1602590961523">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="185" key="GridCell.Tab.0.bottom/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602508304223" />
<state width="2517" height="185" key="GridCell.Tab.0.center" timestamp="1602508304222">
<state width="411" height="464" key="DebuggerActiveHint/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602590961523" />
<state width="2517" height="368" key="GridCell.Tab.0.bottom" timestamp="1602592375552">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="185" key="GridCell.Tab.0.center/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602508304222" />
<state width="2517" height="185" key="GridCell.Tab.0.left" timestamp="1602508304221">
<state width="2517" height="368" key="GridCell.Tab.0.bottom/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375552" />
<state width="2517" height="368" key="GridCell.Tab.0.center" timestamp="1602592375552">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="185" key="GridCell.Tab.0.left/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602508304221" />
<state width="2517" height="185" key="GridCell.Tab.0.right" timestamp="1602508304222">
<state width="2517" height="368" key="GridCell.Tab.0.center/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375552" />
<state width="2517" height="368" key="GridCell.Tab.0.left" timestamp="1602592375551">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="185" key="GridCell.Tab.0.right/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602508304222" />
<state width="2517" height="368" key="GridCell.Tab.0.left/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375551" />
<state width="2517" height="368" key="GridCell.Tab.0.right" timestamp="1602592375552">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.0.right/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375552" />
<state width="2517" height="368" key="GridCell.Tab.1.bottom" timestamp="1602592375553">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.1.bottom/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375553" />
<state width="2517" height="368" key="GridCell.Tab.1.center" timestamp="1602592375553">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.1.center/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375553" />
<state width="2517" height="368" key="GridCell.Tab.1.left" timestamp="1602592375552">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.1.left/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375552" />
<state width="2517" height="368" key="GridCell.Tab.1.right" timestamp="1602592375553">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.1.right/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375553" />
<state width="2517" height="368" key="GridCell.Tab.2.bottom" timestamp="1602592375554">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.2.bottom/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375554" />
<state width="2517" height="368" key="GridCell.Tab.2.center" timestamp="1602592375553">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.2.center/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375553" />
<state width="2517" height="368" key="GridCell.Tab.2.left" timestamp="1602592375553">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.2.left/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375553" />
<state width="2517" height="368" key="GridCell.Tab.2.right" timestamp="1602592375554">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.2.right/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375554" />
<state width="2517" height="368" key="GridCell.Tab.3.bottom" timestamp="1602592375555">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.3.bottom/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375555" />
<state width="2517" height="368" key="GridCell.Tab.3.center" timestamp="1602592375554">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.3.center/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375554" />
<state width="2517" height="368" key="GridCell.Tab.3.left" timestamp="1602592375554">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.3.left/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375554" />
<state width="2517" height="368" key="GridCell.Tab.3.right" timestamp="1602592375555">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.3.right/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375555" />
<state width="2517" height="368" key="GridCell.Tab.4.bottom" timestamp="1602592375557">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.4.bottom/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375557" />
<state width="2517" height="368" key="GridCell.Tab.4.center" timestamp="1602592375555">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.4.center/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375555" />
<state width="2517" height="368" key="GridCell.Tab.4.left" timestamp="1602592375555">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.4.left/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375555" />
<state width="2517" height="368" key="GridCell.Tab.4.right" timestamp="1602592375555">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="2517" height="368" key="GridCell.Tab.4.right/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602592375555" />
<state x="872" y="432" key="Rider.ProjectTemplateDialog.Size" timestamp="1602504924550">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="872" y="432" key="Rider.ProjectTemplateDialog.Size/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602504924550" />
<state x="92" y="92" width="2376" height="1216" key="VCS.FileHistoryDialog" timestamp="1602505640103">
<state x="1078" y="410" key="RollbackChangesDialog" timestamp="1602585122733">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="92" y="92" width="2376" height="1216" key="VCS.FileHistoryDialog/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602505640103" />
<state x="1078" y="410" key="RollbackChangesDialog/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602585122733" />
<state x="781" y="345" key="SettingsEditor" timestamp="1602587357897">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="781" y="345" key="SettingsEditor/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602587357897" />
<state width="498" height="446" key="SwitcherDM" timestamp="1602586590437">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state width="498" height="446" key="SwitcherDM/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602586590437" />
<state x="92" y="92" width="2376" height="1216" key="VCS.FileHistoryDialog" timestamp="1602585129305">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="92" y="92" width="2376" height="1216" key="VCS.FileHistoryDialog/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602585129305" />
<state x="872" y="433" key="Vcs.Push.Dialog.v2" timestamp="1602509069261">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="872" y="433" key="Vcs.Push.Dialog.v2/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602509069261" />
<state x="943" y="315" width="672" height="678" key="search.everywhere.popup" timestamp="1602590571064">
<screen x="0" y="0" width="2560" height="1400" />
</state>
<state x="943" y="315" width="672" height="678" key="search.everywhere.popup/0.0.2560.1400/2560.0.1920.1040@0.0.2560.1400" timestamp="1602590571064" />
</component>
</project>

View File

@ -4,4 +4,8 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EvoCalculator.Core.Models\EvoCalculator.Core.Models.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,73 @@
using System;
using EvoCalculator.Core.Models.Calculation.Interfaces;
using EvoCalculator.Core.Models.Calculation.Models;
namespace EvoCalculator.Core.Calculation.FinanceFormulas
{
public class XIRR : IFinanceFormula<double>
{
private FlowValue[] _values;
private double _guess = 0.1;
public XIRR(FlowValue[] values)
{
_values = values;
}
public XIRR(FlowValue[] values, double guess)
{
_values = values;
_guess = guess;
}
public double GetResult()
{
var x1 = 0.0;
var x2 = _guess;
var f1 = new XNPV(_values, x1).GetResult();
var f2 = new XNPV(_values, x2).GetResult();
for (var i = 0; i < 100; i++)
{
if (f1 * f2 < 0.0) break;
if (Math.Abs(f1) < Math.Abs(f2))
{
x1 += 1.6 * (x1 - x2);
f1 = new XNPV(_values, x1).GetResult();
}
else
{
x2 += 1.6 * (x2 - x1);
f2 = new XNPV(_values, x2).GetResult();
}
}
if (f1 * f2 > 0.0) return 0;
var f = new XNPV(_values, x1).GetResult();
var dx = 0.0;
var rtb = 0.0;
if (f < 0.0)
{
rtb = x1;
dx = x2 - x1;
}
else
{
rtb = x2;
dx = x1 - x2;
}
for (var i = 0; i < 100; i++)
{
dx *= 0.5;
var xMid = rtb + dx;
var fMid = new XNPV(_values, xMid).GetResult();
if (fMid <= 0.0) rtb = xMid;
if (Math.Abs(fMid) < 1.0e-6 || Math.Abs(dx) < 1.0e-6) return xMid;
}
return 0;
}
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Linq;
using EvoCalculator.Core.Models.Calculation.Interfaces;
using EvoCalculator.Core.Models.Calculation.Models;
namespace EvoCalculator.Core.Calculation.FinanceFormulas
{
public class XNPV : IFinanceFormula<double>
{
private FlowValue[] _values;
private double _rate;
public XNPV(FlowValue[] values, double rate)
{
_values = values;
_rate = rate;
}
public double GetResult()
{
var firstDate = _values[0].Date;
return _values.Sum(flowValue =>
flowValue.Flow / Math.Pow(1 + _rate, (flowValue.Date - firstDate).TotalDays / 365));
}
}
}

View File

@ -0,0 +1,7 @@
namespace EvoCalculator.Core.Models.Calculation.Interfaces
{
public interface IFinanceFormula<out T>
{
public T GetResult();
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace EvoCalculator.Core.Models.Calculation.Models
{
public class FlowValue
{
public DateTime Date;
public double Flow;
}
}

View File

@ -5,9 +5,8 @@
</PropertyGroup>
<ItemGroup>
<Folder Include="API\Request" />
<Folder Include="API\Response" />
<Folder Include="Calculation" />
<Folder Include="Calculation\Models\Request" />
<Folder Include="Calculation\Models\Response" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,106 @@
using System;
using System.Linq;
using EvoCalculator.Core.Calculation.FinanceFormulas;
using EvoCalculator.Core.Models.Calculation.Models;
using Xunit;
using Xunit.Abstractions;
namespace EvoCalculator.Core.Tests.Calculation.Suite
{
public class FinanceFormulasTests
{
private readonly ITestOutputHelper output;
readonly FlowValue[] _flowValues =
{
new FlowValue
{
Date = new DateTime(2020, 09, 01),
Flow = -6500000
},
new FlowValue
{
Date = new DateTime(2020, 09, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2020, 10, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2020, 11, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2020, 12, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 1, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 2, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 3, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 4, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 5, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 6, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 7, 01),
Flow = 608944.445718643
},
new FlowValue
{
Date = new DateTime(2021, 8, 01),
Flow = 608944.445718643
},
};
public FinanceFormulasTests(ITestOutputHelper output)
{
this.output = output;
}
[Fact]
public void XNPVTest()
{
var XNPV = new XNPV(_flowValues.Skip(1).ToArray(), 0.3);
var res = XNPV.GetResult();
output.WriteLine(res.ToString());
Assert.InRange(res, 6490000, 6590000);
}
[Fact]
public void XIRRTest()
{
var XIRR = new XIRR(_flowValues);
var res = XIRR.GetResult();
output.WriteLine(res.ToString());
Assert.InRange(res, 0.29, 0.31);
}
}
}

View File

@ -13,4 +13,13 @@
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EvoCalculator.Core.Calculation\EvoCalculator.Core.Calculation.csproj" />
<ProjectReference Include="..\EvoCalculator.Core\EvoCalculator.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Calculation\Controllers" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=90125dce_002D8b20_002D4c11_002D807a_002Da58620eb7b69/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Solution /&gt;&#xD;
&lt;/SessionState&gt;</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=XIRR/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>