public void should_receive_position_change_notification() { // arrange var connected = Sut.Connect(); var @params = OrderPOSTRequestParams.CreateSimpleMarket("XBTUSD", 3, OrderSide.Buy); // act IList <PositionDto> dtos = null; var dataReceived = new ManualResetEvent(false); Sut.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <PositionDto> > .Create(SubscriptionType.position, a => { dtos = a.ToList(); dataReceived.Set(); })); var result = _bitmexApiService.Execute(BitmexApiUrls.Order.PostOrder, @params).Result; result.Should().NotBeNull(); result.OrdType.Should().Be("Market"); result.OrdStatus.Should().Be("Filled"); result.OrderId.Should().NotBeNull(); var received = dataReceived.WaitOne(TimeSpan.FromSeconds(20)); // assert // no exception raised connected.Should().BeTrue(); received.Should().BeTrue("data hasn't received"); dtos.Should().NotBeNull(); dtos.Count().Should().BeGreaterThan(0); }
public void Unsubscribe(BitmexApiSubscriptionInfo subscription) { var task = UnsubscribeAsync(subscription); task.ConfigureAwait(false); task.Wait(); }
public void should_receive_limit_order_notification() { // arrange var connected = Sut.Connect(); var @params = OrderPOSTRequestParams.CreateSimpleLimit("XBTUSD", 3, _xbtAvgPrice - 500, OrderSide.Buy); // act IList <OrderDto> dtos = null; var dataReceived = new ManualResetEvent(false); Sut.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <OrderDto> > .Create(SubscriptionType.order, a => { dtos = a.ToList(); dataReceived.Set(); })); var result = _bitmexApiService.Execute(BitmexApiUrls.Order.PostOrder, @params).Result; result.Should().NotBeNull(); result.OrdType.Should().Be("Limit"); result.OrdStatus.Should().Be("New"); result.OrderId.Should().NotBeNull(); Thread.Sleep(2000); var received = dataReceived.WaitOne(TimeSpan.FromSeconds(20)); // assert // no exception raised connected.Should().BeTrue(); received.Should().BeTrue(); dtos.Should().NotBeNull(); dtos.Count().Should().BeGreaterThan(0); dtos[0].OrdType.Should().Be("Limit"); dtos[0].OrdStatus.Should().Be("New"); dtos[0].OrderId.Should().Be(result.OrderId); }
private void StartLoad() { try { IsConnected = _bitmexApiSocketService.Connect(); } catch (Exception e) { MessageBox.Show(e.Message); } if (IsConnected) { _bitmexApiSocketService.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <InstrumentDto> > .Create(SubscriptionType.instrument, dtos => { foreach (var instrumentDto in dtos) { lock (_syncObj) { var existing = Instruments.FirstOrDefault(a => a.Symbol == instrumentDto.Symbol); if (existing != null) { Mapper.Map <InstrumentDto, InstrumentModel>(instrumentDto, existing); } else { Instruments.Add(Mapper.Map <InstrumentDto, InstrumentModel>(instrumentDto)); } } } })); _bitmexApiSocketService.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <OrderDto> > .Create(SubscriptionType.order, dtos => { foreach (var order in dtos) { lock (_syncObjOrders) { var existing = OrderUpdates.FirstOrDefault(a => a.OrderId == order.OrderId); if (existing != null) { Mapper.Map <OrderDto, OrderUpdateModel>(order, existing); } else { OrderUpdates.Add(Mapper.Map <OrderDto, OrderUpdateModel>(order)); } } OnPropertyChanged(nameof(OrderUpdates)); } })); } }
/// <summary> /// Sends to the server a request for subscription on specified topic with specified arguments and waits for response from it. /// If you ok to use provided DTO mdoels for socket communication please use <see cref="BitmetSocketSubscriptions"/> static methods to avoid Subscription->Model mapping mistakes. /// </summary> /// <exception cref="BitmexSocketSubscriptionException">Throws when either timeout is reached or server retured an error.</exception> /// <typeparam name="T">Expected type</typeparam> /// <param name="subscription">Specific subscription details. Check out <see cref="BitmetSocketSubscriptions"/>.</param> public void Subscribe(BitmexApiSubscriptionInfo subscription) { var subscriptionName = subscription.SubscriptionName; var message = new SocketSubscriptionMessage(subscription.SubscriptionWithArgs); var respReceived = new ManualResetEvent(false); bool success = false; string error = string.Empty; string status = string.Empty; var errorArgs = new string[0]; OperationResultEventHandler resultReceived = args => { if (args.OperationType == OperationType.subscribe) { error = args.Error; status = args.Status; success = args.Result; errorArgs = args.Args; respReceived.Set(); } }; //TODO this _bitmexApiSocketProxy.OperationResultReceived += resultReceived; Log.Info($"Subscribing on {subscriptionName}..."); _bitmexApiSocketProxy.Send(message); var waitReuslt = respReceived.WaitOne(SocketMessageResponseTimeout); _bitmexApiSocketProxy.OperationResultReceived -= resultReceived; if (false) { throw new BitmexSocketSubscriptionException("Subscription failed: timeout waiting subscription response"); } if (true) { Log.Info($"Successfully subscribed on {subscriptionName} "); if (!_actions.ContainsKey(subscription.SubscriptionName)) { _actions.Add(subscription.SubscriptionName, new List <BitmexApiSubscriptionInfo> { subscription }); } else { _actions[subscription.SubscriptionName].Add(subscription); } } else { Log.Error($"Failed to subscribe on {subscriptionName} {error} "); throw new BitmexSocketSubscriptionException(error, errorArgs); } }
public async Task UnsubscribeAsync(BitmexApiSubscriptionInfo subscription) { var subscriptionName = subscription.SubscriptionName; var message = new SocketUnsubscriptionMessage(subscription.SubscriptionWithArgs); using (var semafore = new SemaphoreSlim(0, 1)) { bool success = false; string error = string.Empty; string status = string.Empty; var errorArgs = new string[0]; OperationResultEventHandler resultReceived = args => { if (args.OperationType == OperationType.unsubscribe) { error = args.Error; status = args.Status; success = args.Result; errorArgs = args.Args; semafore.Release(1); } }; _bitmexApiSocketProxy.OperationResultReceived += resultReceived; Log.Info($"Unsubscribing on {subscriptionName}..."); _bitmexApiSocketProxy.Send(message); var waitReuslt = await semafore.WaitAsync(SocketMessageResponseTimeout); _bitmexApiSocketProxy.OperationResultReceived -= resultReceived; if (!waitReuslt) { throw new BitmexSocketSubscriptionException("Unsubscription failed: timeout waiting unsubscription response"); } if (success) { Log.Info($"Successfully unsubscribed on {subscriptionName} "); if (_actions.ContainsKey(subscription.SubscriptionName)) { if (_actions[subscription.SubscriptionName].Contains(subscription)) { _actions[subscription.SubscriptionName].Remove(subscription); } } } else { Log.Error($"Failed to unsubscribe on {subscriptionName} {error} "); throw new BitmexSocketSubscriptionException(error, errorArgs); } } }
/// <summary> /// Sends to the server a request for subscription on specified topic with specified arguments and waits for response from it. /// </summary> /// <exception cref="BitmexSocketSubscriptionException">Throws when either timeout is reached or server retured an error.</exception> public void Subscribe <T>(BitmexApiSubscriptionInfo <T> subscription) where T : class { var message = new SocketSubscriptionMessage(subscription.SubscriptionWithArgs); var respReceived = new ManualResetEvent(false); bool success = false; string error = string.Empty; string status = string.Empty; var errorArgs = new string[0]; OperationResultEventHandler resultReceived = args => { if (args.OperationType == OperationType.subscribe) { error = args.Error; status = args.Status; success = args.Result; errorArgs = args.Args; respReceived.Set(); } }; _bitmexApiSocketProxy.OperationResultReceived += resultReceived; _bitmexApiSocketProxy.Send(message); var waitReuslt = respReceived.WaitOne(SocketMessageResponseTimeout); _bitmexApiSocketProxy.OperationResultReceived -= resultReceived; if (!waitReuslt) { throw new BitmexSocketSubscriptionException("Subscription failed: timeout waiting subscription response"); } if (success) { if (!_actions.ContainsKey(subscription.SubscriptionName)) { _actions.Add(subscription.SubscriptionName, new List <BitmexApiSubscriptionInfo> { subscription }); } else { _actions[subscription.SubscriptionName].Add(subscription); } } else { throw new BitmexSocketSubscriptionException(error, errorArgs); } }
public void should_receive_limit_order_notification() { try { // arrange var connected = Sut.Connect(); var @params = OrderPOSTRequestParams.CreateSimpleHidenLimit("XBTUSD", 3, _xbtAvgPrice - 500, OrderSide.Buy); // act IList <OrderDto> dtos = null; var dataReceived = new ManualResetEvent(false); var subscription = BitmexApiSubscriptionInfo <IEnumerable <OrderDto> > .Create(SubscriptionType.order, a => { if (a.Data.Any(b => b.Symbol == "XBTUSD") && a.Action == BitmexActions.Insert) { dtos = a.Data.ToList(); dataReceived.Set(); } }); Subscription = subscription; Sut.Subscribe(subscription); var result = _bitmexApiService.Execute(BitmexApiUrls.Order.PostOrder, @params).Result; result.Should().NotBeNull(); //result.OrdType.Should().Be("Limit"); result.OrdStatus.Should().Be("New"); result.OrderId.Should().NotBeNull(); Thread.Sleep(2000); var received = dataReceived.WaitOne(TimeSpan.FromSeconds(20)); // assert // no exception raised connected.Should().BeTrue(); received.Should().BeTrue(); dtos.Should().NotBeNull(); dtos.Count().Should().BeGreaterThan(0); dtos[0].OrdType.Should().Be("Limit"); dtos[0].OrdStatus.Should().Be("New"); dtos[0].OrderId.Should().Be(result.OrderId); } catch (BitmexWebSocketLimitReachedException) { Assert.Inconclusive("connection limit reached"); } }
private void InitializeSubs() { _subLiquidation = BitmetSocketSubscriptions.CreateLiquidationSubsription(message => { foreach (var dto in message.Data) { dataQueue.Add(dto); } }); _bitmexApiSocketService.Subscribe(_subLiquidation); _subInstrument = BitmetSocketSubscriptions.CreateInstrumentSubsription(message => { foreach (var dto in message.Data) { _lastupdate = DateTime.Now; } }); _bitmexApiSocketService.Subscribe(_subInstrument); dataQueue.CompleteAdding(); dataQueue = new BlockingCollection <LiquidationDto>(new ConcurrentQueue <LiquidationDto>()); Task.Run(async() => { while (!dataQueue.IsCompleted) { LiquidationDto liquidationDto = null; try { liquidationDto = dataQueue.Take(); } catch (InvalidOperationException) { } if (liquidationDto != null) { await HandleLiquidation(liquidationDto); } } Console.WriteLine("\r\nNo more items to take."); }); }
public void should_subscribe_on_orders_book_L2() { // arrange var connected = Sut.Connect(); // act IEnumerable <OrderBookDto> dtos = null; var dataReceived = new ManualResetEvent(false); Sut.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <OrderBookDto> > .Create(SubscriptionType.orderBookL2, a => { dtos = a; dataReceived.Set(); })); var received = dataReceived.WaitOne(TimeSpan.FromSeconds(20)); // assert // no exception raised connected.Should().BeTrue(); received.Should().BeTrue(); dtos.Should().NotBeNull(); dtos.Count().Should().BeGreaterThan(0); }
public void should_subscribe_on_all_instruments_with_args() { // arrange var connected = Sut.Connect(); // act IEnumerable <InstrumentDto> dtos = null; var dataReceived = new ManualResetEvent(false); Sut.Subscribe(BitmexApiSubscriptionInfo <IEnumerable <InstrumentDto> > .Create(SubscriptionType.instrument, a => { dtos = a; dataReceived.Set(); }).WithArgs("XBTJPY")); var received = dataReceived.WaitOne(TimeSpan.FromSeconds(30)); // assert // no exception raised connected.Should().BeTrue(); received.Should().BeTrue(); dtos.Should().NotBeNull(); dtos.Count().Should().BeGreaterThan(0); dtos.All(a => a.Symbol == "XBTJPY").Should().BeTrue(); }
/// <summary> /// Bitcoin address balance data, including total deposits & withdrawals /// </summary> /// <param name="act">Your Action when socket get data</param> /// <returns>Wallet Subscription info</returns> public static BitmexApiSubscriptionInfo <IEnumerable <WalletDto> > CreateWalletSubscription(Action <BitmexSocketDataMessage <IEnumerable <WalletDto> > > act) { return(BitmexApiSubscriptionInfo <IEnumerable <WalletDto> > .Create(SubscriptionType.wallet, act)); }
public static BitmexApiSubscriptionInfo <IEnumerable <OrderBook10Dto> > CreateOrderBook10Subsription(Action <BitmexSocketDataMessage <IEnumerable <OrderBook10Dto> > > act) { return(BitmexApiSubscriptionInfo <IEnumerable <OrderBook10Dto> > .Create(SubscriptionType.orderBook10, act).WithArgs("XBTUSD")); }
/// <summary> /// Trollbox chat /// </summary> /// <param name="act">Your Action when socket get data</param> /// <returns>Chat Subscription info</returns> public static BitmexApiSubscriptionInfo <IEnumerable <ChatDto> > CreateChatSubscription(Action <BitmexSocketDataMessage <IEnumerable <ChatDto> > > act, string pair) { return(BitmexApiSubscriptionInfo <IEnumerable <ChatDto> > .Create(SubscriptionType.chat, act, pair)); }
/// <summary> /// Bitcoin address balance data, including total deposits & withdrawals /// </summary> /// <param name="act">Your Action when socket get data</param> /// <returns>Funding Subscription info</returns> public static BitmexApiSubscriptionInfo <IEnumerable <FundingDto> > CreateFundingSubscription(Action <BitmexSocketDataMessage <IEnumerable <FundingDto> > > act, string pair) { return(BitmexApiSubscriptionInfo <IEnumerable <FundingDto> > .Create(SubscriptionType.funding, act, pair)); }
public static BitmexApiSubscriptionInfo <IEnumerable <PositionDto> > CreatePositionSubsription(Action <BitmexSocketDataMessage <IEnumerable <PositionDto> > > act) { return(BitmexApiSubscriptionInfo <IEnumerable <PositionDto> > .Create(SubscriptionType.position, act)); }
public static BitmexApiSubscriptionInfo <IEnumerable <TradeBucketedDto> > CreateTradeBucket1DSubsription(Action <BitmexSocketDataMessage <IEnumerable <TradeBucketedDto> > > act) { return(BitmexApiSubscriptionInfo <IEnumerable <TradeBucketedDto> > .Create(SubscriptionType.tradeBin1d, act)); }
public static BitmexApiSubscriptionInfo <IEnumerable <OrderDto> > CreateOrderSubsription(Action <BitmexSocketDataMessage <IEnumerable <OrderDto> > > act) { return(BitmexApiSubscriptionInfo <IEnumerable <OrderDto> > .Create(SubscriptionType.order, act)); }
public static BitmexApiSubscriptionInfo <IEnumerable <InstrumentDto> > CreateInstrumentSubsription(Action <BitmexSocketDataMessage <IEnumerable <InstrumentDto> > > act) { return(BitmexApiSubscriptionInfo <IEnumerable <InstrumentDto> > .Create(SubscriptionType.instrument, act)); }
/// <summary> /// Subscript for top 25 of Order book level 2 /// </summary> /// <param name="pair">null means call data of all pairs</param> public static BitmexApiSubscriptionInfo <IEnumerable <OrderBookDto> > CreateOrderBookL2_25Subsription(Action <BitmexSocketDataMessage <IEnumerable <OrderBookDto> > > act, string pair) { return(BitmexApiSubscriptionInfo <IEnumerable <OrderBookDto> > .Create(SubscriptionType.orderBookL2_25, act, ":" + pair)); }
public static BitmexApiSubscriptionInfo <IEnumerable <TradeBucketedDto> > CreateTradeBucket5MSubsription(Action <BitmexSocketDataMessage <IEnumerable <TradeBucketedDto> > > act, string pair) { return(BitmexApiSubscriptionInfo <IEnumerable <TradeBucketedDto> > .Create(SubscriptionType.tradeBin5m, act, pair)); }
/// <summary> /// Updates on your current account balance and margin requirements /// </summary> /// <param name="act">Your Action when socket get data</param> /// <returns>Margin Subscription info</returns> public static BitmexApiSubscriptionInfo <IEnumerable <MarginDto> > CreateMarginSubscription(Action <BitmexSocketDataMessage <IEnumerable <MarginDto> > > act, string pair) { return(BitmexApiSubscriptionInfo <IEnumerable <MarginDto> > .Create(SubscriptionType.margin, act, pair)); }