mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-07 15:11:03 +00:00
* starting public endpoints * Adding public endpoints * added public spot market endpoints * websocket subscriptions updates * websocket push data handlers completing * linter fix * Added funding private endpoints * Adding authenticated account endpoints * Added fiat and OTC-RFQ authenticated endpoints * trading authenticated endpoints * completing trade endpoints and add public wrapper endpoints * Authenticated wrapper functions and corresponding unit test * Adding authenticated websocket endpoint and fixing wrapper functions * Documentation and exchange websocket update * update websocket orderbook checksum handling * linter issues fix and unit test update * remove invalid orderbook endpoint and unit test * Documentation, handlers, and model types update * minot fix * Minor fixes * Updating unit tests and added missing endpoints * Add missing credential check * Minor unit test fixes * fix minor linter issue * add snaphot test unit test * Fix on update checksum and documentation update * update exchange, add UpdateOrderExecutionLimits, and update documentation * Minor fix on tickers fetching * Minor websocket fix and smaill unit tests * Minor websocket and naming fixes * uncomment default channels * Fix type and unit test issues * websocket channels and data handling update * Update Advanced-Algo websocket handling and minor fixes * documentation and minor code fixes * Fix name changes * documentation contribution update * intervalToString method update * fix exchange_wrapper_standard tests * Fix minor issues based on exchange_wrapper_standards_test * Fix wrapper extended candlestick check * websocket orders fetching error check method update * Exchange name check and change * docs: Add missing contributors --------- Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
184 lines
5.6 KiB
Go
184 lines
5.6 KiB
Go
package okcoin
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"strconv"
|
|
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
|
|
)
|
|
|
|
// WsPlaceOrder place trade order through the websocket channel.
|
|
func (o *Okcoin) WsPlaceOrder(arg *PlaceTradeOrderParam) (*TradeOrderResponse, error) {
|
|
err := arg.validateTradeOrderParameter()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp []TradeOrderResponse
|
|
err = o.SendWebsocketRequest("order", arg, &resp, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(resp) == 0 {
|
|
return nil, errNoValidResponseFromServer
|
|
}
|
|
if resp[0].SCode != "0" {
|
|
return nil, fmt.Errorf("code: %s msg: %s", resp[0].SCode, resp[0].SMsg)
|
|
}
|
|
return &resp[0], nil
|
|
}
|
|
|
|
// WsPlaceMultipleOrder place orders in batches through the websocket stream. Maximum 20 orders can be placed per request. Request parameters should be passed in the form of an array.
|
|
func (o *Okcoin) WsPlaceMultipleOrder(args []PlaceTradeOrderParam) ([]TradeOrderResponse, error) {
|
|
var err error
|
|
if len(args) == 0 {
|
|
return nil, fmt.Errorf("%w, 0 length place order requests", errNilArgument)
|
|
}
|
|
for x := range args {
|
|
err = args[x].validateTradeOrderParameter()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
var resp []TradeOrderResponse
|
|
return resp, o.SendWebsocketRequest("batch-orders", args, &resp, true)
|
|
}
|
|
|
|
// WsCancelTradeOrder cancels a single trade order through the websocket stream.
|
|
func (o *Okcoin) WsCancelTradeOrder(arg *CancelTradeOrderRequest) (*TradeOrderResponse, error) {
|
|
if arg == nil {
|
|
return nil, errNilArgument
|
|
}
|
|
if arg.InstrumentID == "" {
|
|
return nil, errMissingInstrumentID
|
|
}
|
|
if arg.OrderID == "" && arg.ClientOrderID == "" {
|
|
return nil, errOrderIDOrClientOrderIDRequired
|
|
}
|
|
var resp []TradeOrderResponse
|
|
err := o.SendWebsocketRequest("cancel-order", &arg, &resp, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(resp) == 0 {
|
|
return nil, errNoValidResponseFromServer
|
|
}
|
|
if resp[0].SCode != "0" {
|
|
return nil, fmt.Errorf("code: %s msg: %s", resp[0].SCode, resp[0].SMsg)
|
|
}
|
|
return &resp[0], nil
|
|
}
|
|
|
|
// WsCancelMultipleOrders cancel incomplete orders in batches through the websocket stream. Maximum 20 orders can be canceled per request.
|
|
// Request parameters should be passed in the form of an array.
|
|
func (o *Okcoin) WsCancelMultipleOrders(args []CancelTradeOrderRequest) ([]TradeOrderResponse, error) {
|
|
var err error
|
|
if len(args) == 0 {
|
|
return nil, fmt.Errorf("%w, 0 length place order requests", errNilArgument)
|
|
}
|
|
for x := range args {
|
|
err = args[x].validate()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
var resp []TradeOrderResponse
|
|
return resp, o.SendWebsocketRequest("batch-cancel-orders", args, &resp, true)
|
|
}
|
|
|
|
// WsAmendOrder amends an incomplete order through the websocket connection
|
|
func (o *Okcoin) WsAmendOrder(arg *AmendTradeOrderRequestParam) (*AmendTradeOrderResponse, error) {
|
|
err := arg.validate()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp []AmendTradeOrderResponse
|
|
err = o.SendWebsocketRequest("amend-order", &arg, &resp, true)
|
|
if err != nil {
|
|
if len(resp) > 0 && resp[0].StatusCode != "0" && resp[0].StatusCode != "" {
|
|
return nil, fmt.Errorf("%w, code: %s msg: %s", err, resp[0].StatusCode, resp[0].StatusMessage)
|
|
}
|
|
return nil, err
|
|
}
|
|
if len(resp) == 0 {
|
|
return nil, errNoValidResponseFromServer
|
|
}
|
|
if resp[0].StatusCode != "0" {
|
|
return nil, fmt.Errorf("code: %s msg: %s", resp[0].StatusCode, resp[0].StatusMessage)
|
|
}
|
|
return &resp[0], nil
|
|
}
|
|
|
|
// WsAmendMultipleOrder amends multiple trade orders.
|
|
func (o *Okcoin) WsAmendMultipleOrder(args []AmendTradeOrderRequestParam) ([]AmendTradeOrderResponse, error) {
|
|
if len(args) == 0 {
|
|
return nil, fmt.Errorf("%w, please provide at least one trade order amendment request", errNilArgument)
|
|
}
|
|
for x := range args {
|
|
err := args[x].validate()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
var resp []AmendTradeOrderResponse
|
|
return resp, o.SendWebsocketRequest("batch-amend-orders", args, &resp, true)
|
|
}
|
|
|
|
// SendWebsocketRequest send a request through the websocket connection.
|
|
func (o *Okcoin) SendWebsocketRequest(operation string, data, result interface{}, authenticated bool) error {
|
|
switch {
|
|
case !o.Websocket.IsEnabled():
|
|
return errors.New(stream.WebsocketNotEnabled)
|
|
case !o.Websocket.IsConnected():
|
|
return stream.ErrNotConnected
|
|
case !o.Websocket.CanUseAuthenticatedEndpoints() && authenticated:
|
|
return errors.New("websocket connection not authenticated")
|
|
}
|
|
req := &struct {
|
|
ID string `json:"id"`
|
|
Operation string `json:"op"`
|
|
Arguments interface{} `json:"args"`
|
|
}{
|
|
ID: strconv.FormatInt(o.Websocket.Conn.GenerateMessageID(false), 10),
|
|
Operation: operation,
|
|
}
|
|
if reflect.TypeOf(data).Kind() == reflect.Slice {
|
|
req.Arguments = data
|
|
} else {
|
|
req.Arguments = []interface{}{data}
|
|
}
|
|
var byteData []byte
|
|
var err error
|
|
// TODO: ratelimits for websocket
|
|
if authenticated {
|
|
byteData, err = o.Websocket.AuthConn.SendMessageReturnResponse(req.ID, req)
|
|
} else {
|
|
byteData, err = o.Websocket.Conn.SendMessageReturnResponse(req.ID, req)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
response := struct {
|
|
ID string `json:"id"`
|
|
Operation string `json:"op"`
|
|
Data interface{} `json:"data"`
|
|
Code string `json:"code"`
|
|
Message string `json:"msg"`
|
|
}{
|
|
Data: &result,
|
|
}
|
|
err = json.Unmarshal(byteData, &response)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if response.Code != "" && response.Code != "0" && response.Code != "1" && response.Code != "2" {
|
|
if response.Message == "" {
|
|
response.Message = websocketErrorCodes[response.Code]
|
|
}
|
|
return fmt.Errorf("%s websocket error code: %s message: %s", o.Name, response.Code, response.Message)
|
|
}
|
|
return nil
|
|
}
|