JKorf / Binance.Net

A C# .netstandard client library for the Binance REST and Websocket Spot and Futures API focusing on clear usage and models
https://jkorf.github.io/Binance.Net/
MIT License
1.03k stars 425 forks source link

Sub-calls of SubscribeToUserDataUpdatesAsync function not coming (positionchange) #1245

Closed gelebians closed 1 year ago

gelebians commented 1 year ago

All 5 calls (leverageupdate, marginupdate, etc.) in the SubscribeToUserDataUpdatesAsync function do not work. Although I am in the position, userdataupdate data is not coming. As an example, I placed an order and canceled it. There was no trigger orderupdate. where am i doing wrong. var apiAyar = new BinanceApiCredentials(GenelAyar.Default.ApiKey, GenelAyar.Default.SecretKey); _soket = new BinanceSocketClient(new BinanceSocketClientOptions() { ApiCredentials = apiAyar,LogLevel=LogLevel.Debug }); var key = await _istemci.CoinFuturesApi.Account.StartUserStreamAsync(); if (key.Success) await _soket.CoinFuturesStreams.SubscribeToUserDataUpdatesAsync(key.Data, CoinMKaldıraçOlayı, CoinMMarginÇağrısı, CoinMHesapGüncellemesi, CoinMSiparişGüncellemesi, CoinMKeySüreDoldu, soketİptal);

JKorf commented 1 year ago

Hard to say. Can you try setting LogLevel to Trace in the socket client options? You should see logging in the VS Output window on what the client is doing. Also you should check if the SubscribeToUserDataUpdatesAsync call is successful by checking the returned object

gelebians commented 1 year ago

Trace | Binance | Socket 1 sent 107 bytes 2023.05.03 10:19:42:630 | Trace | Binance | Socket 1 received 22 bytes in single message 2023.05.03 10:19:42:644 | Trace | Binance | Socket 1 received data: {"id":9,"result":null} 2023.05.03 10:19:42:658 | Trace | Binance | Socket 1 Subscription completed

Thread 0xd130 exited with code 0 (0x0).

JKorf commented 1 year ago

Seems fine. 2 things that might cause the issue

  1. You're using the Coin Futures stream while you're position is on USDT futures
  2. The socket client or program is disposed before anything happens. Could you share some more context on how your code works?
gelebians commented 1 year ago

Of course `public MainWindow() { InitializeComponent(); DataContext = this; ApiKey.Text = GenelAyar.Default.ApiKey; SecretKey.Text = GenelAyar.Default.SecretKey; VadeliTürü.SelectedValue = (Piyasaİşlemi)GenelAyar.Default.VadeliTürü; CoinAdı.SelectedItem = new ÖzelVeri() { Başlık = GenelAyar.Default.CoinSembol, Değer = GenelAyar.Default.CoinSembol }; Mum.SelectedValue = GenelAyar.Default.Mum; NwuPeriot.Value = GenelAyar.Default.NwuPeriot; NwuKaynak.SelectedValue = (OHLCTürü)GenelAyar.Default.NwuKaynak; var apiAyar = new BinanceApiCredentials(GenelAyar.Default.ApiKey, GenelAyar.Default.SecretKey); _istemci = new BinanceClient(new BinanceClientOptions() { ApiCredentials = apiAyar }); _soket = new BinanceSocketClient(new BinanceSocketClientOptions() { ApiCredentials = apiAyar,LogLevel=LogLevel.Trace }); _soketİptal = new CancellationTokenSource();

        PozisyonGörünüm = Visibility.Collapsed;
        Siparişler = new ObservableCollection<Sipariş>();
        _ = KlineİlkYükleme();

    }

private async Task KlineİlkYükleme() { CancellationToken soketİptal = _soketİptal.Token; if (((Piyasaİşlemi)GenelAyar.Default.VadeliTürü) == Piyasaİşlemi.CoinM) { //Kline verilerini çekme var veri = await istemci.CoinFuturesApi.ExchangeData.GetKlinesAsync(symbol: GenelAyar.Default.CoinSembol.Replace("", string.Empty)+"_PERP", interval: (KlineInterval)GenelAyar.Default.Mum, limit: 500); if (veri.Success) { _temelKaynak = veri.Data.ToList().ConvertAll(x => new OHLC() { T = x.OpenTime, O = x.OpenPrice, H = x.HighPrice, L = x.LowPrice, C = x.ClosePrice, V = x.Volume }); mesajYöneticisi.ShowAlert(new RadDesktopAlert() { Header = "Veri Alma", Content = GenelAyar.Default.CoinSembol + " verilerini alma başarılı." }); GüncelFiyat = _temelKaynak[_temelKaynak.Count - 1].C; } else { mesajYöneticisi.ShowAlert(new RadDesktopAlert() { Header = "Hata", Content = GenelAyar.Default.CoinSembol + " verileri alınamadı. Hata Kodu:" + veri.Error.Message }); } //Cüzdan verilerini çekme var cüzdan = await istemci.CoinFuturesApi.Account.GetBalancesAsync(); if (cüzdan.Success) { var bilgi = cüzdan.Data.ToList().Where(x => x.Asset == GenelAyar.Default.CoinSembol.Split("")[0]).FirstOrDefault(); Bakiye = bilgi.WalletBalance; MarjMiktarı = Bakiye+bilgi.CrossUnrealizedPnl; BekleyenPnl = bilgi.CrossUnrealizedPnl; ToplamUsdt = Bakiye * _temelKaynak[_temelKaynak.Count - 1].C;

            }
            //coin bilgilerini çekme
            var coinbilgi = await _istemci.CoinFuturesApi.Account.GetBracketsAsync(symbolOrPair:GenelAyar.Default.CoinSembol.Replace("_",String.Empty));
            if (coinbilgi.Success)
            {
                _vadeliBilgi = coinbilgi.Data.ToList()[0].Brackets.ToList().Where(x => x.Bracket == 1).FirstOrDefault();
                KaldıraçOranı.Maximum = _vadeliBilgi.InitialLeverage;
                KaldıraçOranı.Value = 1;
                KaldıraçOranı.LargeChange = KaldıraçOranı.TickFrequency = _vadeliBilgi.InitialLeverage / 5;

            }
            //Pozisyon verilerini çekme
            var pozisyon = await _istemci.CoinFuturesApi.Account.GetPositionInformationAsync(marginAsset: GenelAyar.Default.CoinSembol.Split("_")[0]);
            if (pozisyon.Success)
            {
                var pozbilgi = pozisyon.Data.ToList().FirstOrDefault();
                PozisyonGörünüm = (pozisyon.Data.ToList().Count > 0) ? Visibility.Visible : Visibility.Collapsed;
                BekleyenPnl = pozbilgi.UnrealizedPnl;
                MarjMiktarı = Bakiye + pozbilgi.UnrealizedPnl;

                if (pozbilgi.PositionSide == PositionSide.Short)
                {
                    PozisyonYönü = "SHORT";
                    YönRengi = new SolidColorBrush(Colors.Red);
                }
                else
                {
                    PozisyonYönü = "LONG";
                    YönRengi = new SolidColorBrush(Colors.Green);
                }
                PozisyonKaldıraçı = pozbilgi.Leverage;
                PozisyonMarjı = pozbilgi.IsolatedMargin;
                MarjBüyüklük = pozbilgi.Quantity;
                GirişFiyatı = pozbilgi.EntryPrice;
                LiqFiyatı = pozbilgi.LiquidationPrice;
                int pozyön = (pozbilgi.PositionSide == PositionSide.Short) ? -1 : 1;
                PozRengi = (pozyön < 0) ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Green);
                ROE = Decimal.ToDouble(pozyön * pozbilgi.UnrealizedPnl/ pozbilgi.IsolatedMargin);

            }
            //Sipariş bilgisi getir
            var sipariş = await _istemci.CoinFuturesApi.Trading.GetOpenOrdersAsync(symbol: GenelAyar.Default.CoinSembol.Split("_")[0]);
            if (sipariş.Success)
            {
                if (sipariş.Data != null)
                {
                    Siparişler = new ObservableCollection<Sipariş>(sipariş.Data.ToList().ConvertAll(x => new Sistem.Sipariş() { 
                        SiparişID = x.ClientOrderId,
                        EmirTürü=x.Side,
                        PozisyonYönü=x.PositionSide,
                        SiparişTürü=x.Type,
                        SiparişDurumu=x.Status,
                        SiparişMiktarı=x.Quantity,
                        SiparişFiyatı=x.Price,
                        StopFiyatı=(decimal)x.StopPrice
                    }));

                }

            }
        }
        else
        {
            var veri = await _istemci.UsdFuturesApi.ExchangeData.GetKlinesAsync(symbol: GenelAyar.Default.CoinSembol.Replace("_", string.Empty), interval: (KlineInterval)GenelAyar.Default.Mum, limit: 500);
            if (veri.Success)
            {
                _temelKaynak = veri.Data.ToList().ConvertAll(x => new OHLC() { T = x.OpenTime, O = x.OpenPrice, H = x.HighPrice, L = x.LowPrice, C = x.ClosePrice, V = x.Volume });
                mesajYöneticisi.ShowAlert(new RadDesktopAlert() { Header = "Veri Alma", Content = GenelAyar.Default.CoinSembol + " verilerini alma başarılı." });
            }
            else
            {
                mesajYöneticisi.ShowAlert(new RadDesktopAlert() { Header = "Hata", Content = GenelAyar.Default.CoinSembol + " verileri alınamadı. Hata Kodu:" + veri.Error.Message });
            }
        }
        Klines = new ObservableCollection<OHLC>(_temelKaynak);
        //Nwu verileri gruplandırılarak rengine göre çizilmek üzere hazırlanıyor
        NwuVeri = new List<List<NwuResult>>();
        _temelNwu = İndikatör.NwuGetir(_temelKaynak, 8, OHLCTürü.C).ToList();
        SinyalYönü tempYön = SinyalYönü.DUMP;
        NwuResult tempnwu = null;
        bool ilkVeri = true;
        int j = 0;
        for (int i = 0; i < _temelNwu.Count; i++)
        {
            //ilk veriyse boş liste ekle
            if (i == 0)
                NwuVeri.Add(new List<NwuResult>());

            //ilk veri değiolse ve yön öncekinden farklı ise boş liste ekle j 1 artır, nwu j inci veriye önceki nwu yu ekle
            if (_temelNwu[i].Yön != tempYön && i > 0)
            {
                NwuVeri.Add(new List<NwuResult>());
                j++;
                NwuVeri[j].Add(tempnwu);
            }
            else
            {
                NwuVeri[j].Add(_temelNwu[i]);
            }
            tempnwu = _temelNwu[i];
            tempYön = _temelNwu[i].Yön;

        }

        /*
        var candleSeri = new CandlestickSeries();
        candleSeri.CategoryBinding = new PropertyNameDataPointBinding("T");
        candleSeri.HighBinding= new PropertyNameDataPointBinding("H");
        candleSeri.OpenBinding = new PropertyNameDataPointBinding("O");
        candleSeri.LowBinding=new PropertyNameDataPointBinding("L");
        candleSeri.CloseBinding=new PropertyNameDataPointBinding("C");
        Binding binding = new Binding("Klines");
        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        candleSeri.SetBinding(CandlestickSeries.ItemsSourceProperty, binding);
        Grafik.Series.Add(candleSeri);
       */
        for (int i = 0; i < NwuVeri.Count; i++)
        {
            var nwuSeri = new Telerik.Windows.Controls.ChartView.SplineSeries();
            nwuSeri.Stroke = (NwuVeri[i][0].Yön == SinyalYönü.PUMP) ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Red);
            nwuSeri.CategoryBinding = new PropertyNameDataPointBinding("Date");
            nwuSeri.ValueBinding = new PropertyNameDataPointBinding("Y");
            Binding binding2 = new Binding("NwuVeri[" + i + "]");
            binding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            nwuSeri.SetBinding(Telerik.Windows.Controls.ChartView.SplineSeries.ItemsSourceProperty, binding2);
            Grafik.Series.Add(nwuSeri);
        }

        Sembol = GenelAyar.Default.CoinSembol.Split("_")[0];
        if (((Piyasaİşlemi)GenelAyar.Default.VadeliTürü) == Piyasaİşlemi.CoinM)
        {
            //
            var key = await _istemci.CoinFuturesApi.Account.StartUserStreamAsync();
            if (key.Success)
                await _soket.CoinFuturesStreams.SubscribeToUserDataUpdatesAsync(key.Data, CoinMKaldıraçOlayı, CoinMMarginÇağrısı, CoinMHesapGüncellemesi, CoinMSiparişGüncellemesi, CoinMKeySüreDoldu, soketİptal);
            //await _soket.CoinFuturesStreams.SubscribeToIndexKlineUpdatesAsync(GenelAyar.Default.CoinSembol.Replace("_", string.Empty), KlineInterval.FiveMinutes, KlineGeldi, soketİptal);
        }
        else
        {
            var key = await _istemci.UsdFuturesApi.Account.StartUserStreamAsync();
            //await _soket.UsdFuturesStreams.SubscribeToUserDataUpdatesAsync(key.Data, CoinMKaldıraçOlayı, CoinMMarginÇağrısı, CoinMHesapGüncellemesi, CoinMSiparişGüncellemesi, CoinMKeySüreDoldu, soketİptal);
        }
    }

CoinMHesapGüncellemesi() private void CoinMHesapGüncellemesi(DataEvent obj) { MessageBox.Show("xxx");

    }

` sorry i couldn't edit the code in the message

JKorf commented 1 year ago

It's a bit hard to get through without formatting and in Turkish (I assume?). Does the USDT futures variant work or doesn't it work either for you?

gelebians commented 1 year ago

usdtfutures haven't tried it yet. I'm progressing step by step.

salsburg commented 1 year ago

I'm having a similar issue, and can offer some more insight, but not yet a solution. I am subscribed to user data updates on both usdm futures, as well as spot. I am getting order, position, and asset updates perfectly in usdm futures. In spot, I am getting balance updates just fine. But I am getting absolutely no order updates in spot.

I ran the trace, and see this in the immediate window, when the order update is supposed to come thru (send new buy order -1% below bid price). This problem is because of field "V" in the orderupdate executionReport. Please see below. What is the fix to get this orderupdate on spot to work? Thank you!

2023/05/08 15:05:41:348 | Warning | Binance | Couldn't deserialize data received from order stream: : Deserialize JsonSerializationException: Error converting value "NONE" to type 'System.Nullable`1[System.Int64]'. Path 'data.V', line 37, position 15. data: { "e": "executionReport", "E": 1683558340130, "s": "ETHUSDT", "c": "23050854269--0", "S": "BUY", "o": "LIMIT", "f": "GTC", "q": "0.01100000", "p": "1848.88000000", "P": "0.00000000", "F": "0.00000000", "g": -1, "C": "", "x": "NEW", "X": "NEW", "r": "NONE", "i": 13375317883, "l": "0.00000000", "z": "0.00000000", "L": "0.00000000", "n": "0", "N": null, "T": 1683558340126, "t": -1, "I": 27872231469, "w": true, "m": false, "M": false, "O": 1683558340126, "Z": "0.00000000", "Y": "0.00000000", "Q": "0.00000000", "W": 1683558340126, "V": "NONE" }

salsburg commented 1 year ago

I solved my issue above by simply updating to Binance.Net 8.6.0. It looks like SocketClient.SpotStreams moved to SocketCilent.SpotApi.Account; and other refactors within the namespace. Also the json serialization based errors disappeared with the update.