構文がどれほど簡潔かを確認するために、c# に既にあるものを f# に実装しようとしています。これは私には機能上の問題のように思われるため、テストとしてオプション価格計算式 (Black 76) を使用しました。すべて問題ないようですが、同じクラスのメソッドを内部から呼び出す必要があるため、暗黙のボリュームを計算するのに問題があります。これが私がこれまでに持っているものです:
module Module1
open System
type Black76 (CallPutFlag, Fwd, Strike, time, rf, vol, ?BlackPrice:float) =
let d1 = (Math.Log(Fwd / Strike) + (vol * vol * 0.5) * time) / (vol * Math.Sqrt(time))
let d2 = d1 - vol * Math.Sqrt(time)
let n = new MathNet.Numerics.Distributions.Normal()
member x.valuation =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> Math.Exp(-rf * time) * (Fwd * n.InverseCumulativeDistribution(d1) - Strike * n.InverseCumulativeDistribution(d2))
| "p" | "P" | "Put" | "put" -> Math.Exp(-rf * time) * (Strike * n.InverseCumulativeDistribution(-d2)- Fwd * n.InverseCumulativeDistribution(-d1))
| _ -> failwith "Unrecognized option type"
member x.delta =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> Math.Exp(-rf * time) * n.InverseCumulativeDistribution(d1)
| "p" | "P" | "Put" | "put" -> Math.Exp(-rf * time) * n.InverseCumulativeDistribution(-d1)
| _ -> failwith "Unrecognized option type"
member x.gamma =
Math.Exp(-rf * time) * (n.Density(d1) / (Fwd * vol * Math.Sqrt(time)))
member x.vega =
Math.Exp(-rf * time) * n.Density(d1) * Fwd * Math.Sqrt(time)
member x.rho =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> time * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(d2)
| "p" | "P" | "Put" | "put" -> -time * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(-d2)
| _ -> failwith "Unrecognized option type"
member x.theta =
match CallPutFlag with
| "c" | "C" | "Call" | "call" -> -(Fwd * vol * n.Density(d1)) / (2.0 * Math.Sqrt(time)) - rf * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(d2)
| "p" | "P" | "Put" | "put" -> -(Fwd * vol * n.Density(d1)) / (2.0 * Math.Sqrt(time)) + rf * Strike * Math.Sqrt(-rf * time) * n.InverseCumulativeDistribution(-d2)
| _ -> failwith "Unrecognized option type"
member x.impliedvol =
let vst = Math.Sqrt(2.0*Math.Abs((Math.Log(Fwd/Strike)+rf*time)/time))
let tol = 0.0001
let mutable v = vst
let mutable sigmadiff = 1.0
let mutable k = 1
let kmax = 100
while (sigmadiff >= tol && k < kmax) do
let option = Black76.valuation(CallPutFlag, Fwd, Strike, time, rf, v)
let cvega = Black76.vega(CallPutFlag, Fwd, Strike, time, rf, v)
let increment = (option - BlackPrice) / cvega
v <- v - increment
k < - k + 1
sigmadiff = Math.Abs(increment)
v
これはすべて、暗黙の vol 関数とは別に機能します。また、C# バージョンよりも簡潔ではないようです。暗黙の vol 関数に対して内部からメソッドを呼び出す方法を教えてください。また、let mutable を取り除く方法を知っていますか (結局のところ、これを fsharp で使用することは想定されていません (私はそう思います))。