gateio / gateapi-csharp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't close futures trade with CancelFuturesOrders or with CancelFuturesOrder

Workingsolutions1 opened this issue · comments

Trying to close with each of methods but for some reason it doesn't work. CancelFuturesOrder code is next:

`using System;
using System.Timers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using Io.Gate.GateApi.Api;
using Io.Gate.GateApi.Client;
using Io.Gate.GateApi.Model;

namespace GateApiDemo
{
public class FuturesDemo
{
public GateApiException returnException;

    public void Run()
    {

        const string settle = "usdt";
        const string contract = "MATIC_USDT";

        Configuration config = new Configuration
        {
            BasePath = "https://api.gateio.ws/api/v4",
            ApiV4Key = "key1",
            ApiV4Secret = "key2",
        };

        //New futures api
        FuturesApi futuresApi = new FuturesApi(config);

        //Wallet api for transfers between accounts and for total balance
        var apiInstance = new WalletApi(config);
        var currency = "USDT";  // string | Currency unit used to calculate the balance amount. BTC, CNY, USD and USDT are allowed. USDT is the default. (optional)  (default to "USDT")

        //Get account total balance
        var result = new TotalBalance();
        try
        {
            // Retrieve user's total balances
            result = apiInstance.GetTotalBalance(currency);
            Console.WriteLine(result);
        }
        catch (GateApiException e)
        {
            Debug.Print("Exception when calling WalletApi.GetTotalBalance: " + e.Message);
            Debug.Print("Exception label: {0}, message: {1}", e.ErrorLabel, e.ErrorMessage);
            Debug.Print("Status Code: " + e.ErrorCode);
            Debug.Print(e.StackTrace);
        }

        //Get contract info
        Contract futuresContract = new Contract();
        try
        {
            futuresContract = futuresApi.GetFuturesContract(settle, contract);
        }
        catch (GateApiException e)
        {
            returnException = e;
            return;
        }

        //Get lot size according to total balance and contract
        var totalBalanceLotSize = Convert.ToDecimal(result.Total.Amount) / (Convert.ToDecimal(futuresContract.LastPrice) * Convert.ToDecimal(futuresContract.QuantoMultiplier));
        
        //Set lot size according to leverage and total balance
        var leverage = 1;
        var leveragedLotSize = totalBalanceLotSize * leverage;

        //Create futures order
        FuturesOrder futuresOrder = new FuturesOrder(contract)
        {
            Size = (long)leveragedLotSize,
            Price = "0",
            Tif = FuturesOrder.TifEnum.Ioc,
        };

        FuturesOrder orderResponse;
        string orderResponseStr = "0";
        long orderId = 0;
        try
        {
            orderResponse = futuresApi.CreateFuturesOrder(settle, futuresOrder);
            orderResponseStr = orderResponse.Status.ToString();
            orderId = orderResponse.Id;
        }
        catch (GateApiException e)
        {
            returnException = e;
        }


        if (orderResponseStr == "Finished")
        {
            FuturesOrder order = futuresApi.GetFuturesOrder(settle, orderId.ToString());
            Console.WriteLine(order);
            //var stopwatch = Stopwatch.StartNew();
            //System.Threading.Thread.SpinWait(100 * 100);
            Console.WriteLine("test");
            futuresApi.CancelFuturesOrder(settle, order.Id.ToString());
            //futuresApi.CancelFuturesOrder(settle, Convert.ToString(orderId));
        }
        
    }
}

}`

That's what I get in console (here is XRP but doesn't matter):
image

And then this exception:

Io.Gate.GateApi.Client.GateApiException
HResult=0x80131500
Source=Io.Gate.GateApi
StackTrace:
at Io.Gate.GateApi.Api.FuturesApi.CancelFuturesOrderWithHttpInfo(String settle, String orderId)
at Io.Gate.GateApi.Api.FuturesApi.CancelFuturesOrder(String settle, String orderId)
at GateApiDemo.FuturesDemo.Run() in C:\Users\root\source\repos\NewListings\FuturesDemo.cs:line 109
at GateApiDemo.Program.Main(String[] args) in C:\Users\root\source\repos\NewListings\Program.cs:line 17

That's details, according to it for some reason api can't find order with such number:

image

order id looks to be correct, it's probably bug or idk what. How to solve this ?

It's not a bug. Finished order cannot be cancelled. Cancel operation is only valid for open orders.

PS. It is advised not to use TotalBalance as it's an estimate value and is updated periodically. You should use ListFuturesAccounts instead

It's not a bug. Finished order cannot be cancelled. Cancel operation is only valid for open orders.

PS. It is advised not to use TotalBalance as it's an estimate value and is updated periodically. You should use ListFuturesAccounts instead

And if order is finished what does it mean ? How can I close it, it's reflected in my personal cabinet and it's not closed, what to do with it? I can close it manually via futures interface. It's for sure opened order because it's displayed on the "Holding" tab and it was opened as market order

@revilwang revilwang Need your help here, can't find the answer tried many solutions already

I think you need to check your data again. Your log output test in the status == finished block and left field of the order above is 0, which both means the order is finished, meaning the order has been filled totally. In that case, when you call order cancellation, ORDER_NOT_FOUND will be returned.

I think you need to check your data again. Your log output test in the status == finished block and left field of the order above is 0, which both means the order is finished, meaning the order has been filled totally. In that case, when you call order cancellation, ORDER_NOT_FOUND will be returned.

Let's try it 1 more time:

That's the code:

`using System;
using System.Timers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using Io.Gate.GateApi.Api;
using Io.Gate.GateApi.Client;
using Io.Gate.GateApi.Model;

namespace GateApiDemo
{
public class FuturesDemo
{
public GateApiException returnException;

    public void Run()
    {

        const string settle = "usdt";
        const string contract = "XRP_USDT";

        Configuration config = new Configuration
        {
            BasePath = "https://api.gateio.ws/api/v4",
            ApiV4Key = "key1",
            ApiV4Secret = "key2",
        };

        //New futures api
        FuturesApi futuresApi = new FuturesApi(config);

        //Wallet api for transfers between accounts and for total balance
        var apiInstance = new WalletApi(config);
        var currency = "USDT";  // string | Currency unit used to calculate the balance amount. BTC, CNY, USD and USDT are allowed. USDT is the default. (optional)  (default to "USDT")

        //Get account total balance
        var result = new TotalBalance();
        try
        {
            // Retrieve user's total balances
            result = apiInstance.GetTotalBalance(currency);
            Console.WriteLine(result);
        }
        catch (GateApiException e)
        {
            Debug.Print("Exception when calling WalletApi.GetTotalBalance: " + e.Message);
            Debug.Print("Exception label: {0}, message: {1}", e.ErrorLabel, e.ErrorMessage);
            Debug.Print("Status Code: " + e.ErrorCode);
            Debug.Print(e.StackTrace);
        }

        //Get contract info
        Contract futuresContract = new Contract();
        try
        {
            futuresContract = futuresApi.GetFuturesContract(settle, contract);
        }
        catch (GateApiException e)
        {
            returnException = e;
            return;
        }
        
        //Get lot size according to total balance and contract
        var totalBalanceLotSize = Convert.ToDecimal(result.Total.Amount) / (Convert.ToDecimal(futuresContract.LastPrice) * Convert.ToDecimal(futuresContract.QuantoMultiplier));
        
        //Set lot size according to leverage and total balance
        var leverage = 1;
        var leveragedLotSize = totalBalanceLotSize * leverage;

        //Create futures order
        FuturesOrder futuresOrder = new FuturesOrder(contract)
        {
            Size = (long)leveragedLotSize,
            Price = "0",
            Tif = FuturesOrder.TifEnum.Ioc,
        };

        FuturesOrder orderResponse;
        string orderResponseStr = "0";
        long orderId = 0;
        try
        {
            orderResponse = futuresApi.CreateFuturesOrder(settle, futuresOrder);
            orderResponseStr = orderResponse.Status.ToString();
            orderId = orderResponse.Id;
        }
        catch (GateApiException e)
        {
            returnException = e;
        }


        if (orderResponseStr == "Finished")
        {
            FuturesOrder order = futuresApi.GetFuturesOrder(settle, orderId.ToString());
            Console.WriteLine(order.Id);
            Console.WriteLine("test");

            futuresApi.CancelFuturesOrder(settle, Convert.ToString(orderId));

        }

    }
}

}`

That's code output while debugging:

image

And that's the error:

image

Also you can see that I have order opened on my personal cabinet:

image

I don't get what's wrong with it then.

@revilwang I've sent both requests with links to those issues on support email. Waiting for response.

The last screenshot you posted means your Position, not your orders. When you create an order that no price can match, you have an open Order. When the order is matched and filled, you have your Position, while the order is finished(if it is filled totally). What you want is closing your Position instead of cancelling your order.

To close your Position, you need to create another order with close set as true and size as 0. Also, the order will first be opened until it can be matched and filled, then your Position will be closed.

The last screenshot you posted means your Position, not your orders. When you create an order that no price can match, you have an open Order. When the order is matched and filled, you have your Position, while the order is finished(if it is filled totally). What you want is closing your Position instead of cancelling your order.

To close your Position, you need to create another order with close set as true and size as 0. Also, the order will first be opened until it can be matched and filled, then your Position will be closed.

Tried to create another position like you said with Size = 0 and Price = 0 but it gives error "Missing required parameter: size"

image

Same with

FuturesOrder futuresOrder1 = new FuturesOrder(contract)
{
Size = 0,
Close = true,
};

gives same error

That's a bug of the SDK. 0 size is taken as default value and is removed from serialization.

I'll fix the problem on next version ASAP. For now, you can try to remove the EmitDefaultValue = false from the Size field in Model/FuturesOrder.cs file and build the SDK yourself.

That's a bug of the SDK. 0 size is taken as default value and is removed from serialization.

I'll fix the problem on next version ASAP. For now, you can try to remove the EmitDefaultValue = false from the Size field in Model/FuturesOrder.cs file and build the SDK yourself.

Okay worked other thing:

FuturesOrder futuresOrder1 = new FuturesOrder(contract)
{
Size = -10,
Price = "0",
Tif = FuturesOrder.TifEnum.Ioc,
};

Closing with same size but as short trade. Left then question with exceeding borrowable limit. By the way support wrote me back to ask questions related to api on github

Yes, 0 size is the same effect as setting the size to the opposite direction.

If the support say so, I'll try to figure out the other problem on my own.