dss_reuters 0.7.0 → 0.8.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/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
|