/// <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(TradierStreamData tsd) { var symbol = _subscriptions.FirstOrDefault(x => x.Value == tsd.Symbol).Key; // Not subscribed to this symbol. if (symbol == null) return null; // Occassionally Tradier sends trades with 0 volume? if (tsd.TradeSize == 0) return null; // Tradier trades are US NY time only. Convert local server time to NY Time: var unix = tsd.UnixDate.ConvertInvariant<long>() / 1000; var utc = Time.UnixTimeStampToDateTime(unix); // Occassionally Tradier sends old ticks every 20sec-ish if no trading? if (DateTime.UtcNow - utc > TimeSpan.FromSeconds(10)) return null; //Convert the to security timezone and pass into algorithm var time = utc.ConvertTo(DateTimeZone.Utc, TimeZones.NewYork); return new Tick { Exchange = tsd.TradeExchange, TickType = TickType.Trade, Quantity = (int) tsd.TradeSize, Time = time, EndTime = time, Symbol = symbol, DataType = MarketDataType.Tick, Suspicious = false, Value = tsd.TradePrice }; }
/// <summary> /// Create an IEnumerable simulated data stream for "live" testing after hours and weekends. /// </summary> /// <param name="symbols">Symbols to return the simulated stream</param> /// <returns>Tradier data:</returns> public IEnumerable <TradierStreamData> SimulatedStream(List <string> symbols) { //Initialize: var rand = new Random((int)DateTime.Now.TimeOfDay.TotalMilliseconds); var prices = new Dictionary <string, decimal>(); if (symbols.Count == 0) { yield break; } //Setup prices: always sends a bunch of last trades. foreach (var symbol in symbols) { //Random starting price from $5 - $100 prices.Add(symbol, ((decimal)rand.Next(500, 10000)) / 100m); var data = new TradierStreamData(); //Set back to the Tradier Object: data.Symbol = symbol; data.TradePrice = prices[symbol]; data.TradeSize = rand.Next(10, 1000); data.Type = "trade"; yield return(data); } while (true) { //Initialize var data = new TradierStreamData(); //Randomly pick a symbol: var symbol = symbols[rand.Next(0, symbols.Count - 1)]; //Randomly walk a price change: var price = prices[symbol]; price += (rand.Next(-1, 1)) * price * 0.001m; prices[symbol] = price; //Set back to the Tradier Object: data.Symbol = symbol; data.TradePrice = price; data.TradeSize = rand.Next(10, 1000); data.Type = "trade"; //Randomly pick a delay: Thread.Sleep(rand.Next(200, 700)); yield return(data); } }
/// <summary> /// Create a tick from the tradier stream data /// </summary> /// <param name="tsd">Tradier stream data object</param> /// <returns>LEAN Tick object</returns> private Tick CreateTick(TradierStreamData tsd) { Symbol symbol; if (!_subscribedTickers.TryGetValue(tsd.Symbol, out symbol)) { // Not subscribed to this symbol. return(null); } if (tsd.Type == "trade") { // Occasionally Tradier sends trades with 0 volume? if (tsd.TradeSize == 0) { return(null); } } // Tradier trades are US NY time only. Convert local server time to NY Time: var utc = tsd.GetTickTimestamp(); // Occasionally Tradier sends old ticks every 20sec-ish if no trading? if (DateTime.UtcNow - utc > TimeSpan.FromSeconds(10)) { return(null); } // Convert the timestamp to exchange timezone and pass into algorithm var time = utc.ConvertTo(DateTimeZone.Utc, TimeZones.NewYork); switch (tsd.Type) { case "trade": return(new Tick(time, symbol, "", tsd.TradeExchange, (int)tsd.TradeSize, tsd.TradePrice)); case "quote": return(new Tick(time, symbol, "", "", tsd.BidSize, tsd.BidPrice, tsd.AskSize, tsd.AskPrice)); } return(null); }
/// <summary> /// Connect to tradier API strea: /// </summary> /// <param name="symbols">symbol list</param> /// <returns></returns> public IEnumerable <TradierStreamData> Stream(List <string> symbols) { var stream = new List <TradierStreamData>(); var symbolJoined = String.Join(",", symbols); var success = true; var session = CreateStreamSession(); if (session == null || session.SessionId == null || session.Url == null) { Log.Error("Tradier.Stream(): Failed to Created Stream Session", true); yield break; } Log.Trace("Tradier.Stream(): Created Stream Session Id: " + session.SessionId + " Url:" + session.Url, true); var request = (HttpWebRequest)WebRequest.Create((string)session.Url); do { //Connect to URL: success = true; request = (HttpWebRequest)WebRequest.Create((string)session.Url); //Authenticate a request: request.Accept = "application/json"; request.Headers.Add("Authorization", "Bearer " + _accessToken); //Add the desired data: var postData = "symbols=" + symbolJoined + "&sessionid=" + session.SessionId;; var encodedData = Encoding.ASCII.GetBytes(postData); //Set post: request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = encodedData.Length; //Send request: try { using (var postStream = request.GetRequestStream()) { postStream.Write(encodedData, 0, encodedData.Length); } } catch (Exception err) { Log.Error("Tradier.Stream(): Failed to write session parameters to URL: " + err.Message + " >> ST >>" + err.StackTrace, true); success = false; } }while (!success); //Get response as a stream: Log.Trace("Tradier.Stream(): Session Created, Reading Stream...", true); var response = (HttpWebResponse)request.GetResponse(); var tradierStream = response.GetResponseStream(); using (var sr = new StreamReader(tradierStream)) using (var jsonReader = new JsonTextReader(sr)) { var serializer = new JsonSerializer(); jsonReader.SupportMultipleContent = true; var successfulRead = true; while (successfulRead) { try { //Read the jsonSocket in a safe manner: might close and so need handlers, but can't put handlers around a yield. successfulRead = jsonReader.Read(); } catch (Exception err) { Console.Write(err.Message); successfulRead = false; } if (successfulRead) { //Have a Tradier JSON Object: var tsd = new TradierStreamData(); try { tsd = serializer.Deserialize <TradierStreamData>(jsonReader); } 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. Console.Write(err.Message); } yield return(tsd); } else { //Error in stream or market has closed, neatly exit the stream yield break; } } } }
/// <summary> /// Connect to tradier API strea: /// </summary> /// <param name="symbols">symbol list</param> /// <returns></returns> private IEnumerable <TradierStreamData> Stream(List <string> symbols) { bool success; var symbolJoined = String.Join(",", symbols); var session = CreateStreamSession(); if (session == null || session.SessionId == null || session.Url == null) { Log.Error("Tradier.Stream(): Failed to Created Stream Session", true); yield break; } Log.Trace("Tradier.Stream(): Created Stream Session Id: " + session.SessionId + " Url:" + session.Url, true); HttpWebRequest request; do { //Connect to URL: success = true; request = (HttpWebRequest)WebRequest.Create(session.Url); //Authenticate a request: request.Accept = "application/json"; request.Headers.Add("Authorization", "Bearer " + AccessToken); //Add the desired data: var postData = "symbols=" + symbolJoined + "&filter=trade&sessionid=" + session.SessionId; var encodedData = Encoding.ASCII.GetBytes(postData); //Set post: request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = encodedData.Length; //Send request: try { using (var postStream = request.GetRequestStream()) { postStream.Write(encodedData, 0, encodedData.Length); } } catch (Exception err) { Log.Error(err, "Failed to write session parameters to URL", true); success = false; } }while (!success); //Get response as a stream: Log.Trace("Tradier.Stream(): Session Created, Reading Stream...", true); var response = (HttpWebResponse)request.GetResponse(); _tradierStream = response.GetResponseStream(); if (_tradierStream == null) { yield break; } using (var sr = new StreamReader(_tradierStream)) using (var jsonReader = new JsonTextReader(sr)) { var serializer = new JsonSerializer(); jsonReader.SupportMultipleContent = true; // keep going until we fail to read more from the stream while (true) { bool successfulRead; try { //Read the jsonSocket in a safe manner: might close and so need handlers, but can't put handlers around a yield. successfulRead = jsonReader.Read(); } catch (Exception err) { Log.Trace("TradierBrokerage.DataQueueHandler.Stream(): Handled breakout / socket close from jsonRead operation: " + err.Message); break; } if (!successfulRead) { // if we couldn't get a successful read just end the enumerable yield break; } //Have a Tradier JSON Object: TradierStreamData tsd = null; try { tsd = serializer.Deserialize <TradierStreamData>(jsonReader); } 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("TradierBrokerage.DataQueueHandler.Stream(): Handled breakout / socket close from jsonRead operation: " + err.Message); } // don't yield garbage, just wait for the next one if (tsd != null) { yield return(tsd); } } } }
/// <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(TradierStreamData tsd) { var symbol = _subscriptions.FirstOrDefault(x => x.Value == tsd.Symbol).Key; // Not subscribed to this symbol. if (symbol == null) return null; // Occassionally Tradier sends trades with 0 volume? if (tsd.TradeSize == 0) return null; // Tradier trades are US NY time only. Convert local server time to NY Time: var unix = Convert.ToInt64(tsd.UnixDate) / 1000; var utc = Time.UnixTimeStampToDateTime(unix); // Occassionally Tradier sends old ticks every 20sec-ish if no trading? if (DateTime.UtcNow - utc > TimeSpan.FromSeconds(10)) return null; //Convert the to security timezone and pass into algorithm var time = utc.ConvertTo(DateTimeZone.Utc, TimeZones.NewYork); return new Tick { Exchange = tsd.TradeExchange, TickType = TickType.Trade, Quantity = (int) tsd.TradeSize, Time = time, EndTime = time, Symbol = symbol, DataType = MarketDataType.Tick, Suspicious = false, Value = tsd.TradePrice }; }