Initial commit
This commit is contained in:
49
app/api/v2/coin_gecko/entities/orderbook.rb
Normal file
49
app/api/v2/coin_gecko/entities/orderbook.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
module Entities
|
||||
class Orderbook < API::V2::Entities::Base
|
||||
expose(
|
||||
:ticker_id,
|
||||
documentation: {
|
||||
type: String,
|
||||
desc: 'A pair such as "BTC_ETH", with delimiter between different cryptoassets.'
|
||||
}
|
||||
) do |orderbook|
|
||||
orderbook.market.underscore_name
|
||||
end
|
||||
|
||||
expose(
|
||||
:timestamp,
|
||||
documentation: {
|
||||
type: Integer,
|
||||
desc: 'Unix timestamp in milliseconds for when the last updated time occurred'
|
||||
}
|
||||
) do
|
||||
DateTime.now.strftime('%Q').to_i
|
||||
end
|
||||
|
||||
expose(
|
||||
:asks,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
is_array: true,
|
||||
desc: 'An array containing 2 elements. The offer price and quantity for each bid order.'
|
||||
}
|
||||
)
|
||||
|
||||
expose(
|
||||
:bids,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
is_array: true,
|
||||
desc: 'An array containing 2 elements. The ask price and quantity for each ask order.'
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
41
app/api/v2/coin_gecko/entities/pair.rb
Normal file
41
app/api/v2/coin_gecko/entities/pair.rb
Normal file
@@ -0,0 +1,41 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
module Entities
|
||||
class Pair < API::V2::Entities::Base
|
||||
expose(
|
||||
:ticker_id,
|
||||
documentation: {
|
||||
type: String,
|
||||
desc: 'Identifier of a ticker with delimiter to separate base/target, eg. BTC_ETH.'
|
||||
}
|
||||
) do |market|
|
||||
market.underscore_name
|
||||
end
|
||||
|
||||
expose(
|
||||
:base,
|
||||
documentation: {
|
||||
type: String,
|
||||
desc: 'Symbol/currency code of a the base cryptoasset, eg. BTC.'
|
||||
}
|
||||
) do |market|
|
||||
market[:base_unit].upcase
|
||||
end
|
||||
|
||||
expose(
|
||||
:target,
|
||||
documentation: {
|
||||
type: String,
|
||||
desc: 'Symbol/currency code of the target cryptoasset, eg. ETH.'
|
||||
}
|
||||
) do |market|
|
||||
market[:quote_unit].upcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
111
app/api/v2/coin_gecko/entities/ticker.rb
Normal file
111
app/api/v2/coin_gecko/entities/ticker.rb
Normal file
@@ -0,0 +1,111 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
module Entities
|
||||
class Ticker < API::V2::Entities::Base
|
||||
expose(
|
||||
:ticker_id,
|
||||
documentation: {
|
||||
type: String,
|
||||
desc: 'Identifier of a ticker with delimiter to separate base/target, eg. BTC_ETH.'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:market].underscore_name
|
||||
end
|
||||
|
||||
expose(
|
||||
:base_currency,
|
||||
documentation: {
|
||||
type: String,
|
||||
desc: 'Symbol/currency code of base pair, eg. BTC.'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:market][:base_unit].upcase
|
||||
end
|
||||
|
||||
expose(
|
||||
:target_currency,
|
||||
documentation: {
|
||||
type: String,
|
||||
desc: 'Symbol/currency code of target pair, eg. ETH.'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:market][:quote_unit].upcase
|
||||
end
|
||||
|
||||
expose(
|
||||
:last_price,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
desc: 'Last transacted price of base currency based on given target currency.'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:last]
|
||||
end
|
||||
|
||||
expose(
|
||||
:base_volume,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
desc: '24 hour trading volume in base pair volume.'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:amount]
|
||||
end
|
||||
|
||||
expose(
|
||||
:target_volume,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
desc: '24 hour trading volume in base pair volume.'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:volume]
|
||||
end
|
||||
|
||||
expose(
|
||||
:bid,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
desc: 'Current highest bid price.'
|
||||
}
|
||||
) do |ticker|
|
||||
OrderBid.get_depth(ticker[:market].id).flatten.first.to_d
|
||||
end
|
||||
|
||||
expose(
|
||||
:ask,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
desc: 'Current lowest ask price.'
|
||||
}
|
||||
) do |ticker|
|
||||
OrderAsk.get_depth(ticker[:market].id).flatten.first.to_d
|
||||
end
|
||||
|
||||
expose(
|
||||
:high,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
desc: 'The highest trade price during last 24 hours (0.0 if no trades executed during last 24 hours).'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:high]
|
||||
end
|
||||
|
||||
expose(
|
||||
:low,
|
||||
documentation: {
|
||||
type: BigDecimal,
|
||||
desc: 'The lowest trade price during last 24 hours (0.0 if no trades executed during last 24 hours).'
|
||||
}
|
||||
) do |ticker|
|
||||
ticker[:low]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
22
app/api/v2/coin_gecko/helpers.rb
Normal file
22
app/api/v2/coin_gecko/helpers.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
module Helpers
|
||||
MILLISECONDS_IN_SECOND = 1000
|
||||
|
||||
def format_trade(trade)
|
||||
{
|
||||
trade_id: trade[:id],
|
||||
price: trade[:price],
|
||||
base_volume: trade[:amount],
|
||||
target_volume: trade[:total],
|
||||
trade_timestamp: trade[:created_at] * MILLISECONDS_IN_SECOND,
|
||||
type: trade[:taker_type]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
43
app/api/v2/coin_gecko/historical_trades.rb
Normal file
43
app/api/v2/coin_gecko/historical_trades.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
class HistoricalTrades < Grape::API
|
||||
desc 'Get recent trades on market'
|
||||
params do
|
||||
requires :ticker_id,
|
||||
type: String,
|
||||
desc: 'A pair such as "LTC_BTC"',
|
||||
coerce_with: ->(name) { name.strip.split('_').join.downcase }
|
||||
optional :type,
|
||||
type: String,
|
||||
values: { value: %w(buy sell), message: 'coingecko.historical_trades.invalid_type' },
|
||||
desc: 'To indicate nature of trade - buy/sell'
|
||||
optional :limit,
|
||||
type: Integer,
|
||||
values: { value: 0..1000, message: 'coingecko.historical_trades.invalid_limit' },
|
||||
desc: 'Number of historical trades to retrieve from time of query. [0, 200, 500...]. 0 returns full history'
|
||||
optional :start_time,
|
||||
type: Integer,
|
||||
desc: '',
|
||||
coerce_with: ->(start_time) { Time.parse(start_time).to_i }
|
||||
optional :end_time,
|
||||
type: Integer,
|
||||
desc: '',
|
||||
coerce_with: ->(end_time) { Time.parse(end_time).to_i }
|
||||
end
|
||||
get '/historical_trades' do
|
||||
market = ::Market.find(params[:ticker_id])
|
||||
|
||||
filters = declared(params, include_missing: false)
|
||||
.except(:ticker_id, :limit)
|
||||
|
||||
Trade.public_from_influx(market.id, params[:limit], filters).each_with_object({'buy' => [], 'sell' => []}) do |trade, hash|
|
||||
hash[trade[:taker_type]] << format_trade(trade)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/api/v2/coin_gecko/mount.rb
Normal file
20
app/api/v2/coin_gecko/mount.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
class Mount < Grape::API
|
||||
PREFIX = '/coingecko'
|
||||
|
||||
before { set_ets_context! }
|
||||
|
||||
helpers CoinGecko::Helpers
|
||||
|
||||
mount CoinGecko::Pairs
|
||||
mount CoinGecko::Tickers
|
||||
mount CoinGecko::Orderbook
|
||||
mount CoinGecko::HistoricalTrades
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
39
app/api/v2/coin_gecko/orderbook.rb
Normal file
39
app/api/v2/coin_gecko/orderbook.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
class Orderbook < Grape::API
|
||||
class OrderBook < Struct.new(:market, :asks, :bids); end
|
||||
|
||||
desc 'Get depth or specified market'
|
||||
params do
|
||||
requires :ticker_id,
|
||||
type: String,
|
||||
desc: 'A pair such as "LTC_BTC"',
|
||||
coerce_with: ->(name) { name.strip.split('_').join.downcase }
|
||||
optional :depth,
|
||||
type: { value: Integer, message: 'coingecko.market_depth.non_integer_depth' },
|
||||
values: { value: 0..1000, message: 'coingecko.market_depth.invalid_depth' },
|
||||
desc: 'Orders depth quantity: [0, 100, 200, 500...]'
|
||||
end
|
||||
|
||||
get '/orderbook' do
|
||||
market = ::Market.find(params[:ticker_id])
|
||||
asks = OrderAsk.get_depth(market.id)
|
||||
bids = OrderBid.get_depth(market.id)
|
||||
|
||||
# Depth = 100 means 50 for each bid/ask side
|
||||
# Not defined or 0 = full order book
|
||||
unless params[:depth].to_d.zero?
|
||||
asks = asks[0, params[:depth]/2]
|
||||
bids = bids[0, params[:depth]/2]
|
||||
end
|
||||
|
||||
orderbook = OrderBook.new market, asks, bids
|
||||
present orderbook, with: API::V2::CoinGecko::Entities::Orderbook
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
16
app/api/v2/coin_gecko/pairs.rb
Normal file
16
app/api/v2/coin_gecko/pairs.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# encoding: UTF-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
class Pairs < Grape::API
|
||||
desc 'Get list of all available trading pairs'
|
||||
get "/pairs" do
|
||||
present ::Rails.cache.fetch(:markets_coingecko, expires_in: 60) { ::Market.enabled.ordered },
|
||||
with: API::V2::CoinGecko::Entities::Pair
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
21
app/api/v2/coin_gecko/tickers.rb
Normal file
21
app/api/v2/coin_gecko/tickers.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
# encoding: UTF-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
module API
|
||||
module V2
|
||||
module CoinGecko
|
||||
class Tickers < Grape::API
|
||||
desc 'Get list of all available trading pairs'
|
||||
get "/tickers" do
|
||||
tickers = ::Rails.cache.fetch(:markets_tickers_coingecko, expires_in: 60) do
|
||||
::Market.enabled.ordered.inject([]) do |hash, market|
|
||||
hash << TickersService[market].ticker.merge(market: market)
|
||||
end
|
||||
end
|
||||
|
||||
present tickers, with: API::V2::CoinGecko::Entities::Ticker
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user