Beispiel #1
0
            public override void Destroy()
            {
                Broker.Instance.UnsubscribePosition(PositionSubscription);
                PositionSubscription = null;

                base.Destroy();
            }
Beispiel #2
0
            public override void Initialize()
            {
                // Attempt to get a reference price either as the purchase price if there is a position in this stock, or the day's starting price otherwise
                DataAccessor.Accessor.GetStockInfo(StockSubscription.Symbol, (DataAccessor.StockInfo info) =>
                {
                    if (PositionSubscription.PositionInfo.Shares == 0)
                    {
                        this.RefPrice = info.PreviousClose;
                    }
                });
                PositionSubscription         = Broker.Instance.SubscribeToPositionInfo(StockSubscription.Symbol);
                PositionSubscription.Notify += (Broker.PositionSubscription sub) =>
                {
                    if (sub.PositionInfo.Shares > 0)
                    {
                        this.RefPrice = sub.PositionInfo.AverageBuyPrice;
                    }
                };

                // Update the notification periodically
                StockSubscription.Notify += (DataAccessor.Subscription s) =>
                {
                    this.BeginInvoke((Action)(() =>
                    {
                        PriceLabel.Text = string.Format("{0:c}", s.Price);
                        PercentageLabel.Text = string.Format("{0}{1:P2}", (s.Price >= RefPrice) ? "+" : "-", (RefPrice != 0) ? Math.Abs((s.Price - RefPrice) / RefPrice) : 0);
                    }));
                };

                // Set the notification background color
                this.ParentLine.BackColor = GuiStyle.NOTIFICATION_COLOR;
            }
 /// <summary>
 /// Ends the specified subscription
 /// </summary>
 /// <param name="subscription">The subscription to stop</param>
 public void UnsubscribePosition(Broker.PositionSubscription subscription)
 {
     if (RobinhoodThreadMutex.WaitOne(100))
     {
         PositionSubscriptions.Remove(subscription);
         RobinhoodThreadMutex.ReleaseMutex();
     }
 }
        /// <summary>
        /// Returns information about a current position whenever there is a change
        /// </summary>
        /// <param name="symbol">The symbol to request the position for</param>
        /// <returns>The subscription instance</returns>
        public Broker.PositionSubscription SubscribeToPositionInfo(string symbol)
        {
            var subscription = new Broker.PositionSubscription(symbol);

            if (RobinhoodThreadMutex.WaitOne(100))
            {
                PositionSubscriptions.Add(subscription);
                RobinhoodThreadMutex.ReleaseMutex();
            }

            return(subscription);
        }
Beispiel #5
0
 public override void Initialize()
 {
     PositionSubscription         = Broker.Instance.SubscribeToPositionInfo(StockSubscription.Symbol);
     PositionSubscription.Notify += (Broker.PositionSubscription sub) =>
     {
         if (sub.PositionInfo.Shares > 0)
         {
             this.RefPrice = sub.PositionInfo.AverageBuyPrice;
         }
         else
         {
             // Remove the position indication once there are no shares left
             ParentLine.ParentList.Remove(ParentLine);
         }
     };
     StockSubscription.Notify += (DataAccessor.Subscription s) =>
     {
         this.BeginInvoke((Action)(() =>
         {
             PriceLabel.Text = string.Format("{0:c}", (s.Price * PositionSubscription.PositionInfo.Shares));
             PercentageLabel.Text = string.Format("{0}{1:P2}", (s.Price >= RefPrice) ? "+" : "-", (RefPrice != 0) ? Math.Abs((s.Price - RefPrice) / RefPrice) : 0);
         }));
     };
 }
        /// <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);
            }
        }