diff --git a/exchanges/alphapoint/alphapoint_test.go b/exchanges/alphapoint/alphapoint_test.go index a69ef9cd..dc264c6d 100644 --- a/exchanges/alphapoint/alphapoint_test.go +++ b/exchanges/alphapoint/alphapoint_test.go @@ -577,3 +577,13 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + a := &Alphapoint{} + a.SetDefaults() + + _, err := a.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/alphapoint/alphapoint_wrapper.go b/exchanges/alphapoint/alphapoint_wrapper.go index eaff8af9..e14cc136 100644 --- a/exchanges/alphapoint/alphapoint_wrapper.go +++ b/exchanges/alphapoint/alphapoint_wrapper.go @@ -125,9 +125,8 @@ func (a *Alphapoint) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, o // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (a *Alphapoint) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - // return a.ModifyExistingOrder(p.Pair().String(), orderID, action) - return 0, common.ErrNotYetImplemented +func (a *Alphapoint) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrNotYetImplemented } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/anx/anx_test.go b/exchanges/anx/anx_test.go index b373d5d0..2fe52732 100644 --- a/exchanges/anx/anx_test.go +++ b/exchanges/anx/anx_test.go @@ -326,3 +326,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := a.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/anx/anx_wrapper.go b/exchanges/anx/anx_wrapper.go index 7ed42668..13710a73 100644 --- a/exchanges/anx/anx_wrapper.go +++ b/exchanges/anx/anx_wrapper.go @@ -257,8 +257,8 @@ func (a *ANX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTyp // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (a *ANX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (a *ANX) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/binance/binance_test.go b/exchanges/binance/binance_test.go index d93d75c7..1388cdf9 100644 --- a/exchanges/binance/binance_test.go +++ b/exchanges/binance/binance_test.go @@ -430,3 +430,10 @@ func TestGetAccountInfo(t *testing.T) { t.Error("test failed - GetAccountInfo() error:", err) } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index 592cf0ab..a9a46775 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -26,9 +26,15 @@ func (b *Binance) Start(wg *sync.WaitGroup) { // Run implements the OKEX wrapper func (b *Binance) Run() { if b.Verbose { - log.Printf("%s Websocket: %s. (url: %s).\n", b.GetName(), common.IsEnabled(b.Websocket.IsEnabled()), b.Websocket.GetWebsocketURL()) - log.Printf("%s polling delay: %ds.\n", b.GetName(), b.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs) + log.Printf("%s Websocket: %s. (url: %s).\n%s polling delay: %ds.\n%s %d currencies enabled: %s.\n", + b.GetName(), + common.IsEnabled(b.Websocket.IsEnabled()), + b.Websocket.GetWebsocketURL(), + b.GetName(), + b.RESTPollingDelay, + b.GetName(), + len(b.EnabledPairs), + b.EnabledPairs) } symbols, err := b.GetExchangeValidCurrencyPairs() @@ -60,7 +66,6 @@ func (b *Binance) Run() { // UpdateTicker updates and returns the ticker for a currency pair func (b *Binance) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) { var tickerPrice ticker.Price - tick, err := b.GetTickers() if err != nil { return tickerPrice, err @@ -154,7 +159,6 @@ func (b *Binance) GetAccountInfo() (exchange.AccountInfo, error) { info.ExchangeName = b.GetName() info.Currencies = currencyBalance - return info, nil } @@ -168,7 +172,6 @@ func (b *Binance) GetFundingHistory() ([]exchange.FundHistory, error) { // GetExchangeHistory returns historic trade data since exchange opening. func (b *Binance) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) { var resp []exchange.TradeHistory - return resp, common.ErrNotYetImplemented } @@ -216,19 +219,20 @@ func (b *Binance) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Binance) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *Binance) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number func (b *Binance) CancelOrder(order exchange.OrderCancellation) error { orderIDInt, err := strconv.ParseInt(order.OrderID, 10, 64) - if err != nil { return err } - _, err = b.CancelExistingOrder(exchange.FormatExchangeCurrency(b.Name, order.CurrencyPair).String(), orderIDInt, order.AccountID) + _, err = b.CancelExistingOrder(exchange.FormatExchangeCurrency(b.Name, order.CurrencyPair).String(), + orderIDInt, + order.AccountID) return err } diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index 1fd6ae19..bf9f4a4b 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -806,3 +806,10 @@ func TestCancelAllExchangeOrdera(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index 771a4390..8bf37569 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -198,8 +198,8 @@ func (b *Bitfinex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, ord // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitfinex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *Bitfinex) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/bitflyer/bitflyer_test.go b/exchanges/bitflyer/bitflyer_test.go index 90b93a8e..e2e1d32d 100644 --- a/exchanges/bitflyer/bitflyer_test.go +++ b/exchanges/bitflyer/bitflyer_test.go @@ -334,3 +334,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/bitflyer/bitflyer_wrapper.go b/exchanges/bitflyer/bitflyer_wrapper.go index a9660b30..bcfdb9eb 100644 --- a/exchanges/bitflyer/bitflyer_wrapper.go +++ b/exchanges/bitflyer/bitflyer_wrapper.go @@ -161,8 +161,8 @@ func (b *Bitflyer) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, ord // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitflyer) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *Bitflyer) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/bithumb/bithumb.go b/exchanges/bithumb/bithumb.go index d816d8d3..b1a2db05 100644 --- a/exchanges/bithumb/bithumb.go +++ b/exchanges/bithumb/bithumb.go @@ -2,6 +2,7 @@ package bithumb import ( "bytes" + "encoding/json" "errors" "fmt" "log" @@ -247,15 +248,8 @@ func (b *Bithumb) GetAccountInformation(currency string) (Account, error) { val.Set("currency", currency) } - err := b.SendAuthenticatedHTTPRequest(privateAccInfo, val, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateAccInfo, val, &response) } // GetAccountBalance returns customer wallet information @@ -279,10 +273,6 @@ func (b *Bithumb) GetAccountBalance(c string) (FullBalance, error) { return fullBalance, err } - if response.Status != noError { - return fullBalance, errors.New(response.Message) - } - // Added due to increasing of the usuable currencies on exchange, usually // without notificatation, so we dont need to update structs later on for tag, datum := range response.Data { @@ -331,30 +321,16 @@ func (b *Bithumb) GetWalletAddress(currency string) (WalletAddressRes, error) { params := url.Values{} params.Set("currency", common.StringToUpper(currency)) - err := b.SendAuthenticatedHTTPRequest(privateWalletAdd, params, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateWalletAdd, params, &response) } // GetLastTransaction returns customer last transaction func (b *Bithumb) GetLastTransaction() (LastTransactionTicker, error) { response := LastTransactionTicker{} - err := b.SendAuthenticatedHTTPRequest(privateTicker, nil, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateTicker, nil, &response) } // GetOrders returns order list @@ -374,30 +350,16 @@ func (b *Bithumb) GetOrders(orderID, transactionType, count, after, currency str params.Set("after", after) params.Set("currency", common.StringToUpper(currency)) - err := b.SendAuthenticatedHTTPRequest(privateOrders, params, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateOrders, params, &response) } // GetUserTransactions returns customer transactions func (b *Bithumb) GetUserTransactions() (UserTransactions, error) { response := UserTransactions{} - err := b.SendAuthenticatedHTTPRequest(privateUserTrans, nil, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateUserTrans, nil, &response) } // PlaceTrade executes a trade order @@ -417,15 +379,24 @@ func (b *Bithumb) PlaceTrade(orderCurrency, transactionType string, units float6 params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) params.Set("price", strconv.FormatInt(price, 10)) - err := b.SendAuthenticatedHTTPRequest(privatePlaceTrade, params, &response) - if err != nil { - return response, err - } + return response, + b.SendAuthenticatedHTTPRequest(privatePlaceTrade, params, &response) +} - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil +// ModifyTrade modifies an order already on the exchange books +func (b *Bithumb) ModifyTrade(orderID, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) { + response := OrderPlace{} + + params := url.Values{} + params.Set("order_currency", common.StringToUpper(orderCurrency)) + params.Set("Payment_currency", "KRW") + params.Set("type", common.StringToUpper(transactionType)) + params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) + params.Set("price", strconv.FormatInt(price, 10)) + params.Set("order_id", orderID) + + return response, + b.SendAuthenticatedHTTPRequest(privatePlaceTrade, params, &response) } // GetOrderDetails returns specific order details @@ -442,15 +413,8 @@ func (b *Bithumb) GetOrderDetails(orderID, transactionType, currency string) (Or params.Set("type", common.StringToUpper(transactionType)) params.Set("currency", common.StringToUpper(currency)) - err := b.SendAuthenticatedHTTPRequest(privateOrderDetail, params, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateOrderDetail, params, &response) } // CancelTrade cancels a customer purchase/sales transaction @@ -466,15 +430,8 @@ func (b *Bithumb) CancelTrade(transactionType, orderID, currency string) (Action params.Set("type", common.StringToUpper(transactionType)) params.Set("currency", common.StringToUpper(currency)) - err := b.SendAuthenticatedHTTPRequest(privateCancelTrade, nil, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateCancelTrade, nil, &response) } // WithdrawCrypto withdraws a customer currency to an address @@ -494,15 +451,8 @@ func (b *Bithumb) WithdrawCrypto(address, destination, currency string, units fl params.Set("currency", common.StringToUpper(currency)) params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) - err := b.SendAuthenticatedHTTPRequest(privateBTCWithdraw, params, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateBTCWithdraw, params, &response) } // RequestKRWDepositDetails returns Bithumb banking details for deposit @@ -510,15 +460,8 @@ func (b *Bithumb) WithdrawCrypto(address, destination, currency string, units fl func (b *Bithumb) RequestKRWDepositDetails() (KRWDeposit, error) { response := KRWDeposit{} - err := b.SendAuthenticatedHTTPRequest(privateKRWDeposit, nil, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateKRWDeposit, nil, &response) } // RequestKRWWithdraw allows a customer KRW withdrawal request @@ -534,15 +477,8 @@ func (b *Bithumb) RequestKRWWithdraw(bank, account string, price int64) (ActionS params.Set("account", account) params.Set("price", strconv.FormatInt(price, 10)) - err := b.SendAuthenticatedHTTPRequest(privateKRWWithdraw, params, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateKRWWithdraw, params, &response) } // MarketBuyOrder initiates a buy order through available order books @@ -557,15 +493,8 @@ func (b *Bithumb) MarketBuyOrder(currency string, units float64) (MarketBuy, err params.Set("currency", common.StringToUpper(currency)) params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) - err := b.SendAuthenticatedHTTPRequest(privateMarketBuy, params, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateMarketBuy, params, &response) } // MarketSellOrder initiates a sell order through available order books @@ -580,15 +509,8 @@ func (b *Bithumb) MarketSellOrder(currency string, units float64) (MarketSell, e params.Set("currency", common.StringToUpper(currency)) params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) - err := b.SendAuthenticatedHTTPRequest(privateMarketSell, params, &response) - if err != nil { - return response, err - } - - if response.Status != noError { - return response, errors.New(response.Message) - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest(privateMarketSell, params, &response) } // SendHTTPRequest sends an unauthenticated HTTP request @@ -615,7 +537,9 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(path string, params url.Values, r params.Set("endpoint", path) payload := params.Encode() hmacPayload := path + string(0) + payload + string(0) + b.Nonce.String() - hmac := common.GetHMAC(common.HashSHA512, []byte(hmacPayload), []byte(b.APISecret)) + hmac := common.GetHMAC(common.HashSHA512, + []byte(hmacPayload), + []byte(b.APISecret)) hmacStr := common.HexEncodeToString(hmac) headers := make(map[string]string) @@ -624,7 +548,34 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(path string, params url.Values, r headers["Api-Nonce"] = b.Nonce.String() headers["Content-Type"] = "application/x-www-form-urlencoded" - return b.SendPayload("POST", b.APIUrl+path, headers, bytes.NewBufferString(payload), result, true, b.Verbose) + var intermediary json.RawMessage + + errCapture := struct { + Status string `json:"status"` + Message string `json:"message"` + }{} + + err := b.SendPayload("POST", + b.APIUrl+path, + headers, + bytes.NewBufferString(payload), + &intermediary, + true, + b.Verbose) + if err != nil { + return err + } + + err = common.JSONDecode(intermediary, &errCapture) + if err == nil { + if errCapture.Status != "" && errCapture.Status != "0000" { + return fmt.Errorf("SendAuthenticatedHTTPRequest error Code:%s Message:%s", + errCapture.Status, + errCode[errCapture.Status]) + } + } + + return common.JSONDecode(intermediary, result) } // GetFee returns an estimate of fee based on type of transaction @@ -692,3 +643,14 @@ func getDepositFee(currency string, amount float64) float64 { func getWithdrawalFee(currency string) float64 { return WithdrawalFees[currency] } + +var errCode = map[string]string{ + "5100": "Bad Request", + "5200": "Not Member", + "5300": "Invalid Apikey", + "5302": "Method Not Allowed", + "5400": "Database Fail", + "5500": "Invalid Parameter", + "5600": "CUSTOM NOTICE (상황별 에러 메시지 출력) usually means transaction not allowed", + "5900": "Unknown Error", +} diff --git a/exchanges/bithumb/bithumb_test.go b/exchanges/bithumb/bithumb_test.go index 62877a93..04ac20d3 100644 --- a/exchanges/bithumb/bithumb_test.go +++ b/exchanges/bithumb/bithumb_test.go @@ -6,7 +6,7 @@ import ( "github.com/thrasher-/gocryptotrader/config" "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/thrasher-/gocryptotrader/currency/symbol" - exchange "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges" ) // Please supply your own keys here for due diligence testing @@ -389,3 +389,15 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + curr := pair.NewCurrencyPairFromString("BTCUSD") + _, err := b.ModifyOrder(exchange.ModifyOrder{OrderID: "1337", + Price: 100, + Amount: 1000, + OrderSide: exchange.Sell, + Currency: curr}) + if err == nil { + t.Error("Test Failed - ModifyOrder() error") + } +} diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index 546f1c58..2fcdb69d 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -189,8 +189,18 @@ func (b *Bithumb) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bithumb) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *Bithumb) ModifyOrder(action exchange.ModifyOrder) (string, error) { + order, err := b.ModifyTrade(action.OrderID, + action.Currency.FirstCurrency.String(), + common.StringToLower(action.OrderSide.ToString()), + action.Amount, + int64(action.Price)) + + if err != nil { + return "", err + } + + return order.Data[0].ContID, nil } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index 96e36e6d..7119b396 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -403,13 +403,13 @@ func (b *Bitmex) GetOrders(params GenericRequestParams) ([]Order, error) { } // AmendOrder amends the quantity or price of an open order -func (b *Bitmex) AmendOrder(params OrderAmendParams) ([]Order, error) { - var orders []Order +func (b *Bitmex) AmendOrder(params OrderAmendParams) (Order, error) { + var order Order - return orders, b.SendAuthenticatedHTTPRequest("PUT", + return order, b.SendAuthenticatedHTTPRequest("PUT", bitmexEndpointOrder, params, - &orders) + &order) } // CreateOrder creates a new order diff --git a/exchanges/bitmex/bitmex_test.go b/exchanges/bitmex/bitmex_test.go index b973879d..acd442ba 100644 --- a/exchanges/bitmex/bitmex_test.go +++ b/exchanges/bitmex/bitmex_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" - "github.com/thrasher-/gocryptotrader/config" "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/thrasher-/gocryptotrader/currency/symbol" - exchange "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges" + + "github.com/thrasher-/gocryptotrader/config" ) // Please supply your own keys here for due diligence testing @@ -565,3 +566,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{OrderID: "1337"}) + if err == nil { + t.Error("Test Failed - ModifyOrder() error") + } +} diff --git a/exchanges/bitmex/bitmex_wrapper.go b/exchanges/bitmex/bitmex_wrapper.go index ec25699c..58c5bba9 100644 --- a/exchanges/bitmex/bitmex_wrapper.go +++ b/exchanges/bitmex/bitmex_wrapper.go @@ -3,6 +3,7 @@ package bitmex import ( "errors" "log" + "math" "sync" "time" @@ -164,6 +165,12 @@ func (b *Bitmex) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]ex // SubmitOrder submits a new order func (b *Bitmex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) { var submitOrderResponse exchange.SubmitOrderResponse + + if math.Mod(amount, 1) != 0 { + return submitOrderResponse, + errors.New("contract amount can not have decimals") + } + var orderNewParams = OrderNewParams{ OrdType: side.ToString(), Symbol: p.Pair().String(), @@ -189,8 +196,23 @@ func (b *Bitmex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitmex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *Bitmex) ModifyOrder(action exchange.ModifyOrder) (string, error) { + var params OrderAmendParams + + if math.Mod(action.Amount, 1) != 0 { + return "", errors.New("contract amount can not have decimals") + } + + params.OrderID = action.OrderID + params.OrderQty = int32(action.Amount) + params.Price = action.Price + + order, err := b.AmendOrder(params) + if err != nil { + return "", err + } + + return order.OrderID, nil } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index df3e0baa..1808a45a 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -455,3 +455,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index fe2b81c6..257a1633 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -186,8 +186,8 @@ func (b *Bitstamp) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, ord // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitstamp) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *Bitstamp) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/bittrex/bittrex_test.go b/exchanges/bittrex/bittrex_test.go index 7a1c0c4d..490ae7c3 100644 --- a/exchanges/bittrex/bittrex_test.go +++ b/exchanges/bittrex/bittrex_test.go @@ -420,3 +420,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/bittrex/bittrex_wrapper.go b/exchanges/bittrex/bittrex_wrapper.go index a07271c7..316cc0a6 100644 --- a/exchanges/bittrex/bittrex_wrapper.go +++ b/exchanges/bittrex/bittrex_wrapper.go @@ -198,8 +198,8 @@ func (b *Bittrex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bittrex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *Bittrex) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/btcc/btcc_test.go b/exchanges/btcc/btcc_test.go index a8c49c94..7e44d6e8 100644 --- a/exchanges/btcc/btcc_test.go +++ b/exchanges/btcc/btcc_test.go @@ -258,3 +258,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/btcc/btcc_wrapper.go b/exchanges/btcc/btcc_wrapper.go index fa532ae4..9a9e4dea 100644 --- a/exchanges/btcc/btcc_wrapper.go +++ b/exchanges/btcc/btcc_wrapper.go @@ -159,8 +159,8 @@ func (b *BTCC) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTy // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *BTCC) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (b *BTCC) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrNotYetImplemented } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/btcmarkets/btcmarkets_test.go b/exchanges/btcmarkets/btcmarkets_test.go index 305c0179..9f309515 100644 --- a/exchanges/btcmarkets/btcmarkets_test.go +++ b/exchanges/btcmarkets/btcmarkets_test.go @@ -153,13 +153,6 @@ func TestGetFundingHistory(t *testing.T) { } } -func TestModifyOrder(t *testing.T) { - _, err := b.ModifyOrder(1337, exchange.ModifyOrder{}) - if err == nil { - t.Error("Test failed - ModifyOrder() error", err) - } -} - func TestCancelOrder(t *testing.T) { _, err := b.CancelExistingOrder([]int64{1337}) @@ -384,3 +377,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := b.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index 77517525..b4db650e 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -172,8 +172,8 @@ func (b *BTCMarkets) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, o // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *BTCMarkets) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrFunctionNotSupported +func (b *BTCMarkets) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/coinbasepro/coinbasepro_test.go b/exchanges/coinbasepro/coinbasepro_test.go index ce6af061..ea738b78 100644 --- a/exchanges/coinbasepro/coinbasepro_test.go +++ b/exchanges/coinbasepro/coinbasepro_test.go @@ -494,3 +494,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := c.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/coinbasepro/coinbasepro_wrapper.go b/exchanges/coinbasepro/coinbasepro_wrapper.go index eaf2dee6..247aef2c 100644 --- a/exchanges/coinbasepro/coinbasepro_wrapper.go +++ b/exchanges/coinbasepro/coinbasepro_wrapper.go @@ -170,8 +170,8 @@ func (c *CoinbasePro) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (c *CoinbasePro) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (c *CoinbasePro) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/coinut/coinut_test.go b/exchanges/coinut/coinut_test.go index d5db3755..c90c196f 100644 --- a/exchanges/coinut/coinut_test.go +++ b/exchanges/coinut/coinut_test.go @@ -294,3 +294,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := c.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/coinut/coinut_wrapper.go b/exchanges/coinut/coinut_wrapper.go index 5e8f246d..8455bee4 100644 --- a/exchanges/coinut/coinut_wrapper.go +++ b/exchanges/coinut/coinut_wrapper.go @@ -259,8 +259,8 @@ func (c *COINUT) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (c *COINUT) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (c *COINUT) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/exchange.go b/exchanges/exchange.go index 1a61bf3e..31d199d9 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -262,7 +262,7 @@ type IBotExchange interface { GetFundingHistory() ([]FundHistory, error) SubmitOrder(p pair.CurrencyPair, side OrderSide, orderType OrderType, amount, price float64, clientID string) (SubmitOrderResponse, error) - ModifyOrder(orderID int64, modify ModifyOrder) (int64, error) + ModifyOrder(action ModifyOrder) (string, error) CancelOrder(order OrderCancellation) error CancelAllOrders(orders OrderCancellation) (CancelAllOrdersResponse, error) GetOrderInfo(orderID int64) (OrderDetail, error) @@ -728,10 +728,24 @@ func (e *Base) UpdateCurrencies(exchangeProducts []string, enabled, force bool) // ModifyOrder is a an order modifyer type ModifyOrder struct { + OrderID string OrderType OrderSide - Price float64 - Amount float64 + Price float64 + Amount float64 + LimitPriceUpper float64 + LimitPriceLower float64 + Currency pair.CurrencyPair + + ImmediateOrCancel bool + HiddenOrder bool + FillOrKill bool + PostOnly bool +} + +// ModifyOrderResponse is an order modifying return type +type ModifyOrderResponse struct { + OrderID string } // Format holds exchange formatting @@ -754,8 +768,9 @@ type OrderType string // OrderType ...types const ( - Limit OrderType = "Limit" - Market OrderType = "Market" + Limit OrderType = "Limit" + Market OrderType = "Market" + ImmediateOrCancel OrderType = "IMMEDIATE_OR_CANCEL" ) // ToString changes the ordertype to the exchange standard and returns a string diff --git a/exchanges/exmo/exmo_test.go b/exchanges/exmo/exmo_test.go index 82aa5c59..b4f14cec 100644 --- a/exchanges/exmo/exmo_test.go +++ b/exchanges/exmo/exmo_test.go @@ -335,3 +335,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := e.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/exmo/exmo_wrapper.go b/exchanges/exmo/exmo_wrapper.go index a480a53c..536809c8 100644 --- a/exchanges/exmo/exmo_wrapper.go +++ b/exchanges/exmo/exmo_wrapper.go @@ -207,8 +207,8 @@ func (e *EXMO) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTy // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (e *EXMO) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (e *EXMO) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/gateio/gateio_test.go b/exchanges/gateio/gateio_test.go index 75352e7a..db6e97e8 100644 --- a/exchanges/gateio/gateio_test.go +++ b/exchanges/gateio/gateio_test.go @@ -351,3 +351,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := g.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/gateio/gateio_wrapper.go b/exchanges/gateio/gateio_wrapper.go index a4eb391e..cd1e9666 100644 --- a/exchanges/gateio/gateio_wrapper.go +++ b/exchanges/gateio/gateio_wrapper.go @@ -214,8 +214,8 @@ func (g *Gateio) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (g *Gateio) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (g *Gateio) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/gemini/gemini_test.go b/exchanges/gemini/gemini_test.go index 9a4c81ac..13656b1a 100644 --- a/exchanges/gemini/gemini_test.go +++ b/exchanges/gemini/gemini_test.go @@ -411,3 +411,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := Session[1].ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index 9b2e0425..49a561d2 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -146,8 +146,8 @@ func (g *Gemini) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (g *Gemini) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (g *Gemini) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/hitbtc/hitbtc_test.go b/exchanges/hitbtc/hitbtc_test.go index 036ddc13..f744e001 100644 --- a/exchanges/hitbtc/hitbtc_test.go +++ b/exchanges/hitbtc/hitbtc_test.go @@ -262,3 +262,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := h.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index a075a3e7..da7d0c58 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -173,8 +173,8 @@ func (h *HitBTC) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (h *HitBTC) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (h *HitBTC) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/huobi/huobi_test.go b/exchanges/huobi/huobi_test.go index 80f9ec67..fb680720 100644 --- a/exchanges/huobi/huobi_test.go +++ b/exchanges/huobi/huobi_test.go @@ -499,3 +499,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := h.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index a5f2eea1..a989f59d 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -279,8 +279,8 @@ func (h *HUOBI) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderT // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (h *HUOBI) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (h *HUOBI) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/huobihadax/huobihadax_test.go b/exchanges/huobihadax/huobihadax_test.go index 89e3cb52..8b5fb453 100644 --- a/exchanges/huobihadax/huobihadax_test.go +++ b/exchanges/huobihadax/huobihadax_test.go @@ -478,3 +478,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := h.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/huobihadax/huobihadax_wrapper.go b/exchanges/huobihadax/huobihadax_wrapper.go index 2e4c24c8..a907ca7b 100644 --- a/exchanges/huobihadax/huobihadax_wrapper.go +++ b/exchanges/huobihadax/huobihadax_wrapper.go @@ -244,8 +244,8 @@ func (h *HUOBIHADAX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, o // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (h *HUOBIHADAX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (h *HUOBIHADAX) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/itbit/itbit_test.go b/exchanges/itbit/itbit_test.go index d69c5580..e260880c 100644 --- a/exchanges/itbit/itbit_test.go +++ b/exchanges/itbit/itbit_test.go @@ -340,3 +340,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := i.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/itbit/itbit_wrapper.go b/exchanges/itbit/itbit_wrapper.go index 9e21601f..e0f8c9d4 100644 --- a/exchanges/itbit/itbit_wrapper.go +++ b/exchanges/itbit/itbit_wrapper.go @@ -201,8 +201,8 @@ func (i *ItBit) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderT // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (i *ItBit) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (i *ItBit) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/kraken/kraken_test.go b/exchanges/kraken/kraken_test.go index 5633ffe9..dd76274b 100644 --- a/exchanges/kraken/kraken_test.go +++ b/exchanges/kraken/kraken_test.go @@ -431,3 +431,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := k.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index a99368f3..d7d47116 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -195,8 +195,8 @@ func (k *Kraken) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (k *Kraken) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (k *Kraken) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/lakebtc/lakebtc_test.go b/exchanges/lakebtc/lakebtc_test.go index 3c85afa5..edb6184c 100644 --- a/exchanges/lakebtc/lakebtc_test.go +++ b/exchanges/lakebtc/lakebtc_test.go @@ -335,3 +335,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := l.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/lakebtc/lakebtc_wrapper.go b/exchanges/lakebtc/lakebtc_wrapper.go index 7773c827..8d788ae7 100644 --- a/exchanges/lakebtc/lakebtc_wrapper.go +++ b/exchanges/lakebtc/lakebtc_wrapper.go @@ -157,8 +157,8 @@ func (l *LakeBTC) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (l *LakeBTC) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (l *LakeBTC) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/liqui/liqui_test.go b/exchanges/liqui/liqui_test.go index 7c2dfc64..400c2fc0 100644 --- a/exchanges/liqui/liqui_test.go +++ b/exchanges/liqui/liqui_test.go @@ -320,3 +320,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := l.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/liqui/liqui_wrapper.go b/exchanges/liqui/liqui_wrapper.go index 3518ef33..1751b93b 100644 --- a/exchanges/liqui/liqui_wrapper.go +++ b/exchanges/liqui/liqui_wrapper.go @@ -166,8 +166,8 @@ func (l *Liqui) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderT // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (l *Liqui) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (l *Liqui) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/localbitcoins/localbitcoins_test.go b/exchanges/localbitcoins/localbitcoins_test.go index 11d4b44a..5062da33 100644 --- a/exchanges/localbitcoins/localbitcoins_test.go +++ b/exchanges/localbitcoins/localbitcoins_test.go @@ -285,3 +285,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := l.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/localbitcoins/localbitcoins_wrapper.go b/exchanges/localbitcoins/localbitcoins_wrapper.go index 5c46af8e..d5765117 100644 --- a/exchanges/localbitcoins/localbitcoins_wrapper.go +++ b/exchanges/localbitcoins/localbitcoins_wrapper.go @@ -209,8 +209,8 @@ func (l *LocalBitcoins) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (l *LocalBitcoins) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (l *LocalBitcoins) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/okcoin/okcoin_test.go b/exchanges/okcoin/okcoin_test.go index bb1d4bc0..03611d04 100644 --- a/exchanges/okcoin/okcoin_test.go +++ b/exchanges/okcoin/okcoin_test.go @@ -235,3 +235,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := o.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/okcoin/okcoin_wrapper.go b/exchanges/okcoin/okcoin_wrapper.go index 5f936b16..1ae773d8 100644 --- a/exchanges/okcoin/okcoin_wrapper.go +++ b/exchanges/okcoin/okcoin_wrapper.go @@ -227,8 +227,8 @@ func (o *OKCoin) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (o *OKCoin) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (o *OKCoin) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/okex/okex_test.go b/exchanges/okex/okex_test.go index dd8c3f13..d8bf5b5b 100644 --- a/exchanges/okex/okex_test.go +++ b/exchanges/okex/okex_test.go @@ -498,3 +498,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := o.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/okex/okex_wrapper.go b/exchanges/okex/okex_wrapper.go index 985f6258..311b33d6 100644 --- a/exchanges/okex/okex_wrapper.go +++ b/exchanges/okex/okex_wrapper.go @@ -228,8 +228,8 @@ func (o *OKEX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTy // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (o *OKEX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (o *OKEX) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/poloniex/poloniex.go b/exchanges/poloniex/poloniex.go index c22dd45e..786b7bbb 100644 --- a/exchanges/poloniex/poloniex.go +++ b/exchanges/poloniex/poloniex.go @@ -544,18 +544,37 @@ func (p *Poloniex) CancelExistingOrder(orderID int64) (bool, error) { } // MoveOrder moves an order -func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64) (MoveOrderResponse, error) { +func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64, postOnly, immediateOrCancel bool) (MoveOrderResponse, error) { result := MoveOrderResponse{} values := url.Values{} + + if orderID == 0 { + return result, errors.New("OrderID cannot be zero") + } + + if rate == 0 { + return result, errors.New("Rate cannot be zero") + } + values.Set("orderNumber", strconv.FormatInt(orderID, 10)) values.Set("rate", strconv.FormatFloat(rate, 'f', -1, 64)) + if postOnly { + values.Set("postOnly", "true") + } + + if immediateOrCancel { + values.Set("immediateOrCancel", "true") + } + if amount != 0 { values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) } - err := p.SendAuthenticatedHTTPRequest("POST", poloniexOrderMove, values, &result) - + err := p.SendAuthenticatedHTTPRequest("POST", + poloniexOrderMove, + values, + &result) if err != nil { return result, err } diff --git a/exchanges/poloniex/poloniex_test.go b/exchanges/poloniex/poloniex_test.go index 9606850a..accd21df 100644 --- a/exchanges/poloniex/poloniex_test.go +++ b/exchanges/poloniex/poloniex_test.go @@ -6,7 +6,7 @@ import ( "github.com/thrasher-/gocryptotrader/config" "github.com/thrasher-/gocryptotrader/currency/pair" "github.com/thrasher-/gocryptotrader/currency/symbol" - exchange "github.com/thrasher-/gocryptotrader/exchanges" + "github.com/thrasher-/gocryptotrader/exchanges" ) var p Poloniex @@ -280,3 +280,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := p.ModifyOrder(exchange.ModifyOrder{OrderID: "1337", Price: 1337}) + if err == nil { + t.Error("Test Failed - ModifyOrder() error") + } +} diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index 05ebd63c..e53b9dd4 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -175,8 +175,22 @@ func (p *Poloniex) SubmitOrder(currencyPair pair.CurrencyPair, side exchange.Ord // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (p *Poloniex) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (p *Poloniex) ModifyOrder(action exchange.ModifyOrder) (string, error) { + oID, err := strconv.ParseInt(action.OrderID, 10, 64) + if err != nil { + return "", err + } + + resp, err := p.MoveOrder(oID, + action.Price, + action.Amount, + action.PostOnly, + action.ImmediateOrCancel) + if err != nil { + return "", err + } + + return strconv.FormatInt(resp.OrderNumber, 10), nil } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/request/request.go b/exchanges/request/request.go index adf2f5b0..ed1f5613 100644 --- a/exchanges/request/request.go +++ b/exchanges/request/request.go @@ -258,6 +258,10 @@ func (r *Requester) checkRequest(method, path string, body io.Reader, headers ma func (r *Requester) DoRequest(req *http.Request, method, path string, headers map[string]string, body io.Reader, result interface{}, authRequest, verbose bool) error { if verbose { log.Printf("%s exchange request path: %s requires rate limiter: %v", r.Name, path, r.RequiresRateLimiter()) + for k, d := range headers { + log.Printf("%s exchange request header [%s]: %s", r.Name, k, d) + } + log.Println(body) } var timeoutError error diff --git a/exchanges/wex/wex_test.go b/exchanges/wex/wex_test.go index 62bd1034..3ad3f302 100644 --- a/exchanges/wex/wex_test.go +++ b/exchanges/wex/wex_test.go @@ -419,3 +419,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := w.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/wex/wex_wrapper.go b/exchanges/wex/wex_wrapper.go index ecc1f716..ed399284 100644 --- a/exchanges/wex/wex_wrapper.go +++ b/exchanges/wex/wex_wrapper.go @@ -176,8 +176,8 @@ func (w *WEX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTyp // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (w *WEX) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (w *WEX) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrNotYetImplemented } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/yobit/yobit_test.go b/exchanges/yobit/yobit_test.go index de908b68..9c0d6f8b 100644 --- a/exchanges/yobit/yobit_test.go +++ b/exchanges/yobit/yobit_test.go @@ -399,3 +399,10 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Errorf("%v orders failed to cancel", len(resp.OrderStatus)) } } + +func TestModifyOrder(t *testing.T) { + _, err := y.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/yobit/yobit_wrapper.go b/exchanges/yobit/yobit_wrapper.go index 3f04bb30..fff8f446 100644 --- a/exchanges/yobit/yobit_wrapper.go +++ b/exchanges/yobit/yobit_wrapper.go @@ -158,8 +158,8 @@ func (y *Yobit) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderT // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (y *Yobit) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (y *Yobit) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/exchanges/zb/zb_test.go b/exchanges/zb/zb_test.go index c935ebac..3f2de5a8 100644 --- a/exchanges/zb/zb_test.go +++ b/exchanges/zb/zb_test.go @@ -330,3 +330,10 @@ func TestGetAccountInfo(t *testing.T) { } } } + +func TestModifyOrder(t *testing.T) { + _, err := z.ModifyOrder(exchange.ModifyOrder{}) + if err == nil { + t.Error("Test failed - ModifyOrder() error") + } +} diff --git a/exchanges/zb/zb_wrapper.go b/exchanges/zb/zb_wrapper.go index 5023bf08..e6e31651 100644 --- a/exchanges/zb/zb_wrapper.go +++ b/exchanges/zb/zb_wrapper.go @@ -194,8 +194,8 @@ func (z *ZB) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (z *ZB) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func (z *ZB) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number diff --git a/tools/exchange_template/wrapper_file.tmpl b/tools/exchange_template/wrapper_file.tmpl index 0ea78ab5..ec5531b2 100644 --- a/tools/exchange_template/wrapper_file.tmpl +++ b/tools/exchange_template/wrapper_file.tmpl @@ -127,8 +127,8 @@ func ({{.Variable}} *{{.CapitalName}}) SubmitOrder(p pair.CurrencyPair, side exc // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func ({{.Variable}} *{{.CapitalName}}) ModifyOrder(orderID int64, action exchange.ModifyOrder) (int64, error) { - return 0, common.ErrNotYetImplemented +func ({{.Variable}} *{{.CapitalName}}) ModifyOrder(action exchange.ModifyOrder) (string, error) { + return "", common.ErrNotYetImplemented } // CancelOrder cancels an order by its corresponding ID number