Skip to content

Commit

Permalink
✨ New account endpoint, stoploss example
Browse files Browse the repository at this point in the history
  • Loading branch information
joeri-vv committed Nov 12, 2020
1 parent ccb5f02 commit 279fcc7
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 8 deletions.
101 changes: 97 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This is the Go wrapper for the Bitvavo API. This project can be used to build yo
* Cancel Orders [REST](https://github.com/bitvavo/go-bitvavo-api#cancel-orders) [Websocket](https://github.com/bitvavo/go-bitvavo-api#cancel-orders-1)
* Orders Open [REST](https://github.com/bitvavo/go-bitvavo-api#get-orders-open) [Websocket](https://github.com/bitvavo/go-bitvavo-api#get-orders-open-1)
* Trades [REST](https://github.com/bitvavo/go-bitvavo-api#get-trades) [Websocket](https://github.com/bitvavo/go-bitvavo-api#get-trades-1)
* Account [REST](https://github.com/bitvavo/go-bitvavo-api#get-account) [Websocket](https://github.com/bitvavo/go-bitvavo-api#get-account-1)
* Balance [REST](https://github.com/bitvavo/go-bitvavo-api#get-balance) [Websocket](https://github.com/bitvavo/go-bitvavo-api#get-balance-1)
* Deposit Assets [REST](https://github.com/bitvavo/go-bitvavo-api#deposit-assets) [Websocket](https://github.com/bitvavo/go-bitvavo-api#deposit-assets-1)
* Withdraw Assets [REST](https://github.com/bitvavo/go-bitvavo-api#withdraw-assets) [Websocket](https://github.com/bitvavo/go-bitvavo-api#withdraw-assets-1)
Expand Down Expand Up @@ -773,7 +774,9 @@ When placing an order, make sure that the correct optional parameters are set. F

```go
// optional parameters: limit:(amount, price, postOnly), market:(amount, amountQuote, disableMarketProtection),
// both: timeInForce, selfTradePrevention, responseRequired
// stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit:(amount, price, postOnly, triggerType, triggerReference, triggerAmount)
// all orderTypes: timeInForce, selfTradePrevention, responseRequired
response, err := bitvavo.PlaceOrder("BTC-EUR", "buy", "market", map[string]string{"amount": "0.3"})
if err != nil {
fmt.Println(err)
Expand Down Expand Up @@ -885,7 +888,8 @@ When updating an order make sure that at least one of the optional parameters ha

```go
// Optional parameters: limit:(amount, amountRemaining, price, timeInForce, selfTradePrevention, postOnly)
// (set at least 1) (responseRequired can be set as well, but does not update anything)
// untriggered stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit: (amount, price, postOnly, triggerType, triggerReference, triggerAmount)
response, err := bitvavo.UpdateOrder("BTC-EUR", "c2aa3b68-d72f-4a02-bb3d-30401f7d43ed",
map[string]string{"price": "4000"})
if err != nil {
Expand Down Expand Up @@ -1483,6 +1487,47 @@ type Trades struct {
```
</details>

#### Get Account
Returns the fee tier for this account.

```go
accountResponse, accountErr := bitvavo.Account()
if accountErr != nil {
fmt.Println(accountErr)
} else {
PrettyPrint(accountResponse)
}
```
<details>
<summary>View Response</summary>

```go
{
"fees": {
"taker": "0.0025",
"maker": "0.0015",
"volume": "100.00"
}
}
```
</details>

<details>
<summary>Struct Definition</summary>

```go
type Account struct {
Fees FeeObject `json:"fees"`
}

type FeeObject struct {
Taker string `json:"taker"`
Maker string `json:"maker"`
Volume string `json:"volume"`
}
```
</details>

#### Get balance
Returns the balance for this account.

Expand Down Expand Up @@ -2498,7 +2543,9 @@ When placing an order, make sure that the correct optional parameters are set. F

```go
// optional parameters: limit:(amount, price, postOnly), market:(amount, amountQuote, disableMarketProtection),
// both: timeInForce, selfTradePrevention, responseRequired
// stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit:(amount, price, postOnly, triggerType, triggerReference, triggerAmount)
// all orderTypes: timeInForce, selfTradePrevention, responseRequired
channel := websocket.PlaceOrder("BTC-EUR", "sell", "market", map[string]string{"amount": "0.3"})

for {
Expand Down Expand Up @@ -2614,7 +2661,8 @@ When updating an order make sure that at least one of the optional parameters ha

```go
// Optional parameters: limit:(amount, amountRemaining, price, timeInForce, selfTradePrevention, postOnly)
// (set at least 1) (responseRequired can be set as well, but does not update anything)
// untriggered stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit: (amount, price, postOnly, triggerType, triggerReference, triggerAmount)
channel := websocket.UpdateOrder("BTC-EUR", "4729e0c3-fb21-41cf-957c-4c406ea78b11",
map[string]string{"amount":"0.4"})

Expand Down Expand Up @@ -3239,6 +3287,51 @@ type Trades struct {
```
</details>

#### Get Account
Returns the fee tier for this account.

```go
channel := websocket.Account()

for {
select {
case errorMsg := <-errChannel:
fmt.Println("Handle error", errorMsg)
case result := <-channel:
fmt.Printf("%+v\n", result)
}
}
```
<details>
<summary>View Response</summary>

```go
{
"fees": {
"taker": "0.0025",
"maker": "0.0015",
"volume": "100.00"
}
}
```
</details>

<details>
<summary>Struct Definition</summary>

```go
type Account struct {
Fees FeeObject `json:"fees"`
}

type FeeObject struct {
Taker string `json:"taker"`
Maker string `json:"maker"`
Volume string `json:"volume"`
}
```
</details>

#### Get balance
Returns the balance for this account.

Expand Down
65 changes: 61 additions & 4 deletions bitvavo.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ type Order struct {
DisableMarketProtection bool `json:"disableMarketProtection"`
TimeInForce string `json:"timeInForce"`
PostOnly bool `json:"postOnly"`
TriggerAmount string `json:"triggerAmount"`
TriggerPrice string `json:"triggerPrice"`
TriggerType string `json:"triggerType"`
TriggerReference string `json:"triggerReference"`
}

type Fill struct {
Expand Down Expand Up @@ -246,6 +250,21 @@ type Trades struct {
Settled bool `json:"settled"`
}

type AccountResponse struct {
Action string `json:"action"`
Response Account `json:"response"`
}

type Account struct {
Fees FeeObject `json:"fees"`
}

type FeeObject struct {
Taker string `json:"taker"`
Maker string `json:"maker"`
Volume string `json:"volume"`
}

type BalanceResponse struct {
Action string `json:"action"`
Response []Balance `json:"response"`
Expand Down Expand Up @@ -350,6 +369,10 @@ type SubscriptionAccountOrder struct {
PostOnly bool `json:"postOnly"`
SelfTradePrevention string `json:"selfTradePrevention"`
Visible bool `json:"visible"`
TriggerAmount string `json:"triggerAmount"`
TriggerPrice string `json:"triggerPrice"`
TriggerType string `json:"triggerType"`
TriggerReference string `json:"triggerReference"`
}

type SubscriptionCandlesResponse struct {
Expand Down Expand Up @@ -489,6 +512,7 @@ type Websocket struct {
cancelOrdersChannel chan []CancelOrder
ordersOpenChannel chan []Order
tradesChannel chan []Trades
accountChannel chan Account
balanceChannel chan []Balance
depositAssetsChannel chan DepositAssets
withdrawAssetsChannel chan WithdrawAssets
Expand Down Expand Up @@ -814,7 +838,10 @@ func (bitvavo Bitvavo) Ticker24h(options map[string]string) ([]Ticker24h, error)
return t, nil
}

// optional body parameters: limit:(amount, price, postOnly), market:(amount, amountQuote, disableMarketProtection), both: timeInForce, selfTradePrevention, responseRequired
// optional body parameters: limit:(amount, price, postOnly), market:(amount, amountQuote, disableMarketProtection)
// stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit:(amount, price, postOnly, triggerType, triggerReference, triggerAmount)
// all orderTypes: timeInForce, selfTradePrevention, responseRequired
func (bitvavo Bitvavo) PlaceOrder(market string, side string, orderType string, body map[string]string) (Order, error) {
body["market"] = market
body["side"] = side
Expand Down Expand Up @@ -847,7 +874,8 @@ func (bitvavo Bitvavo) GetOrder(market string, orderId string) (Order, error) {
}

// Optional body parameters: limit:(amount, amountRemaining, price, timeInForce, selfTradePrevention, postOnly)
// (set at least 1) (responseRequired can be set as well, but does not update anything)
// untriggered stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit: (amount, price, postOnly, triggerType, triggerReference, triggerAmount)
func (bitvavo Bitvavo) UpdateOrder(market string, orderId string, body map[string]string) (Order, error) {
body["market"] = market
body["orderId"] = orderId
Expand Down Expand Up @@ -928,6 +956,16 @@ func (bitvavo Bitvavo) Trades(market string, options map[string]string) ([]Trade
return t, nil
}

func (bitvavo Bitvavo) Account() (Account, error) {
jsonResponse := bitvavo.sendPrivate("/account", "", map[string]string{}, "GET")
var t Account
err := json.Unmarshal(jsonResponse, &t)
if err != nil {
return Account{}, MyError{Err: err}
}
return t, nil
}

// options: symbol
func (bitvavo Bitvavo) Balance(options map[string]string) ([]Balance, error) {
postfix := bitvavo.createPostfix(options)
Expand Down Expand Up @@ -1367,6 +1405,13 @@ func (bitvavo Bitvavo) handleMessage(ws *Websocket) {
return
}
ws.tradesChannel <- t.Response
} else if x["action"] == "privateGetAccount" {
var t AccountResponse
err = json.Unmarshal(message, &t)
if handleError(err) {
return
}
ws.accountChannel <- t.Response
} else if x["action"] == "privateGetBalance" {
var t BalanceResponse
err = json.Unmarshal(message, &t)
Expand Down Expand Up @@ -1549,7 +1594,10 @@ func (ws *Websocket) sendPrivate(msg []byte) {
}
}

// optional body parameters: limit:(amount, price, postOnly), market:(amount, amountQuote, disableMarketProtection), both: timeInForce, selfTradePrevention, responseRequired
// optional body parameters: limit:(amount, price, postOnly), market:(amount, amountQuote, disableMarketProtection)
// stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit:(amount, price, postOnly, triggerType, triggerReference, triggerAmount)
// all orderTypes: timeInForce, selfTradePrevention, responseRequired
func (ws *Websocket) PlaceOrder(market string, side string, orderType string, body map[string]string) chan Order {
body["market"] = market
body["side"] = side
Expand All @@ -1570,7 +1618,8 @@ func (ws *Websocket) GetOrder(market string, orderId string) chan Order {
}

// Optional body parameters: limit:(amount, amountRemaining, price, timeInForce, selfTradePrevention, postOnly)
// (set at least 1) (responseRequired can be set as well, but does not update anything)
// untriggered stopLoss/takeProfit:(amount, amountQuote, disableMarketProtection, triggerType, triggerReference, triggerAmount)
// stopLossLimit/takeProfitLimit: (amount, price, postOnly, triggerType, triggerReference, triggerAmount)
func (ws *Websocket) UpdateOrder(market string, orderId string, body map[string]string) chan Order {
ws.updateOrderChannel = make(chan Order, 100)
body["market"] = market
Expand Down Expand Up @@ -1626,6 +1675,14 @@ func (ws *Websocket) Trades(market string, options map[string]string) chan []Tra
return ws.tradesChannel
}

func (ws *Websocket) Account() chan Account {
ws.accountChannel = make(chan Account, 100)
options := map[string]string{"action": "privateGetAccount"}
myMessage, _ := json.Marshal(options)
go ws.sendPrivate(myMessage)
return ws.accountChannel
}

// options: symbol
func (ws *Websocket) Balance(options map[string]string) chan []Balance {
ws.balanceChannel = make(chan []Balance, 100)
Expand Down
21 changes: 21 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ func testREST(bitvavo bitvavo.Bitvavo) {
// PrettyPrint(placeOrderResponse)
// }

// placeOrderResponse, placeOrderErr := bitvavo.PlaceOrder(
// "BTC-EUR",
// "sell",
// "stopLoss",
// map[string]string{"amount": "0.1", "triggerType": "price", "triggerReference": "lastTrade", "triggerAmount": "5000"})
// if placeOrderErr != nil {
// fmt.Println(placeOrderErr)
// } else {
// PrettyPrint(placeOrderResponse)
// }

// updateOrderResponse, updateOrderErr := bitvavo.UpdateOrder("BTC-EUR", "68c72b7a-2cf5-4516-8915-703a5d38c77e", map[string]string{"amount": "0.4"})
// if updateOrderErr != nil {
// fmt.Println(updateOrderErr)
Expand Down Expand Up @@ -190,6 +201,13 @@ func testREST(bitvavo bitvavo.Bitvavo) {
// }
// }

// accountResponse, accountErr := bitvavo.Account()
// if accountErr != nil {
// fmt.Println(accountErr)
// } else {
// PrettyPrint(accountResponse)
// }

// balanceResponse, balanceErr := bitvavo.Balance(map[string]string{})
// if balanceErr != nil {
// fmt.Println(balanceErr)
Expand Down Expand Up @@ -257,6 +275,7 @@ func testWebsocket(bitvavo bitvavo.Bitvavo) {

// tradesChannel := websocket.Trades("BTC-EUR", map[string]string{})

// accountChannel := websocket.Account()
// balanceChannel := websocket.Balance(map[string]string{})
// depositAssetsChannel := websocket.DepositAssets("BTC")
// withdrawAssetsChannel := websocket.WithdrawAssets("EUR", "50", "NL123BIM", map[string]string{})
Expand Down Expand Up @@ -310,6 +329,8 @@ func testWebsocket(bitvavo bitvavo.Bitvavo) {
// PrettyPrint(result)
// case result := <-tradesChannel:
// PrettyPrint(result)
// case result := <-accountChannel:
// PrettyPrint(result)
// case result := <-balanceChannel:
// PrettyPrint(result)
// case result := <-depositAssetsChannel:
Expand Down

0 comments on commit 279fcc7

Please sign in to comment.