File Coverage

lib/Finance/Robinhood/Equity/Market.pm
Criterion Covered Total %
statement 53 53 100.0
branch 2 8 25.0
condition 4 8 50.0
subroutine 14 14 100.0
pod 3 3 100.0
total 76 86 88.3


line stmt bran cond sub pod time code
1             package Finance::Robinhood::Equity::Market;
2              
3             =encoding utf-8
4              
5             =for stopwords watchlist watchlists untradable urls
6              
7             =head1 NAME
8              
9             Finance::Robinhood::Equity::Market - Represents a Single Equity Market
10              
11             =head1 SYNOPSIS
12              
13             use Finance::Robinhood;
14             my $rh = Finance::Robinhood->new;
15             my $msft = $rh->equity_instrument_by_symbol('MSFT');
16              
17             CORE::say $msft->symbol . ' is traded on ' . $msft->market->name;
18              
19             =cut
20              
21             our $VERSION = '0.92_003';
22 1     1   7 use Mojo::Base-base, -signatures;
  1         2  
  1         6  
23 1     1   182 use Mojo::URL;
  1         2  
  1         6  
24 1     1   37 use Time::Moment;
  1         2  
  1         28  
25 1     1   413 use Finance::Robinhood::Equity::Market::Hours;
  1         3  
  1         25  
26              
27             sub _test__init {
28 1     1   15342 my $rh = t::Utility::rh_instance(0);
29 1         17 my $market = $rh->equity_market_by_mic('XNAS'); # NASDAQ
30 1         726 isa_ok($market, __PACKAGE__);
31 1         418 t::Utility::stash('MARKET', $market); # Store it for later
32             }
33 1     1   104 use overload '""' => sub ($s, @) { $s->{url} }, fallback => 1;
  1     5   2  
  1         4  
  5         9  
  5         31  
  5         331  
  5         11  
34              
35             sub _test_stringify {
36 1   50 1   2977 t::Utility::stash('MARKET') // skip_all();
37 1         5 is(+t::Utility::stash('MARKET'),
38             'https://api.robinhood.com/markets/XNAS/');
39             }
40             #
41             has _rh => undef => weak => 1;
42              
43             =head1 METHODS
44              
45             =head2 C
46              
47             Simple acronym typically used to identify the exchange. Note that the same
48             acronym may be used for more than one venue.
49              
50             =head2 C
51              
52             Location of the exchange/market.
53              
54             =head2 C
55              
56             Location of the exchange/market.
57              
58             =head2 C
59              
60             Returns the ISO 10383 Market Identifier Code.
61              
62             =head2 C
63              
64             Name of the exchange/market. Suited for display.
65              
66             =head2 C
67              
68             Returns the ISO 20022 Operating Market Identifier Code.
69              
70             =head2 C
71              
72             Timezone of the exchange/market.
73              
74             =cut
75              
76             has ['acronym', 'city', 'country', 'mic', 'name', 'operating_mic',
77             'timezone'];
78              
79             =head2 C
80              
81             Website of the exchange in a Mojo::URL object.
82              
83             =cut
84              
85 2     2 1 26 sub website ($s) {
  2         3  
  2         3  
86 2         12 Mojo::URL->new($s->{website});
87             }
88              
89             sub _test_website {
90 1   50 1   2728 t::Utility::stash('MARKET') // skip_all();
91 1         5 isa_ok(t::Utility::stash('MARKET')->website, 'Mojo::URL');
92 1         278 is(+t::Utility::stash('MARKET')->website, 'www.nasdaq.com');
93             }
94              
95             =head2 C
96              
97             my $hours = $market->todays_hours( );
98              
99             Return a Finance::Robinhood::Equity::Market::Hours object with today's data.
100              
101             =cut
102              
103 1     1 1 11 sub todays_hours ( $s ) {
  1         3  
  1         2  
104 1         7 my $res = $s->_rh->_get($s->{todays_hours});
105             $res->is_success
106             ? Finance::Robinhood::Equity::Market::Hours->new(_rh => $s->_rh,
107 1 0       32 %{$res->json})
  1 50       30  
108             : Finance::Robinhood::Error->new(
109             $res->is_server_error ? (details => $res->message) : $res->json);
110             }
111              
112             sub _test_todays_hours {
113 1   50 1   2147 t::Utility::stash('MARKET') // skip_all();
114 1         5 my $hours = t::Utility::stash('MARKET')->todays_hours();
115 1         563 isa_ok($hours, 'Finance::Robinhood::Equity::Market::Hours');
116 1         414 ok($hours->date <= Time::Moment->now_utc);
117             }
118              
119             =head2 C
120              
121             my $hours = $market->hours( $date );
122              
123             Returns the Finance::Robinhood::Equity::Market::Hours object for the given
124             date. This method expects C<$date> to be a Time::Moment object.
125              
126             =cut
127              
128 3     3 1 1496 sub hours ($s, $date) {
  3         10  
  3         7  
  3         6  
129             my $res = $s->_rh->_get(
130 3         14 $s->{url} . 'hours/' . $date->strftime('%Y-%m-%d') . '/');
131             $res->is_success
132             ? Finance::Robinhood::Equity::Market::Hours->new(_rh => $s->_rh,
133 3 0       94 %{$res->json})
  3 50       81  
134             : Finance::Robinhood::Error->new(
135             $res->is_server_error ? (details => $res->message) : $res->json);
136             }
137              
138             sub _test_hours {
139 1   50 1   2219 t::Utility::stash('MARKET') // skip_all();
140 1         4 my $hours = t::Utility::stash('MARKET')->hours(Time::Moment->now);
141 1         728 isa_ok($hours, 'Finance::Robinhood::Equity::Market::Hours');
142 1         381 is($hours->date->strftime('%Y-%m-%d'),
143             Time::Moment->now->strftime('%Y-%m-%d'));
144             }
145              
146             =head1 LEGAL
147              
148             This is a simple wrapper around the API used in the official apps. The author
149             provides no investment, legal, or tax advice and is not responsible for any
150             damages incurred while using this software. This software is not affiliated
151             with Robinhood Financial LLC in any way.
152              
153             For Robinhood's terms and disclosures, please see their website at
154             https://robinhood.com/legal/
155              
156             =head1 LICENSE
157              
158             Copyright (C) Sanko Robinson.
159              
160             This library is free software; you can redistribute it and/or modify it under
161             the terms found in the Artistic License 2. Other copyrights, terms, and
162             conditions may apply to data transmitted through this module. Please refer to
163             the L section.
164              
165             =head1 AUTHOR
166              
167             Sanko Robinson Esanko@cpan.orgE
168              
169             =cut
170              
171             1;