[Add]新增Black-Scholes模型的Cython版本
This commit is contained in:
parent
ade399d0e0
commit
5e03feef29
@ -2,6 +2,6 @@
|
|||||||
"brokerID": "9999",
|
"brokerID": "9999",
|
||||||
"mdAddress": "tcp://180.168.146.187:10011",
|
"mdAddress": "tcp://180.168.146.187:10011",
|
||||||
"tdAddress": "tcp://180.168.146.187:10001",
|
"tdAddress": "tcp://180.168.146.187:10001",
|
||||||
"userID": "000300",
|
"userID": "simnow申请",
|
||||||
"password": "19890624"
|
"password": "simnow申请"
|
||||||
}
|
}
|
4
vnpy/pricing/README.md
Normal file
4
vnpy/pricing/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
* Cython相关模型的编译方法:python setup.py build_ext --inplace
|
||||||
|
|
||||||
|
* 报错Unable to find vcvarsall.bat的解决方法:SET VS90COMNTOOLS=%VS120COMNTOOLS%
|
||||||
|
|
BIN
vnpy/pricing/bsCython.pyd
Normal file
BIN
vnpy/pricing/bsCython.pyd
Normal file
Binary file not shown.
148
vnpy/pricing/bsCython/bsCython.pyx
Normal file
148
vnpy/pricing/bsCython/bsCython.pyx
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
DX_TARGET = 0.00001
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cdef extern from "math.h" nogil:
|
||||||
|
double exp(double)
|
||||||
|
double sqrt(double)
|
||||||
|
double pow(double, double)
|
||||||
|
double log(double)
|
||||||
|
double erf(double)
|
||||||
|
double fabs(double)
|
||||||
|
|
||||||
|
cdef double cdf(double x):
|
||||||
|
return 0.5 * (1 + erf(x / sqrt(2.0)))
|
||||||
|
|
||||||
|
cdef double pdf(double x):
|
||||||
|
return exp(- pow(x, 2) / 2) / sqrt(2 * 3.1416)
|
||||||
|
|
||||||
|
cdef double calculateD1(double s, double k, double r, double t, double v):
|
||||||
|
return (log(s / k) + (r + 0.5 * pow(v, 2)) * t) / (v * sqrt(t))
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculatePrice(double s, double k, double r, double t, double v, int cp):
|
||||||
|
""""""
|
||||||
|
cdef double d1, d2, price
|
||||||
|
|
||||||
|
if v <= 0:
|
||||||
|
return max(0, cp * (s - k))
|
||||||
|
|
||||||
|
d1 = calculateD1(s, k, r, t, v)
|
||||||
|
d2 = d1 - v * sqrt(t)
|
||||||
|
price = cp * (s * cdf(cp * d1) - k * cdf(cp * d2) * exp(-r * t))
|
||||||
|
|
||||||
|
return price
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculateDelta(double s, double k, double r, double t, double v, int cp):
|
||||||
|
""""""
|
||||||
|
cdef double d1, delta
|
||||||
|
|
||||||
|
if v <= 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
d1 = calculateD1(s, k, r, t, v)
|
||||||
|
delta = cp * cdf(cp * d1)
|
||||||
|
delta = delta * s * 0.01
|
||||||
|
|
||||||
|
return delta
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculateGamma(double s, double k, double r, double t, double v, int cp):
|
||||||
|
""""""
|
||||||
|
cdef double d1, gamma
|
||||||
|
|
||||||
|
if v <= 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
d1 = calculateD1(s, k, r, t, v)
|
||||||
|
gamma = pdf(d1) / (s * v * sqrt(t))
|
||||||
|
gamma = gamma * pow(s, 2) * 0.0001
|
||||||
|
|
||||||
|
return gamma
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculateTheta(double s, double k, double r, double t, double v, int cp):
|
||||||
|
""""""
|
||||||
|
cdef double d1, d2, theta
|
||||||
|
|
||||||
|
if v <= 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
d1 = calculateD1(s, k, r, t, v)
|
||||||
|
d2 = d1 - v * sqrt(t)
|
||||||
|
theta = (-0.5 * s * pdf(d1) * v / sqrt(t) -
|
||||||
|
cp * r * k * exp(-r * t) * cdf(cp * d2))
|
||||||
|
theta = theta / 240
|
||||||
|
return theta
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculateVega(double s, double k, double r, double t, double v, int cp):
|
||||||
|
""""""
|
||||||
|
vega = calculateOriginalVega(s, k, r, t, v, cp) / 100
|
||||||
|
return vega
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculateOriginalVega(double s, double k, double r, double t, double v, int cp):
|
||||||
|
""""""
|
||||||
|
cdef double d1, vega
|
||||||
|
|
||||||
|
if v <= 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
d1 = calculateD1(s, k, r, t, v)
|
||||||
|
vega = s * pdf(d1) * sqrt(t)
|
||||||
|
|
||||||
|
return vega
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculateGreeks(double s, double k, double r, double t, double v, int cp):
|
||||||
|
""""""
|
||||||
|
price = calculatePrice(s, k, r, t, v, cp)
|
||||||
|
delta = calculateDelta(s, k, r, t, v, cp)
|
||||||
|
gamma = calculateGamma(s, k, r, t, v, cp)
|
||||||
|
theta = calculateTheta(s, k, r, t, v, cp)
|
||||||
|
vega = calculateVega(s, k, r, t, v, cp)
|
||||||
|
return price, delta, gamma, theta, vega
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def calculateImpv(price, s, k, r, t, cp):
|
||||||
|
""""""
|
||||||
|
if price <= 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
meet = False
|
||||||
|
|
||||||
|
if cp == 1 and (price > (s - k) * exp(-r * t)):
|
||||||
|
meet = True
|
||||||
|
elif cp == -1 and (price > k * exp(-r * t) - s):
|
||||||
|
meet = True
|
||||||
|
|
||||||
|
if not meet:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
v = 0.3
|
||||||
|
|
||||||
|
for i in range(50):
|
||||||
|
p = calculatePrice(s, k, r, t, v, cp)
|
||||||
|
|
||||||
|
vega = calculateOriginalVega(s, k, r, t, v, cp)
|
||||||
|
|
||||||
|
if not vega:
|
||||||
|
break
|
||||||
|
|
||||||
|
dx = (price - p) / vega
|
||||||
|
|
||||||
|
if abs(dx) < DX_TARGET:
|
||||||
|
break
|
||||||
|
|
||||||
|
v += dx
|
||||||
|
|
||||||
|
if v <= 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
v = round(v, 4)
|
||||||
|
|
||||||
|
return v
|
||||||
|
|
7
vnpy/pricing/bsCython/setup.py
Normal file
7
vnpy/pricing/bsCython/setup.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from distutils.core import setup
|
||||||
|
from Cython.Build import cythonize
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name = 'bsCython',
|
||||||
|
ext_modules = cythonize("bsCython.pyx"),
|
||||||
|
)
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "etf_portfolio",
|
"name": "etf_portfolio",
|
||||||
"model": "black",
|
"model": "bsCython",
|
||||||
"underlying": [
|
"underlying": [
|
||||||
"510050"
|
"510050"
|
||||||
],
|
],
|
||||||
|
@ -17,7 +17,7 @@ from vnpy.trader.vtConstant import (PRODUCT_OPTION, OPTION_CALL, OPTION_PUT,
|
|||||||
DIRECTION_LONG, DIRECTION_SHORT,
|
DIRECTION_LONG, DIRECTION_SHORT,
|
||||||
OFFSET_OPEN, OFFSET_CLOSE,
|
OFFSET_OPEN, OFFSET_CLOSE,
|
||||||
PRICETYPE_LIMITPRICE)
|
PRICETYPE_LIMITPRICE)
|
||||||
from vnpy.pricing import black, bs, crr
|
from vnpy.pricing import black, bs, crr, bsCython
|
||||||
|
|
||||||
from .omBase import (OmOption, OmUnderlying, OmChain, OmPortfolio,
|
from .omBase import (OmOption, OmUnderlying, OmChain, OmPortfolio,
|
||||||
EVENT_OM_LOG, EVENT_OM_STRATEGY, EVENT_OM_STRATEGYLOG,
|
EVENT_OM_LOG, EVENT_OM_STRATEGY, EVENT_OM_STRATEGYLOG,
|
||||||
@ -31,6 +31,7 @@ MODEL_DICT = {}
|
|||||||
MODEL_DICT['black'] = black
|
MODEL_DICT['black'] = black
|
||||||
MODEL_DICT['bs'] = bs
|
MODEL_DICT['bs'] = bs
|
||||||
MODEL_DICT['crr'] = crr
|
MODEL_DICT['crr'] = crr
|
||||||
|
MODEL_DICT['bsCython'] = bsCython
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user