Header menu logo Teaching

Script

#r "nuget: FSharp.Data, 5.0.2"

open System
open System.IO
open FSharp.Data

Environment.CurrentDirectory <- __SOURCE_DIRECTORY__

module Secrets =
    let envVars = System.Environment.GetEnvironmentVariables() 
    let localPath = "../secrets.fsx"
    let localPath2 = "secrets.fsx"
    let tiingoKey = 
        let var = "TIINGO_KEY"
        if envVars.Contains var then 
            envVars.[var] :?> string
        elif File.Exists(localPath) then 
            File.ReadAllText(localPath)
                .Replace("let tiingoKey = ","")
                .Replace("\"","")
        elif File.Exists(localPath2) then
            File.ReadAllText(localPath2)
                .Replace("let tiingoKey = ","")
                .Replace("\"","")
        else "you don't have a key"


type Frequency = Daily | Monthly
type ReturnObs = { Symbol : string; Date : DateTime; Return : float }

module Tiingo =

    type TiingoCsv = CsvProvider<"date,close,high,low,open,volume,adjClose,adjHigh,adjLow,adjOpen,adjVolume,divCash,splitFactor
2020-10-01,9.77,10.25,9.69,10.09,4554055,9.77,10.25,9.69,10.09,4554055.0,0.0,1.0">

    type TiingoRequest = { Symbol : string; Start : DateTime; End : DateTime }

    type TiingoObs =
        {
            Date : DateTime
            Close : decimal
            High : decimal
            Low : decimal
            Open : decimal 
            Volume : int
            AdjClose : decimal
            AdjHigh : decimal
            AdjLow : decimal
            AdjOpen : decimal
            AdjVolume : decimal
            DivCash : decimal
            SplitFactor : decimal
        }

    ///<summary>Constructs a Tiingo request. By default is to get the past year of data.</summary>
        /// <param name="symbol">The ticker symbol such as "AAPL","MSFT" etc.</param>
    let request symbol = { Symbol = symbol; Start = DateTime.Now.AddYears(-1); End = DateTime.Now}
    ///<summary>Sets the Tiingo request start date.</summary>
        /// <param name="startOn">Request start date</param>
        /// <param name="request">The Tiingo request to update.</param>
    let startOn startOn request = { request with Start = startOn }
    ///<summary>Sets the Tiingo request end date.</summary>
        /// <param name="endOn">Request start date</param>
        /// <param name="request">The Tiingo request to update.</param>
    let endOn endOn request = { request with End = endOn }

    let private cache = Runtime.Caching.createInMemoryCache (TimeSpan(hours=12,minutes=0,seconds=0))

    ///<summary>Downloads Tiingo data.</summary>
        /// <param name="request">The Tiingo request to download.</param>
    let get request =
        let dtStr (x : DateTime) = x.Date.ToString("yyyy-MM-dd")
        let request = { request with Start = request.Start.Date; End = request.End.Date }
        let key = $"{request.Symbol}-{dtStr request.Start}-{dtStr request.End}.csv"
        match cache.TryRetrieve(key) with
        | Some res -> res
        | None ->
            let result = 
                Http.RequestString
                            ( $"https://api.tiingo.com/tiingo/daily/{request.Symbol}/prices", 
                                httpMethod = "GET",
                                query   = [ "token", Secrets.tiingoKey; 
                                            "startDate", request.Start.ToString("yyyy-MM-dd");
                                            "endDate", request.End.ToString("yyyy-MM-dd");
                                            "format","csv"],
                                headers = [HttpRequestHeaders.Accept HttpContentTypes.Csv])
            cache.Set(key,result)
            result
        |> TiingoCsv.Parse
        |> fun parsed ->
            parsed.Rows
            |> Seq.map(fun row ->
                { Date = row.Date
                  Close = row.Close
                  High = row.High
                  Low = row.Low
                  Open = row.Open
                  Volume = row.Volume
                  AdjClose = row.AdjClose
                  AdjHigh = row.AdjHigh
                  AdjLow = row.AdjLow
                  AdjOpen = row.AdjOpen
                  AdjVolume = row.AdjVolume
                  DivCash = row.DivCash
                  SplitFactor = row.SplitFactor 
                  })
            |> Seq.toArray      
    
    // using a class, keeping private for now.
    type private Download(symbol:string,?startOn:DateTime,?endOn:DateTime) =
        let startOn = defaultArg startOn (DateTime.Now.AddYears(-1))
        let endOn = defaultArg endOn (DateTime.Now)
        let data = get { Symbol = symbol; Start = startOn; End = endOn }
        member this.Rows = data
 
    // Probably deprecated
    let private getFromCacheDirectory cacheDirectory request =
        let dtStr (x : DateTime) = x.Date.ToString("yyyy-MM-dd")
        let request = { request with Start = request.Start.Date; End = request.End.Date }
        let key = $"{request.Symbol}-{dtStr request.Start}-{dtStr request.End}.csv"
        let cacheFile = cacheDirectory + key
        if File.Exists(cacheFile) then
            File.ReadAllText(cacheFile)
        else    
            let result = 
                Http.RequestString
                            ( $"https://api.tiingo.com/tiingo/daily/{request.Symbol}/prices", 
                                httpMethod = "GET",
                                query   = [ "token", Secrets.tiingoKey; 
                                            "startDate", request.Start.ToString("yyyy-MM-dd");
                                            "endDate", request.End.ToString("yyyy-MM-dd");
                                            "format","csv"],
                                headers = [HttpRequestHeaders.Accept HttpContentTypes.Csv])
            File.WriteAllText(cacheFile,result)
            result
        |> TiingoCsv.Parse
    
    let private returnHelper symbol (xs:TiingoObs seq) =
        xs
        |> Seq.sortBy(fun x -> x.Date)
        |> Seq.pairwise
        |> Seq.map(fun (yesterday, today) ->
            { Symbol = symbol 
              Date = today.Date
              Return =  float (today.AdjClose / yesterday.AdjClose) - 1.0})
        |> Seq.toArray      

    let getReturns request =
        get request
        |> (returnHelper request.Symbol)

    // Marking as private so people don't use it by accident
    let private getInternetFileCache request =
        let cache = Runtime.Caching.createInternetFileCache "tiingo" (TimeSpan.FromDays 30.0)
        let request = { request with Start = request.Start.Date; End = request.End.Date }
        let key = request.ToString()
        match cache.TryRetrieve(key) with
        | Some res -> res
        | None ->
            let res =
                Http.RequestString
                        ( $"https://api.tiingo.com/tiingo/daily/{request.Symbol}/prices", 
                            httpMethod = "GET",
                            query   = [ "token", Secrets.tiingoKey; 
                                        "startDate", request.Start.ToString("yyyy-MM-dd");
                                        "endDate", request.End.ToString("yyyy-MM-dd");
                                        "format","csv"],
                            headers = [HttpRequestHeaders.Accept HttpContentTypes.Csv ])
            cache.Set(key, res)
            res
        |> TiingoCsv.Parse

module French =
    //open System.Net
    open System.IO.Compression

    type private FF3Csv = CsvProvider<"Date (string),Mkt-RF,SMB,HML,RF
        19260701,    0.10,   -0.24,   -0.28,   0.009">
    type FF3Obs = 
        { Date : DateTime 
          MktRf : float
          Smb : float 
          Hml : float
          Rf : float 
          Frequency : Frequency } 

    type private FF5Csv = CsvProvider<"Date (string),Mkt-RF,SMB,HML,RMW,CMA,RF
        19260701,    0.10,   -0.24,   -0.28,0.0,1.2,  0.009">

    type FF5Obs = 
        { Date : DateTime 
          MktRf : float
          Smb : float 
          Hml : float
          Rmw : float
          Cma : float
          Rf : float 
          Frequency : Frequency } 

    let private frenchDay x = 
        DateTime.ParseExact(x,
            "yyyyMMdd",
            Globalization.CultureInfo.InvariantCulture)
    let private frenchMonth x = 
        DateTime.ParseExact(x,
            "yyyyMM",
            Globalization.CultureInfo.InvariantCulture)

    let private cache = 
        let today = DateTime.Now
        let nextMonth = today.AddMonths(1)
        let eom = DateTime(nextMonth.Year, nextMonth.Month, 1).AddSeconds(-1.0) 
        Runtime.Caching.createInternetFileCache "French" (eom - today)

    let private getData (dataset:string) =
        match cache.TryRetrieve(dataset) with
        | Some data -> data
        | None ->
            //let dataset = "F-F_Research_Data_Factors_CSV"
            let urlString = $"http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/ftp/{dataset}.zip"
            let request = Http.RequestStream(urlString, httpMethod = "GET",headers = [HttpRequestHeaders.Accept HttpContentTypes.Any])
            use archive = new ZipArchive(request.ResponseStream,ZipArchiveMode.Read)
            let file = archive.GetEntry($"{dataset}".Replace("_CSV",".CSV"))
            use reader = new StreamReader(file.Open())
            let data  = reader.ReadToEnd()
            cache.Set(dataset,data)
            data
    let getFF3 frequency =
            let (dataset, dateParser) =
                match frequency with
                | Monthly -> "F-F_Research_Data_Factors_CSV", frenchMonth
                | Daily -> "F-F_Research_Data_Factors_daily_CSV", frenchDay
            let data = new StringReader(getData dataset)
            [| while data.Peek() <> -1 do
                    data.ReadLine() |]
            |> Array.skipWhile(fun line -> not (line.Contains("Mkt-RF")))
            |> Array.skip 1
            |> Array.takeWhile(fun line -> line <> "")
            |> Array.map(fun line -> 
                let parsedLine = FF3Csv.ParseRows(line).[0] 
                { Date = dateParser parsedLine.Date
                  MktRf = float parsedLine.``Mkt-RF`` / 100.0
                  Smb = float parsedLine.SMB / 100.0
                  Hml = float parsedLine.HML / 100.0
                  Rf = float parsedLine.RF / 100.0 
                  Frequency = frequency })

    let getFF5 frequency =
        let (dataset, dateParser) =
            match frequency with
            | Monthly -> "F-F_Research_Data_5_Factors_2x3_CSV", frenchMonth
            | Daily -> "F-F_Research_Data_5_Factors_2x3_daily_CSV", frenchDay
        let data = new StringReader(getData dataset)
        [| while data.Peek() <> -1 do
                data.ReadLine() |]
        |> Array.skipWhile(fun line -> not (line.Contains("Mkt-RF")))
        |> Array.skip 1
        |> Array.takeWhile(fun line -> line <> "")
        |> Array.map(fun line -> 
            let parsedLine = FF5Csv.ParseRows(line).[0] 
            { Date = dateParser parsedLine.Date
              MktRf = float parsedLine.``Mkt-RF`` / 100.0
              Smb = float parsedLine.SMB / 100.0
              Hml = float parsedLine.HML / 100.0
              Rmw = float parsedLine.RMW / 100.0
              Cma = float parsedLine.CMA / 100.0
              Rf = float parsedLine.RF / 100.0 
              Frequency = frequency })

module Fred =
    type Series = CsvProvider<"https://fred.stlouisfed.org/graph/fredgraph.csv?id=GS10",
                              Schema="Date,Value (float)",
                              MissingValues=".">
    let private fredUrl series = $"https://fred.stlouisfed.org/graph/fredgraph.csv?id={series}"
    
    ///<summary>Gets a FRED data series as a CsvProvider</summary>
        /// <param name="series">The series name such as GS10, EXUSEU, etc.</param>
    let get (series:string) =  Series.Load(fredUrl series)
    
namespace System
namespace System.IO
Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Data

--------------------
namespace Microsoft.FSharp.Data
type Environment = static member Exit: exitCode: int -> unit static member ExpandEnvironmentVariables: name: string -> string static member FailFast: message: string -> unit + 1 overload static member GetCommandLineArgs: unit -> string array static member GetEnvironmentVariable: variable: string -> string + 1 overload static member GetEnvironmentVariables: unit -> IDictionary + 1 overload static member GetFolderPath: folder: SpecialFolder -> string + 1 overload static member GetLogicalDrives: unit -> string array static member SetEnvironmentVariable: variable: string * value: string -> unit + 1 overload static member CommandLine: string ...
<summary>Provides information about, and means to manipulate, the current environment and platform. This class cannot be inherited.</summary>
property Environment.CurrentDirectory: string with get, set
<summary>Gets or sets the fully qualified path of the current working directory.</summary>
<exception cref="T:System.ArgumentException">Attempted to set to an empty string ("").</exception>
<exception cref="T:System.ArgumentNullException">Attempted to set to <see langword="null" />.</exception>
<exception cref="T:System.IO.IOException">An I/O error occurred.</exception>
<exception cref="T:System.IO.DirectoryNotFoundException">Attempted to set a local path that cannot be found.</exception>
<exception cref="T:System.Security.SecurityException">The caller does not have the appropriate permission.</exception>
<returns>The directory path.</returns>
val envVars: Collections.IDictionary
Environment.GetEnvironmentVariables() : Collections.IDictionary
Environment.GetEnvironmentVariables(target: EnvironmentVariableTarget) : Collections.IDictionary
val localPath: string
val localPath2: string
val tiingoKey: string
val var: string
Collections.IDictionary.Contains(key: obj) : bool
Multiple items
val string: value: 'T -> string

--------------------
type string = String
type File = static member AppendAllLines: path: string * contents: IEnumerable<string> -> unit + 1 overload static member AppendAllLinesAsync: path: string * contents: IEnumerable<string> * encoding: Encoding * ?cancellationToken: CancellationToken -> Task + 1 overload static member AppendAllText: path: string * contents: string -> unit + 1 overload static member AppendAllTextAsync: path: string * contents: string * encoding: Encoding * ?cancellationToken: CancellationToken -> Task + 1 overload static member AppendText: path: string -> StreamWriter static member Copy: sourceFileName: string * destFileName: string -> unit + 1 overload static member Create: path: string -> FileStream + 2 overloads static member CreateSymbolicLink: path: string * pathToTarget: string -> FileSystemInfo static member CreateText: path: string -> StreamWriter static member Decrypt: path: string -> unit ...
<summary>Provides static methods for the creation, copying, deletion, moving, and opening of a single file, and aids in the creation of <see cref="T:System.IO.FileStream" /> objects.</summary>
File.Exists(path: string) : bool
File.ReadAllText(path: string) : string
File.ReadAllText(path: string, encoding: Text.Encoding) : string
type Frequency = | Daily | Monthly
type ReturnObs = { Symbol: string Date: DateTime Return: float }
Multiple items
[<Struct>] type DateTime = new: year: int * month: int * day: int -> unit + 16 overloads member Add: value: TimeSpan -> DateTime member AddDays: value: float -> DateTime member AddHours: value: float -> DateTime member AddMicroseconds: value: float -> DateTime member AddMilliseconds: value: float -> DateTime member AddMinutes: value: float -> DateTime member AddMonths: months: int -> DateTime member AddSeconds: value: float -> DateTime member AddTicks: value: int64 -> DateTime ...
<summary>Represents an instant in time, typically expressed as a date and time of day.</summary>

--------------------
DateTime ()
   (+0 other overloads)
DateTime(ticks: int64) : DateTime
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(date: DateOnly, time: TimeOnly) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : DateTime
   (+0 other overloads)
DateTime(date: DateOnly, time: TimeOnly, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : DateTime
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : DateTime
   (+0 other overloads)
Multiple items
val float: value: 'T -> float (requires member op_Explicit)

--------------------
type float = Double

--------------------
type float<'Measure> = float
type TiingoCsv = CsvProvider<...>
type CsvProvider
<summary>Typed representation of a CSV file.</summary> <param name='Sample'>Location of a CSV sample file or a string containing a sample CSV document.</param> <param name='Separators'>Column delimiter(s). Defaults to <c>,</c>.</param> <param name='InferRows'>Number of rows to use for inference. Defaults to <c>1000</c>. If this is zero, all rows are used.</param> <param name='Schema'>Optional column types, in a comma separated list. Valid types are <c>int</c>, <c>int64</c>, <c>bool</c>, <c>float</c>, <c>decimal</c>, <c>date</c>, <c>datetimeoffset</c>, <c>timespan</c>, <c>guid</c>, <c>string</c>, <c>int?</c>, <c>int64?</c>, <c>bool?</c>, <c>float?</c>, <c>decimal?</c>, <c>date?</c>, <c>datetimeoffset?</c>, <c>timespan?</c>, <c>guid?</c>, <c>int option</c>, <c>int64 option</c>, <c>bool option</c>, <c>float option</c>, <c>decimal option</c>, <c>date option</c>, <c>datetimeoffset option</c>, <c>timespan option</c>, <c>guid option</c> and <c>string option</c>. You can also specify a unit and the name of the column like this: <c>Name (type&lt;unit&gt;)</c>, or you can override only the name. If you don't want to specify all the columns, you can reference the columns by name like this: <c>ColumnName=type</c>.</param> <param name='HasHeaders'>Whether the sample contains the names of the columns as its first line.</param> <param name='IgnoreErrors'>Whether to ignore rows that have the wrong number of columns or which can't be parsed using the inferred or specified schema. Otherwise an exception is thrown when these rows are encountered.</param> <param name='SkipRows'>Skips the first n rows of the CSV file.</param> <param name='AssumeMissingValues'>When set to true, the type provider will assume all columns can have missing values, even if in the provided sample all values are present. Defaults to false.</param> <param name='PreferOptionals'>When set to true, inference will prefer to use the option type instead of nullable types, <c>double.NaN</c> or <c>""</c> for missing values. Defaults to false.</param> <param name='Quote'>The quotation mark (for surrounding values containing the delimiter). Defaults to <c>"</c>.</param> <param name='MissingValues'>The set of strings recognized as missing values specified as a comma-separated string (e.g., "NA,N/A"). Defaults to <c>NaN,NA,N/A,#N/A,:,-,TBA,TBD</c>.</param> <param name='CacheRows'>Whether the rows should be caches so they can be iterated multiple times. Defaults to true. Disable for large datasets.</param> <param name='Culture'>The culture used for parsing numbers and dates. Defaults to the invariant culture.</param> <param name='Encoding'>The encoding used to read the sample. You can specify either the character set name or the codepage number. Defaults to UTF8 for files, and to ISO-8859-1 the for HTTP requests, unless <c>charset</c> is specified in the <c>Content-Type</c> response header.</param> <param name='ResolutionFolder'>A directory that is used when resolving relative file references (at design time and in hosted execution).</param> <param name='EmbeddedResource'>When specified, the type provider first attempts to load the sample from the specified resource (e.g. 'MyCompany.MyAssembly, resource_name.csv'). This is useful when exposing types generated by the type provider.</param>
type TiingoRequest = { Symbol: string Start: DateTime End: DateTime }
type TiingoObs = { Date: DateTime Close: decimal High: decimal Low: decimal Open: decimal Volume: int AdjClose: decimal AdjHigh: decimal AdjLow: decimal AdjOpen: decimal ... }
Multiple items
val decimal: value: 'T -> decimal (requires member op_Explicit)

--------------------
type decimal = Decimal

--------------------
type decimal<'Measure> = decimal
Multiple items
val int: value: 'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
val request: symbol: string -> TiingoRequest
<summary>Constructs a Tiingo request. By default is to get the past year of data.</summary>
 <param name="symbol">The ticker symbol such as "AAPL","MSFT" etc.</param>
val symbol: string
property DateTime.Now: DateTime with get
<summary>Gets a <see cref="T:System.DateTime" /> object that is set to the current date and time on this computer, expressed as the local time.</summary>
<returns>An object whose value is the current local date and time.</returns>
DateTime.AddYears(value: int) : DateTime
val startOn: startOn: DateTime -> request: TiingoRequest -> TiingoRequest
<summary>Sets the Tiingo request start date.</summary>
 <param name="startOn">Request start date</param>
 <param name="request">The Tiingo request to update.</param>
val startOn: DateTime
val request: TiingoRequest
val endOn: endOn: DateTime -> request: TiingoRequest -> TiingoRequest
<summary>Sets the Tiingo request end date.</summary>
 <param name="endOn">Request start date</param>
 <param name="request">The Tiingo request to update.</param>
val endOn: DateTime
val private cache: Runtime.Caching.ICache<string,string>
Multiple items
namespace FSharp.Data.Runtime

--------------------
namespace System.Runtime
module Caching from FSharp.Data.Runtime
<summary> Implements caching using in-memory and local file system </summary>
val createInMemoryCache: expiration: TimeSpan -> Runtime.Caching.ICache<'TKey_,'TValue>
<summary> Creates a cache that uses in-memory collection </summary>
Multiple items
[<Struct>] type TimeSpan = new: hours: int * minutes: int * seconds: int -> unit + 4 overloads member Add: ts: TimeSpan -> TimeSpan member CompareTo: value: obj -> int + 1 overload member Divide: divisor: float -> TimeSpan + 1 overload member Duration: unit -> TimeSpan member Equals: value: obj -> bool + 2 overloads member GetHashCode: unit -> int member Multiply: factor: float -> TimeSpan member Negate: unit -> TimeSpan member Subtract: ts: TimeSpan -> TimeSpan ...
<summary>Represents a time interval.</summary>

--------------------
TimeSpan ()
TimeSpan(ticks: int64) : TimeSpan
TimeSpan(hours: int, minutes: int, seconds: int) : TimeSpan
TimeSpan(days: int, hours: int, minutes: int, seconds: int) : TimeSpan
TimeSpan(days: int, hours: int, minutes: int, seconds: int, milliseconds: int) : TimeSpan
TimeSpan(days: int, hours: int, minutes: int, seconds: int, milliseconds: int, microseconds: int) : TimeSpan
val get: request: TiingoRequest -> TiingoObs array
<summary>Downloads Tiingo data.</summary>
 <param name="request">The Tiingo request to download.</param>
val dtStr: x: DateTime -> string
val x: DateTime
property DateTime.Date: DateTime with get
<summary>Gets the date component of this instance.</summary>
<returns>A new object with the same date as this instance, and the time value set to 12:00:00 midnight (00:00:00).</returns>
DateTime.ToString() : string
DateTime.ToString(format: string) : string
DateTime.ToString(provider: IFormatProvider) : string
DateTime.ToString(format: string, provider: IFormatProvider) : string
TiingoRequest.Start: DateTime
TiingoRequest.End: DateTime
val key: string
TiingoRequest.Symbol: string
abstract Runtime.Caching.ICache.TryRetrieve: key: 'TKey * ?extendCacheExpiration: bool -> 'TValue option
union case Option.Some: Value: 'T -> Option<'T>
val res: string
union case Option.None: Option<'T>
val result: string
type Http = static member AsyncRequest: url: string * [<Optional>] ?query: (string * string) list * [<Optional>] ?headers: (string * string) seq * [<Optional>] ?httpMethod: string * [<Optional>] ?body: HttpRequestBody * [<Optional>] ?cookies: (string * string) seq * [<Optional>] ?cookieContainer: CookieContainer * [<Optional>] ?silentHttpErrors: bool * [<Optional>] ?silentCookieErrors: bool * [<Optional>] ?responseEncodingOverride: string * [<Optional>] ?customizeHttpRequest: (HttpWebRequest -> HttpWebRequest) * [<Optional>] ?timeout: int -> Async<HttpResponse> static member AsyncRequestStream: url: string * [<Optional>] ?query: (string * string) list * [<Optional>] ?headers: (string * string) seq * [<Optional>] ?httpMethod: string * [<Optional>] ?body: HttpRequestBody * [<Optional>] ?cookies: (string * string) seq * [<Optional>] ?cookieContainer: CookieContainer * [<Optional>] ?silentHttpErrors: bool * [<Optional>] ?silentCookieErrors: bool * [<Optional>] ?customizeHttpRequest: (HttpWebRequest -> HttpWebRequest) * [<Optional>] ?timeout: int -> Async<HttpResponseWithStream> static member AsyncRequestString: url: string * [<Optional>] ?query: (string * string) list * [<Optional>] ?headers: (string * string) seq * [<Optional>] ?httpMethod: string * [<Optional>] ?body: HttpRequestBody * [<Optional>] ?cookies: (string * string) seq * [<Optional>] ?cookieContainer: CookieContainer * [<Optional>] ?silentHttpErrors: bool * [<Optional>] ?silentCookieErrors: bool * [<Optional>] ?responseEncodingOverride: string * [<Optional>] ?customizeHttpRequest: (HttpWebRequest -> HttpWebRequest) * [<Optional>] ?timeout: int -> Async<string> static member Request: url: string * [<Optional>] ?query: (string * string) list * [<Optional>] ?headers: (string * string) seq * [<Optional>] ?httpMethod: string * [<Optional>] ?body: HttpRequestBody * [<Optional>] ?cookies: (string * string) seq * [<Optional>] ?cookieContainer: CookieContainer * [<Optional>] ?silentHttpErrors: bool * [<Optional>] ?silentCookieErrors: bool * [<Optional>] ?responseEncodingOverride: string * [<Optional>] ?customizeHttpRequest: (HttpWebRequest -> HttpWebRequest) * [<Optional>] ?timeout: int -> HttpResponse static member RequestStream: url: string * [<Optional>] ?query: (string * string) list * [<Optional>] ?headers: (string * string) seq * [<Optional>] ?httpMethod: string * [<Optional>] ?body: HttpRequestBody * [<Optional>] ?cookies: (string * string) seq * [<Optional>] ?cookieContainer: CookieContainer * [<Optional>] ?silentHttpErrors: bool * [<Optional>] ?silentCookieErrors: bool * [<Optional>] ?customizeHttpRequest: (HttpWebRequest -> HttpWebRequest) * [<Optional>] ?timeout: int -> HttpResponseWithStream static member RequestString: url: string * [<Optional>] ?query: (string * string) list * [<Optional>] ?headers: (string * string) seq * [<Optional>] ?httpMethod: string * [<Optional>] ?body: HttpRequestBody * [<Optional>] ?cookies: (string * string) seq * [<Optional>] ?cookieContainer: CookieContainer * [<Optional>] ?silentHttpErrors: bool * [<Optional>] ?silentCookieErrors: bool * [<Optional>] ?responseEncodingOverride: string * [<Optional>] ?customizeHttpRequest: (HttpWebRequest -> HttpWebRequest) * [<Optional>] ?timeout: int -> string
<summary> Utilities for working with network via HTTP. Includes methods for downloading resources with specified headers, query parameters and HTTP body </summary>
static member Http.RequestString: url: string * [<Runtime.InteropServices.Optional>] ?query: (string * string) list * [<Runtime.InteropServices.Optional>] ?headers: (string * string) seq * [<Runtime.InteropServices.Optional>] ?httpMethod: string * [<Runtime.InteropServices.Optional>] ?body: HttpRequestBody * [<Runtime.InteropServices.Optional>] ?cookies: (string * string) seq * [<Runtime.InteropServices.Optional>] ?cookieContainer: Net.CookieContainer * [<Runtime.InteropServices.Optional>] ?silentHttpErrors: bool * [<Runtime.InteropServices.Optional>] ?silentCookieErrors: bool * [<Runtime.InteropServices.Optional>] ?responseEncodingOverride: string * [<Runtime.InteropServices.Optional>] ?customizeHttpRequest: (Net.HttpWebRequest -> Net.HttpWebRequest) * [<Runtime.InteropServices.Optional>] ?timeout: int -> string
val query: Linq.QueryBuilder
module Secrets from Common
module HttpRequestHeaders from FSharp.Data
<summary> Headers that can be sent in an HTTP request </summary>
val Accept: contentType: string -> string * string
<summary> Content-Types that are acceptable for the response </summary>
module HttpContentTypes from FSharp.Data
<summary> Constants for common HTTP content types </summary>
[<Literal>] val Csv: string = "text/csv"
<summary> text/csv </summary>
abstract Runtime.Caching.ICache.Set: key: 'TKey * value: 'TValue -> unit
CsvProvider<...>.Parse(text: string) : CsvProvider<...>
Parses the specified CSV string
val parsed: CsvProvider<...>
property Runtime.CsvFile.Rows: CsvProvider<...>.Row seq with get
<summary> The rows with data </summary>
module Seq from Microsoft.FSharp.Collections
val map: mapping: ('T -> 'U) -> source: 'T seq -> 'U seq
val row: CsvProvider<...>.Row
property CsvProvider<...>.Row.Date: DateTime with get
property CsvProvider<...>.Row.Close: decimal with get
property CsvProvider<...>.Row.High: decimal with get
property CsvProvider<...>.Row.Low: decimal with get
property CsvProvider<...>.Row.Open: decimal with get
property CsvProvider<...>.Row.Volume: int with get
property CsvProvider<...>.Row.AdjClose: decimal with get
property CsvProvider<...>.Row.AdjHigh: decimal with get
property CsvProvider<...>.Row.AdjLow: decimal with get
property CsvProvider<...>.Row.AdjOpen: decimal with get
property CsvProvider<...>.Row.AdjVolume: decimal with get
property CsvProvider<...>.Row.DivCash: decimal with get
property CsvProvider<...>.Row.SplitFactor: decimal with get
val toArray: source: 'T seq -> 'T array
Multiple items
type private Download = class end

--------------------
private new: symbol: string * ?startOn: DateTime * ?endOn: DateTime -> Download
val startOn: DateTime option
val endOn: DateTime option
val defaultArg: arg: 'T option -> defaultValue: 'T -> 'T
val data: TiingoObs array
val this: Download
val private getFromCacheDirectory: cacheDirectory: string -> request: TiingoRequest -> CsvProvider<...>
val cacheDirectory: string
val cacheFile: string
File.WriteAllText(path: string, contents: string) : unit
File.WriteAllText(path: string, contents: string, encoding: Text.Encoding) : unit
val private returnHelper: symbol: string -> xs: TiingoObs seq -> ReturnObs array
val xs: TiingoObs seq
Multiple items
val seq: sequence: 'T seq -> 'T seq

--------------------
type 'T seq = Collections.Generic.IEnumerable<'T>
val sortBy: projection: ('T -> 'Key) -> source: 'T seq -> 'T seq (requires comparison)
val x: TiingoObs
TiingoObs.Date: DateTime
val pairwise: source: 'T seq -> ('T * 'T) seq
val yesterday: TiingoObs
val today: TiingoObs
TiingoObs.AdjClose: decimal
val getReturns: request: TiingoRequest -> ReturnObs array
val private getInternetFileCache: request: TiingoRequest -> CsvProvider<...>
val cache: Runtime.Caching.ICache<string,string>
val createInternetFileCache: prefix: string -> expiration: TimeSpan -> Runtime.Caching.ICache<string,string>
<summary> Creates a cache that stores data in a local file system </summary>
TimeSpan.FromDays(value: float) : TimeSpan
Object.ToString() : string
namespace System.IO.Compression
type private FF3Csv = CsvProvider<...>
type FF3Obs = { Date: DateTime MktRf: float Smb: float Hml: float Rf: float Frequency: Frequency }
type private FF5Csv = CsvProvider<...>
type FF5Obs = { Date: DateTime MktRf: float Smb: float Hml: float Rmw: float Cma: float Rf: float Frequency: Frequency }
val private frenchDay: x: string -> DateTime
val x: string
DateTime.ParseExact(s: string, format: string, provider: IFormatProvider) : DateTime
DateTime.ParseExact(s: string, formats: string array, provider: IFormatProvider, style: Globalization.DateTimeStyles) : DateTime
DateTime.ParseExact(s: string, format: string, provider: IFormatProvider, style: Globalization.DateTimeStyles) : DateTime
DateTime.ParseExact(s: ReadOnlySpan<char>, formats: string array, provider: IFormatProvider, ?style: Globalization.DateTimeStyles) : DateTime
DateTime.ParseExact(s: ReadOnlySpan<char>, format: ReadOnlySpan<char>, provider: IFormatProvider, ?style: Globalization.DateTimeStyles) : DateTime
namespace System.Globalization
Multiple items
type CultureInfo = interface ICloneable interface IFormatProvider new: culture: int -> unit + 3 overloads member ClearCachedData: unit -> unit member Clone: unit -> obj member Equals: value: obj -> bool member GetConsoleFallbackUICulture: unit -> CultureInfo member GetFormat: formatType: Type -> obj member GetHashCode: unit -> int member ToString: unit -> string ...
<summary>Provides information about a specific culture (called a locale for unmanaged code development). The information includes the names for the culture, the writing system, the calendar used, the sort order of strings, and formatting for dates and numbers.</summary>

--------------------
Globalization.CultureInfo(culture: int) : Globalization.CultureInfo
Globalization.CultureInfo(name: string) : Globalization.CultureInfo
Globalization.CultureInfo(culture: int, useUserOverride: bool) : Globalization.CultureInfo
Globalization.CultureInfo(name: string, useUserOverride: bool) : Globalization.CultureInfo
property Globalization.CultureInfo.InvariantCulture: Globalization.CultureInfo with get
<summary>Gets the <see cref="T:System.Globalization.CultureInfo" /> object that is culture-independent (invariant).</summary>
<returns>The object that is culture-independent (invariant).</returns>
val private frenchMonth: x: string -> DateTime
val today: DateTime
val nextMonth: DateTime
DateTime.AddMonths(months: int) : DateTime
val eom: DateTime
property DateTime.Year: int with get
<summary>Gets the year component of the date represented by this instance.</summary>
<returns>The year, between 1 and 9999.</returns>
property DateTime.Month: int with get
<summary>Gets the month component of the date represented by this instance.</summary>
<returns>The month component, expressed as a value between 1 and 12.</returns>
val private getData: dataset: string -> string
val dataset: string
val data: string
val urlString: string
val request: HttpResponseWithStream
static member Http.RequestStream: url: string * [<Runtime.InteropServices.Optional>] ?query: (string * string) list * [<Runtime.InteropServices.Optional>] ?headers: (string * string) seq * [<Runtime.InteropServices.Optional>] ?httpMethod: string * [<Runtime.InteropServices.Optional>] ?body: HttpRequestBody * [<Runtime.InteropServices.Optional>] ?cookies: (string * string) seq * [<Runtime.InteropServices.Optional>] ?cookieContainer: Net.CookieContainer * [<Runtime.InteropServices.Optional>] ?silentHttpErrors: bool * [<Runtime.InteropServices.Optional>] ?silentCookieErrors: bool * [<Runtime.InteropServices.Optional>] ?customizeHttpRequest: (Net.HttpWebRequest -> Net.HttpWebRequest) * [<Runtime.InteropServices.Optional>] ?timeout: int -> HttpResponseWithStream
[<Literal>] val Any: string = "*/*"
<summary> */* </summary>
val archive: ZipArchive
Multiple items
type ZipArchive = interface IDisposable new: stream: Stream -> unit + 3 overloads member CreateEntry: entryName: string -> ZipArchiveEntry + 1 overload member Dispose: unit -> unit member GetEntry: entryName: string -> ZipArchiveEntry member Comment: string member Entries: ReadOnlyCollection<ZipArchiveEntry> member Mode: ZipArchiveMode
<summary>Represents a package of compressed files in the zip archive format.</summary>

--------------------
ZipArchive(stream: Stream) : ZipArchive
ZipArchive(stream: Stream, mode: ZipArchiveMode) : ZipArchive
ZipArchive(stream: Stream, mode: ZipArchiveMode, leaveOpen: bool) : ZipArchive
ZipArchive(stream: Stream, mode: ZipArchiveMode, leaveOpen: bool, entryNameEncoding: Text.Encoding) : ZipArchive
HttpResponseWithStream.ResponseStream: Stream
[<Struct>] type ZipArchiveMode = | Read = 0 | Create = 1 | Update = 2
<summary>Specifies values for interacting with zip archive entries.</summary>
field ZipArchiveMode.Read: ZipArchiveMode = 0
<summary>Only reading archive entries is permitted.</summary>
val file: ZipArchiveEntry
ZipArchive.GetEntry(entryName: string) : ZipArchiveEntry
String.Replace(oldValue: string, newValue: string) : string
String.Replace(oldChar: char, newChar: char) : string
String.Replace(oldValue: string, newValue: string, comparisonType: StringComparison) : string
String.Replace(oldValue: string, newValue: string, ignoreCase: bool, culture: Globalization.CultureInfo) : string
val reader: StreamReader
Multiple items
type StreamReader = inherit TextReader new: stream: Stream -> unit + 12 overloads member Close: unit -> unit member DiscardBufferedData: unit -> unit member Peek: unit -> int member Read: unit -> int + 2 overloads member ReadAsync: buffer: char array * index: int * count: int -> Task<int> + 1 overload member ReadBlock: buffer: char array * index: int * count: int -> int + 1 overload member ReadBlockAsync: buffer: char array * index: int * count: int -> Task<int> + 1 overload member ReadLine: unit -> string ...
<summary>Implements a <see cref="T:System.IO.TextReader" /> that reads characters from a byte stream in a particular encoding.</summary>

--------------------
StreamReader(stream: Stream) : StreamReader
   (+0 other overloads)
StreamReader(path: string) : StreamReader
   (+0 other overloads)
StreamReader(stream: Stream, detectEncodingFromByteOrderMarks: bool) : StreamReader
   (+0 other overloads)
StreamReader(stream: Stream, encoding: Text.Encoding) : StreamReader
   (+0 other overloads)
StreamReader(path: string, detectEncodingFromByteOrderMarks: bool) : StreamReader
   (+0 other overloads)
StreamReader(path: string, options: FileStreamOptions) : StreamReader
   (+0 other overloads)
StreamReader(path: string, encoding: Text.Encoding) : StreamReader
   (+0 other overloads)
StreamReader(stream: Stream, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool) : StreamReader
   (+0 other overloads)
StreamReader(path: string, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool) : StreamReader
   (+0 other overloads)
StreamReader(stream: Stream, encoding: Text.Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int) : StreamReader
   (+0 other overloads)
ZipArchiveEntry.Open() : Stream
StreamReader.ReadToEnd() : string
val getFF3: frequency: Frequency -> FF3Obs array
val frequency: Frequency
val dateParser: (string -> DateTime)
union case Frequency.Monthly: Frequency
union case Frequency.Daily: Frequency
val data: StringReader
Multiple items
type StringReader = inherit TextReader new: s: string -> unit member Close: unit -> unit member Peek: unit -> int member Read: unit -> int + 2 overloads member ReadAsync: buffer: char array * index: int * count: int -> Task<int> + 1 overload member ReadBlock: buffer: Span<char> -> int member ReadBlockAsync: buffer: char array * index: int * count: int -> Task<int> + 1 overload member ReadLine: unit -> string member ReadLineAsync: unit -> Task<string> + 1 overload ...
<summary>Implements a <see cref="T:System.IO.TextReader" /> that reads from a string.</summary>

--------------------
StringReader(s: string) : StringReader
StringReader.Peek() : int
StringReader.ReadLine() : string
type Array = interface ICollection interface IEnumerable interface IList interface IStructuralComparable interface IStructuralEquatable interface ICloneable member Clone: unit -> obj member CopyTo: array: Array * index: int -> unit + 1 overload member GetEnumerator: unit -> IEnumerator member GetLength: dimension: int -> int ...
<summary>Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the base class for all arrays in the common language runtime.</summary>
val skipWhile: predicate: ('T -> bool) -> array: 'T array -> 'T array
val line: string
String.Contains(value: string) : bool
String.Contains(value: char) : bool
String.Contains(value: string, comparisonType: StringComparison) : bool
String.Contains(value: char, comparisonType: StringComparison) : bool
val skip: count: int -> array: 'T array -> 'T array
val takeWhile: predicate: ('T -> bool) -> array: 'T array -> 'T array
val map: mapping: ('T -> 'U) -> array: 'T array -> 'U array
val parsedLine: CsvProvider<...>.Row
CsvProvider<...>.ParseRows(text: string) : CsvProvider<...>.Row array
property CsvProvider<...>.Row.Date: string with get
property CsvProvider<...>.Row.SMB: decimal with get
property CsvProvider<...>.Row.HML: decimal with get
property CsvProvider<...>.Row.RF: decimal with get
val getFF5: frequency: Frequency -> FF5Obs array
property CsvProvider<...>.Row.RMW: decimal with get
property CsvProvider<...>.Row.CMA: decimal with get
module Fred from Common
type Series = CsvProvider<...>
val private fredUrl: series: 'a -> string
val series: 'a
val get: series: string -> CsvProvider<...>
<summary>Gets a FRED data series as a CsvProvider</summary>
 <param name="series">The series name such as GS10, EXUSEU, etc.</param>
val series: string
CsvProvider<...>.Load(uri: string) : CsvProvider<...>
Loads CSV from the specified uri
CsvProvider<...>.Load(reader: TextReader) : CsvProvider<...>
Loads CSV from the specified reader
CsvProvider<...>.Load(stream: Stream) : CsvProvider<...>
Loads CSV from the specified stream

Type something to start searching.