Search Forum
(57415 Postings)
Search Site/Articles

Archived Articles
712 Articles

C# Books
C# Consultants
What Is C#?
Download Compiler
Code Archive
Archived Articles
Advertise
Contribute
C# Jobs
Beginners Tutorial
C# Contractors
C# Consulting
Links
C# Manual
Contact Us
Legal

GoDiagram for .NET from Northwoods Software www.nwoods.com


              
Printable Version

A C# Stock Ticker
By Narendra Maharaj

A running stock market ticker-tape with realtime updates.
The Problem
In order to write this program, I had to solve three main problems:

1. How to draw a Form based window and manipulate it without a menu bar.

2. How to get the stock data from the web server.

3. How to display the data as a running stream.

As it turns out, it is quite easy to supress the menu bar, two things are required. Set the ControlBox of the Form control to false, and the Text field to blank. To move the window around the screen first capture the MouseDown, MouseMove and MouseUp events save the mouse-down point, calculate how far the mouse has moved and redraw the Form there.
      
    private void OnMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
    {
      if (WinMoving)
      {
        Point pt = new Point(Cursor.Position.X - MsDownPt.X, Cursor.Position.Y - MsDownPt.Y);
        DesktopLocation = pt; 
      }
    }
	    
The second problem is also quite easy to solve, we employ the standard WebRequest/WebResponse mechanism. Attach a StreamReader, then parse and collect the required data from the stream. This method is used for the initial data load and the periodic update of the stock price, volume etc.
      
			...
        wreq=WebRequest.Create(@"http://stock_ticker_url.com");	
        wresp=(HttpWebResponse)wreq.GetResponse();		
        StockStream = wresp.GetResponseStream();
        StockStreamReader = new StreamReader(StockStream);

        sRow = StockStreamReader.ReadLine();
        while (sRow != null)
			...

	    
The third problem is a little more involved. There are a few techniques available. The most obvious is to draw the data using a single string by generating a Graphics object and use the DrawString(...) method. Several things makes this a poor approach, for one thing it is difficult to perform a smooth transition a the boundary of the Form's client area, second we would require another string if we wanted to draw on the client area, below the main stock stream. This would make alignment of the strings crucial and very dificult. So I decided upon a variation: Build a class to hold all the stock data (obviously), together with a point indicating where on the client area to draw the data-string. In order to move the string, subtract a few points from the location, blank out the current string and redraw the string at the new location. This has a cool bonus, I can also store a color to draw with depending on if the stock is up (green), down (red) or has the same price as the open (white). Yet another problem is solved by this approach, using the same location I can draw at any position relative to it. In particular I can draw a string right below the main stream for no real added cost. In the program I actually store two points to save time on the creation of the points during the drawing, simply reducing the X-Axis co-ordinate moves the string along. In this manner I use the top data-string to display the stock symbol, price and price change, and the bottom data-string to display the volume (number of shares traded).
Program Outline
Following is the basic block diagram of the program.
We begin by reading in a set of symbols (stocks) to display together with a number of user settings. These are stored in an XML file on the local machine. During serialization any number of symbols can be stored in this file the display attribute determines whether or not the user wants the symbol displayed. Note: for a multi-user system, this data should be stored in a database.
      
	< ?xml version="1.0"?>
	< xml>
          < stock symbol="AAP" display="Y" />
  	  < stock symbol="AOL" display="Y" />
  	  < stock symbol="DSS" display="N" />
				...
          < preferences opacity="0.84" refreshtime="10000" font="Verdana" 
            fontsize="8.25" fontstyle="regular" 
            topmost="true" displayspeed="20" />
	< /xml>
	    
The preferences.cs file has the code for our: XmlTextReader xtr = new XmlTextReader(xmlFile) and XmlTextWriter xtw = new XmlTextWriter(xmlFile, null), reader and writer methods. A SortedList is used as the main memory storage. The XMLReader builds this list as it reads symbols from the XML file. The SortedList has a hybrid behavior, it can be accessed like a HashTable via a key or like an Arraylist via an an index. We will use both techniques in the program. An initial read from the web server is performed followed by the initial calculation of the display locations. The display thread is then created and it begins the continous process of looping through the display SortedList and moving the display data along the Form control client area.
      
    public void MoveText()
    {
      int i;
      stock st;
      stock stl;

      while (true)
      {
        for (i = 0; i < mQuoteList.Count; i++)
        {
          st = (stock)(mQuoteList.GetByIndex(i));

          DelPoly(st.loc1, st.mLen);
          st.loc1.X -= 2;
          st.loc2.X -= 2;
          if (st.loc1.X  + st.mLen*t.FontWidth < 0)
          {
            if (i == 0)
              stl = (stock)(mQuoteList.GetByIndex(mQuoteList.Count - 1));
            else
              stl = (stock)(mQuoteList.GetByIndex(i - 1));

            st.loc1.X = stl.loc1.X + stl.mLen*t.FontWidth;
            st.loc2.X = stl.loc2.X + stl.mLen*t.FontWidth;
          }
          if (st.loc1.X < t.ClientSize.Width)
          {
            _draw(st.displayString1, st.loc1, st.mBrush);
            _draw(st.displayString2, st.loc2, st.mBrush);
          }
        }
        Thread.Sleep(40 - mDisplaySpeed);
      } // while true
    }
	    
User input and requests are taken via a ContextMenu displayed when the right-mouse button is pressed. Of interest is the Settings menu option.
The settings menu generates the stock options dialog box (pun intented).
Only the Opacity option may be unfamiliar. It determines the transparency of the ticker. Please exercise caution, Opacity of zero makes the control vanish! Below the ticker is on top a "cmd" window, which can be seen through the ticker.
The Stock Selection tab looks like this:
Again very straightforward. The checkbox next to the symbol determines if it is displayed on the ticker, it is NOT removed from the user list unless Delete Symbol is pressed. Even then it is not completly lost unless the Save Settings button is pressed. Note: Only when the Save Settings button is pressed is the XMLWriter invoked, all settings used for a session will be lost unless saved. Below "DSS" is not displayed but is is still part of the user list.
Then the Stock Details tab, keyin the symbol then press the Enter key:
This shows all the stock details we are unable to display on the ticker itself.
Worth mentioning is the Font button the the options tab. This allows for some fun fonts!

Download ticker.zip