trade endpoints

This commit is contained in:
wuhewuhe 2023-11-05 23:18:48 +01:00
parent 065fb758e2
commit 7dba469e44
8 changed files with 615 additions and 250 deletions

View File

@ -25,9 +25,6 @@ type ServerResponse struct {
Time int64 `json:"time"` Time int64 `json:"time"`
} }
// TimeInForceType define time in force type of order
type TimeInForceType string
// Client define API client // Client define API client
type Client struct { type Client struct {
APIKey string APIKey string
@ -237,7 +234,7 @@ func (c *Client) NewPlaceOrderService(category, symbol, side, orderType, qty str
} }
} }
func (c *Client) NewPlaceTradeService(params map[string]interface{}) *Trade { func (c *Client) NewTradeService(params map[string]interface{}) *Trade {
return &Trade{ return &Trade{
c: c, c: c,
params: params, params: params,

View File

@ -0,0 +1,51 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceBatchTrade()
}
func PlaceBatchTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "option",
"request": []map[string]interface{}{
{
"category": "option",
"symbol": "BTC-10FEB23-24000-C",
"orderType": "Limit",
"side": "Buy",
"qty": "0.1",
"price": "5",
"orderIv": "0.1",
"timeInForce": "GTC",
"orderLinkId": "9b381bb1-401",
"mmp": false,
"reduceOnly": false,
},
{
"category": "option",
"symbol": "BTC-10FEB23-24000-C",
"orderType": "Limit",
"side": "Buy",
"qty": "0.1",
"price": "5",
"orderIv": "0.1",
"timeInForce": "GTC",
"orderLinkId": "82ee86dd-001",
"mmp": false,
"reduceOnly": false,
},
},
}
orderResult, err := client.NewTradeService(params).PlaceBatchOrder(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
}

View File

@ -13,7 +13,7 @@ func main() {
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "side": "Buy", "positionIdx": 0, "orderType": "Limit", "qty": "0.001", "price": "10000", "timeInForce": "GTC"} params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "side": "Buy", "positionIdx": 0, "orderType": "Limit", "qty": "0.001", "price": "10000", "timeInForce": "GTC"}
orderResult, err := client.NewPlaceTradeService(params).Do(context.Background()) orderResult, err := client.NewTradeService(params).PlaceOrder(context.Background())
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return

92
models/orderResponse.go Normal file
View File

@ -0,0 +1,92 @@
package models
type OrderResult struct {
OrderId string `json:"orderId"`
OrderLinkId string `json:"orderLinkId"`
}
type ListOrderResult struct {
List []OrderResult `json:"list"`
}
type OrderInfo struct {
OrderId string `json:"orderId"`
OrderLinkId string `json:"orderLinkId"`
BlockTradeId string `json:"blockTradeId"`
Symbol string `json:"symbol"`
Price string `json:"price"`
Qty string `json:"qty"`
Side string `json:"side"`
IsLeverage string `json:"isLeverage"`
PositionIdx int `json:"positionIdx"`
OrderStatus string `json:"orderStatus"`
CancelType string `json:"cancelType"`
RejectReason string `json:"rejectReason"`
AvgPrice string `json:"avgPrice"`
LeavesQty string `json:"leavesQty"`
LeavesValue string `json:"leavesValue"`
CumExecQty string `json:"cumExecQty"`
CumExecValue string `json:"cumExecValue"`
CumExecFee string `json:"cumExecFee"`
TimeInForce string `json:"timeInForce"`
OrderType string `json:"orderType"`
StopOrderType string `json:"stopOrderType"`
OrderIv string `json:"orderIv"`
TriggerPrice string `json:"triggerPrice"`
TakeProfit string `json:"takeProfit"`
StopLoss string `json:"stopLoss"`
TpslMode string `json:"tpslMode"`
OcoTriggerType string `json:"ocoTriggerType"`
TpLimitPrice string `json:"tpLimitPrice"`
SlLimitPrice string `json:"slLimitPrice"`
TpTriggerBy string `json:"tpTriggerBy"`
SlTriggerBy string `json:"slTriggerBy"`
TriggerDirection int `json:"triggerDirection"`
TriggerBy string `json:"triggerBy"`
LastPriceOnCreated string `json:"lastPriceOnCreated"`
ReduceOnly bool `json:"reduceOnly"`
CloseOnTrigger bool `json:"closeOnTrigger"`
PlaceType string `json:"placeType"`
SmpType string `json:"smpType"`
SmpGroup int `json:"smpGroup"`
SmpOrderId string `json:"smpOrderId"`
CreatedTime string `json:"createdTime"`
UpdatedTime string `json:"updatedTime"`
}
type OpenOrdersInfo struct {
Category string `json:"category"`
NextPageCursor string `json:"nextPageCursor"`
List []OrderInfo `json:"list"`
}
type BorrowQuotaInfo struct {
Symbol string `json:"symbol"`
Side string `json:"side"`
MaxTradeQty string `json:"maxTradeQty"`
MaxTradeAmount string `json:"maxTradeAmount"`
SpotMaxTradeQty string `json:"spotMaxTradeQty"`
SpotMaxTradeAmount string `json:"spotMaxTradeAmount"`
BorrowCoin string `json:"borrowCoin"`
}
type BatchOrderServerResponse struct {
RetCode int `json:"retCode"`
RetMsg string `json:"retMsg"`
Result struct {
List []struct {
Category string `json:"category"`
Symbol string `json:"symbol"`
OrderId string `json:"orderId"`
OrderLinkId string `json:"orderLinkId"`
CreateAt *string `json:"createAt,omitempty"`
} `json:"list"`
} `json:"result"`
RetExtInfo struct {
List []struct {
Code int `json:"code"`
Msg string `json:"msg"`
} `json:"list"`
} `json:"retExtInfo"`
Time int64 `json:"time"`
}

View File

@ -0,0 +1 @@
package models

246
place_order.go Normal file
View File

@ -0,0 +1,246 @@
package bybit_connector
import (
"context"
"encoding/json"
"net/http"
)
type Order struct {
c *Client
category string
symbol string
isLeverage *int
side string
orderType string
qty string
price *string
triggerDirection *int
orderFilter *string
triggerPrice *string
triggerBy *string
orderIv *string
timeInForce *string
positionIdx *int
orderLinkId *string
takeProfit *string
stopLoss *string
tpTriggerBy *string
slTriggerBy *string
reduceOnly *bool
closeOnTrigger *bool
smpType *string
mmp *bool
tpslMode *string
tpLimitPrice *string
slLimitPrice *string
tpOrderType *string
slOrderType *string
}
func (order *Order) TimeInForce(tif string) *Order {
order.timeInForce = &tif
return order
}
func (order *Order) IsLeverage(isLeverage int) *Order {
order.isLeverage = &isLeverage
return order
}
func (order *Order) TriggerPrice(triggerPrice string) *Order {
order.triggerPrice = &triggerPrice
return order
}
func (order *Order) OrderLinkId(orderLinkId string) *Order {
order.orderLinkId = &orderLinkId
return order
}
func (order *Order) Price(price string) *Order {
order.price = &price
return order
}
func (order *Order) TriggerDirection(direction int) *Order {
order.triggerDirection = &direction
return order
}
func (order *Order) OrderFilter(filter string) *Order {
order.orderFilter = &filter
return order
}
func (order *Order) TriggerBy(triggerBy string) *Order {
order.triggerBy = &triggerBy
return order
}
func (order *Order) OrderIv(iv string) *Order {
order.orderIv = &iv
return order
}
func (order *Order) PositionIdx(idx int) *Order {
order.positionIdx = &idx
return order
}
func (order *Order) TakeProfit(profit string) *Order {
order.takeProfit = &profit
return order
}
func (order *Order) StopLoss(loss string) *Order {
order.stopLoss = &loss
return order
}
func (order *Order) TpTriggerBy(triggerBy string) *Order {
order.tpTriggerBy = &triggerBy
return order
}
func (order *Order) SlTriggerBy(triggerBy string) *Order {
order.slTriggerBy = &triggerBy
return order
}
func (order *Order) ReduceOnly(reduce bool) *Order {
order.reduceOnly = &reduce
return order
}
func (order *Order) CloseOnTrigger(close bool) *Order {
order.closeOnTrigger = &close
return order
}
func (order *Order) SmpType(smp string) *Order {
order.smpType = &smp
return order
}
func (order *Order) Mmp(mmp bool) *Order {
order.mmp = &mmp
return order
}
func (order *Order) TpslMode(mode string) *Order {
order.tpslMode = &mode
return order
}
func (order *Order) TpLimitPrice(price string) *Order {
order.tpLimitPrice = &price
return order
}
func (order *Order) SlLimitPrice(price string) *Order {
order.slLimitPrice = &price
return order
}
func (order *Order) TpOrderType(orderType string) *Order {
order.tpOrderType = &orderType
return order
}
func (order *Order) SlOrderType(orderType string) *Order {
order.slOrderType = &orderType
return order
}
func (order *Order) Do(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/create",
secType: secTypeSigned,
}
m := params{
"category": order.category,
"symbol": order.symbol,
"side": order.side,
"orderType": order.orderType,
"qty": order.qty,
}
if order.price != nil {
m["price"] = *order.price
}
if order.triggerDirection != nil {
m["triggerDirection"] = *order.triggerDirection
}
if order.orderFilter != nil {
m["orderFilter"] = *order.orderFilter
}
if order.triggerPrice != nil {
m["triggerPrice"] = *order.triggerPrice
}
if order.triggerBy != nil {
m["triggerBy"] = *order.triggerBy
}
if order.orderIv != nil {
m["orderIv"] = *order.orderIv
}
if order.timeInForce != nil {
m["timeInForce"] = *order.timeInForce
}
if order.positionIdx != nil {
m["positionIdx"] = *order.positionIdx
}
if order.orderLinkId != nil {
m["orderLinkId"] = *order.orderLinkId
}
if order.takeProfit != nil {
m["takeProfit"] = *order.takeProfit
}
if order.stopLoss != nil {
m["stopLoss"] = *order.stopLoss
}
if order.tpTriggerBy != nil {
m["tpTriggerBy"] = *order.tpTriggerBy
}
if order.slTriggerBy != nil {
m["slTriggerBy"] = *order.slTriggerBy
}
if order.reduceOnly != nil {
m["reduceOnly"] = *order.reduceOnly
}
if order.closeOnTrigger != nil {
m["closeOnTrigger"] = *order.closeOnTrigger
}
if order.smpType != nil {
m["smpType"] = *order.smpType
}
if order.mmp != nil {
m["mmp"] = *order.mmp
}
if order.tpslMode != nil {
m["tpslMode"] = *order.tpslMode
}
if order.tpLimitPrice != nil {
m["tpLimitPrice"] = *order.tpLimitPrice
}
if order.slLimitPrice != nil {
m["slLimitPrice"] = *order.slLimitPrice
}
if order.tpOrderType != nil {
m["tpOrderType"] = *order.tpOrderType
}
if order.slOrderType != nil {
m["slOrderType"] = *order.slOrderType
}
r.setParams(m)
data, err := order.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}

1
position.go Normal file
View File

@ -0,0 +1 @@
package bybit_connector

467
trade.go
View File

@ -4,259 +4,16 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers" "github.com/wuhewuhe/bybit.go.api/handlers"
"github.com/wuhewuhe/bybit.go.api/models"
"net/http" "net/http"
) )
type OrderResult struct {
OrderId string `json:"orderId"`
OrderLinkId string `json:"orderLinkId"`
}
type Trade struct { type Trade struct {
c *Client c *Client
params map[string]interface{} params map[string]interface{}
} }
type Order struct { func (s *Trade) PlaceOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
c *Client
category string
symbol string
isLeverage *int
side string
orderType string
qty string
price *string
triggerDirection *int
orderFilter *string
triggerPrice *string
triggerBy *string
orderIv *string
timeInForce *string
positionIdx *int
orderLinkId *string
takeProfit *string
stopLoss *string
tpTriggerBy *string
slTriggerBy *string
reduceOnly *bool
closeOnTrigger *bool
smpType *string
mmp *bool
tpslMode *string
tpLimitPrice *string
slLimitPrice *string
tpOrderType *string
slOrderType *string
}
func (order *Order) TimeInForce(tif string) *Order {
order.timeInForce = &tif
return order
}
func (order *Order) IsLeverage(isLeverage int) *Order {
order.isLeverage = &isLeverage
return order
}
func (order *Order) TriggerPrice(triggerPrice string) *Order {
order.triggerPrice = &triggerPrice
return order
}
func (order *Order) OrderLinkId(orderLinkId string) *Order {
order.orderLinkId = &orderLinkId
return order
}
func (order *Order) Price(price string) *Order {
order.price = &price
return order
}
func (order *Order) TriggerDirection(direction int) *Order {
order.triggerDirection = &direction
return order
}
func (order *Order) OrderFilter(filter string) *Order {
order.orderFilter = &filter
return order
}
func (order *Order) TriggerBy(triggerBy string) *Order {
order.triggerBy = &triggerBy
return order
}
func (order *Order) OrderIv(iv string) *Order {
order.orderIv = &iv
return order
}
func (order *Order) PositionIdx(idx int) *Order {
order.positionIdx = &idx
return order
}
func (order *Order) TakeProfit(profit string) *Order {
order.takeProfit = &profit
return order
}
func (order *Order) StopLoss(loss string) *Order {
order.stopLoss = &loss
return order
}
func (order *Order) TpTriggerBy(triggerBy string) *Order {
order.tpTriggerBy = &triggerBy
return order
}
func (order *Order) SlTriggerBy(triggerBy string) *Order {
order.slTriggerBy = &triggerBy
return order
}
func (order *Order) ReduceOnly(reduce bool) *Order {
order.reduceOnly = &reduce
return order
}
func (order *Order) CloseOnTrigger(close bool) *Order {
order.closeOnTrigger = &close
return order
}
func (order *Order) SmpType(smp string) *Order {
order.smpType = &smp
return order
}
func (order *Order) Mmp(mmp bool) *Order {
order.mmp = &mmp
return order
}
func (order *Order) TpslMode(mode string) *Order {
order.tpslMode = &mode
return order
}
func (order *Order) TpLimitPrice(price string) *Order {
order.tpLimitPrice = &price
return order
}
func (order *Order) SlLimitPrice(price string) *Order {
order.slLimitPrice = &price
return order
}
func (order *Order) TpOrderType(orderType string) *Order {
order.tpOrderType = &orderType
return order
}
func (order *Order) SlOrderType(orderType string) *Order {
order.slOrderType = &orderType
return order
}
func (order *Order) Do(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/create",
secType: secTypeSigned,
}
m := params{
"category": order.category,
"symbol": order.symbol,
"side": order.side,
"orderType": order.orderType,
"qty": order.qty,
}
if order.price != nil {
m["price"] = *order.price
}
if order.triggerDirection != nil {
m["triggerDirection"] = *order.triggerDirection
}
if order.orderFilter != nil {
m["orderFilter"] = *order.orderFilter
}
if order.triggerPrice != nil {
m["triggerPrice"] = *order.triggerPrice
}
if order.triggerBy != nil {
m["triggerBy"] = *order.triggerBy
}
if order.orderIv != nil {
m["orderIv"] = *order.orderIv
}
if order.timeInForce != nil {
m["timeInForce"] = *order.timeInForce
}
if order.positionIdx != nil {
m["positionIdx"] = *order.positionIdx
}
if order.orderLinkId != nil {
m["orderLinkId"] = *order.orderLinkId
}
if order.takeProfit != nil {
m["takeProfit"] = *order.takeProfit
}
if order.stopLoss != nil {
m["stopLoss"] = *order.stopLoss
}
if order.tpTriggerBy != nil {
m["tpTriggerBy"] = *order.tpTriggerBy
}
if order.slTriggerBy != nil {
m["slTriggerBy"] = *order.slTriggerBy
}
if order.reduceOnly != nil {
m["reduceOnly"] = *order.reduceOnly
}
if order.closeOnTrigger != nil {
m["closeOnTrigger"] = *order.closeOnTrigger
}
if order.smpType != nil {
m["smpType"] = *order.smpType
}
if order.mmp != nil {
m["mmp"] = *order.mmp
}
if order.tpslMode != nil {
m["tpslMode"] = *order.tpslMode
}
if order.tpLimitPrice != nil {
m["tpLimitPrice"] = *order.tpLimitPrice
}
if order.slLimitPrice != nil {
m["slLimitPrice"] = *order.slLimitPrice
}
if order.tpOrderType != nil {
m["tpOrderType"] = *order.tpOrderType
}
if order.slOrderType != nil {
m["slOrderType"] = *order.slOrderType
}
r.setParams(m)
data, err := order.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) Do(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil { if err = handlers.ValidateParams(s.params); err != nil {
return nil, err return nil, err
} }
@ -277,3 +34,223 @@ func (s *Trade) Do(ctx context.Context, opts ...RequestOption) (res *ServerRespo
} }
return res, nil return res, nil
} }
func (s *Trade) AmendOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/amend",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) CancelOrder(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/cancel",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) GetOpenOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/order/realtime",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) GetOrderHistory(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/order/history",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) GetSpotBorrowQuota(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/order/spot-borrow-check",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) CancelAllOrders(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/cancel-all",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) SetDisconnectCancelAll(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/disconnected-cancel-all",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) PlaceBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/create-batch",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(models.BatchOrderServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) AmendBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/amend-batch",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(models.BatchOrderServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *Trade) CancelBatchOrder(ctx context.Context, opts ...RequestOption) (res *models.BatchOrderServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/order/cancel-batch",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(models.BatchOrderServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}