mirror of https://github.com/miguelmota/cointop
currencyconversion var
parent
9bc7d61f02
commit
40f0b3a3b3
@ -0,0 +1,356 @@
|
|||||||
|
// Package coinmarketcap Coin Market Cap API client for Go
|
||||||
|
package coinmarketcap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/anaskhan96/soup"
|
||||||
|
"github.com/coincircle/go-coinmarketcap/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
siteURL = "https://coinmarketcap.com"
|
||||||
|
baseURL = "https://api.coinmarketcap.com/v2"
|
||||||
|
coinGraphURL = "https://graphs2.coinmarketcap.com/currencies"
|
||||||
|
globalMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-total"
|
||||||
|
altcoinMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-altcoin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Interface interface
|
||||||
|
type Interface interface {
|
||||||
|
Listings() ([]*types.Listing, error)
|
||||||
|
Tickers(options *TickersOptions) (map[string]*types.Ticker, error)
|
||||||
|
Ticker(options *TickerOptions) (*types.Ticker, error)
|
||||||
|
TickerGraph(options *TickerGraphOptions) (*types.TickerGraph, error)
|
||||||
|
GlobalMarket(options *GlobalMarketOptions) (*types.GlobalMarket, error)
|
||||||
|
GlobalMarketGraph(options *GlobalMarketGraphOptions) (*types.MarketGraph, error)
|
||||||
|
GlobalAltcoinMarketGraph(options *GlobalAltcoinMarketGraphOptions) (*types.MarketGraph, error)
|
||||||
|
Markets(options *MarketsOptions) ([]*types.Market, error)
|
||||||
|
Price(options *PriceOptions) (float64, error)
|
||||||
|
CoinID(symbol string) (int, error)
|
||||||
|
CoinSlug(symbol string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// listingsMedia listings response media
|
||||||
|
type listingsMedia struct {
|
||||||
|
Data []*types.Listing `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listings gets all coin listings
|
||||||
|
func Listings() ([]*types.Listing, error) {
|
||||||
|
url := fmt.Sprintf("%s/listings", baseURL)
|
||||||
|
resp, err := makeReq(url)
|
||||||
|
var body listingsMedia
|
||||||
|
err = json.Unmarshal(resp, &body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return body.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TickersOptions options for tickers method
|
||||||
|
type TickersOptions struct {
|
||||||
|
Start int
|
||||||
|
Limit int
|
||||||
|
Convert string
|
||||||
|
}
|
||||||
|
|
||||||
|
// tickerMedia tickers response media
|
||||||
|
type tickersMedia struct {
|
||||||
|
Data map[string]*types.Ticker `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tickers gets ticker information on coins
|
||||||
|
func Tickers(options *TickersOptions) (map[string]*types.Ticker, error) {
|
||||||
|
var params []string
|
||||||
|
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=%v", options.Convert))
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("%s/ticker?%s", baseURL, strings.Join(params, "&"))
|
||||||
|
resp, err := makeReq(url)
|
||||||
|
var body tickersMedia
|
||||||
|
err = json.Unmarshal(resp, &body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tickers := make(map[string]*types.Ticker)
|
||||||
|
data := body.Data
|
||||||
|
for _, v := range data {
|
||||||
|
tickers[strings.ToUpper(string(v.Symbol))] = v
|
||||||
|
}
|
||||||
|
return tickers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TickerOptions options for ticker method
|
||||||
|
type TickerOptions struct {
|
||||||
|
Symbol string
|
||||||
|
Convert string
|
||||||
|
}
|
||||||
|
|
||||||
|
type tickerMedia struct {
|
||||||
|
Data *types.Ticker `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ticker gets ticker information about a cryptocurrency
|
||||||
|
func Ticker(options *TickerOptions) (*types.Ticker, error) {
|
||||||
|
var params []string
|
||||||
|
if options.Convert != "" {
|
||||||
|
params = append(params, fmt.Sprintf("convert=%v", options.Convert))
|
||||||
|
}
|
||||||
|
id, err := CoinID(options.Symbol)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("%s/ticker/%v?%s", baseURL, id, strings.Join(params, "&"))
|
||||||
|
resp, err := makeReq(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var body tickerMedia
|
||||||
|
err = json.Unmarshal(resp, &body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return body.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TickerGraphOptions options for ticker graph
|
||||||
|
type TickerGraphOptions struct {
|
||||||
|
Symbol string
|
||||||
|
Start int64
|
||||||
|
End int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// TickerGraph gets graph data points for a cryptocurrency
|
||||||
|
func TickerGraph(options *TickerGraphOptions) (*types.TickerGraph, error) {
|
||||||
|
slug, err := CoinSlug(options.Symbol)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("%s/%s/%d/%d", coinGraphURL, slug, options.Start*1000, options.End*1000)
|
||||||
|
resp, err := makeReq(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var data *types.TickerGraph
|
||||||
|
err = json.Unmarshal(resp, &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalMarketOptions options for global data method
|
||||||
|
type GlobalMarketOptions struct {
|
||||||
|
Convert string
|
||||||
|
}
|
||||||
|
|
||||||
|
// globalMedia global data response media
|
||||||
|
type globalMarketMedia struct {
|
||||||
|
Data *types.GlobalMarket `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalMarket gets information about the global market of the cryptocurrencies
|
||||||
|
func GlobalMarket(options *GlobalMarketOptions) (*types.GlobalMarket, error) {
|
||||||
|
var params []string
|
||||||
|
if options.Convert != "" {
|
||||||
|
params = append(params, fmt.Sprintf("convert=%v", options.Convert))
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("%s/global?%s", baseURL, strings.Join(params, "&"))
|
||||||
|
resp, err := makeReq(url)
|
||||||
|
var body globalMarketMedia
|
||||||
|
err = json.Unmarshal(resp, &body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return body.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalMarketGraphOptions options for global market graph method
|
||||||
|
type GlobalMarketGraphOptions struct {
|
||||||
|
Start int64
|
||||||
|
End int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalMarketGraph get graph data points of global market
|
||||||
|
func GlobalMarketGraph(options *GlobalMarketGraphOptions) (*types.MarketGraph, error) {
|
||||||
|
url := fmt.Sprintf("%s/%d/%d", globalMarketGraphURL, options.Start*1000, options.End*1000)
|
||||||
|
resp, err := makeReq(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var data *types.MarketGraph
|
||||||
|
err = json.Unmarshal(resp, &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalAltcoinMarketGraphOptions options for global altcoin market graph method
|
||||||
|
type GlobalAltcoinMarketGraphOptions struct {
|
||||||
|
Start int64
|
||||||
|
End int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalAltcoinMarketGraph gets graph data points of altcoin market
|
||||||
|
func GlobalAltcoinMarketGraph(options *GlobalAltcoinMarketGraphOptions) (*types.MarketGraph, error) {
|
||||||
|
url := fmt.Sprintf("%s/%d/%d", altcoinMarketGraphURL, options.Start*1000, options.End*1000)
|
||||||
|
resp, err := makeReq(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var data *types.MarketGraph
|
||||||
|
err = json.Unmarshal(resp, &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarketsOptions options for markets method
|
||||||
|
type MarketsOptions struct {
|
||||||
|
Symbol string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Markets get market data for a cryptocurrency
|
||||||
|
func Markets(options *MarketsOptions) ([]*types.Market, error) {
|
||||||
|
slug, err := CoinSlug(options.Symbol)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("%s/currencies/%s/#markets", siteURL, slug)
|
||||||
|
var markets []*types.Market
|
||||||
|
response, err := soup.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows := soup.HTMLParse(response).Find("table", "id", "markets-table").Find("tbody").FindAll("tr")
|
||||||
|
for _, row := range rows {
|
||||||
|
var data []string
|
||||||
|
for _, column := range row.FindAll("td") {
|
||||||
|
attrs := column.Attrs()
|
||||||
|
if attrs["data-sort"] != "" {
|
||||||
|
data = append(data, attrs["data-sort"])
|
||||||
|
} else {
|
||||||
|
data = append(data, column.Text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
markets = append(markets, &types.Market{
|
||||||
|
Rank: toInt(data[0]),
|
||||||
|
Exchange: data[1],
|
||||||
|
Pair: data[2],
|
||||||
|
VolumeUSD: toFloat(data[3]),
|
||||||
|
Price: toFloat(data[4]),
|
||||||
|
VolumePercent: toFloat(data[5]),
|
||||||
|
Updated: data[6],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return markets, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PriceOptions options for price method
|
||||||
|
type PriceOptions struct {
|
||||||
|
Symbol string
|
||||||
|
Convert string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Price gets price of a cryptocurrency
|
||||||
|
func Price(options *PriceOptions) (float64, error) {
|
||||||
|
coins, err := Tickers(&TickersOptions{
|
||||||
|
Convert: options.Convert,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
coin := coins[options.Symbol]
|
||||||
|
if coin == nil {
|
||||||
|
return 0, errors.New("coin not found")
|
||||||
|
}
|
||||||
|
return coin.Quotes[options.Convert].Price, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoinID gets the ID for the cryptocurrency
|
||||||
|
func CoinID(symbol string) (int, error) {
|
||||||
|
symbol = strings.ToUpper(strings.TrimSpace(symbol))
|
||||||
|
coins, err := Tickers(&TickersOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
coin := coins[symbol]
|
||||||
|
if coin == nil {
|
||||||
|
return 0, errors.New("coin not found")
|
||||||
|
}
|
||||||
|
return coin.ID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CoinSlug gets the slug for the cryptocurrency
|
||||||
|
func CoinSlug(symbol string) (string, error) {
|
||||||
|
symbol = strings.ToUpper(strings.TrimSpace(symbol))
|
||||||
|
coins, err := Tickers(&TickersOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
coin := coins[symbol]
|
||||||
|
if coin == nil {
|
||||||
|
return "", errors.New("coin not found")
|
||||||
|
}
|
||||||
|
return coin.Slug, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toInt helper for parsing strings to int
|
||||||
|
func toInt(rawInt string) int {
|
||||||
|
parsed, _ := strconv.Atoi(strings.Replace(strings.Replace(rawInt, "$", "", -1), ",", "", -1))
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
// toFloat helper for parsing strings to float
|
||||||
|
func toFloat(rawFloat string) float64 {
|
||||||
|
parsed, _ := strconv.ParseFloat(strings.Replace(strings.Replace(strings.Replace(rawFloat, "$", "", -1), ",", "", -1), "%", "", -1), 64)
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
// doReq HTTP client
|
||||||
|
func doReq(req *http.Request) ([]byte, error) {
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if 200 != resp.StatusCode {
|
||||||
|
return nil, fmt.Errorf("%s", body)
|
||||||
|
}
|
||||||
|
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeReq HTTP request helper
|
||||||
|
func makeReq(url string) ([]byte, error) {
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp, err := doReq(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, err
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
// Listing struct
|
||||||
|
type Listing struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Symbol string `json:"symbol"`
|
||||||
|
Slug string `json:"website_slug"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ticker struct
|
||||||
|
type Ticker struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Symbol string `json:"symbol"`
|
||||||
|
Slug string `json:"website_slug"`
|
||||||
|
Rank int `json:"rank"`
|
||||||
|
CirculatingSupply float64 `json:"circulating_supply"`
|
||||||
|
TotalSupply float64 `json:"total_supply"`
|
||||||
|
MaxSupply float64 `json:"max_supply"`
|
||||||
|
Quotes map[string]*TickerQuote `json:"quotes"`
|
||||||
|
LastUpdated int `json:"last_updated"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TickerQuote struct
|
||||||
|
type TickerQuote struct {
|
||||||
|
Price float64 `json:"price"`
|
||||||
|
Volume24H float64 `json:"volume_24h"`
|
||||||
|
MarketCap float64 `json:"market_cap"`
|
||||||
|
PercentChange1H float64 `json:"percent_change_1h"`
|
||||||
|
PercentChange24H float64 `json:"percent_change_24h"`
|
||||||
|
PercentChange7D float64 `json:"percent_change_7d"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalMarket struct
|
||||||
|
type GlobalMarket struct {
|
||||||
|
ActiveCurrencies int `json:"active_cryptocurrencies"`
|
||||||
|
ActiveMarkets int `json:"active_markets"`
|
||||||
|
BitcoinPercentageOfMarketCap float64 `json:"bitcoin_percentage_of_market_cap"`
|
||||||
|
LastUpdated int `json:"last_updated"`
|
||||||
|
Quotes map[string]*GlobalMarketQuote `json:"quotes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalMarketQuote struct
|
||||||
|
type GlobalMarketQuote struct {
|
||||||
|
TotalMarketCap float64 `json:"total_market_cap"`
|
||||||
|
TotalVolume24H float64 `json:"total_volume_24h"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TickerGraph struct
|
||||||
|
type TickerGraph struct {
|
||||||
|
MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"`
|
||||||
|
PriceBTC [][]float64 `json:"price_btc"`
|
||||||
|
PriceUSD [][]float64 `json:"price_usd"`
|
||||||
|
VolumeUSD [][]float64 `json:"volume_usd"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Market struct
|
||||||
|
type Market struct {
|
||||||
|
Rank int
|
||||||
|
Exchange string
|
||||||
|
Pair string
|
||||||
|
VolumeUSD float64
|
||||||
|
Price float64
|
||||||
|
VolumePercent float64
|
||||||
|
Updated string
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarketGraph struct
|
||||||
|
type MarketGraph struct {
|
||||||
|
MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"`
|
||||||
|
VolumeUSD [][]float64 `json:"volume_usd"`
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Folders
|
|
||||||
_obj
|
|
||||||
_test
|
|
||||||
|
|
||||||
# Architecture specific extensions/prefixes
|
|
||||||
*.[568vq]
|
|
||||||
[568vq].out
|
|
||||||
|
|
||||||
*.cgo1.go
|
|
||||||
*.cgo2.c
|
|
||||||
_cgo_defun.c
|
|
||||||
_cgo_gotypes.go
|
|
||||||
_cgo_export.*
|
|
||||||
|
|
||||||
_testmain.go
|
|
||||||
|
|
||||||
*.exe
|
|
||||||
*.test
|
|
||||||
*.prof
|
|
||||||
|
|
||||||
.DS_Store
|
|
@ -1,9 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- "1.9.x"
|
|
||||||
- "1.10.x"
|
|
||||||
- "master"
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make test
|
|
@ -1,24 +0,0 @@
|
|||||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
|
||||||
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/anaskhan96/soup"
|
|
||||||
packages = ["."]
|
|
||||||
revision = "7a8d31f81bad1a5abeed0d0219c35e5e295a5a76"
|
|
||||||
version = "v1.0.1"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
name = "golang.org/x/net"
|
|
||||||
packages = [
|
|
||||||
"html",
|
|
||||||
"html/atom"
|
|
||||||
]
|
|
||||||
revision = "dc948dff8834a7fe1ca525f8d04e261c2b56e70d"
|
|
||||||
|
|
||||||
[solve-meta]
|
|
||||||
analyzer-name = "dep"
|
|
||||||
analyzer-version = 1
|
|
||||||
inputs-digest = "ef92c4a55490132c4b677cba28dd5f0ee0bb397d0b3581ea46df6c3f4f169646"
|
|
||||||
solver-name = "gps-cdcl"
|
|
||||||
solver-version = 1
|
|
@ -1,34 +0,0 @@
|
|||||||
# Gopkg.toml example
|
|
||||||
#
|
|
||||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
|
||||||
# for detailed Gopkg.toml documentation.
|
|
||||||
#
|
|
||||||
# required = ["github.com/user/thing/cmd/thing"]
|
|
||||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project"
|
|
||||||
# version = "1.0.0"
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project2"
|
|
||||||
# branch = "dev"
|
|
||||||
# source = "github.com/myfork/project2"
|
|
||||||
#
|
|
||||||
# [[override]]
|
|
||||||
# name = "github.com/x/y"
|
|
||||||
# version = "2.4.0"
|
|
||||||
#
|
|
||||||
# [prune]
|
|
||||||
# non-go = false
|
|
||||||
# go-tests = true
|
|
||||||
# unused-packages = true
|
|
||||||
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/anaskhan96/soup"
|
|
||||||
version = "1.0.1"
|
|
||||||
|
|
||||||
[prune]
|
|
||||||
go-tests = true
|
|
||||||
unused-packages = true
|
|
@ -1,21 +0,0 @@
|
|||||||
MIT license
|
|
||||||
|
|
||||||
Copyright (C) 2015 Miguel Mota
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
@ -1,5 +0,0 @@
|
|||||||
all:
|
|
||||||
@echo "no default"
|
|
||||||
|
|
||||||
test:
|
|
||||||
go test -v
|
|
@ -1,47 +0,0 @@
|
|||||||
# go-coinmarketcap
|
|
||||||
|
|
||||||
> The Unofficial [CoinMarketCap](https://coinmarketcap.com/) API client for Go.
|
|
||||||
|
|
||||||
[![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/miguelmota/go-coinmarketcap/master/LICENSE.md) [![Build Status](https://travis-ci.org/miguelmota/go-coinmarketcap.svg?branch=master)](https://travis-ci.org/miguelmota/go-coinmarketcap) [![Go Report Card](https://goreportcard.com/badge/github.com/miguelmota/go-coinmarketcap?)](https://goreportcard.com/report/github.com/miguelmota/go-coinmarketcap) [![GoDoc](https://godoc.org/github.com/miguelmota/go-coinmarketcap?status.svg)](https://godoc.org/github.com/miguelmota/go-coinmarketcap)
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
[https://godoc.org/github.com/miguelmota/go-coinmarketcap](https://godoc.org/github.com/miguelmota/go-coinmarketcap)
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get -u github.com/miguelmota/go-coinmarketcap
|
|
||||||
```
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
cmc "github.com/miguelmota/go-coinmarketcap"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
coins, err := cmc.GetAllCoinData(0)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, coin := range coins {
|
|
||||||
fmt.Println(coin.Symbol, coin.PriceUSD)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
Check out the [`./example`](./example) directory and documentation.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
@ -1,210 +0,0 @@
|
|||||||
// Package coinmarketcap Coin Market Cap API client for Go
|
|
||||||
package coinmarketcap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/anaskhan96/soup"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
baseURL = "https://api.coinmarketcap.com/v1"
|
|
||||||
coinGraphURL = "https://graphs2.coinmarketcap.com/currencies"
|
|
||||||
globalMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-total"
|
|
||||||
altcoinMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-altcoin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetGlobalMarketData get information about the global market data of the cryptocurrencies
|
|
||||||
func GetGlobalMarketData() (GlobalMarketData, error) {
|
|
||||||
url := fmt.Sprintf(baseURL + "/global/")
|
|
||||||
|
|
||||||
resp, err := makeReq(url)
|
|
||||||
|
|
||||||
var data GlobalMarketData
|
|
||||||
err = json.Unmarshal(resp, &data)
|
|
||||||
if err != nil {
|
|
||||||
return GlobalMarketData{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGlobalMarketGraphData get graph data points of global market
|
|
||||||
func GetGlobalMarketGraphData(start int64, end int64) (MarketGraph, error) {
|
|
||||||
url := fmt.Sprintf("%s/%d/%d", globalMarketGraphURL, start*1000, end*1000)
|
|
||||||
resp, err := makeReq(url)
|
|
||||||
if err != nil {
|
|
||||||
return MarketGraph{}, err
|
|
||||||
}
|
|
||||||
var data MarketGraph
|
|
||||||
err = json.Unmarshal(resp, &data)
|
|
||||||
if err != nil {
|
|
||||||
return MarketGraph{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAltcoinMarketGraphData get graph data points of altcoin market
|
|
||||||
func GetAltcoinMarketGraphData(start int64, end int64) (MarketGraph, error) {
|
|
||||||
url := fmt.Sprintf("%s/%d/%d", altcoinMarketGraphURL, start*1000, end*1000)
|
|
||||||
resp, err := makeReq(url)
|
|
||||||
if err != nil {
|
|
||||||
return MarketGraph{}, err
|
|
||||||
}
|
|
||||||
var data MarketGraph
|
|
||||||
err = json.Unmarshal(resp, &data)
|
|
||||||
if err != nil {
|
|
||||||
return MarketGraph{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCoinData get information about a crypto currency
|
|
||||||
func GetCoinData(coin string) (Coin, error) {
|
|
||||||
coin = strings.ToLower(coin)
|
|
||||||
url := fmt.Sprintf("%s/ticker/%s", baseURL, coin)
|
|
||||||
resp, err := makeReq(url)
|
|
||||||
if err != nil {
|
|
||||||
return Coin{}, err
|
|
||||||
}
|
|
||||||
var data []Coin
|
|
||||||
err = json.Unmarshal(resp, &data)
|
|
||||||
if err != nil {
|
|
||||||
return Coin{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return data[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAllCoinData get information about all coins listed in Coin Market Cap
|
|
||||||
func GetAllCoinData(limit int) (map[string]Coin, error) {
|
|
||||||
var l string
|
|
||||||
if limit >= 0 {
|
|
||||||
l = fmt.Sprintf("?limit=%v", limit)
|
|
||||||
}
|
|
||||||
url := fmt.Sprintf("%s/ticker/%s", baseURL, l)
|
|
||||||
|
|
||||||
resp, err := makeReq(url)
|
|
||||||
|
|
||||||
var data []Coin
|
|
||||||
err = json.Unmarshal(resp, &data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// creating map from the array
|
|
||||||
allCoins := make(map[string]Coin)
|
|
||||||
for i := 0; i < len(data); i++ {
|
|
||||||
allCoins[data[i].ID] = data[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return allCoins, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCoinGraphData get graph data points for a crypto currency
|
|
||||||
func GetCoinGraphData(coin string, start int64, end int64) (CoinGraph, error) {
|
|
||||||
url := fmt.Sprintf("%s/%s/%d/%d", coinGraphURL, strings.ToLower(coin), start*1000, end*1000)
|
|
||||||
resp, err := makeReq(url)
|
|
||||||
if err != nil {
|
|
||||||
return CoinGraph{}, err
|
|
||||||
}
|
|
||||||
var data CoinGraph
|
|
||||||
err = json.Unmarshal(resp, &data)
|
|
||||||
if err != nil {
|
|
||||||
return CoinGraph{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCoinPriceUSD get USD price of crypto currency
|
|
||||||
func GetCoinPriceUSD(coin string) (float64, error) {
|
|
||||||
data, err := GetCoinData(strings.ToLower(coin))
|
|
||||||
if err != nil {
|
|
||||||
return float64(0), nil
|
|
||||||
}
|
|
||||||
return data.PriceUSD, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCoinMarkets get market data for a coin name
|
|
||||||
func GetCoinMarkets(coin string) ([]Market, error) {
|
|
||||||
url := fmt.Sprintf("https://coinmarketcap.com/currencies/%s/#markets", strings.ToLower(coin))
|
|
||||||
var markets []Market
|
|
||||||
response, err := soup.Get(url)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rows := soup.HTMLParse(response).Find("table", "id", "markets-table").Find("tbody").FindAll("tr")
|
|
||||||
for _, row := range rows {
|
|
||||||
var data []string
|
|
||||||
for _, column := range row.FindAll("td") {
|
|
||||||
attrs := column.Attrs()
|
|
||||||
if attrs["data-sort"] != "" {
|
|
||||||
data = append(data, attrs["data-sort"])
|
|
||||||
} else {
|
|
||||||
data = append(data, column.Text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
markets = append(markets, Market{
|
|
||||||
Rank: toInt(data[0]),
|
|
||||||
Exchange: data[1],
|
|
||||||
Pair: data[2],
|
|
||||||
VolumeUSD: toFloat(data[3]),
|
|
||||||
Price: toFloat(data[4]),
|
|
||||||
VolumePercent: toFloat(data[5]),
|
|
||||||
Updated: data[6],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return markets, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// doReq HTTP client
|
|
||||||
func doReq(req *http.Request) ([]byte, error) {
|
|
||||||
client := &http.Client{}
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if 200 != resp.StatusCode {
|
|
||||||
return nil, fmt.Errorf("%s", body)
|
|
||||||
}
|
|
||||||
|
|
||||||
return body, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// makeReq HTTP request helper
|
|
||||||
func makeReq(url string) ([]byte, error) {
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp, err := doReq(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// toInt helper for parsing strings to int
|
|
||||||
func toInt(rawInt string) int {
|
|
||||||
parsed, _ := strconv.Atoi(strings.Replace(strings.Replace(rawInt, "$", "", -1), ",", "", -1))
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
|
|
||||||
// toFloat helper for parsing strings to float
|
|
||||||
func toFloat(rawFloat string) float64 {
|
|
||||||
parsed, _ := strconv.ParseFloat(strings.Replace(strings.Replace(strings.Replace(rawFloat, "$", "", -1), ",", "", -1), "%", "", -1), 64)
|
|
||||||
return parsed
|
|
||||||
}
|
|
@ -1,219 +0,0 @@
|
|||||||
package coinmarketcap
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestGetGlobalMarketData(t *testing.T) {
|
|
||||||
market, err := GetGlobalMarketData()
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if market.ActiveAssets == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.ActiveCurrencies == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.ActiveMarkets == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.BitcoinPercentageOfMarketCap == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.Total24HVolumeUSD == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.TotalMarketCapUSD == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetGlobalMarketGraphData(t *testing.T) {
|
|
||||||
var threeMonths int64 = (60 * 60 * 24 * 90)
|
|
||||||
end := time.Now().Unix()
|
|
||||||
start := end - threeMonths
|
|
||||||
|
|
||||||
graph, err := GetGlobalMarketGraphData(start, end)
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if graph.MarketCapByAvailableSupply[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if graph.VolumeUSD[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetAltcoinMarketGraphData(t *testing.T) {
|
|
||||||
var threeMonths int64 = (60 * 60 * 24 * 90)
|
|
||||||
end := time.Now().Unix()
|
|
||||||
start := end - threeMonths
|
|
||||||
|
|
||||||
graph, err := GetAltcoinMarketGraphData(start, end)
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if graph.MarketCapByAvailableSupply[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if graph.VolumeUSD[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCoinData(t *testing.T) {
|
|
||||||
coin, err := GetCoinData("ethereum")
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if coin.AvailableSupply == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.ID == "" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.LastUpdated == "" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.MarketCapUSD == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.Name == "" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.PercentChange1H == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.PercentChange24H == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.PercentChange7D == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.PriceBTC == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.PriceUSD == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.Rank == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.Symbol == "" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.TotalSupply == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if coin.USD24HVolume == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetAllCoinData(t *testing.T) {
|
|
||||||
coins, err := GetAllCoinData(10)
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(coins) != 10 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCoinGraphData(t *testing.T) {
|
|
||||||
var threeMonths int64 = (60 * 60 * 24 * 90)
|
|
||||||
end := time.Now().Unix()
|
|
||||||
start := end - threeMonths
|
|
||||||
|
|
||||||
graph, err := GetCoinGraphData("ethereum", start, end)
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
if graph.MarketCapByAvailableSupply[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if graph.PriceBTC[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if graph.PriceUSD[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if graph.VolumeUSD[0][0] == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCoinPriceUSD(t *testing.T) {
|
|
||||||
price, err := GetCoinPriceUSD("ethereum")
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if price <= 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetCoinMarkets(t *testing.T) {
|
|
||||||
markets, err := GetCoinMarkets("ethereum")
|
|
||||||
if err != nil {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if len(markets) == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
market := markets[0]
|
|
||||||
if market.Rank == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.Exchange == "" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.Pair == "" {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.VolumeUSD == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.Price == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.VolumePercent == 0 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
if market.Updated == "" {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDoReq(t *testing.T) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMakeReq(t *testing.T) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToInt(t *testing.T) {
|
|
||||||
v := toInt("5")
|
|
||||||
if v != 5 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestToFloat(t *testing.T) {
|
|
||||||
v := toFloat("5.2")
|
|
||||||
if v != 5.2 {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
cmc "github.com/miguelmota/go-coinmarketcap"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// get data for all coins
|
|
||||||
coins, err := cmc.GetAllCoinData(0)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, coin := range coins {
|
|
||||||
fmt.Println(coin.Symbol, coin.PriceUSD)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
cmc "github.com/miguelmota/go-coinmarketcap"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get info about coin
|
|
||||||
coinInfo, err := cmc.GetCoinData("ethereum")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(coinInfo)
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
cmc "github.com/miguelmota/go-coinmarketcap"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
threeMonths := int64(60 * 60 * 24 * 90)
|
|
||||||
now := time.Now()
|
|
||||||
secs := now.Unix()
|
|
||||||
start := secs - threeMonths
|
|
||||||
end := secs
|
|
||||||
|
|
||||||
// Get graph data for coin
|
|
||||||
coinGraphData, err := cmc.GetCoinGraphData("ethereum", start, end)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(coinGraphData)
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
cmc "github.com/miguelmota/go-coinmarketcap"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Get global market data
|
|
||||||
marketInfo, err := cmc.GetGlobalMarketData()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(marketInfo)
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
package coinmarketcap
|
|
||||||
|
|
||||||
// Interface interface
|
|
||||||
type Interface interface {
|
|
||||||
GetGlobalMarketData() (GlobalMarketData, error)
|
|
||||||
GetGlobalMarketGraphData(start int64, end int64) (MarketGraph, error)
|
|
||||||
GetAltcoinMarketGraphData(start int64, end int64) (MarketGraph, error)
|
|
||||||
GetCoinData(coin string) (Coin, error)
|
|
||||||
GetAllCoinData(limit int) (map[string]Coin, error)
|
|
||||||
GetCoinGraphData(coin string, start int64, end int64) (CoinGraph, error)
|
|
||||||
GetCoinPriceUSD(coin string) (float64, error)
|
|
||||||
GetCoinMarkets(coin string) ([]Market, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coin struct
|
|
||||||
type Coin struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Symbol string `json:"symbol"`
|
|
||||||
Rank int `json:"rank,string"`
|
|
||||||
PriceUSD float64 `json:"price_usd,string"`
|
|
||||||
PriceBTC float64 `json:"price_btc,string"`
|
|
||||||
USD24HVolume float64 `json:"24h_volume_usd,string"`
|
|
||||||
MarketCapUSD float64 `json:"market_cap_usd,string"`
|
|
||||||
AvailableSupply float64 `json:"available_supply,string"`
|
|
||||||
TotalSupply float64 `json:"total_supply,string"`
|
|
||||||
PercentChange1H float64 `json:"percent_change_1h,string"`
|
|
||||||
PercentChange24H float64 `json:"percent_change_24h,string"`
|
|
||||||
PercentChange7D float64 `json:"percent_change_7d,string"`
|
|
||||||
LastUpdated string `json:"last_updated"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalMarketData struct
|
|
||||||
type GlobalMarketData struct {
|
|
||||||
TotalMarketCapUSD float64 `json:"total_market_cap_usd"`
|
|
||||||
Total24HVolumeUSD float64 `json:"total_24h_volume_usd"`
|
|
||||||
BitcoinPercentageOfMarketCap float64 `json:"bitcoin_percentage_of_market_cap"`
|
|
||||||
ActiveCurrencies int `json:"active_currencies"`
|
|
||||||
ActiveAssets int `json:"active_assets"`
|
|
||||||
ActiveMarkets int `json:"active_markets"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// CoinGraph struct
|
|
||||||
type CoinGraph struct {
|
|
||||||
MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"`
|
|
||||||
PriceBTC [][]float64 `json:"price_btc"`
|
|
||||||
PriceUSD [][]float64 `json:"price_usd"`
|
|
||||||
VolumeUSD [][]float64 `json:"volume_usd"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Market struct
|
|
||||||
type Market struct {
|
|
||||||
Rank int
|
|
||||||
Exchange string
|
|
||||||
Pair string
|
|
||||||
VolumeUSD float64
|
|
||||||
Price float64
|
|
||||||
VolumePercent float64
|
|
||||||
Updated string
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarketGraph struct
|
|
||||||
type MarketGraph struct {
|
|
||||||
MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"`
|
|
||||||
VolumeUSD [][]float64 `json:"volume_usd"`
|
|
||||||
}
|
|
Loading…
Reference in New Issue