mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-31 07:26:44 +00:00
Binance,Okx: Add Leverage, MarginType, Positions and CollateralMode support (#1220)
* init * surprise train commit * basic distinctions * the terms of binance are confusing * renames and introduction of allocatedMargin * add new margin funcs * pulling out wires * implement proper getposition stuff * bad coding day * investigate order manager next * a broken mess, but a progressing one * finally completes some usdtmargined stuff * coinMfutures eludes me * expand to okx * imports fix * completes okx wrapper implementations * cleans and polishes before rpc implementations * rpc setup, order manager features, exch features * more rpc, collateral and margin things * mini test * looking at rpc response, expansion of features * reorganising before the storm * changing how futures requests work * cleanup and tests of cli usage * remove silly client side logic * cleanup * collateral package, typo fix, margin err, rpc derive * uses convert.StringToFloat ONLY ON STRUCTS FROM THIS PR * fix binance order history bug * niteroos * adds new funcs to exchange standards testing * more post merge fixes * fix binance * replace simepletimeformat * fix for merge * merge fixes * micro fixes * order side now required for leverage * fix up the rest * global -> portfolio collateral * Update exchanges/collateral/collateral_test.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * adds fields and todos * rm field redundancy * lint fix oopsie daisy * fixes panic, expands error and cli explanations (sorry shaz) * ensures casing is appropriate for underlying * Adds a shiny TODO --------- Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
@@ -9,7 +9,9 @@ import (
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/collateral"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/margin"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -35,6 +37,8 @@ var (
|
||||
ErrNoPositionsFound = errors.New("no positions found")
|
||||
// ErrGetFundingDataRequired is returned when requesting funding rate data without the prerequisite
|
||||
ErrGetFundingDataRequired = errors.New("getfundingdata is a prerequisite")
|
||||
// ErrOrderHistoryTooLarge is returned when you lookup order history, but with too early a start date
|
||||
ErrOrderHistoryTooLarge = errors.New("order history start date too long ago")
|
||||
|
||||
errExchangeNameEmpty = errors.New("exchange name empty")
|
||||
errExchangeNameMismatch = errors.New("exchange name mismatch")
|
||||
@@ -65,57 +69,12 @@ type TotalCollateralResponse struct {
|
||||
TotalValueOfPositiveSpotBalances decimal.Decimal
|
||||
CollateralContributedByPositiveSpotBalances decimal.Decimal
|
||||
UsedCollateral decimal.Decimal
|
||||
UsedBreakdown *UsedCollateralBreakdown
|
||||
UsedBreakdown *collateral.UsedBreakdown
|
||||
AvailableCollateral decimal.Decimal
|
||||
AvailableMaintenanceCollateral decimal.Decimal
|
||||
UnrealisedPNL decimal.Decimal
|
||||
BreakdownByCurrency []CollateralByCurrency
|
||||
BreakdownOfPositions []CollateralByPosition
|
||||
}
|
||||
|
||||
// CollateralByPosition shows how much collateral is used
|
||||
// from positions
|
||||
type CollateralByPosition struct {
|
||||
PositionCurrency currency.Pair
|
||||
Size decimal.Decimal
|
||||
OpenOrderSize decimal.Decimal
|
||||
PositionSize decimal.Decimal
|
||||
MarkPrice decimal.Decimal
|
||||
RequiredMargin decimal.Decimal
|
||||
CollateralUsed decimal.Decimal
|
||||
}
|
||||
|
||||
// CollateralByCurrency individual collateral contribution
|
||||
// along with what the potentially scaled collateral
|
||||
// currency it is represented as
|
||||
// eg in Bybit ScaledCurrency is USDC
|
||||
type CollateralByCurrency struct {
|
||||
Currency currency.Code
|
||||
SkipContribution bool
|
||||
TotalFunds decimal.Decimal
|
||||
AvailableForUseAsCollateral decimal.Decimal
|
||||
CollateralContribution decimal.Decimal
|
||||
AdditionalCollateralUsed decimal.Decimal
|
||||
FairMarketValue decimal.Decimal
|
||||
Weighting decimal.Decimal
|
||||
ScaledCurrency currency.Code
|
||||
UnrealisedPNL decimal.Decimal
|
||||
ScaledUsed decimal.Decimal
|
||||
ScaledUsedBreakdown *UsedCollateralBreakdown
|
||||
Error error
|
||||
}
|
||||
|
||||
// UsedCollateralBreakdown provides a detailed
|
||||
// breakdown of where collateral is currently being allocated
|
||||
type UsedCollateralBreakdown struct {
|
||||
LockedInStakes decimal.Decimal
|
||||
LockedInNFTBids decimal.Decimal
|
||||
LockedInFeeVoucher decimal.Decimal
|
||||
LockedInSpotMarginFundingOffers decimal.Decimal
|
||||
LockedInSpotOrders decimal.Decimal
|
||||
LockedAsCollateral decimal.Decimal
|
||||
UsedInPositions decimal.Decimal
|
||||
UsedInSpotMarginBorrows decimal.Decimal
|
||||
BreakdownByCurrency []collateral.ByCurrency
|
||||
BreakdownOfPositions []collateral.ByPosition
|
||||
}
|
||||
|
||||
// PositionController manages all futures orders
|
||||
@@ -310,38 +269,27 @@ type Position struct {
|
||||
type PositionSummaryRequest struct {
|
||||
Asset asset.Item
|
||||
Pair currency.Pair
|
||||
// UnderlyingPair is optional if the exchange requires it for a contract like BTCUSDT-13333337
|
||||
UnderlyingPair currency.Pair
|
||||
|
||||
// offline calculation requirements below
|
||||
CalculateOffline bool
|
||||
Direction Side
|
||||
FreeCollateral decimal.Decimal
|
||||
TotalCollateral decimal.Decimal
|
||||
OpeningPrice decimal.Decimal
|
||||
CurrentPrice decimal.Decimal
|
||||
OpeningSize decimal.Decimal
|
||||
CurrentSize decimal.Decimal
|
||||
CollateralUsed decimal.Decimal
|
||||
NotionalPrice decimal.Decimal
|
||||
Leverage decimal.Decimal
|
||||
MaxLeverageForAccount decimal.Decimal
|
||||
TotalAccountValue decimal.Decimal
|
||||
TotalOpenPositionNotional decimal.Decimal
|
||||
}
|
||||
|
||||
// PositionSummary returns basic details on an open position
|
||||
type PositionSummary struct {
|
||||
MaintenanceMarginRequirement decimal.Decimal
|
||||
InitialMarginRequirement decimal.Decimal
|
||||
EstimatedLiquidationPrice decimal.Decimal
|
||||
CollateralUsed decimal.Decimal
|
||||
MarkPrice decimal.Decimal
|
||||
CurrentSize decimal.Decimal
|
||||
BreakEvenPrice decimal.Decimal
|
||||
AverageOpenPrice decimal.Decimal
|
||||
RecentPNL decimal.Decimal
|
||||
MarginFraction decimal.Decimal
|
||||
FreeCollateral decimal.Decimal
|
||||
TotalCollateral decimal.Decimal
|
||||
// EstimatePosition if enabled, can be used to calculate a new position
|
||||
EstimatePosition bool
|
||||
// These fields are also used for offline calculation
|
||||
OpeningPrice decimal.Decimal
|
||||
OpeningSize decimal.Decimal
|
||||
Leverage decimal.Decimal
|
||||
Direction Side
|
||||
TotalAccountValue decimal.Decimal
|
||||
}
|
||||
|
||||
// PositionDetails are used to track open positions
|
||||
@@ -359,4 +307,56 @@ type PositionsRequest struct {
|
||||
Asset asset.Item
|
||||
Pairs currency.Pairs
|
||||
StartDate time.Time
|
||||
EndDate time.Time
|
||||
// RespectOrderHistoryLimits is designed for the order manager
|
||||
// it allows for orders to be tracked if the start date in the config is
|
||||
// beyond the allowable limits by the API, rather than returning an error
|
||||
RespectOrderHistoryLimits bool
|
||||
}
|
||||
|
||||
// PositionResponse are used to track open positions
|
||||
// in the order manager
|
||||
type PositionResponse struct {
|
||||
Pair currency.Pair
|
||||
Asset asset.Item
|
||||
Orders []Detail
|
||||
}
|
||||
|
||||
// PositionSummary returns basic details on an open position
|
||||
type PositionSummary struct {
|
||||
Pair currency.Pair
|
||||
Asset asset.Item
|
||||
MarginType margin.Type
|
||||
CollateralMode collateral.Mode
|
||||
// The currency in which the values are quoted against. Isn't always pair.Quote
|
||||
// eg BTC-USDC-230929's quote in GCT is 230929, but the currency should be USDC
|
||||
Currency currency.Code
|
||||
|
||||
AvailableEquity decimal.Decimal
|
||||
CashBalance decimal.Decimal
|
||||
DiscountEquity decimal.Decimal
|
||||
EquityUSD decimal.Decimal
|
||||
IsolatedEquity decimal.Decimal
|
||||
IsolatedLiabilities decimal.Decimal
|
||||
IsolatedUPL decimal.Decimal
|
||||
NotionalLeverage decimal.Decimal
|
||||
TotalEquity decimal.Decimal
|
||||
StrategyEquity decimal.Decimal
|
||||
|
||||
IsolatedMargin decimal.Decimal
|
||||
NotionalSize decimal.Decimal
|
||||
Leverage decimal.Decimal
|
||||
MaintenanceMarginRequirement decimal.Decimal
|
||||
InitialMarginRequirement decimal.Decimal
|
||||
EstimatedLiquidationPrice decimal.Decimal
|
||||
CollateralUsed decimal.Decimal
|
||||
MarkPrice decimal.Decimal
|
||||
CurrentSize decimal.Decimal
|
||||
AverageOpenPrice decimal.Decimal
|
||||
PositionPNL decimal.Decimal
|
||||
MaintenanceMarginFraction decimal.Decimal
|
||||
FreeCollateral decimal.Decimal
|
||||
TotalCollateral decimal.Decimal
|
||||
FrozenBalance decimal.Decimal
|
||||
EquityOfCurrency decimal.Decimal
|
||||
}
|
||||
|
||||
@@ -820,7 +820,7 @@ func TestStringToOrderSide(t *testing.T) {
|
||||
{"any", AnySide, nil},
|
||||
{"ANY", AnySide, nil},
|
||||
{"aNy", AnySide, nil},
|
||||
{"woahMan", UnknownSide, errUnrecognisedOrderSide},
|
||||
{"woahMan", UnknownSide, ErrSideIsInvalid},
|
||||
}
|
||||
for i := range cases {
|
||||
testData := &cases[i]
|
||||
@@ -1340,8 +1340,8 @@ func TestValidationOnOrderTypes(t *testing.T) {
|
||||
|
||||
getOrders.AssetType = asset.Spot
|
||||
err = getOrders.Validate()
|
||||
if !errors.Is(err, errUnrecognisedOrderSide) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, errUnrecognisedOrderSide)
|
||||
if !errors.Is(err, ErrSideIsInvalid) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, ErrSideIsInvalid)
|
||||
}
|
||||
|
||||
getOrders.Side = AnySide
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/margin"
|
||||
)
|
||||
|
||||
// var error definitions
|
||||
@@ -19,10 +20,12 @@ var (
|
||||
ErrPairIsEmpty = errors.New("order pair is empty")
|
||||
ErrAssetNotSet = errors.New("order asset type is not set")
|
||||
ErrSideIsInvalid = errors.New("order side is invalid")
|
||||
ErrCollateralInvalid = errors.New("collateral type is invalid")
|
||||
ErrTypeIsInvalid = errors.New("order type is invalid")
|
||||
ErrAmountIsInvalid = errors.New("order amount is equal or less than zero")
|
||||
ErrPriceMustBeSetIfLimitOrder = errors.New("order price must be set if limit order type is desired")
|
||||
ErrOrderIDNotSet = errors.New("order id or client order id is not set")
|
||||
ErrSubmitLeverageNotSupported = errors.New("leverage is not supported via order submission")
|
||||
ErrClientOrderIDNotSupported = errors.New("client order id not supported")
|
||||
ErrUnsupportedOrderType = errors.New("unsupported order type")
|
||||
// ErrNoRates is returned when no margin rates are returned when they are expected
|
||||
@@ -64,6 +67,9 @@ type Submit struct {
|
||||
TriggerPrice float64
|
||||
ClientID string // TODO: Shift to credentials
|
||||
ClientOrderID string
|
||||
// MarginType such as isolated or cross margin for when an exchange
|
||||
// supports margin type definition when submitting an order eg okx
|
||||
MarginType margin.Type
|
||||
// RetrieveFees use if an API submit order response does not return fees
|
||||
// enabling this will perform additional request(s) to retrieve them
|
||||
// and set it in the SubmitResponse
|
||||
@@ -103,6 +109,7 @@ type SubmitResponse struct {
|
||||
Fee float64
|
||||
FeeAsset currency.Code
|
||||
Cost float64
|
||||
MarginType margin.Type
|
||||
}
|
||||
|
||||
// Modify contains all properties of an order
|
||||
@@ -191,6 +198,7 @@ type Detail struct {
|
||||
CloseTime time.Time
|
||||
LastUpdated time.Time
|
||||
Pair currency.Pair
|
||||
MarginType margin.Type
|
||||
Trades []TradeHistory
|
||||
}
|
||||
|
||||
@@ -226,6 +234,7 @@ type Cancel struct {
|
||||
Side Side
|
||||
AssetType asset.Item
|
||||
Pair currency.Pair
|
||||
MarginType margin.Type
|
||||
}
|
||||
|
||||
// CancelAllResponse returns the status from attempting to
|
||||
|
||||
@@ -35,7 +35,6 @@ var (
|
||||
ErrOrderNotFound = errors.New("order not found")
|
||||
|
||||
errTimeInForceConflict = errors.New("multiple time in force options applied")
|
||||
errUnrecognisedOrderSide = errors.New("unrecognised order side")
|
||||
errUnrecognisedOrderType = errors.New("unrecognised order type")
|
||||
errUnrecognisedOrderStatus = errors.New("unrecognised order status")
|
||||
errExchangeNameUnset = errors.New("exchange name unset")
|
||||
@@ -476,6 +475,7 @@ func (s *Submit) DeriveSubmitResponse(orderID string) (*SubmitResponse, error) {
|
||||
TriggerPrice: s.TriggerPrice,
|
||||
ClientID: s.ClientID,
|
||||
ClientOrderID: s.ClientOrderID,
|
||||
MarginType: s.MarginType,
|
||||
|
||||
LastUpdated: time.Now(),
|
||||
Date: time.Now(),
|
||||
@@ -1056,7 +1056,7 @@ func StringToOrderSide(side string) (Side, error) {
|
||||
case AnySide.String():
|
||||
return AnySide, nil
|
||||
default:
|
||||
return UnknownSide, fmt.Errorf("'%s' %w", side, errUnrecognisedOrderSide)
|
||||
return UnknownSide, fmt.Errorf("'%s' %w", side, ErrSideIsInvalid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1210,7 +1210,7 @@ func (g *MultiOrderRequest) Validate(opt ...validate.Checker) error {
|
||||
}
|
||||
|
||||
if g.Side == UnknownSide {
|
||||
return errUnrecognisedOrderSide
|
||||
return ErrSideIsInvalid
|
||||
}
|
||||
|
||||
if g.Type == UnknownType {
|
||||
|
||||
Reference in New Issue
Block a user