第一部分 新手入门
- 一 量化投资视频学习课程
- 二 Python 手把手教学
- 量化分析师的Python日记【第1天:谁来给我讲讲Python?】
- 量化分析师的Python日记【第2天:再接着介绍一下Python呗】
- 量化分析师的Python日记【第3天:一大波金融Library来袭之numpy篇】
- 量化分析师的Python日记【第4天:一大波金融Library来袭之scipy篇】
- 量化分析师的Python日记【第5天:数据处理的瑞士军刀pandas】
- 量化分析师的Python日记【第6天:数据处理的瑞士军刀pandas下篇
- 量化分析师的Python日记【第7天:Q Quant 之初出江湖】
- 量化分析师的Python日记【第8天 Q Quant兵器谱之函数插值】
- 量化分析师的Python日记【第9天 Q Quant兵器谱之二叉树】
- 量化分析师的Python日记【第10天 Q Quant兵器谱 -之偏微分方程1】
- 量化分析师的Python日记【第11天 Q Quant兵器谱之偏微分方程2】
- 量化分析师的Python日记【第12天:量化入门进阶之葵花宝典:因子如何产生和回测】
- 量化分析师的Python日记【第13天 Q Quant兵器谱之偏微分方程3】
- 量化分析师的Python日记【第14天:如何在优矿上做Alpha对冲模型】
- 量化分析师的Python日记【第15天:如何在优矿上搞一个wealthfront出来】
第二部分 股票量化相关
- 一 基本面分析
- 1.1 alpha 多因子模型
- 1.2 基本面因子选股
- 1.3 财报阅读 • [米缸量化读财报] 资产负债表-投资相关资产
- 1.4 股东分析
- 1.5 宏观研究
- 二 套利
- 三 事件驱动
- 四 技术分析
- 4.1 布林带
- 4.2 均线系统
- 4.3 MACD
- 4.4 阿隆指标 • 技术指标阿隆( Aroon )全解析
- 4.5 CCI • CCI 顺势指标探索
- 4.6 RSI
- 4.7 DMI • DMI 指标体系的构建及简单应用
- 4.8 EMV • EMV 技术指标的构建及应用
- 4.9 KDJ • KDJ 策略
- 4.10 CMO
- 4.11 FPC • FPC 指标选股
- 4.12 Chaikin Volatility
- 4.13 委比 • 实时计算委比
- 4.14 封单量
- 4.15 成交量 • 决战之地, IF1507 !
- 4.16 K 线分析 • 寻找夜空中最亮的星
- 五 量化模型
- 5.1 动量模型
- 5.2 Joseph Piotroski 9 F-Score Value Investing Model
- 5.3 SVR
- 5.4 决策树、随机树
- 5.5 钟摆理论
- 5.6 海龟模型
- 5.7 5217 策略
- 5.8 SMIA
- 5.9 神经网络
- 5.10 PAMR
- 5.11 Fisher Transform
- 5.12 分型假说, Hurst 指数
- 5.13 变点理论
- 5.14 Z-score Model
- 5.15 机器学习
- 5.16 DualTrust 策略和布林强盗策略
- 5.17 卡尔曼滤波
- 5.18 LPPL anti-bubble model
- 六 大数据模型
- 6.1 市场情绪分析
- 6.2 新闻热点
- 七 排名选股系统
- 八 轮动模型
- 九 组合投资
- 十 波动率
- 十一 算法交易
- 十二 中高频交易
- 十三 Alternative Strategy
第三部分 基金、利率互换、固定收益类
- 一 分级基金
- 二 基金分析
- 三 债券
- 四 利率互换
第四部分 衍生品相关
- 一 期权数据
- 二 期权系列
- 三 期权分析
- 四 期货分析
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
量化分析师的Python日记【第10天 Q Quant兵器谱 -之偏微分方程1】
1. 热传导方程
其中:
κ
称为热传导系数[2]
称为方程的初值条件(Initial Condition)[3][4]
称为方程的边值条件 (Boundaries Condition)。这里我们使用Dirichlet条件
我们可以看一下初值条件的形状:
from matplotlib import pylab
import seaborn as sns
import numpy as np
font.set_size(20)
def initialCondition(x):
return 4.0*(1.0 - x) * x
xArray = np.linspace(0,1.0,50)
yArray = map(initialCondition, xArray)
pylab.figure(figsize = (12,6))
pylab.plot(xArray, yArray)
pylab.xlabel('$x$', fontsize = 15)
pylab.ylabel('$f(x)$', fontsize = 15)
pylab.title(u'一维热传导方程初值条件', fontproperties = font)
<matplotlib.text.Text at 0x12523810>
2. 显式差分格式
这里的基本思想是用差分格式替换对应的微分形式,并且期盼两种格式的"误差"在网格足够密的情况下会趋于0。我们分别在时间方向以及空间方向做差分格式:
合并在一起,我们就得到了原始微分方程的差分格式:
这里我们使用差分网格上的近似值Uj,k
代替uj,k
,得到新的方程:
到这里我们得到一个迭代方程组:
其中。下面我们使用Python代码实现上面的过程。
首先定义基本变量:
N
空间方向的网格数M
时间方向的网格数T
最大时间期限X
最大空间范围U
用来存储差分网格点上值得矩阵
N = 25 # x方向网格数
M = 2500 # t方向网格数
T = 1.0
X = 1.0
xArray = np.linspace(0,X,N+1)
yArray = map(initialCondition, xArray)
starValues = yArray
U = np.zeros((N+1,M+1))
U[:,0] = starValues
dx = X / N
dt = T / M
kappa = 1.0
rho = kappa * dt / dx / dx
这里我们做正向迭代:迭代时 k=0,1...M−1
, 代表我们从0时刻运行至T
for k in range(0, M):
for j in range(1, N):
U[j][k+1] = rho * U[j-1][k] + (1. - 2*rho) * U[j][k] + rho * U[j+1][k]
U[0][k+1] = 0.
U[N][k+1] = 0.
我们可以画出不同时间点 U(,˙τk)
的结果:
pylab.figure(figsize = (12,6))
pylab.plot(xArray, U[:,0])
pylab.plot(xArray, U[:, int(0.10/ dt)])
pylab.plot(xArray, U[:, int(0.20/ dt)])
pylab.plot(xArray, U[:, int(0.50/ dt)])
pylab.xlabel('$x$', fontsize = 15)
pylab.ylabel(r'$U(\dot, \tau)$', fontsize = 15)
pylab.title(u'一维热传导方程', fontproperties = font)
pylab.legend([r'$\tau = 0.$', r'$\tau = 0.10$', r'$\tau = 0.20$', r'$\tau = 0.50$'], fontsize = 15)
<matplotlib.legend.Legend at 0x12577cd0>
也可以通过三维立体图看一下整体的热传导过程:
tArray = np.linspace(0, 0.2, int(0.2 / dt) + 1)
xGrids, tGrids = np.meshgrid(xArray, tArray)
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig= pylab.figure(figsize = (16,10))
ax = fig.add_subplot(1, 1, 1, projection = '3d')
surface = ax.plot_surface(xGrids, tGrids, U[:,:int(0.2 / dt) + 1].T, cmap=cm.coolwarm)
ax.set_xlabel("$x$", fontdict={"size":18})
ax.set_ylabel(r"$\tau$", fontdict={"size":18})
ax.set_zlabel(r"$U$", fontdict={"size":18})
ax.set_title(u"热传导方程 $u_\\tau = u_{xx}$" , fontproperties = font)
fig.colorbar(surface,shrink=0.75)
<matplotlib.colorbar.Colorbar instance at 0xf6eb878>
3. 组装起来
就像在前一天二叉树建模中介绍的一样,我们这里会以面向对象的方式重新封装分散的代码,方便复用。首先是方程的描述:
class HeatEquation:
def __init__(self, kappa, X, T,
initialConstion = lambda x:4.0*x*(1.0-x), boundaryConditionL = lambda x: 0, boundaryCondtionR = lambda x:0):
self.kappa = kappa
self.ic = initialConstion
self.bcl = boundaryConditionL
self.bcr = boundaryCondtionR
self.X = X
self.T = T
下面的是显式差分格式的描述:
class ExplicitEulerScheme:
def __init__(self, M, N, equation):
self.eq = equation
self.dt = self.eq.T / M
self.dx = self.eq.X / N
self.U = np.zeros((N+1, M+1))
self.xArray = np.linspace(0,self.eq.X,N+1)
self.U[:,0] = map(self.eq.ic, self.xArray)
self.rho = self.eq.kappa * self.dt / self.dx / self.dx
self.M = M
self.N = N
def roll_back(self):
for k in range(0, self.M):
for j in range(1, self.N):
self.U[j][k+1] = self.rho * self.U[j-1][k] + (1. - 2*self.rho) * self.U[j][k] + self.rho * self.U[j+1][k]
self.U[0][k+1] = self.eq.bcl(self.xArray[0])
self.U[N][k+1] = self.eq.bcr(self.xArray[-1])
def mesh_grids(self):
tArray = np.linspace(0, self.eq.T, M+1)
tGrids, xGrids = np.meshgrid(tArray, self.xArray)
return tGrids, xGrids
有了以上的部分,现在整个过程可以简单的通过初始化和一行关于roll_back
的调用完成:
ht = HeatEquation(1.,1.,1.)
scheme = ExplicitEulerScheme(2500,25, ht)
scheme.roll_back()
我们可以获取与之前相同的图像:
tGrids, xGrids = scheme.mesh_grids()
fig= pylab.figure(figsize = (16,10))
ax = fig.add_subplot(1, 1, 1, projection = '3d')
cutoff = int(0.2 / scheme.dt) + 1
surface = ax.plot_surface(xGrids[:,:cutoff], tGrids[:,:cutoff], scheme.U[:,:cutoff], cmap=cm.coolwarm)
ax.set_xlabel("$x$", fontdict={"size":18})
ax.set_ylabel(r"$\tau$", fontdict={"size":18})
ax.set_zlabel(r"$U$", fontdict={"size":18})
ax.set_title(u"热传导方程 $u_\\tau = u_{xx}$" , fontproperties = font)
fig.colorbar(surface,shrink=0.75)
<matplotlib.colorbar.Colorbar instance at 0x12d69e60>
4. 什么时候显式格式会失败?
显式格式不能任意取时间和空间的网格点数,即M
与N
不能随意取值。我们称显式格式为条件稳定。特别地,需要满足所谓CFL条件(Courant–Friedrichs–Lewy):
例如:
M
= 2500N
= 25
则:
M
= 1200N
= 25
则:
下面的代码计算在第二种情形下的网格点计算过程:
ht = HeatEquation(1.,1.,1.)
scheme = ExplicitEulerScheme(1200,25, ht)
scheme.roll_back()
我们可以通过下图看到,在CFL条件无法满足的情况下,数值误差累计的结果(特别注意后面的锯齿):
tGrids, xGrids = scheme.mesh_grids()
fig= pylab.figure(figsize = (16,10))
ax = fig.add_subplot(1, 1, 1, projection = '3d')
cutoff = int(0.2 / scheme.dt) + 1
surface = ax.plot_surface(xGrids[:,:cutoff], tGrids[:,:cutoff], scheme.U[:,:cutoff], cmap=cm.coolwarm)
ax.set_xlabel("$x$", fontdict={"size":18})
ax.set_ylabel(r"$\tau$", fontdict={"size":18})
ax.set_zlabel(r"$U$", fontdict={"size":18})
ax.set_title(u"热传导方程 $u_\\tau = u_{xx}$, $\\rho = 0.521$" , fontproperties = font)
fig.colorbar(surface,shrink=0.75)
<matplotlib.colorbar.Colorbar instance at 0x10f51b48>
今天的日记到此为止,这个问题我们会在下一篇中进行讨论,引出无条件稳定格式:隐式差分格式(Implicit)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论