Skip to content
This repository has been archived by the owner on Sep 19, 2023. It is now read-only.

Commit

Permalink
implement latest market pairs endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmota committed Feb 25, 2019
1 parent 7585e8f commit 1ab78e6
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 18 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ go get -u github.com/miguelmota/go-coinmarketcap
| Cryptocurrency | /v1/cryptocurrency/info ||
| Cryptocurrency | /v1/cryptocurrency/map ||
| Cryptocurrency | /v1/cryptocurrency/listings/latest ||
| Cryptocurrency | /v1/cryptocurrency/market-pairs/latest | - |
| Cryptocurrency | /v1/cryptocurrency/market-pairs/latest | |
| Cryptocurrency | /v1/cryptocurrency/ohlcv/historical | - |
| Cryptocurrency | /v1/cryptocurrency/quotes/latest ||
| Cryptocurrency | /v1/cryptocurrency/quotes/historical | - |
Expand All @@ -47,6 +47,8 @@ go get -u github.com/miguelmota/go-coinmarketcap
| Global Metrics | /v1/global-metrics/quotes/historical | - |
| Tools | /v1/tools/price-conversion ||

Note: some endpoints require a paid plan.

### Getting started

```go
Expand Down
126 changes: 109 additions & 17 deletions pro/v1/coinmarketcap.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@ type ConvertOptions struct {
Convert string
}

// MarketPairOptions options
type MarketPairOptions struct {
ID int
Symbol string
Start int
Limit int
Convert string
}

// service is abstraction for individual endpoint resources
type service struct {
client *Client
Expand Down Expand Up @@ -389,51 +398,134 @@ func (s *CryptocurrencyService) Map(options *MapOptions) ([]*MapListing, error)
return result, nil
}

// Exchange ...
type Exchange struct {
ID int `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
}

// MarketPairBase ...
type MarketPairBase struct {
CurrencyID int `json:"currency_id"`
CurrencySymbol string `json:"currency_symbol"`
CurrencyType string `json:"currency_type"`
}

// MarketPairQuote ...
type MarketPairQuote struct {
CurrencyID int `json:"currency_id"`
CurrencySymbol string `json:"currency_symbol"`
CurrencyType string `json:"currency_type"`
}

// ExchangeQuote ...
type ExchangeQuote struct {
Price float64 `json:"price"`
Volume24 float64 `json:"volume_24h"`
Volume24HBase float64 `json:"volume_24h_base"` // for 'exchange_reported'
Volume24HQuote float64 `json:"volume_24h_quote"` // for 'exchange_reported'
LastUpdated string `json:"last_updated"`
}

// ExchangeQuotes ...
type ExchangeQuotes map[string]*ExchangeQuote

// ExchangeReported ...
type ExchangeReported struct {
Price float64 `json:"price"`
Volume24HBase float64 `json:"volume_24h_base"`
Volume24HQuote float64 `json:"volume_24h_quote"`
LastUpdated string `json:"last_updated"`
}

// MarketPairs ...
type MarketPairs struct {
ID int `json:"id"`
Name string `json:"name"`
Symbol string `json:"symbol"`
NumMarketPairs int `json:"num_market_pairs"`
MarketPairs []*MarketPair `json:"market_pairs"`
}

// MarketPair ...
type MarketPair struct {
Exchange *Exchange
MarketPair string `json:"market_pair"`
MarketPairBase *MarketPairBase `json:"market_pair_base"`
MarketPairQuote *MarketPairQuote `json:"market_pair_quote"`
Quote ExchangeQuotes `json:"quote"`
ExchangeReported *ExchangeReported `json:"exchange_reported"`
}

// LatestMarketPairs Lists all market pairs across all exchanges for the specified cryptocurrency with associated stats. Use the "convert" option to return market values in multiple fiat and cryptocurrency conversions in the same call.
func (s *CryptocurrencyService) LatestMarketPairs(options *QuoteOptions) ([]*QuoteLatest, error) {
func (s *CryptocurrencyService) LatestMarketPairs(options *MarketPairOptions) (*MarketPairs, error) {
var params []string
if options == nil {
options = new(QuoteOptions)
options = new(MarketPairOptions)
}

if options.ID != 0 {
params = append(params, fmt.Sprintf("id=%v", options.ID))
}

if options.Symbol != "" {
params = append(params, fmt.Sprintf("symbol=%s", options.Symbol))
}

if options.Start != 0 {
params = append(params, fmt.Sprintf("start=%v", options.Start))
}

if options.Limit != 0 {
params = append(params, fmt.Sprintf("limit=%v", options.Limit))
}

if options.Convert != "" {
params = append(params, fmt.Sprintf("convert=%s", options.Convert))
}

url := fmt.Sprintf("%s/cryptocurrency/quotes/latest?%s", baseURL, strings.Join(params, "&"))
url := fmt.Sprintf("%s/cryptocurrency/market-pairs/latest?%s", baseURL, strings.Join(params, "&"))

body, err := s.client.makeReq(url)
resp := new(Response)

err = json.Unmarshal(body, &resp)
if err != nil {
return nil, fmt.Errorf("JSON Error: [%s]. Response body: [%s]", err.Error(), string(body))
}

var quotesLatest []*QuoteLatest
ifcs, ok := resp.Data.(interface{})
data, ok := resp.Data.(interface{})
if !ok {
return nil, ErrTypeAssertion
}

for _, coinObj := range ifcs.(map[string]interface{}) {
quoteLatest := new(QuoteLatest)
b, err := json.Marshal(coinObj)
if err != nil {
return nil, err
}
marketPairs := new(MarketPairs)
b, err := json.Marshal(data)
if err != nil {
return nil, err
}

err = json.Unmarshal(b, quoteLatest)
if err != nil {
return nil, err
}
err = json.Unmarshal(b, marketPairs)
if err != nil {
return nil, err
}

quotesLatest = append(quotesLatest, quoteLatest)
for _, pair := range marketPairs.MarketPairs {
reported, ok := pair.Quote["exchange_reported"]
if ok {
pair.ExchangeReported = &ExchangeReported{
Price: reported.Price,
Volume24HBase: reported.Volume24HBase,
Volume24HQuote: reported.Volume24HQuote,
LastUpdated: reported.LastUpdated,
}

delete(pair.Quote, "exchange_reported")
}
}
return quotesLatest, nil

return marketPairs, nil
}

// HistoricalOHLCV NOT IMPLEMENTED
Expand Down
63 changes: 63 additions & 0 deletions pro/v1/coinmarketcap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,33 @@ func TestCryptocurrencyLatestListings(t *testing.T) {
}
}

func TestCryptocurrencyLatestMarketPairs(t *testing.T) {
t.Skip("requires paid plan for api")

info, err := client.Cryptocurrency.LatestMarketPairs(&MarketPairOptions{
Symbol: "BTC",
})
if err != nil {
t.Error(err)
}
if info.Name != "Bitcoin" {
t.FailNow()
}
if len(info.MarketPairs) == 0 {
t.FailNow()
}
if info.MarketPairs[0].Quote["USD"].Price == 0 {
t.FailNow()
}
if info.MarketPairs[0].ExchangeReported.Price == 0 {
t.FailNow()
}
}

func TestCryptocurrencyHistoricalOHLCV(t *testing.T) {
// TODO
}

func TestCryptocurrencyLatestQuotes(t *testing.T) {
quotes, err := client.Cryptocurrency.LatestQuotes(&QuoteOptions{
Symbol: "BTC",
Expand All @@ -78,6 +105,42 @@ func TestCryptocurrencyLatestQuotes(t *testing.T) {
}
}

func TestCryptocurrencyHistoricalQuotes(t *testing.T) {
// TODO
}

func TestExchangeInfo(t *testing.T) {
// TODO
}

func TestExchangeMap(t *testing.T) {
// TODO
}

func TestExchangeLatestListings(t *testing.T) {
// TODO
}

func TestExchangeLatestMarketPairs(t *testing.T) {
// TODO
}

func TestExchangeLatestQuotes(t *testing.T) {
// TODO
}

func TestExchangeHistoricalQuotes(t *testing.T) {
// TODO
}

func TestGlobalMetricsLatestQuotes(t *testing.T) {
// TODO
}

func TestGlobalMetricsHistoricalQuotes(t *testing.T) {
// TODO
}

func TestToolsPriceConversion(t *testing.T) {
t.Skip("requires paid plan for api")
listing, err := client.Tools.PriceConversion(&ConvertOptions{
Expand Down
25 changes: 25 additions & 0 deletions pro/v1/example/latest_market_pairs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"fmt"
"os"

cmc "github.com/miguelmota/go-coinmarketcap/pro/v1"
)

func main() {
client := cmc.NewClient(&cmc.Config{
ProAPIKey: os.Getenv("CMC_PRO_API_KEY"),
})

info, err := client.Cryptocurrency.LatestMarketPairs(&cmc.MarketPairOptions{
Symbol: "BTC",
})
if err != nil {
panic(err)
}

fmt.Println(info.Name) // "Bitcoin"
fmt.Println(info.MarketPairs[0].Quote["USD"].Price) // 8127.80075640354
fmt.Println(info.MarketPairs[0].ExchangeReported.Price) // 8136.96
}

0 comments on commit 1ab78e6

Please sign in to comment.