mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-31 15:10:42 +00:00
Engine QA (#381)
* 1) Update Dockerfile/docker-compose.yml 2) Remove inline strings for buy/sell/test pairs 3) Remove dangerous order submission values 4) Fix consistency with audit_events (all other spec files use CamelCase) 5) Update web websocket endpoint 6) Fix main param set (and induce dryrun mode on specific command line params) * Engine QA Link up exchange syncer to cmd params, disarm market selling bombs and fix OKEX endpoints * Fix linter issue after merge * Engine QA changes Template updates Wrapper code cleanup Disarmed order bombs Documentation updates * Daily engine QA Bitstamp improvements Spelling mistakes Add Coinbene exchange to support list Protect API authenticated calls for Coinbene/LBank * Engine QA changes Fix exchange_wrapper_coverage tool Add SupportsAsset to exchange interface Fix inline string usage and add BCH withdrawal support * Engine QA Fix Bitstamp types Inform user of errors when parsing time accross the codebase Change time parsing warnings to errors (as they are) Update markdown docs [with linter fixes] * Engine QA changes 1) Add test for dryrunParamInteraction 2) Disarm OKCoin/OKEX bombs if someone accidently sets canManipulateRealOrders to true and runs all package tests 3) Actually check exchange setup errors for BTSE and Coinbene, plus address this in the wrapper template 4) Hardcode missing/non-retrievable contributors and bump the contributors 5) Convert numbers/strings to meaningful types in Bitstamp and OKEX 6) If WS is supported for the exchange wrapper template, preset authWebsocketSupport var * Fix the shadow people * Link the SyncContinuously paramerino * Also show SyncContinuously in engine.PrintSettings * Address nitterinos and use correct filepath for logs * Bitstamp: Extract ALL THE APM * Fix additional nitterinos * Fix time parsing error for Bittrex
This commit is contained in:
@@ -47,22 +47,22 @@ main.go
|
||||
```go
|
||||
var o exchange.IBotExchange
|
||||
|
||||
for i := range bot.exchanges {
|
||||
if bot.exchanges[i].GetName() == "OKex" {
|
||||
y = bot.exchanges[i]
|
||||
for i := range Bot.Exchanges {
|
||||
if Bot.Exchanges[i].GetName() == "OKex" {
|
||||
y = Bot.Exchanges[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Public calls - wrapper functions
|
||||
|
||||
// Fetches current ticker information
|
||||
tick, err := o.GetTickerPrice()
|
||||
tick, err := o.FetchTicker()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
// Fetches current orderbook information
|
||||
ob, err := o.GetOrderbookEx()
|
||||
ob, err := o.FetchOrderbook()
|
||||
if err != nil {
|
||||
// Handle error
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ type OKGroup struct {
|
||||
|
||||
// GetAccountCurrencies returns a list of tradable spot instruments and their properties
|
||||
func (o *OKGroup) GetAccountCurrencies() (resp []GetAccountCurrenciesResponse, _ error) {
|
||||
return resp, o.SendHTTPRequest(http.MethodGet, okGroupAccountSubsection, okGroupGetAccountCurrencies, nil, &resp, false)
|
||||
return resp, o.SendHTTPRequest(http.MethodGet, okGroupAccountSubsection, okGroupGetAccountCurrencies, nil, &resp, true)
|
||||
}
|
||||
|
||||
// GetAccountWalletInformation returns a list of wallets and their properties
|
||||
@@ -173,7 +173,7 @@ func (o *OKGroup) GetAccountDepositHistory(currency string) (resp []GetAccountDe
|
||||
if currency != "" {
|
||||
requestURL = fmt.Sprintf("%v/%v", OKGroupGetAccountDepositHistory, currency)
|
||||
} else {
|
||||
requestURL = okGroupGetWithdrawalHistory
|
||||
requestURL = OKGroupGetAccountDepositHistory
|
||||
}
|
||||
return resp, o.SendHTTPRequest(http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true)
|
||||
}
|
||||
@@ -198,17 +198,23 @@ func (o *OKGroup) GetSpotBillDetailsForCurrency(request GetSpotBillDetailsForCur
|
||||
// PlaceSpotOrder token trading only supports limit and market orders (more order types will become available in the future).
|
||||
// You can place an order only if you have enough funds.
|
||||
// Once your order is placed, the amount will be put on hold.
|
||||
func (o *OKGroup) PlaceSpotOrder(request *PlaceSpotOrderRequest) (resp PlaceSpotOrderResponse, _ error) {
|
||||
func (o *OKGroup) PlaceSpotOrder(request *PlaceOrderRequest) (resp PlaceOrderResponse, _ error) {
|
||||
if request.OrderType == "" {
|
||||
request.OrderType = strconv.Itoa(NormalOrder)
|
||||
}
|
||||
return resp, o.SendHTTPRequest(http.MethodPost, okGroupTokenSubsection, OKGroupOrders, request, &resp, true)
|
||||
}
|
||||
|
||||
// PlaceMultipleSpotOrders supports placing multiple orders for specific trading pairs
|
||||
// up to 4 trading pairs, maximum 4 orders for each pair
|
||||
func (o *OKGroup) PlaceMultipleSpotOrders(request []PlaceSpotOrderRequest) (map[string][]PlaceSpotOrderResponse, []error) {
|
||||
func (o *OKGroup) PlaceMultipleSpotOrders(request []PlaceOrderRequest) (map[string][]PlaceOrderResponse, []error) {
|
||||
currencyPairOrders := make(map[string]int)
|
||||
resp := make(map[string][]PlaceSpotOrderResponse)
|
||||
resp := make(map[string][]PlaceOrderResponse)
|
||||
|
||||
for i := range request {
|
||||
if request[i].OrderType == "" {
|
||||
request[i].OrderType = strconv.Itoa(NormalOrder)
|
||||
}
|
||||
currencyPairOrders[request[i].InstrumentID]++
|
||||
}
|
||||
|
||||
@@ -422,14 +428,14 @@ func (o *OKGroup) RepayMarginLoan(request RepayMarginLoanRequest) (resp RepayMar
|
||||
|
||||
// PlaceMarginOrder OKEx API only supports limit and market orders (more orders will become available in the future).
|
||||
// You can place an order only if you have enough funds. Once your order is placed, the amount will be put on hold.
|
||||
func (o *OKGroup) PlaceMarginOrder(request *PlaceSpotOrderRequest) (resp PlaceSpotOrderResponse, _ error) {
|
||||
func (o *OKGroup) PlaceMarginOrder(request *PlaceOrderRequest) (resp PlaceOrderResponse, _ error) {
|
||||
return resp, o.SendHTTPRequest(http.MethodPost, okGroupMarginTradingSubsection, OKGroupOrders, request, &resp, true)
|
||||
}
|
||||
|
||||
// PlaceMultipleMarginOrders Place multiple orders for specific trading pairs (up to 4 trading pairs, maximum 4 orders each)
|
||||
func (o *OKGroup) PlaceMultipleMarginOrders(request []PlaceSpotOrderRequest) (map[string][]PlaceSpotOrderResponse, []error) {
|
||||
func (o *OKGroup) PlaceMultipleMarginOrders(request []PlaceOrderRequest) (map[string][]PlaceOrderResponse, []error) {
|
||||
currencyPairOrders := make(map[string]int)
|
||||
resp := make(map[string][]PlaceSpotOrderResponse)
|
||||
resp := make(map[string][]PlaceOrderResponse)
|
||||
for i := range request {
|
||||
currencyPairOrders[request[i].InstrumentID]++
|
||||
}
|
||||
@@ -556,10 +562,7 @@ func (o *OKGroup) SendHTTPRequest(httpMethod, requestType, requestPath string, d
|
||||
o.Name)
|
||||
}
|
||||
|
||||
utcTime := time.Now().UTC()
|
||||
iso := utcTime.String()
|
||||
isoBytes := []byte(iso)
|
||||
iso = string(isoBytes[:10]) + "T" + string(isoBytes[11:23]) + "Z"
|
||||
utcTime := time.Now().UTC().Format(time.RFC3339)
|
||||
payload := []byte("")
|
||||
|
||||
if data != nil {
|
||||
@@ -584,11 +587,11 @@ func (o *OKGroup) SendHTTPRequest(httpMethod, requestType, requestPath string, d
|
||||
signPath := fmt.Sprintf("/%v%v%v%v", OKGroupAPIPath,
|
||||
requestType, o.APIVersion, requestPath)
|
||||
hmac := crypto.GetHMAC(crypto.HashSHA256,
|
||||
[]byte(iso+httpMethod+signPath+string(payload)),
|
||||
[]byte(utcTime+httpMethod+signPath+string(payload)),
|
||||
[]byte(o.API.Credentials.Secret))
|
||||
headers["OK-ACCESS-KEY"] = o.API.Credentials.Key
|
||||
headers["OK-ACCESS-SIGN"] = crypto.Base64Encode(hmac)
|
||||
headers["OK-ACCESS-TIMESTAMP"] = iso
|
||||
headers["OK-ACCESS-TIMESTAMP"] = utcTime
|
||||
headers["OK-ACCESS-PASSPHRASE"] = o.API.Credentials.ClientID
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,21 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
// Order types
|
||||
const (
|
||||
NormalOrder = iota
|
||||
PostOnlyOrder
|
||||
FillOrKillOrder
|
||||
ImmediateOrCancelOrder
|
||||
)
|
||||
|
||||
// GetAccountCurrenciesResponse response data for GetAccountCurrencies
|
||||
type GetAccountCurrenciesResponse struct {
|
||||
CanDeposit int64 `json:"can_deposit"`
|
||||
CanWithdraw int64 `json:"can_withdraw"`
|
||||
Currency string `json:"currency"`
|
||||
MinWithdrawal float64 `json:"min_withdrawal"`
|
||||
Name string `json:"name"`
|
||||
Currency string `json:"currency"`
|
||||
CanDeposit int `json:"can_deposit,string"`
|
||||
CanWithdraw int `json:"can_withdraw,string"`
|
||||
MinWithdrawal float64 `json:"min_withdrawal,string"`
|
||||
}
|
||||
|
||||
// WalletInformationResponse response data for WalletInformation
|
||||
@@ -64,22 +72,22 @@ type AccountWithdrawResponse struct {
|
||||
// GetAccountWithdrawalFeeResponse response data for GetAccountWithdrawalFee
|
||||
type GetAccountWithdrawalFeeResponse struct {
|
||||
Currency string `json:"currency"`
|
||||
MinFee float64 `json:"min_fee"`
|
||||
MaxFee float64 `json:"max_fee"`
|
||||
MinFee float64 `json:"min_fee,string"`
|
||||
MaxFee float64 `json:"max_fee,string"`
|
||||
}
|
||||
|
||||
// WithdrawalHistoryResponse response data for WithdrawalHistoryResponse
|
||||
type WithdrawalHistoryResponse struct {
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Fee string `json:"fee"`
|
||||
From string `json:"from"`
|
||||
Status int64 `json:"status"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
To string `json:"to"`
|
||||
Txid string `json:"txid"`
|
||||
PaymentID string `json:"payment_id"`
|
||||
Tag string `json:"tag"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Currency string `json:"currency"`
|
||||
Fee string `json:"fee"`
|
||||
From string `json:"from"`
|
||||
Status int64 `json:"status,string"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
To string `json:"to"`
|
||||
TransactionID string `json:"txid"`
|
||||
PaymentID string `json:"payment_id"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
|
||||
// GetAccountBillDetailsRequest request data for GetAccountBillDetailsRequest
|
||||
@@ -112,11 +120,12 @@ type GetDepositAddressResponse struct {
|
||||
|
||||
// GetAccountDepositHistoryResponse response data for GetAccountDepositHistory
|
||||
type GetAccountDepositHistoryResponse struct {
|
||||
Amount float64 `json:"amount"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Currency string `json:"currency"`
|
||||
Status int64 `json:"status"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Status int64 `json:"status,string"`
|
||||
TransactionID string `json:"txid"`
|
||||
}
|
||||
|
||||
@@ -156,20 +165,21 @@ type SpotBillDetails struct {
|
||||
InstrumentID string `json:"instrument_id"`
|
||||
}
|
||||
|
||||
// PlaceSpotOrderRequest request data for PlaceSpotOrder
|
||||
type PlaceSpotOrderRequest struct {
|
||||
// PlaceOrderRequest request data for placing an order
|
||||
type PlaceOrderRequest struct {
|
||||
ClientOID string `json:"client_oid,omitempty"` // the order ID customized by yourself
|
||||
Type string `json:"type"` // limit / market(default: limit)
|
||||
Side string `json:"side"` // buy or sell
|
||||
InstrumentID string `json:"instrument_id"` // trading pair
|
||||
MarginTrading string `json:"margin_trading"` // order type (The request value is 1)
|
||||
MarginTrading string `json:"margin_trading"` // margin trading
|
||||
OrderType string `json:"order_type"` // order type (0: Normal order (Unfilled and 0 imply normal limit order) 1: Post only 2: Fill or Kill 3: Immediate Or Cancel
|
||||
Size string `json:"size"`
|
||||
Notional string `json:"notional,omitempty"` //
|
||||
Price string `json:"price,omitempty"` // price (Limit order only)
|
||||
}
|
||||
|
||||
// PlaceSpotOrderResponse response data for PlaceSpotOrder
|
||||
type PlaceSpotOrderResponse struct {
|
||||
// PlaceOrderResponse response data for PlaceSpotOrder
|
||||
type PlaceOrderResponse struct {
|
||||
ClientOid string `json:"client_oid"`
|
||||
OrderID string `json:"order_id"`
|
||||
Result bool `json:"result"`
|
||||
@@ -1497,7 +1507,7 @@ type WebsocketSpotOrderResponse struct {
|
||||
Notional float64 `json:"notional,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
Status string `json:"status"`
|
||||
MarginTrading int64 `json:"margin_trading"`
|
||||
MarginTrading int64 `json:"margin_trading,omitempty"`
|
||||
Type string `json:"type"`
|
||||
// Price A member, but part already exists as part of WebsocketDataResponse
|
||||
// InstrumentID A member, but part already exists as part of WebsocketDataResponse
|
||||
|
||||
@@ -267,19 +267,21 @@ func (o *OKGroup) WsHandleData(wg *sync.WaitGroup) {
|
||||
// WsLogin sends a login request to websocket to enable access to authenticated endpoints
|
||||
func (o *OKGroup) WsLogin() error {
|
||||
o.Websocket.SetCanUseAuthenticatedEndpoints(true)
|
||||
utcTime := time.Now().UTC()
|
||||
unixTime := utcTime.Unix()
|
||||
unixTime := time.Now().UTC().Unix()
|
||||
signPath := "/users/self/verify"
|
||||
hmac := crypto.GetHMAC(crypto.HashSHA256,
|
||||
[]byte(fmt.Sprintf("%v", unixTime)+http.MethodGet+signPath),
|
||||
[]byte(o.API.Credentials.Secret))
|
||||
[]byte(strconv.FormatInt(unixTime, 10)+http.MethodGet+signPath),
|
||||
[]byte(o.API.Credentials.Secret),
|
||||
)
|
||||
base64 := crypto.Base64Encode(hmac)
|
||||
request := WebsocketEventRequest{
|
||||
Operation: "login",
|
||||
Arguments: []string{o.API.Credentials.Key,
|
||||
Arguments: []string{
|
||||
o.API.Credentials.Key,
|
||||
o.API.Credentials.ClientID,
|
||||
fmt.Sprintf("%v", unixTime),
|
||||
base64},
|
||||
strconv.FormatInt(unixTime, 10),
|
||||
base64,
|
||||
},
|
||||
}
|
||||
err := o.WebsocketConn.SendMessage(request)
|
||||
if err != nil {
|
||||
@@ -470,7 +472,7 @@ func (o *OKGroup) wsProcessCandles(response *WebsocketDataResponse) {
|
||||
timeData, err := time.Parse(time.RFC3339Nano,
|
||||
response.Data[i].WebsocketCandleResponse.Candle[0])
|
||||
if err != nil {
|
||||
log.Warnf(log.ExchangeSys,
|
||||
log.Errorf(log.ExchangeSys,
|
||||
"%v Time data could not be parsed: %v",
|
||||
o.Name,
|
||||
response.Data[i].Candle[0])
|
||||
|
||||
@@ -236,7 +236,7 @@ func (o *OKGroup) GetFundingHistory() (resp []exchange.FundHistory, err error) {
|
||||
ExchangeName: o.Name,
|
||||
Status: OrderStatus[accountWithdrawlHistory[i].Status],
|
||||
Timestamp: accountWithdrawlHistory[i].Timestamp,
|
||||
TransferID: accountWithdrawlHistory[i].Txid,
|
||||
TransferID: accountWithdrawlHistory[i].TransactionID,
|
||||
TransferType: "withdrawal",
|
||||
})
|
||||
}
|
||||
@@ -255,11 +255,11 @@ func (o *OKGroup) SubmitOrder(s *order.Submit) (resp order.SubmitResponse, err e
|
||||
return resp, err
|
||||
}
|
||||
|
||||
request := PlaceSpotOrderRequest{
|
||||
request := PlaceOrderRequest{
|
||||
ClientOID: s.ClientID,
|
||||
InstrumentID: o.FormatExchangeCurrency(s.Pair, asset.Spot).String(),
|
||||
Side: strings.ToLower(s.OrderSide.String()),
|
||||
Type: strings.ToLower(s.OrderType.String()),
|
||||
Side: s.OrderSide.Lower(),
|
||||
Type: s.OrderType.Lower(),
|
||||
Size: strconv.FormatFloat(s.Amount, 'f', -1, 64),
|
||||
}
|
||||
if s.OrderType == order.Limit {
|
||||
|
||||
Reference in New Issue
Block a user