Skip to content

Commit

Permalink
Add GetExchangeStatus()
Browse files Browse the repository at this point in the history
  • Loading branch information
nao1215 committed Aug 3, 2024
1 parent 037d90b commit 51520cf
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ If you want to execute the Private API, you need to create a client with the API
| GET /api/order_books | [GetOrderBooks()](https://pkg.go.dev/github.com/nao1215/coincheck#Client.GetOrderBooks) | Fetch order book information. |
| GET /api/exchange/orders/rate | [GetExchangeOrdersRate()](https://pkg.go.dev/github.com/nao1215/coincheck#Client.GetExchangeOrdersRate) | To calculate the rate from the order of the exchange. |
| GET /api/rate/[pair] | [GetRate()](https://pkg.go.dev/github.com/nao1215/coincheck#Client.GetRate) | Get the Standard Rate of Coin. |
| GET /api/exchange_status | [GetExchangeStatus()](https://pkg.go.dev/github.com/nao1215/coincheck#Client.GetExchangeStatus) | Retrieving the status of the exchange. |

### Private API

Expand Down
84 changes: 84 additions & 0 deletions exchange.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package coincheck

import (
"context"
"net/http"
)

// GetExchangeStatusInput represents the input parameter for the GetExchangeStatus method.
type GetExchangeStatusInput struct {
// Pair represents the pair of the currency.
// If pair is not specified, information on all tradable pairs is returned.
// If pair is specified, information is returned only for that particular currency.
Pair *Pair
}

// GetExchangeStatusResponse represents the output from the GetExchangeStatus method.
type GetExchangeStatusResponse struct {
ExchangeStatus []ExchangeStatus `json:"exchange_status"`
}

// ExchangeStatus represents the exchange status.
type ExchangeStatus struct {
// Pair is the pair of the currency.
Pair Pair `json:"pair"`
// Status is the exchange status (available, itayose, stop).
Status ExchangeStatusAvailability `json:"status"`
// Timestamp is the time of the status.
Timestamp float64 `json:"timestamp"`
// Availability response whether limit orders ( order ), market orders ( market_order ), or cancel orders ( cancel ) can be placed.
Availability Availability `json:"availability"`
}

// ExchangeStatusAvailability represents the availability of the exchange.
type ExchangeStatusAvailability string

const (
// ExchangeStatusAvailabilityAvailable means the availability of available.
ExchangeStatusAvailabilityAvailable ExchangeStatusAvailability = "available"
// ExchangeStatusAvailabilityItayose is the availability of itayose.
// Itayose (Itayose method) is a method of determining the transaction price
// before orders (bids) are executed by recording them on an order book called "ita."
// Following the price priority principle, market orders are given priority first.
// Then, orders are matched starting from the lowest sell orders and highest buy orders.
// When the quantities of buy and sell orders match, a trade is executed at that price.
ExchangeStatusAvailabilityItayose ExchangeStatusAvailability = "itayose"
// ExchangeStatusAvailabilityStop is the availability of stop.
ExchangeStatusAvailabilityStop ExchangeStatusAvailability = "stop"
)

// Availability represents the availability of the exchange.
type Availability struct {
// Order is the availability of limit orders.
Order bool `json:"order"`
// MarketOrder is the availability of market orders.
MarketOrder bool `json:"market_order"`
// Cancel is the availability of cancel orders.
Cancel bool `json:"cancel"`
}

// GetExchangeStatus get retrieving the status of the exchange.
// API: GET /api/exchange_status
// Visibility: Public
// If GetExchangeStatusInput.Pair is not specified, information on all tradable pairs is returned.
func (c *Client) GetExchangeStatus(ctx context.Context, input GetExchangeStatusInput) (*GetExchangeStatusResponse, error) {
queryParam := map[string]string{}
if input.Pair != nil {
queryParam["pair"] = input.Pair.String()
}

req, err := c.createRequest(ctx, createRequestInput{
method: http.MethodGet,
path: "/api/exchange_status",
queryParam: queryParam,
})
if err != nil {
return nil, err
}

var output GetExchangeStatusResponse
if err := c.do(req, &output); err != nil {
return nil, err
}
return &output, nil
}
175 changes: 175 additions & 0 deletions exchange_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package coincheck

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/shogo82148/pointer"
)

func TestClient_GetExchangeStatus(t *testing.T) {
t.Run("GetExchangeStatus returns the all exchange status", func(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
wantMethod := http.MethodGet
if got := r.Method; got != wantMethod {
t.Errorf("Method: got %v, want %v", got, wantMethod)
}

wantEndpoint := "/api/exchange_status"
if got := r.URL.Path; got != wantEndpoint {
t.Errorf("Endpoint: got %v, want %v", got, wantEndpoint)
}

result := GetExchangeStatusResponse{
ExchangeStatus: []ExchangeStatus{
{
Pair: PairBTCJPY,
Status: ExchangeStatusAvailabilityAvailable,
Timestamp: 1609459200,
Availability: Availability{
Order: true,
MarketOrder: true,
Cancel: true,
},
},
{
Pair: PairBrilJPY,
Status: ExchangeStatusAvailabilityItayose,
Timestamp: 1609459200,
Availability: Availability{
Order: false,
MarketOrder: false,
Cancel: false,
},
},
},
}
if err := json.NewEncoder(w).Encode(result); err != nil {
t.Fatal(err)
}
}))

client, err := NewClient(WithBaseURL(testServer.URL))
if err != nil {
t.Fatal(err)
}

got, err := client.GetExchangeStatus(context.Background(), GetExchangeStatusInput{})
if err != nil {
t.Fatal(err)
}
want := &GetExchangeStatusResponse{
ExchangeStatus: []ExchangeStatus{
{
Pair: PairBTCJPY,
Status: ExchangeStatusAvailabilityAvailable,
Timestamp: 1609459200,
Availability: Availability{
Order: true,
MarketOrder: true,
Cancel: true,
},
},
{
Pair: PairBrilJPY,
Status: ExchangeStatusAvailabilityItayose,
Timestamp: 1609459200,
Availability: Availability{
Order: false,
MarketOrder: false,
Cancel: false,
},
},
},
}
if diff := cmp.Diff(want, got); diff != "" {
printDiff(t, diff)
}
})

t.Run("If pair is PairETCJPY, GetExchangeStatus returns the exchange status of PairETCJPY", func(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
wantMethod := http.MethodGet
if got := r.Method; got != wantMethod {
t.Errorf("Method: got %v, want %v", got, wantMethod)
}

wantEndpoint := "/api/exchange_status"
if got := r.URL.Path; got != wantEndpoint {
t.Errorf("Endpoint: got %v, want %v", got, wantEndpoint)
}

wantPair := PairETCJPY
if got := r.URL.Query().Get("pair"); got != wantPair.String() {
t.Errorf("Pair: got %v, want %v", got, wantPair)
}

result := GetExchangeStatusResponse{
ExchangeStatus: []ExchangeStatus{
{
Pair: PairETCJPY,
Status: ExchangeStatusAvailabilityAvailable,
Timestamp: 1609459200,
Availability: Availability{
Order: true,
MarketOrder: true,
Cancel: true,
},
},
},
}
if err := json.NewEncoder(w).Encode(result); err != nil {
t.Fatal(err)
}
}))

client, err := NewClient(WithBaseURL(testServer.URL))
if err != nil {
t.Fatal(err)
}

got, err := client.GetExchangeStatus(context.Background(), GetExchangeStatusInput{
Pair: pointer.Ptr(PairETCJPY),
})
if err != nil {
t.Fatal(err)
}
want := &GetExchangeStatusResponse{
ExchangeStatus: []ExchangeStatus{
{
Pair: PairETCJPY,
Status: ExchangeStatusAvailabilityAvailable,
Timestamp: 1609459200,
Availability: Availability{
Order: true,
MarketOrder: true,
Cancel: true,
},
},
},
}
if diff := cmp.Diff(want, got); diff != "" {
printDiff(t, diff)
}
})

t.Run("GetExchangeStatus returns an error", func(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer testServer.Close()

client, err := NewClient(WithBaseURL(testServer.URL))
if err != nil {
t.Fatal(err)
}

if _, err = client.GetExchangeStatus(context.Background(), GetExchangeStatusInput{}); err == nil {
t.Error("want error, but got nil")
}
})
}

0 comments on commit 51520cf

Please sign in to comment.