New Version 8.1!

Supports .NET 6.0. Try it for free with our fully functional 60-day trial version.

Get from Nuget

QuickStart Samples

Simple Time Series QuickStart Sample (F#)

Illustrates how to perform simple operations on time series data using classes in the Extreme.Statistics.TimeSeriesAnalysis namespace in F#.

C# code Visual Basic code IronPython code Back to QuickStart Samples

// Illustrates the use of the TimeSeriesCollection class to represent
// and manipulate time series data.


open System

open System
open System.Collections.Generic

open System.Data
open System.Data.OleDb

open Extreme.DataAnalysis
open Extreme.Mathematics
open Extreme.Statistics

// Time series collections can be created in a variety of ways.
// Here we use an ADO.NET data table:
let seriesTable =
    let filename = @"..\..\..\..\Data\MicrosoftStock.xls"
    let connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+filename+";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\""
    let ds = new DataSet()
    use cnn = new OleDbConnection(connectionString)
        use adapter = new OleDbDataAdapter("Select * from [MicrosoftStock$]", cnn)
        adapter.Fill(ds) |> ignore
    with :? OleDbException as ex -> printfn "%s" ex.InnerException.Message
let timeSeries = DataFrame.FromDataTable<DateTime>(seriesTable, "Date")

// The RowCount property returns the number of
// observations:
printfn "# observations: %d" timeSeries.RowCount

// Accessing variables

// Variables are accessed by name or numeric index.
// They need to be cast to the appropriate specialized
// type using the As() method:
let close = timeSeries.["Close"].As<double>()
Console.WriteLine("Average close price: ${0:F2}", close.Mean())

// Variables can also be accessed by numeric index:
printfn "3rd variable: %A" timeSeries.[2].Name

// The GetRows method returns the data from the specified range.
let y2004 = DateTime(2004, 1, 1)
let y2005 = DateTime(2005, 1, 1)
let series2004 = timeSeries.GetRows(y2004, y2005)
Console.WriteLine("Opening price on the first trading day of 2004: {0}",

// Transforming the Frequency

// The first step is to define the aggregator function
// for each variable. This function specifies how each
// observation in the new time series is calculated
// from the observations in the original series.

// The Aggregators class has a number of 
// pre-defined aggregator functions.

// We create a dictionary that maps column names
// to aggregators:
let aggregators = 
    let d = Dictionary<string, AggregatorGroup>()
    d.Add("Open", Aggregators.First)
    d.Add("Close", Aggregators.Last)
    d.Add("High", Aggregators.Max)
    d.Add("Low", Aggregators.Min)
    d.Add("Volume", Aggregators.Sum)

// We can then resample the data frame in accordance with
// a recurrence pattern we specify, in this case monthly:
let monthlySeries = timeSeries.Resample(Recurrence.Monthly, aggregators)

// We can specify a subset of the series by selecting it
// from the data frame first:
let monthlySeries2 = timeSeries.GetRows(y2004, y2005).Resample(Recurrence.Monthly, aggregators)

// We can now print the results:
Console.WriteLine("Monthly statistics for Microsoft Corp. (MSFT)")

printf "Press any key to exit."
Console.ReadLine() |> ignore