diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index c23774cd..00000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Launch",
- "type": "go",
- "request": "launch",
- "mode": "auto",
- "program": "${fileDirname}",
- "env": {},
- "args": []
- }
- ]
-}
\ No newline at end of file
diff --git a/Const.go b/Const.go
index f4032eff..9d197b2a 100644
--- a/Const.go
+++ b/Const.go
@@ -155,3 +155,16 @@ const (
COINBENE = "coinbene.com"
ATOP = "a.top"
)
+
+const (
+ SUB_ACCOUNT = iota //子账户
+ SPOT // 币币交易
+ _
+ FUTURE //交割合约
+ C2C //法币
+ SPOT_MARGIN //币币杠杆交易
+ WALLET // 资金账户
+ _
+ TIPS //余币宝
+ SWAP //永续合约
+)
diff --git a/FutureRestAPI.go b/FutureRestAPI.go
index 2f0ccc42..a80e538b 100644
--- a/FutureRestAPI.go
+++ b/FutureRestAPI.go
@@ -51,6 +51,8 @@ type FutureRestAPI interface {
*/
PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (string, error)
+ LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int) (*FutureOrder, error)
+
/**
* 取消订单
* @param symbol btc_usd:比特币 ltc_usd :莱特币
diff --git a/Models.go b/Models.go
index ae341fa1..87fad236 100644
--- a/Models.go
+++ b/Models.go
@@ -6,20 +6,21 @@ import (
)
type Order struct {
- Price float64
- Amount float64
- AvgPrice float64
- DealAmount float64
- Fee float64
- Cid string //客户端自定义ID
- OrderID2 string
- OrderID int //deprecated
- OrderTime int
- Status TradeStatus
- Currency CurrencyPair
- Side TradeSide
- Type string //limit / market
- OrderType int //0:default,1:maker,2:fok,3:ioc
+ Price float64
+ Amount float64
+ AvgPrice float64
+ DealAmount float64
+ Fee float64
+ Cid string //客户端自定义ID
+ OrderID2 string
+ OrderID int //deprecated
+ Status TradeStatus
+ Currency CurrencyPair
+ Side TradeSide
+ Type string //limit / market
+ OrderType int //0:default,1:maker,2:fok,3:ioc
+ OrderTime int // create timestamp
+ FinishedTime int64 //finished timestamp
}
type Trade struct {
@@ -75,7 +76,7 @@ type Ticker struct {
type FutureTicker struct {
*Ticker
ContractType string `json:"omitempty"`
- ContractId int `json:"contractId"`
+ ContractId string `json:"contractId"`
LimitHigh float64 `json:"limitHigh,string"`
LimitLow float64 `json:"limitLow,string"`
HoldAmount float64 `json:"hold_amount,string"`
@@ -102,7 +103,8 @@ func (dr DepthRecords) Less(i, j int) bool {
}
type Depth struct {
- ContractType string //for future
+ ContractType string `json:"contract_type,omitempty"` //for futures
+ ContractId string `json:"contract_id,omitempty"` // for futures
Pair CurrencyPair
UTime time.Time
AskList DepthRecords // Descending order
@@ -164,6 +166,7 @@ type FutureOrder struct {
LeverRate int //倍数
Fee float64 //手续费
ContractName string
+ FinishedTime int64 // finished timestamp
}
type FuturePosition struct {
@@ -202,8 +205,8 @@ type TickSize struct {
type FuturesContractInfo struct {
*TickSize
ContractVal float64 //合约面值(美元)
- Delivery string //交割日期
- ContractType string // 本周 this_week 次周 next_week 季度 quarter
+ Delivery string //交割日期
+ ContractType string // 本周 this_week 次周 next_week 季度 quarter
}
//api parameter struct
@@ -218,3 +221,37 @@ type RepaymentParameter struct {
BorrowParameter
BorrowId string
}
+
+
+type TransferParameter struct {
+ Currency string `json:"currency"`
+ From int `json:"from"`
+ To int `json:"to"`
+ Amount float64 `json:"amount"`
+ SubAccount string `json:"sub_account"`
+ InstrumentId string `json:"instrument_id"`
+ ToInstrumentId string `json:"to_instrument_id"`
+}
+
+type WithdrawParameter struct {
+ Currency string `json:"currency"`
+ Amount float64 `json:"amount,string"`
+ Destination int `json:"destination"` //提币到(2:OKCoin国际 3:OKEx 4:数字货币地址)
+ ToAddress string `json:"to_address"`
+ TradePwd string `json:"trade_pwd"`
+ Fee string `json:"fee"`
+}
+
+
+type DepositWithdrawHistory struct {
+ WithdrawalId string `json:"withdrawal_id,omitempty"`
+ Currency string `json:"currency"`
+ Txid string `json:"txid"`
+ Amount float64 `json:"amount,string"`
+ From string `json:"from,omitempty"`
+ To string `json:"to"`
+ Memo string `json:"memo,omitempty"`
+ Fee string `json:"fee"`
+ Status int `json:"status,string"`
+ Timestamp time.Time `json:"timestamp"`
+}
diff --git a/README.md b/README.md
index c0b9993d..e46be10d 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@

-
- [] (https://www.jetbrains.com/?from=goex)
### goex目标
@@ -15,111 +13,37 @@ goex项目是为了统一并标准化各个数字资产交易平台的接口而
| 交易所 | 行情接口 | 交易接口 | 版本号 |
| --- | --- | --- | --- |
-| hbg.com | Y | Y | 1 |
-| hbdm.com | Y| Y | 1 |
-| okex.com | Y | Y | 3 |
+| huobi.pro | Y | Y | 1 |
+| hbdm.com | Y (REST / WS)| Y | 1 |
+| okex.com (spot/future)| Y (REST / WS) | Y | 1 |
+| okex.com (swap future) | Y | Y | 2 |
| binance.com | Y | Y | 1 |
| kucoin.com | Y | Y | 1 |
| bitstamp.net | Y | Y | 1 |
| bitfinex.com | Y | Y | 1 |
| zb.com | Y | Y | 1 |
| kraken.com | Y | Y | * |
-| poloniex.com | Y | Y | * |
-| aacoin.com | Y | Y | 1 |
-| allcoin.ca | Y | Y | * |
+| poloniex.com | Y | Y | * |
| big.one | Y | Y | 2\|3 |
-| fcoin.com | Y | Y | 2 |
| hitbtc.com | Y | Y | * |
| coinex.com | Y | Y | 1 |
| exx.com | Y | Y | 1 |
| bithumb.com | Y | Y | * |
| gate.io | Y | N | 1 |
-| btcbox.co.jp | Y | N | * |
-| coinbig.com | Y | Y | * |
-|coinbene.com|Y|Y|*|
+| bittrex.com | Y | N | 1.1 |
### 安装goex库
+> go get
``` go get github.com/nntaoli-project/goex ```
>建议go mod 管理依赖
```
require (
- github.com/nntaoli-project/goex v1.0.4
+ github.com/nntaoli-project/goex latest
)
```
-### 例子
-
-```golang
-
- package main
-
- import (
- "github.com/nntaoli-project/goex"
- "github.com/nntaoli-project/goex/builder"
- "log"
- "time"
- )
-
- func main() {
- apiBuilder := builder.NewAPIBuilder().HttpTimeout(5 * time.Second)
- //apiBuilder := builder.NewAPIBuilder().HttpTimeout(5 * time.Second).HttpProxy("socks5://127.0.0.1:1080")
-
- //build spot api
- //api := apiBuilder.APIKey("").APISecretkey("").ClientID("123").Build(goex.BITSTAMP)
- api := apiBuilder.APIKey("").APISecretkey("").Build(goex.HUOBI_PRO)
- log.Println(api.GetExchangeName())
- log.Println(api.GetTicker(goex.BTC_USD))
- log.Println(api.GetDepth(2, goex.BTC_USD))
- //log.Println(api.GetAccount())
- //log.Println(api.GetUnfinishOrders(goex.BTC_USD))
-
- //build future api
- futureApi := apiBuilder.APIKey("").APISecretkey("").BuildFuture(goex.HBDM)
- log.Println(futureApi.GetExchangeName())
- log.Println(futureApi.GetFutureTicker(goex.BTC_USD, goex.QUARTER_CONTRACT))
- log.Println(futureApi.GetFutureDepth(goex.BTC_USD, goex.QUARTER_CONTRACT, 5))
- //log.Println(futureApi.GetFutureUserinfo()) // account
- //log.Println(futureApi.GetFuturePosition(goex.BTC_USD , goex.QUARTER_CONTRACT))//position info
- }
-
-```
-
-### websocket 使用例子
-
-```golang
-import (
- "github.com/nntaoli-project/goex"
- "github.com/nntaoli-project/goex/huobi"
- //"github.com/nntaoli-project/goex/okcoin"
- "log"
-)
-
-func main() {
-
- //ws := okcoin.NewOKExFutureWs() //ok期货
- ws := huobi.NewHbdmWs() //huobi期货
- //设置回调函数
- ws.SetCallbacks(func(ticker *goex.FutureTicker) {
- log.Println(ticker)
- }, func(depth *goex.Depth) {
- log.Println(depth)
- }, func(trade *goex.Trade, contract string) {
- log.Println(contract, trade)
- })
- //订阅行情
- ws.SubscribeTrade(goex.BTC_USDT, goex.NEXT_WEEK_CONTRACT)
- ws.SubscribeDepth(goex.BTC_USDT, goex.QUARTER_CONTRACT, 5)
- ws.SubscribeTicker(goex.BTC_USDT, goex.QUARTER_CONTRACT)
-}
-
-```
-
-### 更多文档
-
-[goex.TOP](https://goex.top)
-
### 注意事项
1. 推荐使用GoLand开发。
@@ -127,7 +51,6 @@ func main() {
3. 不建议对现已存在的文件进行重新格式化,这样会导致commit特别糟糕。
4. 请用OrderID2这个字段代替OrderID
5. 请不要使用deprecated关键字标注的方法和字段,后面版本可能随时删除的
-6. 交流QQ群:574829125
-----------------
donate
diff --git a/README_en.md b/README_en.md
index 921944d8..f4a70cec 100644
--- a/README_en.md
+++ b/README_en.md
@@ -11,7 +11,7 @@ goex project is designed to unify and standardize the interfaces of each digital
### Exchanges are supported by goex `23+`
| Exchange | Market API | Order API | Version |
| --- | --- | --- | --- |
-| hbg.com | Y | Y | 1 |
+| huobi.pro | Y | Y | 1 |
| hbdm.com | Y (REST / WS)| Y | 1 |
| okex.com (spot/future)| Y (REST / WS) | Y | 1 |
| okex.com (swap future) | Y | Y | 2 |
@@ -21,104 +21,38 @@ goex project is designed to unify and standardize the interfaces of each digital
| bitfinex.com | Y | Y | 1 |
| zb.com | Y | Y | 1 |
| kraken.com | Y | Y | * |
-| poloniex.com | Y | Y | * |
-| aacoin.com | Y | Y | 1 |
-| allcoin.ca | Y | Y | * |
+| poloniex.com | Y | Y | * |
| big.one | Y | Y | 2\|3 |
-| fcoin.com | Y (REST / WS) | Y | 2 |
| hitbtc.com | Y | Y | * |
| coinex.com | Y | Y | 1 |
| exx.com | Y | Y | 1 |
| bithumb.com | Y | Y | * |
| gate.io | Y | N | 1 |
-| btcbox.co.jp | Y | N | * |
| bittrex.com | Y | N | 1.1 |
-| btcchina.com | Y | Y | 1 |
-| coinbig.com | Y | Y | * |
### Install goex
-``` go get github.com/nntaoli-project/goex ```
-
-### Example
-```golang
-
- package main
-
- import (
- "github.com/nntaoli-project/goex"
- "github.com/nntaoli-project/goex/builder"
- "log"
- "time"
- )
-
- func main() {
- apiBuilder := builder.NewAPIBuilder().HttpTimeout(5 * time.Second)
- //apiBuilder := builder.NewAPIBuilder().HttpTimeout(5 * time.Second).HttpProxy("socks5://127.0.0.1:1080")
-
- //build spot api
- //api := apiBuilder.APIKey("").APISecretkey("").ClientID("123").Build(goex.BITSTAMP)
- api := apiBuilder.APIKey("").APISecretkey("").Build(goex.HUOBI_PRO)
- log.Println(api.GetExchangeName())
- log.Println(api.GetTicker(goex.BTC_USD))
- log.Println(api.GetDepth(2, goex.BTC_USD))
- //log.Println(api.GetAccount())
- //log.Println(api.GetUnfinishOrders(goex.BTC_USD))
-
- //build future api
- futureApi := apiBuilder.APIKey("").APISecretkey("").BuildFuture(goex.HBDM)
- log.Println(futureApi.GetExchangeName())
- log.Println(futureApi.GetFutureTicker(goex.BTC_USD, goex.QUARTER_CONTRACT))
- log.Println(futureApi.GetFutureDepth(goex.BTC_USD, goex.QUARTER_CONTRACT, 5))
- //log.Println(futureApi.GetFutureUserinfo()) // account
- //log.Println(futureApi.GetFuturePosition(goex.BTC_USD , goex.QUARTER_CONTRACT))//position info
- }
+> go get
-```
+``` go get github.com/nntaoli-project/goex ```
+> go mod
-### websocket Example
-```golang
-import (
- "github.com/nntaoli-project/goex"
- "github.com/nntaoli-project/goex/huobi"
- //"github.com/nntaoli-project/goex/okcoin"
- "log"
+```
+require (
+ github.com/nntaoli-project/goex latest
)
-
-func main() {
-
- //ws := okcoin.NewOKExFutureWs() //ok future
- ws := huobi.NewHbdmWs() //huobi future
- //setup callback
- ws.SetCallbacks(func(ticker *goex.FutureTicker) {
- log.Println(ticker)
- }, func(depth *goex.Depth) {
- log.Println(depth)
- }, func(trade *goex.Trade, contract string) {
- log.Println(contract, trade)
- })
- //subscribe
- ws.SubscribeTrade(goex.BTC_USDT, goex.NEXT_WEEK_CONTRACT)
- ws.SubscribeDepth(goex.BTC_USDT, goex.QUARTER_CONTRACT, 5)
- ws.SubscribeTicker(goex.BTC_USDT, goex.QUARTER_CONTRACT)
-}
-
```
-### More Detail
-
-[goex.TOP](https://goex.top)
-
-# Highly Recommended(IMPORTANCE)
+#Recommended(IMPORTANCE)
1. use GoLand development.
2. turn off the auto format function.
3. DONOT reformat existing files, which will result in a particularly bad commit.
4. use the OrderID2 field instead of the OrderID
+5. can't use the deprecated field or method
-### How to find us
-Join QQ group: [574829125](#)
-
+donate & Buy a cup of Coffee for author
-----------------
+BTC:13cBHLk6B7t3Uj7caJbCwv1UaiuiA6Qx8z
-### Buy me a Coffe
-
-
+LTC:LVxM7y1K2dnpuNBU42ei3dKzPySf4VAm1H
+
+ETH:0x98573ddb33cdddce480c3bc1f9279ccd88ca1e93
\ No newline at end of file
diff --git a/Utils.go b/Utils.go
index 0222988e..4d196637 100644
--- a/Utils.go
+++ b/Utils.go
@@ -8,6 +8,7 @@ import (
"fmt"
"github.com/google/uuid"
"io/ioutil"
+ "math"
"net/url"
"strconv"
"strings"
@@ -92,10 +93,13 @@ func ToInt64(v interface{}) int64 {
}
}
-//n :保留的小数点位数,去除末尾多余的0(StripTrailingZeros)
-func FloatToString(v float64, n int) string {
- ret := strconv.FormatFloat(v, 'f', n, 64)
- return strconv.FormatFloat(ToFloat64(ret), 'f', -1, 64) //StripTrailingZeros
+func FloatToString(v float64, precision int) string {
+ return fmt.Sprint(FloatToFixed(v, precision))
+}
+
+func FloatToFixed(v float64, precision int) float64 {
+ p := math.Pow(10, float64(precision))
+ return math.Round(v*p) / p
}
func ValuesToJson(v url.Values) ([]byte, error) {
@@ -124,5 +128,5 @@ func FlateDecompress(data []byte) ([]byte, error) {
func GenerateOrderClientId(size int) string {
uuidStr := strings.Replace(uuid.New().String(), "-", "", 32)
- return "goex-" + uuidStr[0:size-5]
+ return "goex" + uuidStr[0:size-5]
}
diff --git a/Utils_test.go b/Utils_test.go
index 713b24d1..7e6a4bc9 100644
--- a/Utils_test.go
+++ b/Utils_test.go
@@ -8,8 +8,9 @@ import (
func TestFloatToString(t *testing.T) {
assert.Equal(t, "1", FloatToString(1.10231000, 0))
assert.Equal(t, "0.102", FloatToString(0.10231000, 3))
- assert.Equal(t, "1.10231", FloatToString(1.10231000, 8))
+ assert.Equal(t, "189.61", FloatToString(189.61020000, 2))
assert.NotEqual(t, "1.10231000", FloatToString(1.10231000, 8))
+ assert.Equal(t, 0.13, FloatToFixed(0.1299999, 5))
}
func TestGenerateOrderClientId(t *testing.T) {
diff --git a/WalletApi.go b/WalletApi.go
new file mode 100644
index 00000000..c88309e6
--- /dev/null
+++ b/WalletApi.go
@@ -0,0 +1,14 @@
+package goex
+
+type WalletApi interface {
+ //获取钱包资产
+ GetAccount() (*Account, error)
+ //提币
+ Withdrawal(param WithdrawParameter) (withdrawId string, err error)
+ //划转资产
+ Transfer(param TransferParameter) error
+ //获取提币记录
+ GetWithDrawHistory(currency *Currency) ([]DepositWithdrawHistory, error)
+ //获取充值记录
+ GetDepositHistory(currency *Currency) ([]DepositWithdrawHistory, error)
+}
diff --git a/binance/BinanceSwap.go b/binance/BinanceSwap.go
index f569a6d5..00014735 100644
--- a/binance/BinanceSwap.go
+++ b/binance/BinanceSwap.go
@@ -19,6 +19,10 @@ type BinanceSwap struct {
Binance
}
+func (bs *BinanceSwap) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int) (*FutureOrder, error) {
+ return bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, 0, 10)
+}
+
func NewBinanceSwap(config *APIConfig) *BinanceSwap {
if config.Endpoint == "" {
config.Endpoint = baseUrl
@@ -289,6 +293,11 @@ func (bs *BinanceSwap) Transfer(currency Currency, transferType int, amount floa
return ToInt64(respmap["tranId"]), nil
}
+func (bs *BinanceSwap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (string, error) {
+ fOrder, err := bs.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, matchPrice, leverRate)
+ return fOrder.OrderID2, err
+}
+
/**
* @deprecated
* 期货下单
@@ -299,13 +308,23 @@ func (bs *BinanceSwap) Transfer(currency Currency, transferType int, amount floa
* @param openType 1:开多 2:开空 3:平多 4:平空
* @param matchPrice 是否为对手价 0:不是 1:是 ,当取值为1时,price无效
*/
-func (bs *BinanceSwap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (string, error) {
+func (bs *BinanceSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (*FutureOrder, error) {
+ fOrder := &FutureOrder{
+ Currency: currencyPair,
+ ClientOid: GenerateOrderClientId(32),
+ Price: ToFloat64(price),
+ Amount: ToFloat64(amount),
+ OrderType: openType,
+ LeverRate: leverRate,
+ ContractName: contractType,
+ }
pair := bs.adaptCurrencyPair(currencyPair)
path := bs.apiV1 + ORDER_URI
params := url.Values{}
params.Set("symbol", pair.ToSymbol(""))
params.Set("quantity", amount)
+ params.Set("newClientOrderId", fOrder.ClientOid)
switch openType {
case OPEN_BUY, CLOSE_SELL:
@@ -325,20 +344,22 @@ func (bs *BinanceSwap) PlaceFutureOrder(currencyPair CurrencyPair, contractType,
resp, err := HttpPostForm2(bs.httpClient, path, params,
map[string]string{"X-MBX-APIKEY": bs.accessKey})
if err != nil {
- return "", err
+ return fOrder, err
}
respmap := make(map[string]interface{})
err = json.Unmarshal(resp, &respmap)
if err != nil {
- return "", err
+ return fOrder, err
}
orderId := ToInt(respmap["orderId"])
if orderId <= 0 {
- return "", errors.New(string(resp))
+ return fOrder, errors.New(string(resp))
}
- return strconv.Itoa(orderId), nil
+ fOrder.OrderID2 = strconv.Itoa(orderId)
+
+ return fOrder, nil
}
/**
diff --git a/binance/BinanceWs.go b/binance/BinanceWs.go
index 0bb2eb5d..4c3a5213 100644
--- a/binance/BinanceWs.go
+++ b/binance/BinanceWs.go
@@ -92,7 +92,7 @@ func (bnWs *BinanceWs) SetCallbacks(
bnWs.klineCallback = klineCallback
}
-func (bnWs *BinanceWs) Subscribe(endpoint string, handle func(msg []byte) error) {
+func (bnWs *BinanceWs) Subscribe(endpoint string, handle func(msg []byte) error) *WsConn {
wsConn := NewWsBuilder().
WsUrl(endpoint).
AutoReconnect().
@@ -102,6 +102,7 @@ func (bnWs *BinanceWs) Subscribe(endpoint string, handle func(msg []byte) error)
Build()
bnWs.wsConns = append(bnWs.wsConns, wsConn)
go bnWs.exitHandler(wsConn)
+ return wsConn
}
func (bnWs *BinanceWs) Close() {
@@ -121,11 +122,10 @@ func (bnWs *BinanceWs) SubscribeDepth(pair CurrencyPair, size int) error {
handle := func(msg []byte) error {
rawDepth := struct {
- LastUpdateID int64 `json:"T"`
- Bids [][]interface{} `json:"b"`
- Asks [][]interface{} `json:"a"`
+ LastUpdateID int64 `json:"lastUpdateId"`
+ Bids [][]interface{} `json:"bids"`
+ Asks [][]interface{} `json:"asks"`
}{}
-
err := json.Unmarshal(msg, &rawDepth)
if err != nil {
fmt.Println("json unmarshal error for ", string(msg))
diff --git a/bitmex/bitmex.go b/bitmex/bitmex.go
index 7bee6db3..a10e80bb 100644
--- a/bitmex/bitmex.go
+++ b/bitmex/bitmex.go
@@ -120,6 +120,11 @@ type BitmexOrder struct {
}
func (bm *bitmex) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (string, error) {
+ fOrder, err := bm.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, matchPrice, leverRate)
+ return fOrder.OrderID2, err
+}
+
+func (bm *bitmex) PlaceFutureOrder2(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (*FutureOrder, error) {
var createOrderParameter BitmexOrder
var resp struct {
@@ -150,13 +155,29 @@ func (bm *bitmex) PlaceFutureOrder(currencyPair CurrencyPair, contractType, pric
// createOrderParameter.OrderQty = -ToInt(amount)
//}
+ fOrder := &FutureOrder{
+ ClientOid: createOrderParameter.ClOrdID,
+ Currency: currencyPair,
+ Price: ToFloat64(price),
+ Amount: ToFloat64(amount),
+ OType: openType,
+ LeverRate: leverRate,
+ ContractName: contractType,
+ }
+
err := bm.doAuthRequest("POST", "/api/v1/order", bm.toJson(createOrderParameter), &resp)
if err != nil {
- return "", err
+ return fOrder, err
}
- return resp.OrderId, nil
+ fOrder.OrderID2 = resp.OrderId
+
+ return fOrder, nil
+}
+
+func (bm *bitmex) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int) (*FutureOrder, error) {
+ return bm.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, 0, 10)
}
func (bm *bitmex) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) {
diff --git a/builder/APIBuilder.go b/builder/APIBuilder.go
index e2835fea..637c9004 100644
--- a/builder/APIBuilder.go
+++ b/builder/APIBuilder.go
@@ -335,3 +335,16 @@ func (builder *APIBuilder) BuildSpotWs(exName string) (SpotWsApi, error) {
}
return nil, errors.New("not support the exchange " + exName)
}
+
+func (builder *APIBuilder) BuildWallet(exName string) (WalletApi, error) {
+ switch exName {
+ case OKEX_V3, OKEX:
+ return okex.NewOKEx(&APIConfig{
+ HttpClient: builder.client,
+ ApiKey: builder.apiKey,
+ ApiSecretKey: builder.secretkey,
+ ApiPassphrase: builder.apiPassphrase,
+ }).OKExWallet, nil
+ }
+ return nil, errors.New("not support the wallet api for " + exName)
+}
diff --git a/coinbene/CoinbeneSwap.go b/coinbene/CoinbeneSwap.go
index d55bb151..421582a2 100644
--- a/coinbene/CoinbeneSwap.go
+++ b/coinbene/CoinbeneSwap.go
@@ -192,6 +192,18 @@ func (swap *CoinbeneSwap) PlaceFutureOrder(currencyPair CurrencyPair, contractTy
return data.orderId, nil
}
+func (swap *CoinbeneSwap) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int) (*FutureOrder, error) {
+ orderId, err := swap.PlaceFutureOrder(currencyPair, contractType, price, amount, openType, 0, 10)
+ return &FutureOrder{
+ Currency: currencyPair,
+ OrderID2: orderId,
+ Price: ToFloat64(price),
+ Amount: ToFloat64(amount),
+ OType: openType,
+ ContractName: contractType,
+ }, err
+}
+
func (swap *CoinbeneSwap) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) {
var param struct {
OrderId string `json:"orderId"`
diff --git a/huobi/Hbdm.go b/huobi/Hbdm.go
index 9ad23327..31485d60 100644
--- a/huobi/Hbdm.go
+++ b/huobi/Hbdm.go
@@ -57,8 +57,11 @@ var (
FuturesContractInfos []FuturesContractInfo
)
-func init() {
+func hbdmInit() {
go func() {
+ defer func() {
+ logger.Info("[hbdm] Get Futures Tick Size Finished.")
+ }()
interval := time.Second
intervalTimer := time.NewTimer(interval)
@@ -104,9 +107,9 @@ func init() {
ContractType: info.ContractType,
})
}
- interval = 10 * time.Minute
+ return
reset:
- intervalTimer.Reset(interval)
+ intervalTimer.Reset(10 * interval)
}
}
@@ -118,6 +121,7 @@ func NewHbdm(conf *APIConfig) *Hbdm {
if conf.Endpoint == "" {
conf.Endpoint = defaultBaseUrl
}
+ hbdmInit()
return &Hbdm{conf}
}
@@ -194,10 +198,14 @@ func (dm *Hbdm) GetFuturePosition(currencyPair CurrencyPair, contractType string
var positions []FuturePosition
for _, d := range data {
+ if d.ContractType != contractType {
+ continue
+ }
+
switch d.Direction {
case "buy":
positions = append(positions, FuturePosition{
- ContractType: contractType,
+ ContractType: d.ContractType,
ContractId: int64(ToInt(d.ContractCode[3:])),
Symbol: currencyPair,
BuyAmount: d.Volume,
@@ -208,7 +216,7 @@ func (dm *Hbdm) GetFuturePosition(currencyPair CurrencyPair, contractType string
LeverRate: d.LeverRate})
case "sell":
positions = append(positions, FuturePosition{
- ContractType: contractType,
+ ContractType: d.ContractType,
ContractId: int64(ToInt(d.ContractCode[3:])),
Symbol: currencyPair,
SellAmount: d.Volume,
@@ -224,6 +232,11 @@ func (dm *Hbdm) GetFuturePosition(currencyPair CurrencyPair, contractType string
}
func (dm *Hbdm) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (string, error) {
+ fOrder, err := dm.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, matchPrice, leverRate)
+ return fOrder.OrderID2, err
+}
+
+func (dm *Hbdm) PlaceFutureOrder2(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (*FutureOrder, error) {
var data struct {
OrderId int64 `json:"order_id"`
COrderId int64 `json:"client_order_id"`
@@ -232,6 +245,7 @@ func (dm *Hbdm) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price,
params := &url.Values{}
path := "/api/v1/contract_order"
+ params.Add("client_order_id", fmt.Sprint(time.Now().UnixNano()))
params.Add("contract_type", contractType)
params.Add("symbol", currencyPair.CurrencyA.Symbol)
params.Add("volume", amount)
@@ -251,7 +265,26 @@ func (dm *Hbdm) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price,
err := dm.doRequest(path, params, &data)
- return fmt.Sprint(data.OrderId), err
+ fOrd := &FutureOrder{
+ ClientOid: params.Get("client_order_id"),
+ ContractName: contractType,
+ Currency: currencyPair,
+ Price: ToFloat64(price),
+ Amount: ToFloat64(amount),
+ OType: openType,
+ }
+
+ if err != nil {
+ return fOrd, err
+ }
+
+ fOrd.OrderID2 = fmt.Sprint(data.OrderId)
+
+ return fOrd, err
+}
+
+func (dm *Hbdm) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int) (*FutureOrder, error) {
+ return dm.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, 0, 10)
}
func (dm *Hbdm) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) {
@@ -598,9 +631,9 @@ func (dm *Hbdm) adaptOffsetDirectionToOpenType(offset, direction string) int {
switch offset {
case "close":
if direction == "buy" {
- return CLOSE_BUY
- } else {
return CLOSE_SELL
+ } else {
+ return CLOSE_BUY
}
default:
@@ -670,15 +703,17 @@ func (dm *Hbdm) doRequest(path string, params *url.Values, data interface{}) err
}
func (dm *Hbdm) formatPriceSize(contract string, currency Currency, price string) string {
- var tickSize = 0
+ var tickSize = 2 //default set 2
for _, v := range FuturesContractInfos {
if (v.ContractType == contract || v.InstrumentID == contract) && v.UnderlyingIndex == currency.Symbol {
if v.PriceTickSize == 0 {
break
}
- for v.PriceTickSize < 1 {
+ tickSize = 0
+ priceSize := v.PriceTickSize
+ for priceSize < 1 {
tickSize++
- v.PriceTickSize *= 10
+ priceSize *= 10
}
break
}
diff --git a/huobi/Hbdm_Ws.go b/huobi/Hbdm_Ws.go
index 19a67d74..6b460768 100644
--- a/huobi/Hbdm_Ws.go
+++ b/huobi/Hbdm_Ws.go
@@ -76,6 +76,7 @@ func NewHbdmWs() *HbdmWs {
//Heartbeat(func() []byte { return []byte("{\"op\":\"ping\"}") }(), 5*time.Second).
DecompressFunc(GzipDecompress).
ProtoHandleFunc(hbdmWs.handle)
+ go hbdmInit()
return hbdmWs
}
@@ -144,7 +145,7 @@ func (hbdmWs *HbdmWs) handle(msg []byte) error {
hbdmWs.wsConn.SendMessage(pong)
return nil
}
-
+
var resp WsResponse
err := json.Unmarshal(msg, &resp)
if err != nil {
@@ -171,6 +172,7 @@ func (hbdmWs *HbdmWs) handle(msg []byte) error {
dep := ParseDepthFromResponse(depResp)
dep.ContractType = contract
+ dep.ContractId = hbdmWs.getContractId(contract)
dep.Pair = pair
dep.UTime = time.Unix(0, resp.Ts*int64(time.Millisecond))
@@ -266,3 +268,12 @@ func (hbdmWs *HbdmWs) adaptTime(tm string) int64 {
return t.UnixNano() / 1e6
}
+
+func (hbdmWs *HbdmWs) getContractId(alias string) string {
+ for _, info := range FuturesContractInfos {
+ if info.ContractType == alias {
+ return info.InstrumentID
+ }
+ }
+ return ""
+}
diff --git a/huobi/HuobiPro.go b/huobi/HuobiPro.go
index 314f8766..2f2a49eb 100644
--- a/huobi/HuobiPro.go
+++ b/huobi/HuobiPro.go
@@ -55,6 +55,8 @@ type HuoBiProSymbol struct {
QuoteCurrency string
PricePrecision float64
AmountPrecision float64
+ MinAmount float64
+ MinValue float64
SymbolPartition string
Symbol string
}
@@ -108,7 +110,7 @@ func NewHuoBiProSpot(client *http.Client, apikey, secretkey string) *HuoBiPro {
accinfo, err := hb.GetAccountInfo(HB_SPOT_ACCOUNT)
if err != nil {
hb.accountId = ""
- //panic(err)
+ panic(err)
} else {
hb.accountId = accinfo.Id
Log.Info("account state :", accinfo.State)
@@ -742,6 +744,8 @@ func (hbpro *HuoBiPro) GetCurrenciesPrecision() ([]HuoBiProSymbol, error) {
sym.QuoteCurrency = _sym["quote-currency"].(string)
sym.PricePrecision = _sym["price-precision"].(float64)
sym.AmountPrecision = _sym["amount-precision"].(float64)
+ sym.MinAmount = _sym["min-order-amt"].(float64)
+ sym.MinValue = _sym["min-order-value"].(float64)
sym.SymbolPartition = _sym["symbol-partition"].(string)
sym.Symbol = _sym["symbol"].(string)
Symbols = append(Symbols, sym)
diff --git a/okex/OKExFuture.go b/okex/OKExFuture.go
index b4303cff..6a02e1c1 100644
--- a/okex/OKExFuture.go
+++ b/okex/OKExFuture.go
@@ -4,11 +4,9 @@ import (
"errors"
"fmt"
"sort"
- "strings"
"sync"
"time"
- "github.com/google/uuid"
. "github.com/nntaoli-project/goex"
"github.com/nntaoli-project/goex/internal/logger"
)
@@ -81,11 +79,27 @@ func (ok *OKExFuture) GetAllFutureContractInfo() ([]FutureContractInfo, error) {
}
func (ok *OKExFuture) GetContractInfo(contractId string) (*FutureContractInfo, error) {
+ now := time.Now()
+ if len(ok.allContractInfo.contractInfos) == 0 ||
+ (ok.allContractInfo.uTime.Hour() < 16 && now.Hour() == 16 && now.Minute() <= 10) {
+ ok.Lock()
+ defer ok.Unlock()
+
+ infos, err := ok.GetAllFutureContractInfo()
+ if err != nil {
+ logger.Errorf("Get All Futures Contract Infos Error=%s", err)
+ } else {
+ ok.allContractInfo.contractInfos = infos
+ ok.allContractInfo.uTime = now
+ }
+ }
+
for _, itm := range ok.allContractInfo.contractInfos {
if itm.InstrumentID == contractId {
return &itm, nil
}
}
+
return nil, errors.New("unknown contract id " + contractId)
}
@@ -101,7 +115,7 @@ func (ok *OKExFuture) GetFutureContractId(pair CurrencyPair, contractAlias strin
hour := now.Hour()
minute := now.Minute()
- if ok.allContractInfo.uTime.IsZero() || (hour == 16 && minute <= 11) {
+ if ok.allContractInfo.uTime.IsZero() || (ok.allContractInfo.uTime.Hour() < 16 && hour == 16 && minute <= 11) {
ok.Lock()
defer ok.Unlock()
@@ -357,7 +371,7 @@ func (ok *OKExFuture) PlaceFutureOrder2(matchPrice int, ord *FutureOrder) (*Futu
return nil, errors.New("ord param is nil")
}
param.InstrumentId = ok.GetFutureContractId(ord.Currency, ord.ContractName)
- param.ClientOid = strings.Replace(uuid.New().String(), "-", "", 32)
+ param.ClientOid = GenerateOrderClientId(32)
param.Type = ord.OType
param.OrderType = ord.OrderType
param.Price = ok.normalizePrice(ord.Price, ord.Currency)
@@ -386,42 +400,24 @@ func (ok *OKExFuture) PlaceFutureOrder2(matchPrice int, ord *FutureOrder) (*Futu
}
func (ok *OKExFuture) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (string, error) {
- urlPath := "/api/futures/v3/order"
- var param struct {
- ClientOid string `json:"client_oid"`
- InstrumentId string `json:"instrument_id"`
- Type string `json:"type"`
- OrderType string `json:"order_type"`
- Price string `json:"price"`
- Size string `json:"size"`
- MatchPrice string `json:"match_price"`
- Leverage string `json:"leverage"`
- }
-
- var response struct {
- Result bool `json:"result"`
- ErrorMessage string `json:"error_message"`
- ErrorCode string `json:"error_code"`
- ClientOid string `json:"client_oid"`
- OrderId string `json:"order_id"`
- }
-
- param.InstrumentId = ok.GetFutureContractId(currencyPair, contractType)
- param.ClientOid = strings.Replace(uuid.New().String(), "-", "", 32)
- param.Type = fmt.Sprint(openType)
- param.OrderType = "0"
- param.Price = price
- param.Size = amount
- param.MatchPrice = fmt.Sprint(matchPrice)
- param.Leverage = fmt.Sprint(leverRate)
-
- reqBody, _, _ := ok.BuildRequestBody(param)
- err := ok.DoRequest("POST", urlPath, reqBody, &response)
- if err != nil {
- return "", err
- }
-
- return response.OrderId, nil
+ fOrder, err := ok.PlaceFutureOrder2(matchPrice, &FutureOrder{
+ Price: ToFloat64(price),
+ Amount: ToFloat64(amount),
+ OType: openType,
+ ContractName: contractType,
+ Currency: currencyPair,
+ })
+ return fOrder.OrderID2, err
+}
+
+func (ok *OKExFuture) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int) (*FutureOrder, error) {
+ return ok.PlaceFutureOrder2(0, &FutureOrder{
+ Currency: currencyPair,
+ Price: ToFloat64(price),
+ Amount: ToFloat64(amount),
+ OType: openType,
+ ContractName: contractType,
+ })
}
func (ok *OKExFuture) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) {
diff --git a/okex/OKExFuturesWs.go b/okex/OKExFuturesWs.go
index 05423d00..2de0cb47 100644
--- a/okex/OKExFuturesWs.go
+++ b/okex/OKExFuturesWs.go
@@ -68,7 +68,11 @@ func (okV3Ws *OKExV3FuturesWs) getChannelName(currencyPair CurrencyPair, contrac
} else {
prefix = "futures"
contractId = okV3Ws.base.OKExFuture.GetFutureContractId(currencyPair, contractType)
- logger.Info("contractid=", contractId)
+ // logger.Info("contractid=", contractId)
+ }
+
+ if contractId == "" {
+ return ""
}
channelName = prefix + "/%s:" + contractId
@@ -82,6 +86,9 @@ func (okV3Ws *OKExV3FuturesWs) SubscribeDepth(currencyPair CurrencyPair, contrac
}
chName := okV3Ws.getChannelName(currencyPair, contractType)
+ if chName == "" {
+ return errors.New("subscribe error, get channel name fail")
+ }
return okV3Ws.v3Ws.Subscribe(map[string]interface{}{
"op": "subscribe",
@@ -92,7 +99,12 @@ func (okV3Ws *OKExV3FuturesWs) SubscribeTicker(currencyPair CurrencyPair, contra
if okV3Ws.tickerCallback == nil {
return errors.New("please set ticker callback func")
}
+
chName := okV3Ws.getChannelName(currencyPair, contractType)
+ if chName == "" {
+ return errors.New("subscribe error, get channel name fail")
+ }
+
return okV3Ws.v3Ws.Subscribe(map[string]interface{}{
"op": "subscribe",
"args": []string{fmt.Sprintf(chName, "ticker")}})
@@ -102,7 +114,12 @@ func (okV3Ws *OKExV3FuturesWs) SubscribeTrade(currencyPair CurrencyPair, contrac
if okV3Ws.tradeCallback == nil {
return errors.New("please set trade callback func")
}
+
chName := okV3Ws.getChannelName(currencyPair, contractType)
+ if chName == "" {
+ return errors.New("subscribe error, get channel name fail")
+ }
+
return okV3Ws.v3Ws.Subscribe(map[string]interface{}{
"op": "subscribe",
"args": []string{fmt.Sprintf(chName, "trade")}})
@@ -119,6 +136,10 @@ func (okV3Ws *OKExV3FuturesWs) SubscribeKline(currencyPair CurrencyPair, contrac
}
chName := okV3Ws.getChannelName(currencyPair, contractType)
+ if chName == "" {
+ return errors.New("subscribe error, get channel name fail")
+ }
+
return okV3Ws.v3Ws.Subscribe(map[string]interface{}{
"op": "subscribe",
"args": []string{fmt.Sprintf(chName, fmt.Sprintf("candle%ds", seconds))}})
@@ -192,6 +213,7 @@ func (okV3Ws *OKExV3FuturesWs) handle(channel string, data json.RawMessage) erro
Vol: t.Volume24h,
Date: uint64(date.UnixNano() / int64(time.Millisecond)),
},
+ ContractId: t.InstrumentId,
ContractType: alias,
})
}
@@ -232,6 +254,7 @@ func (okV3Ws *OKExV3FuturesWs) handle(channel string, data json.RawMessage) erro
alias, pair := okV3Ws.getContractAliasAndCurrencyPairFromInstrumentId(depthResp[0].InstrumentId)
dep.Pair = pair
dep.ContractType = alias
+ dep.ContractId = depthResp[0].InstrumentId
dep.UTime, _ = time.Parse(time.RFC3339, depthResp[0].Timestamp)
for _, itm := range depthResp[0].Asks {
dep.AskList = append(dep.AskList, DepthRecord{
diff --git a/okex/OKExSpot.go b/okex/OKExSpot.go
index 8367fefc..2f111bb3 100644
--- a/okex/OKExSpot.go
+++ b/okex/OKExSpot.go
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/go-openapi/errors"
. "github.com/nntaoli-project/goex"
+ "github.com/nntaoli-project/goex/internal/logger"
"sort"
"strings"
"time"
@@ -110,7 +111,7 @@ func (ok *OKExSpot) BatchPlaceOrders(orders []Order) ([]PlaceOrderResponse, erro
func (ok *OKExSpot) PlaceOrder(ty string, ord *Order) (*Order, error) {
urlPath := "/api/spot/v3/orders"
param := PlaceOrderParam{
- ClientOid: ok.UUID(),
+ ClientOid: GenerateOrderClientId(32),
InstrumentId: ord.Currency.AdaptUsdToUsdt().ToLower().ToSymbol("-"),
}
@@ -205,9 +206,11 @@ func (ok *OKExSpot) CancelOrder(orderId string, currency CurrencyPair) (bool, er
}{currency.AdaptUsdToUsdt().ToLower().ToSymbol("-")}
reqBody, _, _ := ok.BuildRequestBody(param)
var response struct {
- ClientOid string `json:"client_oid"`
- OrderId string `json:"order_id"`
- Result bool `json:"result"`
+ ClientOid string `json:"client_oid"`
+ OrderId string `json:"order_id"`
+ Result bool `json:"result"`
+ ErrorCode string `json:"error_code"`
+ ErrorMessage string `json:"error_message"`
}
err := ok.OKEx.DoRequest("POST", urlPath, reqBody, &response)
if err != nil {
@@ -216,7 +219,7 @@ func (ok *OKExSpot) CancelOrder(orderId string, currency CurrencyPair) (bool, er
if response.Result {
return true, nil
}
- return false, errors.New(400, "cancel fail, unknown error")
+ return false, errors.New(400, fmt.Sprintf("cancel fail, %s", response.ErrorMessage))
}
type OrderResponse struct {
@@ -266,7 +269,7 @@ func (ok *OKExSpot) adaptOrder(response OrderResponse) *Order {
date, err := time.Parse(time.RFC3339, response.Timestamp)
//log.Println(date.Local().UnixNano()/int64(time.Millisecond))
if err != nil {
- println(err)
+ logger.Error("parse timestamp err=", err, ",timestamp=", response.Timestamp)
} else {
ordInfo.OrderTime = int(date.UnixNano() / int64(time.Millisecond))
}
@@ -312,7 +315,21 @@ func (ok *OKExSpot) GetUnfinishOrders(currency CurrencyPair) ([]Order, error) {
}
func (ok *OKExSpot) GetOrderHistorys(currency CurrencyPair, currentPage, pageSize int) ([]Order, error) {
- panic("unsupported")
+ urlPath := fmt.Sprintf("/api/spot/v3/orders?instrument_id=%s&state=7", currency.AdaptUsdToUsdt().ToSymbol("-"))
+ var response []OrderResponse
+ err := ok.OKEx.DoRequest("GET", urlPath, "", &response)
+ if err != nil {
+ return nil, err
+ }
+
+ var orders []Order
+ for _, itm := range response {
+ ord := ok.adaptOrder(itm)
+ ord.Currency = currency
+ orders = append(orders, *ord)
+ }
+
+ return orders, nil
}
func (ok *OKExSpot) GetExchangeName() string {
@@ -479,3 +496,55 @@ func (ok *OKExSpot) GetTrades(currencyPair CurrencyPair, since int64) ([]Trade,
return trades, nil
}
+
+type OKExSpotSymbol struct {
+ BaseCurrency string
+ QuoteCurrency string
+ PricePrecision float64
+ AmountPrecision float64
+ MinAmount float64
+ MinValue float64
+ SymbolPartition string
+ Symbol string
+}
+
+func (ok *OKExSpot) GetCurrenciesPrecision() ([]OKExSpotSymbol, error) {
+ var response []struct {
+ InstrumentId string `json:"instrument_id"`
+ BaseCurrency string `json:"base_currency"`
+ QuoteCurrency string `json:"quote_currency"`
+ MinSize float64 `json:"min_size,string"`
+ SizeIncrement string `json:"size_increment"`
+ TickSize string `json:"tick_size"`
+ }
+ err := ok.DoRequest("GET", "/api/spot/v3/instruments", "", &response)
+ if err != nil {
+ return nil, err
+ }
+
+ var Symbols []OKExSpotSymbol
+ for _, v := range response {
+ var sym OKExSpotSymbol
+ sym.BaseCurrency = v.BaseCurrency
+ sym.QuoteCurrency = v.QuoteCurrency
+ sym.Symbol = v.InstrumentId
+ sym.MinAmount = v.MinSize
+
+ pres := strings.Split(v.TickSize, ".")
+ if len(pres) == 1 {
+ sym.PricePrecision = 0
+ } else {
+ sym.PricePrecision = float64(len(pres[1]))
+ }
+
+ pres = strings.Split(v.SizeIncrement, ".")
+ if len(pres) == 1 {
+ sym.AmountPrecision = 0
+ } else {
+ sym.AmountPrecision = float64(len(pres[1]))
+ }
+
+ Symbols = append(Symbols, sym)
+ }
+ return Symbols, nil
+}
diff --git a/okex/OKExSwap.go b/okex/OKExSwap.go
index 5753d09f..0f8e9b18 100644
--- a/okex/OKExSwap.go
+++ b/okex/OKExSwap.go
@@ -6,10 +6,8 @@ import (
"fmt"
"net/url"
"strconv"
- "strings"
"time"
- "github.com/google/uuid"
. "github.com/nntaoli-project/goex"
)
@@ -280,12 +278,31 @@ type PlaceOrdersInfo struct {
}
func (ok *OKExSwap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (string, error) {
+ fOrder, err := ok.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, matchPrice, leverRate)
+ return fOrder.OrderID2, err
+}
+func (ok *OKExSwap) PlaceFutureOrder2(currencyPair CurrencyPair, contractType, price, amount string, openType, matchPrice, leverRate int) (*FutureOrder, error) {
+ cid := GenerateOrderClientId(32)
reqBody, _, _ := ok.OKEx.BuildRequestBody(PlaceOrderInfo{
- BasePlaceOrderInfo{ClientOid: strings.Replace(uuid.New().String(), "-", "", 32), Price: price, MatchPrice: fmt.Sprint(matchPrice), Type: fmt.Sprint(openType), Size: amount},
+ BasePlaceOrderInfo{
+ ClientOid: cid,
+ Price: price,
+ MatchPrice: fmt.Sprint(matchPrice),
+ Type: fmt.Sprint(openType),
+ Size: amount},
ok.adaptContractType(currencyPair),
})
+ fOrder := &FutureOrder{
+ ClientOid: cid,
+ Currency: currencyPair,
+ ContractName: contractType,
+ OType: openType,
+ Price: ToFloat64(price),
+ Amount: ToFloat64(amount),
+ }
+
var resp struct {
BaseResponse
OrderID string `json:"order_id"`
@@ -294,14 +311,20 @@ func (ok *OKExSwap) PlaceFutureOrder(currencyPair CurrencyPair, contractType, pr
err := ok.DoRequest("POST", PLACE_ORDER, reqBody, &resp)
if err != nil {
- return "", err
+ return fOrder, err
}
if resp.ErrorMessage != "" {
- return "", errors.New(fmt.Sprintf("%s:%s", resp.ErrorCode, resp.ErrorMessage))
+ return fOrder, errors.New(fmt.Sprintf("%s:%s", resp.ErrorCode, resp.ErrorMessage))
}
- return resp.OrderID, nil
+ fOrder.OrderID2 = resp.OrderID
+
+ return fOrder, nil
+}
+
+func (ok *OKExSwap) LimitFuturesOrder(currencyPair CurrencyPair, contractType, price, amount string, openType int) (*FutureOrder, error) {
+ return ok.PlaceFutureOrder2(currencyPair, contractType, price, amount, openType, 0, 10)
}
func (ok *OKExSwap) FutureCancelOrder(currencyPair CurrencyPair, contractType, orderId string) (bool, error) {
diff --git a/okex/OKExWallet.go b/okex/OKExWallet.go
index 32c1864e..d6d0c079 100644
--- a/okex/OKExWallet.go
+++ b/okex/OKExWallet.go
@@ -4,20 +4,6 @@ import (
"errors"
"fmt"
. "github.com/nntaoli-project/goex"
- "time"
-)
-
-const (
- SUB_ACCOUNT = iota //子账户
- SPOT // 币币交易
- _
- FUTURE //交割合约
- C2C //法币
- SPOT_MARGIN //币币杠杆交易
- WALLET // 资金账户
- _
- TIPS //余币宝
- SWAP //永续合约
)
const (
@@ -26,25 +12,6 @@ const (
WITHDRAWAL_COIN = 4 //提币到数字货币地址,跨平台提币或者提到自己钱包
)
-type TransferParameter struct {
- Currency string `json:"currency"`
- From int `json:"from"`
- To int `json:"to"`
- Amount float64 `json:"amount"`
- SubAccount string `json:"sub_account"`
- InstrumentId string `json:"instrument_id"`
- ToInstrumentId string `json:"to_instrument_id"`
-}
-
-type WithdrawParameter struct {
- Currency string `json:"currency"`
- Amount float64 `json:"amount,string"`
- Destination int `json:"destination"` //提币到(2:OKCoin国际 3:OKEx 4:数字货币地址)
- ToAddress string `json:"to_address"`
- TradePwd string `json:"trade_pwd"`
- Fee string `json:"fee"`
-}
-
type OKExWallet struct {
*OKEx
}
@@ -166,35 +133,22 @@ func (ok *OKExWallet) GetWithDrawalFee(currency *Currency) ([]WithdrawFee, error
return response, nil
}
-type DepositWithDrawHistory struct {
- WithdrawalId string `json:"withdrawal_id,omitempty"`
- Currency string `json:"currency"`
- Txid string `json:"txid"`
- Amount float64 `json:"amount,string"`
- From string `json:"from,omitempty"`
- To string `json:"to"`
- Memo string `json:"memo,omitempty"`
- Fee string `json:"fee"`
- Status int `json:"status,string"`
- Timestamp time.Time `json:"timestamp"`
-}
-
-func (ok *OKExWallet) GetWithDrawalHistory(currency *Currency) ([]DepositWithDrawHistory, error) {
+func (ok *OKExWallet) GetWithDrawHistory(currency *Currency) ([]DepositWithdrawHistory, error) {
urlPath := "/api/account/v3/withdrawal/history"
if currency != nil && *currency != UNKNOWN {
urlPath += "/" + currency.Symbol
}
- var response []DepositWithDrawHistory
+ var response []DepositWithdrawHistory
err := ok.DoRequest("GET", urlPath, "", &response)
return response, err
}
-func (ok *OKExWallet) GetDepositHistory(currency *Currency) ([]DepositWithDrawHistory, error) {
+func (ok *OKExWallet) GetDepositHistory(currency *Currency) ([]DepositWithdrawHistory, error) {
urlPath := "/api/account/v3/deposit/history"
if currency != nil && *currency != UNKNOWN {
urlPath += "/" + currency.Symbol
}
- var response []DepositWithDrawHistory
+ var response []DepositWithdrawHistory
err := ok.DoRequest("GET", urlPath, "", &response)
return response, err
}
diff --git a/okex/OKEx_test.go b/okex/OKEx_test.go
index aa477773..e4502658 100644
--- a/okex/OKEx_test.go
+++ b/okex/OKEx_test.go
@@ -239,3 +239,11 @@ func TestOKExMargin_CancelOrder(t *testing.T) {
func TestOKExMargin_GetOneOrder(t *testing.T) {
t.Log(okex.OKExMargin.GetOneOrder("3174778420532224", goex.EOS_USDT))
}
+
+func TestOKExSpot_GetCurrenciesPrecision(t *testing.T) {
+ t.Log(okex.OKExSpot.GetCurrenciesPrecision())
+}
+
+func TestOKExSpot_GetOrderHistorys(t *testing.T) {
+ t.Log(okex.OKExSpot.GetOrderHistorys(goex.BTC_USDT, 1, 10))
+}
diff --git a/okex/README.md b/okex/README.md
index b0793fae..9fd39471 100644
--- a/okex/README.md
+++ b/okex/README.md
@@ -23,7 +23,7 @@ var okex = NewOKEx(&goex.APIConfig{
)
//接口调用,更多接口调用请看代码
- log.Prinitln(okexSpot.GetAccount()) //获取账户资产信息
+ log.Println(okexSpot.GetAccount()) //获取账户资产信息
//okexSpot.BatchPlaceOrders([]goex.Order{...}) //批量下单,单个交易对同时最大只能下10笔
log.Println(okexSwap.GetFutureUserinfo()) //获取账户权益信息
log.Println(okexFuture.GetFutureUserinfo())//获取账户权益信息