siat 3.10.130__py3-none-any.whl → 3.10.132__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. build/lib/build/lib/siat/__init__.py +75 -0
  2. build/lib/build/lib/siat/allin.py +137 -0
  3. build/lib/build/lib/siat/assets_liquidity.py +915 -0
  4. build/lib/build/lib/siat/beta_adjustment.py +1058 -0
  5. build/lib/build/lib/siat/beta_adjustment_china.py +548 -0
  6. build/lib/build/lib/siat/blockchain.py +143 -0
  7. build/lib/build/lib/siat/bond.py +2900 -0
  8. build/lib/build/lib/siat/bond_base.py +992 -0
  9. build/lib/build/lib/siat/bond_china.py +100 -0
  10. build/lib/build/lib/siat/bond_zh_sina.py +143 -0
  11. build/lib/build/lib/siat/capm_beta.py +783 -0
  12. build/lib/build/lib/siat/capm_beta2.py +887 -0
  13. build/lib/build/lib/siat/common.py +5360 -0
  14. build/lib/build/lib/siat/compare_cross.py +642 -0
  15. build/lib/build/lib/siat/copyrights.py +18 -0
  16. build/lib/build/lib/siat/cryptocurrency.py +667 -0
  17. build/lib/build/lib/siat/economy.py +1471 -0
  18. build/lib/build/lib/siat/economy2.py +1853 -0
  19. build/lib/build/lib/siat/esg.py +536 -0
  20. build/lib/build/lib/siat/event_study.py +815 -0
  21. build/lib/build/lib/siat/fama_french.py +1521 -0
  22. build/lib/build/lib/siat/fin_stmt2_yahoo.py +982 -0
  23. build/lib/build/lib/siat/financial_base.py +1160 -0
  24. build/lib/build/lib/siat/financial_statements.py +598 -0
  25. build/lib/build/lib/siat/financials.py +2339 -0
  26. build/lib/build/lib/siat/financials2.py +1278 -0
  27. build/lib/build/lib/siat/financials_china.py +4433 -0
  28. build/lib/build/lib/siat/financials_china2.py +2212 -0
  29. build/lib/build/lib/siat/fund.py +629 -0
  30. build/lib/build/lib/siat/fund_china.py +3307 -0
  31. build/lib/build/lib/siat/future_china.py +551 -0
  32. build/lib/build/lib/siat/google_authenticator.py +47 -0
  33. build/lib/build/lib/siat/grafix.py +3636 -0
  34. build/lib/build/lib/siat/holding_risk.py +867 -0
  35. build/lib/build/lib/siat/luchy_draw.py +638 -0
  36. build/lib/build/lib/siat/market_china.py +1168 -0
  37. build/lib/build/lib/siat/markowitz.py +2363 -0
  38. build/lib/build/lib/siat/markowitz2.py +3150 -0
  39. build/lib/build/lib/siat/markowitz2_20250704.py +2969 -0
  40. build/lib/build/lib/siat/markowitz2_20250705.py +3158 -0
  41. build/lib/build/lib/siat/markowitz_simple.py +373 -0
  42. build/lib/build/lib/siat/ml_cases.py +2291 -0
  43. build/lib/build/lib/siat/ml_cases_example.py +60 -0
  44. build/lib/build/lib/siat/option_china.py +3069 -0
  45. build/lib/build/lib/siat/option_pricing.py +1925 -0
  46. build/lib/build/lib/siat/other_indexes.py +409 -0
  47. build/lib/build/lib/siat/risk_adjusted_return.py +1576 -0
  48. build/lib/build/lib/siat/risk_adjusted_return2.py +1900 -0
  49. build/lib/build/lib/siat/risk_evaluation.py +2218 -0
  50. build/lib/build/lib/siat/risk_free_rate.py +351 -0
  51. build/lib/build/lib/siat/sector_china.py +4140 -0
  52. build/lib/build/lib/siat/security_price2.py +727 -0
  53. build/lib/build/lib/siat/security_prices.py +3408 -0
  54. build/lib/build/lib/siat/security_trend.py +402 -0
  55. build/lib/build/lib/siat/security_trend2.py +646 -0
  56. build/lib/build/lib/siat/stock.py +4284 -0
  57. build/lib/build/lib/siat/stock_advice_linear.py +934 -0
  58. build/lib/build/lib/siat/stock_base.py +26 -0
  59. build/lib/build/lib/siat/stock_china.py +2095 -0
  60. build/lib/build/lib/siat/stock_prices_kneighbors.py +910 -0
  61. build/lib/build/lib/siat/stock_prices_linear.py +386 -0
  62. build/lib/build/lib/siat/stock_profile.py +707 -0
  63. build/lib/build/lib/siat/stock_technical.py +3305 -0
  64. build/lib/build/lib/siat/stooq.py +74 -0
  65. build/lib/build/lib/siat/transaction.py +347 -0
  66. build/lib/build/lib/siat/translate.py +5183 -0
  67. build/lib/build/lib/siat/valuation.py +1378 -0
  68. build/lib/build/lib/siat/valuation_china.py +2076 -0
  69. build/lib/build/lib/siat/var_model_validation.py +444 -0
  70. build/lib/build/lib/siat/yf_name.py +811 -0
  71. build/lib/siat/__init__.py +75 -0
  72. build/lib/siat/allin.py +137 -0
  73. build/lib/siat/assets_liquidity.py +915 -0
  74. build/lib/siat/beta_adjustment.py +1058 -0
  75. build/lib/siat/beta_adjustment_china.py +548 -0
  76. build/lib/siat/blockchain.py +143 -0
  77. build/lib/siat/bond.py +2900 -0
  78. build/lib/siat/bond_base.py +992 -0
  79. build/lib/siat/bond_china.py +100 -0
  80. build/lib/siat/bond_zh_sina.py +143 -0
  81. build/lib/siat/capm_beta.py +783 -0
  82. build/lib/siat/capm_beta2.py +887 -0
  83. build/lib/siat/common.py +5360 -0
  84. build/lib/siat/compare_cross.py +642 -0
  85. build/lib/siat/copyrights.py +18 -0
  86. build/lib/siat/cryptocurrency.py +667 -0
  87. build/lib/siat/economy.py +1471 -0
  88. build/lib/siat/economy2.py +1853 -0
  89. build/lib/siat/esg.py +536 -0
  90. build/lib/siat/event_study.py +815 -0
  91. build/lib/siat/fama_french.py +1521 -0
  92. build/lib/siat/fin_stmt2_yahoo.py +982 -0
  93. build/lib/siat/financial_base.py +1160 -0
  94. build/lib/siat/financial_statements.py +598 -0
  95. build/lib/siat/financials.py +2339 -0
  96. build/lib/siat/financials2.py +1278 -0
  97. build/lib/siat/financials_china.py +4433 -0
  98. build/lib/siat/financials_china2.py +2212 -0
  99. build/lib/siat/fund.py +629 -0
  100. build/lib/siat/fund_china.py +3307 -0
  101. build/lib/siat/future_china.py +551 -0
  102. build/lib/siat/google_authenticator.py +47 -0
  103. build/lib/siat/grafix.py +3636 -0
  104. build/lib/siat/holding_risk.py +867 -0
  105. build/lib/siat/luchy_draw.py +638 -0
  106. build/lib/siat/market_china.py +1168 -0
  107. build/lib/siat/markowitz.py +2363 -0
  108. build/lib/siat/markowitz2.py +3150 -0
  109. build/lib/siat/markowitz2_20250704.py +2969 -0
  110. build/lib/siat/markowitz2_20250705.py +3158 -0
  111. build/lib/siat/markowitz_simple.py +373 -0
  112. build/lib/siat/ml_cases.py +2291 -0
  113. build/lib/siat/ml_cases_example.py +60 -0
  114. build/lib/siat/option_china.py +3069 -0
  115. build/lib/siat/option_pricing.py +1925 -0
  116. build/lib/siat/other_indexes.py +409 -0
  117. build/lib/siat/risk_adjusted_return.py +1576 -0
  118. build/lib/siat/risk_adjusted_return2.py +1900 -0
  119. build/lib/siat/risk_evaluation.py +2218 -0
  120. build/lib/siat/risk_free_rate.py +351 -0
  121. build/lib/siat/sector_china.py +4140 -0
  122. build/lib/siat/security_price2.py +727 -0
  123. build/lib/siat/security_prices.py +3408 -0
  124. build/lib/siat/security_trend.py +402 -0
  125. build/lib/siat/security_trend2.py +646 -0
  126. build/lib/siat/stock.py +4284 -0
  127. build/lib/siat/stock_advice_linear.py +934 -0
  128. build/lib/siat/stock_base.py +26 -0
  129. build/lib/siat/stock_china.py +2095 -0
  130. build/lib/siat/stock_prices_kneighbors.py +910 -0
  131. build/lib/siat/stock_prices_linear.py +386 -0
  132. build/lib/siat/stock_profile.py +707 -0
  133. build/lib/siat/stock_technical.py +3305 -0
  134. build/lib/siat/stooq.py +74 -0
  135. build/lib/siat/transaction.py +347 -0
  136. build/lib/siat/translate.py +5183 -0
  137. build/lib/siat/valuation.py +1378 -0
  138. build/lib/siat/valuation_china.py +2076 -0
  139. build/lib/siat/var_model_validation.py +444 -0
  140. build/lib/siat/yf_name.py +811 -0
  141. siat/__init__.py +0 -0
  142. siat/allin.py +0 -0
  143. siat/assets_liquidity.py +0 -0
  144. siat/beta_adjustment.py +0 -0
  145. siat/beta_adjustment_china.py +0 -0
  146. siat/blockchain.py +0 -0
  147. siat/bond.py +0 -0
  148. siat/bond_base.py +0 -0
  149. siat/bond_china.py +0 -0
  150. siat/bond_zh_sina.py +0 -0
  151. siat/capm_beta.py +0 -0
  152. siat/capm_beta2.py +0 -0
  153. siat/common.py +94 -30
  154. siat/compare_cross.py +0 -0
  155. siat/copyrights.py +0 -0
  156. siat/cryptocurrency.py +0 -0
  157. siat/economy.py +0 -0
  158. siat/economy2.py +0 -0
  159. siat/esg.py +0 -0
  160. siat/event_study.py +0 -0
  161. siat/fama_french.py +0 -0
  162. siat/fin_stmt2_yahoo.py +0 -0
  163. siat/financial_base.py +0 -0
  164. siat/financial_statements.py +0 -0
  165. siat/financials.py +0 -0
  166. siat/financials2.py +0 -0
  167. siat/financials_china.py +0 -0
  168. siat/financials_china2.py +0 -0
  169. siat/fund.py +0 -0
  170. siat/fund_china.py +0 -0
  171. siat/future_china.py +0 -0
  172. siat/google_authenticator.py +0 -0
  173. siat/grafix.py +1 -1
  174. siat/holding_risk.py +0 -0
  175. siat/luchy_draw.py +0 -0
  176. siat/market_china.py +7 -1
  177. siat/markowitz.py +0 -0
  178. siat/markowitz2.py +240 -39
  179. siat/markowitz2_20250704.py +2969 -0
  180. siat/markowitz2_20250705.py +3158 -0
  181. siat/markowitz_simple.py +0 -0
  182. siat/ml_cases.py +0 -0
  183. siat/ml_cases_example.py +0 -0
  184. siat/option_china.py +0 -0
  185. siat/option_pricing.py +0 -0
  186. siat/other_indexes.py +0 -0
  187. siat/risk_adjusted_return.py +0 -0
  188. siat/risk_adjusted_return2.py +0 -0
  189. siat/risk_evaluation.py +0 -0
  190. siat/risk_free_rate.py +0 -0
  191. siat/sector_china.py +0 -0
  192. siat/security_price2.py +0 -0
  193. siat/security_prices.py +3 -1
  194. siat/security_trend.py +0 -0
  195. siat/security_trend2.py +1 -1
  196. siat/stock.py +4 -2
  197. siat/stock_advice_linear.py +0 -0
  198. siat/stock_base.py +0 -0
  199. siat/stock_china.py +0 -0
  200. siat/stock_prices_kneighbors.py +0 -0
  201. siat/stock_prices_linear.py +0 -0
  202. siat/stock_profile.py +0 -0
  203. siat/stock_technical.py +0 -0
  204. siat/stooq.py +0 -0
  205. siat/transaction.py +0 -0
  206. siat/translate.py +11 -11
  207. siat/valuation.py +0 -0
  208. siat/valuation_china.py +0 -0
  209. siat/var_model_validation.py +0 -0
  210. siat/yf_name.py +0 -0
  211. {siat-3.10.130.dist-info → siat-3.10.132.dist-info}/METADATA +11 -11
  212. siat-3.10.132.dist-info/RECORD +218 -0
  213. siat-3.10.132.dist-info/top_level.txt +4 -0
  214. siat-3.10.130.dist-info/RECORD +0 -76
  215. siat-3.10.130.dist-info/top_level.txt +0 -1
  216. {siat-3.10.130.dist-info → siat-3.10.132.dist-info}/WHEEL +0 -0
  217. {siat-3.10.130.dist-info → siat-3.10.132.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,3069 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 本模块功能:期权定价趋势分析,仅限于中国大陆的期权产品
4
+ 所属工具包:证券投资分析工具SIAT
5
+ SIAT:Security Investment Analysis Tool
6
+ 创建日期:2020年7月16日
7
+ 最新修订日期:2020年8月5日
8
+ 作者:王德宏 (WANG Dehong, Peter)
9
+ 作者单位:北京外国语大学国际商学院
10
+ 作者邮件:wdehong2000@163.com
11
+ 版权所有:王德宏
12
+ 用途限制:仅限研究与教学使用,不可商用!商用需要额外授权。
13
+ 特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
14
+ """
15
+ #==============================================================================
16
+ #关闭所有警告
17
+ import warnings; warnings.filterwarnings('ignore')
18
+ #==============================================================================
19
+
20
+ from siat.common import *
21
+ from siat.grafix import *
22
+ from siat.security_prices import *
23
+ from siat.option_pricing import *
24
+ from siat.fama_french import *
25
+
26
+ import pandas as pd
27
+ #==============================================================================
28
+ if __name__=='__main__':
29
+ symbol='黄金期权'
30
+
31
+ def option_comm_dict_china(symbol="玉米期权"):
32
+ """
33
+ 获取中国商品期权大类合约
34
+ 显示symbol类期权的可用合约列表
35
+ """
36
+ import akshare as ak
37
+ import datetime
38
+ today = datetime.date.today()
39
+
40
+ try:
41
+ #optiondict=ak.option_sina_commodity_dict(symbol=symbol)
42
+ optiondict=ak.option_commodity_contract_sina(symbol=symbol)
43
+ print("\n中国"+symbol+"的当前可用合约:")
44
+ #contractlist=optiondict[symbol]
45
+ contractlist=list(optiondict['合约'])
46
+ contractlist.sort(reverse=False)
47
+ #print(contractlist)
48
+ printlist(contractlist,numperline=8,beforehand=' '*4,separator=' ')
49
+ print('*** 注:合约代码后四位数字为合约到期日YYMM')
50
+ print(' 每种合约还将分为看涨(C)/看跌(P)两个方向和不同的行权价')
51
+ print(' 数据来源:新浪财经,',today)
52
+ return optiondict
53
+ except:
54
+ print(" #Error(option_com_china): failed to get dict info for",symbol)
55
+ print(" Solution: upgrade siat and akshare plug-in, then try again")
56
+ print(" If problem remains, report to the author via wechat or email.")
57
+ return None
58
+
59
+ if __name__=='__main__':
60
+ df=option_comm_dict_china(symbol='黄金期权')
61
+ #==============================================================================
62
+ if __name__=='__main__':
63
+ symbol='黄金期权'
64
+ contract='au2508'
65
+ printout=True
66
+ graph=True
67
+
68
+ df=option_comm_china(symbol='黄金期权',contract='au2508')
69
+
70
+ def option_comm_china(symbol='',contract='', \
71
+ twinx=True,
72
+ loc1='upper left',loc2='upper right', \
73
+ printout=True,graph=True):
74
+ """
75
+ 获取中国商品期权大类
76
+ 若symbol=''或错误且contract=''时显示中国商品期权大类
77
+ 若symbol查到且contract=''或未查到时显示该类期权的合约列表
78
+ 若symbol查到且contract查到时显示该类期权合约的价格与持仓量分析
79
+ """
80
+ import akshare as ak
81
+ import datetime
82
+ today = datetime.date.today()
83
+
84
+ symbollist=['豆粕期权','玉米期权','铁矿石期权','棉花期权','白糖期权','PTA期权', \
85
+ '甲醇期权','橡胶期权','沪铜期权','黄金期权','菜籽粕期权', \
86
+ '液化石油气期权','动力煤期权']
87
+ if not (symbol in symbollist):
88
+ print("\n中国商品期权的常见品种:")
89
+ #print(symbollist)
90
+ printlist(symbollist,numperline=6,beforehand=' '*4,separator=' ')
91
+ print('*** 数据来源:新浪财经,',today)
92
+ return symbollist
93
+
94
+ #symbol=underlying+'期权'
95
+ if (symbol in symbollist) and (contract==''):
96
+ optiondict=option_comm_dict_china(symbol)
97
+ return optiondict
98
+
99
+ try:
100
+ df2=ak.option_commodity_contract_table_sina(symbol=symbol,contract=contract)
101
+ except:
102
+ print(" #Error(option_com_china): contract",contract,'not found in',symbol)
103
+ optiondict=option_comm_dict_china(symbol)
104
+ return optiondict
105
+
106
+ #df2cols=['买量C','买价C','最新价C','卖价C','卖量C','持仓量C','涨跌C','行权价','看涨期权合约','买量P','买价P','最新价P','卖价P','卖量P','持仓量P','涨跌P','看跌期权合约']
107
+ df2cols=['看涨合约-买量','看涨合约-买价','看涨合约-最新价','看涨合约-卖价', \
108
+ '看涨合约-卖量','看涨合约-持仓量','看涨合约-涨跌','行权价', \
109
+ '看涨合约-看涨期权合约', \
110
+ '看跌合约-买量','看跌合约-买价','看跌合约-最新价','看跌合约-卖价', \
111
+ '看跌合约-卖量','看跌合约-持仓量','看跌合约-涨跌','看跌合约-看跌期权合约']
112
+ df2.columns=df2cols
113
+
114
+ df2['最新价C']=df2['看涨合约-最新价'].astype('float')
115
+ df2['持仓量C']=df2['看涨合约-持仓量'].astype('float')
116
+ df2['最新价P']=df2['看跌合约-最新价'].astype('float')
117
+ df2['持仓量P']=df2['看跌合约-持仓量'].astype('float')
118
+ df2['行权价']=df2['行权价'].astype('float')
119
+
120
+ df2['看涨期权合约']=df2['看涨合约-看涨期权合约']
121
+ df2['看跌期权合约']=df2['看跌合约-看跌期权合约']
122
+
123
+ df2.set_index('行权价',inplace=True)
124
+
125
+ if printout:
126
+ df2c=df2['看涨期权合约']
127
+ df2c.dropna(inplace=True)
128
+ df2clist=list(df2c)
129
+ print(" \n中国"+symbol+contract+"的看涨期权合约:")
130
+ printlist(df2clist,numperline=6,beforehand=' '*4,separator=' ')
131
+ df2p=df2['看跌期权合约']
132
+ df2p.dropna(inplace=True)
133
+ df2plist=list(df2p)
134
+ print(" \n中国"+symbol+contract+"的看跌期权合约:")
135
+ printlist(df2plist,numperline=6,beforehand=' '*4,separator=' ')
136
+
137
+ if graph:
138
+ if not (twinx in ['UD','LR']):
139
+ footnote="行权价-->\n\n"+"数据来源:新浪财经,"+str(today)
140
+ else:
141
+ footnote="行权价-->\n"+"数据来源:新浪财经,"+str(today)
142
+
143
+ print("\nRendering graphics btw contract and strike prices...")
144
+ titletxt="期权价格与行权价的关系:"+symbol+contract
145
+ # maxticks为bool类型时表示横轴不能按照日期处理,否则会丢失数据成空图!!!
146
+ plot_line2(df2,"看涨期权",'最新价C','价格', \
147
+ df2,"看跌期权",'最新价P','价格', \
148
+ '价格',titletxt,footnote,power=0, \
149
+ twinx=twinx, \
150
+ loc1=loc1,loc2=loc2, \
151
+ maxticks=False)
152
+ """
153
+ print("Rendering graphics for the relationships btw call price and open interest ...")
154
+ titletxt="当前期权价格与持仓量的关系:"+symbol+contract+'的'+"看涨期权"
155
+ plot_line2(df2,"看涨期权",'最新价C','价格', \
156
+ df2,"看涨期权",'持仓量C','持仓量', \
157
+ '',titletxt,footnote,power=0,twinx=True)
158
+
159
+ print("Rendering graphics for the relationships btw put price and open interest ...")
160
+ titletxt="当前期权价格与持仓量的关系:"+symbol+contract+'的'+"看跌期权"
161
+ plot_line2(df2,"看跌期权",'最新价P','价格', \
162
+ df2,"看跌期权",'持仓量P','持仓量', \
163
+ '',titletxt,footnote,power=0,twinx=True)
164
+
165
+ print("Rendering graphics for the relationships btw open interests ...")
166
+ titletxt="当前期权方向与持仓量的关系:"+symbol+contract
167
+ plot_line2(df2,"看涨期权",'持仓量C','持仓量', \
168
+ df2,"看跌期权",'持仓量P','持仓量', \
169
+ '',titletxt,footnote,power=0,twinx=False)
170
+ """
171
+ return df2
172
+ #==============================================================================
173
+
174
+
175
+ def check_contract(contract):
176
+ """
177
+ 功能:检查新浪期权数据中一项合约是否存在
178
+ """
179
+ # 太啰嗦了,暂时不做了
180
+
181
+ #==============================================================================
182
+ if __name__=='__main__':
183
+ contract='au2212C324'
184
+ contract='pg2212C3850'
185
+ contract=['au2212C324','au2212P324']
186
+ contract=[]
187
+ power=0
188
+ twinx=False
189
+ start='2022-7-1'
190
+ end='2022-11-6'
191
+
192
+ def option_comm_trend_china(contract,start='',end='',power=0, \
193
+ twinx=False,loc1='best',loc2='best'):
194
+ """
195
+ 绘制期权合约价格历史价格趋势图
196
+ 若contract为一个合约,则绘制单折线图
197
+ 若contract为多于一个合约,则绘制前两个合约的双单折线图
198
+ """
199
+
200
+ contract1=contract2=''
201
+ if isinstance(contract,str):
202
+ contract1=contract
203
+ contract2=''
204
+
205
+ if isinstance(contract,list):
206
+ if len(contract)==1:
207
+ contract1=contract
208
+ contract2=''
209
+ elif len(contract)>=2:
210
+ contract1=contract[0]
211
+ contract2=contract[1]
212
+
213
+ if contract1=='':
214
+ print(" #Error(option_comm_trend_china): unknown option contract",contract)
215
+ return None
216
+
217
+ import pandas as pd
218
+ start1=end1=''
219
+ if not (start==''):
220
+ try:
221
+ start1=pd.to_datetime(start)
222
+ except:
223
+ print(" #Error(option_comm_trend_china): invalid date",start)
224
+ if not (end==''):
225
+ try:
226
+ end1=pd.to_datetime(end)
227
+ except:
228
+ print(" #Error(option_comm_trend_china): invalid date",end)
229
+
230
+ import akshare as ak
231
+ import datetime
232
+ today = datetime.date.today()
233
+ footnote="数据来源:新浪财经,"+str(today)
234
+
235
+ #绘制单折线
236
+ if contract2=='':
237
+ contract1,dict1=option_comm_contract_decode_china(contract1)
238
+ try:
239
+ #df3=ak.option_sina_commodity_hist(contract=contract1)
240
+ df3=ak.option_commodity_hist_sina(symbol=contract1)
241
+ except:
242
+ print(" #Error(option_comm_trend_china): data unavailable for",contract1)
243
+ print(" Possible reasons: no such contract or no tradings for the contract")
244
+ return None
245
+
246
+ if len(df3)==0:
247
+ print(" #Warning(option_comm_trend_china): no record found for contract",contract1)
248
+ return None
249
+
250
+ df3['date2']=pd.to_datetime(df3['date'])
251
+ df3.set_index('date2',inplace=True)
252
+ df3['close']=df3['close'].astype('float')
253
+
254
+ if not (start1==''):
255
+ df3=df3.drop(df3[df3.index < start1].index)
256
+ if not (end1==''):
257
+ df3=df3.drop(df3[df3.index > end1].index)
258
+
259
+ print(" Rendering graphics for option contract price trend...")
260
+ titletxt="期权合约价格的运动趋势:"+contract1
261
+ footnote=contract1+':'+dict1['标的物']+dict1['期权方向']+','+dict1['到期日']+'到期'+',行权价'+dict1['行权价']+'\n'+footnote
262
+ plot_line(df3,'close','收盘价','价格',titletxt,footnote,power=power)
263
+ return df3
264
+
265
+ #绘制双折线
266
+ contract1ok=contract2ok=True
267
+ if not (contract2==''):
268
+ contract1,dict1=option_comm_contract_decode_china(contract1)
269
+ try:
270
+ df31=ak.option_commodity_hist_sina(symbol=contract1)
271
+ df31['date2']=pd.to_datetime(df31['date'])
272
+ df31.set_index('date2',inplace=True)
273
+ df31['close']=df31['close'].astype('float')
274
+ except:
275
+ print(" #Error(option_comm_trend_china): data unavailable for",contract1)
276
+ print(" Possible reasons: no such contract or no tradings for the contract")
277
+ contract1ok=False
278
+ if contract1ok:
279
+ if not (start1==''):
280
+ df31=df31.drop(df31[df31.index < start1].index)
281
+ if not (end1==''):
282
+ df31=df31.drop(df31[df31.index > end1].index)
283
+
284
+ if len(df31)==0:
285
+ #print(" #Warning(option_comm_trend_china): no record found for contract",contract1)
286
+ contract1ok=False
287
+
288
+ contract2,dict2=option_comm_contract_decode_china(contract2)
289
+ try:
290
+ df32=ak.option_commodity_hist_sina(symbol=contract2)
291
+ df32['date2']=pd.to_datetime(df32['date'])
292
+ df32.set_index('date2',inplace=True)
293
+ df32['close']=df32['close'].astype('float')
294
+ except:
295
+ print(" #Error(option_comm_trend_china): data unavailable for",contract2)
296
+ print(" Possible reasons: no such contract or no tradings for the contract")
297
+ contract2ok=False
298
+ if contract2ok:
299
+ if not (start1==''):
300
+ df32=df32.drop(df32[df32.index < start1].index)
301
+ if not (end1==''):
302
+ df32=df32.drop(df32[df32.index > end1].index)
303
+
304
+ if len(df32)==0:
305
+ #print(" #Warning(option_comm_trend_china): no record found for contract",contract2)
306
+ contract2ok=False
307
+
308
+ if contract1ok and contract2ok:
309
+ print(" Rendering graphics for comparing two option contract price trends...")
310
+ titletxt="期权价格的运动趋势对比:"+contract1+'与'+contract2
311
+ footnote=contract2+':'+dict2['标的物']+dict2['期权方向']+','+dict2['到期日']+'到期'+',行权价'+dict2['行权价']+'\n'+footnote
312
+ footnote=contract1+':'+dict1['标的物']+dict1['期权方向']+','+dict1['到期日']+'到期'+',行权价'+dict1['行权价']+'\n'+footnote
313
+
314
+ plot_line2(df31,contract1,'close','收盘价', \
315
+ df32,contract2,'close','收盘价', \
316
+ '价格',titletxt,footnote,twinx=twinx,loc1=loc1,loc2=loc2)
317
+ return df31,df32
318
+ elif contract1ok:
319
+ print(" Rendering graphics for option contract price trend...")
320
+ titletxt="期权合约价格的运动趋势:"+contract1
321
+ footnote=contract1+':'+dict1['标的物']+dict1['期权方向']+','+dict1['到期日']+'到期'+',行权价'+dict1['行权价']+'\n'+footnote
322
+
323
+ plot_line(df31,'close','收盘价','价格',titletxt,footnote,power=power,loc=loc1)
324
+ return df31
325
+ elif contract2ok:
326
+ print(" Rendering graphics for option contract price trend...")
327
+ titletxt="期权合约价格的运动趋势:"+contract2
328
+ footnote=contract2+':'+dict2['标的物']+dict2['期权方向']+','+dict2['到期日']+'到期'+',行权价'+dict2['行权价']+'\n'+footnote
329
+
330
+ plot_line(df32,'close','收盘价','价格',titletxt,footnote,power=power,loc=loc1)
331
+ return df32
332
+ else:
333
+ print(" #Warning(option_comm_trend_china): no record found for contracts",contract1,'and',contract2)
334
+ return None
335
+
336
+ #==============================================================================
337
+ if __name__=='__main__':
338
+ contract='xu2112'
339
+ contract='au2112C328'
340
+
341
+ def option_comm_contract_decode_china(contract):
342
+ """
343
+ 例:
344
+ contract='c2111'或'cf2111'
345
+ contract='c2111C235'或'cf2111P235'
346
+ """
347
+
348
+ prelist=['m','c','i','cf','sr','ta','ma','ru','cu','au','rm','pg','zc']
349
+ ualist=['豆粕','玉米','铁矿石','棉花','白糖','PTA','甲醇','橡胶','沪铜','黄金','菜籽粕','液化石油气','动力煤']
350
+
351
+ import string
352
+ ucletters=list(string.ascii_uppercase)
353
+ lcletters=list(string.ascii_lowercase)
354
+
355
+ pos=0
356
+ contract1=contract.lower()
357
+ for c in contract1:
358
+ if c in lcletters:
359
+ pos=pos+1
360
+ else:
361
+ break
362
+ prefix=contract1[:pos]
363
+ yymm=contract1[pos:pos+4]
364
+ maturity='20'+yymm[:2]+'-'+yymm[2:] #到期年月
365
+
366
+ direction=''
367
+ strike=''
368
+ if len(contract1)>6:
369
+ direction=contract1[pos+4:pos+5]
370
+ direction=direction.upper() #期权方向
371
+ contract2=contract1[:pos+4]+direction+contract1[pos+5:]
372
+ strike=contract1[pos+5:] #行权价
373
+
374
+ if direction=='C':
375
+ otype="看涨期权"
376
+ elif direction=='P':
377
+ otype="看跌期权"
378
+ else:
379
+ otype="未知"
380
+ else:
381
+ contract2=contract1
382
+
383
+ try:
384
+ pos1=prelist.index(prefix)
385
+ ua=ualist[pos1] #期权标的物类别
386
+ except:
387
+ print(" #Error(option_comm_contract_decode_china): contract",contract,"not found")
388
+ return None,None
389
+
390
+ contract_notes={}
391
+ contract_notes['合约']=contract2
392
+ contract_notes['标的物']=ua
393
+ contract_notes['到期日']=maturity
394
+ if not (direction==''):
395
+ contract_notes['期权方向']=otype
396
+ if not (strike==''):
397
+ contract_notes['行权价']=strike
398
+
399
+
400
+ return contract2,contract_notes
401
+ #==============================================================================
402
+ #==============================================================================
403
+ #==============================================================================
404
+ #==============================================================================
405
+ #==============================================================================
406
+ # 以上为商品期权,以下为金融期权
407
+ #==============================================================================
408
+ #==============================================================================
409
+ #==============================================================================
410
+ #==============================================================================
411
+ #==============================================================================
412
+ if __name__=='__main__':
413
+ detail=True
414
+ detail=False
415
+
416
+ # 定义中国当前金融期权的所有品种
417
+ option_fin_list_sse=["华夏上证50ETF期权", \
418
+ "华夏科创50ETF期权", \
419
+ "易方达科创50ETF期权", \
420
+ "华泰柏瑞沪深300ETF期权", \
421
+ "南方中证500ETF期权"]
422
+ underlying_fin_list_sse=["510050.SS", \
423
+ "588000.SS", \
424
+ "588080.SS", \
425
+ "510300.SS", \
426
+ "510500.SS"]
427
+
428
+ option_fin_list_szse=["易方达深证100ETF期权", \
429
+ "易方达创业板ETF期权", \
430
+ "嘉实沪深300ETF期权", \
431
+ "嘉实中证500ETF期权"]
432
+ underlying_fin_list_szse=["159901.SZ", \
433
+ "159915.SZ", \
434
+ "159919.SZ", \
435
+ "159922.SZ"]
436
+
437
+ option_fin_list_cffe=["上证50股指期权", \
438
+ "沪深300股指期权", \
439
+ "中证1000股指期权"]
440
+ underlying_fin_list_cffe=["000016.SS", \
441
+ "000300.SS", \
442
+ "000852.SS"]
443
+
444
+ option_fin_list=option_fin_list_sse + option_fin_list_szse + option_fin_list_cffe
445
+ underlying_fin_list=underlying_fin_list_sse + underlying_fin_list_szse + underlying_fin_list_cffe
446
+
447
+ """
448
+ option_fin_list=["华夏上证50ETF期权","华夏科创50ETF期权","易方达科创50ETF期权", \
449
+ "华泰柏瑞沪深300ETF期权","南方中证500ETF期权", \
450
+ "易方达深证100ETF期权","易方达创业板ETF期权","嘉实沪深300ETF期权", \
451
+ "嘉实中证500ETF期权", \
452
+ "上证50股指期权","沪深300股指期权","中证1000股指期权"]
453
+ underlying_fin_list=["510050.SS","588000.SS","588080.SS", \
454
+ "510300.SS","510500.SS",
455
+ "159901.SZ","159915.SZ","159919.SZ", \
456
+ "159922.SZ", \
457
+ "000016.SS","000300.SS","000852.SS"]
458
+ """
459
+ if __name__=='__main__':
460
+ option="华夏上证50ETF期权"
461
+ option_fin_underlying(option)
462
+
463
+
464
+ def option_fin_underlying(option):
465
+ """
466
+ 功能:给定金融期权名称,返回标的物证券代码
467
+ """
468
+ import pandas as pd
469
+ df=pd.DataFrame()
470
+ df['option_name']=option_fin_list
471
+ df['underlying_code']=underlying_fin_list
472
+
473
+ try:
474
+ underlying=df[df['option_name']==option]['underlying_code'].values[0]
475
+ except:
476
+ underlying=None
477
+
478
+ return underlying
479
+
480
+
481
+ def option_fin_china(detail=False):
482
+ """
483
+ 功能:描述当前中国市场中的金融期权,标注日期
484
+ """
485
+
486
+ if detail:
487
+ heading="\n***"
488
+ else:
489
+ heading=' '
490
+ lead_blanks=' '*3
491
+
492
+ print("\n===== 中国金融期权一览表 =====")
493
+
494
+ #=====上交所
495
+ print("\n----- 上交所 -----")
496
+ #华夏上证50ETF期权
497
+ print(heading,"华夏上证50ETF期权")
498
+ if detail:
499
+ print(lead_blanks,"俗称 :上证50ETF期权")
500
+ print(lead_blanks,"类别 :欧式期权")
501
+ print(lead_blanks,"标的证券:华夏上证50ETF基金(510050.SS)")
502
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
503
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
504
+ print(lead_blanks,"合约交易代码:xCyMz,xPyMz,x-标的代码,y-到期年月,z-基金行权价")
505
+ print(lead_blanks,"上市日期:2015-2-9")
506
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
507
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
508
+ print(lead_blanks,"交易所 :上海证券交易所")
509
+
510
+ #华夏科创50ETF期权
511
+ print(heading,"华夏科创50ETF期权")
512
+ if detail:
513
+ print(lead_blanks,"俗称 :科创50ETF期权")
514
+ print(lead_blanks,"类别 :欧式期权")
515
+ print(lead_blanks,"标的证券:华夏科创50ETF基金(588000.SS)")
516
+ print(lead_blanks,"上市日期:2023-6-5")
517
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
518
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
519
+ print(lead_blanks,"合约交易代码:xCyMz,xPyMz,x-标的代码,y-到期年月,z-基金行权价")
520
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
521
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
522
+ print(lead_blanks,"交易所 :上海证券交易所")
523
+
524
+ #易方达科创50ETF期权
525
+ print(heading,"易方达科创50ETF期权")
526
+ if detail:
527
+ print(lead_blanks,"俗称 :科创板50ETF期权")
528
+ print(lead_blanks,"类别 :欧式期权")
529
+ print(lead_blanks,"标的证券:易方达科创50ETF基金(588080.SS)")
530
+ print(lead_blanks,"上市日期:2023-6-5")
531
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
532
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
533
+ print(lead_blanks,"合约交易代码:xCyMz,xPyMz,x-标的代码,y-到期年月,z-基金行权价")
534
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
535
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
536
+ print(lead_blanks,"交易所 :上海证券交易所")
537
+
538
+ #华泰柏瑞沪深300ETF期权
539
+ print(heading,"华泰柏瑞沪深300ETF期权")
540
+ if detail:
541
+ print(lead_blanks,"俗称 :(上证)沪深300ETF期权")
542
+ print(lead_blanks,"类别 :欧式期权")
543
+ print(lead_blanks,"标的证券:华泰柏瑞沪深300ETF基金(510300.SS)")
544
+ print(lead_blanks,"上市日期:2019-12-23")
545
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
546
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
547
+ print(lead_blanks,"合约交易代码:xCyMz,xPyMz,x-标的代码,y-到期年月,z-基金行权价")
548
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
549
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
550
+ print(lead_blanks,"交易所 :上海证券交易所")
551
+
552
+ #南方中证500ETF期权
553
+ print(heading,"南方中证500ETF期权")
554
+ if detail:
555
+ print(lead_blanks,"俗称 :(上证)中证500ETF期权")
556
+ print(lead_blanks,"类别 :欧式期权")
557
+ print(lead_blanks,"标的证券:南方中证500ETF基金(510500.SS)")
558
+ print(lead_blanks,"上市日期:2022-9-19")
559
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
560
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
561
+ print(lead_blanks,"合约交易代码:xCyMz,xPyMz,x-标的代码,y-到期年月,z-基金行权价")
562
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
563
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
564
+ print(lead_blanks,"交易所 :上海证券交易所")
565
+
566
+
567
+ #=====深交所
568
+ print("\n----- 深交所 -----")
569
+ #易方达深证100ETF期权
570
+ print(heading,"易方达深证100ETF期权")
571
+ if detail:
572
+ print(lead_blanks,"俗称 :深证100ETF期权")
573
+ print(lead_blanks,"类别 :欧式期权")
574
+ print(lead_blanks,"标的证券:易方达深证100ETF基金(159901.SZ)")
575
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
576
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
577
+ print(lead_blanks,"合约编码:9000xxxx,后4位为合约序号")
578
+ print(lead_blanks,"合约简称:x购y月z,x沽y月z,x-标的名称,y-到期月,z-基金行权价")
579
+ print(lead_blanks,"上市日期:2022-12-12")
580
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
581
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
582
+ print(lead_blanks,"交易所 :深圳证券交易所")
583
+
584
+ #易方达创业板ETF期权
585
+ print(heading,"易方达创业板ETF期权")
586
+ if detail:
587
+ print(lead_blanks,"俗称 :创业板ETF")
588
+ print(lead_blanks,"类别 :欧式期权")
589
+ print(lead_blanks,"标的证券:易方达创业板ETF基金(159915.SZ)")
590
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
591
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
592
+ print(lead_blanks,"合约编码:9000xxxx,后4位为合约序号")
593
+ print(lead_blanks,"合约简称:x购y月z,x沽y月z,x-标的名称,y-到期月,z-基金行权价")
594
+ print(lead_blanks,"上市日期:2022-9-19")
595
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
596
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
597
+ print(lead_blanks,"交易所 :深圳证券交易所")
598
+
599
+ #嘉实沪深300ETF期权
600
+ print(heading,"嘉实沪深300ETF期权")
601
+ if detail:
602
+ print(lead_blanks,"俗称 :(深证)沪深300ETF期权")
603
+ print(lead_blanks,"类别 :欧式期权")
604
+ print(lead_blanks,"标的证券:嘉实沪深300ETF基金(159919.SZ)")
605
+ print(lead_blanks,"上市日期:2019-12-23")
606
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
607
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
608
+ print(lead_blanks,"合约编码:9000xxxx,后4位为合约序号")
609
+ print(lead_blanks,"合约简称:x购y月z,x沽y月z,x-标的名称,y-到期月,z-基金行权价")
610
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
611
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
612
+ print(lead_blanks,"交易所 :深圳证券交易所")
613
+
614
+
615
+ #嘉实中证500ETF期权
616
+ print(heading,"嘉实中证500ETF期权")
617
+ if detail:
618
+ print(lead_blanks,"俗称 :(深证)中证500ETF期权")
619
+ print(lead_blanks,"类别 :欧式期权")
620
+ print(lead_blanks,"标的证券:嘉实中证500ETF基金(159922.SZ)")
621
+ print(lead_blanks,"行权价格:9个(1个平值合约、4个虚值合约、4个实值合约)")
622
+ print(lead_blanks,"合约单位:10000份,1手期权=10000份基金,实物交割")
623
+ print(lead_blanks,"合约编码:9000xxxx,后4位为合约序号")
624
+ print(lead_blanks,"合约简称:x购y月z,x沽y月z,x-标的名称,y-到期月,z-基金行权价")
625
+ print(lead_blanks,"上市日期:2022-9-19")
626
+ print(lead_blanks,"到期月份:当月、下月及随后两个季月(季度末月)")
627
+ print(lead_blanks,"到期日期:到期月份的第四个星期三(节假日顺延)")
628
+ print(lead_blanks,"交易所 :深圳证券交易所")
629
+
630
+
631
+ #=====中金所
632
+ print("\n----- 中金所 -----")
633
+ #上证50股指期权
634
+ print(heading,"上证50股指期权")
635
+ if detail:
636
+ print(lead_blanks,"类别 :欧式期权")
637
+ print(lead_blanks,"标的证券:上证50指数(000016.SS)")
638
+ print(lead_blanks,"上市日期:2022-12-19")
639
+ print(lead_blanks,"合约乘数:现金交割,每点人民币100元")
640
+ print(lead_blanks,"交易代码:HO合约月份-C-行权股指点位,HO合约月份-P-行权股指点位")
641
+ print(lead_blanks,"到期月份:当月、下2个月、随后3个季月(季度末月)")
642
+ print(lead_blanks,"到期日期:到期月份的第三个星期五(节假日顺延)")
643
+ print(lead_blanks,"交易所 :中国金融期货交易所")
644
+
645
+ #沪深300股指期权
646
+ print(heading,"沪深300股指期权")
647
+ if detail:
648
+ print(lead_blanks,"类别 :欧式期权")
649
+ print(lead_blanks,"标的证券:沪深300指数(000300.SS,399300.SZ)")
650
+ print(lead_blanks,"上市日期:2019-12-23")
651
+ print(lead_blanks,"合约乘数:现金交割,每点人民币100元")
652
+ print(lead_blanks,"交易代码:IO合约月份-C-行权股指点位,IO合约月份-P-行权股指点位")
653
+ print(lead_blanks,"到期月份:当月、下2个月、随后3个季月(季度末月)")
654
+ print(lead_blanks,"到期日期:到期月份的第三个星期五(节假日顺延)")
655
+ print(lead_blanks,"交易所 :中国金融期货交易所")
656
+
657
+ #中证1000股指期权
658
+ print(heading,"中证1000股指期权")
659
+ if detail:
660
+ print(lead_blanks,"类别 :欧式期权")
661
+ print(lead_blanks,"标的证券:中证1000指数(000852.SS)")
662
+ print(lead_blanks,"上市日期:2022-7-22")
663
+ print(lead_blanks,"合约乘数:现金交割,每点人民币100元")
664
+ print(lead_blanks,"交易代码:MO合约月份-C-行权股指点位,MO合约月份-P-行权股指点位")
665
+ print(lead_blanks,"到期月份:当月、下2个月、随后3个季月(季度末月)")
666
+ print(lead_blanks,"到期日期:到期月份的第三个星期五(节假日顺延)")
667
+ print(lead_blanks,"交易所 :中国金融期货交易所")
668
+
669
+ import datetime as dt; today=str(dt.date.today())
670
+ if not detail: print('')
671
+ print(heading,"来源:上交所/深交所/中金所,",today)
672
+ return
673
+
674
+ if __name__=='__main__':
675
+ option_fin_china()
676
+ option_fin_china(detail=True)
677
+ #==============================================================================
678
+ if __name__=='__main__':
679
+ date='2021-11-1'
680
+
681
+ def get_yymm(date):
682
+
683
+ import datetime as dt
684
+ d=dt.datetime.strptime(date, '%Y-%m-%d')
685
+ year=d.strftime('%Y')
686
+ month=d.strftime('%m')
687
+ yymm=str(year)[2:]+str(month)
688
+
689
+ return yymm
690
+
691
+ if __name__=='__main__':
692
+ get_yymm('2020-03-25')
693
+ #==============================================================================
694
+
695
+ if __name__=='__main__':
696
+ start='2021-11-1'
697
+ start=''
698
+ num=12
699
+
700
+ def get_yymm_list(start='',num=12):
701
+ """
702
+ 获取一个给定日期start及其后续的YYMM年月列表,共num个
703
+ """
704
+
705
+ import datetime as dt
706
+ if start=='':
707
+ start=str(dt.date.today())
708
+
709
+ start1=dt.datetime.strptime(start, '%Y-%m-%d')
710
+ date_list=[start1]
711
+
712
+ from datetime import timedelta
713
+ for d in range(1,num+1):
714
+ date=start1+timedelta(days=d*30)
715
+ date_list=date_list+[date]
716
+
717
+ yymm_list=[]
718
+ for d in date_list:
719
+ year=d.strftime('%Y')
720
+ month=d.strftime('%m')
721
+ yymm=str(year)[2:]+str(month)
722
+ yymm_list=yymm_list+[yymm]
723
+
724
+ return yymm_list
725
+
726
+ if __name__=='__main__':
727
+ get_yymm_list()
728
+ get_yymm_list(num=13)
729
+ get_yymm_list('2021-1-11')
730
+ get_yymm_list('2021-1-11',num=13)
731
+
732
+ #==============================================================================
733
+
734
+ if __name__=='__main__':
735
+ symbol="华夏上证50ETF期权"
736
+ symbol="华泰柏瑞沪深300ETF期权"
737
+ symbol="嘉实沪深300ETF期权"
738
+ symbol="沪深300股指期权"
739
+ num=9
740
+
741
+ def option_fin_month_china(symbol,num=12):
742
+ """
743
+ 功能:遍历并显示一个金融期货品种的到期年月YYMM
744
+ 未来到期日:当月,下月,下两个季月
745
+ """
746
+
747
+ if not (symbol in option_fin_list):
748
+ print(" #Warning(option_fin_month_china): info not found / unaccessible for",symbol)
749
+ return None
750
+
751
+ #当前年月开始的年月列表
752
+ import datetime as dt; todaydt=str(dt.date.today())
753
+ yymm_list=get_yymm_list(todaydt,num=num)
754
+
755
+ import akshare as ak
756
+ end_month_list=[]
757
+
758
+ #临时措施:深交所期权只能找到"嘉实沪深300ETF期权",其他的找不到但实际存在
759
+ if symbol in option_fin_list_szse: symbol="嘉实沪深300ETF期权"
760
+
761
+ for yymm in yymm_list:
762
+ print(' ... Scanning option maturity',yymm,end=', ')
763
+
764
+ try:
765
+ df = ak.option_finance_board(symbol=symbol,end_month=yymm)
766
+ except:
767
+ print("failed!")
768
+ #print(" #Warning(option_fin_month_china): something went wrong in akshare, try upgrade it")
769
+ continue
770
+
771
+ if df is None:
772
+ print("not found")
773
+ continue
774
+ if len(df)==0:
775
+ print("not found")
776
+ continue
777
+
778
+ print("seems found, checking",end=', ')
779
+ if symbol in option_fin_list_sse:
780
+ y2m2=df['合约交易代码'][:1].values[0][7:11]
781
+
782
+ if symbol in option_fin_list_szse:
783
+ d1=df['期权行权日'][:1].values[0]
784
+ d2=d1.astype('str')
785
+ yy=d2[2:4]; mm=d2[5:7]; y2m2=yy+mm
786
+
787
+ if symbol in option_fin_list_cffe:
788
+ y2m2=df['instrument'][:1].values[0][2:6]
789
+
790
+ if y2m2==yymm:
791
+ print("confirmed found")
792
+ end_month_list=end_month_list+[yymm]
793
+ else:
794
+ print("fake")
795
+
796
+ print("\n=== 中国金融期权品种的到期日(年月) ===")
797
+ print(symbol+':')
798
+ print(end_month_list)
799
+
800
+ print("来源:上交所/深交所/中金所,",todaydt)
801
+
802
+ return
803
+
804
+
805
+ if __name__=='__main__':
806
+ option_fin_month_china("华夏上证50ETF期权")
807
+ option_fin_month_china("嘉实沪深300ETF期权")
808
+ option_fin_month_china("华泰柏瑞沪深300ETF期权")
809
+ option_fin_month_china("沪深300股指期权")
810
+
811
+ #==============================================================================
812
+ if __name__=='__main__':
813
+ end_month='2112'
814
+ nth=4 #第四个
815
+ wd=3 #星期三
816
+
817
+ def nth_weekday(end_month,nth,wd):
818
+ """
819
+ 功能:给定年月end_month的第nth个星期wd,求日期
820
+ """
821
+ import calendar
822
+ import datetime
823
+ c = calendar.Calendar(firstweekday=calendar.SUNDAY)
824
+
825
+ myear=int('20'+end_month[:2])
826
+ mmonth=int(end_month[2:])
827
+ monthcal = c.monthdatescalendar(myear,mmonth)
828
+
829
+ mdatelist=[]
830
+ for mweek in monthcal:
831
+ #print(mweek)
832
+ for mday in mweek:
833
+ #print(mday)
834
+ if (mday.weekday()==(wd-1)) and (mday.month==mmonth):
835
+ mdatelist=mdatelist+[mday]
836
+ mdate=str(mdatelist[nth-1])
837
+
838
+ return mdate
839
+
840
+ if __name__=='__main__':
841
+ #求第四个星期三
842
+ nth_weekday('2111',4,3)
843
+ nth_weekday('2112',4,3)
844
+ #==============================================================================
845
+ if __name__=='__main__':
846
+ symbol="华夏上证50ETF期权"
847
+ symbol="华泰柏瑞沪深300ETF期权"
848
+ symbol="嘉实沪深300ETF期权"
849
+ symbol="沪深300股指期权"
850
+ end_month='2312'
851
+ direction='call'
852
+ printout=True
853
+
854
+
855
+ def option_fin_contracts(symbol,end_month,direction='call',printout=True):
856
+ """
857
+ 功能:抓取指定金融期权品种和到期日年月的具体合约
858
+ """
859
+
860
+ if not (symbol in option_fin_list):
861
+ print(" #Warning(option_fin_contracts): info not found for",symbol)
862
+ return None
863
+
864
+ import akshare as ak
865
+ try:
866
+ df = ak.option_finance_board(symbol=symbol, end_month=end_month)
867
+ except:
868
+ print(" #Error(option_fin_contracts): info unaccessible for",symbol,'on maturity',end_month)
869
+ return None
870
+ if df is None:
871
+ print(" #Error(option_fin_contracts): none found for",symbol,'on maturity',end_month)
872
+ return None
873
+
874
+ #检查期权方向
875
+ typelist=['CALL','PUT','BOTH']
876
+ utype=direction.upper()
877
+ if not (utype in typelist):
878
+ print(" #Warning(option_fin_contracts): unsupported option direction",direction)
879
+ print(" Supported option direction:",typelist)
880
+ return None
881
+
882
+ import pandas as pd
883
+ contracts=pd.DataFrame()
884
+ #==================================================================
885
+ if symbol in option_fin_list_sse:
886
+ #期权方向标志
887
+ df['direction']=df['合约交易代码'].apply(lambda x:x[6:7])
888
+ if utype=='CALL':
889
+ df1=df[df['direction']=='C']
890
+ elif utype=='PUT':
891
+ df1=df[df['direction']=='P']
892
+ else:
893
+ df1=df
894
+
895
+ #取交易日期
896
+ df1.set_index('日期',inplace=True)
897
+ df1['date']=df1.index[0][:8]
898
+ contracts['date']=pd.to_datetime(df1['date'])
899
+
900
+ #去掉前后空格
901
+ df1['合约交易代码']=df1['合约交易代码'].apply(lambda x: x.strip())
902
+ contracts['contract']=df1['合约交易代码']
903
+
904
+ contracts['name']=contracts['contract']
905
+ contracts['direction']=df1['direction']
906
+ #contracts['Close']=df1['前结价']
907
+ contracts['Strike']=df1['行权价']
908
+
909
+ #到期日:到期月的第四个星期三
910
+ mdate=nth_weekday(end_month,4,3)
911
+ contracts['maturity']=mdate
912
+
913
+ #标的物
914
+ pos=option_fin_list.index(symbol)
915
+ ua=underlying_fin_list[pos]
916
+ contracts['underlying']=ua
917
+
918
+ #=================================================================
919
+ if symbol in option_fin_list_szse:
920
+ #期权方向标志
921
+ df['direction']=df['类型'].apply(lambda x:'C' if x in ["认购"] else 'P')
922
+ if utype=='CALL':
923
+ df1=df[df['direction']=='C']
924
+ elif utype=='PUT':
925
+ df1=df[df['direction']=='P']
926
+ else:
927
+ df1=df
928
+
929
+ #去掉前后空格
930
+ df1['合约编码']=df1['合约编码'].apply(lambda x: str(x).strip())
931
+ contracts['contract']=df1['合约编码']
932
+
933
+ contracts['name']=df1['合约简称']
934
+ contracts['direction']=df1['direction']
935
+ #????contracts['Close']=df1['前结价']
936
+ try:
937
+ contracts['Strike']=df1['行权价']
938
+ except:
939
+ contracts['Strike']=df1['行权价(元)']
940
+
941
+ #行权日
942
+ contracts['maturity']=df1['期权行权日'].apply(lambda x: x.strftime('%Y-%m-%d'))
943
+
944
+ #标的物
945
+ pos=option_fin_list.index(symbol)
946
+ ua=underlying_fin_list[pos]
947
+ contracts['underlying']=ua
948
+
949
+ #取交易日期
950
+ import datetime as dt; today=str(dt.date.today())
951
+ contracts['date']=pd.to_datetime(today)
952
+
953
+ #=================================================================
954
+ if symbol in option_fin_list_cffe:
955
+ """
956
+ 字段解读:
957
+ instrument:合约编号
958
+ position:持仓量
959
+ volume:成交量
960
+ lastprice:最新价
961
+ updown:涨跌,涨跌=最新价-前结算价
962
+ bprice:买价
963
+ bamount:买量
964
+ sprice:卖价
965
+ samount:卖量
966
+ """
967
+ #期权方向标志
968
+ df['direction']=df['instrument'].apply(lambda x:x[7:8])
969
+ if utype=='CALL':
970
+ df1=df[df['direction']=='C']
971
+ elif utype=='PUT':
972
+ df1=df[df['direction']=='P']
973
+ else:
974
+ df1=df
975
+
976
+ #去掉前后空格
977
+ df1['instrument']=df1['instrument'].apply(lambda x: x.strip())
978
+ contracts['contract']=df1['instrument']
979
+
980
+ contracts['name']=df1['instrument']
981
+ contracts['direction']=df1['direction']
982
+ #????contracts['Close']=df1['前结价']
983
+ contracts['Strike']=df1['instrument'].apply(lambda x:x[9:13]).astype('int')
984
+
985
+ #行权日:到期月份第三周的周三
986
+ mdate=nth_weekday(end_month,3,5)
987
+ #contracts['maturity']='20'+df1['instrument'].apply(lambda x:x[2:6])+'28'
988
+ contracts['maturity']=mdate
989
+
990
+ #标的物
991
+ pos=option_fin_list.index(symbol)
992
+ ua=underlying_fin_list[pos]
993
+ contracts['underlying']=ua
994
+
995
+ #取交易日期
996
+ import datetime as dt; today=str(dt.date.today())
997
+ contracts['date']=pd.to_datetime(today)
998
+
999
+ contracts['Option']=symbol
1000
+ contracts['end_month']=end_month
1001
+ contracts.set_index('date',inplace=True)
1002
+ contracts.sort_values(by=['Strike'],ascending=True,inplace=True)
1003
+
1004
+ #打印
1005
+ if printout:
1006
+ print("\n========= 中国金融期权合约 =========\n")
1007
+ print("期权品种:",symbol)
1008
+ print("到期年月:",end_month)
1009
+ print("合约方向:",utype)
1010
+
1011
+ #改换中文字段栏
1012
+ collist=['contract','direction','maturity','underlying','Strike']
1013
+ collistcn=['期权合约','方向','到期日','标的证券','行权价']
1014
+ printdf=contracts[collist].copy()
1015
+ printdf.columns=collistcn
1016
+
1017
+ printdf.reset_index(drop=True,inplace=True)
1018
+
1019
+ #打印对齐
1020
+ pd.set_option('display.unicode.ambiguous_as_wide', True)
1021
+ pd.set_option('display.unicode.east_asian_width', True)
1022
+ pd.set_option('display.width', 180) # 设置打印宽度(**重要**)
1023
+
1024
+ #print(printdf.to_string(index=False))
1025
+
1026
+ import datetime as dt; todaydt=str(dt.date.today())
1027
+ #print("\n来源:新浪/上交所/深交所/中金所,",today)
1028
+ footnote="数据来源:新浪/上交所/深交所/中金所, "+str(todaydt)
1029
+ df_display_CSS(printdf,titletxt='',footnote=footnote,facecolor='papayawhip', \
1030
+ first_col_align='center',second_col_align='center', \
1031
+ last_col_align='center',other_col_align='center')
1032
+
1033
+
1034
+ return contracts
1035
+
1036
+ if __name__=='__main__':
1037
+ symbol="华夏上证50ETF期权"
1038
+ symbol="华泰柏瑞沪深300ETF期权"
1039
+ symbol="嘉实沪深300ETF期权"
1040
+ symbol="沪深300股指期权"
1041
+ end_month='2112'
1042
+ direction='call'
1043
+ df=option_fin_contracts(symbol,end_month,direction='call')
1044
+
1045
+ #==============================================================================
1046
+ if __name__=='__main__':
1047
+ symbol="华夏上证50ETF期权"
1048
+ symbol="华泰柏瑞沪深300ETF期权"
1049
+ symbol="嘉实沪深300ETF期权"
1050
+ symbol="沪深300股指期权"
1051
+
1052
+ contract='510050C2206M02900'
1053
+ contract='90000871'
1054
+ end_month='2206'
1055
+ direction='call'
1056
+
1057
+ symbol="中证1000股指期权"
1058
+ end_month='2312'
1059
+ contract='MO2312-P-5800'
1060
+ direction='put'
1061
+
1062
+ def option_fin_contract_parms(symbol,end_month,contract,direction='call'):
1063
+ """
1064
+ 功能:抓取期权合约的到期日、行权价和标的证券
1065
+ """
1066
+
1067
+ df=option_fin_contracts(symbol=symbol,end_month=end_month, \
1068
+ direction=direction,printout=False)
1069
+
1070
+ df1=df[df['contract']==contract]
1071
+ if len(df1)==0:
1072
+ print(" #Warning(option_fin_contract_parms): contract not found for",contract)
1073
+ return None,None,None
1074
+
1075
+ underlying=df1['underlying'].values[0]
1076
+ maturity=df1['maturity'].values[0]
1077
+ strike=float(df1['Strike'].values[0])
1078
+
1079
+ return underlying,maturity,strike
1080
+
1081
+ if __name__=='__main__':
1082
+ option_fin_contract_parms("华夏上证50ETF期权",'2206','510050C2206M02900',direction='call')
1083
+ #=============================================================================
1084
+ if __name__=='__main__':
1085
+ underlying='510050.SS'
1086
+ date='2021-11-19'
1087
+ days=30
1088
+
1089
+ underlying='000852.SS'
1090
+ date='2023-12-1'
1091
+ days=183
1092
+
1093
+
1094
+ def underlying_sigma(underlying,date,days=30):
1095
+ """
1096
+ 功能:计算标的物价格的年化标准差
1097
+ underlying:标的证券代码
1098
+ date:当前日期
1099
+ days:历史期间长度,日历日天数,默认30个日历日
1100
+ """
1101
+
1102
+ #年度交易日天数
1103
+ annual_trading_days=252
1104
+
1105
+ #计算历史样本的开始日期
1106
+ import pandas as pd
1107
+ try:
1108
+ end=pd.to_datetime(date)
1109
+ except:
1110
+ print(" #Error(annualized_sigma): invalid date",date)
1111
+ return None,None
1112
+
1113
+ from datetime import timedelta
1114
+ start=end-timedelta(days=days+1)
1115
+ start1=start.strftime('%Y-%m-%d')
1116
+
1117
+ #抓取标的物的历史价格样本
1118
+ """
1119
+ try:
1120
+ df=get_prices(underlying,start1,date)
1121
+ except:
1122
+ print(" #Error(annualized_sigma): failed to retrieve info for",underlying)
1123
+ return None,None
1124
+ """
1125
+ df=get_prices(underlying,start1,date)
1126
+ #标的物当前价格
1127
+ s0=df[-1:]['Close'].values[0]
1128
+
1129
+ """
1130
+ #采用算数收益率
1131
+ df['ret']=df['Close'].pct_change()
1132
+ """
1133
+
1134
+ #采用对数收益率
1135
+ df['Close_lag']=df['Close'].shift(1)
1136
+ df['Close_lag'].dropna(inplace=True)
1137
+ import numpy as np
1138
+ df['ret']=np.log(df['Close']/df['Close_lag'])
1139
+ sigma=df['ret'].std()
1140
+ annualized_sigma=sigma*np.sqrt(annual_trading_days)
1141
+
1142
+ return annualized_sigma,s0,df
1143
+
1144
+ if __name__=='__main__':
1145
+ sigma1,_,_=underlying_sigma('510050.SS','2021-11-19',days=365)
1146
+ sigma2,_,_=underlying_sigma('510050.SS','2021-11-19',days=183)
1147
+ sigma3,_,_=underlying_sigma('510050.SS','2021-11-19',days=92)
1148
+ sigma4,_,_=underlying_sigma('510050.SS','2021-11-19',days=60)
1149
+ sigma5,_,_=underlying_sigma('510050.SS','2021-11-19',days=30)
1150
+ print(sigma1,sigma2,sigma3,sigma4,sigma5)
1151
+
1152
+ #=============================================================================
1153
+
1154
+ #=============================================================================
1155
+ if __name__=='__main__':
1156
+ start='2021-1-1'
1157
+ end='2021-10-12'
1158
+
1159
+ def calc_days(start,end):
1160
+ """
1161
+ 计算两个日期之间的年数
1162
+ """
1163
+
1164
+ #检查日期期间的有效性
1165
+ valid,start1,end1=check_period(start,end)
1166
+ if not valid:
1167
+ print(" #Error(calc_days): date period invalid")
1168
+ return None
1169
+
1170
+ diff=end1-start1
1171
+ #日历天数
1172
+ diff2=diff.days
1173
+ diff_in_years=diff2/365
1174
+
1175
+ return diff2,round(diff_in_years,5)
1176
+
1177
+ if __name__=='__main__':
1178
+ days,_=calc_days('2020-10-31','2021-10-12')
1179
+
1180
+
1181
+ #=============================================================================
1182
+ if __name__=='__main__':
1183
+ option="华泰柏瑞沪深300ETF期权"
1184
+ end_month='2512'
1185
+ contract='510300C2512M04000'
1186
+ direction='call'
1187
+
1188
+ today='2025-6-18'
1189
+ sample_days=183
1190
+
1191
+ rate_type='treasury'
1192
+ rate_period='1Y'
1193
+ daysahead=183
1194
+
1195
+ def option_fin_pricing_china(option,end_month,contract,today,direction='call', \
1196
+ sample_days=183, \
1197
+ rate_type='treasury',rate_period='1Y',RF=0, \
1198
+ printout=True):
1199
+ """
1200
+ 功能:将中国金融期权定价的过程整合在一起,提供默认选项,改善小白的使用体验
1201
+ 参数:
1202
+ option:金融期权品种
1203
+ end_month:期权到期YYMM
1204
+ contract:期权合约编号
1205
+ today:计算日,可选任意日期,最新日期建议选上一个交易日,便于获取数据
1206
+ direction:期权方向,默认认购/看涨'call'
1207
+ sample_days:计算(标的物)历史波动率的取样日历天数,默认183
1208
+ rate_type:获取无风险利率的方式,默认自动获取'treasury',也可直接指定数值'value'
1209
+ RF:当rate_type为'value'时,直接给出无风险利率的数值
1210
+
1211
+ 注:波动率使用历史波动率
1212
+ """
1213
+
1214
+ #第1步:查找计算金融期权预期价格所需要的参数
1215
+ ua,maturity,x=option_fin_contract_parms(option,end_month,contract,direction)
1216
+ if ua is None:
1217
+ print(" #Error(option_fin_pricing_china): info not found")
1218
+ print(" Possible reasons: one or some of the following")
1219
+ print(" Option not found for",option)
1220
+ print(" Maturity year-month not found for",end_month)
1221
+ print(" Contract not found for",contract,'as',direction.lower())
1222
+ print(" Contract not found in the above option + maturity")
1223
+ return None
1224
+
1225
+ #第2步:计算标的证券价格收益率的历史波动率:
1226
+ sigma,s0,_=underlying_sigma(ua,today,days=sample_days)
1227
+
1228
+ #第3步:查找年化无风险利率
1229
+ rate_type=rate_type.upper()
1230
+ if rate_type=='SHIBOR':
1231
+ rf=shibor_rate(today,rate_period)
1232
+ elif rate_type=='TREASURY':
1233
+ rf=treasury_yield_china(today,rate_period)
1234
+ elif rate_type=='VALUE':
1235
+ rf=RF
1236
+ else:
1237
+ print(" #Error(option_fin_pricing_china): invalid rate type",rate_type.lower())
1238
+ return None
1239
+
1240
+ #第4步:计算当前日期距离合约到期日的天数
1241
+ days,_=calc_days(today,maturity)
1242
+ #print("days is",days)
1243
+
1244
+ #第5步:计算期权合约的预期价格
1245
+ #中国目前金融期权均为无红利的欧式期权,可以直接采用Black-Scholes期权定价模型
1246
+ expected_price=bs_pricing(s0,x,days,rf,sigma,direction,printout=False)
1247
+
1248
+ if printout:
1249
+ print("\n============ 中国金融期权定价 ============\n")
1250
+
1251
+ print("*** 合约信息:")
1252
+ print(" 合约代码:",contract)
1253
+ print(" 期权品种:",option)
1254
+ print(" 标的证券:",ua)
1255
+ print(" 行权价格:",x)
1256
+ print(" 到期年月:",end_month)
1257
+ print(" 期权方向:",direction)
1258
+
1259
+ print("*** 合约现状:")
1260
+ print(" 定价日期:",today,'\b,标的市价:',s0)
1261
+ print(" 距离到期:",days,'\b天')
1262
+ print(" 历史波动率期间:",sample_days,'\b天')
1263
+ print(" 历史波动率数值:",round(sigma,5))
1264
+
1265
+ print(" 无风险利率种类:",rate_type.lower(),'\b,',rate_period)
1266
+ print(" 年化无风险利率:",round(rf*100,4),'\b%')
1267
+
1268
+ print("*** 定价结果:")
1269
+ print(" 定价模型: Black-Scholes")
1270
+ print(" 理论价格:",round(expected_price,5))
1271
+
1272
+ print("\n注:历史/隐含波动率的差异是定价误差的主要原因")
1273
+
1274
+ import datetime; pgm_date = datetime.date.today()
1275
+ print("数据来源: 新浪/沪深所/中金所,",pgm_date)
1276
+
1277
+ return expected_price
1278
+
1279
+ if __name__=='__main__':
1280
+ option="华泰柏瑞沪深300ETF期权"
1281
+ end_month='2206'
1282
+ #看涨合约
1283
+ option_fin_contracts(option,end_month,direction='call')
1284
+ contract='510300C2206M04500'
1285
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1286
+ direction='call', \
1287
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1288
+ #理论价格:0.5748,实际收盘价:0.5584
1289
+ #查看实际价格网址:https://stock.finance.sina.com.cn/option/quotes.html
1290
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1291
+ direction='call', \
1292
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1293
+ #理论价格:0.5631,实际收盘价:0.5584
1294
+
1295
+ #看跌合约
1296
+ option_fin_contracts(option,end_month,direction='put')
1297
+ contract='510300P2206M04500'
1298
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1299
+ direction='put', \
1300
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1301
+ #理论价格:0.083,实际收盘价:0.0893
1302
+ #查看实际价格网址:http://quote.eastmoney.com/center/gridlist.html#options_sahs300etf_rengu
1303
+
1304
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1305
+ direction='put', \
1306
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1307
+ #理论价格:0.086,实际收盘价:0.0893
1308
+ #=============================
1309
+
1310
+ option="华夏上证50ETF期权"
1311
+ end_month='2206'
1312
+ #看涨合约
1313
+ option_fin_contracts(option,end_month,direction='call')
1314
+ contract='510050C2206M02900'
1315
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1316
+ direction='call', \
1317
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1318
+ #理论价格:0.4264,实际收盘价:0.4411
1319
+ #查看网址:http://quote.eastmoney.com/center/gridlist.html#options_sz50etf_txbj
1320
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1321
+ direction='call', \
1322
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1323
+ #理论价格:0.4191,实际收盘价:0.4411
1324
+
1325
+ #看跌合约
1326
+ option_fin_contracts(option,end_month,direction='put')
1327
+ contract='510050P2206M02900'
1328
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1329
+ direction='put', \
1330
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1331
+ #理论价格:0.0505,实际收盘价:0.0441
1332
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1333
+ direction='put', \
1334
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1335
+ #理论价格:0.0524,实际收盘价:0.0441
1336
+ #=============================
1337
+
1338
+ option="嘉实沪深300ETF期权"
1339
+ end_month='2206'
1340
+ option_fin_contracts(option,end_month,direction='call')
1341
+ #看涨合约
1342
+ contract='90000905'
1343
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1344
+ direction='call', \
1345
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1346
+ #理论价格:0.5878,实际收盘价:0.57
1347
+ #查看网站:http://quote.eastmoney.com/center/gridlist.html#options_szetf_all
1348
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1349
+ direction='call', \
1350
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1351
+ #理论价格:0.5766,实际收盘价:0.57
1352
+
1353
+ #看跌合约
1354
+ option_fin_contracts(option,end_month,direction='put')
1355
+ contract='90000906'
1356
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1357
+ direction='put', \
1358
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1359
+ #理论价格:0.0692,实际收盘价:0.0848
1360
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1361
+ direction='put', \
1362
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1363
+ #理论价格:0.072,实际收盘价:0.0848
1364
+ #=============================
1365
+
1366
+ option="沪深300股指期权"
1367
+ end_month='2206'
1368
+ option_fin_contracts(option,end_month,direction='call')
1369
+ #看涨合约
1370
+ contract='IO2206-C-4200'
1371
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1372
+ direction='call', \
1373
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1374
+ #理论价格:770.9,实际收盘价:700.6
1375
+ #查看网站:http://quote.eastmoney.com/center/gridlist.html#options_cffex_all
1376
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1377
+ direction='call', \
1378
+ sample_days=90,rate_type='shibor',rate_period='1Y')
1379
+ #理论价格:759,实际收盘价:700.6
1380
+
1381
+ #看跌合约
1382
+ option_fin_contracts(option,end_month,direction='put')
1383
+ contract='IO2206-P-4200'
1384
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1385
+ direction='put', \
1386
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1387
+ #理论价格:40.7,实际收盘价:49.2
1388
+ eprice=option_fin_pricing_china(option,end_month,contract,today='2021-11-19', \
1389
+ direction='put', \
1390
+ sample_days=365,rate_type='shibor',rate_period='1Y')
1391
+ #理论价格:42.6,实际收盘价:49.2
1392
+
1393
+ #=============================================================================
1394
+ def option_fin_pricing_china2(option,end_month,contract,today,direction='call', \
1395
+ rate_type='shibor',printout=True):
1396
+ """
1397
+ 功能:将中国金融期权定价的过程整合在一起,提供默认选项,改善小白的使用体验
1398
+ 注1:波动率使用历史波动率
1399
+ 注2:sample_days使用与距离到期日相同天数,rate_period使用与距离到期日近似的期间
1400
+
1401
+ 特别注意:因难以确定上述关系,本函数不建议使用,可能导致误差过大!!!
1402
+ """
1403
+
1404
+ #第1步:查找计算金融期权预期价格所需要的参数
1405
+ ua,maturity,x=option_fin_contract_parms(option,end_month,contract,direction)
1406
+ if ua is None:
1407
+ print(" #Error(option_fin_pricing_china): info not found")
1408
+ print(" Possible reasons: one or some of the following")
1409
+ print(" Option not found for",option)
1410
+ print(" Maturity year-month not found for",end_month)
1411
+ print(" Contract not found for",contract,'as',direction.lower())
1412
+ print(" Contract not found in the above option + maturity")
1413
+ return None
1414
+
1415
+ #第2步:计算当前日期距离合约到期日的天数
1416
+ days,_=calc_days(today,maturity)
1417
+ #print("days is",days)
1418
+
1419
+ #第3步:计算标的证券价格收益率的历史波动率:
1420
+ sigma,s0,_=underlying_sigma(ua,today,days=days)
1421
+
1422
+ #第3步:查找年化无风险利率
1423
+
1424
+ rate_type=rate_type.upper()
1425
+ if rate_type=='SHIBOR':
1426
+ if days == 1:
1427
+ rate_period='ON'
1428
+ elif days <=7:
1429
+ rate_period='1W'
1430
+ elif days <=14:
1431
+ rate_period='2W'
1432
+ elif days <=30:
1433
+ rate_period='1M'
1434
+ elif days <=90:
1435
+ rate_period='3M'
1436
+ elif days <=183:
1437
+ rate_period='6M'
1438
+ else:
1439
+ rate_period='1Y'
1440
+
1441
+ rf=shibor_rate(today,rate_period)
1442
+ elif rate_type=='TREASURY':
1443
+ rf=treasury_yield_china(today,rate_period='1Y')
1444
+ else:
1445
+ print(" #Error(option_fin_pricing_china): invalid rate type",rate_type.lower())
1446
+ return None
1447
+
1448
+ #第5步:计算期权合约的预期价格
1449
+ #中国目前金融期权均为无红利的欧式期权,可以直接采用Black-Scholes期权定价模型
1450
+ expected_price=bs_pricing(s0,x,days,rf,sigma,direction,printout=False)
1451
+
1452
+ if printout:
1453
+ print("\n============ 中国金融期权定价 ============\n")
1454
+
1455
+ print("*** 合约信息:")
1456
+ print(" 合约代码:",contract)
1457
+ print(" 期权品种:",option)
1458
+ print(" 标的证券:",ua)
1459
+ print(" 行权价格:",x)
1460
+ print(" 到期年月:",end_month)
1461
+ print(" 期权方向:",direction)
1462
+
1463
+ print("*** 合约现状:")
1464
+ print(" 定价日期:",today,'\b,标的市价:',s0)
1465
+ print(" 距离到期:",days,'\b天')
1466
+ print(" 历史波动率期间:",sample_days,'\b天')
1467
+ print(" 历史波动率数值:",round(sigma,5))
1468
+
1469
+ print(" 无风险利率种类:",rate_type.lower(),'\b,',rate_period)
1470
+ print(" 年化无风险利率:",round(rf*100,4),'\b%')
1471
+
1472
+ print("*** 定价结果:")
1473
+ print(" 定价模型: Black-Scholes")
1474
+ print(" 理论价格:",round(expected_price,5))
1475
+
1476
+ print("\n注:历史/隐含波动率的差异是定价误差的主要原因")
1477
+
1478
+ import datetime; pgm_date = datetime.date.today()
1479
+ print("数据来源: 新浪/上交所/深交所/中金所,",pgm_date)
1480
+
1481
+ return expected_price
1482
+
1483
+ #=============================================================================
1484
+ #=============================================================================
1485
+ #沪深300股指期权价格运动
1486
+ #=============================================================================
1487
+ if __name__=='__main__':
1488
+ variety='hs300'
1489
+ printout=True
1490
+
1491
+ def index_option_maturity_china(variety='hs300',printout=True):
1492
+ """
1493
+ 功能: 套壳函数hs300option_maturity,维持旧版兼容性
1494
+ """
1495
+ varietylist=['hs300']
1496
+ if not (variety in varietylist):
1497
+ print(" #Error(index_option_maturity_china): unsupported option variety",variety)
1498
+ print(" Currently supported option variety",varietylist,"\b, and may support more in the future")
1499
+ return None
1500
+
1501
+ mlist=hs300option_maturity(printout=printout)
1502
+ return mlist
1503
+
1504
+
1505
+ def hs300option_maturity(printout=True):
1506
+ """
1507
+ 功能:获取沪深300股指期权的到期年月
1508
+ 注意:只保留YYMM
1509
+ """
1510
+
1511
+ import akshare as ak
1512
+ mdict=ak.option_cffex_hs300_list_sina()
1513
+
1514
+ mkey="沪深300指数"
1515
+ mvalue=mdict[mkey]
1516
+
1517
+ mlist=[]
1518
+ for m in mvalue:
1519
+ m4=m[-4:]
1520
+ mlist=mlist+[m4]
1521
+ mlist.sort()
1522
+
1523
+ if printout:
1524
+ import datetime; today = datetime.date.today()
1525
+ footnote="数据来源: 新浪财经/东方财富, "+str(today)
1526
+
1527
+ print("\n=== 沪深300股指期权的到期日(YYMM) ===\n")
1528
+ print(mlist)
1529
+ print(footnote)
1530
+
1531
+ return mlist
1532
+
1533
+ if __name__=='__main__':
1534
+ mlist=hs300option_maturity()
1535
+ #=============================================================================
1536
+ if __name__=='__main__':
1537
+ direction="Call"
1538
+ maturity="2306"
1539
+ direction="Call"
1540
+ printout=True
1541
+
1542
+ variety='hs300'
1543
+
1544
+ def index_option_exercise_china(maturity,direction="Call",variety='hs300',printout=True):
1545
+ """
1546
+ 功能:套壳函数hs300option_exercise,维持旧版兼容性
1547
+ """
1548
+ varietylist=['hs300']
1549
+ if not (variety in varietylist):
1550
+ print(" #Error(index_option_exercise_china): unsupported option variety",variety)
1551
+ print(" Currently supported option variety",varietylist,"\b, and may support more in the future")
1552
+ return None
1553
+
1554
+ elist=hs300option_exercise(maturity=maturity,direction=direction,printout=printout)
1555
+ return elist
1556
+
1557
+
1558
+
1559
+ def hs300option_exercise(maturity,direction="Call",printout=True):
1560
+ """
1561
+ 功能:获取沪深300股指期权的行权点位
1562
+ maturity: 到期年月YYMM
1563
+ direction: 看涨期权Call或看跌期权Put
1564
+
1565
+ """
1566
+ #检查期权的看涨看跌方向
1567
+ directionl=direction.lower()
1568
+ if not (directionl in ["call","put"]):
1569
+ print(" #Error(hs300option_exercise): option direction must either Call or Put")
1570
+ return None
1571
+
1572
+ #检查期权的到期日是否有效
1573
+ mlist=mlist=hs300option_maturity(printout=False)
1574
+ if not (maturity in mlist):
1575
+ print(" #Error(hs300option_exercise): maturity not available for", maturity)
1576
+ print(" Currently available",mlist)
1577
+ return None
1578
+
1579
+ symbol="沪深300股指期权"
1580
+ import akshare as ak
1581
+ df=ak.option_finance_board(symbol=symbol, end_month=maturity)
1582
+ df['maturity']=df['instrument'].apply(lambda x: x[2:6])
1583
+ df['direction']=df['instrument'].apply(lambda x: x[7:8])
1584
+ df['exercise']=df['instrument'].apply(lambda x: x[9:13])
1585
+
1586
+ if directionl == "call":
1587
+ df2=df[df["direction"]=='C']
1588
+ else:
1589
+ df2=df[df["direction"]=='P']
1590
+
1591
+ exerciselist=list(df2["exercise"])
1592
+ exerciselist.sort()
1593
+
1594
+ if printout:
1595
+
1596
+ print("\n=== 沪深300股指期权的行权点位 ===\n")
1597
+ print("到期日:",maturity,"\b,方向:",direction)
1598
+ #对列表分组打印
1599
+ n=9
1600
+ for e in [exerciselist[i:i+n] for i in range(0,len(exerciselist),n)]:
1601
+ print(e)
1602
+
1603
+ import datetime; today = datetime.date.today()
1604
+ footnote="数据来源: 新浪财经/东方财富, "+str(today)
1605
+ print("\n"+footnote)
1606
+
1607
+ return exerciselist
1608
+
1609
+ if __name__=='__main__':
1610
+ elist=exerciselist=hs300option_exercise(maturity="2306",direction="Call")
1611
+ #==============================================================================
1612
+
1613
+
1614
+ def get_price_option_fin_china(option,contract):
1615
+ """
1616
+ 功能:获得金融期权option的合约contract全部历史行情
1617
+ """
1618
+ import akshare as ak
1619
+
1620
+ #变换中金所期权合约格式为新浪格式
1621
+ if option in option_fin_list_cffe:
1622
+ clist=contract.split('-')
1623
+ contract1=''
1624
+ for c in clist:
1625
+ contract1=contract1+c
1626
+
1627
+ #获得期权合约历史行情
1628
+ if option in ['沪深300股指期权']:
1629
+ try:
1630
+ df1t = ak.option_cffex_hs300_daily_sina(symbol=contract1)
1631
+ except:
1632
+ print(" #Error(index_option_price_china2): contract",contract,"not found or expired in",option)
1633
+ return None
1634
+
1635
+ if option in ['上证50股指期权']:
1636
+ try:
1637
+ df1t = ak.option_cffex_sz50_daily_sina(symbol=contract1)
1638
+ except:
1639
+ print(" #Error(index_option_price_china2): contract",contract,"not found or expired in",option)
1640
+ return None
1641
+
1642
+
1643
+ if option in ['中证1000股指期权']:
1644
+ try:
1645
+ df1t = ak.option_cffex_zz1000_daily_sina(symbol=contract1)
1646
+ except:
1647
+ print(" #Error(index_option_price_china2): contract",contract,"not found or expired in",option)
1648
+ return None
1649
+
1650
+ import pandas as pd
1651
+ df1t['Date']=df1t['date'].apply(lambda x: pd.to_datetime(x))
1652
+ df1t.set_index('Date',inplace=True)
1653
+
1654
+ df1=df1t[['date','close']]
1655
+
1656
+ return df1
1657
+
1658
+
1659
+
1660
+ #==============================================================================
1661
+
1662
+ if __name__=='__main__':
1663
+ option="沪深300股指期权"
1664
+ contract='IO2403-P-4000'
1665
+ contract='IO2403P3900'
1666
+
1667
+ loc1='best';loc2='best';graph=True
1668
+
1669
+
1670
+ def index_option_price_china2(option,contract, \
1671
+ loc1='best',loc2='best',graph=True):
1672
+ """
1673
+ 功能:绘制期权合约与其标的证券价格的双轴对照图,支持中金所三种股指期权
1674
+ """
1675
+ #获取期权合约的历史行情
1676
+ if not (option in option_fin_list_cffe):
1677
+ print(" #Warning(index_option_price_china2): currently only support:",option_fin_list_cffe)
1678
+ return None,None
1679
+
1680
+ try:
1681
+ df1=get_price_option_fin_china(option,contract)
1682
+ except:
1683
+ print(" #Warning(index_option_price_china2): contract",contract,"unaccessible")
1684
+ return None,None
1685
+
1686
+ start=df1['date'].values[0].strftime('%Y-%m-%d')
1687
+ end=df1['date'].values[-1].strftime('%Y-%m-%d')
1688
+
1689
+ #获得标的证券历史行情
1690
+ ua=option_fin_underlying(option)
1691
+ df2t=get_price(ua,start,end)
1692
+ df2=df2t[['date','Close','ticker']]
1693
+
1694
+ #绘制双轴图
1695
+ if graph:
1696
+ #获取股指历史价格
1697
+ collabel_so='期权价格'
1698
+ collabel_si=ticker_name(ua)
1699
+ if ('P' in contract) or ('p' in contract):
1700
+ direction='Put'
1701
+ else:
1702
+ direction='Call'
1703
+
1704
+ titletxt_so_si=option+':期权价格 vs 标的指数,'+ectranslate(direction)
1705
+ colname='Close'; ylabeltxt=''
1706
+
1707
+ maturity=contract[2:6]
1708
+ exercisestr=contract[-4:]
1709
+
1710
+ #footnote1="新浪期权代码:"+symbol+",到期日"+maturity+",行权股指点位"+exercisestr
1711
+ footnote1="期权代码:"+contract+",到期日"+maturity+",行权股指点位"+exercisestr
1712
+ import datetime; todaydt = datetime.date.today()
1713
+ footnote2="数据来源: 新浪财经/东方财富, "+str(todaydt)
1714
+ footnote=footnote1+"\n"+footnote2
1715
+
1716
+ plot_line2_twinx(df1,'','close',collabel_so, \
1717
+ df2,'','Close',collabel_si, \
1718
+ titletxt_so_si,footnote,loc1=loc1,loc2=loc2)
1719
+
1720
+ return df1,df2
1721
+
1722
+
1723
+ #=============================================================================
1724
+ if __name__=='__main__':
1725
+ maturity="2306"
1726
+ exercise=4500
1727
+ direction="Call"
1728
+
1729
+ option=["2306",4500,'Call']
1730
+
1731
+ variety='hs300'
1732
+
1733
+
1734
+ def index_option_price_china(option,variety='hs300', \
1735
+ loc1='best',loc2='best',graph=True):
1736
+ """
1737
+ 功能:套壳函数hs300option_price,维持旧版兼容性
1738
+ """
1739
+ varietylist=['hs300']+option_fin_list
1740
+ if not (variety in varietylist):
1741
+ print(" #Error(index_option_price_china): unsupported option variety",variety)
1742
+ print(" Currently supported option variety",varietylist,"\b, and may support more in the future")
1743
+ return None
1744
+
1745
+ oprice=hs300option_price(option=option, \
1746
+ loc1=loc1,loc2=loc2,graph=graph)
1747
+ return oprice
1748
+
1749
+
1750
+ """
1751
+ def hs300option_price(maturity,exercise,direction="Call", \
1752
+ loc1='best',loc2='best', \
1753
+ graph=True):
1754
+ """
1755
+ def hs300option_price(option, \
1756
+ loc1='best',loc2='best', \
1757
+ graph=True):
1758
+
1759
+ """
1760
+ 功能:绘制沪深300股指期权的历史价格曲线
1761
+ option的结构:[maturity,exercise,direction],例如["2306",3900,"Call"]
1762
+ """
1763
+
1764
+ #结构期权参数
1765
+ maturity,exercise,direction=option_decode(option)
1766
+
1767
+ #获取行权点位列表
1768
+ exerciselist=hs300option_exercise(maturity=maturity,direction=direction,printout=False)
1769
+
1770
+ #检查行权点位
1771
+ exercisestr=str(exercise)
1772
+ if not (exercisestr in exerciselist):
1773
+ print(" #Error(hs300option_price): no such exercise point for", exercisestr)
1774
+ return None
1775
+
1776
+ #合成新浪期权合约编号
1777
+ if direction.lower() == "call":
1778
+ directionL='C'
1779
+ else:
1780
+ directionL='P'
1781
+ symbol='io'+maturity+directionL+exercisestr
1782
+
1783
+ #获取期权历史价格
1784
+ import akshare as ak
1785
+ hs300op = ak.option_cffex_hs300_daily_sina(symbol=symbol)
1786
+ datelist=list(hs300op['date'])
1787
+ start=datelist[0]
1788
+ end=datelist[-1]
1789
+
1790
+ hs300op['Date']=pd.to_datetime(hs300op['date'])
1791
+ hs300op.set_index('Date',inplace=True)
1792
+ hs300op.sort_index(ascending=True,inplace=True)
1793
+ hs300op2=hs300op[["close"]]
1794
+ hs300op2.rename(columns={'close':'SO Close'},inplace=True)
1795
+
1796
+ if graph:
1797
+ #获取股指历史价格
1798
+ hs300=get_price("000300.SS",start,end)
1799
+ hs3002=hs300[["Close"]]
1800
+ hs3002.rename(columns={'Close':'SI Close'},inplace=True)
1801
+
1802
+ #合成期权和股指
1803
+ hs300_op_zs=pd.merge(hs300op2,hs3002,how="left",left_index=True,right_index=True)
1804
+ hs300_op_zs["SO Exercise"]=float(exercise)
1805
+
1806
+ """
1807
+ #计算期权的内在价值
1808
+ if directionL == "C":
1809
+ hs300_op_zs["IV"]=hs300_op_zs["SI Close"]-hs300_op_zs["SO Exercise"]
1810
+ else:
1811
+ hs300_op_zs["IV"]=-hs300_op_zs["SI Close"]+hs300_op_zs["SO Exercise"]
1812
+ hs300_op_zs["Intrinsic Value"]=hs300_op_zs["IV"].apply(lambda x: 0 if x<0 else x)
1813
+ """
1814
+ collabel_so='期权价格'
1815
+ collabel_si='沪深300指数'
1816
+ titletxt_so_si='沪深300股指期权:期权价格 vs 标的指数,'+ectranslate(direction)
1817
+ colname='Close'; ylabeltxt=''
1818
+
1819
+ footnote1="新浪期权代码:"+symbol+",到期日"+maturity+",行权股指点位"+exercisestr
1820
+ import datetime; today = datetime.date.today()
1821
+ footnote2="数据来源: 新浪财经/东方财富, "+str(today)
1822
+ footnote=footnote1+"\n"+footnote2
1823
+
1824
+ plot_line2_twinx(hs300_op_zs,'','SO Close',collabel_so, \
1825
+ hs300_op_zs,'','SI Close',collabel_si, \
1826
+ titletxt_so_si,footnote,loc1=loc1,loc2=loc2)
1827
+
1828
+ return hs300op2
1829
+
1830
+ if __name__=='__main__':
1831
+ df=hs300option_price(maturity="2306",exercise=3900,direction="Call")
1832
+ #=============================================================================
1833
+ if __name__=='__main__':
1834
+ option1=["2306",3900,"Call"]
1835
+ option2=["2210",3900,"Put"]
1836
+
1837
+ def index_option_compare_china(option1,option2, \
1838
+ variety='hs300', \
1839
+ loc1='best',loc2='best',twinx=False):
1840
+ """
1841
+ 功能:套壳函数hs300option_compare,维持旧版兼容性
1842
+ """
1843
+ varietylist=['hs300']
1844
+ if not (variety in varietylist):
1845
+ print(" #Error(index_option_compare_china): unsupported option variety",variety)
1846
+ print(" Currently supported option variety",varietylist,"\b, and may support more in the future")
1847
+ return None
1848
+
1849
+ df=hs300option_compare(option1=option1,option2=option2, \
1850
+ loc1=loc1,loc2=loc2,twinx=twinx)
1851
+ return df
1852
+
1853
+
1854
+ def hs300option_compare(option1,option2,loc1='best',loc2='best',twinx=False):
1855
+ """
1856
+ 功能:比较两个沪深300股指期权的价格曲线
1857
+ option的结构:[maturity,exercise,direction],例如["2306",3900,"Call"]
1858
+ """
1859
+ #提取期权参数
1860
+ try:
1861
+ maturity1=option1[0]
1862
+ exercise1=option1[1]
1863
+ direction1=option1[2]
1864
+ except:
1865
+ print(" #Error(hs300option_compare): invalid option descroption",option1)
1866
+ print(" Option structure: [maturity YYMM,exercise point, direction Call or Put]")
1867
+ print(" For example, [\"2306\",3900,\"Call\"]")
1868
+ return None,None
1869
+
1870
+ try:
1871
+ maturity2=option2[0]
1872
+ exercise2=option2[1]
1873
+ direction2=option2[2]
1874
+ except:
1875
+ print(" #Error(hs300option_compare): invalid option descroption",option2)
1876
+ print(" Option structure: [maturity YYMM,exercise point, direction Call or Put]")
1877
+ print(" For example, [\"2306\",3900,\"Call\"]")
1878
+ return None,None
1879
+
1880
+ if option1 == option2:
1881
+ print(" #Warning(hs300option_compare): expecting two different options for comparison:-(")
1882
+ return
1883
+
1884
+ #设定是否同轴
1885
+ if direction1 == direction2:
1886
+ twinx=False
1887
+ else:
1888
+ twinx=True
1889
+
1890
+ #获取期权价格
1891
+ df1=hs300option_price([maturity1,exercise1,direction1],graph=False)
1892
+ df2=hs300option_price([maturity2,exercise2,direction2],graph=False)
1893
+
1894
+ #内连接:取共同日期期间
1895
+ import pandas as pd
1896
+ df12=pd.merge(df1,df2,how="inner",left_index=True,right_index=True)
1897
+
1898
+ if not twinx:
1899
+ ticker1="期权1:"+option_description(option1)
1900
+ else:
1901
+ ticker1="期权1"
1902
+ #ticker1="期权1:"+option_description(option1)
1903
+ colname1='SO Close_x'
1904
+
1905
+ if not twinx:
1906
+ ticker2="期权2:"+option_description(option2)
1907
+ else:
1908
+ ticker2="期权2"
1909
+ #ticker2="期权2:"+option_description(option2)
1910
+ colname2='SO Close_y'
1911
+
1912
+ ylabeltxt="期权价格"
1913
+ titletxt='沪深300股指期权:价格运动与影响因素'
1914
+
1915
+ if not twinx:
1916
+ footnote1=''
1917
+ else:
1918
+ footnote1="期权1"+str(option1)+",期权2"+str(option2)+'\n'
1919
+ import datetime; today = datetime.date.today()
1920
+ footnote2="数据来源: 新浪财经/东方财富, "+str(today)
1921
+ footnote=footnote1+footnote2
1922
+ """
1923
+ plot2_line2(df12,ticker1,colname1,'', \
1924
+ df12,ticker2,colname2,'', \
1925
+ ylabeltxt,titletxt,footnote, \
1926
+ twinx=twinx, \
1927
+ loc1=loc1,loc2=loc2, \
1928
+ date_range=False,date_freq=False)
1929
+ """
1930
+ plot_line2(df12,ticker1,colname1,'', \
1931
+ df12,ticker2,colname2,'', \
1932
+ ylabeltxt,titletxt,footnote, \
1933
+ twinx=twinx, \
1934
+ loc1=loc1,loc2=loc2, \
1935
+ #date_range=False,date_freq=False
1936
+ )
1937
+
1938
+
1939
+ return df12
1940
+
1941
+ if __name__=='__main__':
1942
+
1943
+ #不同到期日
1944
+ option1=["2306",3900,"Call"]
1945
+ option2=["2210",3900,"Call"]
1946
+ df=hs300option_compare(option1,option2,loc1='lower left',loc2='upper right')
1947
+
1948
+ #不同行权点位
1949
+ option1=["2306",3900,"Call"]
1950
+ option2=["2306",4500,"Call"]
1951
+ df=hs300option_compare(option1,option2,loc1='lower left',loc2='upper right')
1952
+
1953
+ #不同方向:看涨vs看跌
1954
+ option1=["2306",4500,"Call"]
1955
+ option2=["2306",4500,"Put"]
1956
+ df=hs300option_compare(option1,option2,loc1='upper center',loc2='lower center')
1957
+
1958
+ #==============================================================================
1959
+ if __name__=='__main__':
1960
+ option="沪深300股指期权"
1961
+ contract1="IO2403-P-3700"
1962
+ contract2="IO2403-P-3900"
1963
+
1964
+ def index_option_compare_china2(option,contract1,contract2,loc1='best',loc2='best',twinx=False):
1965
+ """
1966
+ 功能:比较两个股指期权合约的价格曲线
1967
+ """
1968
+
1969
+ #获取期权价格
1970
+ print(" Searching prices for",option,"contract",contract1,"...")
1971
+ df1=get_price_option_fin_china(option,contract1)
1972
+ if df1 is None:
1973
+ print(" Sorry, found none info for contract",contract1)
1974
+ return None,None
1975
+
1976
+ print(" Searching prices for",option,"contract",contract2,"...")
1977
+ df2=get_price_option_fin_china(option,contract2)
1978
+ if df2 is None:
1979
+ print(" Sorry, found none info for contract",contract2)
1980
+ return None,None
1981
+
1982
+ print(" Rendering graphics ...")
1983
+ ylabeltxt="期权价格"
1984
+ titletxt=option+':价格运动与影响因素'
1985
+
1986
+ import datetime; todaydt = datetime.date.today()
1987
+ footnote="数据来源: 新浪财经/东方财富, "+str(todaydt)
1988
+
1989
+ plot2_line2(df1,contract1,'close','', \
1990
+ df2,contract2,'close','', \
1991
+ ylabeltxt,titletxt,footnote, \
1992
+ twinx=twinx, \
1993
+ loc1=loc1,loc2=loc2)
1994
+
1995
+ return df1,df2
1996
+
1997
+ if __name__=='__main__':
1998
+ option="沪深300股指期权"
1999
+ #不同到期日
2000
+ contract1="IO2403-C-3900"
2001
+ contract2="IO2406-C-3900"
2002
+ df=index_option_compare_china2(option,contract1,contract2)
2003
+
2004
+ #不同行权点位
2005
+ contract1="IO2403-C-3900"
2006
+ contract2="IO2403-C-4400"
2007
+ df=index_option_compare_china2(option,contract1,contract2)
2008
+
2009
+ #不同方向:看涨vs看跌
2010
+ contract1="IO2403-C-3300"
2011
+ contract2="IO2403-P-3300"
2012
+ df=index_option_compare_china2(option,contract1,contract2,twinx=True)
2013
+
2014
+ #==============================================================================
2015
+
2016
+
2017
+ if __name__=='__main__':
2018
+ option=["2306",3900,"Call"]
2019
+
2020
+ def option_description(option):
2021
+ """
2022
+ 功能:将期权合约的表示方法转换为字符串,供打印使用
2023
+ option:[到期年月YYMM,行权价格,行权方向]
2024
+ 返回:字符串,到期如YYMM,行权价XXX,ZZ期权
2025
+ """
2026
+
2027
+ try:
2028
+ maturity=option[0]
2029
+ exercise=str(option[1])
2030
+ direct=option[2].lower()
2031
+ if direct=="call":
2032
+ direction="看涨期权"
2033
+ elif direct=="put":
2034
+ direction="看跌期权"
2035
+ else:
2036
+ direction="期权方向未知"
2037
+ except:
2038
+ print(" #Error(option_description): invalid option description structure",option)
2039
+ print(" Expecting structure: [maturity YYMM,exercise price, direction Call or Put]")
2040
+ return None
2041
+
2042
+ option_str="到期日"+maturity+",行权价"+exercise+","+direction
2043
+
2044
+ return option_str
2045
+
2046
+ if __name__=='__main__':
2047
+ option=["2306",3900,"Call"]
2048
+ option_description(option)
2049
+
2050
+ #==============================================================================
2051
+ if __name__=='__main__':
2052
+ option=["2306",3900,"Call"]
2053
+
2054
+ def option_decode(option):
2055
+ """
2056
+ 功能:将期权合约的表示方法分解为各个单项
2057
+ option:[到期年月YYMM,行权价格,行权方向]
2058
+ 返回:到期如YYMM,行权价XXX,Call或Put
2059
+ """
2060
+
2061
+ try:
2062
+ maturity=option[0]
2063
+ exercise=option[1]
2064
+ direct=option[2].capitalize()
2065
+ except:
2066
+ print(" #Error(option_decode): invalid option description structure",option)
2067
+ print(" Expecting structure: [maturity YYMM,exercise price, direction Call or Put]")
2068
+ return None
2069
+
2070
+ return maturity,exercise,direct
2071
+
2072
+ if __name__=='__main__':
2073
+ option=["2306",3900,"Call"]
2074
+ option_decode(option)
2075
+ #==============================================================================
2076
+ if __name__=='__main__':
2077
+ option='50ETF'
2078
+ maturity='2209'
2079
+ exercise=3000
2080
+ trade_date='2022-9-26'
2081
+ printout=True
2082
+
2083
+ def fin_option_risk_sse(option,maturity,exercise,trade_date,printout=True):
2084
+ """
2085
+ 功能:显示指定上交所金融期权的风险指标
2086
+ option: 期权名称
2087
+ maturity: 到期年月YYMM
2088
+ exercise: 行权点位
2089
+ direction: 方向,看涨看跌
2090
+ """
2091
+
2092
+ #初始检查:期权名称
2093
+ optionlist=["50ETF","300ETF","500ETF","科创50","科创板50"]
2094
+ if not (option in optionlist):
2095
+ print(" #Error(fin_option_risk_sse): option not found in SSE for",option)
2096
+ return None
2097
+
2098
+ #初始检查:交易日期
2099
+ if not check_date(trade_date):
2100
+ print(" #Error(fin_option_risk_sse): invalid date",trade_date)
2101
+ return None
2102
+ akdate=convert_date_ts(trade_date)
2103
+
2104
+ import pandas as pd
2105
+ import akshare as ak
2106
+
2107
+ #获取交易日数据
2108
+ try:
2109
+ df = ak.option_risk_indicator_sse(date=akdate)
2110
+ except:
2111
+ print(" #Warning(fin_option_risk_sse): no data retrieved for this date",trade_date)
2112
+ return None
2113
+
2114
+ df['Date']=df['TRADE_DATE']
2115
+ df['date']=df['TRADE_DATE']
2116
+ df['Date']=pd.to_datetime(df['Date'])
2117
+ df.set_index('Date',inplace=True)
2118
+ df.sort_index(ascending=True,inplace=True)
2119
+
2120
+ df['direction']=df['CONTRACT_ID'].apply(lambda x: x[6:7])
2121
+ df['underlying']=df['CONTRACT_ID'].apply(lambda x: x[:6])
2122
+
2123
+ df['ETF end']=df['CONTRACT_SYMBOL'].apply(lambda x: x.find('购'))
2124
+ df['ETF end']=df.apply(lambda x: x['CONTRACT_SYMBOL'].find('沽') if x['ETF end'] < 0 else x['ETF end'],axis=1)
2125
+ df['option']=df.apply(lambda x: x['CONTRACT_SYMBOL'][:x['ETF end']],axis=1)
2126
+
2127
+ df['exercise']=df['CONTRACT_ID'].apply(lambda x: float(x[12:]))
2128
+
2129
+ #进一步检查:到期日
2130
+ df['maturity']=df['CONTRACT_ID'].apply(lambda x: x[7:11])
2131
+ if not (maturity in list(df['maturity'])):
2132
+ print(" #Error(fin_option_risk_sse): maturity not found in SSE for",maturity)
2133
+
2134
+ df_maturity=df[(df['option']==option) & (df['exercise']==exercise)]
2135
+ maturitylist=list(set(list(df_maturity['maturity'])))
2136
+ maturitylist.sort()
2137
+ print(" On "+trade_date+", available maturities:",maturitylist)
2138
+ return None
2139
+
2140
+ #进一步检查:行权点位
2141
+ if not (exercise in list(df['exercise'])):
2142
+ print(" #Error(fin_option_risk_sse): exericse point not found in SSE for",exercise)
2143
+
2144
+ df_exercise=df[(df['option']==option) & (df['maturity']==maturity)]
2145
+ exerciselist=list(set(list(df_exercise['exercise'])))
2146
+ exerciselist.sort()
2147
+ exerciselist2=list(map(int,exerciselist))
2148
+ print(" Available exercises:",exerciselist2)
2149
+ return None
2150
+
2151
+
2152
+ df['delta']=df['DELTA_VALUE']
2153
+ df['theta']=df['THETA_VALUE']
2154
+ df['gamma']=df['GAMMA_VALUE']
2155
+ df['vega']=df['VEGA_VALUE']
2156
+ df['rho']=df['RHO_VALUE']
2157
+ df['implied volatility']=df['IMPLC_VOLATLTY']
2158
+
2159
+ itemlist=["date",'option','underlying','direction','maturity','exercise', \
2160
+ 'delta','theta','gamma','vega','rho','implied volatility']
2161
+ df2=df[itemlist]
2162
+
2163
+ #提取符合条件的记录
2164
+ df9=df2[(df2['option']==option) \
2165
+ & (df2['maturity']==maturity) & (df2['exercise']==exercise)]
2166
+ #综合检查:全部条件
2167
+ if len(df9) == 0:
2168
+ print(" #Warning(fin_option_risk_sse): options not available combining",option,maturity,exercise)
2169
+ df9tmp=df2[(df2['option']==option) & (df2['maturity']==maturity)]
2170
+ execlist=list(df9tmp['exercise'])
2171
+ exerciselist=[]
2172
+ for e in execlist:
2173
+ eint=int(e)
2174
+ exerciselist=exerciselist+[eint]
2175
+ # 消除重复并排序
2176
+ print(" Exercises available under",option,maturity,"\b:",sorted(list(set(exerciselist))))
2177
+ return None
2178
+
2179
+ df9C=df9[(df9['direction']=='C')]
2180
+ underlying=df9C['underlying'][0]+'.SS'
2181
+ deltaC=df9C['delta'][0]
2182
+ thetaC=df9C['theta'][0]
2183
+ gammaC=df9C['gamma'][0]
2184
+ vegaC=df9C['vega'][0]
2185
+ rhoC=df9C['rho'][0]
2186
+ impvolC=df9C['implied volatility'][0]
2187
+
2188
+ df9P=df9[df9['direction']=='P']
2189
+ deltaP=df9P['delta'][0]
2190
+ thetaP=df9P['theta'][0]
2191
+ gammaP=df9P['gamma'][0]
2192
+ vegaP=df9P['vega'][0]
2193
+ rhoP=df9P['rho'][0]
2194
+ impvolP=df9P['implied volatility'][0]
2195
+
2196
+ print("\n===== 期权风险指标 =====\n")
2197
+ print("***期权:",option,"\b,交易日期:",trade_date)
2198
+ print("标的物代码:",underlying,"\b,到期时间:",maturity,"\b,行权股指点位:",exercise)
2199
+
2200
+ print("\n***风险指标:")
2201
+ print("【看涨】Delta =",deltaC,"\b,Theta =",thetaC,"\b,Gamma =",gammaC,"\b,Vega =",vegaC,"\b,Rho =",rhoC)
2202
+ print("隐含波动率 =",impvolC)
2203
+
2204
+ print("【看跌】Delta =",deltaP,"\b,Theta =",thetaP,"\b,Gamma =",gammaP,"\b,Vega =",vegaP,"\b,Rho =",rhoP)
2205
+ print("隐含波动率 =",impvolP)
2206
+
2207
+ import datetime; today = datetime.date.today()
2208
+ footnote="数据来源: 新浪财经/东方财富, "+str(today)
2209
+ print('\n'+footnote)
2210
+
2211
+ return df9
2212
+
2213
+ if __name__=='__main__':
2214
+ df=fin_option_risk_sse(option='50ETF',maturity='2209',exercise=3000,date='2022-9-26')
2215
+
2216
+ #==============================================================================
2217
+ if __name__=='__main__':
2218
+ option='50ETF'
2219
+ maturity='2412'
2220
+ exercise=3000
2221
+
2222
+ option='300ETF'
2223
+ exercise=3500
2224
+
2225
+ trade_date='2024-9-10'
2226
+ printout=True
2227
+
2228
+ def fin_option_risk_sse2(option,maturity,exercise,trade_date, \
2229
+ printout=True,loc='best',facecolor='whitesmoke'):
2230
+ """
2231
+ 功能:显示指定上交所金融期权的风险指标
2232
+ option: 期权名称
2233
+ maturity: 到期年月YYMM
2234
+ exercise: 行权点位
2235
+ direction: 方向,看涨看跌
2236
+ """
2237
+
2238
+ #初始检查:期权名称
2239
+ optionlist=["50ETF","300ETF","500ETF","科创50","科创板50"]
2240
+ if not (option in optionlist):
2241
+ print(" #Error(fin_option_risk_sse): option not found in SSE for",option)
2242
+ return None
2243
+
2244
+ #初始检查:交易日期
2245
+ if not check_date(trade_date):
2246
+ print(" #Error(fin_option_risk_sse): invalid date",trade_date)
2247
+ return None
2248
+ akdate=convert_date_ts(trade_date)
2249
+
2250
+ import pandas as pd
2251
+ import numpy as np
2252
+ import akshare as ak
2253
+
2254
+ #获取交易日数据
2255
+ try:
2256
+ df = ak.option_risk_indicator_sse(date=akdate)
2257
+ except:
2258
+ print(" #Warning(fin_option_risk_sse): failed to retrieved data for",trade_date)
2259
+ return None
2260
+
2261
+ df['Date']=df['TRADE_DATE']
2262
+ df['date']=df['TRADE_DATE']
2263
+ df['Date']=pd.to_datetime(df['Date'])
2264
+ df.set_index('Date',inplace=True)
2265
+ df.sort_index(ascending=True,inplace=True)
2266
+
2267
+ df['direction']=df['CONTRACT_ID'].apply(lambda x: x[6:7])
2268
+ df['underlying']=df['CONTRACT_ID'].apply(lambda x: x[:6])
2269
+
2270
+ df['ETF end']=df['CONTRACT_SYMBOL'].apply(lambda x: x.find('购'))
2271
+ df['ETF end']=df.apply(lambda x: x['CONTRACT_SYMBOL'].find('沽') if x['ETF end'] < 0 else x['ETF end'],axis=1)
2272
+ df['option']=df.apply(lambda x: x['CONTRACT_SYMBOL'][:x['ETF end']],axis=1)
2273
+
2274
+ df['exercise']=df['CONTRACT_ID'].apply(lambda x: float(x[12:]))
2275
+
2276
+ #筛选指定的期权
2277
+ df=df[df['option']==option]
2278
+
2279
+ #进一步检查:到期日
2280
+ df['maturity']=df['CONTRACT_ID'].apply(lambda x: x[7:11])
2281
+ if not (maturity in list(df['maturity'])):
2282
+ print(" #Warning(fin_option_risk_sse): maturity not found in SSE for",maturity)
2283
+
2284
+ df_maturity=df[(df['option']==option) & (df['exercise']==exercise)]
2285
+ maturitylist=list(set(list(df_maturity['maturity'])))
2286
+ maturitylist.sort()
2287
+ print(" On "+trade_date+", available maturities:",maturitylist)
2288
+ return None
2289
+
2290
+ #进一步检查:行权点位
2291
+ if not (exercise in list(df['exercise'])):
2292
+ print(" #Warning(fin_option_risk_sse): exericse point not found in SSE for",exercise)
2293
+
2294
+ df_exercise=df[(df['option']==option) & (df['maturity']==maturity)]
2295
+ exerciselist=list(set(list(df_exercise['exercise'])))
2296
+ exerciselist.sort()
2297
+ exerciselist2=list(map(int,exerciselist))
2298
+ print(" Available exercises:",exerciselist2)
2299
+ return None
2300
+
2301
+ #整理数据项
2302
+ df['Delta']=df['DELTA_VALUE']
2303
+ df['Gamma']=df['GAMMA_VALUE']
2304
+ df['Theta']=df['THETA_VALUE']
2305
+ df['Vega']=df['VEGA_VALUE']
2306
+ df['Rho']=df['RHO_VALUE']
2307
+ df['Implied Volatility']=df['IMPLC_VOLATLTY']
2308
+
2309
+ itemlist=["date",'option','underlying','direction','maturity','exercise', \
2310
+ 'Delta','Gamma','Theta','Vega','Rho','Implied Volatility']
2311
+ df2=df[itemlist]
2312
+
2313
+ #提取符合条件的记录
2314
+ df9=df2[(df2['option']==option) \
2315
+ & (df2['maturity']==maturity) & (df2['exercise']==exercise)]
2316
+ #综合检查:全部条件
2317
+ if len(df9) == 0:
2318
+ print(" #Error(fin_option_risk_sse): options not available fulfilling",option,maturity,exercise)
2319
+ return None
2320
+
2321
+ #去重
2322
+ df9a=df9.drop_duplicates(subset=['date','option','underlying','direction','maturity','exercise'],keep='first')
2323
+
2324
+ #绘制看涨看跌期权风险对比柱状图
2325
+ #排序,保证看涨期权排在前面
2326
+ df9a.sort_values(by='direction',ascending=True,inplace=True)
2327
+ #df9b=df9a[['delta','theta','gamma','vega','rho','implied volatility']]
2328
+ df9b=df9a[['Delta','Gamma','Theta','Vega','Rho']]
2329
+ dfg=df9b.T
2330
+ dfg.columns=['看涨期权','看跌期权']
2331
+
2332
+ #fig = plt.figure()
2333
+ import matplotlib.pyplot as plt
2334
+ #plt.rcParams['figure.figsize']=(12.8,7.2)
2335
+ plt.rcParams['figure.figsize']=(12.8,6.4)
2336
+ plt.rcParams['figure.dpi']=300
2337
+ """
2338
+ c=dfg.plot(kind='bar', y=['看涨期权','看跌期权'],figsize=(12.8,6.4),width=0.8,
2339
+ color=['green','red'],fontsize=16)
2340
+ """
2341
+ #柱状图填充图案
2342
+ hatch_par = ['/', '', '|', '-', '+', 'x', 'o', 'O', '.', '*']
2343
+ c=dfg.plot(kind='bar', y=['看涨期权','看跌期权'],width=0.8,
2344
+ color=['green','red'],fontsize=16,alpha=0.5)
2345
+
2346
+ #display the percentages above the bars as shown above 数据标签列表
2347
+ x=np.arange(len(dfg.index))
2348
+ yv=np.array(list(dfg['看涨期权']))
2349
+ ys=np.array(list(dfg['看跌期权']))
2350
+
2351
+ import numpy as np
2352
+ textupper=0.01
2353
+ #textlower=0.065
2354
+ textlower=0.01
2355
+
2356
+ for a,b in zip(x,yv): ##控制标签位置:横坐标,纵坐标
2357
+ if b >= 0:
2358
+ plt.text(a-0.2,b+textupper,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
2359
+ else:
2360
+ #plt.text(a-0.2,b-textlower,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
2361
+ plt.text(a-0.2,b-textlower,'%.3f'%b,ha = 'center',va = 'top',fontsize=14)
2362
+ for a,b in zip(x,ys):
2363
+ if b >= 0:
2364
+ plt.text(a+0.2,b+textupper,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
2365
+ else:
2366
+ #plt.text(a+0.2,b-textlower,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
2367
+ plt.text(a+0.2,b-textlower,'%.3f'%b,ha = 'center',va = 'top',fontsize=14)
2368
+
2369
+ #绘制图片边框
2370
+ c.spines['top'].set_visible(True)
2371
+ c.spines['right'].set_visible(True)
2372
+ c.spines['bottom'].set_visible(True) #保留横坐标边框
2373
+ c.spines['left'].set_visible(True)
2374
+
2375
+ #绘制零线
2376
+ plt.axhline(y=0, color='k', linestyle='--')
2377
+
2378
+ plt.xticks(rotation=0)
2379
+
2380
+ #option,maturity,exercise,trade_date
2381
+ footnote0="风险指标\n"
2382
+ footnote1="注:"+"到期年月"+maturity+",行权股指点位"+str(exercise)+",交易日"+trade_date
2383
+ import datetime; today = datetime.date.today()
2384
+ footnote2="数据来源: 新浪财经/东方财富, 制图"+str(today)
2385
+ footnote=footnote0+footnote1+"\n"+footnote2
2386
+ plt.xlabel(footnote,fontweight='bold',fontsize=xlabel_txt_size)
2387
+ plt.ylabel('希腊值') # y轴空轴
2388
+
2389
+ #use font size 16 for the title, and, 标题字号
2390
+ plt.title("希腊值风险全景图:"+option+"期权",fontsize=18)
2391
+
2392
+ #use font size 14 for the bar labels, percentages, and legend, 图例颜色
2393
+ plt.legend(fontsize=16,loc=loc)
2394
+
2395
+ plt.gca().set_facecolor(facecolor)
2396
+ plt.show
2397
+
2398
+ return df9
2399
+
2400
+ if __name__=='__main__':
2401
+ df=fin_option_risk_sse2(option='50ETF', \
2402
+ maturity='2209', \
2403
+ exercise=3000, \
2404
+ trade_date='2022-9-26')
2405
+
2406
+ #==============================================================================
2407
+ #==============================================================================
2408
+ if __name__=='__main__':
2409
+ option='50ETF'
2410
+ maturity='2412'
2411
+ exercise=2500
2412
+ trade_date='2024-9-10'
2413
+ measure='delta'
2414
+
2415
+ graph=True
2416
+ loc1='best'
2417
+ loc2='best'
2418
+
2419
+ twinx=False
2420
+ zeroline=False
2421
+ loc1='best';loc2='best'
2422
+ date_range=False;date_freq=False;date_fmt='%Y-%m'
2423
+
2424
+ def fin_option_maturity_risk_sse(option,exercise,trade_date, \
2425
+ measure='delta', \
2426
+ graph=True, \
2427
+ twinx=False,zeroline=False, \
2428
+ loc1='best',loc2='best', \
2429
+ date_range=False,date_freq=False,date_fmt='%Y-%m',
2430
+ facecolor='whitesmoke'):
2431
+ """
2432
+ 功能:绘制指定上交所金融期权的风险指标曲线,风险因素:到期日maturity(横轴),各个风险指标(纵轴,看涨/看跌)
2433
+ option: 期权名称
2434
+ maturity: 到期年月YYMM
2435
+ exercise: 行权点位
2436
+ direction: 方向,看涨看跌
2437
+ """
2438
+
2439
+ #初步检查:期权名称
2440
+ optionlist=["50ETF","300ETF","500ETF","科创50","科创板50"]
2441
+ if not (option in optionlist):
2442
+ print(" #Error(fin_option_maturity_risk_sse): option not found in SSE for",option)
2443
+ return None
2444
+
2445
+ #初步检查:交易日期
2446
+ if not check_date(trade_date):
2447
+ print(" #Error(fin_option_maturity_risk_sse): invalid date",trade_date)
2448
+ return None
2449
+ akdate=convert_date_ts(trade_date)
2450
+
2451
+ #初步检查:风险指标
2452
+ measurelist=['delta','theta','gamma','vega','rho','implied volatility']
2453
+ if not (measure in measurelist):
2454
+ print(" #Error(fin_option_maturity_risk_sse): invalid measure",measure)
2455
+ print(" Valid measure:",measurelist)
2456
+ return None
2457
+
2458
+ import pandas as pd
2459
+ import akshare as ak
2460
+ try:
2461
+ df = ak.option_risk_indicator_sse(date=akdate)
2462
+ except:
2463
+ print(" #Warning(fin_option_maturity_risk_sse): no data available for this date",trade_date)
2464
+ return None
2465
+
2466
+ df['tdate']=df['TRADE_DATE']
2467
+ df['direction']=df['CONTRACT_ID'].apply(lambda x: x[6:7])
2468
+ df['underlying']=df['CONTRACT_ID'].apply(lambda x: x[:6])
2469
+ df['maturity']=df['CONTRACT_ID'].apply(lambda x: x[7:11])
2470
+
2471
+ #获得期权名称
2472
+ #df['ETF end']=df['CONTRACT_SYMBOL'].apply(lambda x: x.find('ETF')+3)
2473
+ df['ETF end']=df['CONTRACT_SYMBOL'].apply(lambda x: x.find('购'))
2474
+ df['ETF end']=df.apply(lambda x: x['CONTRACT_SYMBOL'].find('沽') if x['ETF end'] < 0 else x['ETF end'],axis=1)
2475
+ df['option']=df.apply(lambda x: x['CONTRACT_SYMBOL'][:x['ETF end']],axis=1)
2476
+
2477
+ df['exercise']=df['CONTRACT_ID'].apply(lambda x: float(x[12:]))
2478
+ if not (exercise in list(df['exercise'])):
2479
+ print(" #Warning(fin_option_maturity_risk_sse): exericse point not found in SSE for",exercise)
2480
+
2481
+ df_exercise=df[(df['option']==option)]
2482
+ exerciselist=list(set(list(df_exercise['exercise'])))
2483
+ exerciselist.sort()
2484
+ exerciselist2=list(map(int,exerciselist))
2485
+ print(" Available exercises:",exerciselist2)
2486
+ return None
2487
+
2488
+ #获得风险指标
2489
+ df['delta']=df['DELTA_VALUE']
2490
+ df['theta']=df['THETA_VALUE']
2491
+ df['gamma']=df['GAMMA_VALUE']
2492
+ df['vega']=df['VEGA_VALUE']
2493
+ df['rho']=df['RHO_VALUE']
2494
+ df['implied volatility']=df['IMPLC_VOLATLTY']
2495
+
2496
+ itemlist=["tdate",'option','underlying','direction','maturity','exercise', \
2497
+ 'delta','theta','gamma','vega','rho','implied volatility']
2498
+ df2=df[itemlist]
2499
+
2500
+ df9=df2[(df2['option']==option) & (df2['exercise']==exercise)]
2501
+ if len(df9) == 0:
2502
+ print(" #Warning(fin_option_maturity_risk_sse): options not available fulfilling",option,exercise)
2503
+ return None
2504
+
2505
+ df9['Date']=df9['maturity'].apply(lambda x: '20'+x[:2]+'-'+x[2:4]+'-26')
2506
+ df9['Date']=pd.to_datetime(df9['Date'])
2507
+ df9.set_index('Date',inplace=True)
2508
+ df9.sort_index(ascending=True,inplace=True)
2509
+
2510
+ df9.sort_values(by=['direction','maturity'],ascending=True,inplace=True)
2511
+
2512
+ df9C=df9[df9['direction']=='C']
2513
+ df9P=df9[df9['direction']=='P']
2514
+ underlying=df9C['underlying'][0]+'.SS'
2515
+
2516
+ #绘图:看涨+看跌
2517
+ ticker1="看涨期权"; colname1=measure
2518
+ #label1=measure
2519
+ ticker2="看跌期权"; colname2=measure
2520
+ #label2=measure
2521
+ #ylabeltxt="风险指标"
2522
+ ylabeltxt=ectranslate(measure)
2523
+ titletxt='希腊值风险趋势:'+option+'期权,到期期限对'+ylabeltxt+"的影响"
2524
+
2525
+ footnote0="到期时间(不同期权)\n"
2526
+ footnote1=option+"期权"+",行权股指点位"+str(exercise)+",交易日"+trade_date
2527
+ import datetime; today = datetime.date.today()
2528
+ footnote2="数据来源: 新浪财经/东方财富, 制图"+str(today)
2529
+ footnote=footnote0+footnote1+"\n"+footnote2
2530
+
2531
+ #设置zeroline
2532
+ maxC=df9C[colname1].max(); minC=df9C[colname1].min()
2533
+ maxP=df9P[colname2].max(); minP=df9P[colname2].min()
2534
+
2535
+ aboveZero=False; belowZero=False
2536
+ if maxC>0 or minC>0 or maxP>0 or minP>0: aboveZero=True
2537
+ if maxC<0 or minC<0 or maxP<0 or minP<0: belowZero=True
2538
+ if aboveZero and belowZero:
2539
+ zeroline=True
2540
+ else:
2541
+ zeroline=False
2542
+
2543
+ if twinx:
2544
+ zeroline=False
2545
+
2546
+ """
2547
+ plot2_line2(df9C,ticker1,colname1,'', \
2548
+ df9P,ticker2,colname2,'', \
2549
+ ylabeltxt,titletxt,footnote, \
2550
+ twinx=twinx, \
2551
+ zeroline=zeroline,yline=0, \
2552
+ loc1=loc1,loc2=loc2, \
2553
+ date_range=date_range,date_freq=date_freq,date_fmt=date_fmt)
2554
+ """
2555
+ plot_line2(df9C,ticker1,colname1,'', \
2556
+ df9P,ticker2,colname2,'', \
2557
+ ylabeltxt=ylabeltxt,titletxt=titletxt,footnote=footnote, \
2558
+ zeroline=zeroline,twinx=twinx, \
2559
+ loc1=loc1,loc2=loc2, \
2560
+ facecolor=facecolor
2561
+ )
2562
+
2563
+ return df9
2564
+
2565
+ if __name__=='__main__':
2566
+ df=fin_option_maturity_risk_sse(option='300ETF',exercise=4500,trade_date='2022-9-26',measure='implied volatility')
2567
+
2568
+ #==============================================================================
2569
+ if __name__=='__main__':
2570
+ option='300ETF'
2571
+ maturity='2209'
2572
+ exercise=3000
2573
+ trade_date='2022-9-26'
2574
+ measure='implied volatility'
2575
+ graph=True
2576
+ loc1='best'
2577
+ loc2='best'
2578
+
2579
+ def fin_option_exercise_risk_sse(option,maturity,trade_date, \
2580
+ measure='delta', \
2581
+ graph=True, \
2582
+ zeroline=False, \
2583
+ loc1='best',loc2='best',
2584
+ facecolor='whitesmoke'):
2585
+ """
2586
+ 功能:绘制指定上交所金融期权的风险指标曲线,风险因素:行权点位exercise(横轴),各个风险指标(纵轴,看涨/看跌)
2587
+ option: 期权名称
2588
+ maturity: 到期年月YYMM
2589
+ exercise: 行权点位
2590
+ direction: 方向,看涨看跌
2591
+ """
2592
+
2593
+ #初步检查:期权名称
2594
+ optionlist=["50ETF","300ETF","500ETF","科创50","科创板50"]
2595
+ if not (option in optionlist):
2596
+ print(" #Error(fin_option_exercise_risk_sse): option not found in SSE for",option)
2597
+ return None
2598
+
2599
+ #初步检查:日期
2600
+ if not check_date(trade_date):
2601
+ print(" #Error(fin_option_exercise_risk_sse): invalid date",trade_date)
2602
+ return None
2603
+ akdate=convert_date_ts(trade_date)
2604
+
2605
+ #初步检查:风险指标
2606
+ measurelist=['delta','theta','gamma','vega','rho','implied volatility']
2607
+ if not (measure in measurelist):
2608
+ print(" #Error(fin_option_exercise_risk_sse): invalid measure",measure)
2609
+ print(" Valid measure:",measurelist)
2610
+ return None
2611
+
2612
+ print("\nStarting to search information necessary, please wait ...")
2613
+ import pandas as pd
2614
+ import akshare as ak
2615
+ try:
2616
+ #print("akdate =",akdate)
2617
+ df = ak.option_risk_indicator_sse(date=akdate)
2618
+ except:
2619
+ print(" #Warning(fin_option_exercise_risk_sse): no data available on",trade_date)
2620
+ return None
2621
+
2622
+ df['tdate']=df['TRADE_DATE']
2623
+ df['direction']=df['CONTRACT_ID'].apply(lambda x: x[6:7])
2624
+ df['underlying']=df['CONTRACT_ID'].apply(lambda x: x[:6])
2625
+
2626
+ #进一步检查:到期日
2627
+ df['maturity']=df['CONTRACT_ID'].apply(lambda x: x[7:11])
2628
+ if not (maturity in list(df['maturity'])):
2629
+ print(" #Error(fin_option_exercise_risk_sse): maturity not found in SSE for",maturity)
2630
+
2631
+ df_maturity=df[(df['option']==option)]
2632
+ maturitylist=list(set(list(df_maturity['maturity'])))
2633
+ maturitylist.sort()
2634
+ print(" On "+trade_date+", available maturities:",maturitylist)
2635
+ return None
2636
+
2637
+ df['exercise']=df['CONTRACT_ID'].apply(lambda x: float(x[12:]))
2638
+
2639
+ #获得期权名称
2640
+ df['ETF end']=df['CONTRACT_SYMBOL'].apply(lambda x: x.find('购'))
2641
+ df['ETF end']=df.apply(lambda x: x['CONTRACT_SYMBOL'].find('沽') if x['ETF end'] < 0 else x['ETF end'],axis=1)
2642
+ df['option']=df.apply(lambda x: x['CONTRACT_SYMBOL'][:x['ETF end']],axis=1)
2643
+
2644
+ #获得风险指标
2645
+ df['delta']=df['DELTA_VALUE']
2646
+ df['theta']=df['THETA_VALUE']
2647
+ df['gamma']=df['GAMMA_VALUE']
2648
+ df['vega']=df['VEGA_VALUE']
2649
+ df['rho']=df['RHO_VALUE']
2650
+ df['implied volatility']=df['IMPLC_VOLATLTY']
2651
+
2652
+ itemlist=["tdate",'option','underlying','direction','maturity','exercise', \
2653
+ 'delta','theta','gamma','vega','rho','implied volatility']
2654
+ df2=df[itemlist]
2655
+
2656
+ df9=df2[(df2['option']==option) & (df2['maturity']==maturity)]
2657
+ if len(df9) == 0:
2658
+ print(" #Error(fin_option_exercise_risk_sse): options not available fulfilling",option,maturity)
2659
+ return None
2660
+ df9.sort_values(by=['direction','exercise'],ascending=True,inplace=True)
2661
+
2662
+ df9C=df9[df9['direction']=='C']
2663
+ df9P=df9[df9['direction']=='P']
2664
+ underlying=list(set(list(df9C['underlying'])))[0]+'.SS'
2665
+
2666
+ #绘图:看涨+看跌
2667
+ import matplotlib.pyplot as plt
2668
+
2669
+ dftmp=df9C
2670
+ labeltxt="看涨期权"
2671
+ plt.plot(dftmp.exercise,dftmp[measure],'-',label=labeltxt, \
2672
+ linestyle='-',color='blue',linewidth=2)
2673
+
2674
+ dftmp=df9P
2675
+ labeltxt="看跌期权"
2676
+ plt.plot(dftmp.exercise,dftmp[measure],'-',label=labeltxt, \
2677
+ linestyle='--',color='orange',linewidth=2)
2678
+
2679
+ #设置zeroline
2680
+ maxC=df9C[measure].max(); minC=df9C[measure].min()
2681
+ maxP=df9P[measure].max(); minP=df9P[measure].min()
2682
+
2683
+ aboveZero=False; belowZero=False
2684
+ if maxC>0 or minC>0 or maxP>0 or minP>0: aboveZero=True
2685
+ if maxC<0 or minC<0 or maxP<0 or minP<0: belowZero=True
2686
+ if aboveZero and belowZero:
2687
+ zeroline=True
2688
+ else:
2689
+ zeroline=False
2690
+
2691
+ if zeroline:
2692
+ plt.axhline(y=0,label='',ls=":",c="black",linewidth=2.5)
2693
+
2694
+ plt.legend(loc=loc1,fontsize=legend_txt_size)
2695
+ ylabeltxt=ectranslate(measure)
2696
+ plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
2697
+
2698
+ footnote1="行权股指点位"
2699
+ footnote2=option+"期权"+",到期时间"+maturity+",交易日"+trade_date
2700
+
2701
+ import datetime; today = datetime.date.today()
2702
+ footnote3="数据来源: 新浪财经/东方财富, 制图"+str(today)
2703
+ footnote=footnote1+"\n"+footnote2+"\n"+footnote3
2704
+ plt.xlabel(footnote,fontsize=xlabel_txt_size)
2705
+
2706
+ titletxt='希腊值风险趋势:'+option+'期权,股指点位对'+ylabeltxt+'的影响'
2707
+ plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
2708
+
2709
+ plt.gca().set_facecolor(facecolor)
2710
+ plt.show()
2711
+ plt.close()
2712
+
2713
+ return df9
2714
+
2715
+ if __name__=='__main__':
2716
+ df=fin_option_exercise_risk_sse(option='300ETF',maturity='2209',trade_date='2022-9-26',measure='implied volatility')
2717
+
2718
+ #==============================================================================
2719
+ if __name__=='__main__':
2720
+ option='300ETF'
2721
+ maturity='2412'
2722
+ exercise=3500
2723
+ start='2024-8-10'
2724
+ end ="2024-9-10"
2725
+ measure='delta'
2726
+
2727
+ graph=True
2728
+ twinx=True;zeroline=True
2729
+ loc1='best'
2730
+ loc2='best'
2731
+ date_range=False
2732
+ date_freq=False
2733
+ facecolor='whitesmoke'
2734
+
2735
+ df=fin_option_time_risk_sse(option='300ETF',
2736
+ maturity='2412',
2737
+ exercise=3500,
2738
+ start='2024-8-10',end='2024-9-10',
2739
+ measure='delta',
2740
+ twinx=True,
2741
+ zeroline=True)
2742
+
2743
+ def fin_option_time_risk_sse(option,maturity,exercise,start,end, \
2744
+ measure='delta', \
2745
+ graph=True, \
2746
+ twinx=False, zeroline=False, \
2747
+ loc1='best',loc2='best', \
2748
+ date_range=False,date_freq=False,
2749
+ facecolor='whitesmoke'):
2750
+ """
2751
+ 功能:绘制指定上交所金融期权的风险指标曲线,风险因素:随时间推移start/end(横轴),各个风险指标(纵轴,看涨/看跌)
2752
+ option: 期权名称
2753
+ maturity: 到期年月YYMM
2754
+ exercise: 行权点位
2755
+ start: 开始日期
2756
+ end: 结束日期
2757
+ date_range: True标注每个日期,False为系统自动
2758
+ date_freq: 日期标注频率,仅在date_range为True时起作用,例如'2D'为每隔2天,'2M'为每隔2个月,'1Y'为每年,False为每天
2759
+ """
2760
+
2761
+ #初步检查:期权名称
2762
+ optionlist=["50ETF","300ETF","500ETF","科创50","科创板50"]
2763
+ if not (option in optionlist):
2764
+ print(" #Error(fin_option_time_risk_sse): option not found in SSE for",option)
2765
+ return None
2766
+
2767
+ #初步检查:交易日期
2768
+ flag,startpd,endpd=check_period(start,end)
2769
+ if not flag:
2770
+ print(" #Error(fin_option_time_risk_sse): invalid date or period",start,end)
2771
+ return None
2772
+
2773
+ #初步检查:风险指标
2774
+ measurelist=['delta','theta','gamma','vega','rho','implied volatility']
2775
+ if not (measure in measurelist):
2776
+ print(" #Error(fin_option_time_risk_sse): invalid measure",measure)
2777
+ print(" Valid measure:",measurelist)
2778
+ return None
2779
+
2780
+ print("\nStarting to search information necessary, please wait ...")
2781
+ import pandas as pd
2782
+ import akshare as ak
2783
+
2784
+ #循环获取各个交易日的指标
2785
+ df=pd.DataFrame()
2786
+ curdate=start; curdatepd=startpd
2787
+
2788
+ num_days=calculate_days(start, end)
2789
+ num=0
2790
+ #print("Searching information on ",end='')
2791
+ while curdatepd <= endpd:
2792
+ #print(curdate,end=' ')
2793
+ akdate=convert_date_ts(curdate)
2794
+ try:
2795
+ dftmp = ak.option_risk_indicator_sse(date=akdate)
2796
+ df=df._append(dftmp)
2797
+ except:
2798
+ pass
2799
+
2800
+ curdate=date_adjust(curdate,adjust=1)
2801
+ curdatepd=pd.to_datetime(curdate)
2802
+
2803
+ print_progress_percent(num,num_days-1,steps=5,leading_blanks=2)
2804
+ num=num+1
2805
+
2806
+ print(' ')
2807
+
2808
+ #整理数据
2809
+ df['Date']=df['TRADE_DATE']
2810
+ df['date']=df['TRADE_DATE']
2811
+ df['Date']=pd.to_datetime(df['Date'])
2812
+ df.set_index('Date',inplace=True)
2813
+ df.sort_index(ascending=True,inplace=True)
2814
+
2815
+ df['direction']=df['CONTRACT_ID'].apply(lambda x: x[6:7])
2816
+ df['underlying']=df['CONTRACT_ID'].apply(lambda x: x[:6])
2817
+
2818
+ #获得期权名称
2819
+ df['ETF end']=df['CONTRACT_SYMBOL'].apply(lambda x: x.find('购'))
2820
+ df['ETF end']=df.apply(lambda x: x['CONTRACT_SYMBOL'].find('沽') if x['ETF end'] < 0 else x['ETF end'],axis=1)
2821
+ df['option']=df.apply(lambda x: x['CONTRACT_SYMBOL'][:x['ETF end']],axis=1)
2822
+
2823
+ df['maturity']=df['CONTRACT_ID'].apply(lambda x: x[7:11])
2824
+ df['exercise']=df['CONTRACT_ID'].apply(lambda x: float(x[12:]))
2825
+ #进一步检查:到期日
2826
+ if not (maturity in list(df['maturity'])):
2827
+ print(" #Error(fin_option_time_risk_sse): maturity not found in SSE for",maturity)
2828
+
2829
+ df_maturity=df[(df['option']==option) & (df['exercise']==exercise)]
2830
+ maturitylist=list(set(list(df_maturity['maturity'])))
2831
+ maturitylist.sort()
2832
+ print(" Available maturities:",maturitylist)
2833
+ return None
2834
+ #进一步检查:行权点位
2835
+ if not (exercise in list(df['exercise'])):
2836
+ print(" #Error(fin_option_time_risk_sse): exericse point not found in SSE for",exercise)
2837
+
2838
+ df_exercise=df[(df['option']==option) & (df['maturity']==maturity)]
2839
+ exerciselist=list(set(list(df_exercise['exercise'])))
2840
+ exerciselist.sort()
2841
+ exerciselist2=list(map(int,exerciselist))
2842
+ print(" Available exercises:",exerciselist2)
2843
+ return None
2844
+
2845
+ #获得风险指标
2846
+ df['delta']=df['DELTA_VALUE']
2847
+ df['theta']=df['THETA_VALUE']
2848
+ df['gamma']=df['GAMMA_VALUE']
2849
+ df['vega']=df['VEGA_VALUE']
2850
+ df['rho']=df['RHO_VALUE']
2851
+ df['implied volatility']=df['IMPLC_VOLATLTY']
2852
+
2853
+ itemlist=["date",'option','underlying','direction','maturity','exercise', \
2854
+ 'delta','theta','gamma','vega','rho','implied volatility']
2855
+ df2=df[itemlist]
2856
+
2857
+ df9=df2[(df2['option']==option) & (df2['maturity']==maturity) & (df2['exercise']==exercise)]
2858
+ if len(df9) == 0:
2859
+ print(" #Error(fin_option_time_risk_sse): options not available fulfilling",option,maturity,exercise)
2860
+ return None
2861
+ df9.sort_values(by=['date','direction','maturity'],ascending=True,inplace=True)
2862
+
2863
+ df9C=df9[df9['direction']=='C']
2864
+ df9P=df9[df9['direction']=='P']
2865
+ underlying=list(set(list(df9C['underlying'])))[0]+'.SS'
2866
+
2867
+ #绘图:看涨+看跌
2868
+ ticker1="看涨期权"; colname1=measure
2869
+ #label1=measure
2870
+ ticker2="看跌期权"; colname2=measure
2871
+ #label2=measure
2872
+ #ylabeltxt="风险指标"
2873
+ ylabeltxt=ectranslate(measure)
2874
+ titletxt='希腊值风险趋势:'+option+'期权,时间流逝对'+ylabeltxt+'的影响'
2875
+
2876
+ footnote0="时间流逝(同一期权)\n"
2877
+ footnote1=option+"期权"+",行权股指点位"+str(exercise)+",到期时间"+maturity
2878
+ import datetime; today = datetime.date.today()
2879
+ footnote2="数据来源: 新浪财经/东方财富, 制图"+str(today)
2880
+ footnote=footnote0+footnote1+"\n"+footnote2
2881
+
2882
+ if not date_range:
2883
+ ndays=date_delta(start,end)
2884
+ if ndays <= 20:
2885
+ date_range=True
2886
+ elif ndays <= 40:
2887
+ date_range=True; date_freq='2D'
2888
+ elif ndays <=60:
2889
+ date_range=True; date_freq='3D'
2890
+ elif ndays <=80:
2891
+ date_range=True; date_freq='4D'
2892
+
2893
+ #设置zeroline
2894
+ maxC=df9C[colname1].max(); minC=df9C[colname1].min()
2895
+ maxP=df9P[colname2].max(); minP=df9P[colname2].min()
2896
+
2897
+ aboveZero=False; belowZero=False
2898
+ if maxC>0 or minC>0 or maxP>0 or minP>0: aboveZero=True
2899
+ if maxC<0 or minC<0 or maxP<0 or minP<0: belowZero=True
2900
+ if aboveZero and belowZero:
2901
+ zeroline=True
2902
+ else:
2903
+ zeroline=False
2904
+
2905
+ if twinx:
2906
+ zeroline=False
2907
+ """
2908
+ plot2_line2(df9C,ticker1,colname1,'', \
2909
+ df9P,ticker2,colname2,'', \
2910
+ ylabeltxt,titletxt,footnote, \
2911
+ twinx=twinx, \
2912
+ zeroline=zeroline,yline=0, \
2913
+ loc1=loc1,loc2=loc2, \
2914
+ date_range=date_range,date_freq=date_freq)
2915
+ """
2916
+ plot_line2(df9C,ticker1,colname1,'', \
2917
+ df9P,ticker2,colname2,'', \
2918
+ ylabeltxt=ylabeltxt,titletxt=titletxt,footnote=footnote, \
2919
+ zeroline=zeroline,twinx=twinx, \
2920
+ loc1=loc1,loc2=loc2, \
2921
+ facecolor=facecolor
2922
+ )
2923
+
2924
+ return df9
2925
+
2926
+ if __name__=='__main__':
2927
+ df=fin_option_time_risk_sse(option='300ETF',maturity='2209',exercise=4500,start='2022-8-26',end='2022-9-26',measure='implied volatility')
2928
+ #==============================================================================
2929
+ #==============================================================================
2930
+ #==============================================================================
2931
+ if __name__=='__main__':
2932
+ end_month="2303"
2933
+ numOfWeek=3
2934
+ numOfWeekday=5
2935
+
2936
+ # 期权到期月份2303的第3个星期5
2937
+ option_expire_date('2303',3,5)
2938
+
2939
+ def option_expire_date(end_month,numOfWeek,numOfWeekday):
2940
+ """
2941
+ 功能:给出期权的到期时间YYMM,第numOfWeek个星期的星期几nameOfWeekday
2942
+ end_month:期权的到期月份YYMM
2943
+ numOfWeek:第几个星期,整数
2944
+ nameOfWeekday:星期几,整数
2945
+ """
2946
+ year=int("20"+end_month[:2])
2947
+ month=int(end_month[2:4])
2948
+
2949
+ import calendar
2950
+ c = calendar.Calendar(firstweekday=calendar.SUNDAY)
2951
+ monthcal = c.monthdatescalendar(year, month)
2952
+
2953
+ try:
2954
+ wanted_date = [day for week in monthcal for day in week if
2955
+ day.weekday() == numOfWeekday-1 and day.month == month][numOfWeek-1]
2956
+
2957
+ import datetime
2958
+ strdate=datetime.datetime.strftime(wanted_date,'%Y-%m-%d')
2959
+ return strdate
2960
+
2961
+ except IndexError:
2962
+ print(" #Error(option_expire_date): invalid date --> weekday",numOfWeekday,'of week',numOfWeek,'in',end_month)
2963
+ return None
2964
+
2965
+ #==============================================================================
2966
+ #==============================================================================
2967
+ #==============================================================================
2968
+ if __name__=='__main__':
2969
+ options='50ETF'
2970
+ maturity='2412'
2971
+ exercise=3000
2972
+ trade_date='recent'
2973
+ period_days=30
2974
+ risk='none'
2975
+ twinx=False
2976
+ zeroline=False
2977
+ printout=True; graph=True
2978
+ facecolor='whitesmoke'
2979
+
2980
+ def options_greek_china(options, \
2981
+ exercise=0, \
2982
+ maturity='recent', \
2983
+ trade_date='recent', \
2984
+ period_days=30, \
2985
+ risk='none', \
2986
+ greek='delta', \
2987
+ twinx=False, \
2988
+ zeroline=False, \
2989
+ printout=False, graph=True, \
2990
+ facecolor='whitesmoke', \
2991
+ loc1='best',loc2='best'):
2992
+ """
2993
+ 功能:套壳函数
2994
+ 套壳:fin_option_risk_sse, fin_option_risk_sse2, fin_option_maturity_risk_sse,
2995
+ fin_option_exercise_risk_sse, fin_option_time_risk_sse
2996
+
2997
+ 套壳条件:
2998
+ 当printout==True且risk=='none'时,执行fin_option_risk_sse
2999
+ 当printout==False且graph==True且risk=='none'时,执行fin_option_risk_sse2
3000
+ 当risk=='maturity'时,执行fin_option_maturity_risk_sse
3001
+ 当risk=='exercise'时,执行fin_option_exercise_risk_sse
3002
+ 当risk=='time'时,执行fin_option_time_risk_sse
3003
+ """
3004
+ #处理默认日期为上一个非周末的交易日,也可手动指定交易日
3005
+ if trade_date=='recent':
3006
+ import datetime as dt; stoday=dt.date.today()
3007
+ wd=stoday.weekday() #周一为0
3008
+ if wd==6:#周日
3009
+ trade_date=date_adjust(str(stoday), adjust=-2)
3010
+ elif wd==0:#周一
3011
+ trade_date=date_adjust(str(stoday), adjust=-3)
3012
+ else:
3013
+ trade_date=date_adjust(str(stoday), adjust=-1)
3014
+
3015
+ if risk=='none':
3016
+ if printout:
3017
+ df=fin_option_risk_sse(option=options,
3018
+ maturity=maturity,
3019
+ exercise=exercise,
3020
+ trade_date=trade_date)
3021
+ return df
3022
+
3023
+ if not printout and graph:
3024
+ df=fin_option_risk_sse2(option=options,
3025
+ maturity=maturity,
3026
+ exercise=exercise,
3027
+ trade_date=trade_date)
3028
+ return df
3029
+
3030
+ if risk=='maturity':
3031
+ df=fin_option_maturity_risk_sse(option=options,
3032
+ exercise=exercise,
3033
+ trade_date=trade_date,
3034
+ measure=greek,
3035
+ twinx=twinx,
3036
+ zeroline=zeroline,
3037
+ loc1=loc1,loc2=loc2)
3038
+ return df
3039
+
3040
+ if risk=='exercise':
3041
+ df=fin_option_exercise_risk_sse(option=options,
3042
+ maturity=maturity,
3043
+ trade_date=trade_date,
3044
+ measure=greek,
3045
+ zeroline=zeroline,
3046
+ loc1=loc1,loc2=loc2)
3047
+ return df
3048
+
3049
+ if risk=='time':
3050
+ start=date_adjust(trade_date, adjust=-period_days)
3051
+ df=fin_option_time_risk_sse(option=options,
3052
+ maturity=maturity,
3053
+ exercise=exercise,
3054
+ start=start,end=trade_date,
3055
+ measure=greek,
3056
+ twinx=twinx,
3057
+ zeroline=zeroline,
3058
+ loc1=loc1,loc2=loc2)
3059
+ return df
3060
+
3061
+ print("Sorry, no idea on what I can do for you:-(")
3062
+ return None
3063
+
3064
+
3065
+ #==============================================================================
3066
+ #==============================================================================
3067
+ #==============================================================================
3068
+ #==============================================================================
3069
+ #==============================================================================