σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academy学习路线
Ctrl K
AO
+1.2k 位学习者
登录加入 ↗
学习路线
AO
+1.2k 位学习者
登录
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python 学习路线›模块 1 · 面向量化的 Python 基础›主题 1.31·~40分钟入门

向量与点积

路线进度模块 1/11 · 主题 31/33
1.31 向量与点积
—实验得分— / 100总 XP—连续天数—

向量是带有运算规则的一列数

向量是长度固定的一列有序数字,比如投资组合的权重 [0.5, 0.3, 0.2],或三只资产某一天的收益率 [0.02, -0.01, 0.03]。在 Python 里,一个浮点数列表就够用。向量可以按位置相加、缩放和组合,这也是量化金融里大量内容用它们来表达的原因。只有长度相同的两个向量才能组合;长度不一致是个你希望被明确告知的 bug。

weights = [0.5, 0.3, 0.2]
returns = [0.02, -0.01, 0.03]

# Position by position: zip pairs the elements
products = [w * r for w, r in zip(weights, returns)]
print([round(p, 4) for p in products])   # [0.01, -0.003, 0.006]

# Scaling and adding vectors
print([2 * w for w in weights])          # [1.0, 0.6, 0.4]
print([a + b for a, b in zip(weights, returns)])  # [0.52, 0.29, 0.23]

点积

点积把两个向量按位置相乘再把结果相加:a1*b1 + a2*b2 + ... + an*bn,返回一个数。当 a 是权重、b 是收益率时,它就是投资组合收益:0.5*0.02 + 0.3*(-0.01) + 0.2*0.03 = 0.013。它也是一组持仓的价值(数量点乘价格),还是回归的基本构件。在 Python 中写作 sum(x * y for x, y in zip(a, b)),并且要先检查 len(a) == len(b),因为 zip 会在较短的列表处悄悄停下。

def dot(a, b):
    if len(a) != len(b):
        raise ValueError("vectors must have the same length")
    return sum(x * y for x, y in zip(a, b))

print(dot([1, 2, 3], [4, 5, 6]))                       # 32
print(round(dot([0.5, 0.3, 0.2], [0.02, -0.01, 0.03]), 6))  # 0.013  (portfolio return)

try:
    dot([1, 2], [1, 2, 3])
except ValueError as error:
    print(error)                                       # vectors must have the same length

长度、方向与相似度

向量与自身的点积是它长度的平方,所以范数(长度)是 math.sqrt(dot(a, a)):[3, 4] 的范数是 5.0。把向量除以它的范数,得到长度为 1、只保留方向的单位向量(零向量没有方向,应当用 ValueError 拒绝)。余弦相似度 dot(a, b) / (norm(a) * norm(b)) 衡量两个向量的方向有多一致:从 -1(相反),经 0(无关,成直角),到 1(方向相同,无论尺度)。对去均值后的收益率序列使用它,就得到相关系数,这是投资组合风险中的核心量。

import math

def dot(a, b):
    return sum(x * y for x, y in zip(a, b))

def norm(a):
    return math.sqrt(dot(a, a))

print(norm([3, 4]))                                    # 5.0

def normalize(a):
    length = norm(a)
    if length == 0:
        raise ValueError("a zero vector has no direction")
    return [x / length for x in a]

print(normalize([3, 4]))                               # [0.6, 0.8]

def cosine_similarity(a, b):
    return dot(a, b) / (norm(a) * norm(b))

print(round(cosine_similarity([1, 2], [2, 4]), 6))     # 1.0   (same direction)
print(cosine_similarity([1, 0], [0, 1]))               # 0.0   (perpendicular)
print(round(cosine_similarity([1, 2], [-1, -2]), 6))   # -1.0  (opposite)
import math

def dot(a, b):
    return sum(x * y for x, y in zip(a, b))

def mean(values):
    return sum(values) / len(values)

# Correlation is the cosine of the demeaned series
a = [0.01, 0.02, -0.01, 0.03]
b = [0.02, 0.04, -0.02, 0.06]       # always twice a
da = [x - mean(a) for x in a]
db = [x - mean(b) for x in b]
corr = dot(da, db) / math.sqrt(dot(da, da) * dot(db, db))
print(round(corr, 6))               # 1.0

# Value of a book: quantities dot prices
quantities = [100, -50, 20]
prices = [184.0, 410.0, 171.0]
print(dot(quantities, prices))      # 1320.0
zip 会掩盖长度不一致;浮点数会掩盖严格相等使用 zip 之前一定要检查长度,否则会悄悄丢掉数据。另外,不要用 == 测试浮点结果:两个方向相同的向量,余弦可能得到 0.9999999999999999。要像实验测试那样用 math.isclose(...) 比较。实际工作中你很快会用到 NumPy,它的 np.dot 和 np.linalg.norm 能快速完成这些;知道它们算的是什么,才能验证它们。
  • 点积:按位置相乘再求和;先检查长度。
  • 范数 sqrt(dot(a, a));单位向量 a / norm(a)(拒绝零向量)。
  • 余弦相似度 dot(a, b) / (norm(a) * norm(b)) 取值 -1 到 1;浮点数用 isclose 比较。

下一节:矩阵与线性方程组,作用于向量并一次求解许多方程的数表。

实验:评分内容

  • 用 dot 把权重与收益率结合25 分
  • 用 norm 测量向量的长度25 分
  • 用 cosine_similarity 比较方向25 分
  • 用 normalize 把向量缩放到长度 125 分
资源管理器 · lab-31-1
▾ lab-31-1
…
bash · 浏览器内
learner@quantcraft:~/lab-31-1$
Python 尚未加载PythonLn 1, Col 1Spaces: 4UTF-8

要重置此主题吗?

lab-31-1 中的所有内容将恢复为初始文件,终端也会被清空。你当前的解答将丢失,且无法撤销。

将被重置
  • main.py → 初始代码
  • 终端历史与测试输出
  • 未提交的更改
将被保留
  • 实验最高得分
  • 你的 XP 与连续天数
  • 讲解进度与笔记

登录后即可运行你的代码。

所有讲解均可免费阅读。创建账户或登录后,即可运行代码、运行测试并提交此实验。

  • 浏览器内 IDE 与 bash 终端,无需安装
  • 即时评分、XP 以及你在学习路线中的位置
创建账户登录
或
使用 GitHub 继续