1

我正在努力 在 Python 中实现三叉树。我为二叉树找到了非常好的解决方案 (和矢量化版本),我正在尝试将其更改为三项式情况。
这是我所拥有的:

def Trinomial(type, S0, K, r, sigma, T, N=2000):
import numpy as np
t = float(T) / N
#fixed lambda
lam = np.sqrt(5)
# up and down factor will be constant for the tree so we calculate outside the loop
u = np.exp(lam * sigma * np.sqrt(t))
d = 1.0 / u

#to work with vector we need to init the arrays using numpy
fs =  np.asarray([0.0 for i in xrange(2*N + 1)])

#we need the stock tree for calculations of expiration values
fs2 = np.asarray([(S0 * u**j) for j in xrange(-N, N+1)])

#we vectorize the strikes as well so the expiration check will be faster
fs3 =np.asarray( [float(K) for i in xrange(2*N + 1)])

#formulas, that can be found in the pdf document
a = np.exp(r*t/2.0)
b = np.exp(-sigma * np.sqrt(t/2.0))
c = np.exp(sigma * np.sqrt(t/2.0))
p_u = ( ( a - b ) / ( c - d ) )**2 
p_d = ( ( c - a ) / ( c - b ) )**2
p_m = 1 - p_u - p_d

# Compute the leaves, f_{N, j}
if type =="C":
    fs[:] = np.maximum(fs2-fs3, 0.0)
else:
    fs[:] = np.maximum(-fs2+fs3, 0.0)

#calculate backward the option prices
for i in xrange(N-1, -1, -1):
   fs[:-1] = np.exp(-r * t) * (p_u * fs[1:] + p_d * fs[:-1] + p_m*fs[-1])

return fs[0]

当然,它不会按预期工作,例如调用

print Trinomial("C",100, 100, 0.1, 0.1, 5, 3)

应该输出 39 到 40 之间的东西。
我最关心的行是:

fs2 = np.asarray([(S0 * u**j) for j in xrange(-N, N+1)])

fs[:-1] = np.exp(-r * t) * (p_u * fs[1:] + p_d * fs[:-1] + p_m*fs[-1])

我不确定我是否正确填充了初始树,并且我 100% 确定,反向计算期权价格不起作用。我不知道如何从我一开始链接的pdf中实现公式[10]。
也许它不能在矢量化版本上完成,但我尝试了简单的树并且也失败了。
在这种情况下,我没有使用二项式或 BS 价格,因为我的任务是使用三项式树来完成。

4

1 回答 1

0

我刚刚开始学习 Python 并构建了二项式和三项式模型只是为了测试我的理解,尤其是关于数组的理解。

对于终端股票价格数组,我已经从 InitialStock * u**(iSteps - i) 降级,因为 i 从零变为 2*iSteps+ 1。即。我从最高的终端股票价格 InitialStock * u**(iSteps) 开始,然后向下移动,直到到达 InitalStock * u**(-iSteps) 并将 TerminalStock 数组从 0 填充到 2*iSteps+1 (即最后数组元素是 InitialStock * u**(-iSteps)。因为我来自 VBA 的土地,我还没有学会雄辩的(因此,简短且有时难以阅读的 Python 风格),我的循环看起来像这样:

for i in range(0, 2*iSteps+1) :

    # Terminal stock is initial with up staps and down steps
    dblStockTerminal = dblStock * u ** float(iSteps - i)

    # compute intrinsic values at terminal stock value
    dblTrinOpt[i][iSteps] = max( dblSwitch * (dblStockTerminal - dblStrike), 0 )

我已将 dblTrinOpt 数组初始化为 dblTrinOpt = np.ndarray( ( 2*iSteps+1, iSteps+1), float) 以便它在终端股票价格和 iStep 时间步长处具有 2*iSteps 价格元素,其中 iSteps = OptionTerm / NumberOfSteps . 是的,为我笨拙的 python 代码道歉!(但我必须阅读它)。

之后,我的选项 calc 如下(是的,代码又不优雅):

#------------------------------------------
# steps in time from Terminal to Initial Stock price
#------------------------------------------
for i in range(iSteps-1, -1, -1) :

    #------------------------------------------
    # steps in price range from highest to lowest
    #------------------------------------------
    for j in range(0, 2*i+1) :

        #------------------------------------------
        # discount average of future option value
        # as usual, trinomial averages three values
        #------------------------------------------
        dblTrinOpt[j][i] = dblDisc * (pu * dblTrinOpt[j][i+1] + pm * \
            dblTrinOpt[j+1][i+1] + pd * dblTrinOpt[j+2][i+1])

之后,我的 Trinomial 函数将 dblTrinOpt[0][0] 作为最终折扣期权价格传递。

我想以一种更易读的形式编写它,以便更容易添加两个组件:(a) 一个美式期权工具,因此跟踪每个树节点的股票价格(然后像障碍和百慕大这样的东西将是一个简单的添加, 和 (b) 在每一端添加两个额外的终端价格,这样在时间为零时,我将拥有三个股票和期权价值,这样我就可以计算 delta 和 gamma 而无需重新计算期权树(即避免碰撞和重新计算方法)。我希望这会有所帮助,即使我没有修复您的特定代码,但解释了逻辑。

于 2017-11-08T05:19:24.440 回答