0

プレイグラウンドでこれを試みると:

func StockEvolution(S_0:Double, _ down:Double, _ up:Double, _ totalsteps:Int, _ upsteps:Int) -> Double // function being used in calcCall()
{
    var S_t:Double = S_0 * pow(up, Double(upsteps)) * pow(down, Double(totalsteps - upsteps))
    return S_t 
}

func CallPayoff(S:Double, _ K:Double) -> Double // function being used in calcCall()
{
    return max(S - K, 0.0)
}

func calcCall(S_0:Double, _ down:Double, _ up:Double, _ r:Double, _ steps:Int, _ K:Double) -> Double //calculate Call-Option
{
    var prices = [Double]()
    var q = 0.6 //risk-neutral probability factor

var i = 0
while i < steps
{
    var payOff = CallPayoff(StockEvolution(S_0, down, up, steps, i), K)
    prices.append(payOff)
    i += 1
}

var n = steps - 1
while n >= 0
{
    var j = 0
    while j <= n
    {
        var value = (1 / r) * (prices[j + 1] * q + (1 - q) * prices[j])
        prices.removeAtIndex(j)
        prices.insert(value, atIndex: j)
        j += 1
    }
    n -= 1
}
return prices[0]
}

これを行うことにより:

var checkPrice = calcCall(100, 0.6, 1.5, 1.05, 10, 200)

それは私にこのエラーを与えます:

実行が中断されました。理由: EXC_BAD_INSTRUCTION (コード=EXC_I386_INVOP、サブコード=0x0)

コードにバグが見つからないようです。さまざまな入力値で試しましたが、それでもエラーが発生します。

私のコードを見て、この問題を解決するのを手伝っていただければ幸いです。ご尽力いただきありがとうございます。

4

1 に答える 1

0

問題は、ネストされたwhileループにあります。最初のループでnは が に設定され9ます。これは、入れ子になったループの最終パスで が終了することを意味しj == 9、これは明らかに を意味しj + 1 == 10ます。prices[j + 1] == prices[10]しかし、存在しないを取得しようとしています。したがって、クラッシュ。

これを確認するには、次の if ステートメントを追加します。

if j + 1 < prices.count {
    let value = (1 / r) * (prices[j + 1] * q + (1 - q) * prices[j])
    prices.removeAtIndex(j)
    prices.insert(value, atIndex: j)
}
j += 1

不正なアクセス エラーが発生しなくなります。

さて、問題のドメインがまったくわからないので、なぜあなたのアルゴリズムが間違っていたのかわかりません. そのため、私が提供した回答では、期待する値が得られない場合があります。おそらく、存在しないインデックスにアクセスしようとしている理由と、それを回避する方法を理解する必要があります。

最後に、一般的なスタイルのポイントをいくつか挙げます。

  • var上記のコード サンプルのを に置き換えたことに気付いたかもしれませんlet。決して変更されないためvalue(ループを通過するたびに再定義される代わりに)、変更可能である必要はありません。変更可能な状態を削除すると、コード内の問題を見つけやすくなります。
  • 進行状況を追跡するために、可変状態の while ループを多数使用しました。for...inこれらはすべてループに置き換えることができます。for i in 0..<stepsたとえば、最初の while は、コードに影響を与えずに置き換えることができます。これも、変更可能な状態とプログラマーのエラーを削減するのに役立ちます。

可能な限り多くの変更可能な状態を削除しながら、コードをもう少し「Swifty」にするために自由に書き直しました。ここにあります:

func stockEvolution(s_0: Double, _ down: Double, _ up: Double, _ totalsteps: Int, _ upsteps: Int) -> Double {
    let s_t: Double = s_0 * pow(up,  Double(upsteps)) * pow(down,  Double(totalsteps - upsteps))
    return s_t
}

func callPayoff(s: Double, _ k: Double) -> Double {
    return max(s - k, 0.0)
}

func calcCall(s_0: Double, _ down: Double, _ up: Double, _ r: Double, _ steps:Int, _ k: Double) -> Double {
    var prices = Array(0..<steps).map { step in
        return callPayoff(stockEvolution(s_0, down, up, steps, step), k)
    }
    let q = 0.6 //risk-neutral probability factor

    for n in (0..<steps).reverse() {
        for j in 0...n where j + 1 < prices.count {
            let value = (1 / r) * (prices[j + 1] * q + (1 - q) * prices[j])
            prices.removeAtIndex(j)
            prices.insert(value, atIndex: j)
        }
    }
    return prices[0]
}

let checkPrice = calcCall(100, 0.6, 1.5, 1.05, 10, 200)
于 2016-10-16T15:34:32.167 に答える