PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Bitstamp/BitstampClient.Pusher.cs

https://gitlab.com/prog76.trade/Bitstamp
C# | 116 lines | 95 code | 18 blank | 3 comment | 0 complexity | ac12aac26b960619827750b35b2a43be MD5 | raw file
  1. using Bitstamp.Models;
  2. using Newtonsoft.Json;
  3. using Newtonsoft.Json.Linq;
  4. using PusherClient;
  5. using System;
  6. using System.Collections.Concurrent;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Reactive.Concurrency;
  10. using System.Reactive.Disposables;
  11. using System.Reactive.Linq;
  12. using System.Reactive.Subjects;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. namespace Bitstamp {
  16. public partial class BitstampClient {
  17. private Pusher _pusher;
  18. private ConcurrentDictionary<Type, object> _messages = new ConcurrentDictionary<Type, object>();
  19. private ISubject<object> _observable = new Subject<object>();
  20. private Subscription _orders = new Subscription();
  21. private Subscription _trades = new Subscription();
  22. private Subscription _depth = new Subscription();
  23. private bool _connected = false;
  24. private object _connectionLock = new object();
  25. private object _connectionTarget;
  26. private Task<bool> ConnectAsync(string applicationkey = "de504dc5763aeef9ff52") {
  27. var tcs = new TaskCompletionSource<bool>();
  28. _pusher = new Pusher(applicationkey);
  29. var connected = (ConnectedEventHandler)null;
  30. _orders.Handler = (sender) => {
  31. _orders.Channel.Subscribed -= _orders.Handler;
  32. //_orders.Channel.Bind("order_deleted", (d) => On(OrderDeleted, (d as JObject).AsOrder()));
  33. //_orders.Channel.Bind("order_created", (d) => On(OrderCreated, (d as JObject).AsOrder()));
  34. //_orders.Channel.Bind("order_changed", (d) => On(OrderChanged, (d as JObject).AsOrder()));
  35. };
  36. _trades.Handler = (sender) => {
  37. _trades.Channel.Subscribed -= _trades.Handler;
  38. _trades.Channel.Bind("trade", (d) => OnNext((d as JObject).AsTrade()));
  39. };
  40. _depth.Handler = (sender) => {
  41. _depth.Channel.Subscribed -= _depth.Handler;
  42. _depth.Channel.Bind("data", (d) => OnNext((d as JObject).AsOrderBook()));
  43. };
  44. _pusher.Connected += connected = (sender) => {
  45. _pusher.Connected -= connected;
  46. tcs.SetResult(true);
  47. };
  48. _pusher.ConnectionStateChanged += (s, e) => {
  49. };
  50. _pusher.Connect();
  51. return tcs.Task;
  52. }
  53. private void OnNext<T>(T value) {
  54. _observable.OnNext(value);
  55. }
  56. private IObservable<T> GetObservable<T>(string channel, Subscription subscription) {
  57. LazyInitializer.EnsureInitialized(ref _connectionTarget, ref _connected, ref _connectionLock, () => {
  58. _connected = ConnectAsync().Result;
  59. return null;
  60. });
  61. return (IObservable<T>)_messages.GetOrAdd(typeof(T), type => {
  62. subscription.Channel = _pusher.Subscribe(channel);
  63. subscription.Channel.Subscribed += subscription.Handler;
  64. return _observable.OfType<T>();
  65. });
  66. }
  67. public IObservable<Trade> GetTradesObservable() {
  68. return (IObservable<Trade>)GetObservable<Trade>("live_trades", _trades);
  69. }
  70. public IObservable<OrderBook> GetOrderBookObservable() {
  71. return (IObservable<OrderBook>)GetObservable<OrderBook>("order_book", _depth);
  72. }
  73. public IObservable<Ticker> GetTickerObservable() {
  74. return (IObservable<Ticker>)_messages.GetOrAdd(typeof(Ticker), type => {
  75. return Observable.Create<Ticker>(observer => {
  76. var ticker = GetTickerAsync().Result;
  77. var observable = Observable.CombineLatest(GetTradesObservable(), GetOrderBookObservable(), (trade, book) => new { Trade = trade, OrderBook = book })
  78. .Subscribe(a => {
  79. var ask = a.OrderBook.Asks[0];
  80. var bid = a.OrderBook.Bids[0];
  81. var value = new Ticker {
  82. Ask = ask.Price,
  83. Bid = bid.Price,
  84. Last = a.Trade.Price,
  85. Volume = ticker.Volume += a.Trade.Amount,
  86. High = Math.Min(ticker.High, a.Trade.Price),
  87. Low = Math.Min(ticker.Low, a.Trade.Price),
  88. };
  89. ticker = value;
  90. observer.OnNext(value);
  91. });
  92. observer.OnNext(ticker);
  93. return observable;
  94. });
  95. });
  96. }
  97. }
  98. }