class CoinTools::Cryptowatch
Constants
- BASE_URL
- DAYS_FOR_PERIODS
we expect this many days worth of data for a given period precision (in seconds); NOT guaranteed by the API
- DataPoint
Public Instance Methods
exchanges()
click to toggle source
# File lib/cointools/cryptowatch.rb, line 22 def exchanges @exchanges ||= get_exchanges end
get_current_price(exchange, market)
click to toggle source
# File lib/cointools/cryptowatch.rb, line 96 def get_current_price(exchange, market) raise InvalidExchangeError if exchange.to_s.empty? raise InvalidSymbolError if market.to_s.empty? url = URI("#{BASE_URL}/markets/#{exchange}/#{market}/price") response = Request.get(url) case response when Net::HTTPSuccess json = Utils.parse_json(response.body) raise JSONError.new(response) unless json.is_a?(Hash) data = json['result'] allowance = json['allowance'] raise JSONError.new(response) unless data.is_a?(Hash) && allowance.is_a?(Hash) price = data['price'] raise NoDataError.new(response) unless price return DataPoint.new( price: price, time: nil, api_time_spent: allowance['cost'], api_time_remaining: allowance['remaining'] ) when Net::HTTPNotFound raise UnknownCoinError.new(response) when Net::HTTPClientError raise BadRequestError.new(response) else raise ServiceUnavailableError.new(response) end end
get_markets(exchange)
click to toggle source
# File lib/cointools/cryptowatch.rb, line 26 def get_markets(exchange) raise InvalidExchangeError if exchange.to_s.empty? url = URI("#{BASE_URL}/markets/#{exchange}") response = Request.get(url) case response when Net::HTTPSuccess json = Utils.parse_json(response.body) raise JSONError.new(response) unless json.is_a?(Hash) && json['result'].is_a?(Array) return json['result'].select { |m| m['active'] == true }.map { |m| m['pair'] }.sort when Net::HTTPNotFound raise UnknownExchangeError.new(response) when Net::HTTPClientError raise BadRequestError.new(response) else raise ServiceUnavailableError.new(response) end end
get_price(exchange, market, time = nil)
click to toggle source
# File lib/cointools/cryptowatch.rb, line 48 def get_price(exchange, market, time = nil) raise InvalidExchangeError if exchange.to_s.empty? raise InvalidSymbolError if market.to_s.empty? if time.nil? return get_current_price(exchange, market) elsif time.is_a?(String) time = Utils.parse_time(time) end (time <= Time.now) or raise InvalidDateError.new('Future date was passed') (time.year >= 2009) or raise InvalidDateError.new('Too early date was passed') unixtime = time.to_i current_time = Time.now.to_i url = URI("#{BASE_URL}/markets/#{exchange}/#{market}/ohlc?after=#{unixtime}") response = Request.get(url) case response when Net::HTTPSuccess json = Utils.parse_json(response.body) raise JSONError.new(response) unless json.is_a?(Hash) data = json['result'] allowance = json['allowance'] raise JSONError.new(response) unless data.is_a?(Hash) && allowance.is_a?(Hash) timestamp, o, h, l, c, volume = best_matching_record(data, unixtime, current_time) raise NoDataError.new(response, 'No price data returned') unless timestamp && o actual_time = Time.at(timestamp) return DataPoint.new( price: o, time: actual_time, api_time_spent: allowance['cost'], api_time_remaining: allowance['remaining'] ) when Net::HTTPNotFound raise UnknownCoinError.new(response) when Net::HTTPClientError raise BadRequestError.new(response) else raise ServiceUnavailableError.new(response) end end
get_price_fast(exchange, market, time = nil)
click to toggle source
# File lib/cointools/cryptowatch.rb, line 131 def get_price_fast(exchange, market, time = nil) raise InvalidExchangeError if exchange.to_s.empty? raise InvalidSymbolError if market.to_s.empty? if time.nil? return get_current_price(exchange, market) elsif time.is_a?(String) time = Utils.parse_time(time) end (time <= Time.now) or raise InvalidDateError.new('Future date was passed') (time.year >= 2009) or raise InvalidDateError.new('Too early date was passed') period = precision_for_time(time) if period.nil? return get_price(exchange, market, time) end unixtime = time.to_i current_time = Time.now.to_i url = URI("#{BASE_URL}/markets/#{exchange}/#{market}/ohlc?after=#{unixtime}&periods=#{period}") response = Request.get(url) case response when Net::HTTPSuccess json = Utils.parse_json(response.body) raise JSONError.new(response) unless json.is_a?(Hash) data = json['result'] allowance = json['allowance'] raise JSONError.new(response) unless data.is_a?(Hash) && allowance.is_a?(Hash) timestamp, o, h, l, c, volume = best_matching_record(data, unixtime, current_time) raise NoDataError.new(response, 'No price data returned') unless timestamp && o actual_time = Time.at(timestamp) return DataPoint.new( price: o, time: actual_time, api_time_spent: allowance['cost'], api_time_remaining: allowance['remaining'] ) when Net::HTTPNotFound raise UnknownCoinError.new(response) when Net::HTTPClientError raise BadRequestError.new(response) else raise ServiceUnavailableError.new(response) end end
Private Instance Methods
best_matching_record(data, unixtime, request_time)
click to toggle source
# File lib/cointools/cryptowatch.rb, line 188 def best_matching_record(data, unixtime, request_time) candidates = [] data.keys.sort_by { |k| k.to_i }.each do |k| records = data[k] || [] previous = nil records.each do |record| timestamp, o, h, l, c, volume = record if timestamp >= unixtime candidates.push(record) unless timestamp > request_time break else previous = record end end candidates.push(previous) if previous end candidates.sort_by { |record| (record[0] - unixtime).abs }.first end
get_exchanges()
click to toggle source
# File lib/cointools/cryptowatch.rb, line 227 def get_exchanges url = URI("#{BASE_URL}/exchanges") response = Request.get(url) case response when Net::HTTPSuccess json = Utils.parse_json(response.body) raise JSONError.new(response) unless json.is_a?(Hash) && json['result'].is_a?(Array) return json['result'].select { |e| e['active'] == true }.map { |e| e['symbol'] }.sort when Net::HTTPClientError raise BadRequestError.new(response) else raise ServiceUnavailableError.new(response) end end
precision_for_time(time)
click to toggle source
# File lib/cointools/cryptowatch.rb, line 212 def precision_for_time(time) now = Time.now DAYS_FOR_PERIODS.keys.sort.each do |period| days = DAYS_FOR_PERIODS[period] earliest_date = now - days * 86400 if earliest_date < time return period end end nil end