finnhubrb 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 305ff27db99c18e1a76d1034fd69b568e89b45fd8cfba42a030199b03e4ba4f2
4
+ data.tar.gz: a65a7dc065c422855d5a4a6685349c6a634be771b517586541ab90e43e1c9fde
5
+ SHA512:
6
+ metadata.gz: c8cc6932d02616b872f2ac87737acde0ce0d4b951d72f76875edf32f4fc8e1ac37d37dc67ba59570bdd1a0d5fe4ec9463939748e6dfd8e950a6f029e94c63478
7
+ data.tar.gz: b0323e588781a3eabd6f49347f0985e51dd5d0eb872a02e07790aaa20a8407aab5adc8d5ef7d1ff477ebd134a3e9ca5dbff750c8622388b78d5e4de284f6fd6f
@@ -0,0 +1,24 @@
1
+ # lib = File.expand_path("../lib", __FILE__)
2
+ # $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "rake"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "finnhubrb"
7
+ s.version = "1.0.0"
8
+ s.authors = ["Stefano Martin"]
9
+ s.email = ["stefano.martin87@gmail.com"]
10
+ s.homepage = "https://github.com/StefanoMartin/FinnhubRB"
11
+ s.license = "MIT"
12
+ s.summary = "A gem for Alpha Vantage"
13
+ s.description = "A ruby wrapper for Finnhub's HTTP API"
14
+ s.platform = Gem::Platform::RUBY
15
+ s.require_paths = ["lib"]
16
+ s.files = FileList["lib/*", "spec/**/*", "FinnhubRB.gemspec", "Gemfile", "LICENSE.md", "README.md"].to_a
17
+ s.add_runtime_dependency "httparty", "~>0.17.0", ">= 0.17.0"
18
+ s.add_runtime_dependency "oj", "~>3.9.0", ">= 3.9.0"
19
+ s.add_runtime_dependency "faye-websocket", "~>0.10.9", ">= 0.10.9"
20
+ s.add_development_dependency "pry-byebug", '~> 0'
21
+ s.add_development_dependency "rspec", "~>3.5", ">=3.5"
22
+ s.add_development_dependency "awesome_print", "~>1.7", ">= 1.7"
23
+ s.add_development_dependency "eventmachine", "~>1.2.7", ">= 1.2.7"
24
+ end
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "httparty", ">= 0.17.1"
4
+ gem "oj", ">= 3.9.2"
5
+ gem "faye-websocket", ">= 0.10.9"
6
+ gem "eventmachine", "1.2.7"
7
+
8
+ group :development, :test do
9
+ gem "pry-byebug"
10
+ gem "rspec", ">= 3.5"
11
+ gem "awesome_print", ">= 1.7"
12
+ end
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Stefano Martin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,237 @@
1
+ FinnhubRB
2
+ =========================================================
3
+
4
+ [Finnhub](https://finnhub.io/) is an API for retrieving Stock
5
+ market data in JSON or CSV format.
6
+ FinnhubRB is a wrapper Gem to use Finnhub with Ruby. FinnhubRB is based
7
+ on the [HTTP API of Finnhub](https://finnhub.io/docs/api).
8
+
9
+ To install FinnhubRB: `gem install finnhubrb`
10
+
11
+ To use it in your application: `require "finnhubrb"`
12
+
13
+ ## How to test
14
+
15
+ To test the Gem create a config.yml file inside the folder /spec with inside a line
16
+
17
+ ``` ruby
18
+ key: [YOUR KEY]
19
+ ```
20
+
21
+ Then run "rspec spec/test_all.rb".
22
+
23
+ ## Support
24
+
25
+ * Without a premium account, testing is hard and I could have missed something. Any bug, suggestions and improvements are more than welcome. Please do not be shy to create issues or pull requests.
26
+ * This is a personal project, any stars for giving your support will make a man happy.
27
+
28
+ ## Client
29
+
30
+ To contact Alpha Vantage you need to use a valid key that you can require from [here](https://finnhub.io/register).
31
+
32
+ To setup your clients use:
33
+
34
+ ``` ruby
35
+ client = Finnhub::Client.new(key: "YOURKEY")
36
+ ```
37
+
38
+ If you want to see the request that the client will do to Finnhub you can
39
+ setup verbose equal to true.
40
+
41
+ ``` ruby
42
+ client.verbose = true # You can setup this during the initialization too
43
+ ```
44
+
45
+ ## Stock
46
+
47
+ Finnhub::Stock is used to manage a stock class.
48
+ To create a new Stock class you can use a client.
49
+
50
+ ``` ruby
51
+ stock = client.stock symbol: "AAPL"
52
+ ```
53
+
54
+ Several methods are available under this class:
55
+
56
+ ``` ruby
57
+ stock.symbol # Return the symbol
58
+ stock.profile # Retrieve profile of the stock
59
+ stock.ceo_compensation # Retrieve compensation of the stock's CEO
60
+ stock.recommendation # Retrieve recommendation about this stock
61
+ stock.price_target # Retrieve price target about this stock
62
+ stock.option_chain # Retrieve option chain about this stock
63
+ stock.earnings # Retrieve earnings about this stock
64
+ stock.news # Retrieve news about this stock (only US)
65
+ stock.sentiment # Retrieve social sentiment about this stock (only US)
66
+ stock.peers(plain: true) # Retrieve peers company similar to the one chosen
67
+ stock.peers # Like the previous one, but the results are Finnhub::Stock instances
68
+ stock.pattern # Retrieve pattern
69
+ stock.support_resistance # Retrieve support resistance
70
+ stock.technical_indicators # Retrieve techinical indicators
71
+ ```
72
+
73
+ To create a timeseries you can use:
74
+
75
+ ``` ruby
76
+ stock.timeseries(count: 100) # Return the last 100 entries (default count is 100)
77
+ stock.timeseries(resolution: "D") # Resolution is daily "D", alternative are 1, 5, 15, 30, 60, D, W, M) where the numeric one are for minutes (default resolution is "D")
78
+ stock.timeseries(from: Time.now-24*30*3600, to: Time.now) # Fetch from a date to another date (default from: nil, to: nil)
79
+ stock.timeseries(format: "json") # Return the output in json or in csv (default format: "json")
80
+ ```
81
+
82
+ Remember count and from/to are exclusive. If you use one, you cannot use the other two.
83
+ The methods "open", "high", "low", "close", "volume" and "status" will not work if you use format csv.
84
+
85
+ ``` ruby
86
+ timeseries = stock.timeseries(from: Time.now-24*30*3600, to: Time.now, resolution: 60)
87
+ timeseries.output # Return output obtained from the request
88
+ timeseris.timestamps # Return timestamps obtained from the request
89
+ timeseries.open # Return open obtained from the request
90
+ timeseries.low # Return low obtained from the request
91
+ timeseries.close # Return close obtained from the request
92
+ timeseries.volume # Return volume obtained from the request
93
+ timeseries.status # Return status obtained from the request
94
+ ```
95
+
96
+ ## Crypto
97
+
98
+ To analyse a crypto currency you should start by choosing which crypto exchange you want to analyse.
99
+
100
+ ``` ruby
101
+ client.crypto_exchanges # Retrieve the available crypto exchanges on Finnhub (Finnhub::Crypto_Exchange instances)
102
+ client.crypto_exchanges(plain: true) # As above, but it returns simply the output of the request
103
+ crypto_exchange = client.crypto_exchange(name: "NAME_CRYPTO_EXCHANGE") # Create a single instance of Finnhub::Crypto_Exchange
104
+ ```
105
+
106
+ After that you can choose, in that crypto exchange which symbol you want to check.
107
+
108
+ ``` ruby
109
+ crypto_exchange.symbols # Retrieve the available crypto symbols on the chosen crypto exchange (Finnhub::Crypto_Symbol instances)
110
+ crypto_exchange.symbols(plain: true) # As above, but it returns simply the output of the request
111
+ crypto_symbol = crypto_exchange.symbol(symbol: "BTC") # Create a single instance of Finnhub::Crypto_Symbol
112
+ ```
113
+
114
+ From crypto_symbol instance you can retrieve some interesting information.
115
+
116
+ ``` ruby
117
+ crypto_symbol.exchange # Exchange of the crypto_symbol
118
+ crypto_symbol.hasWM # If it has week and month
119
+ crypto_symbol.displaySymbol # Displayed symbol
120
+ crypto_symbol.symbol # Symbol of the crypto currency
121
+ ```
122
+
123
+ Furthermore you can create a timeseries with the same logic used for Stock timeseries.
124
+
125
+ ``` ruby
126
+ timeseries = crypto_symbol.timeseries(from: Time.now-24*30*3600, to: Time.now, resolution: 60)
127
+ timeseries.output # Return output obtained from the request
128
+ timeseris.timestamps # Return timestamps obtained from the request
129
+ timeseries.open # Return open obtained from the request
130
+ timeseries.low # Return low obtained from the request
131
+ timeseries.close # Return close obtained from the request
132
+ timeseries.volume # Return volume obtained from the request
133
+ timeseries.status # Return status obtained from the request
134
+ ```
135
+
136
+ ## Forex
137
+
138
+ To analyse a forex exchange you should start by choosing which forex exchange you want to analyse.
139
+
140
+ ``` ruby
141
+ client.forex_exchanges # Retrieve the available forex exchanges on Finnhub (Finnhub::Forex_Exchange instances)
142
+ client.forex_exchanges(plain: true) # As above, but it returns simply the output of the request
143
+ forex_exchange = client.forex_exchange(name: "NAME_FOREX_EXCHANGE") # Create a single instance of Finnhub::Forex_Exchange
144
+ ```
145
+
146
+ After that you can choose, in that forex exchange which symbol you want to check.
147
+
148
+ ``` ruby
149
+ forex_exchange.symbols # Retrieve the available forex symbols on the chosen forex exchange (Finnhub::Forex_Symbol instances)
150
+ forex_exchange.symbols(plain: true) # As above, but it returns simply the output of the request
151
+ forex_symbol = forex_exchange.symbol(symbol: "USD") # Create a single instance of Finnhub::Forex_Symbol
152
+ ```
153
+
154
+ From forex_symbol instance you can retrieve some interesting information.
155
+
156
+ ``` ruby
157
+ forex_symbol.exchange # Exchange of the crypto_symbol
158
+ forex_symbol.hasWM # If it has week and month
159
+ forex_symbol.displaySymbol # Displayed symbol
160
+ forex_symbol.symbol # Symbol of the crypto currency
161
+ ```
162
+
163
+ Furthermore you can create a timeseries with the same logic used for Stock timeseries.
164
+
165
+ ``` ruby
166
+ timeseries = forex_symbol.timeseries(from: Time.now-24*30*3600, to: Time.now, resolution: 60)
167
+ timeseries.output # Return output obtained from the request
168
+ timeseris.timestamps # Return timestamps obtained from the request
169
+ timeseries.open # Return open obtained from the request
170
+ timeseries.low # Return low obtained from the request
171
+ timeseries.close # Return close obtained from the request
172
+ timeseries.volume # Return volume obtained from the request
173
+ timeseries.status # Return status obtained from the request
174
+ ```
175
+
176
+ ## Merge
177
+
178
+ You can retrieve information about company that are merging in relation of a given country.
179
+
180
+ ``` ruby
181
+ client.merge_countries # Retrieve the available merge countries on Finnhub (Finnhub::Merge_Country instances)
182
+ client.merge_countries(plain: true) # As above, but it returns simply the output of the request
183
+ country = client.merge_country(country: "France") # Create a single instance of Finnhub::Merge_Country
184
+ country.merger # Fetch information about the company that are going to merge
185
+ ```
186
+
187
+ ## Economic Code
188
+
189
+ You can retrieve information about economic_codes.
190
+
191
+ ``` ruby
192
+ client.economic_codes # Retrieve the available economic_codes on Finnhub (Finnhub::Economic_Code instances)
193
+ client.economic_codes(plain: true) # As above, but it returns simply the output of the request
194
+ economic = client.economic_code(code: "CODE") # Create a single instance of Finnhub::Economic_Code
195
+ economic.data # Data of economic_code
196
+ economic.data(plaint: true) # As above, but it returns simply the output of the request
197
+ ```
198
+
199
+ ## News and calendar
200
+
201
+ You can retrieve news and calendar in the following way.
202
+
203
+ ``` ruby
204
+ client.news(category: "forex") # Retrieve news by category (general, forex, crypto, merger) and by minId (default 0)
205
+ client.economic_calendar # Retrieve economic calendar
206
+ client.earnings_calendar # Retrieve earning calendar
207
+ client.ipo_calendar # Retrieve IPO calendar
208
+ client.ico_calendar # Retrieve ICO calendar
209
+ ```
210
+
211
+ ## Websocket
212
+
213
+ Here an example of how to create websocket.
214
+
215
+ ``` ruby
216
+ Thread.new do
217
+ EM.run do
218
+ websocket = client.websocket # Create websocket
219
+ websocket.on :message do |event|
220
+ result = event.data # Result is not parsed
221
+ end
222
+ websocket.on :close do |event|
223
+ result = [:close, event.code, event.reason]
224
+ websocket = nil
225
+ end
226
+ end
227
+ end
228
+
229
+ websocket.subscribe("AAPL") # Subscribe to a stock
230
+ websocket.unsubscribe("AAPL") # Unubscribe to a stock
231
+ ```
232
+
233
+ The symbol under subscribe/unsubscribe can be a string of a stock, a crypto_symbol or a forex_symbol. Or in alternative can be a Finnhub::Stock, Finnhub::Crypto_Symbol, or a Finnhub::Forex_Symbol instance.
234
+
235
+ ## Errors
236
+
237
+ Error from FinnhubRB are returned under Finnhub::Error exception. You can use e.code to retrieve the code returned to a not successful request.
@@ -0,0 +1,15 @@
1
+ module Finnhub
2
+ module Analysis
3
+ def pattern(resolution: "D")
4
+ @client.request("/scan/pattern?symbol=#{@symbol}&resolution=#{resolution}")
5
+ end
6
+
7
+ def support_resistance(resolution: "D")
8
+ @client.request("/scan/support-resistance?symbol=#{@symbol}&resolution=#{resolution}")
9
+ end
10
+
11
+ def technical_indicators(resolution: "D")
12
+ @client.request("/scan/technical-indicator?symbol=#{@symbol}&resolution=#{resolution}")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module Finnhub
2
+ module Calendar
3
+ def economic_calendar
4
+ request("/calendar/economic")
5
+ end
6
+
7
+ def earnings_calendar
8
+ request("/calendar/earnings")
9
+ end
10
+
11
+ def ipo_calendar
12
+ request("/calendar/ipo")
13
+ end
14
+
15
+ def ico_calendar
16
+ request("/calendar/ico")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,106 @@
1
+ module Finnhub
2
+ class Client
3
+ include Calendar
4
+
5
+ BASE_URI = 'https://finnhub.io/api/v1'
6
+
7
+ def initialize(key:, verbose: false)
8
+ @apikey = key
9
+ @verbose = verbose
10
+ end
11
+
12
+ attr_accessor :verbose
13
+ attr_reader :apikey
14
+
15
+ def request(url)
16
+ send_url = "#{BASE_URI}#{url}"
17
+ send_url += send_url.include?("?") ? "&" : "?"
18
+ send_url += "token=#{@apikey}"
19
+
20
+ puts "\nGET #{send_url}\n" if @verbose
21
+ response = HTTParty.get(send_url)
22
+ if @verbose
23
+ puts "\nCODE: #{response.code}\n"
24
+ puts "OUTPUT: #{response.body}\n"
25
+ end
26
+
27
+ if response.code == 200
28
+ data = response.body
29
+ if data[0] == "[" || data[0] == "{"
30
+ data = Oj.load(data, symbol_keys: true)
31
+ return data
32
+ elsif data.include?("\n")
33
+ return data
34
+ else
35
+ raise Finnhub::Error.new message: data, code: response.code
36
+ end
37
+ else
38
+ raise Finnhub::Error.new message: data, code: response.code
39
+ end
40
+
41
+ rescue Finnhub::Error => e
42
+ raise e
43
+ rescue StandardError => e
44
+ raise Finnhub::Error.new message: "Failed request: #{e.message}"
45
+ end
46
+
47
+ def websocket
48
+ Finnhub::Websocket.new(@apikey)
49
+ end
50
+
51
+ def stock(symbol:)
52
+ Finnhub::Stock.new(client: self, symbol: symbol)
53
+ end
54
+
55
+ def forex_exchanges(plain: false)
56
+ output = request("/forex/exchange")
57
+ return output if plain
58
+
59
+ output.map{|o| Finnhub::Forex_Exchange.new(client: self, name: o)}
60
+ end
61
+
62
+ def forex_exchange(name:)
63
+ Finnhub::Forex_Exchange.new(client: self, name: name)
64
+ end
65
+
66
+ def crypto_exchanges(plain: false)
67
+ output = request("/crypto/exchange")
68
+ return output if plain
69
+
70
+ output.map{|o| Finnhub::Crypto_Exchange.new(client: self, name: o)}
71
+ end
72
+
73
+ def crypto_exchange(name:)
74
+ Finnhub::Crypto_Exchange.new(client: self, name: name)
75
+ end
76
+
77
+ def news(category: "general", minId: nil)
78
+ url = "/news?category=#{category}"
79
+ url += "&minId=#{minId}" unless minId.nil?
80
+ request(url)
81
+ end
82
+
83
+ def merge_countries(plain: false)
84
+ output = request("/merger/country")
85
+ return output if plain
86
+
87
+ output.map{|o| Finnhub::Merge_Country.new(client: self, country: o)}
88
+ end
89
+
90
+ def merge_country(country:)
91
+ Finnhub::Merge_Country.new(client: self, country: country)
92
+ end
93
+
94
+ def economic_codes(plain: false)
95
+ output = request("/economic/code")
96
+ return output if plain
97
+
98
+ output.map{|o| Finnhub::Economic_Code.new(client: self, code: o[0], description: o[1])}
99
+ end
100
+
101
+ def economic_code(code:, description: nil)
102
+ Finnhub::Economic_Code.new(client: self, code: code,
103
+ description: description)
104
+ end
105
+ end
106
+ end