mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-20 07:26:46 +00:00
Poloniex: Implementation of GetOrderInfo method (#607)
* GetClosedOrder implemented for Kraken and Binance, fixed Binance MARKET order creaton, added rate, fee and cost fileds on SubmitOrder responce * return Trades on Binance SubmitOrder, new validation methods on Binance and kraken GetClosedOrderInfo * removed the Binance extra method GetClosedOrder * func description corrected * removed price, fee and cost from SimulateOrder response, as we get all necessary info in response to calculate them on client side * GetClosedOrder implementation moved to GetOrderInfo * changed GetOrderInfo params * removed Canceled order.Type used for Kraken * update QueryOrder in gctscript * add missed params to QueryOrder validator (gctscript) * fixed testing issues * GetClosedOrder implemented for Kraken and Binance, fixed Binance MARKET order creaton, added rate, fee and cost fileds on SubmitOrder responce * return Trades on Binance SubmitOrder, new validation methods on Binance and kraken GetClosedOrderInfo * removed the Binance extra method GetClosedOrder * func description corrected * removed price, fee and cost from SimulateOrder response, as we get all necessary info in response to calculate them on client side * GetClosedOrder implementation moved to GetOrderInfo * changed GetOrderInfo params * removed Canceled order.Type used for Kraken * update QueryOrder in gctscript * add missed params to QueryOrder validator (gctscript) * fixed testing issues * pull previous changes * linter issues fix * updated query_order exmple in gctscript, fixed params check * removed orderPair unnecessary conversion * added wsCancelAllOrders, fixed bugs * fixed Kraken wsAddOrder method * cleanup * CancelBatchOrders implementation * changed CancelBatchOrders signature * fixed tests and wrappers * btcmarkets_test fix * cleanup * cleanup * changed CancelBatchOrders signature * fmt * Update configtest.json * Update configtest.json * rollback configtest * refactored Kraken wsHandleData to allow tests * removed unnecessary error test in TestWsAddOrderJSON * dependencies updates * fixed issue with PortfolioSleepDelay set on startup * add GetWithdrawalsHistory method to exchanges interface * param name changes * add extra params for Binance WithdrawStatus method * add Binance TestWithdrawHistory * add GetOrderInfo on Poloniex * linter errors fix * switch interface type to avoid panic * Poloniex has no para errror in OrderbookResponse - removed, added seq param (incrementing sequence) for future use * linter issues fix * linter issues fix * dependencies update * add tests * refactored unmarshalling of GetAuthenticatedOrderStatus response * test fix * linter issues fix * unmarshaling logic moved to GetAuthenticatedOrderStatus * forced Status setting on GetAuthenticatedOrderStatus error * comment edited Co-authored-by: Vazha Bezhanishvili <vazha.bezhanishvili@elegro.eu>
This commit is contained in:
@@ -196,6 +196,7 @@ type TradeHistory struct {
|
||||
Timestamp time.Time
|
||||
IsMaker bool
|
||||
FeeAsset string
|
||||
Total float64
|
||||
}
|
||||
|
||||
// GetOrdersRequest used for GetOrderHistory and GetOpenOrders wrapper functions
|
||||
|
||||
@@ -29,6 +29,8 @@ const (
|
||||
poloniexDepositsWithdrawals = "returnDepositsWithdrawals"
|
||||
poloniexOrders = "returnOpenOrders"
|
||||
poloniexTradeHistory = "returnTradeHistory"
|
||||
poloniexOrderTrades = "returnOrderTrades"
|
||||
poloniexOrderStatus = "returnOrderStatus"
|
||||
poloniexOrderCancel = "cancelOrder"
|
||||
poloniexOrderMove = "moveOrder"
|
||||
poloniexWithdraw = "withdraw"
|
||||
@@ -418,6 +420,82 @@ func (p *Poloniex) GetAuthenticatedTradeHistory(start, end, limit int64) (Authen
|
||||
return mainResult, json.Unmarshal(result, &mainResult.Data)
|
||||
}
|
||||
|
||||
// GetAuthenticatedOrderStatus returns the status of a given orderId.
|
||||
func (p *Poloniex) GetAuthenticatedOrderStatus(orderID string) (o OrderStatusData, err error) {
|
||||
values := url.Values{}
|
||||
|
||||
if orderID == "" {
|
||||
return o, fmt.Errorf("no orderID passed")
|
||||
}
|
||||
|
||||
values.Set("orderNumber", orderID)
|
||||
var rawOrderStatus OrderStatus
|
||||
err = p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexOrderStatus, values, &rawOrderStatus)
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
|
||||
switch rawOrderStatus.Success {
|
||||
case 0: // fail
|
||||
var errMsg GenericResponse
|
||||
err = json.Unmarshal(rawOrderStatus.Result, &errMsg)
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
return o, fmt.Errorf(errMsg.Error)
|
||||
case 1: // success
|
||||
var status map[string]OrderStatusData
|
||||
err = json.Unmarshal(rawOrderStatus.Result, &status)
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
|
||||
for _, o = range status {
|
||||
return o, err
|
||||
}
|
||||
}
|
||||
|
||||
return o, err
|
||||
}
|
||||
|
||||
// GetAuthenticatedOrderTrades returns all trades involving a given orderId.
|
||||
func (p *Poloniex) GetAuthenticatedOrderTrades(orderID string) (o []OrderTrade, err error) {
|
||||
values := url.Values{}
|
||||
|
||||
if orderID == "" {
|
||||
return nil, fmt.Errorf("no orderId passed")
|
||||
}
|
||||
|
||||
values.Set("orderNumber", orderID)
|
||||
var result json.RawMessage
|
||||
err = p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexOrderTrades, values, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(result) == 0 {
|
||||
return nil, fmt.Errorf("received unexpected response")
|
||||
}
|
||||
|
||||
switch result[0] {
|
||||
case '{': // error message received
|
||||
var resp GenericResponse
|
||||
err = json.Unmarshal(result, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.Error != "" {
|
||||
err = fmt.Errorf(resp.Error)
|
||||
}
|
||||
case '[': // data received
|
||||
err = json.Unmarshal(result, &o)
|
||||
default:
|
||||
return nil, fmt.Errorf("received unexpected response")
|
||||
}
|
||||
|
||||
return o, err
|
||||
}
|
||||
|
||||
// PlaceOrder places a new order on the exchange
|
||||
func (p *Poloniex) PlaceOrder(currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) {
|
||||
result := OrderResponse{}
|
||||
|
||||
@@ -2,6 +2,7 @@ package poloniex
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -248,6 +249,109 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mock bool
|
||||
orderID string
|
||||
errExpected bool
|
||||
errMsgExpected string
|
||||
}{
|
||||
{
|
||||
name: "correct order ID",
|
||||
mock: true,
|
||||
orderID: "96238912841",
|
||||
errExpected: false,
|
||||
errMsgExpected: "",
|
||||
},
|
||||
{
|
||||
name: "wrong order ID",
|
||||
mock: true,
|
||||
orderID: "96238912842",
|
||||
errExpected: true,
|
||||
errMsgExpected: "Order not found",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.mock != mockTests {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := p.GetAuthenticatedOrderStatus(tt.orderID)
|
||||
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Errorf("Could not get order status: %s", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
if !tt.errExpected {
|
||||
t.Errorf("Could not mock get order status: %s", err.Error())
|
||||
} else if !(strings.Contains(err.Error(), tt.errMsgExpected)) {
|
||||
t.Errorf("Could not mock get order status: %s", err.Error())
|
||||
}
|
||||
case mockTests:
|
||||
if tt.errExpected {
|
||||
t.Errorf("Mock get order status expect an error '%s', get no error", tt.errMsgExpected)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mock bool
|
||||
orderID string
|
||||
errExpected bool
|
||||
errMsgExpected string
|
||||
}{
|
||||
{
|
||||
name: "correct order ID",
|
||||
mock: true,
|
||||
orderID: "96238912841",
|
||||
errExpected: false,
|
||||
errMsgExpected: "",
|
||||
},
|
||||
{
|
||||
name: "wrong order ID",
|
||||
mock: true,
|
||||
orderID: "96238912842",
|
||||
errExpected: true,
|
||||
errMsgExpected: "Order not found",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.mock != mockTests {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := p.GetAuthenticatedOrderTrades(tt.orderID)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Errorf("Could not get order trades: %s", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
if !(tt.errExpected && strings.Contains(err.Error(), tt.errMsgExpected)) {
|
||||
t.Errorf("Could not mock get order trades: %s", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
|
||||
// ----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package poloniex
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
@@ -36,6 +37,7 @@ type OrderbookResponse struct {
|
||||
Bids [][]interface{} `json:"bids"`
|
||||
IsFrozen string `json:"isFrozen"`
|
||||
Error string `json:"error"`
|
||||
Seq int64 `json:"seq"`
|
||||
}
|
||||
|
||||
// OrderbookItem holds data on an individual item
|
||||
@@ -66,6 +68,39 @@ type TradeHistory struct {
|
||||
Total float64 `json:"total,string"`
|
||||
}
|
||||
|
||||
// OrderStatus holds order status data
|
||||
type OrderStatus struct {
|
||||
Result json.RawMessage `json:"result"`
|
||||
Success int64 `json:"success"`
|
||||
}
|
||||
|
||||
// OrderStatusData defines order status details
|
||||
type OrderStatusData struct {
|
||||
Pair string `json:"currencyPair"`
|
||||
Rate float64 `json:"rate,string"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Total float64 `json:"total,string"`
|
||||
StartingAmount float64 `json:"startingAmount,string"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Date string `json:"date"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
}
|
||||
|
||||
// OrderTrade holds order trade data
|
||||
type OrderTrade struct {
|
||||
Status string `json:"status"`
|
||||
GlobalTradeID int64 `json:"globalTradeID"`
|
||||
TradeID int64 `json:"tradeID"`
|
||||
CurrencyPair string `json:"currencyPair"`
|
||||
Type string `json:"type"`
|
||||
Rate float64 `json:"rate,string"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Total float64 `json:"total,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Date string `json:"date"`
|
||||
}
|
||||
|
||||
// ChartData holds kline data
|
||||
type ChartData struct {
|
||||
Date int64 `json:"date"`
|
||||
|
||||
@@ -589,8 +589,64 @@ func (p *Poloniex) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, er
|
||||
|
||||
// GetOrderInfo returns order information based on order ID
|
||||
func (p *Poloniex) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) {
|
||||
var orderDetail order.Detail
|
||||
return orderDetail, common.ErrNotYetImplemented
|
||||
orderInfo := order.Detail{
|
||||
Exchange: p.Name,
|
||||
Pair: pair,
|
||||
}
|
||||
|
||||
trades, err := p.GetAuthenticatedOrderTrades(orderID)
|
||||
if err != nil && !strings.Contains(err.Error(), "Order not found") {
|
||||
return orderInfo, err
|
||||
}
|
||||
|
||||
for i := range trades {
|
||||
var tradeHistory order.TradeHistory
|
||||
tradeHistory.Exchange = p.Name
|
||||
tradeHistory.Side, err = order.StringToOrderSide(trades[i].Type)
|
||||
if err != nil {
|
||||
return orderInfo, err
|
||||
}
|
||||
tradeHistory.TID = strconv.FormatInt(trades[i].GlobalTradeID, 10)
|
||||
tradeHistory.Timestamp, err = time.Parse(common.SimpleTimeFormat, trades[i].Date)
|
||||
if err != nil {
|
||||
return orderInfo, err
|
||||
}
|
||||
tradeHistory.Price = trades[i].Rate
|
||||
tradeHistory.Amount = trades[i].Amount
|
||||
tradeHistory.Total = trades[i].Total
|
||||
tradeHistory.Fee = trades[i].Fee
|
||||
orderInfo.Trades = append(orderInfo.Trades, tradeHistory)
|
||||
}
|
||||
|
||||
resp, err := p.GetAuthenticatedOrderStatus(orderID)
|
||||
if err != nil {
|
||||
if len(orderInfo.Trades) > 0 { // on closed orders return trades only
|
||||
if strings.Contains(err.Error(), "Order not found") {
|
||||
orderInfo.Status = order.Closed
|
||||
}
|
||||
return orderInfo, nil
|
||||
}
|
||||
return orderInfo, err
|
||||
}
|
||||
|
||||
orderInfo.Status, _ = order.StringToOrderStatus(resp.Status)
|
||||
orderInfo.Price = resp.Rate
|
||||
orderInfo.Amount = resp.Amount
|
||||
orderInfo.Cost = resp.Total
|
||||
orderInfo.Fee = resp.Fee
|
||||
orderInfo.TargetAmount = resp.StartingAmount
|
||||
|
||||
orderInfo.Side, err = order.StringToOrderSide(resp.Type)
|
||||
if err != nil {
|
||||
return orderInfo, err
|
||||
}
|
||||
|
||||
orderInfo.Date, err = time.Parse(common.SimpleTimeFormat, resp.Date)
|
||||
if err != nil {
|
||||
return orderInfo, err
|
||||
}
|
||||
|
||||
return orderInfo, nil
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
|
||||
Reference in New Issue
Block a user