FTX: Funding rates, payments & stats + order manager tracking (#976)

* Adds basic PoC for calculating/retrieving position data

* A very unfortunate day of miscalculations

* Adds position summary and funding rate details to RPC

* Offline funding rate calculations

* More helpers, more stats, refining data, automated retrieval

* Adds new rpc server commands and attempts some organisation

* lower string, lower stress

* Adds ordermanager config. Fleshes outcli. Tracks positions automatically

* Adds new separation for funding payments/rates

* Combines funding rates and payments

* Fun test coverage

* ALL THE TESTS... I hope

* Fixes

* polishes ftx tests. improves perp check. Loops rates

* Final touches before nit attax

* buff 💪

* Stops NotYetImplemented spam with one simple trick!

* Some lovely little niteroos

* linteroo

* Clarifies a couple of errors to help narrow likely end user problems

* Fixes asset type bug, fixes closed position order return, fixes unset status bug

* Fixes order manager handling when no rates are available yet

* Continues on no funding rates instead. Removes err

* Don't show predicted rate if the time is zero

* Addresses scenario with no funding rate payments

* Bug fixes and commentary before updating maps to use *currency.Item

* Adds a pair key type

* Polishes pKey, fixes map order bug

* key is not a property in the event someone changes the base/quote

* Adds improvements to order processing...Breaks it all

* Shakes up the design of things by removing a function

* Fixes issues with order manager positions. Limits update range

* Fixes build issues. Identification of bad tests.

* Merges and fixes features from master and this branch

* buff linter 💪

* re-gen

* proto regen

* Addresses some nits. But not all of them.

* Fixes issue where funding rates weren't returned 🎉

* completes transition futures tracking to map[*currency.Item]map[*currency.Item]

* who did that? not me

* removes redundant check on account of being redundant and unnecessary

* so buf

* addresses nits: duplications, startTime, loops, go tidy, typos

* fixes minor mistakes

* fixes 🍣 🐻 changes to int64
This commit is contained in:
Scott
2022-08-23 12:16:50 +10:00
committed by GitHub
parent e93ee83563
commit 46cadd6f15
50 changed files with 9249 additions and 3730 deletions

View File

@@ -4,7 +4,7 @@ deps:
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 2646de1347094058879360e68cb2ccc6
commit: 80720a488c9a414bb8d4a9f811084989
- remote: buf.build
owner: grpc-ecosystem
repository: grpc-gateway

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -295,8 +295,8 @@ message OrderDetails {
string asset_type = 6;
string order_side = 7;
string order_type = 8;
int64 creation_time = 9;
int64 update_time = 10;
string creation_time = 9;
string update_time = 10;
string status = 11;
double price = 12;
double amount = 13;
@@ -1026,6 +1026,81 @@ message CurrencyState {
bool trading_enabled = 5;
}
message FundingRate {
string date = 1;
string rate = 2;
string payment = 3;
}
message FundingData {
string exchange = 1;
string asset = 2;
CurrencyPair pair = 3;
string start_date = 4;
string end_date = 5;
repeated FundingRate rates = 6;
FundingRate latest_rate = 7;
FundingRate upcoming_rate = 8;
string payment_sum = 9;
}
message FuturesPositionStats {
string maintenance_margin_requirement = 1;
string initial_margin_requirement = 2;
string estimated_liquidation_price = 3;
string collateral_used = 4;
string mark_price = 5;
string current_size = 6;
string break_even_price = 7;
string average_open_price = 8;
string recent_pnl = 9;
string margin_fraction = 10;
string free_collateral = 11;
string total_collateral = 12;
}
message FuturePosition {
string exchange = 1;
string asset = 2;
CurrencyPair pair = 3;
string status = 4;
string opening_date = 5;
string opening_direction = 6;
string opening_price = 7;
string opening_size = 8;
string current_direction = 9;
string current_price = 10;
string current_size = 11;
string unrealised_pnl = 12;
string realised_pnl = 13;
string closing_date = 14;
int64 order_count = 15;
repeated OrderDetails orders = 16;
FuturesPositionStats position_stats = 17;
FundingData funding_data = 18;
}
message GetManagedPositionRequest {
string exchange = 1;
string asset = 2;
CurrencyPair pair = 3;
bool include_full_order_data = 4;
bool get_funding_payments = 5;
bool include_full_funding_rates = 6;
bool include_predicted_rate = 7;
}
message GetAllManagedPositionsRequest {
bool include_full_order_data = 1;
bool get_funding_payments = 2;
bool include_full_funding_rates = 3;
bool include_predicted_rate = 4;
}
message GetManagedPositionsResponse {
repeated FuturePosition positions = 1;
}
message GetFuturesPositionsRequest {
string exchange = 1;
string asset = 2;
@@ -1034,8 +1109,12 @@ message GetFuturesPositionsRequest {
string end_date = 5;
string status = 6;
int64 position_limit = 7;
bool verbose = 8;
bool overwrite = 9;
bool overwrite = 8;
bool get_position_stats = 9;
bool include_full_order_data = 10;
bool get_funding_payments = 11;
bool include_full_funding_rates = 12;
bool include_predicted_rate = 13;
}
message GetFuturesPositionsResponse {
@@ -1047,16 +1126,6 @@ message GetFuturesPositionsResponse {
repeated FuturePosition positions = 6;
}
message FuturePosition {
string status = 1;
string current_direction = 2;
string unrealised_pnl = 3;
string realised_pnl = 4;
string opening_date = 5;
string closing_date = 6;
repeated OrderDetails orders = 7;
}
message GetCollateralRequest {
string exchange = 1;
string asset = 2;
@@ -1116,6 +1185,20 @@ message CollateralUsedBreakdown {
string used_in_spot_margin = 8;
}
message GetFundingRatesRequest {
string exchange = 1;
string asset = 2;
repeated string pairs = 3;
string start_date = 4;
string end_date = 5;
bool include_predicted = 6;
bool include_payments = 7;
}
message GetFundingRatesResponse {
repeated FundingData funding_payments = 1;
}
message ShutdownRequest {}
message ShutdownResponse {}
@@ -1809,4 +1892,19 @@ service GoCryptoTraderService {
get: "/v1/getmarginrateshistory"
};
}
rpc GetManagedPosition(GetManagedPositionRequest) returns (GetManagedPositionsResponse) {
option (google.api.http) = {
get: "/v1/getmanagedposition"
};
}
rpc GetAllManagedPositions(GetAllManagedPositionsRequest) returns (GetManagedPositionsResponse) {
option (google.api.http) = {
get: "/v1/getallmanagedpositions"
};
}
rpc GetFundingRates(GetFundingRatesRequest) returns (GetFundingRatesResponse) {
option (google.api.http) = {
get: "/v1/getfundingrates"
};
}
}

View File

@@ -1135,6 +1135,54 @@
]
}
},
"/v1/getallmanagedpositions": {
"get": {
"operationId": "GoCryptoTraderService_GetAllManagedPositions",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/gctrpcGetManagedPositionsResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "includeFullOrderData",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "getFundingPayments",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includeFullFundingRates",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includePredictedRate",
"in": "query",
"required": false,
"type": "boolean"
}
],
"tags": [
"GoCryptoTraderService"
]
}
},
"/v1/getauditevent": {
"get": {
"operationId": "GoCryptoTraderService_GetAuditEvent",
@@ -1823,6 +1871,76 @@
]
}
},
"/v1/getfundingrates": {
"get": {
"operationId": "GoCryptoTraderService_GetFundingRates",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/gctrpcGetFundingRatesResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "exchange",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "asset",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "pairs",
"in": "query",
"required": false,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi"
},
{
"name": "startDate",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "endDate",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "includePredicted",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includePayments",
"in": "query",
"required": false,
"type": "boolean"
}
],
"tags": [
"GoCryptoTraderService"
]
}
},
"/v1/getfuturespositions": {
"get": {
"operationId": "GoCryptoTraderService_GetFuturesPositions",
@@ -1897,13 +2015,37 @@
"format": "int64"
},
{
"name": "verbose",
"name": "overwrite",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "overwrite",
"name": "getPositionStats",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includeFullOrderData",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "getFundingPayments",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includeFullFundingRates",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includePredictedRate",
"in": "query",
"required": false,
"type": "boolean"
@@ -2176,6 +2318,84 @@
]
}
},
"/v1/getmanagedposition": {
"get": {
"operationId": "GoCryptoTraderService_GetManagedPosition",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/gctrpcGetManagedPositionsResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "exchange",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "asset",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "pair.delimiter",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "pair.base",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "pair.quote",
"in": "query",
"required": false,
"type": "string"
},
{
"name": "includeFullOrderData",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "getFundingPayments",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includeFullFundingRates",
"in": "query",
"required": false,
"type": "boolean"
},
{
"name": "includePredictedRate",
"in": "query",
"required": false,
"type": "boolean"
}
],
"tags": [
"GoCryptoTraderService"
]
}
},
"/v1/getmarginrateshistory": {
"get": {
"operationId": "GoCryptoTraderService_GetMarginRatesHistory",
@@ -4555,32 +4775,156 @@
}
}
},
"gctrpcFundingData": {
"type": "object",
"properties": {
"exchange": {
"type": "string"
},
"asset": {
"type": "string"
},
"pair": {
"$ref": "#/definitions/gctrpcCurrencyPair"
},
"startDate": {
"type": "string"
},
"endDate": {
"type": "string"
},
"rates": {
"type": "array",
"items": {
"$ref": "#/definitions/gctrpcFundingRate"
}
},
"latestRate": {
"$ref": "#/definitions/gctrpcFundingRate"
},
"upcomingRate": {
"$ref": "#/definitions/gctrpcFundingRate"
},
"paymentSum": {
"type": "string"
}
}
},
"gctrpcFundingRate": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"rate": {
"type": "string"
},
"payment": {
"type": "string"
}
}
},
"gctrpcFuturePosition": {
"type": "object",
"properties": {
"exchange": {
"type": "string"
},
"asset": {
"type": "string"
},
"pair": {
"$ref": "#/definitions/gctrpcCurrencyPair"
},
"status": {
"type": "string"
},
"openingDate": {
"type": "string"
},
"openingDirection": {
"type": "string"
},
"openingPrice": {
"type": "string"
},
"openingSize": {
"type": "string"
},
"currentDirection": {
"type": "string"
},
"currentPrice": {
"type": "string"
},
"currentSize": {
"type": "string"
},
"unrealisedPnl": {
"type": "string"
},
"realisedPnl": {
"type": "string"
},
"openingDate": {
"type": "string"
},
"closingDate": {
"type": "string"
},
"orderCount": {
"type": "string",
"format": "int64"
},
"orders": {
"type": "array",
"items": {
"$ref": "#/definitions/gctrpcOrderDetails"
}
},
"positionStats": {
"$ref": "#/definitions/gctrpcFuturesPositionStats"
},
"fundingData": {
"$ref": "#/definitions/gctrpcFundingData"
}
}
},
"gctrpcFuturesPositionStats": {
"type": "object",
"properties": {
"maintenanceMarginRequirement": {
"type": "string"
},
"initialMarginRequirement": {
"type": "string"
},
"estimatedLiquidationPrice": {
"type": "string"
},
"collateralUsed": {
"type": "string"
},
"markPrice": {
"type": "string"
},
"currentSize": {
"type": "string"
},
"breakEvenPrice": {
"type": "string"
},
"averageOpenPrice": {
"type": "string"
},
"recentPnl": {
"type": "string"
},
"marginFraction": {
"type": "string"
},
"freeCollateral": {
"type": "string"
},
"totalCollateral": {
"type": "string"
}
}
},
@@ -5004,6 +5348,17 @@
}
}
},
"gctrpcGetFundingRatesResponse": {
"type": "object",
"properties": {
"fundingPayments": {
"type": "array",
"items": {
"$ref": "#/definitions/gctrpcFundingData"
}
}
}
},
"gctrpcGetFuturesPositionsResponse": {
"type": "object",
"properties": {
@@ -5108,6 +5463,17 @@
}
}
},
"gctrpcGetManagedPositionsResponse": {
"type": "object",
"properties": {
"positions": {
"type": "array",
"items": {
"$ref": "#/definitions/gctrpcFuturePosition"
}
}
}
},
"gctrpcGetMarginRatesHistoryResponse": {
"type": "object",
"properties": {
@@ -5460,12 +5826,10 @@
"type": "string"
},
"creationTime": {
"type": "string",
"format": "int64"
"type": "string"
},
"updateTime": {
"type": "string",
"format": "int64"
"type": "string"
},
"status": {
"type": "string"

View File

@@ -121,6 +121,9 @@ type GoCryptoTraderServiceClient interface {
Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error)
GetTechnicalAnalysis(ctx context.Context, in *GetTechnicalAnalysisRequest, opts ...grpc.CallOption) (*GetTechnicalAnalysisResponse, error)
GetMarginRatesHistory(ctx context.Context, in *GetMarginRatesHistoryRequest, opts ...grpc.CallOption) (*GetMarginRatesHistoryResponse, error)
GetManagedPosition(ctx context.Context, in *GetManagedPositionRequest, opts ...grpc.CallOption) (*GetManagedPositionsResponse, error)
GetAllManagedPositions(ctx context.Context, in *GetAllManagedPositionsRequest, opts ...grpc.CallOption) (*GetManagedPositionsResponse, error)
GetFundingRates(ctx context.Context, in *GetFundingRatesRequest, opts ...grpc.CallOption) (*GetFundingRatesResponse, error)
}
type goCryptoTraderServiceClient struct {
@@ -1160,6 +1163,33 @@ func (c *goCryptoTraderServiceClient) GetMarginRatesHistory(ctx context.Context,
return out, nil
}
func (c *goCryptoTraderServiceClient) GetManagedPosition(ctx context.Context, in *GetManagedPositionRequest, opts ...grpc.CallOption) (*GetManagedPositionsResponse, error) {
out := new(GetManagedPositionsResponse)
err := c.cc.Invoke(ctx, "/gctrpc.GoCryptoTraderService/GetManagedPosition", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *goCryptoTraderServiceClient) GetAllManagedPositions(ctx context.Context, in *GetAllManagedPositionsRequest, opts ...grpc.CallOption) (*GetManagedPositionsResponse, error) {
out := new(GetManagedPositionsResponse)
err := c.cc.Invoke(ctx, "/gctrpc.GoCryptoTraderService/GetAllManagedPositions", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *goCryptoTraderServiceClient) GetFundingRates(ctx context.Context, in *GetFundingRatesRequest, opts ...grpc.CallOption) (*GetFundingRatesResponse, error) {
out := new(GetFundingRatesResponse)
err := c.cc.Invoke(ctx, "/gctrpc.GoCryptoTraderService/GetFundingRates", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// GoCryptoTraderServiceServer is the server API for GoCryptoTraderService service.
// All implementations must embed UnimplementedGoCryptoTraderServiceServer
// for forward compatibility
@@ -1263,6 +1293,9 @@ type GoCryptoTraderServiceServer interface {
Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error)
GetTechnicalAnalysis(context.Context, *GetTechnicalAnalysisRequest) (*GetTechnicalAnalysisResponse, error)
GetMarginRatesHistory(context.Context, *GetMarginRatesHistoryRequest) (*GetMarginRatesHistoryResponse, error)
GetManagedPosition(context.Context, *GetManagedPositionRequest) (*GetManagedPositionsResponse, error)
GetAllManagedPositions(context.Context, *GetAllManagedPositionsRequest) (*GetManagedPositionsResponse, error)
GetFundingRates(context.Context, *GetFundingRatesRequest) (*GetFundingRatesResponse, error)
mustEmbedUnimplementedGoCryptoTraderServiceServer()
}
@@ -1567,6 +1600,15 @@ func (UnimplementedGoCryptoTraderServiceServer) GetTechnicalAnalysis(context.Con
func (UnimplementedGoCryptoTraderServiceServer) GetMarginRatesHistory(context.Context, *GetMarginRatesHistoryRequest) (*GetMarginRatesHistoryResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetMarginRatesHistory not implemented")
}
func (UnimplementedGoCryptoTraderServiceServer) GetManagedPosition(context.Context, *GetManagedPositionRequest) (*GetManagedPositionsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetManagedPosition not implemented")
}
func (UnimplementedGoCryptoTraderServiceServer) GetAllManagedPositions(context.Context, *GetAllManagedPositionsRequest) (*GetManagedPositionsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetAllManagedPositions not implemented")
}
func (UnimplementedGoCryptoTraderServiceServer) GetFundingRates(context.Context, *GetFundingRatesRequest) (*GetFundingRatesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetFundingRates not implemented")
}
func (UnimplementedGoCryptoTraderServiceServer) mustEmbedUnimplementedGoCryptoTraderServiceServer() {}
// UnsafeGoCryptoTraderServiceServer may be embedded to opt out of forward compatibility for this service.
@@ -3380,6 +3422,60 @@ func _GoCryptoTraderService_GetMarginRatesHistory_Handler(srv interface{}, ctx c
return interceptor(ctx, in, info, handler)
}
func _GoCryptoTraderService_GetManagedPosition_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetManagedPositionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GoCryptoTraderServiceServer).GetManagedPosition(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/gctrpc.GoCryptoTraderService/GetManagedPosition",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GoCryptoTraderServiceServer).GetManagedPosition(ctx, req.(*GetManagedPositionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _GoCryptoTraderService_GetAllManagedPositions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetAllManagedPositionsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GoCryptoTraderServiceServer).GetAllManagedPositions(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/gctrpc.GoCryptoTraderService/GetAllManagedPositions",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GoCryptoTraderServiceServer).GetAllManagedPositions(ctx, req.(*GetAllManagedPositionsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _GoCryptoTraderService_GetFundingRates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetFundingRatesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GoCryptoTraderServiceServer).GetFundingRates(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/gctrpc.GoCryptoTraderService/GetFundingRates",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GoCryptoTraderServiceServer).GetFundingRates(ctx, req.(*GetFundingRatesRequest))
}
return interceptor(ctx, in, info, handler)
}
// GoCryptoTraderService_ServiceDesc is the grpc.ServiceDesc for GoCryptoTraderService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -3759,6 +3855,18 @@ var GoCryptoTraderService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetMarginRatesHistory",
Handler: _GoCryptoTraderService_GetMarginRatesHistory_Handler,
},
{
MethodName: "GetManagedPosition",
Handler: _GoCryptoTraderService_GetManagedPosition_Handler,
},
{
MethodName: "GetAllManagedPositions",
Handler: _GoCryptoTraderService_GetAllManagedPositions_Handler,
},
{
MethodName: "GetFundingRates",
Handler: _GoCryptoTraderService_GetFundingRates_Handler,
},
},
Streams: []grpc.StreamDesc{
{