Skip to content

Commit

Permalink
added trade and position endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
samuael committed Dec 13, 2024
1 parent 46dbb1f commit 03c6f55
Show file tree
Hide file tree
Showing 6 changed files with 773 additions and 2 deletions.
2 changes: 2 additions & 0 deletions exchanges/poloniex/poloniex.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ var (
errGranularityRequired = errors.New("granularity is required")
errBizNoRequired = errors.New("bizNo is required")
errInvalidSequenceNumber = errors.New("invalid sequence number")
errMarginAdjustTypeMissing = errors.New("margin adjust type invalid")
errPositionModeInvalid = errors.New("invalid position mode")
)

// Poloniex is the overarching type across the poloniex package
Expand Down
225 changes: 224 additions & 1 deletion exchanges/poloniex/poloniex_futures.go
Original file line number Diff line number Diff line change
Expand Up @@ -931,4 +931,227 @@ func (p *Poloniex) CloseAllAtMarketPrice(ctx context.Context) ([]FuturesV3OrderI
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodPost, "/v3/trade/positionAll", nil, nil, &resp, true)
}

// func (p *Poloniex) GetCurrentOrders(ctx context.Context)
// GetCurrentOrders get unfilled futures orders. If no request parameters are specified, you will get all open orders sorted on the creation time in chronological order.
func (p *Poloniex) GetCurrentOrders(ctx context.Context, symbol, side, orderID, clientOrderID, direction string, offset, limit int64) ([]FuturesV3Order, error) {
params := url.Values{}
if side != "" {
params.Set("side", side)
}
if symbol != "" {
params.Set("symbol", symbol)
}
if orderID != "" {
params.Set("ordId", orderID)
}
if clientOrderID != "" {
params.Set("clOrdId", clientOrderID)
}
if direction != "" {
params.Set("direct", direction)
}
if offset > 0 {
params.Set("from", strconv.FormatInt(offset, 10))
}
if limit > 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp []FuturesV3Order
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodGet, "/v3/trade/order/opens", params, nil, &resp, true)
}

// GetOrderExecutionDetails retrieves detailed information about your executed futures order
func (p *Poloniex) GetOrderExecutionDetails(ctx context.Context, symbol, orderID, clientOrderID, direction string, startTime, endTime time.Time, offset, limit int64) ([]FuturesV3Order, error) {
params := url.Values{}
if !startTime.IsZero() && !endTime.IsZero() {
err := common.StartEndTimeCheck(startTime, endTime)
if err != nil {
return nil, err
}
params.Set("sTime", strconv.FormatInt(startTime.UnixMilli(), 10))
params.Set("eTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if symbol != "" {
params.Set("symbol", symbol)
}
if orderID != "" {
params.Set("ordId", orderID)
}
if clientOrderID != "" {
params.Set("clOrdId", clientOrderID)
}
if direction != "" {
params.Set("direct", direction)
}
if offset > 0 {
params.Set("from", strconv.FormatInt(offset, 10))
}
if limit > 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp []FuturesV3Order
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodGet, "/v3/trade/order/trades", params, nil, &resp, true)
}

// GetV3FuturesOrderHistory retrieves previous futures orders. Orders that are completely canceled (no transaction has occurred) initiated through the API can only be queried for 4 hours.
func (p *Poloniex) GetV3FuturesOrderHistory(ctx context.Context, symbol, side, orderState, orderID, clientOrderID, direction string, startTime, endTime time.Time, offset, limit int64) ([]FuturesV3Order, error) {
params := url.Values{}
if !startTime.IsZero() && !endTime.IsZero() {
err := common.StartEndTimeCheck(startTime, endTime)
if err != nil {
return nil, err
}
params.Set("sTime", strconv.FormatInt(startTime.UnixMilli(), 10))
params.Set("eTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if side != "" {
params.Set("side", side)
}
if symbol != "" {
params.Set("symbol", symbol)
}
if orderState != "" {
params.Set("state", orderState)
}
if orderID != "" {
params.Set("ordId", orderID)
}
if clientOrderID != "" {
params.Set("clOrdId", clientOrderID)
}
if direction != "" {
params.Set("direct", direction)
}
if offset > 0 {
params.Set("from", strconv.FormatInt(offset, 10))
}
if limit > 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp []FuturesV3Order
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodGet, "/v3/trade/order/history", params, nil, &resp, true)
}

// ------------------------------------------------- Position Endpoints ----------------------------------------------------

// GetV3FuturesCurrentPosition retrieves information about your current position.
func (p *Poloniex) GetV3FuturesCurrentPosition(ctx context.Context, symbol string) ([]V3FuturesPosition, error) {
params := url.Values{}
if symbol != "" {
params.Set("symbol", symbol)
}
var resp []V3FuturesPosition
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodGet, "/v3/trade/position/opens", params, nil, &resp, true)
}

// GetV3FuturesPositionHistory get information about previous positions.
func (p *Poloniex) GetV3FuturesPositionHistory(ctx context.Context, symbol, marginMode, positionSide, direction string, startTime, endTime time.Time, offset, limit int64) ([]V3FuturesPosition, error) {
params := url.Values{}
if symbol != "" {
params.Set("symbol", symbol)
}
if marginMode != "" {
params.Set("mgnMode", marginMode)
}
if positionSide != "" {
params.Set("posSide", positionSide)
}
if !startTime.IsZero() && !endTime.IsZero() {
err := common.StartEndTimeCheck(startTime, endTime)
if err != nil {
return nil, err
}
params.Set("sTime", strconv.FormatInt(startTime.UnixMilli(), 10))
params.Set("eTime", strconv.FormatInt(endTime.UnixMilli(), 10))
}
if direction != "" {
params.Set("direct", direction)
}
if offset > 0 {
params.Set("from", strconv.FormatInt(offset, 10))
}
if limit > 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
var resp []V3FuturesPosition
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodGet, "/v3/trade/position/history", params, nil, &resp, true)
}

// AdjustMarginForIsolatedMarginTradingPositions add or reduce margin for positions in isolated margin mode.
func (p *Poloniex) AdjustMarginForIsolatedMarginTradingPositions(ctx context.Context, symbol, positionSide, adjustType string, amount float64) (*AdjustV3FuturesMarginResponse, error) {
if symbol == "" {
return nil, currency.ErrSymbolStringEmpty
}
if amount <= 0 {
return nil, order.ErrAmountBelowMin
}
if adjustType == "" {
return nil, errMarginAdjustTypeMissing
}
arg := &struct {
Symbol string `json:"symbol"`
PositionSide string `json:"posSide,omitempty"`
Amount float64 `json:"amt,string"`
Type string `json:"type"`
}{
Symbol: symbol,
PositionSide: positionSide,
Amount: amount,
Type: adjustType,
}
var resp *AdjustV3FuturesMarginResponse
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodPost, "/v3/trade/position/margin", nil, arg, &resp, true)
}

// GetV3FuturesLeverage retrieves the list of leverage.
func (p *Poloniex) GetV3FuturesLeverage(ctx context.Context, symbol, marginMode string) ([]V3FuturesLeverage, error) {
if symbol == "" {
return nil, currency.ErrSymbolStringEmpty
}
params := url.Values{}
params.Set("symbol", symbol)
if marginMode != "" {
params.Set("mgnMode", marginMode)
}
var resp []V3FuturesLeverage
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodGet, "/v3/position/leverages", params, nil, &resp, true)
}

// SetV3FuturesLeverage change leverage
func (p *Poloniex) SetV3FuturesLeverage(ctx context.Context, symbol, marginMode, positionSide string, leverage int64) (*V3FuturesLeverage, error) {
if symbol == "" {
return nil, currency.ErrSymbolStringEmpty
}
if marginMode == "" {
return nil, margin.ErrInvalidMarginType
}
if positionSide == "" {
return nil, order.ErrSideIsInvalid
}
if leverage <= 0 {
return nil, order.ErrSubmitLeverageNotSupported
}
var resp *V3FuturesLeverage
return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodPost, "/v3/position/leverage", nil, map[string]string{
"symbol": symbol,
"mgnMode": marginMode,
"posSide": positionSide,
"lever": strconv.FormatInt(leverage, 10),
}, &resp, true)
}

// SwitchPositionMode switch the current position mode. Please ensure you do not have open positions and open orders under this mode before the switch.
// Position mode, HEDGE: LONG/SHORT, ONE_WAY: BOTH
func (p *Poloniex) SwitchPositionMode(ctx context.Context, positionMode string) error {
if positionMode == "" {
return errPositionModeInvalid
}
return p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodPost, "/v3/position/mode", nil, map[string]string{"posMode": positionMode}, &struct{}{}, true)
}

// GetPositionMode get the current position mode.
func (p *Poloniex) GetPositionMode(ctx context.Context) (string, error) {
resp := &struct {
PositionMode string `json:"posMode"`
}{}
return resp.PositionMode, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, request.UnAuth, http.MethodGet, "/v3/position/mode", nil, nil, &resp, true)
}
89 changes: 89 additions & 0 deletions exchanges/poloniex/poloniex_futures_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,92 @@ type CancelOrdersParams struct {
OrderIDs []string `json:"ordIds,omitempty"`
ClientOrderIDs []string `json:"clOrdIds,omitempty"`
}

// FuturesV3Order represents a futures v3 order detail
type FuturesV3Order struct {
OrderID string `json:"ordId"`
AveragePrice types.Number `json:"avgPx"`
CreationTime types.Time `json:"cTime"`
ClientOrderID string `json:"clOrdId"`
DeductAmount types.Number `json:"deductAmt"`
ExecutedAmount types.Number `json:"execAmt"`
DeductCurrency string `json:"deductCcy"`
ExecQuantity types.Number `json:"execQty"`
FeeAmount types.Number `json:"feeAmt"`
FeeCurrency string `json:"feeCcy"`
PositionSide string `json:"posSide"`
Leverage string `json:"lever"`
MarginMode string `json:"mgnMode"`
Price types.Number `json:"px"`
ReduceOnly bool `json:"reduceOnly"`
StopLossPrice types.Number `json:"slPx"`
Side string `json:"side"`
StopLossTriggerPrice string `json:"slTrgPx"`
StopLossTriggerPriceType string `json:"slTrgPxType"`
Source string `json:"source"`
State string `json:"state"`
SelfTradePreventionMode string `json:"stpMode"`
Symbol string `json:"symbol"`
Size types.Number `json:"sz"`
TimeInForce string `json:"timeInForce"`
TakeProfitPrice types.Number `json:"tpPx"`
TakeProfitTriggerPrice types.Number `json:"tpTrgPx"`
TakeProfitTriggerPriceType string `json:"tpTrgPxType"`
Type string `json:"type"`
UpdateTime types.Time `json:"uTime"`
FeeRate types.Number `json:"feeRate"`
ID string `json:"id"`
OrderType string `json:"ordType"`
Quantity types.Number `json:"qty"`
Role string `json:"role"`
TradeID string `json:"trdId"`
CancelReason string `json:"cancelReason"`
}

// V3FuturesPosition represents a v3 futures position detail
type V3FuturesPosition struct {
AutoDeleveraging string `json:"adl"`
AvailQuantity types.Number `json:"availQty"`
CreationTime types.Time `json:"cTime"`
InitialMargin types.Number `json:"im"`
Leverage types.Number `json:"lever"`
LiqudiationPrice types.Number `json:"liqPx"`
MarkPrice types.Number `json:"markPx"`
IsolatedPositionMargin string `json:"mgn"`
MarginMode string `json:"mgnMode"`
PositionSide string `json:"posSide"`
MarginRatio types.Number `json:"mgnRatio"`
MaintenanceMargin string `json:"mm"`
OpenAveragePrice types.Number `json:"openAvgPx"`
ProfitAndLoss types.Number `json:"pnl"`
Quantity types.Number `json:"qty"`
Side string `json:"side"`
State string `json:"state"`
Symbol string `json:"symbol"`
UpdateTime types.Time `json:"uTime"`
UnrealizedPNL types.Number `json:"upl"`
UnrealizedPNLRatio types.Number `json:"uplRatio"`

CloseAvgPx string `json:"closeAvgPx"`
ClosedQty string `json:"closedQty"`
FFee string `json:"fFee"`
Fee string `json:"fee"`
ID string `json:"id"`
}

// AdjustV3FuturesMarginResponse represents a response data after adjusting futures margin positions
type AdjustV3FuturesMarginResponse struct {
Amount types.Number `json:"amt"`
Leverage types.Number `json:"lever"`
Symbol string `json:"symbol"`
PositionSide string `json:"posSide"`
OrderType string `json:"type"`
}

// V3FuturesLeverage represents futures symbols leverage information
type V3FuturesLeverage struct {
Leverage types.Number `json:"lever"`
MarginMode string `json:"mgnMode"`
PositionSide string `json:"posSide"`
Symbol string `json:"symbol"`
}
2 changes: 1 addition & 1 deletion exchanges/poloniex/poloniex_live_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ func TestMain(m *testing.M) {
if err != nil {
log.Fatal(err)
}
// p.HTTPRecording = true
p.HTTPRecording = true
os.Exit(m.Run())
}
Loading

0 comments on commit 03c6f55

Please sign in to comment.