module Portfolio
open System
/// Misc
///
type SecurityId =
| Ticker of string
| Cusip of string
| Bloomberg of string
| Permno of int
| Other of string
type InvestmentUniverse =
{ FormationMonth : DateTime
Securities : SecurityId list }
type SecuritySignal =
{ SecurityId : SecurityId
Signal : float }
type SecuritiesWithSignals =
{ FormationMonth : DateTime
Signals : SecuritySignal list }
type PortfolioId =
| Named of string
| Indexed of {| Name: string; Index: int |}
override this.ToString() =
match this with
| Named name -> name
| Indexed p -> $"{p.Name}: {p.Index}"
type AssignedPortfolio =
{ PortfolioId : PortfolioId
FormationMonth : DateTime
Signals : SecuritySignal list }
let assignSignalSort name n (xs: SecuritiesWithSignals) =
xs.Signals
|> List.sortBy(fun x -> x.Signal)
|> List.splitInto n
|> List.mapi(fun i ys ->
// because lists are 0-indexed and I want the minimum
// portfolio index to be 1, I'm doing index = i+1.
{ PortfolioId = Indexed {| Name = name; Index=i+1 |}
FormationMonth = xs.FormationMonth
Signals = ys })
type Position =
{ SecurityId : SecurityId
Weight : float }
type Portfolio =
{ PortfolioId: PortfolioId
FormationMonth : DateTime
Positions : Position list }
type PortfolioReturn =
{ PortfolioId: PortfolioId
YearMonth : DateTime
Return : float }
// This type alias defines the type of a function that has
// a tuple input of SecurityId * YearMonth and outputs
// a (SecurityId * float) Option. Think of it like
// using types to write documentation of the functions.
type GetsMarketCaps = SecurityId * DateTime -> (SecurityId * float) Option
// Defining this type alias makes it easier to read the type of the function that I want for
// marketCapGetter in the function that I have below. Otherwise it might look something like
// let giveValueWeights (marketCapGetter: (SecurityId * YearMonth -> (SecurityId * float) Option) ...
// which is the same thing but not as clear what we're trying to do.
let giveValueWeights (marketCapGetter: GetsMarketCaps) (x: AssignedPortfolio) =
let mktCaps =
x.Signals
// List.choose throws away None results, so this means
// that if the market cap getter returns None
// then we will not have that security in our portfolio.
|> List.choose(fun signal -> marketCapGetter (signal.SecurityId, x.FormationMonth))
let totMktCap = mktCaps |> List.sumBy snd
let pos =
mktCaps
|> List.map(fun (id, mktCap) ->
{ SecurityId = id
Weight = mktCap / totMktCap })
{ PortfolioId = x.PortfolioId
FormationMonth = x.FormationMonth
Positions = pos }
// This type alias defines the type of a function that has
// a tuple input of SecurityId * YearMonth and outputs
// a (SecurityId * float). Think of it like
// using types to write documentation of the functions.
type GetsReturn = SecurityId * DateTime -> (SecurityId * float)
// Defining this type alias makes it easier to read the type of the function that I want for
// marketCapGetter in the function that I have below. Otherwise it might look something like
// let giveValueWeights (marketCapGetter: (SecurityId * YearMonth -> (SecurityId * float) Option) ...
// which is the same thing but not as clear what we're trying to do.
let getPortfolioReturn (returnGetter: GetsReturn) (x: Portfolio) =
let returnMonth = x.FormationMonth.AddMonths(1)
let portRet =
x.Positions
|> List.sumBy(fun pos ->
let (_id, ret) = returnGetter (pos.SecurityId, returnMonth)
pos.Weight * ret)
{ PortfolioId = x.PortfolioId
YearMonth = returnMonth
Return = portRet }
/// This function takes a sample start and sample end
/// and returns a list with all months from start to end.
/// Don't worry about understanding what this function does.
/// The details are beyond the scope of the class, but if you're
/// curious it's a recursive function:
/// https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/functions/recursive-functions-the-rec-keyword
let getSampleMonths (sampleStart:DateTime, sampleEnd:DateTime) =
let sampleStart = DateTime(sampleStart.Year, sampleStart.Month,1)
let sampleEnd = DateTime(sampleEnd.Year, sampleEnd.Month,1)
if sampleEnd <= sampleStart then failwith "sampleEnd should be after sampleStart"
let rec loop (sampleEnd:DateTime) window =
match window with
| [] -> failwith "Need a starting point"
| lastMonth::_monthsBeforeThat ->
if lastMonth < sampleEnd then
loop sampleEnd (lastMonth.AddMonths(1)::window)
else window
loop sampleEnd [sampleStart]
|> List.rev
type Portfolio =
{
PortfolioId: PortfolioId
FormationMonth: DateTime
Positions: Position list
}
namespace System
type SecurityId =
| Ticker of string
| Cusip of string
| Bloomberg of string
| Permno of int
| Other of string
Misc
Misc
Multiple items
val string: value: 'T -> string
--------------------
type string = String
val string: value: 'T -> string
--------------------
type string = String
Multiple items
val int: value: 'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
val int: value: 'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
type InvestmentUniverse =
{
FormationMonth: DateTime
Securities: SecurityId list
}
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)
[<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)
type 'T list = List<'T>
type SecuritySignal =
{
SecurityId: SecurityId
Signal: float
}
Multiple items
val float: value: 'T -> float (requires member op_Explicit)
--------------------
type float = Double
--------------------
type float<'Measure> = float
val float: value: 'T -> float (requires member op_Explicit)
--------------------
type float = Double
--------------------
type float<'Measure> = float
type SecuritiesWithSignals =
{
FormationMonth: DateTime
Signals: SecuritySignal list
}
Multiple items
[<Struct>] type Index = new: value: int * ?fromEnd: bool -> unit member Equals: other: Index -> bool + 1 overload member GetHashCode: unit -> int member GetOffset: length: int -> int member ToString: unit -> string static member FromEnd: value: int -> Index static member FromStart: value: int -> Index static member op_Implicit: value: int -> Index member IsFromEnd: bool member Value: int ...
<summary>Represents a type that can be used to index a collection either from the beginning or the end.</summary>
--------------------
Index ()
Index(value: int, ?fromEnd: bool) : Index
[<Struct>] type Index = new: value: int * ?fromEnd: bool -> unit member Equals: other: Index -> bool + 1 overload member GetHashCode: unit -> int member GetOffset: length: int -> int member ToString: unit -> string static member FromEnd: value: int -> Index static member FromStart: value: int -> Index static member op_Implicit: value: int -> Index member IsFromEnd: bool member Value: int ...
<summary>Represents a type that can be used to index a collection either from the beginning or the end.</summary>
--------------------
Index ()
Index(value: int, ?fromEnd: bool) : Index
val this: PortfolioId
union case PortfolioId.Named: string -> PortfolioId
val name: string
union case PortfolioId.Indexed: {| Index: int; Name: string |} -> PortfolioId
val p: {| Index: int; Name: string |}
anonymous record field Name: string
type AssignedPortfolio =
{
PortfolioId: PortfolioId
FormationMonth: DateTime
Signals: SecuritySignal list
}
type PortfolioId =
| Named of string
| Indexed of {| Index: int; Name: string |}
override ToString: unit -> string
val assignSignalSort: name: string -> n: int -> xs: SecuritiesWithSignals -> AssignedPortfolio list
val n: int
val xs: SecuritiesWithSignals
SecuritiesWithSignals.Signals: SecuritySignal list
Multiple items
module List from Microsoft.FSharp.Collections
--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
module List from Microsoft.FSharp.Collections
--------------------
type List<'T> = | op_Nil | op_ColonColon of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex: rank: int * offset: int -> int member GetSlice: startIndex: int option * endIndex: int option -> 'T list static member Cons: head: 'T * tail: 'T list -> 'T list member Head: 'T member IsEmpty: bool member Item: index: int -> 'T with get ...
val sortBy: projection: ('T -> 'Key) -> list: 'T list -> 'T list (requires comparison)
val x: SecuritySignal
SecuritySignal.Signal: float
val splitInto: count: int -> list: 'T list -> 'T list list
val mapi: mapping: (int -> 'T -> 'U) -> list: 'T list -> 'U list
val i: int
val ys: SecuritySignal list
SecuritiesWithSignals.FormationMonth: DateTime
type Position =
{
SecurityId: SecurityId
Weight: float
}
type PortfolioReturn =
{
PortfolioId: PortfolioId
YearMonth: DateTime
Return: float
}
type GetsMarketCaps = SecurityId * DateTime -> Option<SecurityId * float>
module Option
from Microsoft.FSharp.Core
val giveValueWeights: marketCapGetter: GetsMarketCaps -> x: AssignedPortfolio -> Portfolio
val marketCapGetter: GetsMarketCaps
val x: AssignedPortfolio
val mktCaps: (SecurityId * float) list
AssignedPortfolio.Signals: SecuritySignal list
val choose: chooser: ('T -> 'U option) -> list: 'T list -> 'U list
val signal: SecuritySignal
SecuritySignal.SecurityId: SecurityId
AssignedPortfolio.FormationMonth: DateTime
val totMktCap: float
val sumBy: projection: ('T -> 'U) -> list: 'T list -> 'U (requires member (+) and member Zero)
val snd: tuple: ('T1 * 'T2) -> 'T2
val pos: Position list
val map: mapping: ('T -> 'U) -> list: 'T list -> 'U list
val id: SecurityId
val mktCap: float
AssignedPortfolio.PortfolioId: PortfolioId
type GetsReturn = SecurityId * DateTime -> SecurityId * float
val getPortfolioReturn: returnGetter: GetsReturn -> x: Portfolio -> PortfolioReturn
val returnGetter: GetsReturn
val x: Portfolio
val returnMonth: DateTime
Portfolio.FormationMonth: DateTime
DateTime.AddMonths(months: int) : DateTime
val portRet: float
Portfolio.Positions: Position list
val pos: Position
val _id: SecurityId
val ret: float
Position.SecurityId: SecurityId
Position.Weight: float
Portfolio.PortfolioId: PortfolioId
val getSampleMonths: sampleStart: DateTime * sampleEnd: DateTime -> DateTime list
This function takes a sample start and sample end
and returns a list with all months from start to end.
Don't worry about understanding what this function does.
The details are beyond the scope of the class, but if you're
curious it's a recursive function:
https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/functions/recursive-functions-the-rec-keyword
This function takes a sample start and sample end
and returns a list with all months from start to end.
Don't worry about understanding what this function does.
The details are beyond the scope of the class, but if you're
curious it's a recursive function:
https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/functions/recursive-functions-the-rec-keyword
val sampleStart: DateTime
val sampleEnd: 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>
<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>
<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 failwith: message: string -> 'T
val loop: sampleEnd: DateTime -> window: DateTime list -> DateTime list
val window: DateTime list
val lastMonth: DateTime
val _monthsBeforeThat: DateTime list
val rev: list: 'T list -> 'T list