Coder Social home page Coder Social logo

glitch100 / binancedotnet Goto Github PK

View Code? Open in Web Editor NEW
161.0 17.0 139.0 737 KB

Official C# Wrapper for the Binance exchange API, with REST and WebSocket endpoints

Home Page: https://www.nuget.org/packages/BinanceDotNet/

License: MIT License

C# 100.00%
dotnet cryptocurrency binance binance-exchange crypto-exchange csharp api-wrapper wrapper nuget websocket-endpoint

binancedotnet's Introduction

BinanceDotNet

C# Wrapper for the official Binance exchange API

Compatible with .NET 4.5.1, .NET 4.5.2, .NET 4.6.1, .NETSTANDARD2.0

This repository provides a C# wrapper for the official Binance API, and provides rate limiting features (set to 10 by 10 out the box), a IAPICacheManager interface to allow users to provide their own cache implementations, all REST endpoints covered, and a best practice solution coupled with strongly typed responses and requests. It is built on the latest .NET Framework and in .NET Core

Feel free to raise issues and Pull Request to help improve the library. If you found this API useful, and you wanted to give back feel free to sign up to Binance via my referral link here.

Documentation

Installation

The package is available in NuGet, or feel free to download: https://www.nuget.org/packages/BinanceDotNet/

Nuget PM

Install-Package BinanceDotNet

dotnet cli

dotnet add package BinanceDotNet

Donations and Contribution

Upkeep of this API takes a lot of time from answering issues and PR's on the Repository, as well as tweets and direct emails. You can donate cryptocurrency of any amount to the following wallets:

ETH: 0xd5775e2dee4b9fa9a3be5222970c04ac574e8412

Want to send something else? Just tweet me! @Glitch100

Or you can help maintain the repository! Donations of time are welcome, just hit me up and we can work on it. From answering issues, to contributing code anyone can assist.

git clone [email protected]:glitch100/BinanceDotNet.git
  • Navigate to ExampleProgram.cs
  • Add your own Private and Secret keys
  • Play around with the API

Features

  • Simple, Configurable, Extendable
  • Rate limiting, with 10 requests in 10 seconds (disabled by default)
  • log4net Interfaces supported
  • dotnet standard, dotnet core, 4.5.1, 4.6.1 support
  • Binance WebSockets
  • Unit test coverage (in progress)
  • IAPICacheManager abstraction for providing your own cache or using the build in concrete implementation. (Currently only one endpoint has caching)
  • Console app with examples ready to launch (provide API keys)

Examples

More examples are available to play around with within the repositorys Console application which can be found here. Otherwise there are some examples around utilising both WebSockets and REST API in the Usage section below.

Roadmap

Work will continue on this API wrapper over the coming months adding and extending out the number of features that the BinanceDotNet library has. Please raise issues for new features desired

  • Start building out Unit Test support - >~2.1.0
  • Provide Builder support for queries - 2.5.0~
  • Abstract out the HttpClient - 3.0.0~

Usage

Code examples below, or clone the repository and run the BinanceExchange.Console project. This repository is built off dotnet core, and runs against C# 7.1

Creating a Client

General usage just requires setting up the client with your credentials, and then calling the Client as necessary.

// Build out a client, provide a logger, and more configuration options, or even your own APIProcessor implementation
var client = new BinanceClient(new ClientConfiguration()
{
    ApiKey = "YOUR_API_KEY",
    SecretKey = "YOUR_SECRET_KEY",
});

//You an also specify symbols like this.
var desiredSymbol = TradingPairSymbols.BNBPairs.BNB_BTC,

IReponse response = await client.GetCompressedAggregateTrades(new GetCompressedAggregateTradesRequest(){
  Symbol = "BNBBTC",
  StartTime = DateTime.UtcNow().AddDays(-1),
  EndTime = Date.UtcNow(),
});

Creating a WebSocket Client

For WebSocket endpoints, just instantiate the BinanceClient, and provide it into the BinanceWebSocketClient You can use a using block or manual management.

var client = new BinanceClient(new ClientConfiguration()
{
    ApiKey = "YOUR_API_KEY",
    SecretKey = "YOUR_SECRET_KEY",
});


// Manual management
var manualWebSocketClient = new InstanceBinanceWebSocketClient(client);
var socketId = binanceWebSocketClient.ConnectToDepthWebSocket("ETHBTC", data =>
{
    System.Console.WriteLine($"DepthCall: {JsonConvert.SerializeObject(data)}");
});
manualWebSocketClient.CloseWebSocketInstance(socketId);


// Disposable and managed
using (var binanceWebSocketClient = new DisposableBinanceWebSocketClient(client))
{
    binanceWebSocketClient.ConnectToDepthWebSocket("ETHBTC", data =>
    {
        System.Console.WriteLine($"DepthCall: {JsonConvert.SerializeObject(data)}");
    });

    Thread.Sleep(180000);
}

Error Handling

The Binance API provides rich exceptions based on different error types. You can decorate calls like this if you would like to handle the various exceptions.

// Firing off a request and catching all the different exception types.
try
{
    accountTrades = await client.GetAccountTrades(new AllTradesRequest()
    {
        FromId = 352262,
        Symbol = "ETHBTC",
    });
}
catch (BinanceBadRequestException badRequestException)
{

}
catch (BinanceServerException serverException)
{

}
catch (BinanceTimeoutException timeoutException)
{

}
catch (BinanceException unknownException)
{
}

Building out a local cache per symbol from the depth WebSocket

The example is mainly 'all in one' so you can see a full runthrough of how it works. In your own implementations you may want to have a cache of only the most recent bids/asks, or perhaps will want the empty quanity/price trades.

You can also calculate volume and more from this cache. The following code is partial from the ExampleProgram.cs.

private static async Task<Dictionary<string, DepthCacheObject>> BuildLocalDepthCache(IBinanceClient client)
{
    // Code example of building out a Dictionary local cache for a symbol using deltas from the WebSocket
    var localDepthCache = new Dictionary<string, DepthCacheObject> {{ "BNBBTC", new DepthCacheObject()
    {
        Asks = new Dictionary<decimal, decimal>(),
        Bids = new Dictionary<decimal, decimal>(),
    }}};
    var bnbBtcDepthCache = localDepthCache["BNBBTC"];

    // Get Order Book, and use Cache
    var depthResults = await client.GetOrderBook("BNBBTC", true, 100);
    //Populate our depth cache
    depthResults.Asks.ForEach(a =>
    {
        if (a.Quantity != 0.00000000M)
        {
            bnbBtcDepthCache.Asks.Add(a.Price, a.Quantity);
        }
    });
    depthResults.Bids.ForEach(a =>
    {
        if (a.Quantity != 0.00000000M)
        {
            bnbBtcDepthCache.Bids.Add(a.Price, a.Quantity);
        }
    });

    // Store the last update from our result set;
    long lastUpdateId = depthResults.LastUpdateId;
    using (var binanceWebSocketClient = new DisposableBinanceWebSocketClient(client))
    {
        binanceWebSocketClient.ConnectToDepthWebSocket("BNBBTC", data =>
        {
            if (lastUpdateId < data.UpdateId)
            {
                data.BidDepthDeltas.ForEach((bd) =>
                {
                    CorrectlyUpdateDepthCache(bd, bnbBtcDepthCache.Bids);
                });
                data.AskDepthDeltas.ForEach((ad) =>
                {
                    CorrectlyUpdateDepthCache(ad, bnbBtcDepthCache.Asks);
                });
            }
            lastUpdateId = data.UpdateId;
            System.Console.Clear();
            System.Console.WriteLine($"{JsonConvert.SerializeObject(bnbBtcDepthCache, Formatting.Indented)}");
            System.Console.SetWindowPosition(0, 0);
        });

        Thread.Sleep(8000);
    }
    return localDepthCache;
}

Result Transformations

You can use the data returned from above to utilise the ResultTransformations static class, to transform data returned from the API into more meaningful, known shapes, such as Volume etc.

// This builds a local depth cache from an initial call to the API and then continues to fill
// the cache with data from the WebSocket
var localDepthCache = await BuildLocalDepthCache(client);
// Build the Buy Sell volume from the results
var volume = ResultTransformations.CalculateTradeVolumeFromDepth("BNBBTC", localDepthCache);

binancedotnet's People

Contributors

alexn78 avatar bjornnordblom avatar dependabot[bot] avatar gayan-rb avatar glitch100 avatar ipinko-bc avatar jgsnijders avatar pythagdev avatar robbaman avatar thusmad avatar xfiodembo avatar xucito avatar yetkinsari avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

binancedotnet's Issues

ConnectToTradesWebSocket?

Issue Overview

No output from ConnectToTradesWebSocket sample code

Package Version: 4.0.1

Repro Steps

Sample websocket code like

using (var binanceWebSocketClient = new DisposableBinanceWebSocketClient(client))
{
    binanceWebSocketClient.ConnectToDepthWebSocket("ETHBTC", data =>
    {
        System.Console.WriteLine($"DepthCall: {JsonConvert.SerializeObject(data)}");
    });

    Thread.Sleep(180000);
}

Gives the expected JSON output with ConnectToDepthWebSocket and ConnectToKlineWebSocket but
no output, or exceptions, with ConnectToTradesWebSocket using ETHBTC or any of the other pairs I tried. Apologies in advance if I've missed something obvious.

Other Information

Using VS2017 latest preview, target framework netcoreapp2.0

BinanceDotNet is a cut above the other exchange APIs I've worked with -- thanks! (And check your eth wallet for a small contribution)

#BINANCEDOTNET C# STREAM USER DATA ConnectToUserDataWebSocket need help !

Anyone knows how to stream user data with BinanceDotNet package ? I've tried everything I looked up for example but no one works. I'm desperate -.- !

It's C# Console application :

using BinanceExchange.API.Client;
using BinanceExchange.API.Models.WebSocket;
using BinanceExchange.API.Websockets;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CsharpBi
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = new BinanceClient(new ClientConfiguration()
            {
                ApiKey = "xxxxxx",
                SecretKey = "xxxxxxx",
            });
           
            using (var binanceWebSocketClient = new DisposableBinanceWebSocketClient(client))
            {
                binanceWebSocketClient.ConnectToUserDataWebSocket(new UserDataWebSocketMessages);

            }

        }
    }
}

I am stuck at ConnectToUserDataWebSocket(new UserDataWebSocketMessages), I didnt find examples about this method and how to use it ! Anyone can help me plz ?!

Errors on BinanceTradeOrderData.cs that prevent successful JSON Deserialization

Issue Overview

The following errors from BinanceTradeOrderData.cs would prevent the User Data Websocket from successfully deserializing BinanceTradeOrderData

Package Version: 4.2.3

BinanceTradeOrderData.cs

1. Duplicate property name "l" exists on line 100 and line 139
line 100

        [DataMember(Order = 17)]
        [JsonProperty(PropertyName = "l")]
        public decimal QuantityOfLastFilledTrade { get; set; }

line 139

        #region Undefined API Result fields
        //TODO: Update when Binance API updated
        [DataMember(Order = 25)]
        [JsonProperty(PropertyName = "l")]
        public long l { get; set; }

2. Unnescessary line for TradeId (TradeId is not a DateTime)?
[JsonConverter(typeof(EpochTimeConverter))]

        [DataMember(Order = 23)]
        [JsonProperty(PropertyName = "t")]
        [JsonConverter(typeof(EpochTimeConverter))]
        public long TradeId { get; set; }

BinanceExchange.API.Enums.ExecutionType Typo on "CANCELLED"

Issue Overview

BinanceExchange.API.Enums.ExecutionType.cs

[EnumMember(Value = "CANCELLED")]
is should be spelled as
[EnumMember(Value = "CANCELED")]

Package Version: 4.2.3

Other Information

Websocket spells it as CANCELED, it is also spelled that way on the official documentation.

Api stop limit price issue and instancewebsocket for firing

For order place, i get an exception saying the stop price is being sent through, i can see it in the object even though i am not creating it. I fixed this temporarily locally.

My main concern is, (I am getting other websocket messages) when i subscribe to user data feeds, I have everything wired up correctly but when I place or cancel an order, nothing is firing. I am debugging locally and onmessage never fires.

Fills List in FullCreateOrderResponse is always null

Issue Overview

When creating an order with NewOrderResponseType set to Full, List<Fill> in FullCreateOrderResponse is always null.All other data is there as expected.

Package Version:

BinanceDotNet v4.2.4

Repro Steps

var createOrder = client.CreateOrder(new CreateOrderRequest
                {
                    Symbol = "ADABTC",
                    Side = OrderSide.Buy,
                    Type = OrderType.Market,
                    Quantity = 35,
                    NewOrderResponseType = NewOrderResponseType.Full
                }).Result;
var fullResponseOrder = (FullCreateOrderResponse) createOrder;
Other Information

CreateOrder always Faults

Whenever I try putting out an Order, it gives be "Order Faulted" back, I can't seem to find any reason for that, or a way to fix it tho.

I am using BinanceDotNet version 4.2.2 (just updated), I started on version 4.0.1, had the same Issue there.

With this code I just try to buy 1 BNB, for example, using USDT - unless I screwed something up there you might can show me, I have no idea what to do... - I got enought USDT on my binance account and all other calls I tried seemed to work just fine (getting the balance, time, stuff like that) - I am just not able to actually create Orders.

var createOrder = client.CreateOrder(new CreateOrderRequest()
                {
                    Price = 0,
                    Quantity = 1m,
                    Symbol = "BNBUSDT",
                    Side = OrderSide.Buy,
                    Type = OrderType.Market
                });
                while (!createOrder.IsCompleted)
                {
                    await Task.Delay(100);
                }

                Console.WriteLine("Status: " + createOrder.Status +
                    "\nCompleted: " + createOrder.IsCompleted +
                    "\nCanceled: " + createOrder.IsCanceled +
                    "\nFaulted: " + createOrder.IsFaulted);

CreateOrder response: OrderID and ClientOrderID are blanks.

After call to CreateOrder(), BaseCreateOrderResponse does NOT have those two fields filled from JSON. My guess, issues is missing DataContract.

[DataContract] // This is missing. With this definition it is working.
public abstract class BaseCreateOrderResponse : IResponse

Executing LIMIT Buy/Sell Order causes "Malformed requests are sent to the server.."

Issue Overview

Trying to execute a LIMIT BUY/SELL Order causes the Binance Webservice to throw an exception:

BinanceExchange.API.Models.Response.Error.BinanceBadRequestException: Malformed requests are sent to the server. Please review the request object/string at BinanceExchange.API.APIProcessor.d__81.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at BinanceExchange.API.APIProcessor.<ProcessPostRequest>d__131.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at BinanceExchange.API.Client.BinanceClient.d__21.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()

Package Version:

BinanceDotNet v4.2.0
VS2017 + .NET 4.7.1

Repro Steps

BinanceClient client = new BinanceClient(new ClientConfiguration {
	ApiKey = "VALID API KEY",
	SecretKey = "VALID SECRET KEY"
});

BaseCreateOrderResponse result = await client.CreateOrder(new CreateOrderRequest {
	Symbol = "XRPBTC",
	Quantity = 10,
	Price = 0.00009662M,

	Side = OrderSide.Buy,
	Type = OrderType.Limit,
	TimeInForce = TimeInForce.IOC
});

GetCurrentOpenOrders cannot be called without symbol parameter

Issue Overview

According to API documentation GetCurrentOpenOrders should have Symbol parameter as optional. This api throws the exception if it is null. If I put in "" then Binance says that there is a malformed request.

Package Version: 4.2.1

Repro Steps

var orders = await client.GetCurrentOpenOrders(new BinanceExchange.API.Models.Request.CurrentOpenOrdersRequest(){ Symbol="" });

var orders = await client.GetCurrentOpenOrders(new BinanceExchange.API.Models.Request.CurrentOpenOrdersRequest());

Other Information

How can one get all currently open orders for the account?

Malformed request when creating two instances of BinanceClient with different configuration

Issue Overview

If you create 2 instances of BinanceClient with different ClientConfiguration then the fist instance is affected by the configuration of the second

Package Version:

NetStandard2.0 consumed by .net framework 4.61

Repro Steps

`
//Initialise the general client client with config
var client = new BinanceClient(new ClientConfiguration()
{
ApiKey = apiKey,
SecretKey = secretKey,
Logger = exampleProgramLogger,
});

        var cli2 = new BinanceClient(new ClientConfiguration()
        {
            ApiKey = "asd",
            SecretKey = "asd", 
        });

        var startTime = new DateTime(2017, 07, 01, 0, 0, 0, DateTimeKind.Utc);
        var candles = cli2.GetKlinesCandlesticks(new GetKlinesCandlesticksRequest
        {
            Symbol = "ADAETH",
            StartTime = startTime,
            Interval = KlineInterval.OneMinute,
            EndTime = DateTime.MaxValue
        }).Result;
        candles = cli2.GetKlinesCandlesticks(new GetKlinesCandlesticksRequest
        {
            Symbol = "ADAETH",
            StartTime = startTime.AddDays(1),
            Interval = KlineInterval.OneMinute,
            EndTime = DateTime.MaxValue
        }).Result;

        System.Console.WriteLine("Interacting with Binance...");
        var wscli = new DisposableBinanceWebSocketClient(client);
        var UserDataSocket = wscli.ConnectToUserDataWebSocket(new UserDataWebSocketMessages()
        {
            AccountUpdateMessageHandler = d => System.Console.WriteLine("asd"),
            OrderUpdateMessageHandler = d => System.Console.WriteLine("asd"),
            TradeUpdateMessageHandler = d => System.Console.WriteLine("asd"),
        }).Result; 

`

Other Information

In the provided example it causes the ConnectToUserDataWebSocket to fail.

Some feedback (simplify namespaces)

Hey, trying to port our codebase from our own Binance client code to this library.

Just have a little feedback/suggestion that I think would make the library easier to use.

It is to remove all the inner namespaces of the library, they make the library harder to use and find types via Intellisense. Basically all that would remain is BinanceExchange.API namespace.

What do you think?

Can't convert JSON result from string to integer

Issue Overview

Serializer can't convert to integer from string

Package Version: v4.0.30319

Repro Steps

private async void button1_Click(object sender, EventArgs e) {
List trades = await client.GetAccountTrades(new AllTradesRequest() {
Symbol = "XLMETH",
});
}

Other Information

BinanceExchange.API.Models.Response.Error.BinanceException: 'Unable to deserialize message from: https://www.binance.com/api/v3/myTrades?symbol=XLMETH. Exception: Could not convert string to integer: 60.00000000. Path '[0].qty', line 1, position 73.'
screenshot

Stop adding unspecified non-manadatory query string parameters to requests

Please stop adding 'default' parameters when they are not specified as the results in broken or unexpected behaviour in some cases.

If I run the following code:
CreateOrderResponse response = await client.CreateOrder(new CreateOrderRequest()
{
Symbol = orderSymbol,
Side = orderSide,
Type = OrderType.Market,
Quantity = quantityInPrimaryCoin
});

The following request is sent:
https://www.binance.com/api/v3/order?icebergQty=0&symbol=FUNETH&side=BUY&type=MARKET&timeInForce=GTC&quantity=0.00954175080625&price=0&stopPrice=0

However, only the following request should be sent:
https://www.binance.com/api/v3/order?symbol=FUNETH&side=BUY&type=MARKET&quantity=0.00954175080625

In some cases this causes errors, or may result in unexpected results. Another example of this is for AllOrders where the limit parameters should be treated as 500 if not provided, but instead it adds &limit=0 instead of not providing the parameter, resulting in 0 items being returned.

Cheers!

ConnectToUserDataWebSocket not receiving events

Issue Overview

ConnectToUserDataWebSocket websocket does not connect to the proper uri. As a result, events are not received by the websocket

Package Version: 4.2.2

Repro Steps

UserDataWebSocketMessages userDataWebSocketMessages = new UserDataWebSocketMessages();
            userDataWebSocketMessages.OrderUpdateMessageHandler = new BinanceWebSocketMessageHandler<BinanceTradeOrderData>(x => {
                System.Console.WriteLine(x.Quantity);
            });

            using (var binanceWebSocketClient = new DisposableBinanceWebSocketClient(client))
            {
                binanceWebSocketClient.ConnectToUserDataWebSocket(userDataWebSocketMessages);
                await Task.Delay(-1);
            }

Then try making an order

Other Information

log4net:

2018-02-21 11:15:41,352 [1] DEBUG BinanceExchange.Console.TestProgram - Logging Test
2018-02-21 11:15:51,452 [1] DEBUG BinanceExchange.API.RequestClient - Timestamp offset is now : 00:00:00
2018-02-21 11:15:51,452 [1] DEBUG BinanceExchange.API.RequestClient - Rate Limiting has been disabled
2018-02-21 11:15:51,534 [1] DEBUG BinanceExchange.API.APIProcessor - API Processor set up. Cache Enabled=True
2018-02-21 11:15:51,621 [1] DEBUG BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient - Connecting to User Data Web Socket
2018-02-21 11:15:51,663 [1] DEBUG BinanceExchange.API.RequestClient - Creating a POST Request to https://api.binance.com/api/v1/userDataStream
2018-02-21 11:15:54,209 [4] DEBUG BinanceExchange.API.APIProcessor - Successful Message Response={"listenKey":"fwmTecSDqUnfvFGQMDC6b00piiNBLQsfARMLDydMWxrM85EN9ktwAjAlp2tu"}
2018-02-21 11:15:55,423 [4] DEBUG BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient - WebSocket Opened:wss://stream.binance.com:9443/ws/BinanceExchange.API.Models.Response.UserDataStreamResponse

note last line:

2018-02-21 11:15:55,423 [4] DEBUG BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient - WebSocket Opened:wss://stream.binance.com:9443/ws/BinanceExchange.API.Models.Response.UserDataStreamResponse
Possible solution

AbstractBinanceWebSocketClient.cs
var endpoint = new Uri($"{BaseWebsocketUri}/{listenKey}");
Should be
var endpoint = new Uri($"{BaseWebsocketUri}/{listenKey.ListenKey}");

Another -2010 insufficient balance

Issue Overview

I'm attempting to send a market buy order to the ETHUSDT market - from the exception, this is the URL that gets fired: https://api.binance.com/api/v3/order?newOrderRespType=RESULT&symbol=ETHUSDT&side=BUY&type=MARKET&quantity=91.7066800000

This returns a -2010 insufficient balance exception, and I can't see why...

Package Version: 4.2.4

Repro Steps

  • Read account balances using GetAccountInformation, specifically pull out the USDT balance
  • Connect to the websocket for the ETHUSDT ticker and pull a price update message
  • Calculate how much ETH to buy:
    • Divide the USDT balance by the price
    • Deduct 0.0015 of itself (0.001 fee rate * 1.5 just to be safe)
    • Cut off the LOT_SIZE
  • Send the buy order:
var response = await binanceClient.CreateOrder(new CreateOrderRequest() {
       Symbol = tradingPair,
       Quantity = Math.Round(calculatedQuantity, 10),
       Side = OrderSide.Buy,
       Type = OrderType.Market
});
Other Information

It should also be noted that I have 35 BNB available in my account, and the toggle button to use BNB for fees is checked. I technically don't think I should have to pre-deduct anything to pay for the fees, since I have the BNB balance, but some other issues seem to suggest otherwise.

Thanks in advance!

Fix test ` CloseUserDataStream_ValidListenKey_CallsProcessPutRequest`

Issue Overview

Test is failing due to static instances when multiple tests run in async

Package Version: 4.0.0*

Repro Steps

  • Run all tests in solution
Other Information

This test shouldn't fail when others are ran async. Clearly are dispose isn't working and it could be an underlying issue

WAPI BaseURL contains an extra space

Issue Overview

In the file Endpoints.cs the private static var WAPIBaseUrl contains a superfluous space at the end. This causes the calls to the WAPI (like depositHistory, withdrawHistory, etc) to fail.

Package Version: 4.2.4

Repro Steps

  • Create a BinanceClient
  • Call client.GetDepositHistory(...)
Other Information

When you look at the generated endpoint that is passed to APIProcessor.ProcessRequest(...) in the debugger, you see an extra %20 in the url.

add Exchange Information endpoint

The official Binance API documentation has an endpoint where Exchange Information can be obtained.
I seriously think this endpoint should be added to the Road to 4.0.

Reason: Not only does it list Binance's rate limits for using their API, it also provides a contract that developers can use to obtain the most current symbol information -- information that is necessary in order to accurately calculate and make trades for a symbol, such as tickSize, min/maxPrice, min/maxQty, stepSize, etc. For example, if tomorrow Binance decides to change the stepSize for a symbol, if a developer is not aware of the change, then it is very possible that a calculated trade that is particular to a specific level of precision will fail if/when Binance changes things on their side. However, trusting and using this endpoint will allow developers to calculate accurate order info, as it will be based on the most current exchange info that Binance has published for all their symbols.

This endpoint is located along with Test/ping and Check Server Time under General endpoints on the official Binance API: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#exchange-information

I didn't see it under General Endpoints on BinanceDotNet, and at least for the reasons above, I do think it is worthy of swift addition: https://github.com/glitch100/BinanceDotNet/blob/master/docs/REST-API.md#general-endpoints

Exchange information

GET /api/v1/exchangeInfo

The response payload looks like this:

{
  "timezone": "UTC",
  "serverTime": 1508631584636,
  "rateLimits": [{
      "rateLimitType": "REQUESTS",
      "interval": "MINUTE",
      "limit": 1200
    },
    {
      "rateLimitType": "ORDERS",
      "interval": "SECOND",
      "limit": 10
    },
    {
      "rateLimitType": "ORDERS",
      "interval": "DAY",
      "limit": 100000
    }
  ],
  "exchangeFilters": [],
  "symbols": [{
    "symbol": "ETHBTC",
    "status": "TRADING",
    "baseAsset": "ETH",
    "baseAssetPrecision": 8,
    "quoteAsset": "BTC",
    "quotePrecision": 8,
    "orderTypes": ["LIMIT", "MARKET"],
    "icebergAllowed": false,
    "filters": [{
      "filterType": "PRICE_FILTER",
      "minPrice": "0.00000100",
      "maxPrice": "100000.00000000",
      "tickSize": "0.00000100"
    }, {
      "filterType": "LOT_SIZE",
      "minQty": "0.00100000",
      "maxQty": "100000.00000000",
      "stepSize": "0.00100000"
    }, {
      "filterType": "MIN_NOTIONAL",
      "minNotional": "0.00100000"
    }]
  }]
}

Keep up the good work. This wrapper is shaping up nicely.

Receiving event from UserDataWebSocket causes JsonSerializationException

Issue Overview

(AbstractBinanceWebSocketClient.cs)
Receiving an event from the UserDataWebSocket causes an exception on the following line:

var primitive = JsonConvert.DeserializeObject<IWebSocketResponse>(e.Data);

Package Version: 4.2.3

Repro Steps

UserDataWebSocketMessages userDataWebSocketMessages = new UserDataWebSocketMessages
            {
                OrderUpdateMessageHandler = new BinanceWebSocketMessageHandler<BinanceTradeOrderData>(x =>
                {
                    System.Console.WriteLine("Order Update Event");
                }),
                TradeUpdateMessageHandler = new BinanceWebSocketMessageHandler<BinanceTradeOrderData>(x =>
                {
                    System.Console.WriteLine("Order Update Event");
                }),
                AccountUpdateMessageHandler = new BinanceWebSocketMessageHandler<BinanceAccountUpdateData>(x =>
                {
                    System.Console.WriteLine("Account Update Event");
                })
            };

            using (var binanceWebSocketClient = new DisposableBinanceWebSocketClient(client))
            {
                binanceWebSocketClient.ConnectToUserDataWebSocket(userDataWebSocketMessages);
                await Task.Delay(-1);
            }
Exception
Newtonsoft.Json.JsonSerializationException
  HResult=0x80131500
  Message=Could not create an instance of type BinanceExchange.API.Models.WebSocket.Interfaces.IWebSocketResponse. Type is an interface or abstract class and cannot be instantiated. Path 'e', line 1, position 5.
  Source=Newtonsoft.Json
  StackTrace:
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at BinanceExchange.API.Websockets.AbstractBinanceWebSocketClient.<>c__DisplayClass15_0.<CreateUserDataBinanceWebSocket>b__1(Object sender, MessageEventArgs e) in C:\Users\romjab\Source\Repos\BinanceDotNet\BinanceExchange.API\Websockets\AbstractBinanceWebSocketClient.cs:line 117
   at WebSocketSharp.WebSocket.messagec(MessageEventArgs e)

Question: is there a way to hide small assets?

Issue Overview

This isn’t an issue, more of a feature question, I’ve noticed that it’s an option on both the app and website so I thought I would ask if this is available through the api somehow or not.

Refactor ApiProcessor

There are areas within the API Processor that need to be rewritten, and could aid in unit testing, and abstraction, which could lead to greater extensibility

Parameter name: The Guarded argument was null.

Issue Overview

Trying to execute a Market Order (via client.CreateTestOrder()) with a valid Key/Secret, the code throws an exception saying: "Parameter name: The Guarded argument was null."

Package Version: BinanceDotNet v4.0.1

Repro Steps

BinanceClient client = new BinanceClient(new ClientConfiguration {
ApiKey = "VALIDAPIKEY",
SecretKey = "VALIDSECRETKEY"
});

await client.CreateTestOrder(new CreateOrderRequest {
Symbol = "TRXBTC",
Quantity = 100,

Side = OrderSide.Buy,
Type = OrderType.Market

});

QueryOrder fails to deserialize OrderType on TakeProfitLimit

When we querying order of type "TakeProfitLimit" it fails with exception:

Newtonsoft.Json.JsonSerializationException: Error converting value "TAKE_PROFIT_LIMIT" to type 'BinanceExchange.API.Enums.OrderType'. Path 'type', line 1, position 213. ---> System.ArgumentException: Requested value 'TAKE_PROFIT_LIMIT' was not found.

My fix on this is:

[JsonConverter(typeof(StringEnumConverter))] // Added this attribute.
public enum OrderType

Should OriginalClientOrderId be of type STRING?

In trying to make sense of what to do with order IDs when creating orders, I was looking at the docs to see what the difference was between clientOrderId and orderId. I think I stumbled upon something. Per Binance's official API documentation, /api/v3/order shows that the parameter origClientOrderId is of type STRING. However, the QueryOrderRequest class in BinanceDotNet has the OriginalClientOrderId property as type LONG.

I could be missing something, but see:
See https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#query-order-user_data
vs
https://github.com/glitch100/BinanceDotNet/blob/master/BinanceExchange.API/Models/Request/QueryOrderRequest.cs

I'm still confused on the difference between clientOrderId and orderId, but I just wanted to point this possible issue with clientOrderId being of type LONG in BinanceDotNet, but being of type STRING in the official Binance API docs.

If the newClientOrderId is "automatically generated [by Binance] if not sent" in the request, and if it is of type String (as seen in the provided Response example ("clientOrderId": "6gCrw2kRUAF9CvJDGP16IP") see here -- https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#new-order--trade), then this will result in an error because BinanceDotNet is expecting LONG, but Binance's API returns STRING. And I don't think it is possible to convert something like "6gCrw2kRUAF9CvJDGP16IP" into LONG.

How to safely place buy order over binance filters

I'm trying to place buy order but getting lot size error. It seems to be rounding and step size issue.

Repro Steps

  • Let's say I'm trying to buy ZRXBTC with buy price 0.00005924 BTC and the trading limit is 0.001 BTC.

  • So, to get amount/quantity using rounding function like this: Math.Round(tradeLimit / buyPrice, 2), it gives 16.88

  • It'll throw error: {3: Server error: {"code":-1013,"msg":"Filter failure: LOT_SIZE"}}

  • Also if to get total (quantity * buyPrice) = 0.0009999712

  • It falls under MinNotional price (i.e 0.00100000)

  • So it throws error, {3: Server error: {"code":-1013,"msg":"Filter failure: MIN_NOTIONAL"}}

What's the best way to resolve this issue?

Support for combined streams

Issue Overview

Is there support for combined websocket streams? From what it looks like, it doesnt seem supported yet but happy to be corrected. If this is the case, is it in the roadmap?

New Feature: Add support for FOK

New Feature Overview

Reading up on the Binance API documentation, there are several references to Fill-Or-Kill order types. This is currently not support as of BinanceDotNet 4.x. This is especially useful for algorithmic trading robots as this feature would prevent any slippage to occur once the BUY/SELL Order has been calculated by the system.

Package Version:

BinanceDotNet 4.x

Deserializing BinanceTradeOrderData would cause an exception

Issue Overview

The following line in AbstractBinanceWebSocketClient.cs will cause a Json Serialization exception
(line 126)

case OrderTradeEventType:
                        var orderTradeData = JsonConvert.DeserializeObject<BinanceTradeOrderData>(e.Data);

Package Version: 4.2.3

Repro Steps

I had to edit the source file to get to this part of the code since the UserDataWebsocket is still buggy, it happens whenever the user data websocket gets an event for BinanceTradeOrderData

Exception
Newtonsoft.Json.JsonSerializationException: 'Could not create an instance of type BinanceExchange.API.Models.WebSocket.BinanceTradeOrderData. Type is an interface or abstract class and cannot be instantiated. Path 'e', line 1, position 5.

removing the abstract modifier for BinanceTradeOrderData.cs fixes the issue for me

Having issue with deployed app

Issue Overview

The app im building works in visual studio, but once deployed through setup.exe after a click once publish, the binancedotnet api fails to connect to my account. Im not sure if theres something missing in my setup or what. I just wanted to see if anyone here had any ideas.

If any more information is needed let me know.

  • Im using Visual Studio 2017 professional,
  • I've experienced this on two different dev machines as well.

Package Version: 4.2.4.0

Exception:

The type initializer for 'BinanceExchange.API.RequestClient' threw an exception.

Add in more complex examples

We currently have 2 examples for local caches that utilise the Client and WebSocket endpoints - this should be expanded to be part of the library with additional examples for User and Trade data

Add in unit test coverage

The repository unfortunately has no unit test coverage - this should be added at the next opportunity to ensure nothing breaks from future changes.

Technology to use:
XUnit

Handling web socket errors

Issue Overview

When looking at the code I'm wondering how to best handle web socket errors?

Here it throws an exception when a web socket error occurs.

If i'm not mistaking it will catch it here and log it without the library user being able to catch it?

If so, i guess the only way is to periodically compare ActiveWebSockets and AllSockets?

Package Version: 4.0.1

GetCompressedAggregateTrades() does not allow absence of optional parameters

Issue Overview

The Binance AggTrades REST API only requires symbol parameter to execute. However, if .StartTime is not set in GetCompressedAggregateTradeRequest Model, it defaults to datetime.minvalue which API Guards against and throws exception.

Package Version: 4.2.0

Repro Steps

Sorry, working in VB.Net......

Code:
Dim Config As New Client.ClientConfiguration
Config.ApiKey = "X"
Config.SecretKey = "C"
Dim Client As New Client.BinanceClient(Config)
Dim Req As New Models.Request.GetCompressedAggregateTradesRequest
Req.Symbol = "LTCBTC"
Dim Result As List(Of Models.Response.CompressedAggregateTradeResponse) = Await Client.GetCompressedAggregateTrades(Req)

Throws the exception:
"The Guarded argument was DateTime min."

Underlying issue:
Because StartTime and EndTime are not defined as nullable in GetCompressedAggregateTradeRequest Model, they initialize to DateTime.MinValue and thus fail Guard.AgainstDateTimeMin()
This also inherently makes StartTime and EndTime required parameters to GetCompressedAggregateTrades() even though Binance REST API does not require them.

Other Information

From Binance API Docs:
aggtrades
From BinanceDotNet Source:
guardmindatetime

Enhance CreateOrder:Request/Response to include ACK, RESULT, OR FULL

The official Binance API's new order(trade) endpoint POST /api/v3/order allows requests to include the type of response desired, whether ACK, RESULT, or FULL via the newOrderRespType parameter in the request. The RESULT and FULL response payloads provide more useful info than the ACK response, particularly the "status". For example, if an order is immediately filled, the developer can know this immediately in the response, and can then move on to the next step in the app flow. However, if the order is not filled, the developer will also know this immediately, and can pause the app flow and check back later (e.g. via QueryOrder, passing in the orderId).

However, in BinanceDotNet, new orders are limited and do not have this functionality, namely, the CreateOrderRequest object in IBinanceClient.CreateOrder(CreateOrderRequest request) does not allow a developer to specify the desired response. Thus, the response only includes an instance of CreateOrderResponse, which currently only provides info from Binance's ACK response, and it does not have other important information (status, etc.) See https://github.com/glitch100/BinanceDotNet/blob/master/BinanceExchange.API/Models/Response/CreateOrderResponse.cs.

So, when using BinanceDotNet, in order to know whether or not an order has been filled after it has been created, a second request must be made to get that information (using IBinanceClient.QueryOrder(QueryOrderRequest request ...). If speedy trades are important to developers/traders (they are), then saving precious milliseconds is vital, so avoiding the need to make this second request is pretty important. Plus, because Binance has API usage limits, not having to make a second request to gather this information would reduce usage against one's API request limit.

Because Binance's API provides this information immediately in its response to the POST /api/v3/order endpoint, I cast a strong vote that BinanceDotNet's CreateOrder:CreateOrderResponse be modified to match Binance's official API new order endpoint, and allow RESULT and FULL response types to be requested and also allow RESULT and FULL payload responses to be returned.

Note: I would attempt to do this myself, but I'd screw it up badly and waste everyone's time. (I'm a technical writer, hence my understanding of APIs and things, but I'm very new to C# and git/github.) Just trying to contribute to the development here by informing everyone where this wrapper could be enhanced for all.

From Binance's API:

https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#new-order--trade

New order (TRADE)

POST /api/v3/order  (HMAC SHA256)

Parameters:

Name Type Mandatory Description
... ... ... ...
newOrderRespType ENUM NO Set the response JSON. ACK, RESULT, or FULL; default: RESULT.
... ... ... ...

Response ACK:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595
}

Response RESULT:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595,
  "price": "0.00000000",
  "origQty": "10.00000000",
  "executedQty": "10.00000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "MARKET",
  "side": "SELL"
}

Response FULL:

{
  "symbol": "BTCUSDT",
  "orderId": 28,
  "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
  "transactTime": 1507725176595,
  "price": "0.00000000",
  "origQty": "10.00000000",
  "executedQty": "10.00000000",
  "status": "FILLED",
  "timeInForce": "GTC",
  "type": "MARKET",
  "side": "SELL",
  "fills": [
    {
      "price": "4000.00000000",
      "qty": "1.00000000",
      "commission": "4.00000000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3999.00000000",
      "qty": "5.00000000",
      "commission": "19.99500000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3998.00000000",
      "qty": "2.00000000",
      "commission": "7.99600000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3997.00000000",
      "qty": "1.00000000",
      "commission": "3.99700000",
      "commissionAsset": "USDT"
    },
    {
      "price": "3995.00000000",
      "qty": "1.00000000",
      "commission": "3.99500000",
      "commissionAsset": "USDT"
    }
  ]
}

Allow (string symbol) in IBinanceClient.GetSymbolOrderBookTicker, and typos in the docs

Two issues related to wrapping Binance's "Symbol order book ticker" endpoint:
GET /api/v3/ticker/bookTicker

  1. BinanceDotNet documentation has errors.
  2. IBinanceClient.GetSymbolOrderBookTicker() should also allow including (string symbol) as a parameter.

1. BinanceDotNet documentation:

2. (string symbol) parameter in IBinanceClient.GetSymbolOrderBookTicker()

Binance's GET /api/v3/ticker/bookTicker endpoint allows providing the optional parameter symbol of type STRING, which will return the bookTickers for that particular symbol. Additionally, "If the symbol is not sent, bookTickers for all symbols will be returned in an array." IBinanceClient.GetSymbolOrderBookTicker() does not allow one to provide a symbol for obtaining bookTickers for a particular symbol and only returns bookTickers for all symbols.

Because speed and being lightweight is important, correcting this should be on the roadmap.

Personally, the extra milliseconds it takes to download the entire list of bookTickers for all symbols is having a negative effect on my app; it is being developed to place an order immediately after a particular calculation is made and before an opportunity is lost, so speed is vital here, and I only need to receive the bookTickers for a particular symbol. Allowing IBinanceClient.GetSymbolOrderBookTicker()'s response to be lightweight for a particular symbol would really help.

Reference: https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#symbol-order-book-ticker

Cancelled -> Canceled in OrderStatus enum

The spelling of canceled is wrong in the OrderStatus enum which is throwing an exception on line

messageObject = JsonConvert.DeserializeObject(messageJson);

in APIProcessor.HandleResponse()

I'd submit a fix for this but I don't know how on github. Fixing this locally for now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.