SciPy 常量模块

SciPy 常量模块(scipy.constants)全面指南

scipy.constants 模块提供了物理、数学、天文常数的高精度值,是科学计算中不可或缺的参考数据源。在量化金融中,这些常数用于时间单位转换、利率计算、数值稳定性检查和模型验证。

1. 模块导入与基本使用

from scipy import constants
import numpy as np

# 基本常数查询
print(f"光速 c: {constants.c:.3e} m/s")
print(f"引力常数 G: {constants.G:.3e} m³/kg/s²")
print(f"普朗克常数 h: {constants.h:.3e} J⋅s")
print(f"阿伏伽德罗常数 N_A: {constants.N_A:.3e} /mol")
print(f"电子电荷 e: {constants.e:.3e} C")
print(f"自然对数底 e: {constants.eV:.3e}")  # 注意:eV是电子伏特,不是e

精度说明

  • 大多数常数提供CODATA 2018推荐值
  • 精度通常达到8-15位有效数字
  • 包含不确定度信息(部分常数)

2. 核心数学常数

# 数学常数(高精度)
print(f"π (pi): {constants.pi}")
print(f"e (自然对数底): {constants.e}")
print(f"黄金分割比 (golden): {constants.golden}")
print(f"欧拉-马歇罗尼常数 (gamma): {constants.gamma}")
print(f"度到弧度转换 (degree): {constants.degree}")
print(f"弧度到度转换 (radian): {constants.radian}")

# 验证数值精度
from mpmath import mp, pi, e, golden_ratio
mp.dps = 50  # 50位精度
print(f"SciPy π精度: {constants.pi}")
print(f"mpmath π精度: {float(pi)}")
print("相对误差:", abs(constants.pi - float(pi)) / float(pi))

金融应用:高精度π在圆周率测试中的使用

# Monte Carlo π估计(验证随机数质量)
def monte_carlo_pi(n_points):
    """Monte Carlo方法估计π"""
    x, y = np.random.uniform(-1, 1, (2, n_points))
    inside_circle = (x**2 + y**2) <= 1
    return 4 * inside_circle.sum() / n_points

n = 1000000
pi_estimate = monte_carlo_pi(n)
error = abs(pi_estimate - constants.pi) / constants.pi
print(f"Monte Carlo π: {pi_estimate:.6f}")
print(f"真实π: {constants.pi:.6f}")
print(f"相对误差: {error:.2%}")

3. 时间单位常数(量化金融核心)

# 时间单位转换常数
print("=== 时间单位 ===")
print(f"秒/分钟: {constants.minute}")
print(f"秒/小时: {constants.hour}")
print(f"秒/天: {constants.day}")
print(f"秒/周: {constants.week}")

# 金融时间计算
trading_days_per_year = 252
seconds_per_trading_day = constants.day
seconds_per_trading_year = trading_days_per_year * seconds_per_trading_day

print(f"交易日/年: {trading_days_per_year}")
print(f"交易年秒数: {seconds_per_trading_year:.0f}")

# 利率连续复利转换
annual_rate = 0.05  # 5%年化利率
continuous_rate = np.log(1 + annual_rate)
print(f"年化利率 {annual_rate*100}% -> 连续利率: {continuous_rate:.4f}")

实际应用:时间加权收益率计算

from datetime import datetime, timedelta

def time_weighted_return(start_time, end_time, rate):
    """时间加权收益率(使用精确时间常数)"""
    delta_t = end_time - start_time
    seconds_elapsed = delta_t.total_seconds()

    # 年化时间比例
    years_elapsed = seconds_elapsed / (constants.day * 365.25)

    # 连续复利
    continuous_return = rate * years_elapsed
    discrete_return = np.exp(continuous_return) - 1

    return {
        'years': years_elapsed,
        'continuous_return': continuous_return,
        'discrete_return': discrete_return,
        'seconds': seconds_elapsed
    }

# 示例:精确时间计算
start = datetime(2024, 1, 1)
end = datetime(2025, 1, 1)
result = time_weighted_return(start, end, 0.05)
print("精确时间加权收益率:", result)

4. 物理常数在金融建模中的应用

波动率标准化(使用基本常数)

# 布朗运动时间缩放
dt = 1 / constants.day  # 日内时间步长
sigma_daily = 0.02  # 日波动率

# 布朗运动方差缩放
variance_scaling = sigma_daily**2 * dt * constants.day
print(f"布朗运动方差缩放: {variance_scaling:.6f}")

# 温度影响交易(另类数据)
k_B = constants.k  # 玻尔兹曼常数
T_celsius = 25
T_kelvin = T_celsius + constants.zero_Celsius
thermal_energy = k_B * T_kelvin
print(f"25°C热能: {thermal_energy:.2e} J")

Black-Scholes中的物理类比

from scipy.stats import norm
from scipy.special import erf

# 使用erf实现高精度N(d)
def precise_norm_cdf(x):
    """使用erf的高精度正态累积分布"""
    return 0.5 * (1 + erf(x / np.sqrt(2)))

# 验证精度
x = 1.96  # 95%置信水平
scipy_norm = norm.cdf(x)
precise_norm = precise_norm_cdf(x)
print(f"scipy.stats.norm.cdf({x}): {scipy_norm:.10f}")
print(f"erf实现: {precise_norm:.10f}")
print(f"相对误差: {abs(scipy_norm - precise_norm)/scipy_norm:.2e}")

5. 单位转换常数

print("=== 单位转换 ===")
print(f"英寸: {constants.inch} m")
print(f"英尺: {constants.foot} m")
print(f"码: {constants.yard} m")
print(f"英里: {constants.mile} m")
print(f"海里: {constants.nautical_mile} m")
print(f"光年: {constants.ly} m")
print(f"秒差距: {constants.pc} m")  # 1 parsec

# 金融应用:外汇汇率单位转换
usd_to_cny = 7.1  # 美元兑人民币
atm_pressure = constants.atm  # 标准大气压(另类指标)
print(f"标准大气压: {atm_pressure:.3f} Pa")

加密货币时间单位(区块链)

# 比特币区块时间常数
block_time_seconds = 600  # 10分钟
blocks_per_day = constants.day / block_time_seconds
blocks_per_year = blocks_per_day * 365.25

print(f"日区块数: {blocks_per_day:.1f}")
print(f"年区块数: {blocks_per_year:.0f}")

# 难度调整周期
difficulty_adjustment_period = 2016  # 块
adjustment_interval = difficulty_adjustment_period * block_time_seconds / constants.week
print(f"难度调整间隔: {adjustment_interval:.1f} 周")

6. CODATA常数与不确定度

# CODATA推荐常数(带不确定度)
print("=== CODATA精确常数 ===")
print(f"精细结构常数 α: {constants.alpha}")
print(f"电子经典半径 r_e: {constants.electron_volt}")
print(f"电子质量 m_e: {constants.m_e}")
print(f"电子g因子: {constants.electron_g_factor}")

# 常数元数据
def print_constant_info(name):
    """打印常数详细信息"""
    const = getattr(constants, name)
    if hasattr(const, 'uncertainty'):
        print(f"{name}: {const} ± {getattr(constants, name + '_uncertainty')}")
    else:
        print(f"{name}: {const}")

print_constant_info('c')
print_constant_info('G')

不确定度传播(金融风险建模)

from uncertainties import ufloat

# 使用uncertainties库处理常数不确定度
c = ufloat(constants.c, 0.1)  # 光速(示例不确定度)
G = ufloat(constants.G, 1e-15)

# 物理量计算(传播不确定度)
orbital_period = 2 * constants.pi * ufloat(1.5e11, 1e8) ** 1.5 / np.sqrt(G * constants.M_earth)
print(f"轨道周期: {orbital_period}")
print(f"相对不确定度: {orbital_period.u/orbital_period.n:.2%}")

7. 金融专用常数计算

精确金融常数

# 日历常数
days_per_year = 365.25  # 儒略年
trading_days_per_year = 252
business_days_per_year = 260

# 秒数常数
seconds_per_trading_year = trading_days_per_year * constants.day
microseconds_per_second = 1e6
nanoseconds_per_second = 1e9

print(f"交易年秒数: {seconds_per_trading_year:.0f}")
print(f"高频交易纳秒/秒: {nanoseconds_per_second}")

# 利率基准
risk_free_rate = 0.03  # 3%无风险利率
continuously_compounded = np.log(1 + risk_free_rate)
print(f"连续复利利率: {continuously_compounded:.4f}")

# 波动率缩放
daily_vol = 0.01
annual_vol = daily_vol * np.sqrt(trading_days_per_year)
print(f"年化波动率: {annual_vol:.4f}")

债券收益率计算常数

# 债券面值常数
par_value = 1000  # 标准面值
semi_annual_periods = 2
days_in_coupon_period = constants.day / semi_annual_periods

# 实际/360日计数惯例
actual_360 = constants.day / 360
print(f"实际/360因子: {actual_360:.6f}")

# 债券久期计算
def macaulay_duration(coupon_rate, yield_rate, years, frequency=2):
    """麦考利久期(使用精确常数)"""
    periods = years * frequency
    coupon = par_value * coupon_rate / frequency
    dt = 1 / frequency

    pv_factors = [(1 + yield_rate/frequency) ** -t for t in range(1, int(periods)+1)]
    cash_flows = [coupon] * int(periods)
    cash_flows[-1] += par_value

    weighted_times = sum(t * cf * pv for t, cf, pv in zip(range(1, int(periods)+1), cash_flows, pv_factors))
    bond_price = sum(cf * pv for cf, pv in zip(cash_flows, pv_factors))

    return weighted_times / bond_price * dt

duration = macaulay_duration(0.05, 0.04, 10)
print(f"10年债券麦考利久期: {duration:.2f}年")

8. 常数在数值计算中的应用

数值稳定性测试

import sys

def test_numerical_precision():
    """测试常数在不同精度下的表现"""
    # 机器精度
    eps = np.finfo(float).eps
    print(f"机器浮点精度: {eps}")
    print(f"相对精度: {constants.pi * eps / constants.pi}")

    # π的各种表示
    pi_float = float(constants.pi)
    pi_str = eval(repr(constants.pi))

    print(f"π类型: {type(constants.pi)}")
    print(f"π字符串重构误差: {abs(pi_float - pi_str)/pi_float}")

test_numerical_precision()

高精度积分验证

from scipy.integrate import quad

def test_gaussian_integral():
    """高斯积分验证(使用精确常数)"""
    def gaussian(x, mu=0, sigma=1):
        return np.exp(-(x-mu)**2 / (2*sigma**2)) / (sigma * np.sqrt(2*constants.pi))

    result, error = quad(gaussian, -np.inf, np.inf)
    theoretical = 1.0  # 正态分布积分

    print(f"数值积分结果: {result:.10f}")
    print(f"理论值: {theoretical}")
    print(f"绝对误差: {abs(result - theoretical):.2e}")
    print(f"相对误差: {abs(result - theoretical)/theoretical:.2e}")

test_gaussian_integral()

9. 自定义金融常数集

class FinancialConstants:
    """金融专用常数集"""

    def __init__(self):
        self.trading_days_year = 252
        self.calendar_days_year = 365.25
        self.business_days_year = 260

        # 时间常数(秒)
        self.seconds_trading_year = self.trading_days_year * constants.day
        self.seconds_calendar_year = self.calendar_days_year * constants.day

        # 利率基准
        self.risk_free_rate = 0.03  # 3%
        self.inflation_rate = 0.02  # 2%

        # 波动率基准
        self.market_vol = 0.15  # 市场平均波动率
        self.vol_of_vol = 0.20  # 波动率波动率

    def get_time_scaling_factor(self, freq='daily'):
        """获取时间缩放因子"""
        if freq == 'daily':
            return np.sqrt(self.trading_days_year)
        elif freq == 'weekly':
            return np.sqrt(self.trading_days_year / 52)
        elif freq == 'monthly':
            return np.sqrt(self.trading_days_year / 12)
        return 1.0

    def annualize_return(self, period_return, freq='daily'):
        """年化收益率"""
        scaling = self.get_time_scaling_factor(freq)
        return (1 + period_return) ** (self.trading_days_year / scaling) - 1

# 使用示例
fc = FinancialConstants()
daily_ret = 0.0005
annual_ret = fc.annualize_return(daily_ret, 'daily')
print(f"日收益率 {daily_ret:.4f} -> 年化: {annual_ret:.4f}")

10. 常数在优化中的应用

约束优化中的常数使用

from scipy.optimize import minimize

# 投资组合优化(使用精确常数)
def portfolio_objective(weights, returns, cov_matrix):
    port_return = np.dot(weights, returns)
    port_risk = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))

    # 夏普比率(使用精确常数)
    risk_free = 0.03
    sharpe = (port_return - risk_free) / port_risk

    return -sharpe  # 最大化夏普比率

# 约束:权重和为1
constraints = {'type': 'eq', 'fun': lambda w: np.sum(w) - 1}
bounds = [(0, 1)] * len(returns)

result = minimize(portfolio_objective, initial_weights,
                 args=(returns, cov_matrix),
                 method='SLSQP', bounds=bounds, constraints=constraints)

11. 版本兼容性与更新

# 检查constants模块版本信息
def check_constants_version():
    """检查常数模块状态"""
    print(f"SciPy版本: {constants.__version__}")

    # CODATA版本
    codata_version = getattr(constants, 'CODATA', '未知')
    print(f"CODATA版本: {codata_version}")

    # 常数数量统计
    const_names = [attr for attr in dir(constants) 
                  if not attr.startswith('_') and 
                  not callable(getattr(constants, attr))]
    print(f"可用常数数量: {len(const_names)}")

    # 示例:最新常数
    if hasattr(constants, 'Planck_constant'):
        print("✓ 包含Planck常数(新版本)")
    else:
        print("⚠ 使用旧版常数命名")

check_constants_version()

12. 最佳实践与注意事项

1. 高精度计算

# 使用decimal模块进行超高精度计算
from decimal import Decimal, getcontext
getcontext().prec = 50

pi_decimal = Decimal(str(constants.pi))
e_decimal = Decimal(str(constants.e))
print(f"高精度π: {pi_decimal}")

2. 常数缓存

from functools import lru_cache

@lru_cache(maxsize=1)
def get_financial_constants():
    """缓存金融常数"""
    return {
        'pi': constants.pi,
        'e': constants.e,
        'trading_days_year': 252,
        'seconds_per_day': constants.day
    }

constants_cache = get_financial_constants()

3. 单位测试

import unittest

class TestConstants(unittest.TestCase):
    def test_pi_accuracy(self):
        self.assertAlmostEqual(constants.pi, 3.141592653589793, places=15)

    def test_time_constants(self):
        self.assertEqual(constants.minute, 60.0)
        self.assertGreater(constants.day, 86400.0)

    def test_equality(self):
        self.assertAlmostEqual(np.exp(1), constants.e, places=15)

if __name__ == '__main__':
    unittest.main(argv=[''], exit=False, verbosity=2)

scipy.constants模块虽然看似简单,但其高精度常数在金融计算中确保了模型精度和数值稳定性。特别是在高频交易、期权定价和风险管理中,精确的数学常数和时间单位转换至关重要。需要特定常数在复杂模型中的应用示例,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注