Exemplo n.º 1
0
        private Tick CreateDerivativeTick(QuoteStreamDefinition tsd, SecurityType derivativeType = SecurityType.Equity)
        {
            Symbol symbol = null;

            //TODO: fix this hackiness
            if (derivativeType == SecurityType.Option)
            {
                symbol = _symbolMapper.OptionNameResolver.FirstOrDefault(x => x.Value == tsd.Symbol).Key;
                if (symbol == null)
                {
                    symbol = _subscriptions.FirstOrDefault(x => x.Key.Value.StartsWith("?") && x.Key.ID.Symbol == tsd.Symbol && x.Key.SecurityType == SecurityType.Option).Key;
                }
            }
            else
            {
                symbol = _subscriptions.FirstOrDefault(x => x.Key.ID.Symbol == tsd.Symbol && x.Key.SecurityType == derivativeType).Key;
            }

            // Not subscribed to this symbol.
            if (symbol == null)
            {
                //Log.Trace("TradeStation.DataQueueHandler.Stream(): Not subscribed to symbol " + tsd.Symbol);
                return(null);
            }
            //this is bad/useless data
            //if (tsd.TradeTime == DateTime.MinValue) return null;
            //TODO: hack fix
            tsd.TradeTime = GetRealTimeTickTime(symbol);

            var tick = new Tick
            {
                Exchange = tsd.Exchange,
                TickType = symbol.ID.SecurityType == SecurityType.Option ? TickType.Quote : TickType.Trade,
                Quantity = (int)tsd.Volume,
                Time     = tsd.TradeTime,
                EndTime  = tsd.TradeTime,
                Symbol   = symbol,
                //DataType = MarketDataType.Tick,
                Suspicious = false,
                Value      = (decimal)tsd.Last,
                AskPrice   = (decimal)tsd.Ask,
                AskSize    = (decimal)tsd.AskSize,
                BidPrice   = (decimal)tsd.Bid,
                BidSize    = (decimal)tsd.BidSize
            };

            /*
             * if (tick.TickType == TickType.Quote)
             * {
             *  Console.WriteLine("got option quote: {0}\t= {1}, {2}", tick.Symbol.ToString(), tick.Value, tick.Time);
             * }
             */

            return(tick);
        }
Exemplo n.º 2
0
 private void mergeQuote(QuoteStreamDefinition source, QuoteStreamDefinition target)
 {
     //we only care about the things needed to create a valid 'Tick' object
     target.Exchange  = target.Exchange != null       ? target.Exchange : source.Exchange;
     target.Volume    = target.Volume != null           ? target.Volume : 0;
     target.TradeTime = target.TradeTime > DateTime.MinValue ? target.TradeTime : source.TradeTime;
     target.Last      = target.Last != null                       ? target.Last : source.Last;
     target.Ask       = target.Ask != null                         ? target.Ask : source.Ask;
     target.AskSize   = target.AskSize != null         ? target.AskSize : source.AskSize;
     target.Bid       = target.Bid != null                         ? target.Bid : source.Bid;
     target.BidSize   = target.BidSize != null         ? target.BidSize : source.BidSize;
 }
Exemplo n.º 3
0
        /// <summary>
        /// Connect to tradier API strea:
        /// </summary>
        /// <param name="symbols">symbol list</param>
        /// <returns></returns>

        private IEnumerable <QuoteStreamDefinition> Stream()
        {
            if (_tradestationStream != null)
            {
                //only 1 is allowed at a time
                _tradestationStream.Close();
            }

            //Tradestation will send a full quote first, then only changes. We need to keep track of the full one,
            // and merge in the changed one.
            var activeQuotes = new Dictionary <string, QuoteStreamDefinition>();
            //Gather together all the symbols we want to subscribe to
            var symbols = new HashSet <string>();

            foreach (var sub in _subscriptions)
            {
                if (sub.Key.Value.StartsWith("?"))
                {
                    //resolve derivative
                    symbols.Add(sub.Key.ID.Symbol);
                }
                else if (sub.Key.SecurityType == SecurityType.Option)
                {
                    if (_symbolMapper.OptionNameResolver.ContainsKey(sub.Key))
                    {
                        symbols.Add(_symbolMapper.OptionNameResolver[sub.Key]);
                    }
                    else
                    {
                        Log.Error("No option symbol was resolved for " + sub.Key.Value);
                    }
                }
                else
                {
                    symbols.Add(sub.Value);
                }
            }
            var symbolJoined = String.Join(",", symbols);

            Log.Trace("TradeStation.Stream(): Creating new session, Reading Stream... (" + symbols.Count + " tickers)", true);
            HttpWebRequest request;

            request         = (HttpWebRequest)WebRequest.Create(String.Format("{0}/stream/quote/changes/{1}?access_token={2}", _tradeStationClient.BaseUrl, symbolJoined, _accessToken));
            request.Timeout = 30 * 1000;
            request.Accept  = "application/vnd.tradestation.streams+json";

            //Get response as a stream:
            try
            {
                var response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    Log.Trace("TradeStation.DataQueueHandler.Stream(): Bad request status " + response.StatusCode + "! Disconnecting from stream...");
                    _isConnected = false;
                    yield break;
                }
                _tradestationStream = response.GetResponseStream();
                if (_tradestationStream == null)
                {
                    Log.Error("TradeStation.DataQueueHandler.Stream(): Null stream error!");
                    yield break;
                }
            }
            catch (Exception ex)
            {
                Log.Error("TradeStation.DataQueueHandler.Stream(): Error establishing connection: " + ex.Message);
                yield break;
            }

            using (_tradestationStream)
                using (var sr = new StreamReader(_tradestationStream))
                    using (var jsonReader = new JsonTextReader(sr))
                    {
                        jsonReader.SupportMultipleContent = true;

                        // keep going until stream gets closed
                        while (!_refresh)
                        {
                            JToken token = null;

                            try
                            {
                                if (!_tradestationStream.CanRead)
                                {
                                    yield break;                     //stream closed down, exit normally
                                }
                                //Read the jsonSocket in a safe manner: might close and so need handlers, but can't put handlers around a yield.
                                jsonReader.Read();
                                if (jsonReader.TokenType != JsonToken.StartObject)
                                {
                                    Log.Debug("TradeStation.DataQueueHandler.Stream(): token parse error");
                                    continue; //bad json or we're parsing in the wrong place somehow, just move along...
                                }

                                token = JToken.Load(jsonReader);
                            }
                            catch (Exception err)
                            {
                                Log.Trace("TradeStation.DataQueueHandler.Stream(): Stream read error: " + err.Message);
                            }

                            if (token == null)
                            {
                                // if we couldn't get a successful read, abort this session
                                yield break;
                            }

                            //after the first read, we set a high timeout on the socket, the server can keep it open as long as it wants.
                            //... but if nothing comes in for a few minutes, might as well restart the stream.
                            _tradestationStream.ReadTimeout = 3 * 60 * 1000; //3mins

                            //now deserialize it for processing

                            /*
                             * Anonymous3 z = null;
                             * try
                             * {
                             *      z = token.ToObject<Anonymous3>();
                             * if (z!=null)
                             * {
                             * Log.Trace("got snapshot from stream");
                             * }
                             * }
                             * catch (Exception err)
                             * {
                             * // Do nothing for now. Can come back later to fix. Errors are from Tradier not properly json encoding values E.g. "NaN" string.
                             * Log.Trace("TradeStation.DataQueueHandler.Stream(): z json deserialization error: " + err.Message);
                             * }
                             */

                            QuoteStreamDefinition tsd = null;
                            try
                            {
                                tsd = token.ToObject <QuoteStreamDefinition>();
                                if (tsd != null)
                                {
                                    Log.Debug("TradeStation.DataQueueHandler.Stream(): got quote: " + token.ToString());
                                }
                            }
                            catch (Exception err)
                            {
                                // Do nothing for now. Can come back later to fix. Errors are from Tradier not properly json encoding values E.g. "NaN" string.
                                Log.Error("TradeStation.DataQueueHandler.Stream(): json deserialization error: " + err.Message);
                            }

                            // don't yield garbage, just wait for the next one
                            if (tsd != null)
                            {
                                if (!activeQuotes.ContainsKey(tsd.Symbol))
                                {
                                    activeQuotes[tsd.Symbol] = tsd;
                                }
                                else
                                {
                                    mergeQuote(activeQuotes[tsd.Symbol], tsd);
                                }
                                yield return(tsd);
                            }

                            //no need to rail the cpu doing this
                            Thread.Sleep(10);
                        }
                    }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Create a tick from the tradier stream data:
 /// </summary>
 /// <param name="tsd">Tradier stream data obejct</param>
 /// <returns>LEAN Tick object</returns>
 private Tick CreateTick(QuoteStreamDefinition tsd)
 {
     return(CreateDerivativeTick(tsd, SecurityType.Equity));
 }