eod 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +377 -0
- data/bin/eod +25 -0
- data/lib/eod/api.rb +42 -0
- data/lib/eod/cli.rb +10 -0
- data/lib/eod/command.rb +267 -0
- data/lib/eod/exceptions.rb +6 -0
- data/lib/eod/refinements.rb +27 -0
- data/lib/eod/version.rb +3 -0
- data/lib/eod.rb +5 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4fbbd24f2657e0181eb845ed5c0d27e86ae7f5cb88063d16ea4ce078683316f2
|
4
|
+
data.tar.gz: c27bca383e1fc681e5866f48ded7c3580f571ab8b0d2c9035c72a181ae1a704e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ff07259af25e6d14ee15d6a477717cb1d2f3077734ca5afd184289e9e0d766892c95a77dd25224a8fb5490439de325e25cdd9e704defd6d90ea757f4488e42d4
|
7
|
+
data.tar.gz: c55da90f485d8ced57beed7a9ac099bcfc4df543b77bbb0e3e1d5cb5c56c472899bc1e33686000408ad4d2413d1ac5967e84f734789a7b2e8317282960415175
|
data/README.md
ADDED
@@ -0,0 +1,377 @@
|
|
1
|
+
# EOD Historical Data API Library and Command Line
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/eod)
|
4
|
+
[](https://github.com/DannyBen/eod/actions?query=workflow%3ATest)
|
5
|
+
|
6
|
+
---
|
7
|
+
|
8
|
+
This gem provides both a Ruby library and a command line interface for the
|
9
|
+
[EOD Historical Data][docs] data service.
|
10
|
+
|
11
|
+
---
|
12
|
+
|
13
|
+
|
14
|
+
## Install
|
15
|
+
|
16
|
+
```
|
17
|
+
$ gem install eod
|
18
|
+
```
|
19
|
+
|
20
|
+
|
21
|
+
## Features
|
22
|
+
|
23
|
+
* Easy to use interface.
|
24
|
+
* Use as a library or through the command line.
|
25
|
+
* Access any EOD Historical Data endpoint and option directly, no need to learn
|
26
|
+
anything other than the original API documentation.
|
27
|
+
* Display output as JSON, YAML or CSV.
|
28
|
+
* Save output to a file as JSON, YAML or CSV.
|
29
|
+
* Includes a built in file cache, so you can avoid wasting API calls.
|
30
|
+
* Lightweight.
|
31
|
+
* Future proof. In case new endpoints are added to the API, they will
|
32
|
+
immediately become available in the Ruby library (but not in the CLI).
|
33
|
+
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
First, require and initialize with your EOD API token:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
require 'eod'
|
41
|
+
api_token = 'OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX' # demo token
|
42
|
+
api = EOD::API.new api_token
|
43
|
+
```
|
44
|
+
|
45
|
+
Now, you can access any of the API endpoints with any optional parameter, like
|
46
|
+
this:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
result = api.get "eod", 'AAPL.US', period: 'm'
|
50
|
+
```
|
51
|
+
|
52
|
+
In addition, for convenience, you can use the first part of the endpoint as
|
53
|
+
a method name, like this:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
result = api.eod 'AAPL.US', period: 'm', from: '2022-01-01'
|
57
|
+
```
|
58
|
+
|
59
|
+
In other words, these calls are the same:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
api.get 'endpoint', param: value
|
63
|
+
api.endpoint, param: value
|
64
|
+
```
|
65
|
+
|
66
|
+
as well as these two:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
api.get 'endpoint/sub', param: value
|
70
|
+
api.endpoint 'sub', param: value
|
71
|
+
```
|
72
|
+
|
73
|
+
By default, you will get a ruby hash in return. If you wish to have more
|
74
|
+
control over the response, use the `get!` method instead:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
payload = api.get! 'eod', 'AAPL.US'
|
78
|
+
|
79
|
+
# Request Object
|
80
|
+
p payload.request.class
|
81
|
+
# => HTTParty::Request
|
82
|
+
|
83
|
+
# Response Object
|
84
|
+
p payload.response.class
|
85
|
+
# => Net::HTTPOK
|
86
|
+
|
87
|
+
p payload.response.body
|
88
|
+
# => JSON string
|
89
|
+
|
90
|
+
p payload.response.code
|
91
|
+
# => 200
|
92
|
+
|
93
|
+
p payload.response.msg
|
94
|
+
# => OK
|
95
|
+
|
96
|
+
# Headers Object
|
97
|
+
p payload.headers
|
98
|
+
# => Hash with headers
|
99
|
+
|
100
|
+
# Parsed Response Object
|
101
|
+
p payload.parsed_response
|
102
|
+
# => Hash with HTTParty parsed response
|
103
|
+
# (this is the content returned with #get)
|
104
|
+
```
|
105
|
+
|
106
|
+
You can get the response as CSV by calling `get_csv`:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
result = api.get_csv "eod", 'AAPL.US'
|
110
|
+
# => CSV string
|
111
|
+
```
|
112
|
+
|
113
|
+
or, if you prefer, you can request a CSV from the API directly, by using the
|
114
|
+
`fmt` argument:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
result = api.eod 'AAPL.US', fmt: 'csv'
|
118
|
+
# => CSV string
|
119
|
+
```
|
120
|
+
|
121
|
+
To save the output directly to a file, use the `save` method:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
api.save 'filename.json', 'eod/AAPL.US', period: 'm'
|
125
|
+
```
|
126
|
+
|
127
|
+
Or, to save CSV, use the `save_csv` method:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
api.save_csv "filename.csv", "eod/AAPL.US", period: 'm'
|
131
|
+
```
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
## Command Line Interface
|
136
|
+
|
137
|
+
The command line utility `eod` that is installed when installing the gem acts
|
138
|
+
in a similar way. The main difference is that you provide any API query string
|
139
|
+
argument using the `key:value` format.
|
140
|
+
|
141
|
+
First, set your API token in the environment variable `EOD_API_TOKEN`:
|
142
|
+
|
143
|
+
```bash
|
144
|
+
$ export EOD_API_TOKEN=OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX
|
145
|
+
````
|
146
|
+
|
147
|
+
Now, you can run one of the many API commands, for example:
|
148
|
+
|
149
|
+
```shell
|
150
|
+
# Show monthly AAPL data in a pretty colorful output
|
151
|
+
$ eod data AAPL.US period:m
|
152
|
+
|
153
|
+
# Show monthly AAPL data in CSV format
|
154
|
+
$ eod data AAPL.US --format csv from:2022-01-01 period:m
|
155
|
+
|
156
|
+
# Saves a file
|
157
|
+
$ eod data AAPL.US --format csv --save aapl.csv from:2022-01-01 period:m
|
158
|
+
|
159
|
+
# Show live (delayed) data
|
160
|
+
# eod live AAPL.US
|
161
|
+
```
|
162
|
+
|
163
|
+
Run [`eod --help`](#full-command-line-usage-patterns) for the full list of usage
|
164
|
+
patterns.
|
165
|
+
|
166
|
+
|
167
|
+
## Caching
|
168
|
+
|
169
|
+
We are using the [Lightly][lightly] gem for automatic HTTP caching.
|
170
|
+
|
171
|
+
You can disable or customize it by either passing options on
|
172
|
+
initialization, or by accessing the `WebCache` object directly at
|
173
|
+
a later stage.
|
174
|
+
|
175
|
+
```ruby
|
176
|
+
# Disable cache completely
|
177
|
+
api = EOD::API.new api_token, use_cache: true
|
178
|
+
|
179
|
+
# Set different cache directory or lifetime
|
180
|
+
api = EOD::API.new api_token, cache_dir: 'data', cache_ilfe: '2h'
|
181
|
+
|
182
|
+
# or
|
183
|
+
|
184
|
+
intrinio = Intrinio::API.new username: user, password: pass
|
185
|
+
intrinio.cache.disable
|
186
|
+
intrinio.cache.enable
|
187
|
+
intrinio.cache.dir = 'tmp/cache' # Change cache folder
|
188
|
+
intrinio.cache.life = '30m' # Change cache life to 30 minutes
|
189
|
+
```
|
190
|
+
|
191
|
+
To enable caching for the command line, simply set one or both of
|
192
|
+
these environment variables:
|
193
|
+
|
194
|
+
```shell
|
195
|
+
$ export EOD_CACHE_DIR=cache # default: 'cache'
|
196
|
+
$ export EOD_CACHE_LIFE=2h # default: 3600 (1 hour)
|
197
|
+
```
|
198
|
+
|
199
|
+
To disable cache for the CLI, set `EOD_CACHE_LIFE=off`.
|
200
|
+
|
201
|
+
The cache life argument supports these formats:
|
202
|
+
|
203
|
+
- `20s` - 20 seconds
|
204
|
+
- `10m` - 10 minutes
|
205
|
+
- `10h` - 10 hours
|
206
|
+
- `10d` - 10 days
|
207
|
+
|
208
|
+
## Full command line usage patterns
|
209
|
+
|
210
|
+
```
|
211
|
+
$ eod --help
|
212
|
+
|
213
|
+
<!-- USAGE -->
|
214
|
+
EOD Historical Data API
|
215
|
+
|
216
|
+
Usage:
|
217
|
+
eod bond SYMBOL [options] [PARAMS...]
|
218
|
+
eod bulk EXCHANGE [options] [PARAMS...]
|
219
|
+
eod calendar CALENDAR [options] [PARAMS...]
|
220
|
+
eod data SYMBOL [options] [PARAMS...]
|
221
|
+
eod dividends SYMBOL [options] [PARAMS...]
|
222
|
+
eod events [options] [PARAMS...]
|
223
|
+
eod exchange EXCHANGE [options] [PARAMS...]
|
224
|
+
eod exchanges [options] [PARAMS...]
|
225
|
+
eod fundamental SYMBOL [options] [PARAMS...]
|
226
|
+
eod fundamental_bulk SYMBOL [options] [PARAMS...]
|
227
|
+
eod insider [options] [PARAMS...]
|
228
|
+
eod intraday SYMBOL [options] [PARAMS...]
|
229
|
+
eod live SYMBOL [options] [PARAMS...]
|
230
|
+
eod macro COUNTRY [options] [PARAMS...]
|
231
|
+
eod news [options] [PARAMS...]
|
232
|
+
eod opts SYMBOL [options] [PARAMS...]
|
233
|
+
eod screener [options] [PARAMS...]
|
234
|
+
eod search QUERY [options] [PARAMS...]
|
235
|
+
eod splits SYMBOL [options] [PARAMS...]
|
236
|
+
eod symbols EXCHANGE [options] [PARAMS...]
|
237
|
+
eod technical SYMBOL [options] [PARAMS...]
|
238
|
+
eod (-h|--help|--version)
|
239
|
+
|
240
|
+
Commands:
|
241
|
+
bond
|
242
|
+
Bond fundamental data (/bond-fundamentals)
|
243
|
+
|
244
|
+
bulk
|
245
|
+
Historical EOD bulk data (/eod-bulk-last-day)
|
246
|
+
|
247
|
+
calendar
|
248
|
+
Calendar data (earnings, trends, IPOs and splits) (/calendar)
|
249
|
+
|
250
|
+
data
|
251
|
+
Historical EOD data (/eod)
|
252
|
+
|
253
|
+
dividends
|
254
|
+
Dividends data (/div)
|
255
|
+
|
256
|
+
events
|
257
|
+
Economic events data (/economic-events)
|
258
|
+
|
259
|
+
exchange
|
260
|
+
Details about an exchange (/exchanges-details)
|
261
|
+
|
262
|
+
exchanges
|
263
|
+
List of exchanges (/exchanges-list)
|
264
|
+
|
265
|
+
fundamental
|
266
|
+
Fundamental data (/fundamentals)
|
267
|
+
|
268
|
+
fundamental_bulk
|
269
|
+
Bulk fundamental data (/bulk-fundamentals)
|
270
|
+
|
271
|
+
insider
|
272
|
+
Insider transactions data (/insider-transactions)
|
273
|
+
|
274
|
+
intraday
|
275
|
+
Intraday data (/intraday)
|
276
|
+
|
277
|
+
live
|
278
|
+
Live data (/real-time)
|
279
|
+
|
280
|
+
macro
|
281
|
+
Macroeconomics data (/macro-indicator)
|
282
|
+
|
283
|
+
news
|
284
|
+
Financial news (/news)
|
285
|
+
|
286
|
+
opts
|
287
|
+
Options data (/options)
|
288
|
+
|
289
|
+
screener
|
290
|
+
Stock market screener (/screener)
|
291
|
+
|
292
|
+
search
|
293
|
+
Search for stocks, ETFs, funds or indices (/search)
|
294
|
+
|
295
|
+
splits
|
296
|
+
Splits data (/splits)
|
297
|
+
|
298
|
+
symbols
|
299
|
+
List of symbols for an exchange (/exchange-symbol-list)
|
300
|
+
|
301
|
+
technical
|
302
|
+
Technical data (/technical)
|
303
|
+
|
304
|
+
Options:
|
305
|
+
-f --format FORMAT
|
306
|
+
Output format: csv, json, yaml, pretty or url [default: pretty]
|
307
|
+
|
308
|
+
-s --save PATH
|
309
|
+
Save output to file
|
310
|
+
|
311
|
+
-h --help
|
312
|
+
Show this help
|
313
|
+
|
314
|
+
--version
|
315
|
+
Show version number
|
316
|
+
|
317
|
+
Parameters:
|
318
|
+
SYMBOL
|
319
|
+
Ticker symbol
|
320
|
+
|
321
|
+
CALENDAR
|
322
|
+
Calendar type: earnings, trends, ipos or splits
|
323
|
+
|
324
|
+
COUNTRY
|
325
|
+
Country code in the Alpha-3 ISO format
|
326
|
+
|
327
|
+
EXCHANGE
|
328
|
+
Exchange code
|
329
|
+
|
330
|
+
PARAMS
|
331
|
+
An optional list of query string parameters, separated by a space, to send
|
332
|
+
with the request. Each parameter should be in the format of key:value.
|
333
|
+
example: period:w from:2022-01-01
|
334
|
+
|
335
|
+
See https://eodhistoricaldata.com/financial-apis/ for all supported params.
|
336
|
+
|
337
|
+
Environment Variables:
|
338
|
+
EOD_API_TOKEN
|
339
|
+
Your EOD Historical Data API token [required]
|
340
|
+
|
341
|
+
EOD_CACHE_DIR
|
342
|
+
API cache diredctory [default: cache]
|
343
|
+
|
344
|
+
EOD_CACHE_LIFE
|
345
|
+
API cache life. These formats are supported:
|
346
|
+
off - No cache
|
347
|
+
20s - 20 seconds
|
348
|
+
10m - 10 minutes
|
349
|
+
10h - 10 hours
|
350
|
+
10d - 10 days
|
351
|
+
|
352
|
+
EOD_API_URI
|
353
|
+
Override the API URI [default: https://eodhistoricaldata.com/api]
|
354
|
+
|
355
|
+
Examples:
|
356
|
+
eod symbols NASDAQ
|
357
|
+
eod data AAPL.US
|
358
|
+
eod data AAPL.US --format csv period:m from:2022-01-01
|
359
|
+
eod live AAPL.US -fyaml
|
360
|
+
eod fundamental 'AAPL.US' filter:General
|
361
|
+
eod technical AAPL.US function:sma
|
362
|
+
eod macro USA indicator:inflation_consumer_prices_annual
|
363
|
+
|
364
|
+
<!-- USAGE -->
|
365
|
+
|
366
|
+
````
|
367
|
+
|
368
|
+
## Contributing / Support
|
369
|
+
|
370
|
+
If you experience any issue, have a question or a suggestion, or if you wish
|
371
|
+
to contribute, feel free to [open an issue][issues].
|
372
|
+
|
373
|
+
|
374
|
+
|
375
|
+
[docs]: https://eodhistoricaldata.com/financial-apis
|
376
|
+
[issues]: https://github.com/DannyBen/eod/issues
|
377
|
+
[lightly]: https://github.com/DannyBen/lightly
|
data/bin/eod
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'colsole'
|
3
|
+
require 'eod'
|
4
|
+
require 'eod/cli'
|
5
|
+
include Colsole
|
6
|
+
|
7
|
+
runner = EOD::CLI.runner
|
8
|
+
|
9
|
+
begin
|
10
|
+
exit runner.run ARGV
|
11
|
+
|
12
|
+
rescue Interrupt
|
13
|
+
say "\nGoodbye"
|
14
|
+
exit 1
|
15
|
+
|
16
|
+
rescue => e
|
17
|
+
if ENV['DEBUG']
|
18
|
+
puts e.backtrace.reverse
|
19
|
+
say ""
|
20
|
+
end
|
21
|
+
say "!undred!ERROR: #{e.class}"
|
22
|
+
say e.message
|
23
|
+
exit 1
|
24
|
+
|
25
|
+
end
|
data/lib/eod/api.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'apicake'
|
2
|
+
|
3
|
+
module EOD
|
4
|
+
# Provides access to all the EOD API endpoints with dynamic methods
|
5
|
+
# anc caching.
|
6
|
+
class API < APICake::Base
|
7
|
+
base_uri 'https://eodhistoricaldata.com/api'
|
8
|
+
|
9
|
+
attr_reader :api_token
|
10
|
+
|
11
|
+
def initialize(api_token, use_cache: true, cache_dir: nil, cache_life: nil)
|
12
|
+
@api_token = api_token
|
13
|
+
cache.disable unless use_cache
|
14
|
+
cache.dir = cache_dir if cache_dir
|
15
|
+
cache.life = cache_life if cache_life
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_query
|
19
|
+
{ api_token: api_token, fmt: :json }
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_csv(*args)
|
23
|
+
payload = get! *args
|
24
|
+
|
25
|
+
if payload.response.code != "200"
|
26
|
+
raise BadResponse, "#{payload.response.code} #{payload.response.msg}"
|
27
|
+
end
|
28
|
+
|
29
|
+
data = payload.parsed_response
|
30
|
+
data = csv_node data if data.is_a? Hash
|
31
|
+
|
32
|
+
header = data.first.keys
|
33
|
+
|
34
|
+
result = CSV.generate do |csv|
|
35
|
+
csv << header
|
36
|
+
data.each { |row| csv << row.values }
|
37
|
+
end
|
38
|
+
|
39
|
+
result
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/eod/cli.rb
ADDED
data/lib/eod/command.rb
ADDED
@@ -0,0 +1,267 @@
|
|
1
|
+
require 'lp'
|
2
|
+
require 'mister_bin'
|
3
|
+
require 'eod/refinements'
|
4
|
+
|
5
|
+
module EOD
|
6
|
+
class Command < MisterBin::Command
|
7
|
+
using EOD::Refinements
|
8
|
+
|
9
|
+
help "EOD Historical Data API\n\n API Documentation:\n https://eodhistoricaldata.com/financial-apis/"
|
10
|
+
version EOD::VERSION
|
11
|
+
|
12
|
+
usage "eod bond SYMBOL [options] [PARAMS...]"
|
13
|
+
usage "eod bulk EXCHANGE [options] [PARAMS...]"
|
14
|
+
usage "eod calendar CALENDAR [options] [PARAMS...]"
|
15
|
+
usage "eod data SYMBOL [options] [PARAMS...]"
|
16
|
+
usage "eod dividends SYMBOL [options] [PARAMS...]"
|
17
|
+
usage "eod events [options] [PARAMS...]"
|
18
|
+
usage "eod exchange EXCHANGE [options] [PARAMS...]"
|
19
|
+
usage "eod exchanges [options] [PARAMS...]"
|
20
|
+
usage "eod fundamental SYMBOL [options] [PARAMS...]"
|
21
|
+
usage "eod fundamental_bulk SYMBOL [options] [PARAMS...]"
|
22
|
+
usage "eod insider [options] [PARAMS...]"
|
23
|
+
usage "eod intraday SYMBOL [options] [PARAMS...]"
|
24
|
+
usage "eod live SYMBOL [options] [PARAMS...]"
|
25
|
+
usage "eod macro COUNTRY [options] [PARAMS...]"
|
26
|
+
usage "eod news [options] [PARAMS...]"
|
27
|
+
usage "eod opts SYMBOL [options] [PARAMS...]"
|
28
|
+
usage "eod screener [options] [PARAMS...]"
|
29
|
+
usage "eod search QUERY [options] [PARAMS...]"
|
30
|
+
usage "eod splits SYMBOL [options] [PARAMS...]"
|
31
|
+
usage "eod symbols EXCHANGE [options] [PARAMS...]"
|
32
|
+
usage "eod technical SYMBOL [options] [PARAMS...]"
|
33
|
+
usage "eod (-h|--help|--version)"
|
34
|
+
|
35
|
+
command "bond", "Bond fundamental data (/bond-fundamentals)"
|
36
|
+
command "bulk", "Historical EOD bulk data (/eod-bulk-last-day)"
|
37
|
+
command "calendar", "Calendar data (earnings, trends, IPOs and splits) (/calendar)"
|
38
|
+
command "data", "Historical EOD data (/eod)"
|
39
|
+
command "dividends", "Dividends data (/div)"
|
40
|
+
command "events", "Economic events data (/economic-events)"
|
41
|
+
command "exchange", "Details about an exchange (/exchanges-details)"
|
42
|
+
command "exchanges", "List of exchanges (/exchanges-list)"
|
43
|
+
command "fundamental", "Fundamental data (/fundamentals)"
|
44
|
+
command "fundamental_bulk", "Bulk fundamental data (/bulk-fundamentals)"
|
45
|
+
command "insider", "Insider transactions data (/insider-transactions)"
|
46
|
+
command "intraday", "Intraday data (/intraday)"
|
47
|
+
command "live", "Live data (/real-time)"
|
48
|
+
command "macro", "Macroeconomics data (/macro-indicator)"
|
49
|
+
command "news", "Financial news (/news)"
|
50
|
+
command "opts", "Options data (/options)"
|
51
|
+
command "screener", "Stock market screener (/screener)"
|
52
|
+
command "search", "Search for stocks, ETFs, funds or indices (/search)"
|
53
|
+
command "splits", "Splits data (/splits)"
|
54
|
+
command "symbols", "List of symbols for an exchange (/exchange-symbol-list)"
|
55
|
+
command "technical", "Technical data (/technical)"
|
56
|
+
|
57
|
+
option "-f --format FORMAT", "Output format: csv, json, yaml, pretty or url [default: pretty]"
|
58
|
+
option "-s --save PATH", "Save output to file"
|
59
|
+
|
60
|
+
param "SYMBOL", "Ticker symbol"
|
61
|
+
param "CALENDAR", "Calendar type: earnings, trends, ipos or splits"
|
62
|
+
param "COUNTRY", "Country code in the Alpha-3 ISO format"
|
63
|
+
param "EXCHANGE", "Exchange code"
|
64
|
+
param "PARAMS", <<~EOF
|
65
|
+
An optional list of query string parameters, separated by a space, to send with the request. \
|
66
|
+
Each parameter should be in the format of key:value.
|
67
|
+
example: period:w from:2022-01-01
|
68
|
+
|
69
|
+
See https://eodhistoricaldata.com/financial-apis/ for all supported params.
|
70
|
+
EOF
|
71
|
+
|
72
|
+
environment "EOD_API_TOKEN", "Your EOD Historical Data API token [required]"
|
73
|
+
environment "EOD_CACHE_DIR", "API cache diredctory [default: cache]"
|
74
|
+
environment "EOD_CACHE_LIFE", <<~EOF
|
75
|
+
API cache life. These formats are supported:
|
76
|
+
off - No cache
|
77
|
+
20s - 20 seconds
|
78
|
+
10m - 10 minutes
|
79
|
+
10h - 10 hours
|
80
|
+
10d - 10 days
|
81
|
+
EOF
|
82
|
+
environment "EOD_API_URI", "Override the API URI [default: #{EOD::API.base_uri}]"
|
83
|
+
|
84
|
+
example "eod symbols NASDAQ"
|
85
|
+
example "eod data AAPL.US"
|
86
|
+
example "eod data AAPL.US --format csv period:m from:2022-01-01"
|
87
|
+
example "eod live AAPL.US -fyaml"
|
88
|
+
example "eod fundamental 'AAPL.US' filter:General"
|
89
|
+
example "eod technical AAPL.US function:sma"
|
90
|
+
example "eod macro USA indicator:inflation_consumer_prices_annual"
|
91
|
+
|
92
|
+
def bond_command
|
93
|
+
disallow :csv
|
94
|
+
send_output get("bond-fundamentals/#{symbol}")
|
95
|
+
end
|
96
|
+
|
97
|
+
def bulk_command
|
98
|
+
send_output get("eod-bulk-last-day/#{exchange}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def calendar_command
|
102
|
+
allowed = %w[earnings trends ipos splits]
|
103
|
+
|
104
|
+
unless allowed.include? calendar
|
105
|
+
raise InputError, "Invalid calendar #{calendar}. Expecting earnings, trends, ipos or splits"
|
106
|
+
end
|
107
|
+
|
108
|
+
send_output get("calendar/#{calendar}")
|
109
|
+
end
|
110
|
+
|
111
|
+
def data_command
|
112
|
+
send_output get("eod/#{symbol}")
|
113
|
+
end
|
114
|
+
|
115
|
+
def dividends_command
|
116
|
+
send_output get("div/#{symbol}")
|
117
|
+
end
|
118
|
+
|
119
|
+
def events_command
|
120
|
+
send_output get("economic-events")
|
121
|
+
end
|
122
|
+
|
123
|
+
def exchange_command
|
124
|
+
disallow :csv
|
125
|
+
send_output get("exchange-details/#{exchange}")
|
126
|
+
end
|
127
|
+
|
128
|
+
def exchanges_command
|
129
|
+
send_output get("exchanges-list")
|
130
|
+
end
|
131
|
+
|
132
|
+
def fundamental_command
|
133
|
+
disallow :csv
|
134
|
+
send_output get("fundamentals/#{symbol}")
|
135
|
+
end
|
136
|
+
|
137
|
+
def fundamental_bulk_command
|
138
|
+
disallow :csv
|
139
|
+
send_output get("bulk-fundamentals/#{symbol}")
|
140
|
+
end
|
141
|
+
|
142
|
+
def insider_command
|
143
|
+
send_output get("insider-transactions")
|
144
|
+
end
|
145
|
+
|
146
|
+
def intraday_command
|
147
|
+
send_output get("intraday/#{symbol}")
|
148
|
+
end
|
149
|
+
|
150
|
+
def live_command
|
151
|
+
send_output get("real-time/#{symbol}")
|
152
|
+
end
|
153
|
+
|
154
|
+
def macro_command
|
155
|
+
send_output get("macro-indicator/#{country}")
|
156
|
+
end
|
157
|
+
|
158
|
+
def news_command
|
159
|
+
disallow :csv
|
160
|
+
send_output get("news")
|
161
|
+
end
|
162
|
+
|
163
|
+
def opts_command
|
164
|
+
disallow :csv
|
165
|
+
send_output get("options/#{symbol}")
|
166
|
+
end
|
167
|
+
|
168
|
+
def screener_command
|
169
|
+
send_output get("screener")
|
170
|
+
end
|
171
|
+
|
172
|
+
def search_command
|
173
|
+
send_output get("search/#{query.uri_encode}")
|
174
|
+
end
|
175
|
+
|
176
|
+
def splits_command
|
177
|
+
send_output get("splits/#{symbol}")
|
178
|
+
end
|
179
|
+
|
180
|
+
def symbols_command
|
181
|
+
send_output get("exchange-symbol-list/#{exchange}")
|
182
|
+
end
|
183
|
+
|
184
|
+
def technical_command
|
185
|
+
send_output get("technical/#{symbol}")
|
186
|
+
end
|
187
|
+
|
188
|
+
def send_output(data)
|
189
|
+
if save
|
190
|
+
say "saved #{save}"
|
191
|
+
File.write save, data
|
192
|
+
elsif pretty
|
193
|
+
lp data
|
194
|
+
else
|
195
|
+
puts data
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def get(endpoint)
|
200
|
+
case format
|
201
|
+
when :url then api.url endpoint, params
|
202
|
+
when :csv then api.get_csv endpoint, params
|
203
|
+
when :json, :pretty then api.get endpoint, params
|
204
|
+
when :yaml then api.get(endpoint, params).to_yaml
|
205
|
+
else
|
206
|
+
raise InputError, "Invalid format #{format}. Expecting csv, json, yaml or pretty"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
private
|
211
|
+
|
212
|
+
def disallow(disallowed_format)
|
213
|
+
raise InputError, "The format #{format} is not supported for this command" if format == disallowed_format
|
214
|
+
end
|
215
|
+
|
216
|
+
def api
|
217
|
+
@api ||= begin
|
218
|
+
EOD::API.base_uri ENV['EOD_API_URI'] if ENV['EOD_API_URI']
|
219
|
+
EOD::API.new api_token,
|
220
|
+
use_cache: (ENV['EOD_CACHE_LIFE'] != 'off'),
|
221
|
+
cache_dir: ENV['EOD_CACHE_DIR'],
|
222
|
+
cache_life: ENV['EOD_CACHE_LIFE']
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def api_token
|
227
|
+
ENV['EOD_API_TOKEN'] or raise MissingAuth, "Please set the 'EOD_API_TOKEN' environment variable"
|
228
|
+
end
|
229
|
+
|
230
|
+
def pretty
|
231
|
+
format == :pretty
|
232
|
+
end
|
233
|
+
|
234
|
+
def params
|
235
|
+
args['PARAMS'].translate_params
|
236
|
+
end
|
237
|
+
|
238
|
+
def symbol
|
239
|
+
args['SYMBOL']
|
240
|
+
end
|
241
|
+
|
242
|
+
def calendar
|
243
|
+
args['CALENDAR']
|
244
|
+
end
|
245
|
+
|
246
|
+
def country
|
247
|
+
args['COUNTRY']
|
248
|
+
end
|
249
|
+
|
250
|
+
def exchange
|
251
|
+
args['EXCHANGE']
|
252
|
+
end
|
253
|
+
|
254
|
+
def query
|
255
|
+
args['QUERY']
|
256
|
+
end
|
257
|
+
|
258
|
+
def format
|
259
|
+
args['--format'].to_sym
|
260
|
+
end
|
261
|
+
|
262
|
+
def save
|
263
|
+
args['--save']
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module EOD
|
4
|
+
module Refinements
|
5
|
+
refine String do
|
6
|
+
def uri_encode
|
7
|
+
CGI.escape(self).gsub('+', '%20')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
refine Array do
|
12
|
+
# Convert a params array like [key:value, key:value] to a hash like
|
13
|
+
# {key: value, key: value}
|
14
|
+
def translate_params
|
15
|
+
result = {}
|
16
|
+
return result if empty?
|
17
|
+
|
18
|
+
each do |pair|
|
19
|
+
key, value = pair.split ':'
|
20
|
+
result[key.to_sym] = value
|
21
|
+
end
|
22
|
+
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/eod/version.rb
ADDED
data/lib/eod.rb
ADDED
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eod
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Danny Ben Shitrit
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-03-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mister_bin
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: lp
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: apicake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.1'
|
55
|
+
description: Easy to use API for eodhistoricaldata.com Data service with a command
|
56
|
+
line interface
|
57
|
+
email: db@dannyben.com
|
58
|
+
executables:
|
59
|
+
- eod
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- README.md
|
64
|
+
- bin/eod
|
65
|
+
- lib/eod.rb
|
66
|
+
- lib/eod/api.rb
|
67
|
+
- lib/eod/cli.rb
|
68
|
+
- lib/eod/command.rb
|
69
|
+
- lib/eod/exceptions.rb
|
70
|
+
- lib/eod/refinements.rb
|
71
|
+
- lib/eod/version.rb
|
72
|
+
homepage: https://github.com/DannyBen/eod
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata:
|
76
|
+
bug_tracker_uri: https://github.com/DannyBen/eod/issues
|
77
|
+
changelog_uri: https://github.com/DannyBen/eod/blob/master/CHANGELOG.md
|
78
|
+
homepage_uri: https://github.com/DannyBen/eod
|
79
|
+
source_code_uri: https://github.com/DannyBen/eod
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 2.7.0
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubygems_version: 3.3.3
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: EOD Historical Data API Library and Command Line
|
99
|
+
test_files: []
|