提问人:Gonçalo Franchini 提问时间:6/12/2023 最后编辑:Gonçalo Franchini 更新时间:6/14/2023 访问量:98
如何从 F 中的元组数组计算累积股票回报#
How to calculate cumulative stock returns from an array of tuples in F#
问:
我正在尝试从元组数组中计算每周股票回报时间序列的累积回报 - 其中第一个元素是一个对象,第二个元素是相应的每周回报 - 并绘制它。然而,我的追求没有成功。这是我的代码示例:DateTime
float
#r "nuget: FSharp.Data"
#r "nuget: Plotly.NET, 4.0.0"
open System
open System.IO
open FSharp.Data
open Plotly.NET
let [<Literal>] sampleFileFullPath = "file_containing_returns.csv"
type stockData = CsvProvider<sampleFileFullPath>
let stockDataCSV = stockData.GetSample()
let calcReturn (pv : float, fv : float) = (fv / pv) - 1.0
let returns (s : stockData) (path : string) =
let dateTimeFormat = "dd/mm/yyyy"
let sequence =
s.Rows
|> Seq.map(fun x -> System.DateTime.Parse(x.Date), calcReturn(float x.AdjClose, float x.Open))
let array =
sequence
|> Seq.toArray |> Array.map snd
printfn "%A" array
正如你在上面看到的,我试图提取(股票回报)的第二个元素。虽然我随后设法获得了时间序列长度内的累积回报总和,但我无法保留相应的 .删除最后一个管道操作将使该函数产生以下输出:tuple
DateTime
[|(01/01/2000 00:00:00, 0.2368421053); (08/01/2000 00:00:00, 0.1973684211);
(15/01/2000 00:00:00, 0.07142857143); (22/01/2000 00:00:00, 0.2597402597);
(29/01/2000 00:00:00, 0.09756097561); (05/02/2000 00:00:00, 0.156626506);
(12/02/2000 00:00:00, 0.1666666667); (19/02/2000 00:00:00, 0.1666666667);
(26/02/2000 00:00:00, 0.01030927835); (04/03/2000 00:00:00, 0.1894736842);
...|]
任何帮助将不胜感激。
感谢您抽出宝贵时间接受采访!
编辑
(工作)示例数据如下所示:
Date, Open , High , Low , Close , AdjClose , Volume
01/01/2000,0.94,1.00,0.85,0.89,0.76,3055203200.00
08/01/2000,0.91,0.91,0.77,0.90,0.76,3345742400.00
15/01/2000,0.90,1.08,0.90,0.99,0.84,3383878400.00
22/01/2000,0.97,1.02,0.90,0.91,0.77,2068673600.00
29/01/2000,0.90,0.98,0.84,0.96,0.82,2384424000.00
05/02/2000,0.96,1.05,0.95,0.97,0.83,1664308800.00
12/02/2000,0.98,1.07,0.97,0.99,0.84,1754468800.00
19/02/2000,0.98,1.06,0.95,0.99,0.84,1520971200.00
26/02/2000,0.98,1.18,0.97,1.14,0.97,2408918400.00
04/03/2000,1.13,1.15,1.06,1.12,0.95,1280126400.00
11/03/2000,1.09,1.13,1.02,1.12,0.95,1859289600.00
18/03/2000,1.10,1.34,1.09,1.24,1.05,2306292800.00
25/03/2000,1.23,1.29,1.12,1.21,1.03,1541019200.00
01/04/2000,1.21,1.25,1.04,1.18,1.00,1948620800.00
08/04/2000,1.18,1.19,0.94,1.00,0.85,2892668800.00
15/04/2000,0.98,1.16,0.97,1.06,0.90,2042756800.00
22/04/2000,1.03,1.15,1.02,1.11,0.94,1778358400.00
29/04/2000,1.11,1.13,0.99,1.01,0.86,1636017600.00
06/05/2000,1.00,1.02,0.88,0.96,0.82,1853790400.00
13/05/2000,0.96,0.97,0.83,0.84,0.71,2631921600.00
20/05/2000,0.84,0.84,0.74,0.77,0.66,2539454400.00
27/05/2000,0.78,0.89,0.72,0.83,0.70,2843254400.00
从这个数据集中,我只取 和 列。在计算简单的回报(通过函数)后,我只剩下 ,然后将其转换为函数正在启动的返回。Date
Open
AdjClose
CalcReturn
sequence
array
输出应如下所示(例如,假设周回报率为 23%,周回报率为 17%,周回报率为 12%):first
second
third
[|(01/01/2000 00:00:00, 0.23); (08/01/2000 00:00:00, 0.40);
(15/01/2000 00:00:00, 0.52);...|]
同样,目标是绘制一段时间内的累积回报。 希望这能使问题更清楚!
答:
0赞
Brian Berns
6/13/2023
#1
F# 提供了一系列称为 scan
的函数,这些函数适用于计算运行总数。正如您所指出的,挑战在于将相关日期与每个总数保持一致。我认为最简单的方法是这样的:
open System
let input =
[
DateOnly(2000, 1, 1), 0.23
DateOnly(2000, 1, 8), 0.17
DateOnly(2000, 1, 15), 0.12
]
input
|> Seq.scan (fun (_, acc) (date, value) ->
date, acc + value) (DateOnly.MinValue, 0.0)
|> Seq.skip 1 // skip initial value of 0.0
|> printfn "%A"
输出为:
seq [(1/1/2000, 0.23); (1/8/2000, 0.4); (1/15/2000, 0.52)]
为清楚起见,我使用并避免了我认为您已经很好地处理的 CSV 和日期格式问题。DateOnly
DateTime
评论