/// <summary>
        /// The function executed as the Robinhood interface
        /// </summary>
        private void ThreadProcess()
        {
            while (Running)
            {
                // Process the history requests
                if (Client.isAuthenticated &&
                    (HistoryRequests.Count > 0) &&
                    ((DateTime.Now - HistoryRequests[0].RequestTime).TotalSeconds) > HISTORY_REQUEST_PROCESS_DELAY)
                {
                    while ((HistoryRequests.Count > 0) && Running)
                    {
                        // Put together a single request
                        RobinhoodThreadMutex.WaitOne();
                        DateTime      start    = HistoryRequests[0].Start;
                        DateTime      end      = HistoryRequests[0].End;
                        TimeSpan      interval = getHistoryInterval(HistoryRequests[0].Interval, getHistoryTimeSpan(start, end));
                        List <string> symbols  = new List <string>()
                        {
                            HistoryRequests[0].Symbol
                        };
                        List <int> servicedIndices = new List <int>()
                        {
                            0
                        };
                        for (int i = 1; i < HistoryRequests.Count; i++)
                        {
                            if (getHistoryInterval(HistoryRequests[i].Interval, getHistoryTimeSpan(HistoryRequests[i].Start, HistoryRequests[i].End)) == interval)
                            {
                                // Include this in the request
                                symbols.Add(HistoryRequests[i].Symbol);
                                servicedIndices.Add(i);
                                start = ((start < HistoryRequests[i].Start) ? start : HistoryRequests[i].Start);
                                end   = ((end > HistoryRequests[i].End) ? end : HistoryRequests[i].End);
                            }
                        }
                        RobinhoodThreadMutex.ReleaseMutex();

                        // Make the request
                        if ((getHistoryTimeSpan(start, end) >= HISTORY_SPANS.ElementAt(HISTORY_SPANS.Count - 1).Key) ||         // If requesting too far back in history
                            ((start.Date == end.Date) && ((end < EXTENDED_HOURS_OPEN) || (start >= EXTENDED_HOURS_CLOSE))))     // If requesting data outside of the available times
                        {
                            foreach (var s in servicedIndices)
                            {
                                HistoryRequests[s].Callback(null);
                            }
                        }
                        else
                        {
                            var bounds  = ((start.Date == end.Date) ? HISTORY_BOUNDS.EXTENDED : HISTORY_BOUNDS.REGULAR); // Can only get extended hours history for the current day
                            var request = Client.DownloadHistory(symbols, HISTORY_INTERVALS[interval], HISTORY_SPANS[getHistoryTimeSpan(start, end)], bounds);
                            request.Wait();
                            if (!request.IsCompleted || request.IsFaulted)
                            {
                                continue;
                            }
                            var history = request.Result;

                            // Return the data to the reqesting sources
                            int servicedCount = 0;
                            foreach (var stock in history)
                            {
                                if (stock.HistoricalInfo.Count > 0)
                                {
                                    // Put the data into a table
                                    DataTable dt = new DataTable();
                                    dt.Columns.Add("Time", typeof(DateTime));
                                    dt.Columns.Add("Price", typeof(float));
                                    foreach (var p in stock.HistoricalInfo)
                                    {
                                        DateTime t = (interval < new TimeSpan(1, 0, 0, 0)) ? p.BeginsAt.ToLocalTime() : p.BeginsAt.AddHours(9.5);
                                        dt.Rows.Add(t, (float)p.OpenPrice);
                                    }

                                    // Add a final price
                                    dt.Rows.Add(stock.HistoricalInfo[stock.HistoricalInfo.Count - 1].BeginsAt.Add(interval).ToLocalTime(), stock.HistoricalInfo[stock.HistoricalInfo.Count - 1].ClosePrice);

                                    // Pass the table back to the caller
                                    if (!HistoryRequests[servicedIndices[servicedCount]].Symbol.Equals(stock.Symbol))
                                    {
                                        //throw new Exception("Response does not match the request");
                                    }
                                    HistoryRequests[servicedIndices[servicedCount]].Callback(dt);
                                    servicedCount++;
                                }
                            }
                        }

                        // Remove the processed requests from the queue
                        RobinhoodThreadMutex.WaitOne();
                        for (int i = servicedIndices.Count - 1; i >= 0; i--)
                        {
                            HistoryRequests.RemoveAt(servicedIndices[i]);
                        }
                        RobinhoodThreadMutex.ReleaseMutex();
                    }
                }

                // Process the position subscriptions
                if (RobinhoodThreadMutex.WaitOne(0))
                {
                    for (int i = 0; Client.isAuthenticated && (i < PositionSubscriptions.Count); i++)
                    {
                        Broker.PositionSubscription sub = PositionSubscriptions[i];
                        var orderInfo = ActiveOrders.Find((a) => { return(a.Symbol.Equals(sub.PositionInfo.Symbol)); });
                        if (((DateTime.Now - sub.LastUpdated).TotalSeconds > 5) &&
                            (sub.Dirty || ((orderInfo != null) && (orderInfo.RefreshedAt != sub.LastUpdated))))
                        {
                            sub.LastUpdated = DateTime.Now;
                            GetPositionInfo(sub.PositionInfo.Symbol, (info) =>
                            {
                                sub.PositionInfo = info;
                                sub.LastUpdated  = ((orderInfo != null) ? orderInfo.RefreshedAt : DateTime.Now);
                                sub.Dirty        = false;
                                if (sub.Notify != null)
                                {
                                    sub.Notify(sub);
                                }
                            });
                        }
                    }
                    RobinhoodThreadMutex.ReleaseMutex();
                }

                // Update the active orders
                RefreshActiveOrders();

                // Sleep so the thread doesn't run at 100% CPU
                System.Threading.Thread.Sleep(5);
            }
        }
Пример #2
0
        public static void Main(string [] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Usage:");
                Console.WriteLine("RhQuote SYMBOL1 [SYMBOL2 SYMBOL3 SYMBOL_N]");
                Environment.Exit(1);
            }

            var rh = new RobinhoodClient();

            if (!authenticate(rh))
            {
                Console.WriteLine("Unable to authenticate user");
                Environment.Exit(1);
            }

            try
            {
                var quotes  = rh.DownloadQuote(args).Result;
                var history = rh.DownloadHistory(args, "5minute", "week").Result;
                Console.WriteLine(DateTime.Now);
                foreach (var q in quotes)
                {
                    if (q == null)
                    {
                        continue;
                    }

                    Console.WriteLine("{0}\tCh: {1}%\tLTP: {2}\tBID: {3}\tASK: {4}",
                                      q.Symbol,
                                      q.ChangePercentage,
                                      q.LastTradePrice,
                                      q.BidPrice,
                                      q.AskPrice);
                }
                foreach (var h in history)
                {
                    if (h == null)
                    {
                        continue;
                    }

                    Console.WriteLine("{0}\tInterval: {1}\tSpan: {2}\tBound: {3}",
                                      h.Symbol,
                                      h.Interval,
                                      h.Span,
                                      h.Bounds);
                    foreach (var p in h.HistoricalInfo)
                    {
                        Console.WriteLine("{0}\tOpen: {1}\tClose: {2}\tHigh: {3}\tLow: {3}",
                                          p.BeginsAt,
                                          p.OpenPrice,
                                          p.ClosePrice,
                                          p.HighPrice,
                                          p.LowPrice);
                    }
                }
            }
            catch
            {
                Console.WriteLine("None of the quotes entered were found.");
            }
        }