刘主席的三年

突然想写点东西,记录一下刘主席的这三年。

我算是12年开始正式接触证券市场,上交所在12年准备股票期权的仿真,我在迎春路那做虚拟撮合,据说旁边郭树清视察时候关心了股票期权的情况。

郭主席是市场派,是创新派,其在任上,证券公司跟着主席后面推创新业务,每周就有新政策出台,就和刘主席任上,我们每周都能看到抓内幕交易一样。

郭主席对经济金融有研究,对创新业务有激情,每年券商创新大会都搞的很隆重,但治下的指数一直在两千多点晃荡,至其留人,下跌了7%,另外其任上IPO暂停了很长一段时间,市场也不见起色,记得蓝筹具有罕见的投资价值,应该是在其在任上喊出来的。

转眼就迎来了肖主席,肖主席在中行时年轻有为,记得我实习的时候,似乎就看到他对资本市场的一篇点评,主要说的是影子银行的问题,那段时间是国内信托业的第五次高潮,刚兑项目如火如荼。肖主席对创新没有郭主席这么热情,政策上面没觉得出台什么东西,券商创新大会也基本不参加了(当然现在这个会都没什么格局了)。不过其任上出来了50期权,这个是我交易生涯的起步。

肖主席对创新热情不高,但是奈何其任上4万亿的药效过了,后遗症来了。朱镕基总理铺下的新局面,红利终于要被消耗赶紧了,没有那种帕累托式的改进,改革开始要触动利益了。

触动利益的改革总是很困难的,于是刘智囊想到了利用资本市场推进改革这条路,各种资金带着杠杆涌进了中国的股票市场,一时间大爷大妈也跑步入场,中国有十亿人口,中国的公司市值是不是应该比美国的还要大。市梦率在这个时候,似乎并没有多少感情色彩,就是一个技术术语。

终于,指数是不能涨到天上去的,越美好的时光是越短暂的,肖主席看到了指数涨的太快的风险,但是他看到的太晚了,而有人是乐意指数这样涨上去的,“四千点是牛市的新起点”言犹在耳,这个肖主席也难以违背这个上次的喜好的。

当然,从技术上面讲,肖主席有很多工作是可以提前做,是可以好好做的,但又或者是由于我们的资本市场是在太过羸弱,自身的调节能力是在是太差,而上层的意思又是那么的明确,总之,肖主席任上,泡沫被吹大了之后(不一定是他吹大的),但是他戳泡泡的手段太过粗暴,连带整个金融体系都来替他扛雷,譬如小川的央行连续降准降息。

不过既然泡泡不是肖刚吹起来的,吹泡泡的人怪罪戳泡泡的,怎么都有点理不直气不壮,但是后来的熔断,直接就将肖主席赶下了椅子了。

终于等来了刘主席。

刘主席是16年接任肖主席的位子的,当时股灾将尽未尽,又添熔断新片,资本市场刚刚经历了一轮波澜壮阔的大戏,急切的需要休养生息。

刘主席做的第一件事情是注册制暂停,取消了上交所推上去的战略新兴产业版(回头来看主席就是在所谓的战略版上栽了跟头)。

注册制这个事情,实际上也是呼吁了很久了,我印象里面,郭主席任上就喊,IPO不审行不行,肖主席任上,这个事情也一直在推进,写到了人大报告里面。

刘主席对注册制不感冒,实际上我一开始是有反感的,作为在改革开放浪潮中出生长大的人,我们天然的对所有的创新有好感,刚一上任就如此保守,对于我们这种新人来说,没有新业务的驱动,哪里有职业生涯的想象力。

虽然刘主席暂停了注册制,但是刘主席治下,IPO发的比以往都快,能难能可贵的是,由于指数下跌,市场上不断有人呼吁暂停IPO,但是主席顶住了这个压力,对市场的声音有回应,但是还是坚持ipo不暂停,也事实上解决了IPO堰塞湖的问题。虽然股票发的多,但是IPO的审核实际上是更严的,交易所的问询函,都能当财务会计的参考案例。很多公司看看自己的报表觉得过不了,主动撤回了首发申请,这也是IPO排队家数减少的另一个原因。

刘主席做的第二件事情,是老虎妖精害人精,这个词虽然被归为刘主席,但是应该是最高层的意思,这是没得跑了。但是刘主席在拿到这个尚方宝剑之后,各路大鳄的严监管,是切切实实让我看到了一个规范市场的希望。

很多人同情姚员外,同情徐股神,甚至同情那个望北楼的大鳄,对这些人动手,我觉得是鼓掌称道的,但是我觉得无法归功到刘主席身上,他的能量还不够。

我不同情这些人,他们或许真的没有突破既定规则,只是把规则揉捏的出神入化,但是从来没有一个规则是一成不变的,当你的能量到了一定级别,你的政治觉悟务必要跟上。德不配位的话,根基就太不牢靠了。

这些人,跟着杠杆赚钱,在金融里面弄潮,德行上修行太少。反而是互联网里面的两个马,政治觉悟上,马云一直是很高的,15年后,马化腾似乎突然意识到,自己已经不仅仅是一个企业家,这么大一个公司的社会责任也是义不容辞的。

不过也只有他们能这样谈,只有把企业做到对社会影响力无与伦比,这个觉悟才是真领悟吧。携程的梁建章,那只是科班的一种观点,缺乏现实的影响力和行动力。

刘主席的第三件事情,实际上是跟着第二件的,如果说大老虎主席没法大,但是各种狐狸苍蝇,刘主席可没少拍。严管妖股炒作,三涨临停,这个是最为人诟病。但实际上,中国股市里面这些妖股,我是看不惯的,完全是赌博的筹码,没有任何价值,对了,只有流动性价值。在刘主席治下,创业板是跌的稀里糊涂,但是某些被妖精炒作起来的大股票,还是涨了不少。当然18年之后,外界经济环境的变化,这个市场下跌,这又是另一个事情。

刘主席的第四件事情就是对指数的维护,这个被很多机构诟病,实际上,这也能看出屁股做的地方不一样。散户觉得不让他追涨停,就是断了发财的路,但是追涨停板能赚钱,那是头部效应,亏钱的小散不会发帖,只有赵老哥在耀武扬威。机构对打压涨停没什么意见,毕竟党委领导下的机构,可是不能参与这个游戏的。但是维护指数这个情,动不动就不然买,还有净卖出限制。

当18年10月份,证监会出台消息说,要减少对市场干预,刘主席在认错了,实际上大概已经知道自己在证监会待不久了。

其实17年就已经传易主席要接任,但奇怪的是,现在找不到那种新闻了,大概是因为被证实为谣言,各种渠道都自觉的删干净了,但实际上,微博上还是有痕迹的。

clipboard

17年的风波抗过去了,以为19大后能高升央行行长,或者外放一方诸侯,但不知是运作的问题,还是想继续治理资本市场,但18年的独角兽和CDR,终于让自己摔了跟头,主席终于还是在19年让出来了。

Posted in 思考评论 | Tagged , | Leave a comment

SVI模型拟合

波动率模型是学界搞期权的重点,BS模型中,使用的是固定的波动率。现在提的较多的是局部波动率模型和随机波动率模型。局部波动率模型是随机波动率模型的一种简化,将波动率定义为标的价格S和时间t的函数sigma(S,t),随机波动率模型中,对波动率描述存在随机项(独立于价格中的随机项)。

局部波动率模型中,常用的是SVI模型(stochastic volatility inspired),SVI模型本质上是描述了波动率微笑曲线,并且增加了一些期权性质上的约束。

我前面研究过一次SVI模型,但由于对python里面最优化函数理解的不透,对外层使用了是穷举法,这个方法显然是不好的,只是让我初次了解这个模型的性质。最近部门一个实习生用matlab实现了一下这个模型,虽然拟合的结果并不是很好,但让我发现原来matlab里面的几个函数,如lsqlin就是二次非线性最优化,而fminsearch的函数,使用的就是Nelder-Mead Simplex方法。

实际上我以前虽然也用matlab做最优化,但是对里面的求解算法实在是没研究,反正直接用就好了。但前面自己用python摸索求解函数的时候,突然觉得自己根本不知道在python里面用什么函数去求解自己要解的最优化方程。

最初以为scipy里面应该有对应的最优化函数,后来发现matlab里面基本的lsqlin在scipy里面就没有实现,scipy最接近的是lsq_liner,但这个函数只能接受上下限,无法接受不等式方程约束,后来发现用凸优化报cvxopt才有希望。但是这个包里面也没有lsqlin函数,不过知识点到这里,搜索一下lsqlin+python关键词就能找到一个俄罗斯人贡献的用python实现的lsqlin代码了。

在这些知识点的基础上,我重新将自己的svi模型实现了一下。

首先是数据源格式

  1. 合约编码    行权日 行权日 剩余到期时间(日历日) 期权类型    标的收盘价   期权行权价   收盘中间价 
  2. 10000887    20171227    2017-12-27  0.052082192 C   2.865   2.209   0.6624 
  3. 10000888    20171227    2017-12-27  0.052082192 C   2.865   2.258   0.6135 
  4. 10000889    20171227    2017-12-27  0.052082192 C   2.865   2.307   0.56465 
  5. 10000890    20171227    2017-12-27  0.052082192 C   2.865   2.356   0.5158 
  6. 10000891    20171227    2017-12-27  0.052082192 C   2.865   2.405   0.46705 
  7. 10000892    20171227    2017-12-27  0.052082192 P   2.865   2.209   0.00015 
  8. 10000893    20171227    2017-12-27  0.052082192 P   2.865   2.258   0.00015 
  9. 10000894    20171227    2017-12-27  0.052082192 P   2.865   2.307   0.00015 
  10. 10000895    20171227    2017-12-27  0.052082192 P   2.865   2.356   0.0002 
  11. 10000896    20171227    2017-12-27  0.052082192 P   2.865   2.405   0.0003 
  12. 10000897    20171227    2017-12-27  0.052082192 C   2.865   2.16    0.7117 

其次是拟合代码

  1. #!/usr/bin/env python 
  2. # encoding: utf-8 
  3. """ 
  4. @version: ?? 
  5. @author: laofish 
  6. @contact: laofish@outlook.com 
  7. @site: http://www.laofish.com 
  8. @file: fitSVI.py 
  9. @time: 2018-09-07 23:48 
  10.  
  11. 拟合SVI曲线 
  12.  
  13. """ 
  14.  
  15. import traceback 
  16.  
  17. from scipy.optimize import lsq_linear 
  18. from scipy.optimize import fmin 
  19.  
  20. from lsqlin import
  21.  
  22. from derivaties_fun2 import
  23.  
  24. from scipy.optimize import least_squares 
  25.  
  26. # 中文和负号的正常显示 
  27. import socket 
  28.  
  29. hostName = socket.gethostname() 
  30.  
  31. if hostName == 'laofish-home-PC': 
  32.     plt.rcParams['font.sans-serif'] = ['Yahei Mono']  # mat 2.1 
  33. else
  34.     plt.rcParams['font.sans-serif'] = ['Microsoft Yahei Mono'] 
  35.  
  36. plt.rcParams['axes.unicode_minus'] = False 
  37.  
  38. # 设置图形的显示风格 
  39. plt.style.use('ggplot') 
  40.  
  41.  
  42. def neicengOptimization(guess, myargs): 
  43.     '''内侧优化使用''' 
  44.     # SVI模型内层优化 
  45.     # m,sigma 为给定值,直接从参数里面得到 
  46.     # x 为自变量,即最优化问题里面的x 
  47.     # a d c 为系数,即最优化问题里面的c 
  48.  
  49.     m, sigma = guess 
  50.  
  51.     x = myargs[0] 
  52.  
  53.     omg_i = myargs[1] 
  54.  
  55.     # x = lsqlin(C,d,A,b) solves the linear system C*x = d 
  56.     # in the least-squares sense subject to A*x ≤ b, where C is m-by-n. 
  57.  
  58.     yx = (x - m) / sigma 
  59.     zx = np.sqrt(yx ** 2 + 1) 
  60.  
  61.     omega = max(omg_i) 
  62.  
  63.     # xz = np.array([np.ones([len(x), 1]).T, yx, zx]) 
  64.     xz = np.array([np.array(np.ones([len(x), 1]).T.tolist()[0]), yx, zx]) 
  65.  
  66.     # 实际上可能可以用cvxpy这个凸优化包的使用更为简单 
  67.     A = [[0, 0, -1], [0, 0, 1], [0, -1, -1], [0, 1, -1], [0, 1, 1], [0, -1, 1], [-1, 0, 0], [1, 0, 0]] 
  68.     # 约束边界b 
  69.  
  70.     b = [0, 4 * sigma, 0, 0, 4 * sigma, 4 * sigma, 0, omega] 
  71.     # lsqlin(C, d, reg=0, A=None) 
  72.     xmatric = lsqlin(xz.T, omg_i, 0, np.array(A), np.array(b)) 
  73.     acap = np.array(xmatric['x'])[0][0] 
  74.     d = np.array(xmatric['x'])[1][0] 
  75.     c = np.array(xmatric['x'])[2][0] 
  76.     # [acap, d, c]=lsqlin(xz.T, omg_i, 0, np.array(A), np.array(b)) 
  77.  
  78.     # [acap,d,c] = lsqlin(xz, omg_i,A,b) 
  79.  
  80.     a = acap 
  81.     b = c / sigma 
  82.     rho = d / c 
  83.  
  84.     # 目标函数 
  85.     sigma2 = np.sum(np.array(acap + d * yx + c * zx - omg_i) ** 2) 
  86.  
  87.     # return [a,b,rho,sigma2] 
  88.  
  89.     return sigma2 
  90.  
  91.  
  92. def neicengOptimization2(guess, myargs): 
  93.     '''返回a d c ''' 
  94.     m, sigma = guess 
  95.     x = myargs[0] 
  96.     omg_i = myargs[1] 
  97.  
  98.     yx = (x - m) / sigma 
  99.     zx = np.sqrt(yx ** 2 + 1) 
  100.  
  101.     omega = max(omg_i) 
  102.  
  103.     # xz = np.array([np.ones([len(x), 1]).T, yx, zx]) 
  104.     xz = np.array([np.array(np.ones([len(x), 1]).T.tolist()[0]), yx, zx]) 
  105.  
  106.     A = [[0, 0, -1], [0, 0, 1], [0, -1, -1], [0, 1, -1], [0, 1, 1], [0, -1, 1], [-1, 0, 0], [1, 0, 0]] 
  107.     # 约束边界b 
  108.  
  109.     b = [0, 4 * sigma, 0, 0, 4 * sigma, 4 * sigma, 0, omega] 
  110.     # lsqlin(C, d, reg=0, A=None) 
  111.     xmatric = lsqlin(xz.T, omg_i, 0, np.array(A), np.array(b)) 
  112.     acap = np.array(xmatric['x'])[0][0] 
  113.     d = np.array(xmatric['x'])[1][0] 
  114.     c = np.array(xmatric['x'])[2][0] 
  115.     # [acap, d, c]=lsqlin(xz.T, omg_i, 0, np.array(A), np.array(b)) 
  116.  
  117.     # [acap,d,c] = lsqlin(xz, omg_i,A,b) 
  118.  
  119.     a = acap 
  120.     b = c / sigma 
  121.     rho = d / c 
  122.  
  123.     # 目标函数 
  124.     # sigma2 = np.sum(np.array(acap + d * yx + c * zx - omg_i) ** 2) 
  125.     return [a, b, rho] 
  126.  
  127.  
  128. def getfitsiv(x, t2M, a_star, b_star, rho_star, m_star, sigma_star): 
  129.     '''生成拟合后的SVI波动率''' 
  130.  
  131.     # 计算拟合值 
  132.     fit_omg = a_star + b_star * (rho_star * (x - m_star) + np.sqrt((x - m_star) ** 2 + sigma_star ** 2)) 
  133.  
  134.     fsigma = np.sqrt(fit_omg / t2M) 
  135.  
  136.     return fsigma 
  137.  
  138.  
  139. if __name__ == '__main__': 
  140.  
  141.     optionData = pd.read_excel('rawOptionData.xlsx') 
  142.  
  143.     strikeArr = pd.unique(optionData['期权行权价']) 
  144.     time2Mature = pd.unique(optionData['剩余到期时间(日历日)']) 
  145.     ulprice = pd.unique(optionData['标的收盘价']) 
  146.  
  147.     r = 0.04 
  148.     S = ulprice[0] 
  149.     q = 0 
  150.  
  151.     # 鉴于国内特色,只计算call 
  152.     oD = optionData 
  153.     vArr = [] 
  154.     strikeArrE = [] 
  155.     time2MatureE = [] 
  156.     cData = pd.DataFrame() 
  157.     try
  158.         # 处理错误 
  159.  
  160.         # step 1 
  161.         # 计算期权市场的隐含波动率 
  162.         for strike in strikeArr: 
  163.             for t2M in time2Mature: 
  164.                 oprice = oD[(oD['期权行权价'] == strike) & (oD['期权类型'] == 'C') 
  165.                             & (oD['剩余到期时间(日历日)'] == t2M)]['收盘中间价'] 
  166.                 if oprice.empty == False
  167.                     cimpv = bsmImpVol(S, strike, t2M, r, q, oprice.tolist()[0], 'C') 
  168.                 else
  169.                     cimpv = 0 
  170.  
  171.                 # 这个就是隐含方差 
  172.                 # total implied variance 
  173.                 v = cimpv ** 2 * t2M 
  174.  
  175.                 vArr.append(v) 
  176.                 strikeArrE.append(strike) 
  177.                 time2MatureE.append(t2M) 
  178.  
  179.         cData['K'] = strikeArrE 
  180.         cData['t2M'] = time2MatureE 
  181.         cData['v'] = vArr 
  182.  
  183.         # 去掉v等于0的元素 
  184.         cData2 = cData[cData['v'] != 0] 
  185.  
  186.         # 论文中没提到的是,这里应该一个到期时间一个到期时间的循环 
  187.         for t2M in cData2['t2M'].unique(): 
  188.             # 扣除所需数据 
  189.             thisData = cData2[cData2['t2M'] == t2M] 
  190.             x = np.log(thisData['K'] / (S * np.exp(r * t2M))) 
  191.  
  192.             omg_i = thisData['v'].values 
  193.  
  194.             # %para为m和sigma的初值 
  195.             m = 0.1 
  196.             sigma = 0.2 
  197.  
  198.             myargs = np.array([x, omg_i])  # 需要传进去的参数 
  199.  
  200.             # arg_out= fmin(neicengOptimization, para) 
  201.             # neicengOptimization(m, sigma, myargs) 
  202.             # arg_out = fmin(neicengOptimization, x0=[m, sigma],args=(myargs,)) 
  203.             guess = [m, sigma] 
  204.             arg_out = fmin(neicengOptimization, guess, args=(myargs,)) 
  205.  
  206.             # m sigma 
  207.             m_star, sigma_star = arg_out 
  208.             # 获取a,b,rho 
  209.             a_star, b_star, rho_star = neicengOptimization2(arg_out.tolist(), myargs) 
  210.  
  211.             # =================================== 
  212.             # 绘制拟合和真是曲线 
  213.             k1 = thisData['K'].tolist() 
  214.  
  215.             # 换成隐含波动率比较 
  216.             tsigma = np.sqrt(omg_i / t2M) 
  217.  
  218.             fig = plt.figure() 
  219.             ax1 = fig.add_subplot(111)  # 在图表1中创建子图1 
  220.  
  221.             ax1.scatter(k1, tsigma, color='.25', label='Value') 
  222.  
  223.             # 生成拟合后的曲线 
  224.             # xaxis = np.linspace(min(k1), max(k1), 100) 
  225.             xaxis = np.linspace(min(k1), max(k1), 100) 
  226.             # np.log(thisData['K'] / (S * np.exp(r * t2M))) 
  227.             # 行权价转化为实际计算用x 
  228.             xbx=[np.log(x / (S * np.exp(r * t2M))) for x in xaxis] 
  229.  
  230.             yaxis = [getfitsiv(xk, t2M, a_star, b_star, rho_star, m_star, sigma_star) for xk in xbx] 
  231.  
  232.             # ax1.plot(xaxis.tolist(), yaxis, color='r--',label='fitValue') 
  233.             ax1.plot(xaxis.tolist(), yaxis, 'r--', label='fitValue') 
  234.  
  235.             # 去除图形顶部边界和右边界的刻度 
  236.             # ax1.tick_params(top='off', right='off') mat 2.1 
  237.             ax1.tick_params(top=False, right=False
  238.  
  239.             ax1.set_title('svi模型拟合对比') 
  240.  
  241.             ax1.legend() 
  242.  
  243.             plt.savefig('fitsvi_t2m=' + str(round(t2M, 3)) + '.png') 
  244.  
  245.             plt.close() 
  246.             # plt.show() 
  247.  
  248.         # 检测是否在要求阈值内 
  249.  
  250.         print(cData) 
  251.     except# 处理异常 
  252.  
  253.         traceback.print_exc() 
  254.         pass 
  255.  
  256.     print(optionData) 

最后展示一下拟合的结果

Posted in 学术研究 | Tagged , , | 5 Comments

P2P之后

最近P2P平台纷纷暴雷,除了那些一眼即可看穿的庞氏平台外,不少貌似正规的也出现呢什么老板跑路,良性清盘之类的说法。老板跑路这种恶意的就不多说了,这里良性清盘,也有可能确实是在拖延时间,但我认为遇到了流动性危机的可能性比较大。

这里就岔开说一句,为什么会遇到流动性危机。如果平台没有资金池,不能立即体现,按理来说,就不存在流动性问题,因为平台只是信息中介,借款方违约了,那最终还是要找借款人的麻烦。但实际上几乎没有P2P平台是这样操作的,因为投资人又不是专业机构在买债券,哪里看得出来某笔投资会不会违约。投P2P的说实话,都是些鸡贼的人,既要高息,又要保本,要是投资的本金初期就会有损失,这些人是不可能用这些平台的。

如此,实际上这些平台本质上采用的是以自有资金担保的保证本金(利息)模式,如果借款方违约,这些平台就需要处置这些资产,偿还投资者本金利息。由于平台实际上的角色错位,导致了就出现了流动性风险了。

而像小赢理财这样,找了众安保险给自己兜底,反而将自己搞成了独立第三方,这样看上去倒是没有流动性问题了。

不过这里想讨论的是,投资者的钱从P2P出来之后,会去哪里。这些资金,实际上是低风险承受能力,同时,流动性又非常强。

更关心的是,这些钱会不会到股市里面去,我觉得是有可能的,但是前提是,股市要不跌了,这是后面的事情。当下,这笔钱,可能还是进入头部平台,也就是陆金所这里面了,券商和银行理财也能承接小部分吧。

Posted in 思考评论 | Tagged | Leave a comment