20250314修改:增加dingdanliu_nb_mflow

This commit is contained in:
2025-03-15 22:40:06 +08:00
parent b814dfe535
commit e2c54c6409
89 changed files with 18394 additions and 22830 deletions

View File

@@ -0,0 +1,228 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import akshare as ak\n",
"import pandas as pd\n",
"import numpy as np\n",
"import os\n",
"import time"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"# option_df = ak.option_finance_board(symbol=\"中证1000股指期权\", end_month=\"2503\")\n",
"# option_df"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# option_cffex_df = ak.option_cffex_zz1000_spot_sina(symbol='ag2504')\n",
"option_commodity_contract_table_sina_df = ak.option_commodity_contract_table_sina(symbol=\"白银期权\", contract=\"ag2504\")\n",
"option_commodity_contract_table_sina_df"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"#根据中证l000指数获取点位\n",
"\n",
"def get_format_option_gap(value:float, deviation:int=0):\n",
" \"\"\"\n",
" 根据标准的行权价,生成不同档位的期权列表,适合中金所\n",
" :param value:当前行权价\n",
" :param deviation:相较于行权价向哪个方向偏移,>0表示较行权价向上调整<-表示较行权价向下调整\n",
" return:\n",
" \"\"\"\n",
" def _gap_value(_mark_value):\n",
" if _mark_value < 500:\n",
" return 25\n",
" elif _mark_value < 5000:\n",
" return 50\n",
" elif _mark_value < 10000:\n",
" return 100\n",
" elif _mark_value >10000:\n",
" return 200\n",
" \n",
" for i in range(abs(deviation)):\n",
" _gap =_gap_value(value)\n",
" #option a ex price=int(value/gap)*gap#买入看跌期权\n",
" if deviation >=0:\n",
" value +=_gap\n",
" elif deviation<0:\n",
" value -=_gap\n",
" return value\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"def future_to_option_code(symbol):\n",
" \"\"\"\n",
" 转换期权代码格式\n",
" \n",
" Args:\n",
" symbol (str): 原始期权代码\n",
" \n",
" Returns:\n",
" str: 转换后的期权代码\n",
" \"\"\"\n",
" symbol_upper = symbol.upper()\n",
" \n",
" if 'IM' in symbol_upper:\n",
" # 将IM替换为MO\n",
" return symbol_upper.replace('IM', 'mo')\n",
" elif 'IF' in symbol_upper:\n",
" # 将IF替换为IO\n",
" return symbol_upper.replace('IF', 'io')\n",
" elif 'IH' in symbol_upper:\n",
" # 将IH替换为HO\n",
" return symbol_upper.replace('IH', 'ho')\n",
" else:\n",
" raise ValueError(f\"不支持的期权代码格式: {symbol}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"future_to_option_code('im2503')"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"\n",
"def get_atm_option_code(symbol:str, current_price:float, call_level:int, put_level:int):\n",
" symbol_upper = symbol.upper()\n",
"\n",
" # if 'IM' in symbol_upper:\n",
" # # 将IM替换为MO\n",
" # return symbol_upper.replace('IM', 'mo')\n",
" # # print(symbol_upper)\n",
" # elif 'IF' in symbol_upper:\n",
" # # 将IF替换为IO\n",
" # return symbol_upper.replace('IF', 'io')\n",
" # elif 'IH' in symbol_upper:\n",
" # # 将IH替换为HO\n",
" # return symbol_upper.replace('IH', 'ho')\n",
" # else:\n",
" # raise ValueError(f\"不支持的期权代码格式: {symbol}\")\n",
"\n",
" # # symbol_upper = symbol_upper.lower()\n",
" # print(symbol_upper)\n",
" if 'MO' in symbol_upper:\n",
" option_cffex_df = ak.option_cffex_zz1000_spot_sina(symbol=symbol)\n",
" elif 'IO' in symbol_upper:\n",
" option_cffex_df = ak.option_cffex_hs300_spot_sina(symbol=symbol)\n",
" elif 'HO' in symbol_upper:\n",
" option_cffex_df = ak.option_cffex_sz50_spot_sina(symbol=symbol)\n",
" else:\n",
" raise ValueError(f\"不支持的期权代码格式: {symbol_upper}\")\n",
" # 提取所有行权价并转换为数值\n",
" strike_prices = option_cffex_df['行权价'].astype(float).unique()\n",
" find_call_prices = get_format_option_gap(current_price,call_level)\n",
" find_put_prices = get_format_option_gap(current_price,-put_level)\n",
" closest_call_strike = min(strike_prices, key=lambda x: abs(x - find_call_prices))\n",
" closest_put_strike = min(strike_prices, key=lambda x: abs(x - find_put_prices))\n",
" # 生成平值期权代码如MO2503-C-6250\n",
" call_atm_option_code = f\"{symbol_upper}-C-{int(closest_call_strike)}\"\n",
" put_atm_option_code = f\"{symbol_upper}-P-{int(closest_put_strike)}\"\n",
" # print(f\"平值看涨期权:{call_atm_option_code}\")\n",
" # print(f\"平值看跌期权:{put_atm_option_code}\")\n",
" return call_atm_option_code, put_atm_option_code\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"get_atm_option_code(future_to_option_code('im2503'),6273,0,0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"get_atm_option_code(future_to_option_code('ih2503'),2628,0,0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"get_atm_option_code(future_to_option_code('if2503'),3386,0,0)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"option_cffex_df = ak.option_cffex_zz1000_spot_sina(symbol='mo2503')"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"# stock_individual_spot_xq_df = ak.stock_individual_spot_xq(symbol='000852')\n",
"# print(stock_individual_spot_xq_df.dtypes)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,165 @@
import akshare as ak
import pandas as pd
import numpy as np
import os
import ast
import time
import mplfinance as mpf
import matplotlib.pyplot as plt
# from flask import Flask, render_template, jsonify
# # 读取数据(注意替换实际文件路径)
file_path = r"C:\Users\zhouj\Desktop\IM888_5MIN_2024_ofdata.csv"
df = pd.read_csv(file_path, parse_dates=["datetime"], index_col="datetime").sort_index()
# 使用akshare获取数据
symbol_name = 'IM2503'
time_period = 30
# df = ak.futures_zh_minute_sina(symbol=symbol_name, period="15")
# ultimate_smoother函数
def ultimate_smoother(price, period):
# 初始化变量(修正角度单位为弧度)
a1 = np.exp(-1.414 * np.pi / period)
b1 = 2 * a1 * np.cos(1.414 * np.pi / period) # 将180改为np.pi
c2 = b1
c3 = -a1**2
c1 = (1 + c2 - c3) / 4
# 准备输出序列
us = np.zeros(len(price))
us_new = np.zeros(len(price))
trend = [None] * (len(price))
ma_close = np.zeros(len(price))
# 前4个点用原始价格初始化
for i in range(len(price)):
if i < 4:
us[i] = price[i]
else:
# 应用递归公式
us[i] = (1 - c1) * price[i] + (2 * c1 - c2) * price[i-1] \
- (c1 + c3) * price[i-2] + c2 * us[i-1] + c3 * us[i-2]
us_new = np.around(us, decimals=2)
ma_close = price.rolling(window=5 * period).mean()
if us_new[i] > price[i] and ma_close[i] > price[i]:
trend[i] = '空头趋势'
elif us_new[i] < price[i] and ma_close[i] < price[i]:
trend[i] = '多头趋势'
else:
trend[i] = '无趋势'
return us_new, trend
def safe_literal_eval(x):
"""带异常处理的安全转换"""
try:
return ast.literal_eval(x)
except:
return [] # 返回空列表作为占位符
def add_poc_column(df):
# 安全转换列数据
df['price'] = df['price'].apply(safe_literal_eval)
df['Ask'] = df['Ask'].apply(lambda x: list(map(int, safe_literal_eval(x))))
df['Bid'] = df['Bid'].apply(lambda x: list(map(int, safe_literal_eval(x))))
# 定义处理函数(带数据验证)
def find_poc(row):
# 验证三个列表长度一致且非空
if not (len(row['price']) == len(row['Ask']) == len(row['Bid']) > 0):
return '缺值' # 返回空值标记异常数据
sums = [a + b for a, b in zip(row['Ask'], row['Bid'])]
try:
max_index = sums.index(max(sums))
return row['price'][max_index]
except ValueError:
return '缺值' # 处理空求和列表情况
# 应用处理函数
df['POC'] = df.apply(find_poc, axis=1)
# 可选:统计异常数据
error_count = df['POC'].isnull().sum()
if error_count > 0:
print(f"警告:发现 {error_count} 行异常数据已标记为NaN")
return df['POC']
df.reset_index()
# df['datetime'] = pd.to_datetime(df['datetime'])
df['终极平滑值'], df['趋势方向'] = ultimate_smoother(df["close"], time_period)
df['POC'] = add_poc_column(df)
df.index = pd.to_datetime(df.index)
print(df.head(5))
# 规范列名兼容MA列
df = df.rename(columns={"close": "Close", "open": "Open", "high": "High", "low": "Low", "volume":"Volume"})
# 创建一个新的DataFrame来存储有效的POC值
valid_poc = pd.DataFrame(index=df.index) # 创建与主数据相同索引的DataFrame
valid_poc['POC'] = df['POC'].apply(lambda x: float(x) if x != '缺值' else np.nan) # 将有效POC值转换为float无效值设为NaN
# 创建附加绘图对象(关键步骤)
apd = [
mpf.make_addplot(
df["终极平滑值"], # MA数据列
color="dodgerblue", # 线条颜色
width=1, # 线宽
panel=0, # 显示在主图区域
ylabel="终极平滑值", # 右侧Y轴标签
mav=(60),#绘制均线
secondary_y=True, # 与主图共享左侧Y轴
),
mpf.make_addplot(
valid_poc['POC'], # 使用处理后的POC值
type='scatter', # 使用散点图
marker='o', # 圆形标记
markersize=100, # 标记大小
color='yellow', # 标记颜色
alpha=0.5, # 透明度
panel=0, # 显示在主图区域
ylabel="POC", # 右侧Y轴标签
secondary_y=False, # 与主图共享左侧Y轴
)
]
# 定义 mplfinance 的自定义风格
mc = mpf.make_marketcolors(up='r', down='g', volume='inherit')
s = mpf.make_mpf_style(base_mpf_style='charles', marketcolors=mc, rc={'font.sans-serif': ['Microsoft YaHei']})
# 创建图形
fig, axes = mpf.plot(
df,
type="candle",
style=s,
addplot=apd, # 添加ultimate_smoother线和POC散点
title=f"{symbol_name} K-Line with ultimate_smoother and POC",
ylabel="Price",
show_nontrading=False,
returnfig=True # 返回图形对象
)
# 获取主图轴对象
ax = axes[0]
# 添加POC值标注
for idx, row in valid_poc.iterrows():
if pd.notnull(row['POC']):
ax.annotate(
f'{row["POC"]:.2f}',
xy=(idx, row['POC']),
xytext=(10, 10),
textcoords='offset points',
color='black',
fontsize=8,
bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5),
arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0')
)
# 显示图形
plt.show()

View File

@@ -0,0 +1,119 @@
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')

File diff suppressed because it is too large Load Diff