import numpy as np
from scipy.stats import norm
from datetime import datetime

# Black 期权定价模型（适用于期货期权）
def black_model(F, K, T, r, sigma, option_type):
    """
    F: 期货价格
    K: 执行价格
    T: 剩余到期时间（年）
    r: 无风险利率
    sigma: 波动率
    option_type: 'call' 或 'put'
    """
    d1 = (np.log(F/K) + (0.5 * sigma**2) * T) / (sigma * np.sqrt(T))
    d2 = d1 - sigma * np.sqrt(T)
    
    if option_type == 'call':
        price = np.exp(-r * T) * (F * norm.cdf(d1) - K * norm.cdf(d2))
    elif option_type == 'put':
        price = np.exp(-r * T) * (K * norm.cdf(-d2) - F * norm.cdf(-d1))
    else:
        raise ValueError("option_type must be 'call' or 'put'")
    
    return price

# 计算平值期权价格
def calculate_atm_options(F, T, r, sigma):
    """
    F: 期货价格（平值执行价 K=F）
    T: 剩余时间（年）
    r: 无风险利率
    sigma: 波动率
    返回：看涨/看跌期权价格元组
    """
    K = F  # 平值期权
    call_price = black_model(F, K, T, r, sigma, 'call')
    put_price = black_model(F, K, T, r, sigma, 'put')
    return call_price, put_price

# 计算到期时间（示例函数）
def calculate_time_to_maturity(expiry_date):
    """
    expiry_date: 期权到期日（格式：'YYYY-MM-DD'）
    返回：剩余时间（年）
    """
    today = datetime.now()
    expiry = datetime.strptime(expiry_date, '%Y-%m-%d')
    delta = expiry - today
    return delta.days / 365.0

# 合成期权策略
def synthetic_position(F, call_price, put_price, option_type):
    """
    构建合成头寸（反向推导标的资产价格）
    option_type: 要合成的标的类型（'future' 或 'option'）
    """
    if option_type == 'future':
        # 合成期货：买入看涨 + 卖出看跌（相同执行价）
        synthetic_future = call_price - put_price
        return synthetic_future
    elif option_type == 'option':
        # 反向合成期权（需要已知期货价格）
        pass  # 需要具体实现策略逻辑

# 市场参数配置（示例数据）
parameters = {
    'IM2503': {
        'expiry': '2025-03-21',  # 假设到期日
        'r': 0.028,              # 无风险利率（2.8%）
        'sigma': 0.22            # 隐含波动率（22%）
    },
    'IF2503': {
        'expiry': '2025-03-21',
        'r': 0.028,
        'sigma': 0.18
    },
    'IH2503': {
        'expiry': '2025-03-21',
        'r': 0.028,
        'sigma': 0.15
    }
}

def main(F, contract_code):
    """
    F: 期货当前价格
    contract_code: 合约代码（IM2503/IF2503/IH2503）
    """
    # 获取参数
    params = parameters[contract_code]
    T = calculate_time_to_maturity(params['expiry'])
    r = params['r']
    sigma = params['sigma']
    
    # 计算平值期权价格
    call, put = calculate_atm_options(F, T, r, sigma)
    
    # 合成期货验证（看涨看跌平价关系）
    synthetic_future = call - put
    
    # 输出结果
    print(f"\n{contract_code} 定价结果（F={F}）：")
    print(f"看涨期权价格：{call:.4f}")
    print(f"看跌期权价格：{put:.4f}")
    print(f"合成期货价值：{synthetic_future:.4f}（理论值应为0，实际误差：{synthetic_future:.2e}）")
    
    return call, put

if __name__ == "__main__":
    # 示例计算（假设当前期货价格）
    im_price = 5000.0
    if_price = 3500.0
    ih_price = 2500.0
    
    # 计算各品种平值期权
    main(im_price, 'IM2503')
    main(if_price, 'IF2503')
    main(ih_price, 'IH2503')
