计算期权 Delta 的最佳实践
Best practice to calculate the Delta of an option
期权是基于某些标的证券的价值(通常是股票价格)的衍生合约。形式上,在定价模型下,期权价格是 s0
、当前标的证券价格、手 其他参数(波动率、利率、股息率等)的函数.), 和一些可能的 kwargs
.
期权的 Delta 是其价格相对于标的证券价格的变化率。实际上,这是像
这样实现的
(calc_price(s0 + ds, **kwargs) - calc_price(s0 - ds, **kwargs)) / (2 * ds)
我想做的是将 get_delta
实现为 Option
class 的 方法 所以现在我已经实现了定价模型选项为:
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
之外,还有 lot 个参数(表示为 lots_of_args,但实际上它们不是一个参数,而是一打),所以我真的很讨厌将它们一个一个地复制到 get_delta
函数中。我需要一种方法来获取传递给 __init__
的参数的字典。第一个想到的当然是用locals()
。但是,存在一些问题:
包含一个额外的 self
arg。
kwargs
未 解包。
doc on locals()
建议不要修改 locals()
返回的字典,所以我认为 del
self
不是个好主意] arg 和 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)
如果您的 class 有一些 dict/list 属性(或使用其他可变 class 的属性),那么您可能想改用 copy.deepcopy
(例如,如果calc_price()
更改这些属性)。
并且您可以定义 __copy__
方法来自定义创建副本的方式。
如果您只是复制那些 "lots of args",而不更改它们,那么您可以使用类似于 namedtuple's _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)
是直接从 namedtuple 继承还是创建自己的 _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
期权是基于某些标的证券的价值(通常是股票价格)的衍生合约。形式上,在定价模型下,期权价格是 s0
、当前标的证券价格、手 其他参数(波动率、利率、股息率等)的函数.), 和一些可能的 kwargs
.
期权的 Delta 是其价格相对于标的证券价格的变化率。实际上,这是像
这样实现的(calc_price(s0 + ds, **kwargs) - calc_price(s0 - ds, **kwargs)) / (2 * ds)
我想做的是将 get_delta
实现为 Option
class 的 方法 所以现在我已经实现了定价模型选项为:
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
之外,还有 lot 个参数(表示为 lots_of_args,但实际上它们不是一个参数,而是一打),所以我真的很讨厌将它们一个一个地复制到 get_delta
函数中。我需要一种方法来获取传递给 __init__
的参数的字典。第一个想到的当然是用locals()
。但是,存在一些问题:
包含一个额外的
self
arg。kwargs
未 解包。doc on
locals()
建议不要修改locals()
返回的字典,所以我认为del
self
不是个好主意] arg 和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)
如果您的 class 有一些 dict/list 属性(或使用其他可变 class 的属性),那么您可能想改用 copy.deepcopy
(例如,如果calc_price()
更改这些属性)。
并且您可以定义 __copy__
方法来自定义创建副本的方式。
如果您只是复制那些 "lots of args",而不更改它们,那么您可以使用类似于 namedtuple's _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)
是直接从 namedtuple 继承还是创建自己的 _replace
类方法由您决定。
为什么不修改 calc_price 方法以包含 ds? get_delta 然后简化为使用正负 ds:
调用 calc_pricedef 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