github.com/bitfinexcom/bitfinex-api-go@v0.0.0-20210608095005-9e0b26f200fb/v1/orders.go (about)

     1  package bitfinex
     2  
     3  import (
     4  	"math"
     5  	"strconv"
     6  )
     7  
     8  // Order types that the API can return.
     9  const (
    10  	OrderTypeMarket               = "market"
    11  	OrderTypeLimit                = "limit"
    12  	OrderTypeStop                 = "stop"
    13  	OrderTypeTrailingStop         = "trailing-stop"
    14  	OrderTypeFillOrKill           = "fill-or-kill"
    15  	OrderTypeExchangeMarket       = "exchange market"
    16  	OrderTypeExchangeLimit        = "exchange limit"
    17  	OrderTypeExchangeStop         = "exchange stop"
    18  	OrderTypeExchangeTrailingStop = "exchange trailing-stop"
    19  	OrderTypeExchangeFillOrKill   = "exchange fill-or-kill"
    20  )
    21  
    22  // OrderService manages the Order endpoint.
    23  type OrderService struct {
    24  	client *Client
    25  }
    26  
    27  // Order represents one order on the bitfinex platform.
    28  type Order struct {
    29  	ID                int64
    30  	Symbol            string
    31  	Exchange          string
    32  	Price             string
    33  	AvgExecutionPrice string `json:"avg_execution_price"`
    34  	Side              string
    35  	Type              string
    36  	Timestamp         string
    37  	IsLive            bool   `json:"is_live"`
    38  	IsCanceled        bool   `json:"is_cancelled"`
    39  	IsHidden          bool   `json:"is_hidden"`
    40  	WasForced         bool   `json:"was_forced"`
    41  	OriginalAmount    string `json:"original_amount"`
    42  	RemainingAmount   string `json:"remaining_amount"`
    43  	ExecutedAmount    string `json:"executed_amount"`
    44  }
    45  
    46  // All returns all orders for the authenticated account.
    47  func (s *OrderService) All() ([]Order, error) {
    48  	req, err := s.client.newAuthenticatedRequest("GET", "orders", nil)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	v := []Order{}
    54  	_, err = s.client.do(req, &v)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	return v, nil
    60  }
    61  
    62  // CancelAll active orders for the authenticated account.
    63  func (s *OrderService) CancelAll() error {
    64  	req, err := s.client.newAuthenticatedRequest("POST", "order/cancel/all", nil)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	_, err = s.client.do(req, nil)
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	return nil
    75  }
    76  
    77  // Create a new order.
    78  func (s *OrderService) Create(symbol string, amount float64, price float64, orderType string) (*Order, error) {
    79  	var side string
    80  	if amount < 0 {
    81  		amount = math.Abs(amount)
    82  		side = "sell"
    83  	} else {
    84  		side = "buy"
    85  	}
    86  
    87  	payload := map[string]interface{}{
    88  		"symbol":   symbol,
    89  		"amount":   strconv.FormatFloat(amount, 'f', -1, 32),
    90  		"price":    strconv.FormatFloat(price, 'f', -1, 32),
    91  		"side":     side,
    92  		"type":     orderType,
    93  		"exchange": "bitfinex",
    94  	}
    95  
    96  	req, err := s.client.newAuthenticatedRequest("POST", "order/new", payload)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	order := new(Order)
   102  	_, err = s.client.do(req, order)
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  
   107  	return order, nil
   108  }
   109  
   110  // Cancel the order with id `orderID`.
   111  func (s *OrderService) Cancel(orderID int64) error {
   112  	payload := map[string]interface{}{
   113  		"order_id": orderID,
   114  	}
   115  
   116  	req, err := s.client.newAuthenticatedRequest("POST", "order/cancel", payload)
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	_, err = s.client.do(req, nil)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	return nil
   127  }
   128  
   129  // SubmitOrder is an order to be created on the bitfinex platform.
   130  type SubmitOrder struct {
   131  	Symbol string
   132  	Amount float64
   133  	Price  float64
   134  	Type   string
   135  }
   136  
   137  // MultipleOrderResponse bundles orders returned by the CreateMulti method.
   138  type MultipleOrderResponse struct {
   139  	Orders []Order `json:"order_ids"`
   140  	Status string
   141  }
   142  
   143  // CreateMulti allows batch creation of orders.
   144  func (s *OrderService) CreateMulti(orders []SubmitOrder) (MultipleOrderResponse, error) {
   145  	ordersMap := make([]interface{}, 0)
   146  	for _, order := range orders {
   147  		var side string
   148  		if order.Amount < 0 {
   149  			order.Amount = math.Abs(order.Amount)
   150  			side = "sell"
   151  		} else {
   152  			side = "buy"
   153  		}
   154  		ordersMap = append(ordersMap, map[string]interface{}{
   155  			"symbol":   order.Symbol,
   156  			"amount":   strconv.FormatFloat(order.Amount, 'f', -1, 32),
   157  			"price":    strconv.FormatFloat(order.Price, 'f', -1, 32),
   158  			"exchange": "bitfinex",
   159  			"side":     side,
   160  			"type":     order.Type,
   161  		})
   162  	}
   163  
   164  	payload := map[string]interface{}{
   165  		"orders": ordersMap,
   166  	}
   167  
   168  	req, err := s.client.newAuthenticatedRequest("POST", "order/new/multi", payload)
   169  	if err != nil {
   170  		return MultipleOrderResponse{}, err
   171  	}
   172  
   173  	response := new(MultipleOrderResponse)
   174  	_, err = s.client.do(req, response)
   175  
   176  	return *response, err
   177  
   178  }
   179  
   180  // CancelMulti allows batch cancellation of orders.
   181  func (s *OrderService) CancelMulti(orderIDS []int64) (string, error) {
   182  	payload := map[string]interface{}{
   183  		"order_ids": orderIDS,
   184  	}
   185  
   186  	req, err := s.client.newAuthenticatedRequest("POST", "order/cancel/multi", payload)
   187  
   188  	if err != nil {
   189  		return "", err
   190  	}
   191  
   192  	response := make(map[string]string)
   193  	_, err = s.client.do(req, &response)
   194  
   195  	return response["result"], err
   196  }
   197  
   198  // Replace an Order
   199  func (s *OrderService) Replace(orderID int64, useRemaining bool, newOrder SubmitOrder) (Order, error) {
   200  	var side string
   201  	if newOrder.Amount < 0 {
   202  		newOrder.Amount = math.Abs(newOrder.Amount)
   203  		side = "sell"
   204  	} else {
   205  		side = "buy"
   206  	}
   207  
   208  	payload := map[string]interface{}{
   209  		"order_id":      strconv.FormatInt(orderID, 10),
   210  		"symbol":        newOrder.Symbol,
   211  		"amount":        strconv.FormatFloat(newOrder.Amount, 'f', -1, 32),
   212  		"price":         strconv.FormatFloat(newOrder.Price, 'f', -1, 32),
   213  		"exchange":      "bitfinex",
   214  		"side":          side,
   215  		"type":          newOrder.Type,
   216  		"use_remaining": useRemaining,
   217  	}
   218  
   219  	req, err := s.client.newAuthenticatedRequest("POST", "order/cancel/replace", payload)
   220  	if err != nil {
   221  		return Order{}, err
   222  	}
   223  
   224  	order := new(Order)
   225  	_, err = s.client.do(req, order)
   226  	if err != nil {
   227  		return *order, err
   228  	}
   229  
   230  	return *order, nil
   231  }
   232  
   233  // Status retrieves the given order from the API.
   234  func (s *OrderService) Status(orderID int64) (Order, error) {
   235  
   236  	payload := map[string]interface{}{
   237  		"order_id": orderID,
   238  	}
   239  
   240  	req, err := s.client.newAuthenticatedRequest("POST", "order/status", payload)
   241  
   242  	if err != nil {
   243  		return Order{}, err
   244  	}
   245  
   246  	order := new(Order)
   247  	_, err = s.client.do(req, order)
   248  	if err != nil {
   249  		return *order, err
   250  	}
   251  
   252  	return *order, nil
   253  }