1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Linq ;
4
+ using System . Net . Security ;
1
5
using Model ;
2
6
3
7
namespace Services
4
8
{
5
9
public interface ISummaryService
6
10
{
7
- public record Summary ( decimal AbsoluteProfit , decimal RelativeProfit , decimal MarketValue ) ;
11
+ public record Summary ( decimal AbsoluteChange , decimal RelativeChange , decimal MarketValue , decimal Cost ) ;
8
12
9
13
public Summary GetMarketOrderSummary ( MarketOrder order , decimal assetPrice ) ;
10
-
11
- public Summary GetPortfolioEntrySummary ( PortfolioEntry entry , decimal assetPrice ) ;
12
-
13
- public Summary GetPortfolioSummary ( Portfolio entry , decimal assetPrice ) ;
14
+
15
+ public Summary GetPortfolioEntrySummary ( List < MarketOrder > portfolioEntryOrders , decimal assetPrice ) ;
16
+
17
+ public Summary GetPortfolioSummary ( Portfolio portfolio , Dictionary < string , decimal > assetPriceMap ) ;
14
18
}
15
-
16
- public class SummaryServiceImpl
19
+
20
+ public class SummaryServiceImpl : ISummaryService
17
21
{
18
-
22
+ public ISummaryService . Summary GetMarketOrderSummary ( MarketOrder order , decimal assetPrice )
23
+ {
24
+ var marketValue = order . Size * assetPrice ;
25
+ var cost = ( order . Size * order . FilledPrice ) + order . Fee ;
26
+ var relativeChange = ( marketValue / cost ) - new decimal ( 1 ) ;
27
+ var absoluteChange = marketValue - cost ;
28
+ return new ( absoluteChange , relativeChange , marketValue , cost ) ;
29
+ }
30
+
31
+ public ISummaryService . Summary GetAverageOfSummaries ( IEnumerable < ISummaryService . Summary > summaries )
32
+ {
33
+ decimal totalMarketValue = 0 ;
34
+ decimal totalCost = 0 ;
35
+ decimal totalAbsoluteChange = 0 ;
36
+
37
+ // iterate over all orders and compute their summaries
38
+ foreach ( var summary in summaries )
39
+ {
40
+ totalMarketValue += summary . MarketValue ;
41
+ totalCost += summary . Cost ;
42
+ totalAbsoluteChange += summary . AbsoluteChange ;
43
+ }
44
+
45
+ decimal totalRelativeChange = ( totalMarketValue / totalCost ) / - 1 ;
46
+
47
+ return new ( totalAbsoluteChange , totalRelativeChange , totalMarketValue , totalCost ) ;
48
+ }
49
+
50
+ public ISummaryService . Summary GetPortfolioEntrySummary ( List < MarketOrder > portfolioEntryOrders , decimal assetPrice )
51
+ {
52
+ decimal totalHoldingSize = 0 ;
53
+ decimal totalSellValue = 0 ;
54
+ decimal totalCost = 0 ;
55
+ decimal totalFee = 0 ;
56
+ portfolioEntryOrders
57
+ . ForEach ( order =>
58
+ {
59
+ totalHoldingSize += order . Size * ( order . Buy ? 1 : - 1 ) ;
60
+ var orderValue = order . Size * order . FilledPrice ;
61
+ if ( ! order . Buy )
62
+ {
63
+ totalSellValue += orderValue ;
64
+ }
65
+ else
66
+ {
67
+ totalCost += orderValue ;
68
+ }
69
+
70
+ totalFee += order . Fee ;
71
+ } ) ;
72
+
73
+ decimal currentTotalHoldingValue = totalHoldingSize * assetPrice ;
74
+
75
+ decimal totalAbsoluteChange = currentTotalHoldingValue + totalSellValue - totalCost - totalFee ;
76
+ decimal totalRelativeChange = totalAbsoluteChange / totalCost ;
77
+
78
+ return new ISummaryService . Summary ( totalAbsoluteChange , totalRelativeChange , currentTotalHoldingValue ,
79
+ totalCost + totalFee ) ;
80
+ }
81
+
82
+ public ISummaryService . Summary GetPortfolioSummary ( Portfolio portfolio ,
83
+ Dictionary < string , decimal > assetPriceMap )
84
+ {
85
+ return null ;
86
+ // var portfolioEntrySumarries = PortfolioEntryService.GetPortfolioEntries(portfolio.Id).Select(entry =>
87
+ // {
88
+ // if (!assetPriceMap.TryGetValue(entry.Symbol, out var assetPrice))
89
+ // {
90
+ // throw new AssetPriceNotFoundException();
91
+ // }
92
+
93
+ // return GetPortfolioEntrySummary(entry, assetPrice);
94
+ // });
95
+ // return GetAverageOfSummaries(portfolioEntrySumarries);
96
+ }
97
+
98
+ public class AssetPriceNotFoundException : Exception
99
+ {
100
+ }
19
101
}
20
102
}
0 commit comments