siat 3.10.25__py3-none-any.whl → 3.10.125__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.
- siat/assets_liquidity.py +168 -30
- siat/bond.py +91 -30
- siat/capm_beta.py +36 -10
- siat/capm_beta2.py +34 -3
- siat/common.py +95 -8
- siat/economy.py +3 -3
- siat/economy2.py +75 -1
- siat/exchange_bond_china.pickle +0 -0
- siat/fama_french.py +292 -12
- siat/financial_statements.py +26 -85
- siat/financials.py +156 -20
- siat/financials_china.py +1 -1
- siat/fund_china.py +52 -22
- siat/future_china.py +53 -59
- siat/grafix.py +218 -155
- siat/holding_risk.py +38 -31
- siat/market_china.py +22 -11
- siat/markowitz2.py +72 -10
- siat/option_china.py +93 -31
- siat/option_pricing.py +16 -6
- siat/other_indexes.py +16 -3
- siat/risk_adjusted_return.py +283 -164
- siat/risk_adjusted_return2.py +3 -1
- siat/risk_evaluation.py +298 -25
- siat/sector_china.py +24 -11
- siat/security_price2.py +19 -4
- siat/security_prices.py +228 -28
- siat/security_trend2.py +14 -14
- siat/stock.py +38 -3
- siat/translate.py +20 -10
- siat/var_model_validation.py +59 -0
- {siat-3.10.25.dist-info → siat-3.10.125.dist-info}/METADATA +1 -1
- {siat-3.10.25.dist-info → siat-3.10.125.dist-info}/RECORD +36 -36
- {siat-3.10.25.dist-info → siat-3.10.125.dist-info}/LICENSE +0 -0
- {siat-3.10.25.dist-info → siat-3.10.125.dist-info}/WHEEL +0 -0
- {siat-3.10.25.dist-info → siat-3.10.125.dist-info}/top_level.txt +0 -0
siat/holding_risk.py
CHANGED
@@ -562,28 +562,29 @@ def get_VaR_portfolio(portfolio,today,future_days=1,alpha=0.99, \
|
|
562
562
|
if not printout: return VaRlist,ratiolist
|
563
563
|
|
564
564
|
#输出VaR金额和比率
|
565
|
-
print("\n=====
|
566
|
-
_,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
|
567
|
-
print("成分股列表 :",tickerlist)
|
568
|
-
print("成分股的配置:",sharelist)
|
569
|
-
print("
|
570
|
-
print("
|
571
|
-
print("
|
572
|
-
print("
|
573
|
-
print("
|
574
|
-
print("
|
565
|
+
print("\n===== 在险价值VaR:投资组合 =====")
|
566
|
+
#_,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
|
567
|
+
#print("成分股列表 :",tickerlist)
|
568
|
+
#print("成分股的配置:",sharelist)
|
569
|
+
print("投资组合:",portfolio_name(portfolio))
|
570
|
+
print("当前日期:",today)
|
571
|
+
print("当前头寸(1份投资组合):",format(position,','))
|
572
|
+
print("预计持有天数:",future_days)
|
573
|
+
print("置信度水平:",str(int(alpha*100))+'%')
|
574
|
+
print("历史样本年数:",pastyears)
|
575
|
+
print("样本数量:",num)
|
575
576
|
|
576
577
|
import datetime as dt; today=dt.date.today()
|
577
|
-
footnote="
|
578
|
+
footnote="\n数据来源:新浪/stooq,"+str(today)
|
578
579
|
if not (modeltyp == 'all'):
|
579
|
-
print("
|
580
|
-
print("VaR
|
580
|
+
print("使用的模型:",model)
|
581
|
+
print("VaR金额/比率:",format(VaR,','), \
|
581
582
|
'\b,',str(round(VaR_ratio*100,2))+'%')
|
582
583
|
|
583
584
|
print(footnote)
|
584
585
|
return VaR,VaR_ratio
|
585
586
|
|
586
|
-
print("\
|
587
|
+
print("\n*** VaR金额/比率 ***")
|
587
588
|
modellist.pop()
|
588
589
|
for m in modellist:
|
589
590
|
pos=modellist.index(m)
|
@@ -687,27 +688,28 @@ def get_ES_portfolio(portfolio,today,future_days=1,alpha=0.99, \
|
|
687
688
|
|
688
689
|
#输出ES金额和比率
|
689
690
|
print("\n===== 投资组合的预期不足ES =====")
|
690
|
-
_,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
|
691
|
-
print("成分股列表 :",tickerlist)
|
692
|
-
print("成分股配置 :",sharelist)
|
693
|
-
print("
|
694
|
-
print("
|
695
|
-
print("
|
696
|
-
print("
|
697
|
-
print("
|
698
|
-
print("
|
691
|
+
#_,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
|
692
|
+
#print("成分股列表 :",tickerlist)
|
693
|
+
#print("成分股配置 :",sharelist)
|
694
|
+
print("投资组合:",portfolio_name(portfolio))
|
695
|
+
print("当前日期:",today)
|
696
|
+
print("当前头寸(1份投资组合):",format(position,','))
|
697
|
+
print("预计持有天数:",future_days)
|
698
|
+
print("置信度水平:",str(int(alpha*100))+'%')
|
699
|
+
print("历史样本年数:",pastyears)
|
700
|
+
print("样本个数:",num)
|
699
701
|
|
700
702
|
import datetime as dt; today=dt.date.today()
|
701
|
-
footnote="
|
703
|
+
footnote="\n数据来源:新浪/stooq,"+str(today)
|
702
704
|
|
703
705
|
if not (modeltyp == 'all'):
|
704
|
-
print("
|
705
|
-
print("ES
|
706
|
+
print("使用的模型:",model)
|
707
|
+
print("ES金额/比率:",format(ES,','), \
|
706
708
|
'\b,',str(round(ES_ratio*100,2))+'%')
|
707
709
|
print(footnote)
|
708
710
|
return ES,ES_ratio
|
709
711
|
|
710
|
-
print("ES
|
712
|
+
print("ES金额/比率:")
|
711
713
|
modellist.pop()
|
712
714
|
for m in modellist:
|
713
715
|
pos=modellist.index(m)
|
@@ -799,13 +801,15 @@ if __name__ == '__main__':
|
|
799
801
|
fromdate='2022-1-1'
|
800
802
|
todate='2022-4-18'
|
801
803
|
|
802
|
-
def portfolio_rets_curve(portfolio,
|
804
|
+
def portfolio_rets_curve(portfolio,start='MRY',end='today'):
|
803
805
|
"""
|
804
806
|
功能:绘制投资组合portfolio在给定期间(fromdate,todate)收益率分布的曲线,
|
805
807
|
并于相应的正态分布图对照
|
806
808
|
显示:收益率分布的直方图(实线),相应的正态分布图(虚线)
|
807
809
|
x轴为收益率(非百分比),y轴为频度(Frequency)
|
808
810
|
"""
|
811
|
+
fromdate,todate=start_end_preprocess(start,end)
|
812
|
+
|
809
813
|
#抓取投资组合股价和收益率
|
810
814
|
prices=get_portfolio_prices0(portfolio,fromdate,todate)
|
811
815
|
if prices is None: return None,None
|
@@ -833,22 +837,25 @@ def portfolio_rets_curve(portfolio,fromdate,todate):
|
|
833
837
|
#plt.ylabel('Frequency')
|
834
838
|
|
835
839
|
footnote1='日收益率%'
|
836
|
-
footnote2='\
|
837
|
-
footnote3="
|
840
|
+
footnote2='\n【注】Shapiro-Wilk检验:W值'+str(W)+',p值'+str(p_value)
|
841
|
+
footnote3="。偏度"+str(S)+",峰度"+str(K)
|
838
842
|
|
839
843
|
import datetime as dt; today=dt.date.today()
|
840
|
-
footnote4="
|
844
|
+
footnote4="。数据来源:新浪/stooq,"+str(today)
|
841
845
|
|
842
846
|
footnote=footnote1+footnote2+footnote3+footnote4
|
843
847
|
plt.xlabel(footnote)
|
844
848
|
|
845
849
|
plt.legend(loc='best')
|
850
|
+
"""
|
846
851
|
titletxt1="投资组合收益率的正态分布检验"
|
847
852
|
titletxt2="\n成分股"+str(tickerlist)
|
848
853
|
titletxt3="\n持仓配置"+str(sharelist)
|
849
854
|
titletxt4="\n样本期间:"+str(fromdate)+'至'+str(todate)+ \
|
850
855
|
',样本数量'+str(num)+'个'
|
851
856
|
titletxt=titletxt1+titletxt2+titletxt3+titletxt4
|
857
|
+
"""
|
858
|
+
titletxt="投资组合收益率的正态分布检验:"+portfolio_name(portfolio)
|
852
859
|
plt.title(titletxt)
|
853
860
|
|
854
861
|
plt.gca().set_facecolor('whitesmoke')
|
siat/market_china.py
CHANGED
@@ -123,11 +123,13 @@ def market_profile_china(market='SSE'):
|
|
123
123
|
if lang == 'Chinese':
|
124
124
|
i2=itemlist2[pos]
|
125
125
|
blanknum=maxlen-hzlen(i2)
|
126
|
-
print(' ',i2+' '*blanknum+':',end='')
|
126
|
+
#print(' ',i2+' '*blanknum+':',end='')
|
127
|
+
print(' ',i2+':',end='')
|
127
128
|
else:
|
128
129
|
i2e=itemlist2e[pos]
|
129
130
|
blanknum=maxlen-hzlen(i2e)
|
130
|
-
print(' ',i2e+' '*blanknum+':',end='')
|
131
|
+
#print(' ',i2e+' '*blanknum+':',end='')
|
132
|
+
print(' ',i2e+':',end='')
|
131
133
|
except:
|
132
134
|
pos=itemlist.index(i)
|
133
135
|
i2=itemlist2[pos]
|
@@ -136,10 +138,12 @@ def market_profile_china(market='SSE'):
|
|
136
138
|
|
137
139
|
if lang == 'Chinese':
|
138
140
|
blanknum=maxlen-hzlen(i2)
|
139
|
-
print(' ',i2+' '*blanknum+':',end='')
|
141
|
+
#print(' ',i2+' '*blanknum+':',end='')
|
142
|
+
print(' ',i2+':',end='')
|
140
143
|
else:
|
141
144
|
blanknum=maxlen-hzlen(i2e)
|
142
|
-
print(' ',i2e+' '*blanknum+':',end='')
|
145
|
+
#print(' ',i2e+' '*blanknum+':',end='')
|
146
|
+
print(' ',i2e+':',end='')
|
143
147
|
|
144
148
|
if i in ["上市股票",'上市公司']: #若是字符则转换成数字
|
145
149
|
value2=int(value)
|
@@ -176,7 +180,8 @@ def market_profile_china(market='SSE'):
|
|
176
180
|
|
177
181
|
info1t=info.T
|
178
182
|
info1t['全貌']=info1t['股票']
|
179
|
-
info1t['主板']=info1t['主板A股']+info1t['主板B股']+info1t['中小板']
|
183
|
+
#info1t['主板']=info1t['主板A股']+info1t['主板B股']+info1t['中小板']
|
184
|
+
info1t['主板']=info1t['主板A股']+info1t['主板B股']
|
180
185
|
info1t['创业板']=info1t['创业板A股']
|
181
186
|
|
182
187
|
infot2=info1t.T
|
@@ -230,11 +235,13 @@ def market_profile_china(market='SSE'):
|
|
230
235
|
if lang == 'Chinese':
|
231
236
|
i2=itemlist2[pos]
|
232
237
|
blanknum=maxlen-hzlen(i2)
|
233
|
-
print(' ',i2+' '*blanknum+':',end='')
|
238
|
+
#print(' ',i2+' '*blanknum+':',end='')
|
239
|
+
print(' ',i2+':',end='')
|
234
240
|
else:
|
235
241
|
i2e=itemlist2e[pos]
|
236
242
|
blanknum=maxlen-hzlen(i2e)
|
237
|
-
print(' ',i2e+' '*blanknum+':',end='')
|
243
|
+
#print(' ',i2e+' '*blanknum+':',end='')
|
244
|
+
print(' ',i2e+':',end='')
|
238
245
|
except:
|
239
246
|
pos=itemlist.index(i)
|
240
247
|
i2=itemlist2[pos]
|
@@ -243,10 +250,12 @@ def market_profile_china(market='SSE'):
|
|
243
250
|
|
244
251
|
if lang == 'Chinese':
|
245
252
|
blanknum=maxlen-hzlen(i2)
|
246
|
-
print(' ',i2+' '*blanknum+':',end='')
|
253
|
+
#print(' ',i2+' '*blanknum+':',end='')
|
254
|
+
print(' ',i2+':',end='')
|
247
255
|
else:
|
248
256
|
blanknum=maxlen-hzlen(i2e)
|
249
|
-
print(' ',i2e+' '*blanknum+':',end='')
|
257
|
+
#print(' ',i2e+' '*blanknum+':',end='')
|
258
|
+
print(' ',i2e+':',end='')
|
250
259
|
|
251
260
|
if i in ['数量']: #若是字符则转换成数字
|
252
261
|
value2=int(value)
|
@@ -353,11 +362,13 @@ def market_profile_china_tmp(market='SSE'):
|
|
353
362
|
value=list(subdf[subdf['item']==i]['number'])[0]
|
354
363
|
|
355
364
|
if lang == 'Chinese':
|
356
|
-
print(' ',i+' '*blanknum+':',end='')
|
365
|
+
#print(' ',i+' '*blanknum+':',end='')
|
366
|
+
print(' ',i+':',end='')
|
357
367
|
else:
|
358
368
|
pos=itemlist.index(i)
|
359
369
|
ie=itemliste[pos]
|
360
|
-
print(' ',ie+' '*blanknum+':',end='')
|
370
|
+
#print(' ',ie+' '*blanknum+':',end='')
|
371
|
+
print(' ',ie+':',end='')
|
361
372
|
|
362
373
|
print("{:,}".format(value))
|
363
374
|
|
siat/markowitz2.py
CHANGED
@@ -288,17 +288,23 @@ def portfolio_cumret(portfolio,thedate,pastyears=1, \
|
|
288
288
|
RF=0, \
|
289
289
|
printout=True,graph=True):
|
290
290
|
"""
|
291
|
-
def portfolio_build(portfolio,thedate='default',pastyears=
|
291
|
+
def portfolio_build(portfolio,thedate='default',pastyears=3, \
|
292
292
|
indicator='Adj Close', \
|
293
293
|
adjust='qfq',source='auto',ticker_type='auto', \
|
294
294
|
printout=False,graph=False,facecolor='papayawhip'):
|
295
295
|
"""
|
296
296
|
功能:收集投资组合成份股数据,绘制收益率趋势图,并与等权和期间内交易额加权策略组合比较
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
297
|
+
注意:
|
298
|
+
1. 此处无需RF,待到优化策略时再指定
|
299
|
+
2. printout=True控制下列内容是否显示:
|
300
|
+
获取股价时的信息
|
301
|
+
是否显示原始组合、等权重组合和交易金额加权组合的成分股构成
|
302
|
+
是否显示原始组合、等权重组合和交易金额加权组合的收益风险排名
|
303
|
+
3. pastyears=3更有可能生成斜向上的椭圆形可行集,需要与不同行业的证券搭配。
|
304
|
+
同行业证券相关性较强,不易生成斜向上的椭圆形可行集。
|
305
|
+
4. 若ticker_type='fund'可能导致无法处理股票的复权价!
|
306
|
+
5. 若要指定特定的证券为债券,则需要使用列表逐一指定证券的类型(股票,债券,基金)
|
307
|
+
6. 默认采用前复权计算收益率,更加平稳
|
302
308
|
"""
|
303
309
|
#判断复权标志
|
304
310
|
indicator_list=['Close','Adj Close']
|
@@ -1145,7 +1151,27 @@ if __name__=='__main__':
|
|
1145
1151
|
portfolio_eset(pf_info,simulation=50000)
|
1146
1152
|
|
1147
1153
|
def portfolio_feset(pf_info,simulation=50000,convex_hull=True,frontier="both",facecolor='papayawhip'):
|
1148
|
-
|
1154
|
+
"""
|
1155
|
+
功能:套壳函数portfolio_eset
|
1156
|
+
当frontier不在列表['efficient','inefficient','both']中时,绘制可行集
|
1157
|
+
当frontier == 'efficient'时绘制有效边界
|
1158
|
+
当frontier == 'inefficient'时绘制无效边界
|
1159
|
+
当frontier == 'both'时同时绘制有效边界和无效边界
|
1160
|
+
当绘制有效/无效边界时,默认使用凸包绘制(convex_hull=True)
|
1161
|
+
"""
|
1162
|
+
if frontier is None:
|
1163
|
+
convex_hull=False
|
1164
|
+
elif isinstance(frontier,str):
|
1165
|
+
frontier=frontier.lower()
|
1166
|
+
|
1167
|
+
frontier_list=['efficient','inefficient','both']
|
1168
|
+
if not any(element in frontier for element in frontier_list):
|
1169
|
+
convex_hull=False
|
1170
|
+
else:
|
1171
|
+
convex_hull=True
|
1172
|
+
else:
|
1173
|
+
convex_hull=False
|
1174
|
+
|
1149
1175
|
results=portfolio_eset(pf_info,simulation=simulation,convex_hull=convex_hull,frontier=frontier,facecolor=facecolor)
|
1150
1176
|
|
1151
1177
|
return results
|
@@ -1158,6 +1184,15 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
|
|
1158
1184
|
"""
|
1159
1185
|
DEBUG=True; MORE_DETAIL=False
|
1160
1186
|
|
1187
|
+
frontier_list=['efficient','inefficient','both']
|
1188
|
+
if isinstance(frontier,str):
|
1189
|
+
if any(element in frontier for element in frontier_list):
|
1190
|
+
efficient_set=True
|
1191
|
+
else:
|
1192
|
+
efficient_set=False
|
1193
|
+
else:
|
1194
|
+
efficient_set=False
|
1195
|
+
|
1161
1196
|
[[portfolio,thedate,stock_return,_,_],_]=pf_info
|
1162
1197
|
pname=portfolio_name(portfolio)
|
1163
1198
|
_,_,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
|
@@ -1322,7 +1357,20 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
|
|
1322
1357
|
if pname == '': pname='投资组合'
|
1323
1358
|
|
1324
1359
|
plt.colorbar(label='收益率/标准差')
|
1325
|
-
|
1360
|
+
|
1361
|
+
if efficient_set:
|
1362
|
+
if frontier == 'efficient':
|
1363
|
+
titletxt0=": 马科维茨有效集(有效边界)"
|
1364
|
+
elif frontier == 'inefficient':
|
1365
|
+
titletxt0=": 马科维茨无效集(无效边界)"
|
1366
|
+
elif frontier == 'both':
|
1367
|
+
titletxt0=": 马科维茨有效边界与无效边界"
|
1368
|
+
else:
|
1369
|
+
titletxt0=": 马科维茨可行集"
|
1370
|
+
else:
|
1371
|
+
titletxt0=": 马科维茨可行集"
|
1372
|
+
|
1373
|
+
plt.title(pname+titletxt0,fontsize=title_txt_size)
|
1326
1374
|
plt.ylabel("年化收益率",fontsize=ylabel_txt_size)
|
1327
1375
|
|
1328
1376
|
footnote1="年化收益率标准差-->"
|
@@ -1332,6 +1380,18 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
|
|
1332
1380
|
else:
|
1333
1381
|
if pname == '': pname='Investment Portfolio'
|
1334
1382
|
|
1383
|
+
if efficient_set:
|
1384
|
+
if frontier == 'efficient':
|
1385
|
+
titletxt0=": Markowitz Efficient Set (Efficient Frontier)"
|
1386
|
+
elif frontier == 'inefficient':
|
1387
|
+
titletxt0=": Markowitz Inefficient Set (Inefficient Frontier)"
|
1388
|
+
elif frontier == 'both':
|
1389
|
+
titletxt0=": Markowitz Efficient & Inefficient Frontier"
|
1390
|
+
else:
|
1391
|
+
titletxt0=": Markowitz Feasible Set"
|
1392
|
+
else:
|
1393
|
+
titletxt0=": Markowitz Feasible Set"
|
1394
|
+
|
1335
1395
|
plt.colorbar(label='Return/Std')
|
1336
1396
|
plt.title(pname+": Feasible/Efficient Set",fontsize=title_txt_size)
|
1337
1397
|
plt.ylabel("Annualized Return",fontsize=ylabel_txt_size)
|
@@ -1344,7 +1404,8 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
|
|
1344
1404
|
plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontsize=xlabel_txt_size)
|
1345
1405
|
|
1346
1406
|
plt.gca().set_facecolor(facecolor)
|
1347
|
-
|
1407
|
+
if efficient_set:
|
1408
|
+
plt.legend(loc='best')
|
1348
1409
|
plt.show()
|
1349
1410
|
|
1350
1411
|
return [pf_info,RandomPortfolios]
|
@@ -1905,7 +1966,7 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
|
|
1905
1966
|
if lang == 'Chinese':
|
1906
1967
|
if pname == '': pname='投资组合'
|
1907
1968
|
|
1908
|
-
plt.title(pname+":
|
1969
|
+
plt.title(pname+": 投资组合优化策略,基于"+title_ext,fontsize=title_txt_size)
|
1909
1970
|
plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
|
1910
1971
|
|
1911
1972
|
import datetime as dt; stoday=dt.date.today()
|
@@ -2350,6 +2411,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
|
|
2350
2411
|
注意:实验发现RF较小时对于结果的影响极其微小难以观察,默认设为不使用无风险利率调整收益
|
2351
2412
|
但RF较大时对于结果的影响明显变大,已经不能忽略!
|
2352
2413
|
"""
|
2414
|
+
ratio=ratio.lower()
|
2353
2415
|
|
2354
2416
|
ratio_list=['treynor','sharpe','sortino','alpha']
|
2355
2417
|
if not (ratio in ratio_list):
|
siat/option_china.py
CHANGED
@@ -40,7 +40,7 @@ def option_comm_dict_china(symbol="玉米期权"):
|
|
40
40
|
try:
|
41
41
|
#optiondict=ak.option_sina_commodity_dict(symbol=symbol)
|
42
42
|
optiondict=ak.option_commodity_contract_sina(symbol=symbol)
|
43
|
-
print("\n中国"+symbol+"
|
43
|
+
print("\n中国"+symbol+"的当前可用合约:")
|
44
44
|
#contractlist=optiondict[symbol]
|
45
45
|
contractlist=list(optiondict['合约'])
|
46
46
|
contractlist.sort(reverse=False)
|
@@ -61,11 +61,16 @@ if __name__=='__main__':
|
|
61
61
|
#==============================================================================
|
62
62
|
if __name__=='__main__':
|
63
63
|
symbol='黄金期权'
|
64
|
-
contract='
|
64
|
+
contract='au2508'
|
65
65
|
printout=True
|
66
66
|
graph=True
|
67
67
|
|
68
|
-
|
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):
|
69
74
|
"""
|
70
75
|
获取中国商品期权大类
|
71
76
|
若symbol=''或错误且contract=''时显示中国商品期权大类
|
@@ -129,14 +134,21 @@ def option_comm_china(symbol='',contract='',printout=True,graph=True):
|
|
129
134
|
print(" \n中国"+symbol+contract+"的看跌期权合约:")
|
130
135
|
printlist(df2plist,numperline=6,beforehand=' '*4,separator=' ')
|
131
136
|
|
132
|
-
if
|
133
|
-
|
137
|
+
if graph:
|
138
|
+
if not (twinx in ['UD','LR']):
|
139
|
+
footnote="行权价-->\n\n"+"数据来源:新浪财经,"+str(today)
|
140
|
+
else:
|
141
|
+
footnote="行权价-->\n"+"数据来源:新浪财经,"+str(today)
|
134
142
|
|
135
|
-
print("\nRendering graphics
|
136
|
-
titletxt="
|
143
|
+
print("\nRendering graphics btw contract and strike prices...")
|
144
|
+
titletxt="期权价格与行权价的关系:"+symbol+contract
|
145
|
+
# maxticks为bool类型时表示横轴不能按照日期处理,否则会丢失数据成空图!!!
|
137
146
|
plot_line2(df2,"看涨期权",'最新价C','价格', \
|
138
147
|
df2,"看跌期权",'最新价P','价格', \
|
139
|
-
'价格',titletxt,footnote,power=0,
|
148
|
+
'价格',titletxt,footnote,power=0, \
|
149
|
+
twinx=twinx, \
|
150
|
+
loc1=loc1,loc2=loc2, \
|
151
|
+
maxticks=False)
|
140
152
|
"""
|
141
153
|
print("Rendering graphics for the relationships btw call price and open interest ...")
|
142
154
|
titletxt="当前期权价格与持仓量的关系:"+symbol+contract+'的'+"看涨期权"
|
@@ -402,18 +414,32 @@ if __name__=='__main__':
|
|
402
414
|
detail=False
|
403
415
|
|
404
416
|
# 定义中国当前金融期权的所有品种
|
405
|
-
option_fin_list_sse=["华夏上证50ETF期权",
|
406
|
-
"
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
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期权", \
|
411
431
|
"嘉实中证500ETF期权"]
|
412
|
-
underlying_fin_list_szse=["159901.SZ",
|
432
|
+
underlying_fin_list_szse=["159901.SZ", \
|
433
|
+
"159915.SZ", \
|
434
|
+
"159919.SZ", \
|
413
435
|
"159922.SZ"]
|
414
436
|
|
415
|
-
option_fin_list_cffe=["上证50股指期权",
|
416
|
-
|
437
|
+
option_fin_list_cffe=["上证50股指期权", \
|
438
|
+
"沪深300股指期权", \
|
439
|
+
"中证1000股指期权"]
|
440
|
+
underlying_fin_list_cffe=["000016.SS", \
|
441
|
+
"000300.SS", \
|
442
|
+
"000852.SS"]
|
417
443
|
|
418
444
|
option_fin_list=option_fin_list_sse + option_fin_list_szse + option_fin_list_cffe
|
419
445
|
underlying_fin_list=underlying_fin_list_sse + underlying_fin_list_szse + underlying_fin_list_cffe
|
@@ -988,15 +1014,22 @@ def option_fin_contracts(symbol,end_month,direction='call',printout=True):
|
|
988
1014
|
printdf=contracts[collist].copy()
|
989
1015
|
printdf.columns=collistcn
|
990
1016
|
|
1017
|
+
printdf.reset_index(drop=True,inplace=True)
|
1018
|
+
|
991
1019
|
#打印对齐
|
992
1020
|
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
993
1021
|
pd.set_option('display.unicode.east_asian_width', True)
|
994
1022
|
pd.set_option('display.width', 180) # 设置打印宽度(**重要**)
|
995
1023
|
|
996
|
-
print(printdf.to_string(index=False))
|
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')
|
997
1032
|
|
998
|
-
import datetime as dt; today=str(dt.date.today())
|
999
|
-
print("\n来源:新浪/上交所/深交所/中金所,",today)
|
1000
1033
|
|
1001
1034
|
return contracts
|
1002
1035
|
|
@@ -1148,21 +1181,33 @@ if __name__=='__main__':
|
|
1148
1181
|
#=============================================================================
|
1149
1182
|
if __name__=='__main__':
|
1150
1183
|
option="华泰柏瑞沪深300ETF期权"
|
1151
|
-
end_month='
|
1152
|
-
contract='
|
1184
|
+
end_month='2512'
|
1185
|
+
contract='510300C2512M04000'
|
1153
1186
|
direction='call'
|
1154
1187
|
|
1155
|
-
today='
|
1156
|
-
sample_days=
|
1188
|
+
today='2025-6-18'
|
1189
|
+
sample_days=183
|
1157
1190
|
|
1158
|
-
rate_type='
|
1191
|
+
rate_type='treasury'
|
1159
1192
|
rate_period='1Y'
|
1160
1193
|
daysahead=183
|
1161
1194
|
|
1162
1195
|
def option_fin_pricing_china(option,end_month,contract,today,direction='call', \
|
1163
|
-
sample_days=183,
|
1196
|
+
sample_days=183, \
|
1197
|
+
rate_type='treasury',rate_period='1Y',RF=0, \
|
1198
|
+
printout=True):
|
1164
1199
|
"""
|
1165
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
|
+
|
1166
1211
|
注:波动率使用历史波动率
|
1167
1212
|
"""
|
1168
1213
|
|
@@ -1186,6 +1231,8 @@ def option_fin_pricing_china(option,end_month,contract,today,direction='call', \
|
|
1186
1231
|
rf=shibor_rate(today,rate_period)
|
1187
1232
|
elif rate_type=='TREASURY':
|
1188
1233
|
rf=treasury_yield_china(today,rate_period)
|
1234
|
+
elif rate_type=='VALUE':
|
1235
|
+
rf=RF
|
1189
1236
|
else:
|
1190
1237
|
print(" #Error(option_fin_pricing_china): invalid rate type",rate_type.lower())
|
1191
1238
|
return None
|
@@ -1852,12 +1899,14 @@ def hs300option_compare(option1,option2,loc1='best',loc2='best',twinx=False):
|
|
1852
1899
|
ticker1="期权1:"+option_description(option1)
|
1853
1900
|
else:
|
1854
1901
|
ticker1="期权1"
|
1902
|
+
#ticker1="期权1:"+option_description(option1)
|
1855
1903
|
colname1='SO Close_x'
|
1856
1904
|
|
1857
1905
|
if not twinx:
|
1858
1906
|
ticker2="期权2:"+option_description(option2)
|
1859
1907
|
else:
|
1860
1908
|
ticker2="期权2"
|
1909
|
+
#ticker2="期权2:"+option_description(option2)
|
1861
1910
|
colname2='SO Close_y'
|
1862
1911
|
|
1863
1912
|
ylabeltxt="期权价格"
|
@@ -1870,14 +1919,23 @@ def hs300option_compare(option1,option2,loc1='best',loc2='best',twinx=False):
|
|
1870
1919
|
import datetime; today = datetime.date.today()
|
1871
1920
|
footnote2="数据来源: 新浪财经/东方财富, "+str(today)
|
1872
1921
|
footnote=footnote1+footnote2
|
1873
|
-
|
1922
|
+
"""
|
1874
1923
|
plot2_line2(df12,ticker1,colname1,'', \
|
1875
1924
|
df12,ticker2,colname2,'', \
|
1876
1925
|
ylabeltxt,titletxt,footnote, \
|
1877
1926
|
twinx=twinx, \
|
1878
1927
|
loc1=loc1,loc2=loc2, \
|
1879
1928
|
date_range=False,date_freq=False)
|
1880
|
-
|
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
|
+
|
1881
1939
|
return df12
|
1882
1940
|
|
1883
1941
|
if __name__=='__main__':
|
@@ -2292,17 +2350,21 @@ def fin_option_risk_sse2(option,maturity,exercise,trade_date, \
|
|
2292
2350
|
|
2293
2351
|
import numpy as np
|
2294
2352
|
textupper=0.01
|
2295
|
-
textlower=0.065
|
2353
|
+
#textlower=0.065
|
2354
|
+
textlower=0.01
|
2355
|
+
|
2296
2356
|
for a,b in zip(x,yv): ##控制标签位置:横坐标,纵坐标
|
2297
2357
|
if b >= 0:
|
2298
2358
|
plt.text(a-0.2,b+textupper,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
|
2299
2359
|
else:
|
2300
|
-
plt.text(a-0.2,b-textlower,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
|
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)
|
2301
2362
|
for a,b in zip(x,ys):
|
2302
2363
|
if b >= 0:
|
2303
2364
|
plt.text(a+0.2,b+textupper,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
|
2304
2365
|
else:
|
2305
|
-
plt.text(a+0.2,b-textlower,'%.3f'%b,ha = 'center',va = 'bottom',fontsize=14)
|
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)
|
2306
2368
|
|
2307
2369
|
#绘制图片边框
|
2308
2370
|
c.spines['top'].set_visible(True)
|