alphavantagerb 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45b9bfaa0883fbcebabc5b26972fd66f736df2c4
4
- data.tar.gz: 9407ed9a0c3761d8ba70bf79a19678bc7b614ac8
3
+ metadata.gz: 743749f1cf99b12c71e4c5550074305f1c7b04a5
4
+ data.tar.gz: 5640ecf935bc22da9f2dc6577e138e1f3846a43c
5
5
  SHA512:
6
- metadata.gz: d07776377781826d1778768bad668cf5125f3e8856b52828c27b0d3a45bfe18907023739cd0d4884af890ce9727f528c4775e02f502fac9970980e48dcdb0bf3
7
- data.tar.gz: 60945c1de9ffc3d0c08dff5b65b87cf3cba61615f32d61107e17f3ffcf9db5afa8570f6abb978cc61069bcc31385ff4e46cc354418728ea0a455f768b31bda9f
6
+ metadata.gz: f46bf5a084371e19873eb21cc8ece703da94469fa079b933db4cc79f6d8b194adf0d280bb75c29f196ab7ce92c111a88b887af2156aa58faefce6e4906735bc0
7
+ data.tar.gz: 7bd15d518d533a731935bfaeca3b30a986e087a35be39562b97e7cf0d0f357b4ff84a3fd29e0133c5f5e422095b9577fcec7be2ab9d8442b5d3b79637aa0540d
@@ -4,7 +4,7 @@ require "rake"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "alphavantagerb"
7
- s.version = "1.2.0"
7
+ s.version = "1.3.0"
8
8
  s.authors = ["Stefano Martin"]
9
9
  s.email = ["stefano.martin87@gmail.com"]
10
10
  s.homepage = "https://github.com/StefanoMartin/AlphaVantageRB"
data/README.md CHANGED
@@ -10,6 +10,16 @@ To install AlphavantageRB: `gem install alphavantagerb`
10
10
 
11
11
  To use it in your application: `require "alphavantagerb"`
12
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
+ ``` ruby
17
+ key: [YOUR KEY]
18
+ ```
19
+
20
+ Then run "rspec spec/test_all.rb".
21
+ Since AlphaVantage does not permit more than 5 request for minutes, many of your tests will fail. I advice either having a premium account or, like me, trying each file of test from the folder "spec/lib/1.0.0".
22
+
13
23
  ## Classes
14
24
 
15
25
  AlphavantateRB has the following classes:
@@ -18,12 +28,12 @@ AlphavantateRB has the following classes:
18
28
  Vantage
19
29
  * [Alphavantage::Stock](#Stock): to create a stock class
20
30
  * [Alphavantage::Timeseries](#Timeseries): to retrieve historical data of a stock
21
- * [Alphavantage::Batch](#Batch): to retrieve multiple stock data at once
22
31
  * [Alphavantage::Indicator](#Indicator): to use some technical indicator of a stock
23
32
  * [Alphavantage::Crypto](#Crypto): to create a crypto currency class
24
33
  * [Alphavantage::Crypto_Timeseries](#Crypto_Timeseries): to retrieve historical
25
34
  data of a crypto currency
26
35
  * [Alphavantage::Exchange](#Exchange): to retrieve how a currency is exchanged currently on the market
36
+ * [Alphavantage::Exchange_Timeseries](#Exchange_Timeseries): to retrieve historical data of how a currency is exchanged currently on the market
27
37
  * [Alphavantage::Sector](#Sector): to retrieve the status of the historical sector performances calculated from S&P500 incumbents
28
38
  * [Alphavantage::Error](#Error): to manage AlphavantageRB errors
29
39
 
@@ -42,7 +52,32 @@ If you want to see the request that the client will do to Alpha Vantage you can
42
52
  setup verbose equal to true.
43
53
 
44
54
  ``` ruby
45
- client.verbose = true # You can setup this during the initialization too
55
+ client.verbose = true # You can setup this during the initialization too
56
+ ```
57
+
58
+ You can use the method search to find some stocks by name.
59
+ ``` ruby
60
+ stocks_found = client.search keywords: "MSFT"
61
+ stocks_found.output # Return the hash retrieved
62
+ ```
63
+
64
+ This will return an array where each elements has the following structure:
65
+ ``` ruby
66
+ stocks_found.stocks[0].symbol
67
+ stocks_found.stocks[0].name
68
+ stocks_found.stocks[0].type
69
+ stocks_found.stocks[0].region
70
+ stocks_found.stocks[0].marketopen
71
+ stocks_found.stocks[0].marketclose
72
+ stocks_found.stocks[0].timezone
73
+ stocks_found.stocks[0].currency
74
+ stocks_found.stocks[0].matchscore
75
+ ```
76
+
77
+ Furthermore you can retrieve its respective AlphaVantage::Stock instance by using:
78
+
79
+ ``` ruby
80
+ stocks_found.stocks[0].stock
46
81
  ```
47
82
 
48
83
  <a name="Stock"></a>
@@ -67,7 +102,7 @@ Note that the initialization owns different entry:
67
102
  You can setup the datatype of future retrieving by doing:
68
103
 
69
104
  ``` ruby
70
- stock.datatype = "csv"
105
+ stock.datatype = "csv"
71
106
  ```
72
107
 
73
108
  <a name="Timeseries"></a>
@@ -96,7 +131,7 @@ Note that the initialization owns different entries:
96
131
 
97
132
  You can retrieve all the output from Alpha Vantage by doing.
98
133
  ``` ruby
99
- timeseries.hash
134
+ timeseries.output
100
135
  ```
101
136
 
102
137
  Specific information about the timeseries can be retrieved using the following methods:
@@ -131,44 +166,6 @@ You can order the data in ascending or descending order.
131
166
  timeseries.open("asc")
132
167
  ```
133
168
 
134
- <a name="Batch"></a>
135
- ## Alphavantage::Batch
136
-
137
- Alphavantage::Batch is used to retrieve the last updated values of multiple stocks.
138
- To create a new Batch class you can use a Client class or you can create it directly.
139
- These two creation commands are equivalent:
140
-
141
- ``` ruby
142
- batch = client.batch symbols: ["MSFT", "FB", "AAPL"]
143
- batch = Alphavantage::Batch.new symbols: ["MSFT", "FB", "AAPL"], key: "YOURKEY"
144
- ```
145
-
146
- Note that the initialization owns different entries:
147
- * symbols: it is an array of string that denote the stocks you want to retrieve.
148
- * key: authentication key. This value cannot be setup if you are initializing a batch from a client
149
- * verbose: used to see the request to Alpha Vantage (default false). This value cannot be setup if you are initializing a batch from a client
150
- * datatype: it can be "json" or "csv" (default "json")
151
- * file: path where a csv file should be saved (default "nil")
152
-
153
- You can retrieve all the output from Alpha Vantage by doing.
154
- ``` ruby
155
- batch.hash
156
- ```
157
-
158
- The array of the stocks is found by using:
159
- ``` ruby
160
- batch.stock_quotes
161
- ```
162
-
163
- Specific information about the batch can be retrieved using the following methods:
164
-
165
- ``` ruby
166
- batch.information # Retrieve information about the batch
167
- batch.symbols # Symbols used by the batch
168
- batch.notes # Generic notes of the batch
169
- batch.time_zone # Time zone of the batch
170
- ```
171
-
172
169
  <a name="Indicator"></a>
173
170
  ## Alphavantage::Indicator
174
171
 
@@ -201,7 +198,7 @@ The MA parameters accept as an entry one of these attributes: "0", "1", "2", "3"
201
198
  Each indicator has several methods that can use in relation of the type. Some are used for each indicator.
202
199
  ``` ruby
203
200
  indicator = stock.indicator(function: "SMA", interval: "weekly", time_period: "60", series_type: "close")
204
- indicator.hash # Retrieve the output from Alpha vantage
201
+ indicator.output # Retrieve the output from Alpha vantage
205
202
  indicator.symbol
206
203
  indicator.interval
207
204
  indicator.indicator
@@ -680,7 +677,7 @@ Note that the initialization owns different entries:
680
677
 
681
678
  You can retrieve all the output from Alpha Vantage by doing.
682
679
  ``` ruby
683
- crypto_timeseries.hash
680
+ crypto_timeseries.output
684
681
  ```
685
682
 
686
683
  Specific information about the timeseries can be retrieved using the following methods:
@@ -740,24 +737,82 @@ Note that the initialization owns different entry:
740
737
  * verbose: used to see the request to Alpha Vantage (default false). This value cannot be setup if you are initializing a timeseries from a stock
741
738
  * datatype: it can be "json" or "csv" (default "json")
742
739
 
743
- You can retrieve all the output from Alpha Vantage by doing.
740
+ You can retrieve the actual situation of the exchange from Alpha Vantage by doing.
744
741
  ``` ruby
745
- exchange.hash
742
+ ex_now = exchange.now
746
743
  ```
747
744
 
748
745
  Other information can be retrieved using the following methods:
749
746
 
750
747
  ``` ruby
751
- exchange.from_currency_code # Code of the from currency
752
- exchange.from_currency_name # Name of the from currency
753
- exchange.to_currency_code # Code of the to currency
754
- exchange.to_currency_name # Name of the to currency
755
- exchange.exchange_rate # Exchange rate between the two currencies
756
- exchange.information # Retrieve information about the timeseries
757
- exchange.symbol # Symbol used by the timeseries
748
+ ex_now.from_currency_code # Code of the from currency
749
+ ex_now.from_currency_name # Name of the from currency
750
+ ex_now.to_currency_code # Code of the to currency
751
+ ex_now.to_currency_name # Name of the to currency
752
+ ex_now.exchange_rate # Exchange rate between the two currencies
753
+ ex_now.information # Retrieve information about the timeseries
754
+ ex_now.symbol # Symbol used by the timeseries
758
755
  exchange.last_refreshed # A timestamp that show when last time the data were refreshed
759
- exchange.output_size # Size of the output
760
- exchange.time_zone # Time zone of the timeseries
756
+ ex_now.output_size # Size of the output
757
+ ex_now.time_zone # Time zone of the timeseries
758
+ ```
759
+
760
+ <a name="Exchange_Timeseries"></a>
761
+ ## Alphavantage::Exchange_Timeseries
762
+
763
+ Alphavantage::Exchange_Timeseries is used to retrieve historical data of an exchange currency.
764
+ To create a new Exchange_Timeseries class you can use an Exchange class or you can create it directly.
765
+ These two creation commands are equivalent:
766
+
767
+ ``` ruby
768
+ exchange_timeseries = exchange.timeseries type: "daily"
769
+ exchange_timeseries = Alphavantage::Exchange_Timeseries.new from: "USD", to: "DKK", key: "YOURKEY", type: "daily"
770
+ ```
771
+
772
+ Note that the initialization owns different entries:
773
+ * symbol: it is a string that denote the stock you want to retrieve. This value cannot be setup if you are initializing a timeseries from a stock
774
+ * key: authentication key. This value cannot be setup if you are initializing a timeseries from a stock
775
+ * verbose: used to see the request to Alpha Vantage (default false). This value cannot be setup if you are initializing a timeseries from a stock
776
+ * type: it can be "intraday", "daily", "weekly", "monthly" (default "daily")
777
+ * adjusted: a boolean value, it returns adjusted values (default false)
778
+ * interval: it can be "1min", "5min", "15min", "30min", or "60min". It is used
779
+ only if type is "intraday" (default nil)
780
+ * outputsize: it can be "compact", or "full" (default "compact")
781
+ * datatype: it can be "json" or "csv" (default "json")
782
+ * file: path where a csv file should be saved (default "nil")
783
+
784
+ You can retrieve all the output from Alpha Vantage by doing.
785
+ ``` ruby
786
+ exchange_timeseries.output
787
+ ```
788
+
789
+ Specific information about the timeseries can be retrieved using the following methods:
790
+
791
+ ``` ruby
792
+ exchange_timeseries.information # Retrieve information about the timeseries
793
+ exchange_timeseries.from_symbol # Code of the from symbol
794
+ exchange_timeseries.to_symbol # Code of the to symbol
795
+ exchange_timeseries.last_refreshed # A timestamp that show when last time the data were refreshed
796
+ exchange_timeseries.output_size # Size of the output
797
+ exchange_timeseries.time_zone # Time zone of the timeseries
798
+ ```
799
+
800
+ Specific data can be retrieved using the following methods.
801
+ These methods will return an array of couples where the first entry is a timestampand the second one is the value of the stock at the timestamp.
802
+ These timeseries return always the corrispective timeseries in relation of the USD market.
803
+
804
+ ``` ruby
805
+ exchange_timeseries.open
806
+ exchange_timeseries.close
807
+ exchange_timeseries.high
808
+ exchange_timeseries.low
809
+ ```
810
+
811
+ You can order the data in ascending or descending order.
812
+
813
+ ``` ruby
814
+ exchange_timeseries.open("desc") # Default
815
+ exchange_timeseries.open("asc")
761
816
  ```
762
817
 
763
818
  <a name="Sector"></a>
@@ -777,7 +832,7 @@ Note that the initialization owns different entries:
777
832
 
778
833
  You can retrieve all the output from Alpha Vantage by doing.
779
834
  ``` ruby
780
- sector.hash
835
+ sector.output
781
836
  ```
782
837
 
783
838
  Specific information about the timeseries can be retrieved using the following methods:
@@ -51,16 +51,31 @@ module Alphavantage
51
51
  return "CSV saved in #{file}"
52
52
  end
53
53
 
54
- def batch(symbols:, datatype: "json", file: nil)
55
- Alphavantage::Batch.new symbols: symbols, key: self, datatype: datatype, file: file
54
+ def search(keywords:, datatype: "json", file: nil)
55
+ check_datatype(datatype, file)
56
+ url = "function=SYMBOL_SEARCH&keywords=#{keywords}"
57
+ return download(url, file) if datatype == "csv"
58
+ output = OpenStruct.new
59
+ output.output = request(url)
60
+ bestMatches = output.output.dig("bestMatches") || {}
61
+ output.stocks = bestMatches.map do |bm|
62
+ val = OpenStruct.new
63
+ bm.each do |key, valz|
64
+ key_sym = recreate_metadata_key(key)
65
+ val[key_sym] = valz
66
+ end
67
+ val.stock = Alphavantage::Stock.new(symbol: bm["1. symbol"], key: self)
68
+ val
69
+ end
70
+ return output
56
71
  end
57
72
 
58
73
  def stock(symbol:, datatype: "json")
59
74
  Alphavantage::Stock.new symbol: symbol, key: self, datatype: datatype
60
75
  end
61
76
 
62
- def exchange(from:, to:)
63
- Alphavantage::Exchange.new from: from, to: to, key: self
77
+ def exchange(from:, to:, datatype: "json")
78
+ Alphavantage::Exchange.new from: from, to: to, key: self, datatype: datatype
64
79
  end
65
80
 
66
81
  def crypto(symbol:, market:, datatype: "json")
@@ -7,17 +7,13 @@ module Alphavantage
7
7
  check_argument([true, false], verbose, "verbose")
8
8
  @client = return_client(key, verbose)
9
9
  check_argument(["json", "csv"], datatype, "datatype")
10
- if datatype == "csv" && file.nil?
11
- raise Alphavantage::Error.new message: "No file specified where to save the CSV data"
12
- elsif datatype != "csv" && !file.nil?
13
- raise Alphavantage::Error.new message: "Hash error: No file necessary"
14
- end
10
+ check_datatype(datatype, file)
15
11
 
16
- @selected_time_series = which_series(type)
12
+ @selected_time_series = which_series(type, "DIGITAL_CURRENCY")
17
13
  url = "function=#{@selected_time_series}&symbol=#{symbol}&market=#{market}"
18
14
  return @client.download(url, file) if datatype == "csv"
19
- @hash = @client.request(url)
20
- metadata = @hash.dig("Meta Data") || {}
15
+ @output = @client.request(url)
16
+ metadata = @output.dig("Meta Data") || {}
21
17
  metadata.each do |key, val|
22
18
  key_sym = key.downcase.gsub(/[0-9.]/, "").lstrip.gsub(" ", "_").to_sym
23
19
  define_singleton_method(key_sym) do
@@ -29,10 +25,10 @@ module Alphavantage
29
25
  @market_cap_usd = [];
30
26
 
31
27
  begin
32
- time_series = @hash.find{|key, val| key.include?("Time Series")}[1]
28
+ time_series = @output.find{|key, val| key.include?("Time Series")}[1]
33
29
  rescue Exception => e
34
30
  raise Alphavantage::Error.new message: "No Time Series found: #{e.message}",
35
- data: @hash
31
+ data: @output
36
32
  end
37
33
 
38
34
  series = {}
@@ -55,13 +51,6 @@ module Alphavantage
55
51
  end
56
52
  end
57
53
 
58
- attr_reader :hash
59
-
60
- def which_series(type)
61
- check_argument(["intraday", "daily", "weekly", "monthly"], type, "type")
62
- series = "DIGITAL_CURRENCY_"
63
- series += type.upcase
64
- return series
65
- end
54
+ attr_reader :output
66
55
  end
67
56
  end
@@ -2,22 +2,34 @@ module Alphavantage
2
2
  class Exchange
3
3
  include HelperFunctions
4
4
 
5
- def initialize from:, to:, key:, verbose: false
5
+ def initialize from:, to:, key:, verbose: false,
6
+ datatype: "json"
6
7
  check_argument([true, false], verbose, "verbose")
7
8
  @client = return_client(key, verbose)
8
9
  @from = from
9
10
  @to = to
10
- @hash = @client.request("function=CURRENCY_EXCHANGE_RATE&from_currency=#{@from}&to_currency=#{@to}")
11
- hash = @hash["Realtime Currency Exchange Rate"]
12
- hash.each do |key, val|
13
- key_sym = recreate_metadata_key(key)
14
- define_singleton_method(key_sym) do
15
- return val
16
- end
17
- end
11
+ check_argument(["json", "csv"], datatype, "datatype")
12
+ @datatype = datatype
18
13
  end
19
14
 
20
- attr_reader :hash
15
+ attr_accessor :from, :to
16
+ attr_reader :datatype
21
17
 
18
+ def datatype=(datatype)
19
+ check_argument(["json", "csv"], datatype, "datatype")
20
+ @datatype = datatype
21
+ end
22
+
23
+ def now(datatype: @datatype, file: nil)
24
+ url = "function=CURRENCY_EXCHANGE_RATE&from_currency=#{@from}&to_currency=#{@to}"
25
+ check_datatype(datatype, file)
26
+ return @client.download(url, file) if datatype == "csv"
27
+ return open_struct(url, "Realtime Currency Exchange Rate")
28
+ end
29
+
30
+ def timeseries from: @from, to: @to, type: "intraday", file: nil, datatype: @datatype, interval: nil, outputsize: "compact"
31
+ Alphavantage::Exchange_Timeseries.new from: from, to: to, type: type, datatype: datatype, file: file, key: @client, interval: interval,
32
+ outputsize: outputsize
33
+ end
22
34
  end
23
35
  end
@@ -0,0 +1,63 @@
1
+ module Alphavantage
2
+ class Exchange_Timeseries
3
+ include HelperFunctions
4
+
5
+ def initialize type: "intraday", from:, to:, datatype: "json", file: nil,
6
+ key:, verbose: false, outputsize: "compact", interval: nil
7
+ check_argument([true, false], verbose, "verbose")
8
+ @client = return_client(key, verbose)
9
+ if type == "intraday"
10
+ interval ||= "1min"
11
+ check_argument(["1min", "5min", "15min", "30min", "60min"], interval, "interval")
12
+ interval = "&interval=#{interval}"
13
+ else
14
+ check_argument([nil], interval, "interval")
15
+ interval = ""
16
+ end
17
+ check_argument(["compact", "full"], outputsize, "outputsize")
18
+ check_argument(["json", "csv"], datatype, "datatype")
19
+ check_datatype(datatype, file)
20
+
21
+ @selected_time_series = which_series(type, "FX")
22
+ url = "function=#{@selected_time_series}&from_symbol=#{from}&to_symbol=#{to}#{interval}&outputsize=#{outputsize}"
23
+ return @client.download(url, file) if datatype == "csv"
24
+ @output = @client.request(url)
25
+ metadata = @output.dig("Meta Data") || {}
26
+ metadata.each do |key, val|
27
+ key_sym = key.downcase.gsub(/[0-9.]/, "").lstrip.gsub(" ", "_").to_sym
28
+ define_singleton_method(key_sym) do
29
+ return val
30
+ end
31
+ end
32
+ @open = []; @high = []; @low = []; @close = [];
33
+
34
+ begin
35
+ time_series = @output.find{|key, val| key.include?("Time Series")}[1]
36
+ rescue Exception => e
37
+ raise Alphavantage::Error.new message: "No Time Series found: #{e.message}",
38
+ data: @output
39
+ end
40
+
41
+ series = {}
42
+ convert_key = {}
43
+ time_series.values[0].keys.each do |key|
44
+ key_sym = recreate_metadata_key(key)
45
+ series[key_sym] = []
46
+ convert_key[key] = key_sym
47
+ end
48
+ time_series.each do |time, ts_hash|
49
+ ts_hash.each do |key, value|
50
+ series[convert_key[key]] << [time, value]
51
+ end
52
+ end
53
+ series.keys.each do |key_sym|
54
+ define_singleton_method(key_sym) do |*args|
55
+ args ||= []
56
+ return return_series(series[key_sym], args[0])
57
+ end
58
+ end
59
+ end
60
+
61
+ attr_reader :output
62
+ end
63
+ end