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