-
Notifications
You must be signed in to change notification settings - Fork 76
/
gateio.go
171 lines (140 loc) · 3.98 KB
/
gateio.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Package gateio gate.io rest api package
package gateio
import (
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"path"
"strings"
"github.com/Akagi201/cryptotrader/model"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
)
const (
RestHost = "data.gate.io"
ApiVer = "api2/1"
)
// Client OkEx client
type Client struct {
URL url.URL
HTTPClient *http.Client
AccessKey string
SecretKey string
}
// New creates a new OkEx Client
func New(accessKey string, secretKey string) *Client {
u := url.URL{
Scheme: "http",
Host: RestHost,
Path: "/",
}
c := Client{
URL: u,
HTTPClient: &http.Client{},
AccessKey: accessKey,
SecretKey: secretKey,
}
return &c
}
func (c *Client) newRequest(ctx context.Context, method string, spath string, values url.Values, body io.Reader) (*http.Request, error) {
u := c.URL
u.Path = path.Join(c.URL.Path, ApiVer, spath)
u.RawQuery = values.Encode()
log.Debugf("Request URL: %#v", u.String())
req, err := http.NewRequest(method, u.String(), body)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
return req, nil
}
func (c *Client) getResponse(req *http.Request) ([]byte, error) {
res, err := c.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
body, _ := ioutil.ReadAll(res.Body)
log.Errorf("body: %v", string(body))
return nil, errors.New(fmt.Sprintf("status code: %d", res.StatusCode))
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return body, nil
}
// GetPairs 返回所有系统支持的交易对, for http://data.gate.io/api2/1/pairs
func (c *Client) GetPairs(ctx context.Context) ([]string, error) {
req, err := c.newRequest(ctx, "GET", "pairs", nil, nil)
if err != nil {
return nil, err
}
body, err := c.getResponse(req)
if err != nil {
return nil, err
}
log.Debugf("Response body: %v", string(body))
var pairs []string
for _, v := range gjson.ParseBytes(body).Array() {
pairs = append(pairs, v.String())
}
return pairs, nil
}
// GetMarketInfo 交易市场订单参数, 返回所有系统支持的交易市场的参数信息,包括交易费,最小下单量,价格精度等。for http://data.gate.io/api2/1/marketinfo
func (c *Client) GetMarketInfo(ctx context.Context) ([]model.MarketInfo, error) {
req, err := c.newRequest(ctx, "GET", "marketinfo", nil, nil)
if err != nil {
return nil, err
}
body, err := c.getResponse(req)
if err != nil {
return nil, err
}
log.Debugf("Response body: %v", string(body))
var marketInfos []model.MarketInfo
var marketInfo model.MarketInfo
for _, v := range gjson.GetBytes(body, "pairs").Array() {
v.ForEach(func(key, value gjson.Result) bool {
marketInfo.Symbol = key.String()
marketInfo.DecimalPlaces = value.Get("decimal_places").Int()
marketInfo.MinAmount = value.Get("min_amount").Float()
marketInfo.Fee = value.Get("fee").Float()
marketInfos = append(marketInfos, marketInfo)
return true // keep iterating
})
}
return marketInfos, nil
}
// GetTicker 返回最新, 最高, 最低 交易行情和交易量, 每 10 秒钟更新, for http://data.gate.io/api2/1/ticker/[quote]_[base]
func (c *Client) GetTicker(ctx context.Context, quote string, base string) (*model.Ticker, error) {
req, err := c.newRequest(ctx, "GET", "ticker/"+strings.ToUpper(quote)+"_"+strings.ToUpper(base), nil, nil)
if err != nil {
return nil, err
}
body, err := c.getResponse(req)
if err != nil {
return nil, err
}
log.Debugf("Response body: %v", string(body))
buy := gjson.GetBytes(body, "highestBid").Float()
sell := gjson.GetBytes(body, "lowestAsk").Float()
last := gjson.GetBytes(body, "last").Float()
low := gjson.GetBytes(body, "low24hr").Float()
high := gjson.GetBytes(body, "high24hr").Float()
vol := gjson.GetBytes(body, "baseVolume").Float()
return &model.Ticker{
Buy: buy,
Sell: sell,
Last: last,
Low: low,
High: high,
Vol: vol,
Raw: string(body),
}, nil
}