计算选项增量的最佳做法



期权是基于某些标的证券的价值(通常是股票价格)的衍生合约。从形式上讲,在定价模式下,期权价格是s0、当前标的证券价格、许多其他参数(波动率、利率、股息率等)以及一些可能的kwargs的函数。

期权的Delta是其价格相对于标的证券价格的变化率。在实践中,这是像

(calc_price(s0 + ds, **kwargs) - calc_price(s0 - ds, **kwargs)) / (2 * ds)

我想做的是将get_delta实现为Option的方法所以现在我已经为该选项实现了定价模型,如下所示:

class Option:
def __init__(self, s0, lots_of_args, **kwargs):
self.s0 = s0
# actually there's a list of lots of args, not packed
self.lots_of_args = lots_of_args
# actually kwargs are unpacked either,
self.kwargs = kwargs
def calc_price(self):
price = ...
return price
def get_delta(self, ds=.05):
cd = Option(self.s0 - ds, self.lots_of_args, **self.kwargs).calc_price()
cu = Option(self.s0 + ds, self.lots_of_args, **self.kwargs).calc_price()   
return (cu - cd) / (2 * ds)

问题是除了s0之外真的有很多参数(表示为lots_of_args,但实际上它们不是单个参数,而是有十几个),所以我真的很讨厌将它们一一复制到get_delta函数中。我需要一种方法来获取传递给__init__的参数的字典.当然,第一个想法是使用locals().但是,存在一些问题:

  1. 房价包括额外的self参数。

  2. kwargs没有拆包。

  3. locals()上的文档建议不要修改locals()返回的字典,所以我认为delself参数并update解压缩的kwargs不是一个好主意。

谁能帮忙?谢谢。

复制怎么样?

import copy
class Option:
def __init__(self, s0, lots_of_args, **kwargs):
self.s0 = s0
def calc_price(self):
price = ...
return price
def get_delta(self, ds=.05):
cd = copy.copy(self)
cd.s0 -= ds
cu = copy.copy(self)
cu.s0 += ds
return (cu.calc_price() - cd.calc_price()) / (2 * ds)

如果您的类有一些字典/列表属性(或使用其他可变类的 attr),那么您可能希望改用copy.deepcopy(例如,如果calc_price()更改了这些属性)。

您可以定义__copy__方法来自定义复制的创建方式。

如果你只需要复制这些"大量的参数",而不改变它们,那么你可以使用类似于namedtuple的_replace方法的方法:

>>> import collections
>>> Option = collections.namedtuple('Option', 'a b c d e f')
>>> opt = Option(a=1, b=2, c=3, d=4, e=5, f=6)
>>> opt
Option(a=1, b=2, c=3, d=4, e=5, f=6)
>>> new_opt = opt._replace(a=74)
>>> new_opt
Option(a=74, b=2, c=3, d=4, e=5, f=6)  # only 'a' changed, all other args remained the same

然后,您的get_delta()方法将如下所示:

def get_delta(self, ds=.05):
cd = self._replace(s0=self.s0 - ds).calc_price()
cu = self._replace(s0=self.s0 + ds).calc_price()   
return (cu - cd) / (2 * ds)

是直接从命名元组继承还是创建自己的类似_replace的方法取决于您。

为什么不修改 calc_price 方法以包含 ds? 然后,get_delta简化为使用正和负 ds 调用calc_price:

def calc_price(self, ds=0):
s0 = self.s0 + ds 
price = ... return price 
def get_delta(self, ds=.05): 
cd = self.calc_price(-ds)
cu = self.calc_price(ds) 
return (cu - cd) / (2 * ds) here

最新更新