| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Finance::StockAccount::Realization; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '0.01'; |
|
4
|
|
|
|
|
|
|
|
|
5
|
7
|
|
|
7
|
|
596
|
use strict; |
|
|
7
|
|
|
|
|
15
|
|
|
|
7
|
|
|
|
|
234
|
|
|
6
|
7
|
|
|
7
|
|
25
|
use warnings; |
|
|
7
|
|
|
|
|
8
|
|
|
|
7
|
|
|
|
|
152
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
7
|
|
|
7
|
|
416
|
use Time::Moment; |
|
|
7
|
|
|
|
|
3531
|
|
|
|
7
|
|
|
|
|
119
|
|
|
9
|
7
|
|
|
7
|
|
26
|
use Carp; |
|
|
7
|
|
|
|
|
8
|
|
|
|
7
|
|
|
|
|
341
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
7
|
|
|
7
|
|
3234
|
use Finance::StockAccount::AccountTransaction; |
|
|
7
|
|
|
|
|
12
|
|
|
|
7
|
|
|
|
|
179
|
|
|
12
|
7
|
|
|
7
|
|
3213
|
use Finance::StockAccount::Acquisition; |
|
|
7
|
|
|
|
|
13
|
|
|
|
7
|
|
|
|
|
6162
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# qw(Symbol ROI Outlays Revenues Profit) |
|
15
|
|
|
|
|
|
|
my $summaryPattern = "%-6s %7.4f %12.2f %12.2f %53.2f\n"; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub new { |
|
18
|
1006
|
|
|
1006
|
0
|
1151
|
my ($class, $init) = @_; |
|
19
|
1006
|
|
|
|
|
4308
|
my $self = { |
|
20
|
|
|
|
|
|
|
stock => undef, |
|
21
|
|
|
|
|
|
|
divestment => undef, |
|
22
|
|
|
|
|
|
|
acquisitions => [], |
|
23
|
|
|
|
|
|
|
costBasis => 0, |
|
24
|
|
|
|
|
|
|
revenue => 0, |
|
25
|
|
|
|
|
|
|
realized => 0, |
|
26
|
|
|
|
|
|
|
commissions => 0, |
|
27
|
|
|
|
|
|
|
regulatoryFees => 0, |
|
28
|
|
|
|
|
|
|
otherFees => 0, |
|
29
|
|
|
|
|
|
|
}; |
|
30
|
1006
|
|
|
|
|
2125
|
bless($self, $class); |
|
31
|
1006
|
50
|
|
|
|
2320
|
$init and $self->set($init); |
|
32
|
1006
|
|
|
|
|
1665
|
return $self; |
|
33
|
|
|
|
|
|
|
} |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub addAcquisition { |
|
36
|
1504
|
|
|
1504
|
0
|
1389
|
my ($self, $acquisition, $dateLimitPortion) = @_; |
|
37
|
1504
|
100
|
|
|
|
2234
|
if (!defined($dateLimitPortion)) { |
|
38
|
4
|
|
|
|
|
5
|
$dateLimitPortion = 1; # Assume no date limit restriction if none specified, i.e., none by default |
|
39
|
|
|
|
|
|
|
} |
|
40
|
1504
|
|
|
|
|
2507
|
my $shares = $acquisition->shares(); |
|
41
|
1504
|
|
|
|
|
1689
|
my $divestment = $self->{divestment}; |
|
42
|
1504
|
|
|
|
|
2787
|
my $divQuantity = $divestment->quantity(); |
|
43
|
1504
|
|
|
|
|
1362
|
my $divestedPortion; |
|
44
|
1504
|
50
|
|
|
|
1854
|
if ($divQuantity) { |
|
45
|
1504
|
|
|
|
|
1518
|
$divestedPortion = $shares / $divQuantity; |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
else { |
|
48
|
0
|
|
|
|
|
0
|
croak "No shares divested in transaction, cannot proceed with realization."; |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
|
|
51
|
1504
|
|
|
|
|
2453
|
my $divCommission += $divestedPortion * $divestment->commission(); |
|
52
|
1504
|
|
|
|
|
2644
|
my $divRegulatoryFees += $divestedPortion * $divestment->regulatoryFees(); |
|
53
|
1504
|
|
|
|
|
2468
|
my $divOtherFees += $divestedPortion * $divestment->otherFees(); |
|
54
|
|
|
|
|
|
|
|
|
55
|
1504
|
|
|
|
|
2763
|
my $costBasis = 0 - $dateLimitPortion * $acquisition->cashEffect(); |
|
56
|
1504
|
|
|
|
|
2758
|
my $revenue = $dateLimitPortion * $divestedPortion * $divestment->cashEffect(); |
|
57
|
1504
|
|
|
|
|
1731
|
$self->{costBasis} += $costBasis; |
|
58
|
1504
|
|
|
|
|
1439
|
$self->{revenue} += $revenue; |
|
59
|
1504
|
|
|
|
|
1499
|
$self->{realized} += $revenue - $costBasis; |
|
60
|
1504
|
|
|
|
|
2630
|
$self->{commissions} += $dateLimitPortion * ($acquisition->commission() + $divCommission ); |
|
61
|
1504
|
|
|
|
|
2738
|
$self->{regulatoryFees} += $dateLimitPortion * ($acquisition->regulatoryFees() + $divRegulatoryFees); |
|
62
|
1504
|
|
|
|
|
2627
|
$self->{otherFees} += $dateLimitPortion * ($acquisition->otherFees() + $divOtherFees ); |
|
63
|
|
|
|
|
|
|
|
|
64
|
1504
|
|
|
|
|
1142
|
push(@{$self->{acquisitions}}, $acquisition); |
|
|
1504
|
|
|
|
|
2274
|
|
|
65
|
1504
|
|
|
|
|
2733
|
return 1; |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub set { |
|
69
|
1006
|
|
|
1006
|
0
|
890
|
my ($self, $init) = @_; |
|
70
|
1006
|
|
|
|
|
923
|
my $status = 1; |
|
71
|
1006
|
|
|
|
|
783
|
foreach my $key (keys %{$init}) { |
|
|
1006
|
|
|
|
|
2282
|
|
|
72
|
2012
|
50
|
|
|
|
2498
|
if (exists($self->{$key})) { |
|
73
|
2012
|
100
|
|
|
|
2907
|
if ($key eq 'divestment') { |
|
|
|
50
|
|
|
|
|
|
|
74
|
1006
|
|
|
|
|
853
|
my $divestment = $init->{$key}; |
|
75
|
1006
|
50
|
33
|
|
|
3214
|
if ($divestment and ref($divestment)) { |
|
76
|
1006
|
|
|
|
|
1798
|
$self->{divestment} = $divestment; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
else { |
|
79
|
0
|
|
|
|
|
0
|
$status = 0; |
|
80
|
0
|
|
|
|
|
0
|
warn "Invalid divestment value in Realization intialization hash.\n"; |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
elsif ($key eq 'stock') { |
|
84
|
1006
|
|
|
|
|
1612
|
$self->{$key} = $init->{$key}; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
else { |
|
87
|
0
|
|
|
|
|
0
|
$status = 0; |
|
88
|
0
|
|
|
|
|
0
|
warn "Unable to initialize Realization object with $key parameter.\n"; |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
else { |
|
92
|
0
|
|
|
|
|
0
|
$status = 0; |
|
93
|
0
|
|
|
|
|
0
|
warn "Tried to set $key in Realization object, but that's not a known key.\n"; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
} |
|
96
|
1006
|
|
|
|
|
1353
|
return $status; |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub ROI { |
|
100
|
54
|
|
|
54
|
0
|
49
|
my $self = shift; |
|
101
|
54
|
|
|
|
|
58
|
my $costBasis = $self->{costBasis}; |
|
102
|
54
|
50
|
|
|
|
73
|
if ($costBasis) { |
|
103
|
54
|
|
|
|
|
553
|
return $self->{realized} / $costBasis; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
else { |
|
106
|
0
|
|
|
|
|
0
|
warn "Realize method finds no cost basis upon which to compute ROI.\n"; |
|
107
|
0
|
|
|
|
|
0
|
return undef; |
|
108
|
|
|
|
|
|
|
} |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub acquisitionCount { |
|
112
|
1005
|
|
|
1005
|
0
|
952
|
my $self = shift; |
|
113
|
1005
|
|
|
|
|
742
|
return scalar(@{$self->{acquisitions}}); |
|
|
1005
|
|
|
|
|
3495
|
|
|
114
|
|
|
|
|
|
|
} |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub startDate { |
|
117
|
387
|
|
|
387
|
0
|
333
|
my $self = shift; |
|
118
|
387
|
|
|
|
|
330
|
my $startDate; |
|
119
|
387
|
|
|
|
|
338
|
foreach my $acquisition (@{$self->{acquisitions}}) { |
|
|
387
|
|
|
|
|
565
|
|
|
120
|
667
|
100
|
|
|
|
1941
|
if (!$startDate) { |
|
121
|
387
|
|
|
|
|
713
|
$startDate = $acquisition->tm(); |
|
122
|
|
|
|
|
|
|
} |
|
123
|
|
|
|
|
|
|
else { |
|
124
|
280
|
|
|
|
|
472
|
my $tm = $acquisition->tm(); |
|
125
|
280
|
100
|
|
|
|
755
|
if ($tm < $startDate) { |
|
126
|
186
|
|
|
|
|
301
|
$startDate = $tm; |
|
127
|
|
|
|
|
|
|
} |
|
128
|
|
|
|
|
|
|
} |
|
129
|
|
|
|
|
|
|
} |
|
130
|
387
|
|
|
|
|
958
|
return $startDate; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub endDate { |
|
134
|
387
|
|
|
387
|
0
|
340
|
my $self = shift; |
|
135
|
387
|
|
|
|
|
387
|
my $divestment = $self->{divestment}; |
|
136
|
387
|
|
|
|
|
651
|
return $divestment->tm(); |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
|
140
|
378
|
|
|
378
|
0
|
790
|
sub divestment { return shift->{divestment}; } |
|
141
|
378
|
|
|
378
|
0
|
693
|
sub acquisitions { return shift->{acquisitions}; } |
|
142
|
1277
|
|
|
1277
|
0
|
3346
|
sub costBasis { return shift->{costBasis}; } |
|
143
|
890
|
|
|
890
|
0
|
2053
|
sub revenue { return shift->{revenue}; } |
|
144
|
389
|
|
|
389
|
0
|
755
|
sub realized { return shift->{realized}; } |
|
145
|
387
|
|
|
387
|
0
|
571
|
sub commissions { return shift->{commissions}; } |
|
146
|
387
|
|
|
387
|
0
|
535
|
sub regulatoryFees { return shift->{regulatoryFees}; } |
|
147
|
387
|
|
|
387
|
0
|
564
|
sub otherFees { return shift->{otherFees}; } |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub headerString { |
|
150
|
2
|
|
|
2
|
0
|
327
|
return Finance::StockAccount::Transaction->lineFormatHeader() . '-'x94 . "\n" . |
|
151
|
|
|
|
|
|
|
sprintf("%-6s %7s %12s %12s %53s\n", qw(Symbol ROI Outlays Revenues Profit)); |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub divestmentLineFormatString { |
|
155
|
54
|
|
|
54
|
0
|
48
|
my $self = shift; |
|
156
|
54
|
|
|
|
|
58
|
my $divestment = $self->{divestment}; |
|
157
|
54
|
|
|
|
|
97
|
my $proportion = $divestment->accounted() / $divestment->quantity(); |
|
158
|
54
|
|
|
|
|
96
|
my $lineFormatValues = $divestment->lineFormatValues(); |
|
159
|
54
|
|
|
|
|
61
|
$lineFormatValues->[5] *= $proportion; |
|
160
|
54
|
|
|
|
|
47
|
$lineFormatValues->[6] *= $proportion; |
|
161
|
54
|
|
|
|
|
35
|
$lineFormatValues->[7] *= $proportion; |
|
162
|
54
|
|
|
|
|
116
|
return sprintf(Finance::StockAccount::Transaction->lineFormatPattern(), @$lineFormatValues); |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
sub string { |
|
166
|
54
|
|
|
54
|
0
|
53
|
my $self = shift; |
|
167
|
54
|
|
|
|
|
64
|
my $divestment = $self->{divestment}; |
|
168
|
54
|
|
|
|
|
45
|
my $string; |
|
169
|
54
|
|
|
|
|
42
|
foreach my $acquisition (@{$self->{acquisitions}}) { |
|
|
54
|
|
|
|
|
90
|
|
|
170
|
93
|
|
|
|
|
196
|
$string .= $acquisition->lineFormatString(); |
|
171
|
|
|
|
|
|
|
} |
|
172
|
54
|
|
50
|
|
|
90
|
$string .= $self->divestmentLineFormatString . '-'x94 . "\n" . |
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sprintf($summaryPattern, $divestment->symbol(), $self->ROI() || 0, (0 - $self->{costBasis}) || 0, $self->{revenue} || 0, $self->{realized} || 0); |
|
174
|
54
|
|
|
|
|
228
|
return $string; |
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
1; |