20250314修改:增加dingdanliu_nb_mflow
This commit is contained in:
228
999.账户相关/test/akshare_find_option.ipynb
Normal file
228
999.账户相关/test/akshare_find_option.ipynb
Normal 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
|
||||
}
|
||||
165
999.账户相关/test/akshare_view.py
Normal file
165
999.账户相关/test/akshare_view.py
Normal 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()
|
||||
|
||||
119
999.账户相关/test/askshare_option.py
Normal file
119
999.账户相关/test/askshare_option.py
Normal 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')
|
||||
1530
999.账户相关/test/dingdanliu_nb.py
Normal file
1530
999.账户相关/test/dingdanliu_nb.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user