coin_market_pro 0.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.
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'coin_market_pro/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'coin_market_pro'
9
+ spec.version = CoinMarketPro::VERSION
10
+ spec.authors = ['snogrammer']
11
+
12
+ spec.summary = 'CoinMarketCap Pro v1 Api Ruby wrapper'
13
+ spec.homepage = 'https://gitlab.com/snogrammer/coin_market_pro'
14
+ spec.license = 'MIT'
15
+
16
+ # Specify which files should be added to the gem when it is released.
17
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ end
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_dependency 'activesupport', '~> 5.1'
26
+ spec.add_dependency 'multi_json', '~> 1.13'
27
+ spec.add_dependency 'rest-client', '~> 2.0'
28
+
29
+ spec.add_development_dependency 'bundler', '~> 1.16'
30
+ spec.add_development_dependency 'pry', '~> 0.11'
31
+ spec.add_development_dependency 'rake', '~> 12.3'
32
+ spec.add_development_dependency 'rspec', '~> 3.8'
33
+ spec.add_development_dependency 'simplecov', '~> 0.16'
34
+ spec.add_development_dependency 'webmock', '~> 3.4'
35
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext/object'
5
+ require 'rest_client'
6
+
7
+ require_relative './result'
8
+ Dir['./lib/coin_market_pro/endpoint/**/*.rb'].each { |f| require f }
9
+
10
+ module CoinMarketPro
11
+ module Client
12
+ class Error < RuntimeError
13
+ def initialize(message)
14
+ super(message)
15
+ end
16
+ end
17
+
18
+ class Base
19
+ attr_reader :host, :api_key, :logger, :cryptocurrency, :exchange, :global_metrics, :tools
20
+
21
+ API_DOMAIN = 'https://pro-api.coinmarketcap.com'
22
+ API_VERSION = 'v1'
23
+ API_URL = "#{API_DOMAIN}/#{API_VERSION}"
24
+ DEFAULT_TIMEOUT = 10
25
+
26
+ def initialize(api_key: ENV.fetch('COIN_MARKET_PRO_API_KEY'), logger: Logger.new(STDOUT), timeout: DEFAULT_TIMEOUT)
27
+ @host = API_URL
28
+ @api_key = api_key
29
+ @logger = logger
30
+ @timeout = timeout
31
+
32
+ # services
33
+ @cryptocurrency = Endpoint::Cryptocurrency.new(client: self, logger: @logger)
34
+ @exchange = Endpoint::Exchange.new(client: self, logger: @logger)
35
+ @global_metrics = Endpoint::GlobalMetrics.new(client: self, logger: @logger)
36
+ @tools = Endpoint::Tools.new(client: self, logger: @logger)
37
+ end
38
+
39
+ # GET request
40
+ #
41
+ # @param uri [String]
42
+ # @param options [Hash]
43
+ # @param headers [Hash]
44
+ # @return [Result]
45
+ def get(uri, options: {}, headers: {})
46
+ request do
47
+ url = host + uri
48
+ options ||= {}
49
+ headers ||= {}
50
+
51
+ query_params = CGI.unescape(options.to_query)
52
+ url += '?' + query_params unless query_params.blank?
53
+
54
+ response = RestClient::Request.execute(method: :get,
55
+ url: url,
56
+ headers: default_headers.merge(headers),
57
+ open_timeout: open_timeout,
58
+ timeout: timeout)
59
+
60
+ logger.debug(message: 'GET Request', url: url, options: options, status: response.code)
61
+ success?(response.code) ? Result.success(response) : Result.failed(response)
62
+ end
63
+ end
64
+
65
+ # @yield [Result]
66
+ def request
67
+ result = yield
68
+
69
+ if result.success?
70
+ logger.debug(status: result.code, body: result.body)
71
+ else
72
+ logger.warn(error: 'Request Error', status: result.code, body: result.body)
73
+ end
74
+
75
+ result
76
+ rescue ::RestClient::GatewayTimeout
77
+ raise Error.new('Gateway timeout')
78
+ rescue ::RestClient::RequestTimeout
79
+ raise Error.new('Request timeout')
80
+ rescue ::RestClient::Exception => e
81
+ handle_error(e)
82
+ end
83
+
84
+ # Handle errors
85
+ # @param error [Error]
86
+ # @return [Result]
87
+ def handle_error(error)
88
+ response = error.response
89
+ message = error.message
90
+ logger.error(error: 'Request Error', code: response.code, message: message)
91
+ Result.failed(response)
92
+ end
93
+
94
+ # @return [Hash]
95
+ def default_headers
96
+ {
97
+ 'Content-Type' => 'application/json',
98
+ 'Accept' => 'application/json',
99
+ 'User-Agent' => "coin_market_pro/#{CoinMarketPro::VERSION}",
100
+ 'Accept-Encoding' => 'deflate, gzip',
101
+ 'X-CMC_PRO_API_KEY' => api_key
102
+ }
103
+ end
104
+
105
+ # @return [Integer]
106
+ def timeout
107
+ @timeout || DEFAULT_TIMEOUT
108
+ end
109
+
110
+ # @return [Integer]
111
+ def open_timeout
112
+ @open_timeout || DEFAULT_TIMEOUT
113
+ end
114
+
115
+ private
116
+
117
+ # @return [Boolean]
118
+ def success?(status_code = 0)
119
+ return true if status_code.in?(200..299)
120
+
121
+ false
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinMarketPro
4
+ module Client
5
+ ##
6
+ # Status object to capture result from an HTTP request
7
+ #
8
+ # Gives callers context of the result and allows them to
9
+ # implement successful strategies to handle success/failure
10
+ #
11
+ class Result
12
+ def self.success(response)
13
+ new(:success, response)
14
+ end
15
+
16
+ def self.failed(response)
17
+ new(:failed, response)
18
+ end
19
+
20
+ attr_reader :status, :code, :headers, :raw
21
+ attr_accessor :body
22
+
23
+ def initialize(status, response)
24
+ @raw = raw_parse(response.body)
25
+ @status = @raw[:status]&.merge(result: status) || { result: status }
26
+ @code = response.code
27
+ @body = @raw[:data]
28
+ @headers = response.headers # e.g. "Content-Type" will become :content_type.
29
+ end
30
+
31
+ def success?
32
+ @status[:result] == :success
33
+ end
34
+
35
+ def failure?
36
+ @status[:result] == :failed
37
+ end
38
+
39
+ def to_h
40
+ { status: @status, code: @code, headers: @headers, body: @body }
41
+ end
42
+
43
+ alias to_hash to_h
44
+
45
+ def method_missing(method, *args, &blk)
46
+ to_h.send(method, *args, &blk)
47
+ end
48
+
49
+ def respond_to_missing?(method, include_private = false)
50
+ to_h.respond_to?(method) || super
51
+ end
52
+
53
+ # @param body [JSON] Raw JSON body
54
+ def raw_parse(body)
55
+ JSON.parse(body, symbolize_names: true)
56
+ rescue StandardError => e
57
+ raise ResponseBodyParseError.new(error: 'JSON parse error', message: e.message, body: body)
58
+ end
59
+
60
+ class ResponseBodyParseError < StandardError; end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinMarketPro
4
+ module Endpoint
5
+ class Base
6
+ attr_reader :client, :logger
7
+
8
+ def initialize(client:, logger:)
9
+ @client = client
10
+ @logger = logger
11
+ end
12
+
13
+ protected
14
+
15
+ # @param args [Hash]
16
+ # @return [Boolean]
17
+ # @raise [ArgumentError]
18
+ def valid_params?(args)
19
+ raise ArgumentError.new('At least one "id" or "symbol" is required.') if args[:id].blank? && args[:symbol].blank?
20
+
21
+ true
22
+ end
23
+
24
+ private
25
+
26
+ # Convert/Standardize base params
27
+ # @param params [Hash]
28
+ # @return [Hash]
29
+ def convert_params(**params)
30
+ return {} if params.blank?
31
+
32
+ params.each { |k, v| params[k] = standardize_value(v) }
33
+ params
34
+ end
35
+
36
+ # Standardize request params
37
+ def standardize_value(param)
38
+ if param.is_a?(Array)
39
+ param.join(',')
40
+ elsif param.is_a?(String)
41
+ param.strip
42
+ else
43
+ param
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,235 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinMarketPro
4
+ module Endpoint
5
+ # @see https://pro.coinmarketcap.com/api/v1#tag/cryptocurrency
6
+ class Cryptocurrency < Base
7
+ ENDPOINT = '/cryptocurrency'
8
+
9
+ # Returns all static metadata for one or more cryptocurrencies
10
+ # including name, symbol, logo, and its various registered URLs.
11
+ #
12
+ # @param [Hash] args
13
+ # @option args [Array<Integer>] :id One or more CoinMarketCap cryptocurrency IDs.
14
+ # @option args [Array<String>] :symbol Alternatively pass one or more cryptocurrency symbols.
15
+ # @return [CoinMarketPro::Result]
16
+ # @note At least one "id" or "symbol" is required.
17
+ #
18
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyInfo
19
+ ##
20
+ def info(**args)
21
+ valid_params?(args)
22
+ params = convert_params(args)
23
+ client.get("#{ENDPOINT}/info", options: params.compact).tap do |resp|
24
+ resp.body = resp.body.map { |_k, data| data }
25
+ end
26
+ end
27
+
28
+ alias metadata info
29
+
30
+ # @note This endpoint is not yet available. It is slated for release in early Q4 2018.
31
+ # Returns paginated list of all cryptocurrencies with market data for a given historical time.
32
+ #
33
+ # @param [Hash] args
34
+ # @option args [String] :timestamp Timestamp (Unix or ISO 8601) to return historical cryptocurrency listings for.
35
+ # @option args [Integer] :start Optionally offset the start (1-based index) of the paginated list of items to return.
36
+ # @option args [Integer] :limit Optionally specify the number of results to return. Use this parameter
37
+ # and the "start" parameter to determine your own pagination size.
38
+ # @option args [String] :convert Optionally calculate market quotes in up to 32 currencies at once by passing a
39
+ # comma-separated list of cryptocurrency or fiat currency symbols. Each additional convert option beyond the
40
+ # first requires an additional call credit. A list of supported fiat options can be found here. Each conversion
41
+ # is returned in its own "quote" object.
42
+ # @option args [String] :sort What field to sort the list of cryptocurrencies by.
43
+ # @option args [String] :sort_dir The direction in which to order cryptocurrencies against the specified sort.
44
+ # @option args [String] :cryptocurrency_type The type of cryptocurrency to include.
45
+ # @return [CoinMarketPro::Result]
46
+ #
47
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyListingsHistorical
48
+ ##
49
+ def listings_historical(**args)
50
+ params = convert_params(args)
51
+ client.get("#{ENDPOINT}/listings/historical", options: params.compact)
52
+ end
53
+
54
+ # Get a paginated list of all cryptocurrencies with latest market data.
55
+ #
56
+ # @option timestamp [String] Timestamp (Unix or ISO 8601) to return historical cryptocurrency listings for.
57
+ # @option start [Integer] Optionally offset the start (1-based index) of the paginated list of items to return.
58
+ # @option limit [Integer] Optionally specify the number of results to return. Use this parameter
59
+ # and the "start" parameter to determine your own pagination size.
60
+ # @option convert [String] Optionally calculate market quotes in up to 32 currencies at once by passing a
61
+ # comma-separated list of cryptocurrency or fiat currency symbols. Each additional convert option beyond the
62
+ # first requires an additional call credit. A list of supported fiat options can be found here. Each conversion
63
+ # is returned in its own "quote" object.
64
+ # @option sort [String] What field to sort the list of cryptocurrencies by.
65
+ # @option sort_dir [String] The direction in which to order cryptocurrencies against the specified sort.
66
+ # @option cryptocurrency_type [String] The type of cryptocurrency to include.
67
+ # @return [CoinMarketPro::Result]
68
+ #
69
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyListingsLatest
70
+ ##
71
+ def listings(**args)
72
+ params = convert_params(args)
73
+ client.get("#{ENDPOINT}/listings/latest", options: params.compact)
74
+ end
75
+
76
+ alias listings_latest listings
77
+
78
+ # Returns a paginated list of all cryptocurrencies by CoinMarketCap ID.
79
+ #
80
+ # @param [Hash] args
81
+ # @option args [String] :listing_status Only active coins are returned by default.
82
+ # Pass 'inactive' to get a list of coins that are no longer active.
83
+ # @option args [Integer] :start Optionally offset the start (1-based index) of the paginated list of items to return.
84
+ # @option args [Integer] :limit Optionally specify the number of results to return.
85
+ # Use this parameter and the "start" parameter to determine your own pagination size.
86
+ # @option args [Array] :symbol Optionally pass a list of cryptocurrency symbols to return
87
+ # CoinMarketCap IDs for. If this option is passed, other options will be ignored.
88
+ # @return [CoinMarketPro::Result]
89
+ #
90
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyMap
91
+ ##
92
+ def map(**args)
93
+ params = convert_params(args)
94
+ client.get("#{ENDPOINT}/map", options: params.compact)
95
+ end
96
+
97
+ # Lists all market pairs for the specified cryptocurrency with associated stats.
98
+ #
99
+ # @option id [String] A cryptocurrency by CoinMarketCap ID. Example: "1"
100
+ # @option symbol [String] Alternatively pass a cryptocurrency by symbol. Example: "BTC".
101
+ # A single cryptocurrency "id" or "symbol" is required.
102
+ # @option start [Integer] Optionally offset the start (1-based index) of the paginated list of items to return.
103
+ # @option limit [Integer] Optionally specify the number of results to return.
104
+ # Use this parameter and the "start" parameter to determine your own pagination size.
105
+ # @option convert [String] Optionally calculate market quotes in up to 32 currencies at once by passing a
106
+ # comma-separated list of cryptocurrency or fiat currency symbols.
107
+ # Each additional convert option beyond the first requires an additional call credit.
108
+ # A list of supported fiat options can be found here. Each conversion is returned in its own "quote" object.
109
+ # @return [CoinMarketPro::Result]
110
+ #
111
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyMarketpairsLatest
112
+ ##
113
+ def market_pairs(**args)
114
+ valid_params?(args)
115
+ params = convert_params(args)
116
+ client.get("#{ENDPOINT}/market-pairs/latest", options: params.compact).tap do |resp|
117
+ resp.body = [resp.body]
118
+ end
119
+ end
120
+
121
+ # Return an interval of historic OHLCV (Open, High, Low, Close, Volume) market quotes for a cryptocurrency.
122
+ #
123
+ # @option id [String] A cryptocurrency by CoinMarketCap ID. Example: "1"
124
+ # @option symbol [String] Alternatively pass a cryptocurrency by symbol. Example: "BTC".
125
+ # A single cryptocurrency "id" or "symbol" is required.
126
+ # @option time_period [String] Time period to return OHLCV data for. The default is "daily".
127
+ # Additional options will be available in the future. See the main endpoint description for details.
128
+ # @option time_start [String] Timestamp (Unix or ISO 8601) to start returning OHLCV time periods for.
129
+ # Only the date portion of the timestamp is used for daily OHLCV so it's recommended to send an ISO date
130
+ # format like "2018-09-19" without time.
131
+ # @option time_end [String] Timestamp (Unix or ISO 8601) to stop returning OHLCV time periods for (inclusive).
132
+ # Optional, if not passed we'll default to the current time. Only the date portion of the timestamp is used for
133
+ # daily OHLCV so it's recommended to send an ISO date format like "2018-09-19" without time.
134
+ # @option count [Number] Optionally limit the number of time periods to return results for.
135
+ # The default is 10 items. The current query limit is 10000 items.
136
+ # @option interval [String] Optionally adjust the interval that "time_period" is sampled.
137
+ # See main endpoint description for available options.
138
+ # Valid Values: "daily" "weekly" "monthly" "yearly" "1d" "2d" "3d" "7d" "14d" "15d" "30d" "60d" "90d" "365d"
139
+ # @option convert [String] Optionally calculate market quotes in up to 32 currencies at once by passing a
140
+ # comma-separated list of cryptocurrency or fiat currency symbols.
141
+ # Each additional convert option beyond the first requires an additional call credit.
142
+ # A list of supported fiat options can be found here. Each conversion is returned in its own "quote" object.
143
+ # @return [CoinMarketPro::Result]
144
+ #
145
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyOhlcvHistorical
146
+ ##
147
+ def ohlcv_historical(**args)
148
+ valid_params?(args)
149
+ params = convert_params(args)
150
+ client.get("#{ENDPOINT}/ohlcv/historical", options: params.compact).tap do |resp|
151
+ resp.body = [resp.body]
152
+ end
153
+ end
154
+
155
+ # Return the latest OHLCV (Open, High, Low, Close, Volume) market values for one or
156
+ # more cryptocurrencies in the currently UTC day.
157
+ #
158
+ # @option id [String] A cryptocurrency by CoinMarketCap ID. Example: "1"
159
+ # @option symbol [String] Alternatively pass a cryptocurrency by symbol. Example: "BTC".
160
+ # A single cryptocurrency "id" or "symbol" is required.
161
+ # @option convert [String] Optionally calculate market quotes in up to 32 currencies at once by passing a
162
+ # comma-separated list of cryptocurrency or fiat currency symbols.
163
+ # Each additional convert option beyond the first requires an additional call credit.
164
+ # A list of supported fiat options can be found here. Each conversion is returned in its own "quote" object.
165
+ # @return [CoinMarketPro::Result]
166
+ #
167
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyOhlcvLatest
168
+ def ohlcv(**args)
169
+ valid_params?(args)
170
+ params = convert_params(args)
171
+ client.get("#{ENDPOINT}/ohlcv/latest", options: params.compact).tap do |resp|
172
+ resp.body = resp.body.map { |_key, data| data }
173
+ end
174
+ end
175
+
176
+ alias ohlcv_latest ohlcv
177
+
178
+ # Returns an interval of historic market quotes for any cryptocurrency based on time and interval parameters.
179
+ #
180
+ # @option id [String] A cryptocurrency by CoinMarketCap ID. Example: "1"
181
+ # @option symbol [String] Alternatively pass a cryptocurrency by symbol. Example: "BTC".
182
+ # A single cryptocurrency "id" or "symbol" is required.
183
+ # @option time_period [String] Time period to return OHLCV data for. The default is "daily".
184
+ # Additional options will be available in the future. See the main endpoint description for details.
185
+ # @option time_start [String] Timestamp (Unix or ISO 8601) to start returning OHLCV time periods for.
186
+ # Only the date portion of the timestamp is used for daily OHLCV so it's recommended to send an ISO date
187
+ # format like "2018-09-19" without time.
188
+ # @option time_end [String] Timestamp (Unix or ISO 8601) to stop returning OHLCV time periods for (inclusive).
189
+ # Optional, if not passed we'll default to the current time. Only the date portion of the timestamp is used for
190
+ # daily OHLCV so it's recommended to send an ISO date format like "2018-09-19" without time.
191
+ # @option count [Number] Optionally limit the number of time periods to return results for.
192
+ # The default is 10 items. The current query limit is 10000 items.
193
+ # @option interval [String] Optionally adjust the interval that "time_period" is sampled.
194
+ # See main endpoint description for available options.
195
+ # Valid Values: "daily" "weekly" "monthly" "yearly" "1d" "2d" "3d" "7d" "14d" "15d" "30d" "60d" "90d" "365d"
196
+ # @option convert [String] Optionally calculate market quotes in up to 32 currencies at once by passing a
197
+ # comma-separated list of cryptocurrency or fiat currency symbols.
198
+ # Each additional convert option beyond the first requires an additional call credit.
199
+ # A list of supported fiat options can be found here. Each conversion is returned in its own "quote" object.
200
+ # @return [CoinMarketPro::Result]
201
+ #
202
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyQuotesHistorical
203
+ def quotes_historical(**args)
204
+ valid_params?(args)
205
+ params = convert_params(args)
206
+ client.get("#{ENDPOINT}/quotes/historical", options: params.compact).tap do |resp|
207
+ resp.body = [resp.body]
208
+ end
209
+ end
210
+
211
+ alias market_quotes_historical quotes_historical
212
+
213
+ # @option id [Array<String>] One or more comma-separated cryptocurrency CoinMarketCap IDs. Example: 1,2
214
+ # @option symbol [String] Alternatively pass a cryptocurrency by symbol. Example: "BTC,ETH".
215
+ # A single cryptocurrency "id" or "symbol" is required.
216
+ # @option convert [String] Optionally calculate market quotes in up to 32 currencies at once by passing a
217
+ # comma-separated list of cryptocurrency or fiat currency symbols.
218
+ # Each additional convert option beyond the first requires an additional call credit.
219
+ # A list of supported fiat options can be found here. Each conversion is returned in its own "quote" object.
220
+ # @return [CoinMarketPro::Result]
221
+ #
222
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1CryptocurrencyQuotesLatest
223
+ def quotes(**args)
224
+ valid_params?(args)
225
+ params = convert_params(args)
226
+ client.get("#{ENDPOINT}/quotes/latest", options: params.compact).tap do |resp|
227
+ resp.body = resp.body.map { |_key, data| data }
228
+ end
229
+ end
230
+
231
+ alias market_quotes quotes
232
+ alias quotes_latest quotes
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CoinMarketPro
4
+ module Endpoint
5
+ # @see https://pro.coinmarketcap.com/api/v1#tag/exchange
6
+ class Exchange < Base
7
+ ENDPOINT = '/exchange'
8
+
9
+ # Returns all static metadata for one or more exchanges including logo and homepage URL.
10
+ #
11
+ # @param [Hash] args
12
+ # @option args [Array<Integer>] :id
13
+ # @option args [Array<String>] :slug
14
+ # @return [CoinMarketPro::Result]
15
+ # @note At least one "id" or "slug" is required.
16
+ #
17
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1ExchangeInfo
18
+ ##
19
+ def info(**args)
20
+ valid_params?(args)
21
+ params = convert_params(args)
22
+ client.get("#{ENDPOINT}/info", options: params.compact).tap do |resp|
23
+ resp.body = resp.body.map { |_k, data| data }
24
+ end
25
+ end
26
+
27
+ alias metadata info
28
+
29
+ # @note This endpoint is not yet available. It is slated for release in early Q4 2018.
30
+ # Get a paginated list of all cryptocurrency exchanges with historical market data for a given point in time.
31
+ #
32
+ # @param args [Hash]
33
+ # @option args [String] :timestamp
34
+ # @option args [Integer] :start
35
+ # @option args [Integer] :limit
36
+ # @option args [String] :convert
37
+ # @option args [String] :sort
38
+ # @option args [String] :sort_dir
39
+ # @option args [String] :market_type Default: 'fees'. Valid values: 'fees', 'no_fees', 'all'
40
+ # @return [CoinMarketPro::Result]
41
+ #
42
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1ExchangeListingsHistorical
43
+ ##
44
+ def listings_historical(**args)
45
+ params = convert_params(args)
46
+ client.get("#{ENDPOINT}/listings/historical", options: params.compact)
47
+ end
48
+
49
+ # Get a paginated list of all cryptocurrency exchanges with 24 hour volume.
50
+ #
51
+ # @param args [Hash]
52
+ # @option args [String] :timestamp
53
+ # @option args [Integer] :start
54
+ # @option args [Integer] :limit
55
+ # @option args [String] :convert
56
+ # @option args [String] :sort
57
+ # @option args [String] :sort_dir
58
+ # @option args [String] :market_type Default: 'fees'. Valid values: 'fees', 'no_fees', 'all'
59
+ # @return [CoinMarketPro::Result]
60
+ #
61
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1ExchangeListingsLatest
62
+ ##
63
+ def listings(**args)
64
+ params = convert_params(args)
65
+ client.get("#{ENDPOINT}/listings/latest", options: params.compact)
66
+ end
67
+
68
+ alias listings_latest listings
69
+
70
+ # Returns a paginated list of all cryptocurrencies by CoinMarketCap ID.
71
+ #
72
+ # @param [Hash] args
73
+ # @option args [String] :listing_status Optional. Defaults to 'active'
74
+ # @option args [Integer] :start
75
+ # @option args [Integer] :limit
76
+ # @option args [Array] :slug
77
+ # @return [CoinMarketPro::Result]
78
+ #
79
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1ExchangeMap
80
+ ##
81
+ def map(**args)
82
+ params = convert_params(args)
83
+ client.get("#{ENDPOINT}/map", options: params.compact)
84
+ end
85
+
86
+ # Get a list of active market pairs for an exchange.
87
+ #
88
+ # @param [Hash] args
89
+ # @option args [Array<Integer>] :id
90
+ # @option args [Array<String>] :slug
91
+ # @option args [Integer] :start
92
+ # @option args [Integer] :limit
93
+ # @option args [String] :convert
94
+ # @return [CoinMarketPro::Result]
95
+ #
96
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1ExchangeMarketpairsLatest
97
+ ##
98
+ def market_pairs(**args)
99
+ valid_params?(args)
100
+ params = convert_params(args)
101
+ client.get("#{ENDPOINT}/market-pairs/latest", options: params.compact).tap do |resp|
102
+ resp.body = [resp.body]
103
+ end
104
+ end
105
+
106
+ # Returns an interval of historic quotes for any exchange based on time and interval parameters.
107
+ #
108
+ # @param [Hash] args
109
+ # @option args [Array<Integer>] :id
110
+ # @option args [Array<String>] :slug
111
+ # A single cryptocurrency "id" or "symbol" is required.
112
+ # @option args [String] :time_period
113
+ # @option args [String] :time_start
114
+ # @option args [String] :time_end
115
+ # @option args [Number] :count
116
+ # @option args [String] :interval
117
+ # @option args [String] :convert
118
+ # @return [CoinMarketPro::Result]
119
+ #
120
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1ExchangeQuotesHistorical
121
+ def quotes_historical(**args)
122
+ valid_params?(args)
123
+ params = convert_params(args)
124
+ client.get("#{ENDPOINT}/quotes/historical", options: params.compact).tap do |resp|
125
+ resp.body = [resp.body]
126
+ end
127
+ end
128
+
129
+ alias market_quotes_historical quotes_historical
130
+
131
+ # @param [Hash] args
132
+ # @option args [Array<Integer>] :id
133
+ # @option args [Array<String>] :slug
134
+ # @option args [String] :convert
135
+ # @return [CoinMarketPro::Result]
136
+ #
137
+ # @see https://pro.coinmarketcap.com/api/v1#operation/getV1ExchangeQuotesLatest
138
+ def quotes(**args)
139
+ valid_params?(args)
140
+ params = convert_params(args)
141
+ client.get("#{ENDPOINT}/quotes/latest", options: params.compact).tap do |resp|
142
+ resp.body = resp.body.map { |_k, data| data }
143
+ end
144
+ end
145
+
146
+ alias market_quotes quotes
147
+ alias quotes_latest quotes
148
+
149
+ protected
150
+
151
+ # @param args [Hash]
152
+ # @return [Boolean]
153
+ # @raise [ArgumentError]
154
+ def valid_params?(args)
155
+ raise ArgumentError.new('At least one "id" or "slug" is required.') if args[:id].blank? && args[:slug].blank?
156
+
157
+ true
158
+ end
159
+ end
160
+ end
161
+ end