Skip to content

Commit ae93736

Browse files
authored
Merge pull request #2 from bitvavo/account_endpoint_stoploss
✨ New account endpoint, stoploss example
2 parents ccb5f02 + 6b2e22b commit ae93736

File tree

3 files changed

+179
-8
lines changed

3 files changed

+179
-8
lines changed

README.md

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ This is the Go wrapper for the Bitvavo API. This project can be used to build yo
2828
* Cancel Orders [REST](https://github.com/bitvavo/go-bitvavo-api#cancel-orders) [Websocket](https://github.com/bitvavo/go-bitvavo-api#cancel-orders-1)
2929
* 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)
3030
* Trades [REST](https://github.com/bitvavo/go-bitvavo-api#get-trades) [Websocket](https://github.com/bitvavo/go-bitvavo-api#get-trades-1)
31+
* Account [REST](https://github.com/bitvavo/go-bitvavo-api#get-account) [Websocket](https://github.com/bitvavo/go-bitvavo-api#get-account-1)
3132
* Balance [REST](https://github.com/bitvavo/go-bitvavo-api#get-balance) [Websocket](https://github.com/bitvavo/go-bitvavo-api#get-balance-1)
3233
* Deposit Assets [REST](https://github.com/bitvavo/go-bitvavo-api#deposit-assets) [Websocket](https://github.com/bitvavo/go-bitvavo-api#deposit-assets-1)
3334
* Withdraw Assets [REST](https://github.com/bitvavo/go-bitvavo-api#withdraw-assets) [Websocket](https://github.com/bitvavo/go-bitvavo-api#withdraw-assets-1)
@@ -773,7 +774,9 @@ When placing an order, make sure that the correct optional parameters are set. F
773774

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

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

1490+
#### Get Account
1491+
Returns the fee tier for this account.
1492+
1493+
```go
1494+
accountResponse, accountErr := bitvavo.Account()
1495+
if accountErr != nil {
1496+
fmt.Println(accountErr)
1497+
} else {
1498+
PrettyPrint(accountResponse)
1499+
}
1500+
```
1501+
<details>
1502+
<summary>View Response</summary>
1503+
1504+
```go
1505+
{
1506+
"fees": {
1507+
"taker": "0.0025",
1508+
"maker": "0.0015",
1509+
"volume": "100.00"
1510+
}
1511+
}
1512+
```
1513+
</details>
1514+
1515+
<details>
1516+
<summary>Struct Definition</summary>
1517+
1518+
```go
1519+
type Account struct {
1520+
Fees FeeObject `json:"fees"`
1521+
}
1522+
1523+
type FeeObject struct {
1524+
Taker string `json:"taker"`
1525+
Maker string `json:"maker"`
1526+
Volume string `json:"volume"`
1527+
}
1528+
```
1529+
</details>
1530+
14861531
#### Get balance
14871532
Returns the balance for this account.
14881533

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

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

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

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

@@ -3239,6 +3287,51 @@ type Trades struct {
32393287
```
32403288
</details>
32413289

3290+
#### Get Account
3291+
Returns the fee tier for this account.
3292+
3293+
```go
3294+
channel := websocket.Account()
3295+
3296+
for {
3297+
select {
3298+
case errorMsg := <-errChannel:
3299+
fmt.Println("Handle error", errorMsg)
3300+
case result := <-channel:
3301+
fmt.Printf("%+v\n", result)
3302+
}
3303+
}
3304+
```
3305+
<details>
3306+
<summary>View Response</summary>
3307+
3308+
```go
3309+
{
3310+
"fees": {
3311+
"taker": "0.0025",
3312+
"maker": "0.0015",
3313+
"volume": "100.00"
3314+
}
3315+
}
3316+
```
3317+
</details>
3318+
3319+
<details>
3320+
<summary>Struct Definition</summary>
3321+
3322+
```go
3323+
type Account struct {
3324+
Fees FeeObject `json:"fees"`
3325+
}
3326+
3327+
type FeeObject struct {
3328+
Taker string `json:"taker"`
3329+
Maker string `json:"maker"`
3330+
Volume string `json:"volume"`
3331+
}
3332+
```
3333+
</details>
3334+
32423335
#### Get balance
32433336
Returns the balance for this account.
32443337

bitvavo.go

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ type Order struct {
181181
DisableMarketProtection bool `json:"disableMarketProtection"`
182182
TimeInForce string `json:"timeInForce"`
183183
PostOnly bool `json:"postOnly"`
184+
TriggerAmount string `json:"triggerAmount"`
185+
TriggerPrice string `json:"triggerPrice"`
186+
TriggerType string `json:"triggerType"`
187+
TriggerReference string `json:"triggerReference"`
184188
}
185189

186190
type Fill struct {
@@ -246,6 +250,21 @@ type Trades struct {
246250
Settled bool `json:"settled"`
247251
}
248252

253+
type AccountResponse struct {
254+
Action string `json:"action"`
255+
Response Account `json:"response"`
256+
}
257+
258+
type Account struct {
259+
Fees FeeObject `json:"fees"`
260+
}
261+
262+
type FeeObject struct {
263+
Taker string `json:"taker"`
264+
Maker string `json:"maker"`
265+
Volume string `json:"volume"`
266+
}
267+
249268
type BalanceResponse struct {
250269
Action string `json:"action"`
251270
Response []Balance `json:"response"`
@@ -350,6 +369,10 @@ type SubscriptionAccountOrder struct {
350369
PostOnly bool `json:"postOnly"`
351370
SelfTradePrevention string `json:"selfTradePrevention"`
352371
Visible bool `json:"visible"`
372+
TriggerAmount string `json:"triggerAmount"`
373+
TriggerPrice string `json:"triggerPrice"`
374+
TriggerType string `json:"triggerType"`
375+
TriggerReference string `json:"triggerReference"`
353376
}
354377

355378
type SubscriptionCandlesResponse struct {
@@ -489,6 +512,7 @@ type Websocket struct {
489512
cancelOrdersChannel chan []CancelOrder
490513
ordersOpenChannel chan []Order
491514
tradesChannel chan []Trades
515+
accountChannel chan Account
492516
balanceChannel chan []Balance
493517
depositAssetsChannel chan DepositAssets
494518
withdrawAssetsChannel chan WithdrawAssets
@@ -814,7 +838,10 @@ func (bitvavo Bitvavo) Ticker24h(options map[string]string) ([]Ticker24h, error)
814838
return t, nil
815839
}
816840

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

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

959+
func (bitvavo Bitvavo) Account() (Account, error) {
960+
jsonResponse := bitvavo.sendPrivate("/account", "", map[string]string{}, "GET")
961+
var t Account
962+
err := json.Unmarshal(jsonResponse, &t)
963+
if err != nil {
964+
return Account{}, MyError{Err: err}
965+
}
966+
return t, nil
967+
}
968+
931969
// options: symbol
932970
func (bitvavo Bitvavo) Balance(options map[string]string) ([]Balance, error) {
933971
postfix := bitvavo.createPostfix(options)
@@ -1367,6 +1405,13 @@ func (bitvavo Bitvavo) handleMessage(ws *Websocket) {
13671405
return
13681406
}
13691407
ws.tradesChannel <- t.Response
1408+
} else if x["action"] == "privateGetAccount" {
1409+
var t AccountResponse
1410+
err = json.Unmarshal(message, &t)
1411+
if handleError(err) {
1412+
return
1413+
}
1414+
ws.accountChannel <- t.Response
13701415
} else if x["action"] == "privateGetBalance" {
13711416
var t BalanceResponse
13721417
err = json.Unmarshal(message, &t)
@@ -1549,7 +1594,10 @@ func (ws *Websocket) sendPrivate(msg []byte) {
15491594
}
15501595
}
15511596

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

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

1678+
func (ws *Websocket) Account() chan Account {
1679+
ws.accountChannel = make(chan Account, 100)
1680+
options := map[string]string{"action": "privateGetAccount"}
1681+
myMessage, _ := json.Marshal(options)
1682+
go ws.sendPrivate(myMessage)
1683+
return ws.accountChannel
1684+
}
1685+
16291686
// options: symbol
16301687
func (ws *Websocket) Balance(options map[string]string) chan []Balance {
16311688
ws.balanceChannel = make(chan []Balance, 100)

example/main.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ func testREST(bitvavo bitvavo.Bitvavo) {
133133
// PrettyPrint(placeOrderResponse)
134134
// }
135135

136+
// placeOrderResponse, placeOrderErr := bitvavo.PlaceOrder(
137+
// "BTC-EUR",
138+
// "sell",
139+
// "stopLoss",
140+
// map[string]string{"amount": "0.1", "triggerType": "price", "triggerReference": "lastTrade", "triggerAmount": "5000"})
141+
// if placeOrderErr != nil {
142+
// fmt.Println(placeOrderErr)
143+
// } else {
144+
// PrettyPrint(placeOrderResponse)
145+
// }
146+
136147
// updateOrderResponse, updateOrderErr := bitvavo.UpdateOrder("BTC-EUR", "68c72b7a-2cf5-4516-8915-703a5d38c77e", map[string]string{"amount": "0.4"})
137148
// if updateOrderErr != nil {
138149
// fmt.Println(updateOrderErr)
@@ -190,6 +201,13 @@ func testREST(bitvavo bitvavo.Bitvavo) {
190201
// }
191202
// }
192203

204+
// accountResponse, accountErr := bitvavo.Account()
205+
// if accountErr != nil {
206+
// fmt.Println(accountErr)
207+
// } else {
208+
// PrettyPrint(accountResponse)
209+
// }
210+
193211
// balanceResponse, balanceErr := bitvavo.Balance(map[string]string{})
194212
// if balanceErr != nil {
195213
// fmt.Println(balanceErr)
@@ -257,6 +275,7 @@ func testWebsocket(bitvavo bitvavo.Bitvavo) {
257275

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

278+
// accountChannel := websocket.Account()
260279
// balanceChannel := websocket.Balance(map[string]string{})
261280
// depositAssetsChannel := websocket.DepositAssets("BTC")
262281
// withdrawAssetsChannel := websocket.WithdrawAssets("EUR", "50", "NL123BIM", map[string]string{})
@@ -310,6 +329,8 @@ func testWebsocket(bitvavo bitvavo.Bitvavo) {
310329
// PrettyPrint(result)
311330
// case result := <-tradesChannel:
312331
// PrettyPrint(result)
332+
// case result := <-accountChannel:
333+
// PrettyPrint(result)
313334
// case result := <-balanceChannel:
314335
// PrettyPrint(result)
315336
// case result := <-depositAssetsChannel:

0 commit comments

Comments
 (0)