How to: Create Stock and Candlestick Charts

Applies to: Functional Programming

Authors: Tomas Petricek and Jon Skeet

Referenced Image

Get this book in Print, PDF, ePub and Kindle at manning.com. Use code “MSDN37b” to save 37%.

This topic contains the following sections.

  • Introduction
  • Using an FSharpChart
  • Using .NET Chart Controls
  • Running the Code
  • See Also

Introduction

Summary: This article shows how to create stock and candlestick charts to visualize financial data in F#. It looks at how to draw charts, use dates as labels, and how to specify the range of a chart.

This article is associated with Real World Functional Programming: With Examples in F# and C# by Tomas Petricek with Jon Skeet from Manning Publications (ISBN 9781933988924, copyright Manning Publications 2009, all rights reserved). No part of these chapters may be reproduced, stored in a retrieval system, or transmitted in any form or by any means—electronic, electrostatic, mechanical, photocopying, recording, or otherwise—without the prior written permission of the publisher, except in the case of brief quotations embodied in critical articles or reviews.

This article looks at how to create stock and candlestick charts from F#. It presents two versions of the example. The first one uses the FSharpChart library that is available as a free download and the second uses .NET Chart Controls directly. For more information about loading the two libraries from F#, refer to the Running the Code section at the end of the page.

Stock and candlestick charts are designed to visualize stock prices. The data recorded about stock prices typically consists of four values representing High, Low, Open, and Close prices. The first two are the maximum and minimum price of the stock reached during the day and the last two are prices at the start and the end of the day. The examples use the following data set (price of MSFT stocks over 10 days):

let prices =
  [ 26.24,25.80,26.22,25.95; 26.40,26.18,26.26,26.20
    26.37,26.04,26.11,26.08; 26.78,26.15,26.60,26.16
    26.86,26.51,26.69,26.58; 26.95,26.50,26.91,26.55
    27.06,26.50,26.64,26.77; 26.86,26.43,26.53,26.59
    27.10,26.52,26.78,26.59; 27.21,26.99,27.13,27.06
    27.37,26.91,26.97,27.21; 27.07,26.60,27.05,27.02
    27.33,26.95,27.04,26.96; 27.27,26.95,27.21,27.23
    27.81,27.07,27.76,27.25; 27.94,27.29,27.93,27.50
    28.26,27.91,28.19,27.97; 28.34,28.05,28.10,28.28
    28.34,27.79,27.80,28.20; 27.84,27.51,27.70,27.77 ]

More information about working with financial data and how to download stock prices from the Yahoo Finance portal using F# can be found in Tutorial: Visualizing stock prices using F# charts. Figure 1 visualizes the data set using a candlestick chart.

Figure 1. A candlestick chart showing MSFT stock price

Referenced Image

Using an FSharpChart

A stock or a candlestick chart can be created using the FSharpChart.Stock and FSharpChart.Candlestick functions. Financial charts for visualizing stocks require four values for drawing each data point (High, Low, Open, and Close price). When calling the functions, it is possible to specify the values as a single collection containing four-element tuples or as four separate collections.

There are also two ways for adding (X values) to the chart. One way is to generate a collection of pairs containing the label and the four-element tuple of prices and the other is to use five separate collections. The second example below uses the first approach. Here are three examples of how to generate financial charts using FSharpChart:

// Display prices using stock chart 
FSharpChart.Stock(prices)

// Display prices with date as a label
prices 
|> List.mapi (fun i v -> DateTime.Now.AddDays(float -i), v)
|> FSharpChart.Stock    

// Candlestick chart price range specified
prices
|> FSharpChart.Candlestick
|> FSharpChart.WithArea.AxisY(Maximum = 29.0, Minimum = 25.0)

When using F# Interactive, each of these examples needs to be evaluated separately. This way, F# Interactive invokes a handler that automatically shows the created chart.

The first snippet calls the FSharpChart.Stock function with a list containing prices as four-element tuples. The second example adds dates as the labels for the chart. This is done using the List.mapi function. The lambda function used as an argument returns a pair containing the date and the original tuple of prices, so that the resulting type is list<DateTime * (float * float * float * float)>. This example also shows an elegant way of preprocessing data using pipelining (the |> operator) and passing the result to a function that draws the chart.

Finally, the last example demonstrates how to create candlestick chart and set the price range of the y-axis. This is done by passing the chart object to a configuration function FSharpChart.WithArea.AxisY (using pipelining). The function takes named parameters that allow us to specify the range and other properties of the axis.

Using .NET Chart Controls

This section shows how to create similar charts using .NET Chart Controls. The following example demonstrates how to create a simple candlestick chart from the data shown in the introduction. When constructing the chart, the type of the chart can be specified using using the ChartType property of the Series object. To create a candlestick chart, the property should be set to SeriesChartType.Candlestick. A stock chart can be created using the SeriesChartType.Stock option.

// Create a chart containing a default area and show it on a form
let chart = new Chart(Dock = DockStyle.Fill)
let form = new Form(Visible = true, Width = 700, Height = 500)
chart.ChartAreas.Add(new ChartArea("MainArea"))
form.Controls.Add(chart)

// Create series and add it to the chart
let series = new Series(ChartType = SeriesChartType.Candlestick)
chart.Series.Add(series)

// Add data to the series in a loop
for o,h,l,c in prices do
  [| o; h; l; c |] |> Array.map box |> series.Points.AddY |> ignore

After initializing the list, the snippet constructs the user interface elements. The snippet displays the chart in a new window. It creates a Form, the Chart control, and then adds the control to the form. Then, it constructs a new series and specifies the type of the chart that it represents.

In this example, the data points are added to the data series one by one using the AddY method of the Points collection. When creating point with multiple values, the method expects an array of type obj[]. To convert numerics values to array of objects, the snippet creates an array containing float values and then boxes all of the numbers to objects using the box function.

Running the Code

This section reviews the prerequisites needed to run the two examples discussed above. Both of the approaches build on top of the Microsoft Charting Library, which is available as part of the .NET 4.0 framework and can be downloaded separately for .NET 3.5.

Using the FSharpChart Library

The F# Charting library is available as a free download. The easiest way to use the library from F# Interactive is to download the library source code (FSharpChart.fsx) and load it in F# Interactive using the #load command:

#load "FSharpChart.fsx"

open System
open System.Drawing
open MSDN.FSharp.Charting

This snippet opens the namespaces that is needed when working with the library (the above examples assume these namespaces are opened). The namespace Samples.Charting contains the F# charting functionality. After writing the above lines, charts can be created using the FSharpChart type.

  • When loading the FSharpChart library in F# Interactive using the FSharpChart.fsx script file, it is not necessary to explicitly load the .NET Chart Controls assembly (System.Windows.Forms.DataVisualization.dll) because it is automatically referenced by the library script.

  • When creating a chart in a Windows Forms application, it is easier to reference the compiled version of the FSharpChart library (which can be downloaded as part of the sample source code at the end of the article). The library name is Samples.Charting.dll and it needs to be referenced together with the .NET Chart Controls assembly System.Windows.Forms.DataVisualization.dll. This can be done using the "Add Reference" command in Solution Explorer in Visual Studio.

Using .NET Chart Controls

When creating a chart from an F# script using F# Interactive, the script needs to reference the Microsoft Chart Controls assembly for Windows Forms. This is done by adding the following lines to an F# Script File (e.g., Script.fsx):

#r "System.Windows.Forms.DataVisualization.dll"

open System
open System.Drawing
open System.Windows.Forms
open System.Windows.Forms.DataVisualization.Charting

The code snippets in the first sections don't include these import declarations. In order to compile the code (as a standalone application), the following step is needed as well:

When creating a chart in a Windows Forms application or a library, the project needs to reference the .NET Chart Controls assembly using the "Add Reference" command in Solution Explorer in Visual Studio. The name of the assembly is System.Windows.Forms.DataVisualization.dll.

See Also

This article demonstrates how to use the FSharpChart library and .NET Chart Controls to create charts. For more information about charting in F# visit the following page:

This article is based on Real World Functional Programming: With Examples in F# and C#. Book chapters related to the content of this article are:

  • Book Chapter 4: “Exploring F# and .NET libraries by example” demonstrates how to create a simple charting application from scratch. This chapter is useful for learning F# programming when focusing on working with data.

  • Book Chapter 12: “Sequence expressions and alternative workflows” explains how to work with in-memory data sets in F# using sequence expressions and higher-order functions.

  • Book Chapter 13: “Asynchronous and data-driven programming” shows how to use asynchronous workflows to obtain data from the internet, how to convert data to a structured format, and how to chart it using Excel.

To download the code snippets shown in this article, go to https://code.msdn.microsoft.com/Chapter-6-Visualizing-Data-c68a2296

Previous article: How to: Create Line and Point Charts

Next article: How to: Create Boxplot Diagrams