我试图弄清楚何时使用 f# 以及何时使用 c#。我有一个能源交易的实际问题。电力合同被引用为,交付开始,交付结束,关税,体积。例如,100MW Cal14 Offpeak,因此从 2014 年 1 月 1 日到 2014 年 12 月 31 日,如果工作时间在一周的 20 到 8 小时(夜间)或周末的所有时间之间,则合同每小时交付 100MW -总共约 5500 小时。高峰合同在工作日交付 8-20,而基地在期间交付所有时间。
如果您有这些合约的投资组合,您希望将它们聚合成每小时头寸向量。到目前为止,这是我的代码:
合同数据示例(日期为 Excel 格式):
let data = [(41275., 41639., "Base", 10.); (41275., 41639., "Base", 60.); (41275., 41639., "Peak", 20.); (41275.,41639.,"Offpeak",30.); (41275.,41364.,"Peak",40.); (41275.,41364.,"Peak",70.); (41275.,41364.,"Offpeak", 50.)]
聚合相同合约的函数:
let group_fold keys value fold acc seq =
seq |> Seq.groupBy keys
|> Seq.map (fun ((key1, key2, key3), seq) ->
(key1, key2, key3, seq |> Seq.map value |> Seq.fold fold acc))
let aggrTrades data =
data |> group_fold (fun (k1, k2, k3, _) -> k1, k2, k3) (fun (_, _, _, v) -> v) (+) 0.0
识别高峰和非高峰时间的功能:
let poindicator dts =
let newdts = DateTime.FromOADate dts
// Match on day of week and hour properties of the date time
match newdts.DayOfWeek, newdts.Hour with
// For weekend, return false
| DayOfWeek.Saturday, _ | DayOfWeek.Sunday, _ -> false
// For working hours, return true
| _, h when h >= 8 && h < 20 -> true
// For non-working weekday hours, return false
| _ -> false
最后一个函数将它们放在一起并创建一个小时向量(std = 小时向量的开始日期和 edd = 结束日期):
let hourlyvec data std edd =
let aggrdata = aggrTrades data
let dtsvec = [std.. 1./24. .. edd]
let nrhrs = dtsvec |> Seq.length
let mutable res = Seq.init nrhrs (fun i -> 0.0)
for i=0 to res |> Seq.length do
for (a, b, c, d) in aggrdata do
match a , b with
| e, f when e <= dtsvec.[i] && f >= dtsvec.[i] ->
match c with
| "Base" -> res.[i] <- res.[i] + d
| "Peak" when poindicator (DateTime.FromOADate dtsvec.[i]) -> res.[i] <- res.[i] + d
| "Offpeak" when not poindicator (DateTime.FromOADate dtsvec.[i]) -> res.[i] <- res.[i] + d
| _ -> failwith "Not recognized tarif"
|_ -> failwith "Not in period tarif"
dtsvec, res
FS0039 失败:未定义字段、构造函数或成员“项目”,并且似乎也不喜欢嵌套指针函数
任何指针将不胜感激?另外,如果您认为这在 c# 中会更容易,请告诉我,我认为它是一个功能问题,所以我首先选择了 f#。