dss_reuters 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -2
- data/README.md +21 -11
- data/lib/data_scope_api.rb +212 -0
- data/lib/data_stream_api.rb +13 -45
- data/lib/dss_reuters/version.rb +1 -1
- data/lib/dss_reuters.rb +2 -192
- data/lib/dss_utilities.rb +1 -1
- data/vcr_cassettes/data_stream_isin.yml +67 -0
- data/vcr_cassettes/data_stream_isin_vs_ric.yml +96 -0
- data/vcr_cassettes/data_stream_login.yml +4 -4
- data/vcr_cassettes/data_stream_ric.yml +45 -11
- data/vcr_cassettes/extract_with_ric.yml +166 -0
- data/vcr_cassettes/extract_with_ric_time_series.yml +225 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8000cd292bec3062f54bea612c530b5bd71049916a699786fe1777bd195775f
|
4
|
+
data.tar.gz: 4619f13ecea949e00d2e93beedb650e50c28fd224044fe06a037227d240a88bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58fb05e16c8ef4dd40eaf8f7b294b7f6809b681933dc9fd2404a7fffe037d0e9b6b37920cee1e7e4d04fbcef3f3010d704ac7b0074b9bf968f6a9e1b99defe60
|
7
|
+
data.tar.gz: 4bcb3ea3fc5a1c9742d9a439d2d733d3430d3936db052ab4e58310c04f268e2ada5164c69ec00853121bbcac4525d193bcfc432f732f292c0c0fee718038c94a
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dss_reuters (0.
|
4
|
+
dss_reuters (0.8.0)
|
5
5
|
dotenv
|
6
6
|
httparty (~> 0.16)
|
7
7
|
pry-byebug
|
@@ -18,9 +18,13 @@ GEM
|
|
18
18
|
diff-lcs (1.3)
|
19
19
|
dotenv (2.5.0)
|
20
20
|
hashdiff (0.3.7)
|
21
|
-
httparty (0.16.
|
21
|
+
httparty (0.16.3)
|
22
|
+
mime-types (~> 3.0)
|
22
23
|
multi_xml (>= 0.5.2)
|
23
24
|
method_source (0.9.2)
|
25
|
+
mime-types (3.2.2)
|
26
|
+
mime-types-data (~> 3.2015)
|
27
|
+
mime-types-data (3.2018.0812)
|
24
28
|
multi_xml (0.6.0)
|
25
29
|
pry (0.12.2)
|
26
30
|
coderay (~> 1.1.0)
|
data/README.md
CHANGED
@@ -24,15 +24,19 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
You need to set your credentials as ENVs :
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
DATA_SCOPE_USERNAME
|
28
|
+
DATA_SCOPE_PASSWORD
|
29
|
+
DATA_STREAM_USERNAME
|
30
|
+
DATA_STREAM_PASSWORD
|
29
31
|
|
30
|
-
You can also set `
|
32
|
+
You can also set `DATA_SCOPE_LOG_LEVEL` or `DATA_STREAM_LOG_LEVEL` to set log level.
|
33
|
+
|
34
|
+
## Data Scope API
|
31
35
|
|
32
36
|
Usage flow goes like this :
|
33
37
|
|
34
38
|
require "dss_reuters"
|
35
|
-
api =
|
39
|
+
api = DataScope::Api.new
|
36
40
|
req = api.extract_with_isin "KE1000001402"
|
37
41
|
req.get_result
|
38
42
|
req.status # check if :completed. If :in_progress, check again
|
@@ -44,14 +48,11 @@ Default request fires a Composite extraction request. You can customize your req
|
|
44
48
|
req = api.extract_with_isin "KE1000001402", :technical_indicators, ["Net Change - Close Price - 1 Day"]
|
45
49
|
req = api.extract_with_isin "KE1000001402", :time_series, ["Close Price", "Trade Date"], {"StartDate" => "2018-01-01", "EndDate" => "2018-08-01"}
|
46
50
|
|
47
|
-
|
51
|
+
You can also use `extract_with_ric` to use Ric instrument identifiers.
|
48
52
|
|
49
|
-
|
53
|
+
req = api.extract_with_ric "SCOM.NR"
|
50
54
|
|
51
|
-
|
52
|
-
DATA_STREAM_PASSWORD
|
53
|
-
|
54
|
-
You can also set `DATA_STREAM_LOG_LEVEL` to set log level.
|
55
|
+
## Data Stream API
|
55
56
|
|
56
57
|
Usage flow goes like this :
|
57
58
|
|
@@ -59,8 +60,17 @@ Usage flow goes like this :
|
|
59
60
|
api = DataStream::Api.new
|
60
61
|
res = api.ric_stream ".TRXFLDAUTFIN", "2018-01-01", "2018-04-01"
|
61
62
|
|
62
|
-
|
63
|
+
You can also use ISIN identifiers as in Data Scope api.
|
64
|
+
|
65
|
+
res = api.isin_stream "SCOM.NR", "2018-01-01", "2018-04-01"
|
66
|
+
|
67
|
+
The request is synchronous, so results are available immediately.
|
68
|
+
|
69
|
+
### Getting ISIN for RIC or vs
|
70
|
+
|
71
|
+
You can use the DataScope api to get Isin code for a Ric code or vs
|
63
72
|
|
73
|
+
req = api.extract_with_isin "KE1000001402", :composite, ["RIC", "Close Price", "ISIN"]
|
64
74
|
|
65
75
|
## Contributing
|
66
76
|
|
@@ -0,0 +1,212 @@
|
|
1
|
+
module DataScope
|
2
|
+
class Config
|
3
|
+
BASE_URI = "https://hosted.datascopeapi.reuters.com"
|
4
|
+
LOG_LEVEL = ENV['DATA_SCOPE_LOG_LEVEL'] || 'INFO'
|
5
|
+
DATA_SCOPE_USERNAME = ENV['DATA_SCOPE_USERNAME'] || ENV['DSS_USERNAME']
|
6
|
+
DATA_SCOPE_PASSWORD = ENV['DATA_SCOPE_PASSWORD'] || ENV['DSS_PASSWORD']
|
7
|
+
end
|
8
|
+
|
9
|
+
class Session
|
10
|
+
include HTTParty
|
11
|
+
base_uri Config::BASE_URI
|
12
|
+
|
13
|
+
attr_reader :context, :token, :logger
|
14
|
+
|
15
|
+
def configured?
|
16
|
+
!Config::DATA_SCOPE_USERNAME.nil? and !Config::DATA_SCOPE_PASSWORD.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def not_configured_error
|
20
|
+
@logger.error "dss_reuters gem not configured. you will not be able to fetch data from data scope API"
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@logger = ::Logger.new(STDOUT)
|
25
|
+
@logger.level = Config::LOG_LEVEL
|
26
|
+
login_path = "/RestApi/v1/Authentication/RequestToken"
|
27
|
+
options = {
|
28
|
+
headers: {
|
29
|
+
"Prefer" => "respond-async",
|
30
|
+
"Content-Type" => "application/json; odata=minimalmetadata"
|
31
|
+
},
|
32
|
+
body: {
|
33
|
+
"Credentials" =>{
|
34
|
+
"Username" => Config::DATA_SCOPE_USERNAME,
|
35
|
+
"Password" => Config::DATA_SCOPE_PASSWORD
|
36
|
+
}
|
37
|
+
}.to_json
|
38
|
+
}
|
39
|
+
if configured?
|
40
|
+
resp = self.class.post login_path, options
|
41
|
+
@token = resp["value"]
|
42
|
+
@context = resp["@odata.context"]
|
43
|
+
@logger.debug resp
|
44
|
+
else
|
45
|
+
not_configured_error
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class User
|
51
|
+
include HTTParty
|
52
|
+
base_uri Config::BASE_URI
|
53
|
+
|
54
|
+
def initialize(session)
|
55
|
+
@session = session
|
56
|
+
path = "/RestApi/v1/Users/Users(#{Config::DSS_USERNAME})"
|
57
|
+
options = {
|
58
|
+
headers: {
|
59
|
+
"Prefer" => "respond-async",
|
60
|
+
"Authorization" => "Token #{@session.token}"
|
61
|
+
}
|
62
|
+
}
|
63
|
+
if session.configured?
|
64
|
+
resp = self.class.get path, options
|
65
|
+
@session.logger.debug resp
|
66
|
+
else
|
67
|
+
session.not_configured_error
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class OnDemandExtract
|
73
|
+
include HTTParty
|
74
|
+
base_uri Config::BASE_URI
|
75
|
+
attr_reader :result
|
76
|
+
attr_accessor :status, :location
|
77
|
+
|
78
|
+
def camelize(str)
|
79
|
+
str.to_s.split('_').collect(&:capitalize).join
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.init_with_location(session, location)
|
83
|
+
ins = self.new(session)
|
84
|
+
ins.status = :in_progress
|
85
|
+
ins.location = location
|
86
|
+
ins
|
87
|
+
end
|
88
|
+
|
89
|
+
def initialize(session, identifiers=nil, type=nil, fields=nil, condition=nil)
|
90
|
+
@session = session
|
91
|
+
@status = :init
|
92
|
+
path = "/RestApi/v1/Extractions/ExtractWithNotes"
|
93
|
+
|
94
|
+
if fields
|
95
|
+
options = {
|
96
|
+
headers: {
|
97
|
+
"Prefer" => "respond-async; wait=5",
|
98
|
+
"Content-Type" => "application/json; odata=minimalmetadata",
|
99
|
+
"Authorization" => "Token #{@session.token}"
|
100
|
+
},
|
101
|
+
body: {
|
102
|
+
"ExtractionRequest" => {
|
103
|
+
"@odata.type" => "#{camelize(type)}ExtractionRequest",
|
104
|
+
"ContentFieldNames" => fields,
|
105
|
+
"IdentifierList" => {
|
106
|
+
"@odata.type" => "InstrumentIdentifierList",
|
107
|
+
"InstrumentIdentifiers" => identifiers,
|
108
|
+
"ValidationOptions" => nil,
|
109
|
+
"UseUserPreferencesForValidationOptions" => false
|
110
|
+
},
|
111
|
+
"Condition" => condition
|
112
|
+
}
|
113
|
+
}.to_json
|
114
|
+
}
|
115
|
+
if session.configured?
|
116
|
+
resp = self.class.post path, options
|
117
|
+
if check_status(resp)
|
118
|
+
@location = resp["location"]
|
119
|
+
end
|
120
|
+
@session.logger.debug resp
|
121
|
+
else
|
122
|
+
session.not_configured_error
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def check_status(resp)
|
128
|
+
if resp["status"] == "InProgress"
|
129
|
+
@status = :in_progress
|
130
|
+
else
|
131
|
+
@status = :complete
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_result
|
136
|
+
if @status == :in_progress
|
137
|
+
options = {
|
138
|
+
headers: {
|
139
|
+
"Prefer" => "respond-async; wait=5",
|
140
|
+
"Authorization" => "Token #{@session.token}"
|
141
|
+
}
|
142
|
+
}
|
143
|
+
if @session.configured?
|
144
|
+
@result = self.class.get @location, options
|
145
|
+
check_status @result
|
146
|
+
@session.logger.debug @result
|
147
|
+
@status
|
148
|
+
else
|
149
|
+
@session.not_configured_error
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class Api
|
156
|
+
attr_reader :session
|
157
|
+
|
158
|
+
def initialize
|
159
|
+
@session = Session.new
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_user
|
163
|
+
@user = User.new(@session)
|
164
|
+
end
|
165
|
+
|
166
|
+
def extract_with_location(location)
|
167
|
+
OnDemandExtract.init_with_location(@session, location)
|
168
|
+
end
|
169
|
+
|
170
|
+
def extract_with_isin(isin_code, type=:composite, fields=nil, condition=nil)
|
171
|
+
fields ||= [
|
172
|
+
"Close Price",
|
173
|
+
"Contributor Code Description",
|
174
|
+
"Currency Code Description",
|
175
|
+
"Dividend Yield",
|
176
|
+
"Main Index",
|
177
|
+
"Market Capitalization",
|
178
|
+
"Market Capitalization - Local Currency",
|
179
|
+
"Percent Change - Close Price - 1 Day",
|
180
|
+
"Universal Close Price Date"
|
181
|
+
]
|
182
|
+
identifiers = [
|
183
|
+
{
|
184
|
+
"Identifier" => isin_code,
|
185
|
+
"IdentifierType" => "Isin"
|
186
|
+
}
|
187
|
+
]
|
188
|
+
OnDemandExtract.new(@session, identifiers, type, fields, condition)
|
189
|
+
end
|
190
|
+
|
191
|
+
def extract_with_ric(ric_code, type=:composite, fields=nil, condition=nil)
|
192
|
+
fields ||= [
|
193
|
+
"Close Price",
|
194
|
+
"Contributor Code Description",
|
195
|
+
"Currency Code Description",
|
196
|
+
"Dividend Yield",
|
197
|
+
"Main Index",
|
198
|
+
"Market Capitalization",
|
199
|
+
"Market Capitalization - Local Currency",
|
200
|
+
"Percent Change - Close Price - 1 Day",
|
201
|
+
"Universal Close Price Date"
|
202
|
+
]
|
203
|
+
identifiers = [
|
204
|
+
{
|
205
|
+
"Identifier" => ric_code,
|
206
|
+
"IdentifierType" => "Ric"
|
207
|
+
}
|
208
|
+
]
|
209
|
+
OnDemandExtract.new(@session, identifiers, type, fields, condition)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
data/lib/data_stream_api.rb
CHANGED
@@ -1,9 +1,3 @@
|
|
1
|
-
require "dotenv/load"
|
2
|
-
require "logger"
|
3
|
-
require "httparty"
|
4
|
-
require "dss_reuters/version"
|
5
|
-
require_relative "dss_utilities"
|
6
|
-
|
7
1
|
module DataStream
|
8
2
|
class Config
|
9
3
|
BASE_URI = "http://product.datastream.com"
|
@@ -53,7 +47,7 @@ module DataStream
|
|
53
47
|
base_uri Config::BASE_URI
|
54
48
|
attr_reader :result
|
55
49
|
|
56
|
-
def initialize(session,
|
50
|
+
def initialize(session, instrument, date)
|
57
51
|
@session = session
|
58
52
|
path = "/DswsClient/V1/DSService.svc/rest/GetData"
|
59
53
|
|
@@ -63,7 +57,6 @@ module DataStream
|
|
63
57
|
},
|
64
58
|
body: {
|
65
59
|
"DataRequest" => {
|
66
|
-
"DataTypes" => types,
|
67
60
|
"Date" => date,
|
68
61
|
"Instrument" => instrument,
|
69
62
|
"Tag" => nil
|
@@ -89,40 +82,7 @@ module DataStream
|
|
89
82
|
@session = Session.new
|
90
83
|
end
|
91
84
|
|
92
|
-
def stream(
|
93
|
-
# types = [
|
94
|
-
# {
|
95
|
-
# "Properties" => nil,
|
96
|
-
# "Value" => "PL"
|
97
|
-
# },
|
98
|
-
# {
|
99
|
-
# "Properties" => nil,
|
100
|
-
# "Value" => "PH"
|
101
|
-
# }
|
102
|
-
# ]
|
103
|
-
# date = {
|
104
|
-
# "End" => "-20D",
|
105
|
-
# "Frequency" => "D",
|
106
|
-
# "Kind" => 1,
|
107
|
-
# "Start" => "-30D"
|
108
|
-
# }
|
109
|
-
# instrument = {
|
110
|
-
# "Properties" => nil,
|
111
|
-
# "Value" => "VOD"
|
112
|
-
# }
|
113
|
-
|
114
|
-
|
115
|
-
Stream.new @session, types, date, instrument
|
116
|
-
end
|
117
|
-
|
118
|
-
def ric_stream(ric, date_start, date_end)
|
119
|
-
types = [
|
120
|
-
{
|
121
|
-
"Properties" => nil,
|
122
|
-
"Value" => ric
|
123
|
-
}
|
124
|
-
]
|
125
|
-
|
85
|
+
def stream(value, date_start, date_end)
|
126
86
|
date = {
|
127
87
|
"End" => date_end,
|
128
88
|
"Frequency" => "",
|
@@ -133,18 +93,26 @@ module DataStream
|
|
133
93
|
instrument = {
|
134
94
|
"Properties" => [
|
135
95
|
{
|
136
|
-
"Key" => "
|
96
|
+
"Key" => "IsSymbolSet",
|
137
97
|
"Value" => true
|
138
98
|
}
|
139
99
|
],
|
140
|
-
"Value" =>
|
100
|
+
"Value" => value
|
141
101
|
}
|
142
|
-
stream = Stream.new @session,
|
102
|
+
stream = Stream.new @session, instrument, date
|
143
103
|
stream.result["DataResponse"]["Dates"].each_with_index.map do |date, i|
|
144
104
|
{ date: parseDate(date),
|
145
105
|
value: stream.result["DataResponse"]["DataTypeValues"][0]["SymbolValues"][0]["Value"][i]
|
146
106
|
}
|
147
107
|
end
|
148
108
|
end
|
109
|
+
|
110
|
+
def ric_stream(ric, date_start, date_end)
|
111
|
+
stream "<#{ric}>", date_start, date_end
|
112
|
+
end
|
113
|
+
|
114
|
+
def isin_stream(isin, date_start, date_end)
|
115
|
+
stream isin, date_start, date_end
|
116
|
+
end
|
149
117
|
end
|
150
118
|
end
|
data/lib/dss_reuters/version.rb
CHANGED
data/lib/dss_reuters.rb
CHANGED
@@ -2,196 +2,6 @@ require "dotenv/load"
|
|
2
2
|
require "logger"
|
3
3
|
require "httparty"
|
4
4
|
require "dss_reuters/version"
|
5
|
+
require_relative "dss_utilities"
|
5
6
|
require_relative "data_stream_api"
|
6
|
-
|
7
|
-
module DssReuters
|
8
|
-
class Config
|
9
|
-
BASE_URI = "https://hosted.datascopeapi.reuters.com"
|
10
|
-
LOG_LEVEL = ENV['DSS_LOG_LEVEL'] || 'INFO'
|
11
|
-
DSS_USERNAME = ENV['DSS_USERNAME']
|
12
|
-
DSS_PASSWORD = ENV['DSS_PASSWORD']
|
13
|
-
end
|
14
|
-
|
15
|
-
class Session
|
16
|
-
include HTTParty
|
17
|
-
base_uri Config::BASE_URI
|
18
|
-
|
19
|
-
attr_reader :context, :token, :logger
|
20
|
-
|
21
|
-
def configured?
|
22
|
-
!Config::DSS_USERNAME.nil? and !Config::DSS_PASSWORD.nil?
|
23
|
-
end
|
24
|
-
|
25
|
-
def not_configured_error
|
26
|
-
@logger.error "dss_reuters gem not configured. you will not be able to fetch data from dss reuters API"
|
27
|
-
end
|
28
|
-
|
29
|
-
def initialize
|
30
|
-
@logger = ::Logger.new(STDOUT)
|
31
|
-
@logger.level = Config::LOG_LEVEL
|
32
|
-
login_path = "/RestApi/v1/Authentication/RequestToken"
|
33
|
-
options = {
|
34
|
-
headers: {
|
35
|
-
"Prefer" => "respond-async",
|
36
|
-
"Content-Type" => "application/json; odata=minimalmetadata"
|
37
|
-
},
|
38
|
-
body: {
|
39
|
-
"Credentials" =>{
|
40
|
-
"Username" => Config::DSS_USERNAME,
|
41
|
-
"Password" => Config::DSS_PASSWORD
|
42
|
-
}
|
43
|
-
}.to_json
|
44
|
-
}
|
45
|
-
if configured?
|
46
|
-
resp = self.class.post login_path, options
|
47
|
-
@token = resp["value"]
|
48
|
-
@context = resp["@odata.context"]
|
49
|
-
@logger.debug resp
|
50
|
-
else
|
51
|
-
not_configured_error
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
class User
|
57
|
-
include HTTParty
|
58
|
-
base_uri Config::BASE_URI
|
59
|
-
|
60
|
-
def initialize(session)
|
61
|
-
@session = session
|
62
|
-
path = "/RestApi/v1/Users/Users(#{Config::DSS_USERNAME})"
|
63
|
-
options = {
|
64
|
-
headers: {
|
65
|
-
"Prefer" => "respond-async",
|
66
|
-
"Authorization" => "Token #{@session.token}"
|
67
|
-
}
|
68
|
-
}
|
69
|
-
if session.configured?
|
70
|
-
resp = self.class.get path, options
|
71
|
-
@session.logger.debug resp
|
72
|
-
else
|
73
|
-
session.not_configured_error
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
class OnDemandExtract
|
79
|
-
include HTTParty
|
80
|
-
base_uri Config::BASE_URI
|
81
|
-
attr_reader :result
|
82
|
-
attr_accessor :status, :location
|
83
|
-
|
84
|
-
def camelize(str)
|
85
|
-
str.to_s.split('_').collect(&:capitalize).join
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.init_with_location(session, location)
|
89
|
-
ins = self.new(session)
|
90
|
-
ins.status = :in_progress
|
91
|
-
ins.location = location
|
92
|
-
ins
|
93
|
-
end
|
94
|
-
|
95
|
-
def initialize(session, identifiers=nil, type=nil, fields=nil, condition=nil)
|
96
|
-
@session = session
|
97
|
-
@status = :init
|
98
|
-
path = "/RestApi/v1/Extractions/ExtractWithNotes"
|
99
|
-
|
100
|
-
if fields
|
101
|
-
options = {
|
102
|
-
headers: {
|
103
|
-
"Prefer" => "respond-async; wait=5",
|
104
|
-
"Content-Type" => "application/json; odata=minimalmetadata",
|
105
|
-
"Authorization" => "Token #{@session.token}"
|
106
|
-
},
|
107
|
-
body: {
|
108
|
-
"ExtractionRequest" => {
|
109
|
-
"@odata.type" => "#{camelize(type)}ExtractionRequest",
|
110
|
-
"ContentFieldNames" => fields,
|
111
|
-
"IdentifierList" => {
|
112
|
-
"@odata.type" => "InstrumentIdentifierList",
|
113
|
-
"InstrumentIdentifiers" => identifiers,
|
114
|
-
"ValidationOptions" => nil,
|
115
|
-
"UseUserPreferencesForValidationOptions" => false
|
116
|
-
},
|
117
|
-
"Condition" => condition
|
118
|
-
}
|
119
|
-
}.to_json
|
120
|
-
}
|
121
|
-
if session.configured?
|
122
|
-
resp = self.class.post path, options
|
123
|
-
if check_status(resp)
|
124
|
-
@location = resp["location"]
|
125
|
-
end
|
126
|
-
@session.logger.debug resp
|
127
|
-
else
|
128
|
-
session.not_configured_error
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def check_status(resp)
|
134
|
-
if resp["status"] == "InProgress"
|
135
|
-
@status = :in_progress
|
136
|
-
else
|
137
|
-
@status = :complete
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def get_result
|
142
|
-
if @status == :in_progress
|
143
|
-
options = {
|
144
|
-
headers: {
|
145
|
-
"Prefer" => "respond-async; wait=5",
|
146
|
-
"Authorization" => "Token #{@session.token}"
|
147
|
-
}
|
148
|
-
}
|
149
|
-
if @session.configured?
|
150
|
-
@result = self.class.get @location, options
|
151
|
-
check_status @result
|
152
|
-
@session.logger.debug @result
|
153
|
-
@status
|
154
|
-
else
|
155
|
-
@session.not_configured_error
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
class Api
|
162
|
-
attr_reader :session
|
163
|
-
|
164
|
-
def initialize
|
165
|
-
@session = Session.new
|
166
|
-
end
|
167
|
-
|
168
|
-
def get_user
|
169
|
-
@user = User.new(@session)
|
170
|
-
end
|
171
|
-
|
172
|
-
def extract_with_location(location)
|
173
|
-
OnDemandExtract.init_with_location(@session, location)
|
174
|
-
end
|
175
|
-
|
176
|
-
def extract_with_isin(isin_code, type=:composite, fields=nil, condition=nil)
|
177
|
-
fields ||= [
|
178
|
-
"Close Price",
|
179
|
-
"Contributor Code Description",
|
180
|
-
"Currency Code Description",
|
181
|
-
"Dividend Yield",
|
182
|
-
"Main Index",
|
183
|
-
"Market Capitalization",
|
184
|
-
"Market Capitalization - Local Currency",
|
185
|
-
"Percent Change - Close Price - 1 Day",
|
186
|
-
"Universal Close Price Date"
|
187
|
-
]
|
188
|
-
identifiers = [
|
189
|
-
{
|
190
|
-
"Identifier" => isin_code,
|
191
|
-
"IdentifierType" => "Isin"
|
192
|
-
}
|
193
|
-
]
|
194
|
-
OnDemandExtract.new(@session, identifiers, type, fields, condition)
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
7
|
+
require_relative "data_scope_api"
|
data/lib/dss_utilities.rb
CHANGED
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://product.datastream.com/DSWSClient/V1/DSService.svc/rest/Token?Password=test&UserName=test
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept-Encoding:
|
11
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
12
|
+
Accept:
|
13
|
+
- "*/*"
|
14
|
+
User-Agent:
|
15
|
+
- Ruby
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Cache-Control:
|
22
|
+
- no-cache
|
23
|
+
Content-Length:
|
24
|
+
- '355'
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=utf-8
|
27
|
+
Server:
|
28
|
+
- Microsoft-IIS/8.0
|
29
|
+
X-Powered-By:
|
30
|
+
- ASP.NET
|
31
|
+
Date:
|
32
|
+
- Wed, 05 Dec 2018 12:55:59 GMT
|
33
|
+
body:
|
34
|
+
encoding: UTF-8
|
35
|
+
string: '{"Properties":null,"TokenExpiry":"\/Date(1544100898530)\/","TokenValue":"sample_token"}'
|
36
|
+
http_version:
|
37
|
+
recorded_at: Wed, 05 Dec 2018 12:56:00 GMT
|
38
|
+
- request:
|
39
|
+
method: post
|
40
|
+
uri: http://product.datastream.com/DswsClient/V1/DSService.svc/rest/GetData
|
41
|
+
body:
|
42
|
+
encoding: UTF-8
|
43
|
+
string: '{"DataRequest":{"Date":{"End":"2018-04-01","Frequency":"","Kind":1,"Start":"2018-01-01"},"Instrument":{"Properties":[{"Key":"IsSymbolSet","Value":true}],"Value":"KE1000001402"},"Tag":null},"Properties":null,"TokenValue":"sample_token"}'
|
44
|
+
headers:
|
45
|
+
Content-Type:
|
46
|
+
- application/json
|
47
|
+
response:
|
48
|
+
status:
|
49
|
+
code: 200
|
50
|
+
message: OK
|
51
|
+
headers:
|
52
|
+
Content-Length:
|
53
|
+
- '2622'
|
54
|
+
Content-Type:
|
55
|
+
- application/json; charset=utf-8
|
56
|
+
Server:
|
57
|
+
- Microsoft-IIS/8.0
|
58
|
+
X-Powered-By:
|
59
|
+
- ASP.NET
|
60
|
+
Date:
|
61
|
+
- Wed, 05 Dec 2018 12:56:00 GMT
|
62
|
+
body:
|
63
|
+
encoding: UTF-8
|
64
|
+
string: '{"DataResponse":{"AdditionalResponses":[{"Key":"Frequency","Value":"D"}],"DataTypeNames":null,"DataTypeValues":[{"DataType":"","SymbolValues":[{"Currency":"KS","Symbol":"KE1000001402","Type":10,"Value":[26.75,26.75,26.75,27,28,28,28,27.75,27.75,28.25,28.75,29,29,29.25,29.5,29.25,29.5,29.5,29.75,30,29.75,29.75,29.5,29.75,29.75,29.75,29.5,28.5,29.25,29,28.25,28.5,28.75,28.75,29.25,29.25,29.75,29.75,29.5,29.5,29.5,29.5,29.75,29.5,29.25,29.25,29.25,29.5,29.5,29.25,29.25,29.75,29.75,29.5,29.5,30,30.75,31.25,31.75,31.75,31.5,31.25,30.75,31,31]}]}],"Dates":["\/Date(1514764800000+0000)\/","\/Date(1514851200000+0000)\/","\/Date(1514937600000+0000)\/","\/Date(1515024000000+0000)\/","\/Date(1515110400000+0000)\/","\/Date(1515369600000+0000)\/","\/Date(1515456000000+0000)\/","\/Date(1515542400000+0000)\/","\/Date(1515628800000+0000)\/","\/Date(1515715200000+0000)\/","\/Date(1515974400000+0000)\/","\/Date(1516060800000+0000)\/","\/Date(1516147200000+0000)\/","\/Date(1516233600000+0000)\/","\/Date(1516320000000+0000)\/","\/Date(1516579200000+0000)\/","\/Date(1516665600000+0000)\/","\/Date(1516752000000+0000)\/","\/Date(1516838400000+0000)\/","\/Date(1516924800000+0000)\/","\/Date(1517184000000+0000)\/","\/Date(1517270400000+0000)\/","\/Date(1517356800000+0000)\/","\/Date(1517443200000+0000)\/","\/Date(1517529600000+0000)\/","\/Date(1517788800000+0000)\/","\/Date(1517875200000+0000)\/","\/Date(1517961600000+0000)\/","\/Date(1518048000000+0000)\/","\/Date(1518134400000+0000)\/","\/Date(1518393600000+0000)\/","\/Date(1518480000000+0000)\/","\/Date(1518566400000+0000)\/","\/Date(1518652800000+0000)\/","\/Date(1518739200000+0000)\/","\/Date(1518998400000+0000)\/","\/Date(1519084800000+0000)\/","\/Date(1519171200000+0000)\/","\/Date(1519257600000+0000)\/","\/Date(1519344000000+0000)\/","\/Date(1519603200000+0000)\/","\/Date(1519689600000+0000)\/","\/Date(1519776000000+0000)\/","\/Date(1519862400000+0000)\/","\/Date(1519948800000+0000)\/","\/Date(1520208000000+0000)\/","\/Date(1520294400000+0000)\/","\/Date(1520380800000+0000)\/","\/Date(1520467200000+0000)\/","\/Date(1520553600000+0000)\/","\/Date(1520812800000+0000)\/","\/Date(1520899200000+0000)\/","\/Date(1520985600000+0000)\/","\/Date(1521072000000+0000)\/","\/Date(1521158400000+0000)\/","\/Date(1521417600000+0000)\/","\/Date(1521504000000+0000)\/","\/Date(1521590400000+0000)\/","\/Date(1521676800000+0000)\/","\/Date(1521763200000+0000)\/","\/Date(1522022400000+0000)\/","\/Date(1522108800000+0000)\/","\/Date(1522195200000+0000)\/","\/Date(1522281600000+0000)\/","\/Date(1522368000000+0000)\/"],"SymbolNames":null,"Tag":null},"Properties":null}'
|
65
|
+
http_version:
|
66
|
+
recorded_at: Wed, 05 Dec 2018 12:56:00 GMT
|
67
|
+
recorded_with: VCR 4.0.0
|