algonquin_stocks 2.0.0 → 2.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 +4 -4
- data/README.md +4 -2
- data/lib/algonquin_stocks/stock.rb +71 -17
- data/lib/algonquin_stocks/stock_client.rb +72 -13
- data/lib/algonquin_stocks/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a853fc21135ba1200935b7ce64979a390eb1c2922ba179500fedb92da2504921
|
4
|
+
data.tar.gz: 639579beeb874967cd76a0e6d465dfa8b36b1ec061d57d016dfaf29ba6cb956b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f3974a9003813154409a4582f62c52080aa9c9307f3d46ffdd452958d3586a275cc4d8ed3d9b0fe0bd61083a68edba58c4feae2571f6090f67f5c5745bca44a
|
7
|
+
data.tar.gz: 6a0e4dae31a22042042f319a23392e62ec7a025929f188ca3d57aa6cce0acacf5dc4d0a03dff87baecc1d36a2cefbf60521bbb59eb518f9e08b423d044644828
|
data/README.md
CHANGED
@@ -12,14 +12,15 @@ To install the 'algonquin_stocks' ruby gem:
|
|
12
12
|
|
13
13
|
To use the gem in your Rails Application, include it in your Gemfile:
|
14
14
|
|
15
|
-
`gem "algonquin_stocks", "~> 1.
|
15
|
+
`gem "algonquin_stocks", "~> 2.1.0"`
|
16
16
|
|
17
17
|
## Initialization
|
18
18
|
|
19
19
|
To initialize AlgonquinStocks with a valid API_KEY:
|
20
20
|
|
21
|
-
`AlgonquinStocks::StockClient.new YOUR_API_KEY`
|
21
|
+
`AlgonquinStocks::StockClient.new YOUR_API_KEY, CACHE`
|
22
22
|
|
23
|
+
CACHE is optional and defaults to false. If set to true, the gem will cache the stock data in a SQLite database.
|
23
24
|
|
24
25
|
## Usage
|
25
26
|
|
@@ -37,6 +38,7 @@ Quote is the primary method, returning a AlgonquinStocks::Stock instance includi
|
|
37
38
|
- close
|
38
39
|
- change
|
39
40
|
- percent
|
41
|
+
- data
|
40
42
|
|
41
43
|
|
42
44
|
### AlgonquinStocks::StockClient#data(symbol)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'date'
|
2
|
+
require 'logger'
|
2
3
|
|
3
4
|
module AlgonquinStocks
|
4
5
|
# => AlgonquinStocks::Stock
|
@@ -6,32 +7,19 @@ module AlgonquinStocks
|
|
6
7
|
# @param json [Hash] The JSON response from Alpha Vantage.
|
7
8
|
# @return [AlgonquinStocks::Stock] The stock object.
|
8
9
|
class Stock
|
9
|
-
attr_reader :symbol, :data, :open, :high, :low, :price, :volume, :date, :close, :change, :percent
|
10
|
-
|
11
|
-
# => AlgonquinStocks::Stock#initialize
|
12
|
-
#
|
13
|
-
# @param json [Hash] The JSON response from Alpha Vantage.
|
14
|
-
# @return [AlgonquinStocks::Stock] The stock object.
|
15
10
|
def initialize(json)
|
16
11
|
update json
|
17
12
|
end
|
18
|
-
|
19
|
-
SYMBOL = '01. symbol'
|
20
|
-
OPEN = '02. open'
|
21
|
-
HIGH = '03. high'
|
22
|
-
LOW = '04. low'
|
23
|
-
PRICE = '05. price'
|
24
|
-
VOLUME = '06. volume'
|
25
|
-
DATE = '07. latest trading day'
|
26
|
-
CLOSE = '08. previous close'
|
27
|
-
CHANGE = '09. change'
|
28
|
-
PERCENT = '10. change percent'
|
29
13
|
|
14
|
+
@@log = Logger.new(STDOUT)
|
15
|
+
@@log.level = Logger::INFO
|
16
|
+
|
30
17
|
# => AlgonquinStocks::Stock#update
|
31
18
|
#
|
32
19
|
# @param json [Hash] The JSON response from Alpha Vantage.
|
33
20
|
# @return [AlgonquinStocks::Stock] The stock object.
|
34
21
|
def update(json)
|
22
|
+
@@log.info "update: #{json}"
|
35
23
|
@symbol = json[SYMBOL]
|
36
24
|
@open = json[OPEN].to_f
|
37
25
|
@high = json[HIGH].to_f
|
@@ -55,11 +43,77 @@ module AlgonquinStocks
|
|
55
43
|
}
|
56
44
|
end
|
57
45
|
|
46
|
+
SYMBOL = '01. symbol'
|
47
|
+
OPEN = '02. open'
|
48
|
+
HIGH = '03. high'
|
49
|
+
LOW = '04. low'
|
50
|
+
PRICE = '05. price'
|
51
|
+
VOLUME = '06. volume'
|
52
|
+
DATE = '07. latest trading day'
|
53
|
+
CLOSE = '08. previous close'
|
54
|
+
CHANGE = '09. change'
|
55
|
+
PERCENT = '10. change percent'
|
56
|
+
|
58
57
|
# => AlgonquinStocks::Stock#to_s
|
59
58
|
#
|
60
59
|
# @return [String] The stock object as a string.
|
61
60
|
def to_s
|
62
61
|
"#{symbol}: #{price} (#{change}, #{percent}) #{date}"
|
63
62
|
end
|
63
|
+
|
64
|
+
# => AlgonquinStocks::Stock#symbol
|
65
|
+
#
|
66
|
+
# @return [String] The symbol of the stock.
|
67
|
+
attr_reader :symbol
|
68
|
+
|
69
|
+
# => AlgonquinStocks::Stock#data
|
70
|
+
#
|
71
|
+
# @return [Hash] The stock data.
|
72
|
+
attr_reader :data
|
73
|
+
|
74
|
+
# => AlgonquinStocks::Stock#open
|
75
|
+
#
|
76
|
+
# @return [Float] The open price of the stock.
|
77
|
+
attr_reader :open
|
78
|
+
|
79
|
+
# => AlgonquinStocks::Stock#high
|
80
|
+
#
|
81
|
+
# @return [Float] The high price of the stock.
|
82
|
+
attr_reader :high
|
83
|
+
|
84
|
+
# => AlgonquinStocks::Stock#low
|
85
|
+
#
|
86
|
+
# @return [Float] The low price of the stock.
|
87
|
+
attr_reader :low
|
88
|
+
|
89
|
+
# => AlgonquinStocks::Stock#price
|
90
|
+
#
|
91
|
+
# @return [Float] The price of the stock.
|
92
|
+
attr_reader :price
|
93
|
+
|
94
|
+
# => AlgonquinStocks::Stock#volume
|
95
|
+
#
|
96
|
+
# @return [Integer] The volume of the stock.
|
97
|
+
attr_reader :volume
|
98
|
+
|
99
|
+
# => AlgonquinStocks::Stock#date
|
100
|
+
#
|
101
|
+
# @return [Date] The latest trading day of the stock.
|
102
|
+
attr_reader :date
|
103
|
+
|
104
|
+
# => AlgonquinStocks::Stock#close
|
105
|
+
#
|
106
|
+
# @return [Float] The previous close price of the stock.
|
107
|
+
attr_reader :close
|
108
|
+
|
109
|
+
# => AlgonquinStocks::Stock#change
|
110
|
+
#
|
111
|
+
# @return [Float] The change of the stock price.
|
112
|
+
attr_reader :change
|
113
|
+
|
114
|
+
# => AlgonquinStocks::Stock#percent
|
115
|
+
#
|
116
|
+
# @return [Float] The percent change of the stock price.
|
117
|
+
attr_reader :percent
|
64
118
|
end
|
65
119
|
end
|
@@ -1,45 +1,104 @@
|
|
1
1
|
require 'rest-client'
|
2
2
|
require 'json'
|
3
|
+
require 'date'
|
4
|
+
require 'sqlite3'
|
5
|
+
require 'logger'
|
3
6
|
|
4
7
|
module AlgonquinStocks
|
5
8
|
# => AlgonquinStocks::StockClient
|
6
9
|
#
|
7
10
|
# @param api_key [String] The API key for Alpha Vantage.
|
11
|
+
# @param cached [Boolean] Whether to use cached data.
|
8
12
|
# @return [AlgonquinStocks::StockClient] The stock client object.
|
9
13
|
class StockClient
|
10
|
-
|
11
|
-
FUNCTION = "GLOBAL_QUOTE"
|
12
|
-
|
13
|
-
# => AlgonquinStocks::StockClient#initialize
|
14
|
-
#
|
15
|
-
# @param api_key [String] The API key for Alpha Vantage.
|
16
|
-
# @return [AlgonquinStocks::StockClient] The stock client object.
|
17
|
-
def initialize(api_key)
|
14
|
+
def initialize(api_key, cached = false)
|
18
15
|
@api_key = api_key
|
16
|
+
@cached = cached
|
19
17
|
@url = "#{URL_BASE}?apikey=#{@api_key}"
|
18
|
+
@db = SQLite3::Database.new 'cache.db'
|
19
|
+
@db.execute 'create table if not exists Stocks (Symbol text, Function text, Data text, Fetched datetime, primary key (Symbol, Function))'
|
20
|
+
end
|
21
|
+
|
22
|
+
@@log = Logger.new(STDOUT)
|
23
|
+
@@log.level = Logger::INFO
|
24
|
+
|
25
|
+
URL_BASE = 'https://www.alphavantage.co/query'
|
26
|
+
FUNCTION = 'GLOBAL_QUOTE'
|
27
|
+
|
28
|
+
SQL_SYMBOL = 0
|
29
|
+
SQL_FUNCTION = 1
|
30
|
+
SQL_DATA = 2
|
31
|
+
SQL_FETCHED = 3
|
32
|
+
# => AlgonquinStocks::StockClient#save_cached
|
33
|
+
#
|
34
|
+
# @param symbol [String] The symbol of the stock.
|
35
|
+
# @param function [String] The API function value.
|
36
|
+
# @param data [Hash] The data to save.
|
37
|
+
# @return [Boolean] Whether the data was saved.
|
38
|
+
def save_cached(symbol, function, data)
|
39
|
+
@@log.info "save_cached: #{symbol}, #{function}, #{data}"
|
40
|
+
return @db.execute 'insert into Stocks (Symbol, Function, Data, Fetched) values (?, ?, ?, ?)', [symbol, function, data, DateTime.now.to_s]
|
41
|
+
end
|
42
|
+
|
43
|
+
# => AlgonquinStocks::StockClient#get_cached
|
44
|
+
#
|
45
|
+
# @param symbol [String] The symbol of the stock.
|
46
|
+
# @param function [String] The API function value.
|
47
|
+
# @return [Hash, String] The cached data and fetched date.
|
48
|
+
def get_cached(symbol, function)
|
49
|
+
@@log.info "get_cached: #{symbol}, #{function}"
|
50
|
+
result = @db.execute 'select * from Stocks where Symbol = ? and Function = ?', [symbol, function]
|
51
|
+
if result.length > 0
|
52
|
+
@@log.info "cached data: #{result}"
|
53
|
+
return result[0][SQL_DATA], result[0][SQL_FETCHED]
|
54
|
+
end
|
55
|
+
@@log.info '*** no cached data found ***'
|
56
|
+
return nil
|
20
57
|
end
|
21
58
|
|
22
59
|
# => AlgonquinStocks::StockClient#data
|
23
60
|
#
|
24
61
|
# @param symbol [String] The symbol of the stock.
|
25
|
-
# @param function [String] The function
|
62
|
+
# @param function [String] The API function value.
|
26
63
|
# @return [Hash] The JSON response from Alpha Vantage.
|
27
64
|
def data(symbol, function=FUNCTION)
|
65
|
+
@@log.info "data: #{symbol}, #{function}"
|
28
66
|
url = "#{@url}&function=#{function}&symbol=#{symbol}"
|
67
|
+
@@log.info "url: #{url}"
|
29
68
|
RestClient::Request.execute url: url, method: :get, verify_ssl: false do |response|
|
30
69
|
raise response.body unless response.code == 200
|
31
|
-
|
70
|
+
response.body
|
32
71
|
end
|
33
72
|
end
|
34
73
|
|
35
74
|
# => AlgonquinStocks::StockClient#quote
|
36
75
|
#
|
37
76
|
# @param symbol [String] The symbol of the stock.
|
38
|
-
# @param function [String] The function
|
77
|
+
# @param function [String] The API function value.
|
39
78
|
# @return [AlgonquinStocks::Stock] The stock object.
|
40
79
|
def quote(symbol, function=FUNCTION)
|
41
|
-
|
42
|
-
|
80
|
+
@@log.info "quote: #{symbol}, #{function}"
|
81
|
+
if @cached
|
82
|
+
json_str, fetched = get_cached symbol, function
|
83
|
+
if fetched
|
84
|
+
fetched_date = DateTime.parse fetched
|
85
|
+
if fetched_date > DateTime.now - DateTime.parse('5 hours')
|
86
|
+
@@log.info '*** using cached data ***'
|
87
|
+
json = JSON.parse json_str
|
88
|
+
stock = Stock.new json
|
89
|
+
return stock
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
json_data = data symbol, function
|
94
|
+
json = (JSON.parse json_data)['Global Quote']
|
95
|
+
if !json
|
96
|
+
@@log.info '*** no data found ***'
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
stock = Stock.new json
|
100
|
+
save_cached symbol, function, json.to_json
|
101
|
+
return stock
|
43
102
|
end
|
44
103
|
end
|
45
104
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algonquin_stocks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrei Grobnic
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A gem for retrieving stock information
|
14
14
|
email:
|