How to select a time period in the in FSharp.Data?

260 Views Asked by At

I wrote this script to plot the historical financial data:

open FSharp.Data
#load "C:\Users\Nick\Documents\Visual Studio 2013\Projects\TryFsharp\packages\FSharp.Charting.0.90.9\FSharp.Charting.fsx"
open FSharp.Charting
open System

let plotprice nasdaqcode =
    let url = "http://ichart.finance.yahoo.com/table.csv?s="+nasdaqcode
    let company = CsvFile.Load(url)
    let companyPrices = [ for r in company.Rows -> r.GetColumn "Date", r.GetColumn "Close" ]
    (companyPrices 
        |> List.sort 
        |> Chart.Line).WithTitle(nasdaqcode, InsideArea=false)

plotprice "MSFT"
plotprice "ORCL"
plotprice "GOOG"
plotprice "NTES"

This works well.

Question:

  1. Some of the data starts from the year 1986, some from 2000. I would like to plot the data from year 2000 to 2015. How to select this time period?

  2. Is it possible to display the time when the mouse hovers over the chart?

2

There are 2 best solutions below

2
On BEST ANSWER

If you are accessing Yahoo data, then it's better to use the CsvProvider rather than using CsvFile from F# Data. You can find more about the type provider here. Sadly, the naming in the standard F# Data library and on TryFSharp.org is different, so this is a bit confusing.

The CSV type provider will automatically infer the types:

open FSharp.Data
open FSharp.Charting
open System

// Generate type based on a sample
type Stocks = CsvProvider<"http://ichart.finance.yahoo.com/table.csv?s=FB">

let plotprice nasdaqcode =
    let url = "http://ichart.finance.yahoo.com/table.csv?s=" + nasdaqcode
    let company = Stocks.Load(url)
    // Now you can access the columns in a statically-typed way
    // and the types of the columns are inferred from the sample
    let companyPrices = [ for r in company.Rows -> r.Date, r.Close ]

    // If you want to do filtering, you can now use the `r.Date` property
    let companyPrices = 
      [ for r in company.Rows do
          if r.Date > DateTime(2010, 1, 1) && r.Date < DateTime(2011, 1, 1) then
            yield r.Date, r.Close ]

    // Charting as before
    companyPrices |> (...)

I'm not sure if the F# Charting library has a way for showing the price based on mouse pointer location - it is based on standard .NET Windows Forms charting controls, so you could have a look at the documentation for the underlying library.

1
On

1) GetColumn gets a string. You need to first convert it to DateTime and simply compare it. i.e.

let plotprice nasdaqcode =
    let url = "http://ichart.finance.yahoo.com/table.csv?s="+nasdaqcode
    let company = CsvFile.Load(url)
    let companyPrices = [ for r in company.Rows -> DateTime.Parse(r.GetColumn "Date"), r.GetColumn "Close" ]
    (companyPrices 
        |> List.filter (fun (date, _) -> date > DateTime(2000, 1, 1))
        |> List.sort 
        |> Chart.Line).WithTitle(nasdaqcode, InsideArea=false)

2) You can try with adding labels (not sure how to do on hover though...)

let plotprice nasdaqcode =
    let url = "http://ichart.finance.yahoo.com/table.csv?s="+nasdaqcode
    let company = CsvFile.Load(url)
    let companyPrices = [ for r in company.Rows -> DateTime.Parse(r.GetColumn "Date"), r.GetColumn "Close" ]
    (companyPrices 
        |> List.filter (fun (date, _) -> date > DateTime(2000, 1, 1))
        |> List.sort 
        |> fun data -> Chart.Line(data, Labels=(Seq.map (fst >> string) data))).WithTitle(nasdaqcode, InsideArea=false)