-1

假设我有一个参数 x 并且有几行使用 x 来计算 y,现在有 10 个 x 值,我需要使用每个值来计算相应的 y,我不想每次都更改 x 并运行我的命令行 10 次,F# 中是否有任何语法允许我重复我已经编写的那些命令行,以便我只需要执行一次即可计算出所有 10 个 y 值?

提前致谢

编辑:我将代码粘贴在下面,基本上,我想要的是获得不同参数组合的 alpha,我的参数是“shreshold”、“WeeksBfReport”和“DaysBfExecution”。我有 30 组参数组合,所以我不想去更改参数并运行命令 30 次。有没有办法不这样做?

let shreshold= 2.0
let ReportDate = "2008/12/15"
let ExeDate = "2009/01/05"
let WeeksBfReport = 1
let DaysBfExecution = 3
let Rf=0.01

let DateIn=ReportDate.ToDateTimeExact("yyyy/MM/dd").AddWeeks(-WeeksBfReport)
let DateOut=ExeDate.ToDateTimeExact("yyyy/MM/dd").AddWorkDays(-DaysBfExecution)
let DateInString=DateIn.ToString("yyyy/MM/dd")
let DateOutString=DateOut.ToString("yyyy/MM/dd")

let mutable FundMV=0.
let FundTicker=csvTable.AsEnumerable().Select(fun (x:DataRow) -> x.Field<string>("Ticker")).ToArray()
for i in 0..csvTable.Rows.Count-1 do
    let FundUnitPrice= float(csvTable.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = FundTicker.[i]).First().Field<string>(DateInString))
    let FundShares= float(csvTable1.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = FundTicker.[i]).First().Field<string>(DateInString))
    FundMV<-FundMV + FundUnitPrice*FundShares
    printfn "%e" FundMV
//use TMV to calculate weights of CSI300 constitutes
let mutable csiTMV=0.
let CSITMV : float array = Array.zeroCreate 300
let DictionaryCSI = Dictionary<String,float>()
for i in 0..299 do
    let TMV=float(csvTable3.Rows.[i].Field<string>(DateInString))
    csiTMV<-csiTMV + TMV
    CSITMV.[i] <- TMV
for i in 0..299 do
    let Weight=CSITMV.[i]/csiTMV
    DictionaryCSI.[csvTable3.Rows.[i].Field<string>("Stock")]<-Weight

let DictionaryOldOut = Dictionary<String,float>()
let array=csvTable2.AsEnumerable().Select(fun (x:DataRow) -> x.Field<string>("Stock")).ToArray()
let OldOutTMV=ResizeArray<float>()
let DictionaryOldOutWeight = Dictionary<string,float>()
let OldOutWeight : float array = Array.zeroCreate (csvTable2.Rows.Count/2)
for i in 0..(csvTable2.Rows.Count/2)-1 do
    let Weight=DictionaryCSI.Item(array.[i+(csvTable2.Rows.Count/2)])
    DictionaryOldOutWeight.[csvTable2.Rows.[i+csvTable2.Rows.Count/2].Field<string>("Stock")]<-Weight
    OldOutWeight.[i]<- Weight
    DictionaryOldOut.[csvTable2.Rows.[i+csvTable2.Rows.Count/2].Field<string>("Stock")]<- Weight*FundMV //OldOut Moving Value
    OldOutTMV.Add(Weight)
let OldOutTMVarray=OldOutTMV.ToArray() //create an array of OldOut weights and then sum up
let SumOldOutTMV=Array.fold (+) 0. OldOutTMVarray 

let mutable NewInTMV=0.
let NewInWeight : float array = Array.zeroCreate (csvTable2.Rows.Count/2)
let DictionaryNewIn = Dictionary<string,float>()
let DictionaryNewInWeight = Dictionary<string,float>()
for i in 0..csvTable3.Rows.Count-300-1 do
    let TMV=float(csvTable3.Rows.[i+300].Field<string>(DateInString))
    NewInTMV<-NewInTMV + TMV
    let Weight=TMV/(csiTMV+NewInTMV-SumOldOutTMV)
    NewInWeight.[i]<-Weight
    DictionaryNewInWeight.[csvTable3.Rows.[i+300].Field<string>("Stock")]<-Weight
    let MovingValue=Weight*FundMV
    DictionaryNewIn.[csvTable3.Rows.[i+300].Field<string>("Stock")]<-MovingValue //NewIn Moving Value

let table2array=csvTable2.AsEnumerable().Select(fun (x:DataRow) -> x.Field<string>("Stock")).ToArray()
let NewInturnoverArray : float array = Array.zeroCreate (csvTable2.Rows.Count/2) 
for i in 0..(csvTable2.Rows.Count/2)-1 do  
    let lastday= float(csvTable2.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = table2array.[i]).First().Field<string>(DateInString)) 
    let turnover = csvTable2.Rows.[i].ItemArray.Skip(3)|>Seq.map(fun (x:obj)-> System.Double.Parse(x.ToString()))|>Seq.toArray
    let lastdayindex : (int) =
        if lastday= 0. then
            let lastdayfake=float(csvTable2.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = table2array.[i+2]).First().Field<string>(DateInString)) 
            let turnoverfake = csvTable2.Rows.[i+2].ItemArray.Skip(3)|>Seq.map(fun (x:obj)-> System.Double.Parse(x.ToString()))|>Seq.toArray
            Array.findIndex(fun elem -> elem=lastdayfake) turnoverfake
        else
            let lastdayfake=lastday
            let turnoverfake=turnover
            Array.findIndex(fun elem -> elem=lastdayfake) turnoverfake
    printfn "%A" lastdayindex
    let TurnoverNeed : float array = Array.zeroCreate 21
    for t in 0..20 do
        TurnoverNeed.[t] <- turnover.[lastdayindex - 20 + t]
    let zerotwo : float array = Array.zeroCreate TurnoverNeed.Length
    if TurnoverNeed=zerotwo then 
        let ave_daily_turnover = 0.
        NewInturnoverArray.[i] <- ave_daily_turnover
    else 
        let ave_daily_turnover  = Seq.average(TurnoverNeed|>Seq.filter(fun x-> x > 0.))
        NewInturnoverArray.[i] <- ave_daily_turnover

type totalinfo = {Name:String;Shock:float}
let NewIn=ResizeArray<totalinfo>()
for i in 0..(csvTable2.Rows.Count/2)-1 do
    let MovingValue=DictionaryNewIn.Item(array.[i])
    let Shock=MovingValue/NewInturnoverArray.[i]
    let V= {Name=string(array.[i]); Shock=Shock}
    NewIn.Add(V)
let NewInShock=NewIn.ToArray()

let OldOutturnoverArray : float array = Array.zeroCreate (csvTable2.Rows.Count/2)
for i in 0..(csvTable2.Rows.Count/2)-1 do   
    let turnover = csvTable2.Rows.[i+csvTable2.Rows.Count/2].ItemArray.Skip(3)|>Seq.map(fun (x:obj)-> System.Double.Parse(x.ToString()))
    let zero : float array = Array.zeroCreate (turnover|>Seq.toArray).Length
    if turnover|>Seq.toArray=zero then
        let ave_daily_turnover  = 0.
        OldOutturnoverArray.[i] <- ave_daily_turnover
    else
        let ave_daily_turnover  = Seq.average(turnover|>Seq.filter(fun x-> x > 0.))
        OldOutturnoverArray.[i] <- ave_daily_turnover

let OldOut=ResizeArray<totalinfo>()
for i in 0..(csvTable2.Rows.Count/2)-1 do
    let MovingValue=DictionaryOldOut.Item(array.[i+csvTable2.Rows.Count/2])
    let Shock=MovingValue/OldOutturnoverArray.[i]
    let V= {Name=string(array.[i+csvTable2.Rows.Count/2]); Shock=Shock}
    OldOut.Add(V)
let OldOutShock=OldOut.ToArray()

let DoIn=NewInShock |> Array.filter (fun t -> t.Shock >= shreshold)
let DoOut=OldOutShock |> Array.filter (fun t -> t.Shock >= shreshold)

let DoInTicker= Array.map (fun e -> e.Name) DoIn
let DoOutTicker= Array.map (fun e -> e.Name) DoOut

let DoInWeight : float array = Array.zeroCreate DoInTicker.Length
for i in 0..DoInTicker.Length-1 do
    DoInWeight.[i] <- DictionaryNewInWeight.Item(DoInTicker.[i])

let TotalDoInWeight= Array.fold (+) 0.  DoInWeight
let DoInRatioX : float array = Array.zeroCreate DoInTicker.Length
for i in 0..(DoInTicker.Length)-1 do  
    DoInRatioX.[i] <- DoInWeight.[i]/TotalDoInWeight
let Beta=csvTable2.AsEnumerable().Select(fun (x:DataRow) -> x.Field<string>("Beta")).ToArray()
//let NewInBeta : float array = Array.zeroCreate (csvTable2.Rows.Count/2)
let DictionaryNewInBeta = Dictionary<string,float>()
for i in 0..(csvTable2.Rows.Count/2)-1 do  
//    NewInBeta.[i] <- float(Beta.[i])
    DictionaryNewInBeta.[csvTable3.Rows.[i+300].Field<string>("Stock")]<-float(Beta.[i])
let DoInBeta : float array = Array.zeroCreate DoInTicker.Length
for i in 0..DoInTicker.Length-1 do
    DoInBeta.[i] <- DictionaryNewInBeta.Item(DoInTicker.[i])

let mutable PortfolioBeta=0.
for i in 0..(DoInTicker.Length)-1 do
    PortfolioBeta <- PortfolioBeta + DoInRatioX.[i] * DoInBeta.[i] 

let mutable PortfolioReturn= 0.
for i in 0..DoInTicker.Length-1 do
    let PriceIn= float(csvTable4.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = DoInTicker.[i]).First().Field<string>(DateInString))
    let PriceOut= float(csvTable4.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = DoInTicker.[i]).First().Field<string>(DateOutString))
    PortfolioReturn <- PortfolioReturn + (1./float(DoInTicker.Length))*(PriceOut - PriceIn)/PriceIn

let IndexIn= float(csvTable4.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = "000300.SH").First().Field<string>(DateInString))
let IndexOut= float(csvTable4.AsEnumerable().Where(fun (x:DataRow) -> x.Field<string>(0) = "000300.SH").First().Field<string>(DateOutString))
let MarketReturn= (IndexOut-IndexIn)/IndexIn
let Alpha= PortfolioReturn-Rf-PortfolioBeta*(MarketReturn-Rf)
4

3 回答 3

1

我也不完全确定您需要什么(其他约束和动机是什么),但是如果您有一些交互式代码可以进行一次计算,请说:

let x = 10
let y = x * x

您可以使用例如列表将其转换为对多个输入执行相同计算的代码:

let xs = [1; 10; 100]
let ys = [ for x in xs -> x * x ]

但如前所述,这取决于您实际想要实现的目标 - 如果您可以添加一个实际示例来说明您正在尝试做什么,那将很有用。

于 2013-01-17T08:33:34.673 回答
1

就像约翰说的那样,把它全部放在一个接受变化值作为参数的函数中。可以使用记录来允许您将参数组合存储在列表中,就像这样。

type ReportParameters = {
    shreshold: float;
    ReportDate: string;
    ExeDate: string;
    WeeksBfReport: int;
    DaysBfExecution: int;
    Rf: float;
}

type Report = {
    NewInShock: totalinfo;
    IndexIn: float;
    // etc
}

let createReport (reportParams:ReportParameters) : Report = 
    let shreshold = reportParams.shreshold
    let ReportDate = reportParams.ReportDate
    let ExeDate = reportParams.ExeDate
    let WeeksBfReport = reportParams.WeeksBfReport
    let DaysBfExecution = reportParams.DaysBfExecution
    let Rf = reportParams.Rf

    // Your function code HERE
    // Remember to move all type definitions out of this scope.

    { // Report data to return.
        NewInShock = NewInShock;
        IndexIn = IndexIn;
        // etc
    }

使用代码就这么简单:

let reportsToBeGenerated = [
    { shreshold = 2.0; ReportDate = "2008/12/15"; ExeDate = "2009/01/05"; WeeksBfReport = 1; DaysBfExecution = 3; Rf = 0.01 };
    { shreshold = 1.5; ReportDate = "2009/12/15"; ExeDate = "2010/01/05"; WeeksBfReport = 2; DaysBfExecution = 2; Rf = 0.01 };
]

let reports = reportsToBeGenerated |> List.map createReport
于 2013-01-17T23:57:15.083 回答
0

查看您的代码,您想做这样的事情

let run shreshold ReportDate ExeDate WeeksBfReport DaysBfExecution  Rf =
    //The entire rest of the code indented - you may want to return alpha etc

然后你可以插入参数值

于 2013-01-17T09:33:59.607 回答