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 +4 -4
- data/AlphavantageRB.gemspec +1 -1
- data/README.md +111 -56
- data/lib/Client.rb +19 -4
- data/lib/Crypto_Timeseries.rb +7 -18
- data/lib/Exchange.rb +22 -10
- data/lib/Exchange_Timeseries.rb +63 -0
- data/lib/Indicator.rb +5 -5
- data/lib/Sector.rb +4 -4
- data/lib/Stock.rb +8 -2
- data/lib/Timeseries.rb +8 -19
- data/lib/alphavantagerb.rb +2 -1
- data/lib/helper_function.rb +27 -0
- data/spec/lib/1.0.0/client.rb +7 -2
- data/spec/lib/1.0.0/crypto_timeseries.rb +6 -6
- data/spec/lib/1.0.0/exchange.rb +8 -6
- data/spec/lib/1.0.0/exchange_timeseries.rb +73 -0
- data/spec/lib/1.0.0/indicator.rb +54 -54
- data/spec/lib/1.0.0/sector.rb +5 -5
- data/spec/lib/1.0.0/stock.rb +2 -2
- data/spec/lib/1.0.0/timeseries.rb +10 -10
- data/spec/test_all.rb +1 -1
- metadata +4 -4
- data/lib/Batch.rb +0 -52
- data/spec/lib/1.1.0/batch.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 743749f1cf99b12c71e4c5550074305f1c7b04a5
|
4
|
+
data.tar.gz: 5640ecf935bc22da9f2dc6577e138e1f3846a43c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f46bf5a084371e19873eb21cc8ece703da94469fa079b933db4cc79f6d8b194adf0d280bb75c29f196ab7ce92c111a88b887af2156aa58faefce6e4906735bc0
|
7
|
+
data.tar.gz: 7bd15d518d533a731935bfaeca3b30a986e087a35be39562b97e7cf0d0f357b4ff84a3fd29e0133c5f5e422095b9577fcec7be2ab9d8442b5d3b79637aa0540d
|
data/AlphavantageRB.gemspec
CHANGED
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.
|
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.
|
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.
|
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
|
740
|
+
You can retrieve the actual situation of the exchange from Alpha Vantage by doing.
|
744
741
|
``` ruby
|
745
|
-
exchange.
|
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
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
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
|
-
|
760
|
-
|
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.
|
835
|
+
sector.output
|
781
836
|
```
|
782
837
|
|
783
838
|
Specific information about the timeseries can be retrieved using the following methods:
|
data/lib/Client.rb
CHANGED
@@ -51,16 +51,31 @@ module Alphavantage
|
|
51
51
|
return "CSV saved in #{file}"
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
|
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")
|
data/lib/Crypto_Timeseries.rb
CHANGED
@@ -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
|
-
|
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
|
-
@
|
20
|
-
metadata = @
|
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 = @
|
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: @
|
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 :
|
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
|
data/lib/Exchange.rb
CHANGED
@@ -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
|
-
|
11
|
-
|
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
|
-
|
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
|