[Add]新增Black-Scholes模型的Cython版本

This commit is contained in:
vn.py 2018-02-09 18:06:31 +08:00
parent ade399d0e0
commit 5e03feef29
7 changed files with 164 additions and 4 deletions

View File

@ -2,6 +2,6 @@
"brokerID": "9999",
"mdAddress": "tcp://180.168.146.187:10011",
"tdAddress": "tcp://180.168.146.187:10001",
"userID": "000300",
"password": "19890624"
"userID": "simnow申请",
"password": "simnow申请"
}

4
vnpy/pricing/README.md Normal file
View 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

Binary file not shown.

View 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

View File

@ -0,0 +1,7 @@
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = 'bsCython',
ext_modules = cythonize("bsCython.pyx"),
)

View File

@ -1,6 +1,6 @@
{
"name": "etf_portfolio",
"model": "black",
"model": "bsCython",
"underlying": [
"510050"
],

View File

@ -17,7 +17,7 @@ from vnpy.trader.vtConstant import (PRODUCT_OPTION, OPTION_CALL, OPTION_PUT,
DIRECTION_LONG, DIRECTION_SHORT,
OFFSET_OPEN, OFFSET_CLOSE,
PRICETYPE_LIMITPRICE)
from vnpy.pricing import black, bs, crr
from vnpy.pricing import black, bs, crr, bsCython
from .omBase import (OmOption, OmUnderlying, OmChain, OmPortfolio,
EVENT_OM_LOG, EVENT_OM_STRATEGY, EVENT_OM_STRATEGYLOG,
@ -31,6 +31,7 @@ MODEL_DICT = {}
MODEL_DICT['black'] = black
MODEL_DICT['bs'] = bs
MODEL_DICT['crr'] = crr
MODEL_DICT['bsCython'] = bsCython