예제 #1
0
        public IEXDataQueueHandler(bool live)
        {
            _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl += (s, t) =>
            {
                Subscribe(s);
                return(true);
            };

            _subscriptionManager.UnsubscribeImpl += (s, t) =>
            {
                Unsubscribe(s);
                return(true);
            };

            Endpoint = "https://ws-api.iextrading.com/1.0/tops";

            if (string.IsNullOrWhiteSpace(_apiKey))
            {
                Log.Trace("IEXDataQueueHandler(): The IEX API key was not provided, history calls will return no data.");
            }

            if (live)
            {
                Reconnect();
            }
        }
예제 #2
0
        /// <summary>
        /// Initialize the instance of this class
        /// </summary>
        /// <param name="wssUrl">The web socket base url</param>
        /// <param name="websocket">instance of websockets client</param>
        /// <param name="restClient">instance of rest client</param>
        /// <param name="apiKey">api key</param>
        /// <param name="apiSecret">api secret</param>
        /// <param name="passPhrase">pass phrase</param>
        /// <param name="algorithm">the algorithm instance is required to retrieve account type</param>
        /// <param name="priceProvider">The price provider for missing FX conversion rates</param>
        /// <param name="aggregator">the aggregator for consolidating ticks</param>
        /// <param name="job">The live job packet</param>
        protected void Initialize(string wssUrl, IWebSocket websocket, IRestClient restClient, string apiKey, string apiSecret,
                                  string passPhrase, IAlgorithm algorithm, IPriceProvider priceProvider, IDataAggregator aggregator, LiveNodePacket job)
        {
            if (IsInitialized)
            {
                return;
            }
            base.Initialize(wssUrl, websocket, restClient, apiKey, apiSecret);
            _job           = job;
            FillSplit      = new ConcurrentDictionary <long, GDAXFill>();
            _passPhrase    = passPhrase;
            _algorithm     = algorithm;
            _priceProvider = priceProvider;
            _aggregator    = aggregator;

            _isDataQueueHandler = this is GDAXDataQueueHandler;

            _fillMonitorTask = Task.Factory.StartNew(FillMonitorAction, _ctsFillMonitor.Token);

            var subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();

            subscriptionManager.SubscribeImpl += (s, t) =>
            {
                Subscribe(s);
                return(true);
            };
            subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);

            SubscriptionManager = subscriptionManager;
        }
예제 #3
0
        /// <summary>
        /// Constructor for brokerage
        /// </summary>
        /// <param name="apiKey">api key</param>
        /// <param name="apiSecret">api secret</param>
        /// <param name="algorithm">the algorithm instance is required to retrieve account type</param>
        /// <param name="aggregator">the aggregator for consolidating ticks</param>
        /// <param name="job">The live job packet</param>
        public BinanceBrokerage(string apiKey, string apiSecret, IAlgorithm algorithm, IDataAggregator aggregator, LiveNodePacket job)
            : base(WebSocketBaseUrl, new WebSocketClientWrapper(), null, apiKey, apiSecret, "Binance")
        {
            _job            = job;
            _algorithm      = algorithm;
            _aggregator     = aggregator;
            _messageHandler = new BrokerageConcurrentMessageHandler <WebSocketMessage>(OnMessageImpl);

            var subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();

            subscriptionManager.SubscribeImpl += (s, t) =>
            {
                Subscribe(s);
                return(true);
            };
            subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);

            SubscriptionManager = subscriptionManager;

            _apiClient = new BinanceRestApiClient(
                _symbolMapper,
                algorithm?.Portfolio,
                apiKey,
                apiSecret);

            _apiClient.OrderSubmit        += (s, e) => OnOrderSubmit(e);
            _apiClient.OrderStatusChanged += (s, e) => OnOrderEvent(e);
            _apiClient.Message            += (s, e) => OnMessage(e);

            // User data streams will close after 60 minutes. It's recommended to send a ping about every 30 minutes.
            // Source: https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md#pingkeep-alive-a-listenkey
            _keepAliveTimer = new Timer
            {
                // 30 minutes
                Interval = 30 * 60 * 1000
            };
            _keepAliveTimer.Elapsed += (s, e) => _apiClient.SessionKeepAlive();

            WebSocket.Open   += (s, e) => { _keepAliveTimer.Start(); };
            WebSocket.Closed += (s, e) => { _keepAliveTimer.Stop(); };

            // A single connection to stream.binance.com is only valid for 24 hours; expect to be disconnected at the 24 hour mark
            // Source: https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#general-wss-information
            _reconnectTimer = new Timer
            {
                // 23.5 hours
                Interval = 23.5 * 60 * 60 * 1000
            };
            _reconnectTimer.Elapsed += (s, e) =>
            {
                Log.Trace("Daily websocket restart: disconnect");
                Disconnect();

                Log.Trace("Daily websocket restart: connect");
                Connect();
            };
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CoinApiDataQueueHandler"/> class
 /// </summary>
 public CoinApiDataQueueHandler()
 {
     _client              = new CoinApiWsClient();
     _client.TradeEvent  += OnTrade;
     _client.QuoteEvent  += OnQuote;
     _client.Error       += OnError;
     _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
     _subscriptionManager.SubscribeImpl   += (s, t) => Subscribe(s);
     _subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);
 }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OandaRestApiBase"/> class.
        /// </summary>
        /// <param name="symbolMapper">The symbol mapper.</param>
        /// <param name="orderProvider">The order provider.</param>
        /// <param name="securityProvider">The holdings provider.</param>
        /// <param name="aggregator">Consolidate ticks</param>
        /// <param name="environment">The Oanda environment (Trade or Practice)</param>
        /// <param name="accessToken">The Oanda access token (can be the user's personal access token or the access token obtained with OAuth by QC on behalf of the user)</param>
        /// <param name="accountId">The account identifier.</param>
        /// <param name="agent">The Oanda agent string</param>
        protected OandaRestApiBase(OandaSymbolMapper symbolMapper, IOrderProvider orderProvider, ISecurityProvider securityProvider, IDataAggregator aggregator, Environment environment, string accessToken, string accountId, string agent)
            : base("Oanda Brokerage")
        {
            SymbolMapper         = symbolMapper;
            OrderProvider        = orderProvider;
            SecurityProvider     = securityProvider;
            Environment          = environment;
            AccessToken          = accessToken;
            AccountId            = accountId;
            Agent                = agent;
            Aggregator           = aggregator;
            _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl   += (s, t) => Refresh();
            _subscriptionManager.UnsubscribeImpl += (s, t) => Refresh();

            PricingConnectionHandler = new DefaultConnectionHandler {
                MaximumIdleTimeSpan = TimeSpan.FromSeconds(20)
            };
            PricingConnectionHandler.ConnectionLost     += OnPricingConnectionLost;
            PricingConnectionHandler.ConnectionRestored += OnPricingConnectionRestored;
            PricingConnectionHandler.ReconnectRequested += OnPricingReconnectRequested;
            PricingConnectionHandler.Initialize(null);

            TransactionsConnectionHandler = new DefaultConnectionHandler {
                MaximumIdleTimeSpan = TimeSpan.FromSeconds(20)
            };
            TransactionsConnectionHandler.ConnectionLost     += OnTransactionsConnectionLost;
            TransactionsConnectionHandler.ConnectionRestored += OnTransactionsConnectionRestored;
            TransactionsConnectionHandler.ReconnectRequested += OnTransactionsReconnectRequested;
            TransactionsConnectionHandler.Initialize(null);

            Task.Factory.StartNew(
                () =>
            {
                do
                {
                    _refreshEvent.WaitOne();
                    Thread.Sleep(SubscribeDelay);

                    if (!_isConnected)
                    {
                        continue;
                    }

                    _refreshEvent.Reset();

                    var symbolsToSubscribe = SubscribedSymbols;
                    // restart streaming session
                    SubscribeSymbols(symbolsToSubscribe);
                } while (!_streamingCancellationTokenSource.IsCancellationRequested);
            },
                TaskCreationOptions.LongRunning
                );
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GDAXDataQueueHandler"/> class
        /// </summary>
        public GDAXDataQueueHandler(string wssUrl, IWebSocket websocket, IRestClient restClient, string apiKey, string apiSecret, string passPhrase, IAlgorithm algorithm,
                                    IPriceProvider priceProvider, IDataAggregator aggregator)
            : base(wssUrl, websocket, restClient, apiKey, apiSecret, passPhrase, algorithm, priceProvider, aggregator)
        {
            var subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();

            subscriptionManager.SubscribeImpl += (s, t) =>
            {
                Subscribe(s);
                return(true);
            };
            subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);

            SubscriptionManager = subscriptionManager;
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FakeDataQueue"/> class to randomly emit data for each symbol
        /// </summary>
        public FakeDataQueue(IDataAggregator dataAggregator)
        {
            _aggregator        = dataAggregator;
            _dataCacheProvider = new ZipDataCacheProvider(new DefaultDataProvider(), true);
            var mapFileProvider = Composer.Instance.GetExportedValueByTypeName <IMapFileProvider>(Config.Get("map-file-provider", "LocalDiskMapFileProvider"), false);

            _optionChainProvider                  = new LiveOptionChainProvider(_dataCacheProvider, mapFileProvider);
            _marketHoursDatabase                  = MarketHoursDatabase.FromDataFolder();
            _symbolExchangeTimeZones              = new Dictionary <Symbol, TimeZoneOffsetProvider>();
            _subscriptionManager                  = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl   += (s, t) => true;
            _subscriptionManager.UnsubscribeImpl += (s, t) => true;

            // load it up to start
            PopulateQueue();
            PopulateQueue();
            PopulateQueue();
            PopulateQueue();

            _timer = new Timer
            {
                AutoReset = false,
                Enabled   = true,
                Interval  = 1000,
            };

            var lastCount = 0;
            var lastTime  = DateTime.UtcNow;

            _timer.Elapsed += (sender, args) =>
            {
                var elapsed        = (DateTime.UtcNow - lastTime);
                var ticksPerSecond = (_count - lastCount) / elapsed.TotalSeconds;
                Log.Trace("TICKS PER SECOND:: " + ticksPerSecond.ToStringInvariant("000000.0") + " ITEMS IN QUEUE:: " + 0);
                lastCount = _count;
                lastTime  = DateTime.UtcNow;
                PopulateQueue();
                try
                {
                    _timer.Reset();
                }
                catch (ObjectDisposedException)
                {
                    // pass
                }
            };
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PolygonDataQueueHandler"/> class
        /// </summary>
        public PolygonDataQueueHandler(bool streamingEnabled)
        {
            if (streamingEnabled)
            {
                foreach (var securityType in new[] { SecurityType.Equity, SecurityType.Forex, SecurityType.Crypto })
                {
                    var client = new PolygonWebSocketClientWrapper(_apiKey, _symbolMapper, securityType, OnMessage);
                    _webSocketClientWrappers.Add(securityType, client);
                }
            }

            var subscriber = new EventBasedDataQueueHandlerSubscriptionManager(t => t.ToString());

            subscriber.SubscribeImpl   += Subscribe;
            subscriber.UnsubscribeImpl += Unsubscribe;

            _subscriptionManager = subscriber;
        }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CoinApiDataQueueHandler"/> class
        /// </summary>
        public CoinApiDataQueueHandler()
        {
            var product = Config.GetValue <CoinApiProduct>("coinapi-product");

            _streamingDataType = product < CoinApiProduct.Streamer
                ? new[] { "trade" }
                : new[] { "trade", "quote" };

            Log.Trace($"CoinApiDataQueueHandler(): using plan '{product}'. Available data types: '{string.Join(",", _streamingDataType)}'");

            _client              = new CoinApiWsClient();
            _client.TradeEvent  += OnTrade;
            _client.QuoteEvent  += OnQuote;
            _client.Error       += OnError;
            _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl   += (s, t) => Subscribe(s);
            _subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);
        }
예제 #10
0
        /// <summary>
        /// Creates a new instance of the <see cref="FxcmBrokerage"/> class
        /// </summary>
        /// <param name="orderProvider">The order provider</param>
        /// <param name="securityProvider">The holdings provider</param>
        /// <param name="aggregator">Consolidate ticks</param>
        /// <param name="server">The url of the server</param>
        /// <param name="terminal">The terminal name</param>
        /// <param name="userName">The user name (login id)</param>
        /// <param name="password">The user password</param>
        /// <param name="accountId">The account id</param>
        public FxcmBrokerage(IOrderProvider orderProvider, ISecurityProvider securityProvider, IDataAggregator aggregator, string server, string terminal, string userName, string password, string accountId)
            : base("FXCM Brokerage")
        {
            _orderProvider    = orderProvider;
            _securityProvider = securityProvider;
            _aggregator       = aggregator;
            _server           = server;
            _terminal         = terminal;
            _userName         = userName;
            _password         = password;
            _accountId        = accountId;

            _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl   += (s, t) => Subscribe(s);
            _subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);

            HistoryResponseTimeout      = 5000;
            MaximumHistoryRetryAttempts = 1;
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FakeDataQueue"/> class to randomly emit data for each symbol
        /// </summary>
        public FakeDataQueue(IDataAggregator dataAggregator)
        {
            _aggregator                           = dataAggregator;
            _marketHoursDatabase                  = MarketHoursDatabase.FromDataFolder();
            _symbolExchangeTimeZones              = new Dictionary <Symbol, TimeZoneOffsetProvider>();
            _subscriptionManager                  = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl   += (s, t) => true;
            _subscriptionManager.UnsubscribeImpl += (s, t) => true;

            // load it up to start
            PopulateQueue();
            PopulateQueue();
            PopulateQueue();
            PopulateQueue();

            _timer = new Timer
            {
                AutoReset = false,
                Enabled   = true,
                Interval  = 1000,
            };

            var lastCount = 0;
            var lastTime  = DateTime.UtcNow;

            _timer.Elapsed += (sender, args) =>
            {
                var elapsed        = (DateTime.UtcNow - lastTime);
                var ticksPerSecond = (_count - lastCount) / elapsed.TotalSeconds;
                Log.Trace("TICKS PER SECOND:: " + ticksPerSecond.ToStringInvariant("000000.0") + " ITEMS IN QUEUE:: " + 0);
                lastCount = _count;
                lastTime  = DateTime.UtcNow;
                PopulateQueue();
                try
                {
                    _timer.Reset();
                }
                catch (ObjectDisposedException)
                {
                    // pass
                }
            };
        }
예제 #12
0
        /// <summary>
        /// IQFeedDataQueueHandler is an implementation of IDataQueueHandler:
        /// </summary>
        public IQFeedDataQueueHandler()
        {
            _symbols             = new HashSet <Symbol>();
            _underlyings         = new Dictionary <Symbol, Symbol>();
            _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl += (s, t) =>
            {
                Subscribe(s);
                return(true);
            };

            _subscriptionManager.UnsubscribeImpl += (s, t) =>
            {
                Unsubscribe(s);
                return(true);
            };

            if (!IsConnected)
            {
                Connect();
            }
        }
예제 #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CoinApiDataQueueHandler"/> class
        /// </summary>
        public CoinApiDataQueueHandler()
        {
            _dataAggregator = Composer.Instance.GetPart <IDataAggregator>();
            if (_dataAggregator == null)
            {
                _dataAggregator =
                    Composer.Instance.GetExportedValueByTypeName <IDataAggregator>(Config.Get("data-aggregator", "QuantConnect.Lean.Engine.DataFeeds.AggregationManager"));
            }
            var product = Config.GetValue <CoinApiProduct>("coinapi-product");

            _streamingDataType = product < CoinApiProduct.Streamer
                ? new[] { "trade" }
                : new[] { "trade", "quote" };

            Log.Trace($"CoinApiDataQueueHandler(): using plan '{product}'. Available data types: '{string.Join(",", _streamingDataType)}'");

            _client              = new CoinApiWsClient();
            _client.TradeEvent  += OnTrade;
            _client.QuoteEvent  += OnQuote;
            _client.Error       += OnError;
            _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();
            _subscriptionManager.SubscribeImpl   += (s, t) => Subscribe(s);
            _subscriptionManager.UnsubscribeImpl += (s, t) => Unsubscribe(s);
        }
예제 #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="IEXDataQueueHandler"/> class.
        /// </summary>
        public IEXDataQueueHandler()
        {
            _subscriptionManager = new EventBasedDataQueueHandlerSubscriptionManager();

            _subscriptionManager.SubscribeImpl += (symbols, t) =>
            {
                symbols.DoForEach(symbol =>
                {
                    if (!_symbols.TryAdd(symbol.Value, symbol))
                    {
                        throw new InvalidOperationException($"Invalid logic, SubscriptionManager tried to subscribe to existing symbol : {symbol.Value}");
                    }
                });

                Refresh();
                return(true);
            };

            _subscriptionManager.UnsubscribeImpl += (symbols, t) =>
            {
                symbols.DoForEach(symbol =>
                {
                    Symbol tmp;
                    _symbols.TryRemove(symbol.Value, out tmp);
                });

                Refresh();
                return(true);
            };

            if (string.IsNullOrWhiteSpace(_apiKey))
            {
                throw new ArgumentException("Could not read IEX API key from config.json. " +
                                            "Please make sure to add \"iex-cloud-api-key\" to your configuration file");
            }

            // Set the sse-clients collection
            _clients = new IEXEventSourceCollection(((o, args) =>
            {
                var message = args.Message.Data;
                ProcessJsonObject(message);
            }), _apiKey);

            // In this thread, we check at each interval whether the client needs to be updated
            // Subscription renewal requests may come in dozens and all at relatively same time - we cannot update them one by one when work with SSE
            var clientUpdateThread = new Thread(() =>
            {
                while (!_cts.Token.IsCancellationRequested)
                {
                    _refreshEvent.WaitOne();
                    Thread.Sleep(SubscribeDelay);

                    _refreshEvent.Reset();

                    try
                    {
                        _clients.UpdateSubscription(_symbols.Keys.ToArray());
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                        throw;
                    }
                }
            })
            {
                IsBackground = true
            };

            clientUpdateThread.Start();
        }