Example #1
0
        public HistoricalExecutionSource(BitFlyerClient client, BfProductCode productCode, long before, long after, long readCount = ReadCountMax)
        {
            readCount = Math.Min(readCount, ReadCountMax);
            _source   = Observable.Create <IBfExecution>(observer => {
                return(Task.Run(async() =>
                {
                    while (true)
                    {
                        var resp = client.GetExecutions(productCode, ReadCountMax, before, 0);
                        if (resp.IsError)
                        {
                            switch (resp.StatusCode)
                            {
                            case HttpStatusCode.BadRequest:     // no more records
                                observer.OnCompleted();
                                return;

                            case HttpStatusCode.InternalServerError:
                                await Task.Delay(30 * 1000);     // Probably server is in maintanace. wait 30 secs
                                break;
                            }
                            continue;
                        }

                        var elements = resp.GetContent();
                        foreach (var element in elements)
                        {
                            if (_cancel.IsCancellationRequested)
                            {
                                observer.OnCompleted();
                                return;
                            }
                            if (element.ExecutionId <= after)
                            {
                                observer.OnCompleted();
                                return;
                            }
                            observer.OnNext(element);
                        }
                        before = elements.Last().ExecutionId;
                    }
                }));
            });
        }
        public static async Task <IEnumerable <(BfProductCode ProductCode, string Symbol)> > GetAvailableMarketsAsync(this BitFlyerClient client, CancellationToken ct)
        {
            var result = new List <(BfProductCode ProductCode, string Symbol)>();

            foreach (var task in client.GetMarketsAllAsync(ct))
            {
                var markets = (await task).GetContent();
                foreach (var market in markets)
                {
                    if (market.ProductCode.StartsWith("BTCJPY"))
                    {
                        if (string.IsNullOrEmpty(market.Alias))
                        {
                            continue; // ******** BTCJPY future somtimes missing alias, skip it ********
                        }
                        result.Add(((BfProductCode)Enum.Parse(typeof(BfProductCode), market.Alias.Replace("_", "")), market.ProductCode));
                    }
                    else
                    {
                        result.Add(((BfProductCode)Enum.Parse(typeof(BfProductCode), market.ProductCode.Replace("_", "")), market.ProductCode));
                    }
                }
            }
            return(result.Distinct(e => e.ProductCode));
        }
        public static IEnumerable <(BfProductCode ProductCode, string Symbol)> GetAvailableMarkets(this BitFlyerClient client)
        {
            var result = new List <(BfProductCode ProductCode, string Symbol)>();

            foreach (var market in client.GetMarketsAll().SelectMany(e => e.GetContent()))
            {
                if (market.ProductCode.StartsWith("BTCJPY"))
                {
                    if (string.IsNullOrEmpty(market.Alias))
                    {
                        continue; // ******** BTCJPY future somtimes missing alias, skip it ********
                    }
                    result.Add(((BfProductCode)Enum.Parse(typeof(BfProductCode), market.Alias.Replace("_", "")), market.ProductCode));
                }
                else
                {
                    result.Add(((BfProductCode)Enum.Parse(typeof(BfProductCode), market.ProductCode.Replace("_", "")), market.ProductCode));
                }
            }
            return(result.Distinct(e => e.ProductCode));
        }
Example #4
0
        public RealtimeSourceFactory(BitFlyerClient client = null)
        {
            _client = (client == null) ? new BitFlyerClient().AddTo(_disposables) : client;
            if (client != null)
            {
                GetAvailableMarkets();
            }

            _webSocket = new WebSocket("wss://ws.lightstream.bitflyer.com/json-rpc");
            _webSocket.Security.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;
            _wsReconnectionTimer = new Timer((_) =>
            {
                _wsReconnectionTimer.Change(Timeout.Infinite, Timeout.Infinite); // stop
                Debug.WriteLine("{0} WebSocket is reopening connection... state={1}", DateTime.Now, _webSocket.State);
                switch (_webSocket.State)
                {
                case WebSocketState.None:
                case WebSocketState.Closed:
                    try
                    {
                        _webSocket.Open();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                        _wsReconnectionTimer.Change(WebSocketReconnectionIntervalMs, Timeout.Infinite);     // restart
                    }
                    break;

                case WebSocketState.Open:
                    Debug.WriteLine("{0} Web socket is still opened.", DateTime.Now);
                    break;

                default:
                    _wsReconnectionTimer.Change(WebSocketReconnectionIntervalMs, Timeout.Infinite);     // restart
                    break;
                }
            });

            _openedEvent.Reset();
            _webSocket.Opened += (_, __) =>
            {
                Debug.WriteLine("{0} WebSocket opened.", DateTime.Now);
                _wsReconnectionTimer.Change(Timeout.Infinite, Timeout.Infinite); // stop
                if (_webSocketSources.Count > 0)
                {
                    Debug.WriteLine("{0} WebSocket recover subscriptions.", DateTime.Now);
                    _webSocketSources.Values.ForEach(source => { source.Subscribe(); }); // resubscribe
                }
                OnWebSocketOpened();
                _openedEvent.Set();
            };

            _webSocket.MessageReceived += (_, e) =>
            {
                var subscriptionResult = JObject.Parse(e.Message)["params"];
                var channel            = subscriptionResult["channel"].Value <string>();
                _webSocketSources[channel].OnSubscribe(subscriptionResult["message"]);
            };

            _webSocket.Error += (_, e) =>
            {
                // Classifies expected or unexpexted
                var error = new ErrorStatus();
                switch (e.Exception)
                {
                case IOException ioex:
                    error.Message = (ioex.InnerException != null) ? ioex.InnerException.Message : ioex.Message;
                    break;

                case SocketException sockex:
                    Debug.WriteLine("{0} WebSocket socket error({1})", DateTime.Now, sockex.SocketErrorCode);
                    Debug.WriteLine("{0} WebSocket caused exception. Will be closed.", DateTime.Now, sockex.Message);
                    error.SocketError = sockex.SocketErrorCode;
                    error.Message     = sockex.Message;
                    break;

                default:
                    switch ((uint)e.Exception.HResult)
                    {
                    case 0x80131500:         // Bad gateway - probably terminated from host
                        error.Message = e.Exception.Message;
                        break;

                    default:         // Unexpected exception
                        throw e.Exception;
                    }
                    break;
                }
                ErrorHandlers?.Invoke(error);
            };

            _webSocket.Closed += (_, __) =>
            {
                Debug.WriteLine("{0} WebSocket connection closed. Will be reopening...", DateTime.Now);
                _wsReconnectionTimer.Change(WebSocketReconnectionIntervalMs, Timeout.Infinite);
            };
        }