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.04k stars 428 forks source link

Question for WPF WebSockets. #364

Closed ExceedingLife closed 4 years ago

ExceedingLife commented 4 years ago

Hello, I am working on displaying all trades into a listview through websockets. I wanted to create a method that returns the data from a websocket call. the message I get is - Anonymous function converted to a void returning delegate cannot return a value. I've never worked with websockets setup this way so its new for me. how would you suggest i do this? any examples you could by chance help me with quick. Here is the method I was going to make:

public async Task<BinanceStreamTrade> StartBTCTradesChannel() { using (var client = new BinanceSocketClient()) { var trades = client.SubscribeToTradeUpdatesAsync("BTCUSD", (data) => { return data.OrderId; }); } return null; }

then i would call this in my mainwindow.cs code to display results in a listview. Would would you do in my situation? Thank you.

infinitibot commented 4 years ago

Just use a datagrid to display the data. Use a ObservableCollection that is in sync with your WPF output, if you change something in your list (from type ObservableCollection) it will be display in your UI.

ViewHarvesterPair is my Object (data type), this is my own example from my own project. So you need to change it.

 ViewHarvesterPairList = new ObservableCollection<ViewHarvesterPair>(db.ViewHarvesterPairs.Where(p => p.ExchangeAccountTypeId == 2).OrderBy(p=>p.LeftPair));

My list

private ObservableCollection<ViewHarvesterPair> _viewHarvesterPairList;
public ObservableCollection<ViewHarvesterPair> ViewHarvesterPairList
{
      get { return _viewHarvesterPairList; }
      set { SetProperty(ref _viewHarvesterPairList, value); }
}

My selected item,

private ViewHarvesterPair _viewHarvesterPairSelectedItem; 
public ViewHarvesterPair ViewHarvesterPairSelectedItem
{
    get { 
    return _viewHarvesterPairSelectedItem; 
   }
  set 
  {   
  SetProperty(ref _viewHarvesterPairSelectedItem, value);
}

Its a combobox example, buth it will work with a datagrid also,

<ComboBox ItemsSource="{Binding Path=ViewHarvesterPairList, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding Path=ViewHarvesterPairSelectedItem.ExchangeUse, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=False, ValidatesOnExceptions=False}" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Pair" SelectedValuePath="Pair" Grid.Row="4" Grid.ColumnSpan="5" VerticalContentAlignment="Center" SelectionChanged="ComboBox_SelectionChanged" Grid.Column="3" />

ExceedingLife commented 4 years ago

thanks for the quick response ill give it a try

infinitibot commented 4 years ago

Does te price ticker socket works for you?

ExceedingLife commented 4 years ago

'SubscribeToSymbolTickerUpdates' and 'SubscribeToTradeUpdatesAsync' are what I been using and they both work. is this the ticker 1 your asking about?

infinitibot commented 4 years ago

yes, if you have problems with something please contact me

infinitibot commented 4 years ago

I'm also a programmer that worked 2 years on my own software for buy and sell. I'm very interesting how other people make software. Maybe i can improve myself.

You have Telegram ? Whatsapp? I want to make a small list with people that do the same things, (programming)

ExceedingLife commented 4 years ago

no sorry only Microsoft Teams and Skype I'm interested with the team you are describing. I built myself a coinbase pro bot but the fees on binance are 5x cheaper so im switching to binance.us. I am going the websocket way which i have not done yet. before i was using tasks/threads and recursively looping them. Websockets i bet will be much more efficient.

ExceedingLife commented 4 years ago

so my question is:

i have a button that is supposed to turn on a websocket. and i have a listview with data binding.

but nothing is showing up. is this that im supposed to do to turn on and have a continous websocket connection?

` public ObservableCollection<IncomingTradeVM> IncomingTrades { get; set; }
        private BinanceSocketClient binanceSocketClient;
        public MainWindow()
        {
            InitializeComponent();
            //BinanceSocketClient = new BinanceSocketClient();
            IncomingTrades = new ObservableCollection<IncomingTradeVM>();
            lstIncoming.ItemsSource = IncomingTrades;
        }

        private void BtnStartCapture_Click(object sender, RoutedEventArgs e)
        {
            //using (var client = new BinanceSocketClient())
            using(binanceSocketClient = new BinanceSocketClient())
            {                   //client.SubscribeToTradeUpdatesAsync("BTCUSD", (data) =>
                var incomingBTC = binanceSocketClient.SubscribeToTradeUpdatesAsync("BTCUSD", (data) =>
                {
                    IncomingTrades.Add(new IncomingTradeVM()
                    {
                        TradeID = data.OrderId,
                        Price = data.Price,
                        CryptoAmount = data.Quantity,
                        TradeTime = data.TradeTime,
                        TradeSymbol = data.Symbol,
                        EventType = data.Event,
                        IsMaker = data.BuyerIsMaker,
                        EventTime = data.EventTime,
                        BuyerID = data.BuyerOrderId,
                        SellerID = data.SellerOrderId
                    });
                });
            }
        }
                    <GridViewColumn Header="Price" Width="100" DisplayMemberBinding="{Binding Price}"/>

`

infinitibot commented 4 years ago

So you constant want to add items to IncomingTrades? IncomingTrades is a list that is linked to a WPF object ListView. So after 1 minut it will be more then 1000 records, do you want that?

Can you send me your project in zip file (without your API key)

ExceedingLife commented 4 years ago

Its only newly posted trades buy and sells only for BTCUSD. its like a few trades a min, binance.us trades are slower than coinbasepro trades. that is what im trying to do at the moment. my project is pretty fresh this is my first stage on this wpf binanse.us to get websockets to process in a listview next ill be doing trades with a restapi. So yes if you know how to turn websockets on with the click of a button to my Incomingtades list that is linked to a wpf object listview that is exactly what i am looking for :) lol

infinitibot commented 4 years ago

Can you send me a small project to example? I will edit it so you have a perfect start for your project.

ExceedingLife commented 4 years ago

Here is a snippet of the MainWindow. if you have a way you want my project id send you the whole thing. its basically just this window though at the moment.

 public partial class MainWindow : Window
    {
        private ObservableCollection<IncomingTradeVM> _incomingTrades;
        public ObservableCollection<IncomingTradeVM> IncomingTrades { get; set; }
        public BinanceClient BinanceClient;
        private BinanceSocketClient binanceSocketClient;

        public MainWindow()
        {
            InitializeComponent();
            IncomingTrades = new ObservableCollection<IncomingTradeVM>();
            lstIncoming.ItemsSource = IncomingTrades;
        }

        private void BtnStartCapture_Click(object sender, RoutedEventArgs e)
        {
            using(binanceSocketClient = new BinanceSocketClient())
            {
                var incomingBTC = binanceSocketClient.SubscribeToTradeUpdatesAsync("BTCUSD", (data) =>
                {
                    IncomingTrades.Add(new IncomingTradeVM()
                    {
                        TradeID = data.OrderId,
                        Price = data.Price,
                        CryptoAmount = data.Quantity,
                        TradeTime = data.TradeTime,
                        TradeSymbol = data.Symbol,
                        EventType = data.Event,
                        IsMaker = data.BuyerIsMaker,
                        EventTime = data.EventTime,
                        BuyerID = data.BuyerOrderId,
                        SellerID = data.SellerOrderId
                    });
                });
            }
        }

        private void BtnStopCapture_Click(object sender, RoutedEventArgs e)
        {
            var client =new BinanceSocketClient();
            binanceSocketClient.UnsubscribeAll();
        }
    }
ExceedingLife commented 4 years ago

Here is my gist of my project https://gist.github.com/ExceedingLife/d1f5aada578c4bc16b4a3e41c9d261fe

infinitibot commented 4 years ago

Thx, i will look to it later on the day. Where are you frome? I'm from Belgium. Interest in to join a new telegram group only for programming bot? It's for learning only. I want to collect people from over the world in one group that are busy to programm a trading bot... so i can learn how other people make things.

ExceedingLife commented 4 years ago

USA I have this bot working on coinbase pro with Tasks and multithreading im interested in the group I want to make this bot with websockets for Binance. Thanks for taking a look at this when you get time. I assume im close.

infinitibot commented 4 years ago

Hallo,

Some questions,

I will change soms things but i first need to know the above questions.

Regards,

ExceedingLife commented 4 years ago

ObservableCollection automatically has inotifypropertychanged? I am only working on websockets at this moment i have the trades set for being like a market buy sell and then it buys it back or resells on price changes. it works well for what i need it for. my only thing i want is websockets to show new trades in my listview, after i get this i can do everything else

ExceedingLife commented 4 years ago

So i got it working but without data binding. Here is what I currently have, I'd like to do this the more proper way though..

        private void BtnStartCapture_Click(object sender, RoutedEventArgs e)
        {
            using(binanceSocketClient = new BinanceSocketClient())
            {              
                var incomingBTC = binanceSocketClient.SubscribeToTradeUpdatesAsync("BTCUSD", (data) =>
                {
                    var newtrade = new IncomingTradeVM()
                    {
                        Price = data.Price,
                        CryptoAmount = data.Quantity,
                        TradeTime = data.TradeTime,
                    };
                    PrintTrade(newtrade);
                });
            }
 private async Task PrintTrade(IncomingTradeVM trade)
        {
            if(trade != null)
            {
                await lstTwo.Dispatcher.InvokeAsync(() =>
                {
                    lstTwo.Items.Add(trade);
                });
            }
        }
ExceedingLife commented 4 years ago

So I officially got it working with Data-Binding. I had to move the lstIncoming.ItemSource = trades into the WebSocket request. I believe I need to update the itemsource each time a new item is added to the list.

 private void BtnStartCapture_Click(object sender, RoutedEventArgs e)
        {
            using(binanceSocketClient = new BinanceSocketClient())
            {             
                var incomingBTC = binanceSocketClient.SubscribeToTradeUpdatesAsync("BTCUSD", (data) =>
                {
                    lstIncoming.Dispatcher.Invoke(() =>
                    {
                        IncomingTrades.Add(new IncomingTradeVM()
                        {
                            TradeID = data.OrderId,
                            Price = data.Price,
                            CryptoAmount = data.Quantity,
                            TradeTime = data.TradeTime,
                            TradeSymbol = data.Symbol,
                            EventType = data.Event,
                            IsMaker = data.BuyerIsMaker,
                            EventTime = data.EventTime,
                            BuyerID = data.BuyerOrderId,
                            SellerID = data.SellerOrderId
                        });                  
                        lstIncoming.ItemsSource = IncomingTrades;
                    });                    
                });
            }