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,17 @@
1
+ module Finnhub
2
+ class Merge_Country
3
+ def initialize(client:, country:)
4
+ @client = client
5
+ @country = country
6
+ end
7
+
8
+ attr_reader :country
9
+
10
+ def merger(from: nil, to: nil)
11
+ url = "/merger?country=#{@country}"
12
+ url += "&from=#{from}" unless from.nil?
13
+ url += "&to=#{to}" unless to.nil?
14
+ @client.request(url)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,59 @@
1
+ module Finnhub
2
+ class Crypto_Exchange
3
+ def initialize(client:, name:)
4
+ @client = client
5
+ @name = name
6
+ end
7
+
8
+ attr_reader :name
9
+
10
+ def symbols(plain: false)
11
+ output = @client.request("/crypto/symbol?exchange=#{@name}")
12
+ return output if plain
13
+
14
+ output.map do |o|
15
+ Finnhub::Crypto_Symbol.new(client: @client, exchange: @name, **o)
16
+ end
17
+ end
18
+
19
+ def symbol(**args)
20
+ Finnhub::Crypto_Symbol.new(client: @client, exchange: @name, **args)
21
+ end
22
+ end
23
+
24
+ class Crypto_Symbol
25
+ include Finnhub::Analysis
26
+
27
+ def initialize(client:, exchange:, description: nil, hasWM: nil,
28
+ displaySymbol: nil, symbol: nil)
29
+ @client = client
30
+ @exchange = exchange
31
+ @hashWM = hasWM
32
+ @displaySymbol = displaySymbol
33
+ @symbol = symbol
34
+ end
35
+
36
+ attr_reader :client, :exchange, :hashWM, :displaySymbol, :symbol
37
+
38
+ def timeseries(**args)
39
+ Finnhub::Crypto_Timeseries.new(client: @client, symbol: @symbol, **args)
40
+ end
41
+ end
42
+
43
+ class Crypto_Timeseries < Finnhub::Timeseries
44
+ def initialize(client:, symbol:, resolution: "D", count: nil,
45
+ from: nil, to: nil, format: nil)
46
+ url = "/crypto/candle?symbol=#{symbol}&resolution=#{resolution}"
47
+ url += "&count=#{count}" unless count.nil?
48
+ url += "&from=#{from}" unless from.nil?
49
+ url += "&to=#{to}" unless to.nil?
50
+ url += "&format=#{format}" unless format.nil?
51
+ @output = client.request(url)
52
+ if @output.is_a?(Hash) && @output[:s] == "ok"
53
+ @timestamps = @output[:t]&.map{|t| DateTime.strptime(t.to_s,'%s')}
54
+ else
55
+ @timestamps = []
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,18 @@
1
+ module Finnhub
2
+ class Economic_Code
3
+ def initialize(client:, code:, description:)
4
+ @client = client
5
+ @code = code
6
+ @description = description
7
+ end
8
+
9
+ attr_reader :code, :description
10
+
11
+ def data(plain: false)
12
+ output = @client.request("/economic?code=#{@code}")
13
+ return output if plain
14
+
15
+ output.map{|o| [Time.parse(o[0]), o[1]]}
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module Finnhub
2
+ class Error < StandardError
3
+ def initialize(message:, code: nil)
4
+ @code = code
5
+ super(message)
6
+ end
7
+ attr_reader :code
8
+ end
9
+ end
@@ -0,0 +1,59 @@
1
+ module Finnhub
2
+ class Forex_Exchange
3
+ def initialize(client:, name:)
4
+ @client = client
5
+ @name = name
6
+ end
7
+
8
+ attr_reader :name
9
+
10
+ def symbols(plain: false)
11
+ output = @client.request("/forex/symbol?exchange=#{@name}")
12
+ return output if plain
13
+
14
+ output.map do |o|
15
+ Finnhub::Forex_Symbol.new(client: @client, exchange: @name, **o)
16
+ end
17
+ end
18
+
19
+ def symbol(**args)
20
+ Finnhub::Forex_Symbol.new(client: @client, exchange: @name, **args)
21
+ end
22
+ end
23
+
24
+ class Forex_Symbol
25
+ include Finnhub::Analysis
26
+
27
+ def initialize(client:, exchange: nil, description: nil, hasWM: nil,
28
+ displaySymbol: nil, symbol:)
29
+ @client = client
30
+ @exchange = exchange
31
+ @hashWM = hasWM
32
+ @displaySymbol = displaySymbol
33
+ @symbol = symbol
34
+ end
35
+
36
+ attr_reader :client, :exchange, :hashWM, :displaySymbol, :symbol
37
+
38
+ def timeseries(**args)
39
+ Finnhub::Forex_Timeseries.new(client: @client, symbol: @symbol, **args)
40
+ end
41
+ end
42
+
43
+ class Forex_Timeseries < Finnhub::Timeseries
44
+ def initialize(client:, symbol:, resolution: "D", count: nil,
45
+ from: nil, to: nil, format: nil)
46
+ url = "/forex/candle?symbol=#{symbol}&resolution=#{resolution}"
47
+ url += "&count=#{count}" unless count.nil?
48
+ url += "&from=#{from}" unless from.nil?
49
+ url += "&to=#{to}" unless to.nil?
50
+ url += "&format=#{format}" unless format.nil?
51
+ @output = client.request(url)
52
+ if @output.is_a?(Hash) && @output[:s] == "ok"
53
+ @timestamps = @output[:t]&.map{|t| DateTime.strptime(t.to_s,'%s')}
54
+ else
55
+ @timestamps = []
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,55 @@
1
+ module Finnhub
2
+ class Stock
3
+ include Finnhub::Analysis
4
+
5
+ def initialize(client:, symbol:)
6
+ @client = client
7
+ @symbol = symbol
8
+ end
9
+
10
+ attr_reader :symbol
11
+
12
+ def profile
13
+ @client.request("/stock/profile?symbol=#{@symbol}")
14
+ end
15
+
16
+ def ceo_compensation
17
+ @client.request("/stock/ceo-compensation?symbol=#{@symbol}")
18
+ end
19
+
20
+ def recommendation
21
+ @client.request("/stock/recommendation?symbol=#{@symbol}")
22
+ end
23
+
24
+ def price_target
25
+ @client.request("/stock/price-target?symbol=#{@symbol}")
26
+ end
27
+
28
+ def option_chain
29
+ @client.request("/stock/option-chain?symbol=#{@symbol}")
30
+ end
31
+
32
+ def peers(plain: false)
33
+ output = @client.request("/stock/peers?symbol=#{@symbol}")
34
+ return output if plain
35
+
36
+ output.map{|o| Finnhub::Stock.new(client: @client, symbol: o)}
37
+ end
38
+
39
+ def earnings
40
+ @client.request("/stock/earnings?symbol=#{@symbol}")
41
+ end
42
+
43
+ def news
44
+ @client.request("/news/#{@symbol}")
45
+ end
46
+
47
+ def sentiment
48
+ @client.request("/news-sentiment?symbol=#{@symbol}")
49
+ end
50
+
51
+ def timeseries(**args)
52
+ Finnhub::Timeseries.new(client: @client, stock: self, **args)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,55 @@
1
+ module Finnhub
2
+ class Timeseries
3
+ def initialize(client:, stock:, resolution: "D", count: 100,
4
+ from: nil, to: nil, format: nil)
5
+ url = "/stock/candle?symbol=#{stock.symbol}&resolution=#{resolution}"
6
+ url += "&count=#{count}" unless count.nil?
7
+ from = from.to_i if from.is_a?(Time)
8
+ url += "&from=#{from}" unless from.nil?
9
+ to = to.to_i if to.is_a?(Time)
10
+ url += "&to=#{to}" unless to.nil?
11
+ url += "&format=#{format}" unless format.nil?
12
+ @output = client.request(url)
13
+ if @output.is_a?(Hash) && @output[:s] == "ok"
14
+ @timestamps = @output[:t]&.map{|t| DateTime.strptime(t.to_s,'%s')}
15
+ else
16
+ @timestamps = []
17
+ end
18
+ end
19
+
20
+ attr_reader :output, :timestamps
21
+
22
+ def open
23
+ operation(:o)
24
+ end
25
+
26
+ def high
27
+ operation(:h)
28
+ end
29
+
30
+ def low
31
+ operation(:l)
32
+ end
33
+
34
+ def close
35
+ operation(:c)
36
+ end
37
+
38
+ def volume
39
+ operation(:v)
40
+ end
41
+
42
+ def status
43
+ raise Finnhub::Error message: "Output is not a hash" unless @output.is_a?(Hash)
44
+ @output[:s]
45
+ end
46
+
47
+ private
48
+
49
+ def operation(type)
50
+ raise Finnhub::Error message: "Output is not a hash" unless @output.is_a?(Hash)
51
+ return [] if @output[type].nil?
52
+ @timestamps.zip(@output[type])
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ module Finnhub
2
+ class Websocket < Faye::WebSocket::Client
3
+ def initialize(apikey)
4
+ super("wss://ws.finnhub.io?token=#{apikey}")
5
+ end
6
+
7
+ def subscribe(symbol)
8
+ case symbol
9
+ when Finnhub::Stock, Finnhub::Crypto_Symbol, Finnhub::Forex_Symbol
10
+ symbol = symbol.symbol
11
+ end
12
+
13
+ send(Oj.dump(
14
+ {"type": "subscribe", "symbol": symbol},
15
+ mode: :json))
16
+ end
17
+
18
+ def unsubscribe(symbol)
19
+ case symbol
20
+ when Finnhub::Stock, Finnhub::Crypto_Symbol, Finnhub::Forex_Symbol
21
+ symbol = symbol.symbol
22
+ end
23
+
24
+ send(Oj.dump(
25
+ {"type": "unsubscribe", "symbol": symbol},
26
+ mode: :json))
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ require "oj"
2
+ require "httparty"
3
+ require "time"
4
+ require 'em/pure_ruby'
5
+ require "faye/websocket"
6
+ require_relative "Analysis"
7
+ require_relative "Calendar"
8
+ require_relative "Timeseries"
9
+ require_relative "Client"
10
+ require_relative "Country"
11
+ require_relative "Crypto"
12
+ require_relative "Economic"
13
+ require_relative "Error"
14
+ require_relative "Forex"
15
+ require_relative "Stock"
16
+ require_relative "Websocket"
@@ -0,0 +1,84 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe "1.0.0" do
4
+ context "Crypto" do
5
+ it "create a new client" do
6
+ @store[:client] = Finnhub::Client.new(key: @key, verbose: true)
7
+ expect(@store[:client].class).to be Finnhub::Client
8
+ end
9
+
10
+ it "can retrieve multiple crypto_exchanges" do
11
+ crypto_exchanges = @store[:client].crypto_exchanges(plain: true)
12
+ expect(crypto_exchanges.class).to be Array
13
+
14
+ @store[:crypto_exchange_name] = crypto_exchanges[0]
15
+
16
+ crypto_exchanges = @store[:client].crypto_exchanges
17
+ expect(crypto_exchanges.class).to be Array
18
+ expect(crypto_exchanges[0].class).to be Finnhub::Crypto_Exchange
19
+ end
20
+
21
+ it "can create a crypto_exchange instance" do
22
+ @store[:crypto_exchange] = @store[:client].crypto_exchange(name: @store[:crypto_exchange_name])
23
+ expect(@store[:crypto_exchange].class).to be Finnhub::Crypto_Exchange
24
+ end
25
+
26
+ it "can retrieve multiple symbols" do
27
+ crypto_symbols = @store[:crypto_exchange].symbols(plain: true)
28
+ expect(crypto_symbols.class).to be Array
29
+
30
+ @store[:crypto_exchange_symbol] = crypto_symbols[0][:symbol]
31
+
32
+ crypto_symbols = @store[:crypto_exchange].symbols
33
+ expect(crypto_symbols.class).to be Array
34
+ expect(crypto_symbols[0].class).to be Finnhub::Crypto_Symbol
35
+ end
36
+
37
+ it "create a new crypto_symbol" do
38
+ @store[:crypto_symbol] = @store[:crypto_exchange].symbol(symbol: @store[:crypto_exchange_symbol])
39
+ expect(@store[:crypto_symbol].class).to be Finnhub::Crypto_Symbol
40
+ end
41
+
42
+
43
+ it "can retrieve timeseries" do
44
+ timeseries = @store[:crypto_symbol].timeseries(count: 100)
45
+ expect(timeseries.open.class).to be Array
46
+ expect(timeseries.high.class).to be Array
47
+ expect(timeseries.low.class).to be Array
48
+ expect(timeseries.close.class).to be Array
49
+ expect(timeseries.volume.class).to be Array
50
+ expect(timeseries.status).to eq "ok"
51
+ expect(timeseries.output.class).to be Hash
52
+
53
+ timeseries = @store[:crypto_symbol].timeseries(resolution: 60, from: Time.now-24*30*3600, to: Time.now)
54
+ expect(timeseries.open.class).to be Array
55
+ expect(timeseries.status).to eq "ok"
56
+
57
+ timeseries = @store[:crypto_symbol].timeseries(resolution: 60, from: Time.now-24*30*3600, to: Time.now, format: "csv")
58
+ expect(timeseries.output.class).to be String
59
+
60
+ error = nil
61
+ begin
62
+ @store[:crypto_symbol].timeseries(resolution: 60, from: Time.now-24*30*3600, to: Time.now, format: "wrong")
63
+ rescue Finnhub::Error => e
64
+ error = e
65
+ end
66
+ expect(error.class).to be Finnhub::Error
67
+ end
68
+
69
+ it "can retrieve pattern" do
70
+ output = @store[:crypto_symbol].pattern
71
+ expect(output[:points][0].key?(:symbol)).to eq true
72
+ end
73
+
74
+ it "can retrieve support_resistance" do
75
+ output = @store[:crypto_symbol].support_resistance
76
+ expect(output.key?(:levels)).to be true
77
+ end
78
+
79
+ it "can retrieve technical_indicators" do
80
+ output = @store[:crypto_symbol].technical_indicators
81
+ expect(output.key?(:technicalAnalysis)).to be true
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,84 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe "1.0.0" do
4
+ context "Forex" do
5
+ it "create a new client" do
6
+ @store[:client] = Finnhub::Client.new(key: @key, verbose: true)
7
+ expect(@store[:client].class).to be Finnhub::Client
8
+ end
9
+
10
+ it "can retrieve multiple forex_exchanges" do
11
+ forex_exchanges = @store[:client].forex_exchanges(plain: true)
12
+ expect(forex_exchanges.class).to be Array
13
+
14
+ @store[:forex_exchange_name] = forex_exchanges[0]
15
+
16
+ forex_exchanges = @store[:client].forex_exchanges
17
+ expect(forex_exchanges.class).to be Array
18
+ expect(forex_exchanges[0].class).to be Finnhub::Forex_Exchange
19
+ end
20
+
21
+ it "can create a forex_exchange instance" do
22
+ @store[:forex_exchange] = @store[:client].forex_exchange(name: @store[:forex_exchange_name])
23
+ expect(@store[:forex_exchange].class).to be Finnhub::Forex_Exchange
24
+ end
25
+
26
+ it "can retrieve multiple symbols" do
27
+ forex_symbols = @store[:forex_exchange].symbols(plain: true)
28
+ expect(forex_symbols.class).to be Array
29
+
30
+ @store[:forex_exchange_symbol] = forex_symbols[0][:symbol]
31
+
32
+ forex_exchanges = @store[:forex_exchange].symbols
33
+ expect(forex_exchanges.class).to be Array
34
+ expect(forex_exchanges[0].class).to be Finnhub::Forex_Symbol
35
+ end
36
+
37
+ it "create a new forex_symbol" do
38
+ @store[:forex_symbol] = @store[:forex_exchange].symbol(symbol: @store[:forex_exchange_symbol])
39
+ expect(@store[:forex_symbol].class).to be Finnhub::Forex_Symbol
40
+ end
41
+
42
+
43
+ it "can retrieve timeseries" do
44
+ timeseries = @store[:forex_symbol].timeseries(count: 100)
45
+ expect(timeseries.open.class).to be Array
46
+ expect(timeseries.high.class).to be Array
47
+ expect(timeseries.low.class).to be Array
48
+ expect(timeseries.close.class).to be Array
49
+ expect(timeseries.volume.class).to be Array
50
+ expect(timeseries.status).to eq "ok"
51
+ expect(timeseries.output.class).to be Hash
52
+
53
+ timeseries = @store[:forex_symbol].timeseries(resolution: 60, from: Time.now-24*30*3600, to: Time.now)
54
+ expect(timeseries.open.class).to be Array
55
+ expect(["ok", "no_data"]).to include timeseries.status
56
+
57
+ timeseries = @store[:forex_symbol].timeseries(resolution: 60, from: Time.now-24*30*3600, to: Time.now, format: "csv")
58
+ expect(timeseries.output.class).to be String
59
+
60
+ error = nil
61
+ begin
62
+ @store[:forex_symbol].timeseries(resolution: 60, from: Time.now-24*30*3600, to: Time.now, format: "wrong")
63
+ rescue Finnhub::Error => e
64
+ error = e
65
+ end
66
+ expect(error.class).to be Finnhub::Error
67
+ end
68
+
69
+ it "can retrieve pattern" do
70
+ output = @store[:forex_symbol].pattern
71
+ expect(output[:points][0].key?(:symbol)).to eq true
72
+ end
73
+
74
+ it "can retrieve support_resistance" do
75
+ output = @store[:forex_symbol].support_resistance
76
+ expect(output.key?(:levels)).to be true
77
+ end
78
+
79
+ it "can retrieve technical_indicators" do
80
+ output = @store[:forex_symbol].technical_indicators
81
+ expect(output.key?(:technicalAnalysis)).to be true
82
+ end
83
+ end
84
+ end