File Coverage

blib/lib/Finance/SE/Catalog.pm
Criterion Covered Total %
statement 66 66 100.0
branch 23 32 71.8
condition n/a
subroutine 8 8 100.0
pod 5 5 100.0
total 102 111 91.8


line stmt bran cond sub pod time code
1             package Finance::SE::Catalog;
2              
3             our $DATE = '2018-09-19'; # DATE
4             our $VERSION = '20180919.1.0'; # VERSION
5              
6 1     1   75751 use 5.010001;
  1         14  
7 1     1   6 use strict;
  1         2  
  1         31  
8 1     1   6 use warnings;
  1         2  
  1         1005  
9              
10             # BEGIN FRAGMENT id=meta-financial_market
11             # note: This fragment's content is generated by a script. Do not edit manually!
12             # src-file: /zpool_host_mnt/mnt/home/u1/repos/gudangdata/bin/../table/financial_market/meta.yaml
13             # src-revision: 19df7615c59fa8815c66595ccb9c708dd291b1be (Wed Sep 19 19:58:54 2018 +0700)
14             # generate-date: Wed Sep 19 12:59:45 2018 UTC
15             # generated-by: update-fragments-in-perl-module
16             our $meta = {
17             fields => {
18             add_codes => {
19             pos => 8,
20             schema => "str*",
21             sortable => 1,
22             summary => "Additional codes (each code separated by semicolon)",
23             unique => 0,
24             },
25             add_names => {
26             pos => 7,
27             schema => "str*",
28             sortable => 1,
29             summary => "Additional names (each name separated by semicolon)",
30             unique => 0,
31             },
32             add_yf_codes => {
33             pos => 4,
34             schema => "str*",
35             sortable => 1,
36             summary => "Additional Yahoo! Finance codes (each code separated by semicolon)",
37             unique => 0,
38             },
39             city => { pos => 10, schema => "str*", sortable => 1, summary => "City", unique => 0 },
40             code => {
41             pos => 0,
42             schema => "str*",
43             sortable => 1,
44             summary => "Code (usually popular acronym if unique, otherwise MIC)",
45             unique => 1,
46             },
47             country_code => {
48             pos => 9,
49             schema => "str*",
50             sortable => 1,
51             summary => "ISO 2-letter country code",
52             unique => 0,
53             },
54             eng_name => {
55             pos => 5,
56             schema => "str*",
57             sortable => 1,
58             summary => "English name",
59             unique => 1,
60             },
61             local_name => { pos => 6, schema => "str*", sortable => 1, summary => "Local name", unique => 0 },
62             mic => {
63             pos => 1,
64             schema => ["str*", { len => 4 }],
65             sortable => 1,
66             summary => "Market Identifier Code (ISO 10383)",
67             unique => 1,
68             },
69             status => { pos => 12, schema => "str*", sortable => 1, summary => "Status", unique => 0 },
70             types => {
71             pos => 2,
72             schema => "str*",
73             sortable => 1,
74             summary => "Types (each type separated by semicolon)",
75             unique => 0,
76             },
77             year_founded => {
78             pos => 11,
79             schema => "str*",
80             sortable => 1,
81             summary => "Year founded",
82             unique => 0,
83             },
84             yf_code => {
85             pos => 3,
86             schema => "str*",
87             sortable => 1,
88             summary => "Yahoo! Finance code",
89             unique => 0,
90             },
91             },
92             header => 1,
93             pk => "code",
94             summary => "Catalog (list) of stock exchanges",
95             };
96             # END FRAGMENT id=meta-financial_market
97              
98             # BEGIN FRAGMENT id=data-financial_market row_as_hash=1
99             # note: This fragment's content is generated by a script. Do not edit manually!
100             # src-file: /zpool_host_mnt/mnt/home/u1/repos/gudangdata/bin/../table/financial_market/data.csv
101             # src-revision: 19df7615c59fa8815c66595ccb9c708dd291b1be (Wed Sep 19 19:58:54 2018 +0700)
102             # generate-date: Wed Sep 19 12:59:45 2018 UTC
103             # generated-by: update-fragments-in-perl-module
104             our $data = [
105             {
106             add_codes => "",
107             add_names => "",
108             add_yf_codes => "",
109             city => "New York City",
110             code => "NYSE",
111             country_code => "US",
112             eng_name => "New York Stock Exchange",
113             local_name => "",
114             mic => "XNYS",
115             status => "active",
116             types => "SE",
117             year_founded => 1792,
118             yf_code => "",
119             },
120             {
121             add_codes => "",
122             add_names => "",
123             add_yf_codes => "",
124             city => "New York City",
125             code => "NASDAQ",
126             country_code => "US",
127             eng_name => "Nasdaq Stock Exchange",
128             local_name => "",
129             mic => "XNAS",
130             status => "active",
131             types => "SE",
132             year_founded => 1971,
133             yf_code => "",
134             },
135             {
136             add_codes => "BEI;BEJ",
137             add_names => "Bursa Efek Jakarta",
138             add_yf_codes => "",
139             city => "Jakarta",
140             code => "IDX",
141             country_code => "ID",
142             eng_name => "Indonesia Stock Exchange",
143             local_name => "Bursa Efek Indonesia",
144             mic => "XIDX",
145             status => "active",
146             types => "SE",
147             year_founded => 1912,
148             yf_code => "JK",
149             },
150             {
151             add_codes => "",
152             add_names => "",
153             add_yf_codes => "IL",
154             city => "London",
155             code => "LSX",
156             country_code => "GB",
157             eng_name => "London Stock Exchange",
158             local_name => "",
159             mic => "XLON",
160             status => "active",
161             types => "SE",
162             year_founded => 1698,
163             yf_code => "L",
164             },
165             {
166             add_codes => "",
167             add_names => "Singapore Stock Exchange;Stock Exchange of Singapore",
168             add_yf_codes => "",
169             city => "Singapore",
170             code => "SGX",
171             country_code => "SG",
172             eng_name => "Singapore Exchange",
173             local_name => "",
174             mic => "XSES",
175             status => "active",
176             types => "SE",
177             year_founded => 1973,
178             yf_code => "SI",
179             },
180             ];
181             # END FRAGMENT id=data-financial_market
182              
183             my %code_occurrences;
184             my %se_by_primary_code;
185             my %se_by_code;
186             my %name_occurrences;
187             my %se_by_primary_name_lc;
188             my %se_by_name_lc;
189              
190             sub new {
191 1     1 1 88 my $class = shift;
192              
193 1 50       5 unless (keys %code_occurrences) {
194             # primary code & name
195 1         4 for my $rec (@$data) {
196             # XXX check uniqueness of primary code & eng_name
197 5         12 $code_occurrences{$rec->{code}}++;
198 5         11 $se_by_primary_code{$rec->{code}} = $rec;
199 5         9 $se_by_code{$rec->{code}} = $rec;
200 5         10 my $name_lc = lc $rec->{eng_name};
201 5         10 $name_occurrences{$name_lc}++;
202 5         8 $se_by_primary_name_lc{$name_lc} = $rec;
203 5         10 $se_by_name_lc{$name_lc} = $rec;
204             }
205 1         3 for my $rec (@$data) {
206             # mic
207 5         11 for ($rec->{mic}) {
208 5 50       12 next if $se_by_primary_code{$_};
209 5         10 $code_occurrences{$_}++;
210 5         10 $se_by_code{$_} = $rec;
211             }
212              
213             # yahoo finance codes
214 5 100       13 if (length $rec->{yf_code}) {
215 3         5 for ($rec->{yf_code}) {
216 3 50       8 next if $se_by_primary_code{$_};
217 3         7 $code_occurrences{$_}++;
218 3         11 $se_by_code{$_} = $rec;
219             }
220 3 100       7 if (length $rec->{add_yf_codes}) {
221 1         4 for (split /;/, $rec->{add_yf_codes}) {
222 1 50       2 next if $se_by_primary_code{$_};
223 1         2 $code_occurrences{$_}++;
224 1         2 $se_by_code{$_} = $rec;
225             }
226             }
227             }
228              
229             # additional codes
230 5 100       12 if (length $rec->{add_codes}) {
231 1         4 for (split /;/, $rec->{add_codes}) {
232 2 50       5 next if $se_by_primary_code{$_};
233 2         4 $code_occurrences{$_}++;
234 2         4 $se_by_code{$_} = $rec;
235             }
236             }
237              
238             # local name
239 5 100       9 if (length $rec->{local_name}) {
240 1         4 for (lc $rec->{local_name}) {
241 1 50       4 next if $se_by_primary_name_lc{$_};
242 1         2 $name_occurrences{$_}++;
243 1         2 $se_by_name_lc{$_} = $rec;
244             }
245             }
246              
247             # additional names
248 5 100       18 if (length $rec->{add_names}) {
249 2         7 for (split /;/, lc $rec->{add_names}) {
250 3 50       7 next if $se_by_primary_name_lc{$_};
251 3         6 $name_occurrences{$_}++;
252 3         7 $se_by_name_lc{$_} = $rec;
253             }
254             }
255             }
256              
257             }
258 1         4 bless {}, $class;
259             }
260              
261             sub by_code {
262 4     4 1 1102 my ($self, $code) = @_;
263 4         9 $code = uc($code);
264             die "Can't find stock exchange with code '$code'"
265 4 100       24 unless my $rec = $se_by_code{$code};
266             die "Ambiguous stock exchange code '$code' (refers to multiple exchanges)"
267 3 50       7 unless $code_occurrences{$code} == 1;
268 3         12 $rec;
269             }
270              
271             sub by_name {
272 3     3 1 2409 my ($self, $name) = @_;
273 3         7 $name = lc $name;
274             die "Can't find stock exchange with name '$name'"
275 3 100       19 unless my $rec = $se_by_name_lc{$name};
276             die "Ambiguous stock exchange name '$name' (refers to multiple exchanges)"
277 2 50       7 unless $name_occurrences{$name} == 1;
278 2         8 $rec;
279             }
280              
281             sub all_codes {
282 1     1 1 2166 my $self = shift;
283 1         2 my @res;
284 1         4 for (@$data) {
285 5         10 push @res, $_->{code};
286             }
287 1         5 @res;
288             }
289              
290             sub all_data {
291 1     1 1 2107 my $self = shift;
292 1         3 @$data;
293             }
294              
295             1;
296             # ABSTRACT: Catalog (list) of stock exchanges
297              
298             __END__