siat 3.10.75__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 +34 -7
- siat/capm_beta.py +34 -9
- siat/common.py +88 -7
- siat/economy2.py +75 -1
- siat/exchange_bond_china.pickle +0 -0
- siat/fama_french.py +201 -12
- siat/financial_statements.py +26 -85
- siat/financials.py +114 -14
- siat/financials_china.py +1 -1
- siat/fund_china.py +6 -5
- siat/future_china.py +8 -2
- siat/holding_risk.py +38 -31
- siat/market_china.py +20 -10
- siat/markowitz2.py +72 -10
- siat/option_china.py +45 -17
- siat/option_pricing.py +3 -0
- siat/other_indexes.py +16 -3
- siat/risk_adjusted_return.py +182 -114
- siat/risk_evaluation.py +252 -20
- siat/sector_china.py +12 -9
- siat/security_price2.py +19 -4
- siat/security_prices.py +222 -23
- siat/security_trend2.py +3 -3
- siat/stock.py +32 -0
- siat/translate.py +18 -9
- siat/var_model_validation.py +59 -0
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/METADATA +1 -1
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/RECORD +32 -32
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/LICENSE +0 -0
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/WHEEL +0 -0
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/top_level.txt +0 -0
siat/assets_liquidity.py
CHANGED
@@ -73,6 +73,40 @@ if __name__=='__main__':
|
|
73
73
|
pfdf=get_portfolio_prices(pf,start,end)
|
74
74
|
rs=calc_roll_spread(pfdf)
|
75
75
|
|
76
|
+
#==============================================================================
|
77
|
+
|
78
|
+
def calc_liquidity(portfolio,indicator='amihud', \
|
79
|
+
start='MRY',end='today',printout=True):
|
80
|
+
"""
|
81
|
+
功能;计算投资组合的流动性,包括罗尔价差、阿米胡德非流动性以及PS流动性
|
82
|
+
"""
|
83
|
+
start,end=start_end_preprocess(start,end)
|
84
|
+
|
85
|
+
if not isinstance(portfolio,dict):
|
86
|
+
print(f" #Error(calc_liquidity): unrecognizable form of portfolio {portfolio}")
|
87
|
+
print(f" Only support securities in the form of a portfolio")
|
88
|
+
return
|
89
|
+
|
90
|
+
indicator1=indicator.lower()
|
91
|
+
|
92
|
+
liquidity_list=['roll','amihud','ps']
|
93
|
+
if not (indicator1 in liquidity_list):
|
94
|
+
print(f" #Error(calc_liquidity): unsupported liquidity type {indicator}")
|
95
|
+
print(f" Supported liquidity: {liquidity_list}")
|
96
|
+
return
|
97
|
+
|
98
|
+
if 'roll' in indicator1:
|
99
|
+
liq=roll_spread_portfolio(portfolio,start,end,printout)
|
100
|
+
return
|
101
|
+
|
102
|
+
if 'amihud' in indicator1:
|
103
|
+
liq=amihud_illiquidity_portfolio(portfolio,start,end,printout)
|
104
|
+
return
|
105
|
+
|
106
|
+
if 'ps' in indicator1:
|
107
|
+
liq=ps_liquidity_portfolio(portfolio,start,end,printout)
|
108
|
+
return
|
109
|
+
|
76
110
|
#==============================================================================
|
77
111
|
def roll_spread_portfolio(portfolio,start,end,printout=True):
|
78
112
|
"""
|
@@ -82,7 +116,8 @@ def roll_spread_portfolio(portfolio,start,end,printout=True):
|
|
82
116
|
输出:罗尔价差%
|
83
117
|
注意:含爬虫部分,调用其他函数
|
84
118
|
"""
|
85
|
-
|
119
|
+
print(f" Calculating Roll spread ...")
|
120
|
+
|
86
121
|
#仅为测试用
|
87
122
|
#portfolio={'Market':('US','^GSPC'),'EDU':0.7,'TAL':0.3}
|
88
123
|
#start='2019-06-01'
|
@@ -95,9 +130,21 @@ def roll_spread_portfolio(portfolio,start,end,printout=True):
|
|
95
130
|
return None
|
96
131
|
|
97
132
|
#抓取股票价格,构建投资组合价格
|
98
|
-
|
133
|
+
#屏蔽函数内print信息输出的类
|
134
|
+
import os, sys
|
135
|
+
class HiddenPrints:
|
136
|
+
def __enter__(self):
|
137
|
+
self._original_stdout = sys.stdout
|
138
|
+
sys.stdout = open(os.devnull, 'w')
|
139
|
+
|
140
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
141
|
+
sys.stdout.close()
|
142
|
+
sys.stdout = self._original_stdout
|
143
|
+
|
144
|
+
with HiddenPrints():
|
145
|
+
sp=get_portfolio_prices(portfolio,start2,end2)
|
99
146
|
if sp is None:
|
100
|
-
print(" #Error(roll_spread_portfolio): portfolio info not available
|
147
|
+
print(" #Error(roll_spread_portfolio): portfolio info not available")
|
101
148
|
return None
|
102
149
|
|
103
150
|
#计算罗尔价差指标
|
@@ -111,15 +158,18 @@ def roll_spread_portfolio(portfolio,start,end,printout=True):
|
|
111
158
|
'-'+str(sp.index[-1].day)
|
112
159
|
print("\n===== 投资组合的流动性风险 =====")
|
113
160
|
|
161
|
+
"""
|
114
162
|
_,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
|
115
163
|
if len(tickerlist)==1:
|
116
164
|
product=str(ticker_name(tickerlist,'bond'))
|
117
165
|
else:
|
118
166
|
product=str(ticker_name(tickerlist))+' by '+str(sharelist)
|
119
|
-
|
167
|
+
"""
|
168
|
+
print("证券资产:",portfolio_name(portfolio))
|
120
169
|
print("计算期间:",date_start,"to",date_end, \
|
121
170
|
"(可用日期)")
|
122
|
-
print("罗尔价差%:",rs_pct)
|
171
|
+
#print("罗尔价差%:",rs_pct)
|
172
|
+
print("罗尔价差比率:",str(rs_pct)+'%')
|
123
173
|
|
124
174
|
return rs_pct
|
125
175
|
|
@@ -166,7 +216,8 @@ def amihud_illiquidity_portfolio(portfolio,start,end,printout=True):
|
|
166
216
|
输出:阿米胡德非流动性指数
|
167
217
|
注意:含爬虫部分,调用其他函数
|
168
218
|
"""
|
169
|
-
|
219
|
+
print(f" Calculating Amihud illiquidity ...")
|
220
|
+
|
170
221
|
#仅为测试用
|
171
222
|
#portfolio={'Market':('US','^GSPC'),'EDU':0.7,'TAL':0.3}
|
172
223
|
#start='2019-06-01'
|
@@ -179,8 +230,29 @@ def amihud_illiquidity_portfolio(portfolio,start,end,printout=True):
|
|
179
230
|
return None
|
180
231
|
|
181
232
|
#抓取股票价格,构建投资组合价格
|
182
|
-
|
183
|
-
|
233
|
+
#屏蔽函数内print信息输出的类
|
234
|
+
import os, sys
|
235
|
+
class HiddenPrints:
|
236
|
+
def __enter__(self):
|
237
|
+
self._original_stdout = sys.stdout
|
238
|
+
sys.stdout = open(os.devnull, 'w')
|
239
|
+
|
240
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
241
|
+
sys.stdout.close()
|
242
|
+
sys.stdout = self._original_stdout
|
243
|
+
|
244
|
+
with HiddenPrints():
|
245
|
+
sp=get_portfolio_prices(portfolio,start2,end2)
|
246
|
+
if sp is None:
|
247
|
+
print(" #Error(amihud_illiquidity_portfolio): portfolio info not available")
|
248
|
+
return None
|
249
|
+
"""
|
250
|
+
with HiddenPrints():
|
251
|
+
sp,found=get_price_1portfolio(portfolio,start2,end2)
|
252
|
+
if found != 'Found':
|
253
|
+
print(" #Error(amihud_illiquidity_portfolio): portfolio info not available")
|
254
|
+
return None
|
255
|
+
"""
|
184
256
|
#计算指标
|
185
257
|
amihud=calc_amihud_illiquidity(sp)
|
186
258
|
|
@@ -191,13 +263,14 @@ def amihud_illiquidity_portfolio(portfolio,start,end,printout=True):
|
|
191
263
|
date_end=str(sp.index[-1].year)+'-'+str(sp.index[-1].month)+ \
|
192
264
|
'-'+str(sp.index[-1].day)
|
193
265
|
print("\n===== 投资组合的流动性风险 =====")
|
194
|
-
|
266
|
+
"""
|
195
267
|
_,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
|
196
268
|
if len(tickerlist)==1:
|
197
269
|
product=str(ticker_name(tickerlist,'bond'))
|
198
270
|
else:
|
199
271
|
product=str(ticker_name(tickerlist))+' by '+str(sharelist)
|
200
|
-
|
272
|
+
"""
|
273
|
+
print("证券资产:",portfolio_name(portfolio))
|
201
274
|
print("计算期间:",date_start,"至",date_end, \
|
202
275
|
"(可用日期)")
|
203
276
|
print("阿米胡德非流动性:",amihud,"(对数算法)")
|
@@ -233,7 +306,7 @@ def calc_ps_liquidity(pfdf):
|
|
233
306
|
reg2=reg1[['Ret-RF','Mkt_1','signAmt_1']].copy()
|
234
307
|
|
235
308
|
#回归前彻底删除带有NaN和inf等无效值的样本,否则回归中可能出错
|
236
|
-
reg2=reg2[~reg2.isin([np.nan, np.inf, -np.inf]).any(1)].dropna()
|
309
|
+
reg2=reg2[~reg2.isin([np.nan, np.inf, -np.inf]).any(axis=1)].dropna()
|
237
310
|
if len(reg2) == 0: return None
|
238
311
|
|
239
312
|
##计算帕斯托-斯坦堡流动性PSL
|
@@ -312,7 +385,7 @@ def ps_liquidity_portfolio(portfolio,start,end,printout=True):
|
|
312
385
|
输出:帕斯托-斯坦堡流动性
|
313
386
|
注意:含爬虫部分,调用其他函数
|
314
387
|
"""
|
315
|
-
|
388
|
+
print(f" Calculating Pastor-Stambaugh liquidity ...")
|
316
389
|
#仅为测试用
|
317
390
|
#portfolio={'Market':('US','^GSPC'),'EDU':0.7,'TAL':0.3}
|
318
391
|
#start='2019-06-01'
|
@@ -325,7 +398,22 @@ def ps_liquidity_portfolio(portfolio,start,end,printout=True):
|
|
325
398
|
return None
|
326
399
|
|
327
400
|
#抓取股票价格,构建投资组合价格
|
328
|
-
|
401
|
+
#屏蔽函数内print信息输出的类
|
402
|
+
import os, sys
|
403
|
+
class HiddenPrints:
|
404
|
+
def __enter__(self):
|
405
|
+
self._original_stdout = sys.stdout
|
406
|
+
sys.stdout = open(os.devnull, 'w')
|
407
|
+
|
408
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
409
|
+
sys.stdout.close()
|
410
|
+
sys.stdout = self._original_stdout
|
411
|
+
|
412
|
+
with HiddenPrints():
|
413
|
+
sp=get_portfolio_prices(portfolio,start2,end2)
|
414
|
+
if sp is None:
|
415
|
+
print(" #Error(ps_liquidity_portfolio): portfolio info not available")
|
416
|
+
return None
|
329
417
|
|
330
418
|
#计算帕斯托-斯坦堡流动性
|
331
419
|
psl=calc_ps_liquidity(sp)
|
@@ -338,12 +426,14 @@ def ps_liquidity_portfolio(portfolio,start,end,printout=True):
|
|
338
426
|
'-'+str(sp.index[-1].day)
|
339
427
|
print("\n===== 投资组合的流动性风险 =====")
|
340
428
|
|
429
|
+
"""
|
341
430
|
_,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
|
342
431
|
if len(tickerlist)==1:
|
343
432
|
product=str(ticker_name(tickerlist,'bond'))
|
344
433
|
else:
|
345
434
|
product=str(ticker_name(tickerlist))+' by '+str(sharelist)
|
346
|
-
|
435
|
+
"""
|
436
|
+
print("证券资产:",portfolio_name(portfolio))
|
347
437
|
print("计算期间:",date_start,"to",date_end, \
|
348
438
|
"(可用日期)")
|
349
439
|
print("Pastor-Stambaugh流动性:",psl,"(对数算法)")
|
@@ -659,35 +749,79 @@ if __name__=='__main__':
|
|
659
749
|
window=30
|
660
750
|
graph=True
|
661
751
|
liquidity_type='roll_spread'
|
752
|
+
liquidity_type='ps'
|
662
753
|
liqs=liquidity_rolling(portfolio,start,end,liquidity_type)
|
663
754
|
|
664
755
|
|
665
756
|
#==============================================================================
|
666
757
|
#==============================================================================
|
667
|
-
def compare_liquidity(portfolio1,portfolio2,start,end,
|
758
|
+
def compare_liquidity(portfolio1,portfolio2,start='MRY',end='today', \
|
759
|
+
indicator='amihud',window=30, \
|
760
|
+
period_value=False):
|
668
761
|
"""
|
669
762
|
功能:套壳函数compare_liquidity_rolling,无差异,保持兼容性
|
670
763
|
"""
|
764
|
+
start,end=start_end_preprocess(start,end)
|
765
|
+
|
766
|
+
indicator1=indicator.lower()
|
767
|
+
if 'roll' in indicator1:
|
768
|
+
indicator1='roll_spread'
|
769
|
+
elif 'amihud' in indicator1:
|
770
|
+
indicator1='amihud_illiquidity'
|
771
|
+
else:
|
772
|
+
indicator1='ps_liquidity'
|
671
773
|
|
672
774
|
compare_liquidity_rolling(portfolio1=portfolio1,portfolio2=portfolio2, \
|
673
|
-
start=start,end=end,liquidity_type=
|
775
|
+
start=start,end=end,liquidity_type=indicator1, \
|
674
776
|
window=window)
|
675
777
|
|
778
|
+
|
779
|
+
#对比两个投资组合在期间内的流动性整体数值
|
780
|
+
if period_value:
|
781
|
+
calc_liquidity(portfolio1,start=start,end=end,indicator=indicator)
|
782
|
+
calc_liquidity(portfolio2,start=start,end=end,indicator=indicator)
|
783
|
+
|
676
784
|
return
|
677
785
|
|
678
786
|
#==============================================================================
|
679
|
-
def compare_liquidity_rolling(portfolio1,portfolio2,start,end,
|
787
|
+
def compare_liquidity_rolling(portfolio1,portfolio2,start='MRY',end='today', \
|
788
|
+
liquidity_type='amihud_illiquidity',window=30):
|
680
789
|
"""
|
681
790
|
功能:比较两个投资组合portfolio1和portfolio2在start至end期间的流动性指标liquidity_type
|
682
791
|
"""
|
792
|
+
start,end=start_end_preprocess(start,end)
|
793
|
+
|
794
|
+
if not(isinstance(portfolio1,dict)):
|
795
|
+
print(" #Error(compare_liquidity_rolling): unresolveable protfolio {portfolio1}")
|
796
|
+
return
|
797
|
+
|
798
|
+
if not(isinstance(portfolio2,dict)):
|
799
|
+
print(" #Error(compare_liquidity_rolling): unresolveable protfolio {portfolio2}")
|
800
|
+
return
|
801
|
+
|
802
|
+
print(" Working on the liquidities of 2 securities ...")
|
803
|
+
|
804
|
+
#屏蔽函数内print信息输出的类
|
805
|
+
import os, sys
|
806
|
+
class HiddenPrints:
|
807
|
+
def __enter__(self):
|
808
|
+
self._original_stdout = sys.stdout
|
809
|
+
sys.stdout = open(os.devnull, 'w')
|
810
|
+
|
811
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
812
|
+
sys.stdout.close()
|
813
|
+
sys.stdout = self._original_stdout
|
814
|
+
|
683
815
|
#投资组合1
|
684
816
|
pf1name=portfolio_name(portfolio1)
|
685
817
|
if pf1name == '投资组合':
|
686
818
|
pf1name == '组合1'
|
687
|
-
|
688
|
-
|
819
|
+
|
820
|
+
with HiddenPrints():
|
821
|
+
liqs1=liquidity_rolling(portfolio1,start,end,liquidity_type, \
|
822
|
+
window=window,graph=False)
|
689
823
|
if liqs1 is None:
|
690
|
-
print(" #Error(compare_liquidity_rolling): portfolio info inaccesible for"
|
824
|
+
print(f" #Error(compare_liquidity_rolling): portfolio info inaccesible for {pf1name}")
|
691
825
|
return
|
692
826
|
|
693
827
|
colname1='Ratio'
|
@@ -702,11 +836,13 @@ def compare_liquidity_rolling(portfolio1,portfolio2,start,end,liquidity_type,win
|
|
702
836
|
pf2name=portfolio_name(portfolio2)
|
703
837
|
if pf2name == '投资组合':
|
704
838
|
pf2name == '组合2'
|
705
|
-
|
706
|
-
|
707
|
-
|
839
|
+
|
840
|
+
with HiddenPrints():
|
841
|
+
liqs2=liquidity_rolling(portfolio2,start,end,liquidity_type, \
|
842
|
+
window=window,graph=False)
|
843
|
+
|
708
844
|
if liqs2 is None:
|
709
|
-
print(" #Error(compare_liquidity_rolling): portfolio info inaccesible for"
|
845
|
+
print(f" #Error(compare_liquidity_rolling): portfolio info inaccesible for {pf2name}")
|
710
846
|
return
|
711
847
|
|
712
848
|
colname2='Ratio'
|
@@ -719,7 +855,7 @@ def compare_liquidity_rolling(portfolio1,portfolio2,start,end,liquidity_type,win
|
|
719
855
|
|
720
856
|
#绘图
|
721
857
|
ylabeltxt=ectranslate(liquidity_type)
|
722
|
-
titletxt="
|
858
|
+
titletxt="证券流动性风险:"+pf1name+' vs '+pf2name
|
723
859
|
|
724
860
|
_,_,tickerlist1,sharelist1,ticker_type1=decompose_portfolio(portfolio1)
|
725
861
|
if len(tickerlist1)==1:
|
@@ -737,8 +873,8 @@ def compare_liquidity_rolling(portfolio1,portfolio2,start,end,liquidity_type,win
|
|
737
873
|
footnote=pf1name+":"+product1+"\n"+pf2name+":"+product2+ \
|
738
874
|
"\n数据来源:新浪/stooq, "+str(today)
|
739
875
|
"""
|
740
|
-
if liquidity_type
|
741
|
-
notes="
|
876
|
+
if liquidity_type in ['amihud_illiquidity','ps_liquidity']:
|
877
|
+
notes="注:图中流动性指标采用对数算法\n"
|
742
878
|
else:
|
743
879
|
notes=''
|
744
880
|
footnote= notes+"数据来源:新浪/stooq, "+str(today)
|
@@ -748,10 +884,12 @@ def compare_liquidity_rolling(portfolio1,portfolio2,start,end,liquidity_type,win
|
|
748
884
|
liqs2,pf2name,colname2,label2, \
|
749
885
|
ylabeltxt,titletxt,footnote,power,datatag1,datatag2,zeroline)
|
750
886
|
|
887
|
+
"""
|
751
888
|
print("\n*** 投资组合的成分股与持仓比例")
|
752
|
-
print(pf1name+":"+product1)
|
753
|
-
print(pf2name+":"+product2)
|
754
|
-
|
889
|
+
print(pf1name+":"+list2str(product1))
|
890
|
+
print(pf2name+":"+list2str(product2))
|
891
|
+
"""
|
892
|
+
|
755
893
|
return
|
756
894
|
|
757
895
|
|
siat/bond.py
CHANGED
@@ -748,13 +748,17 @@ if __name__=='__main__':
|
|
748
748
|
|
749
749
|
prices=exchange_bond_price(symbol,fromdate,todate,power=power)
|
750
750
|
|
751
|
-
def exchange_bond_price(symbol,fromdate,todate,power=0,graph=True,data_crop=True):
|
751
|
+
#def exchange_bond_price(symbol,fromdate,todate,power=0,graph=True,data_crop=True):
|
752
|
+
def exchange_bond_price(ticker,start,end='today',power=0,graph=True,data_crop=True):
|
752
753
|
"""
|
753
754
|
功能:获得沪深债券市场历史成交行情
|
754
755
|
输入:沪深债券代码symbol,起始日期fromdate,截止日期todate。
|
755
756
|
返回:历史价格df
|
756
757
|
输出:折线图
|
757
758
|
"""
|
759
|
+
symbol=ticker
|
760
|
+
fromdate,todate=start_end_preprocess(start,end)
|
761
|
+
|
758
762
|
import pandas as pd
|
759
763
|
import akshare as ak
|
760
764
|
import datetime
|
@@ -813,7 +817,7 @@ if __name__=='__main__':
|
|
813
817
|
ebp=exchange_bond_price('sh019521',fromdate,todate)
|
814
818
|
|
815
819
|
#==============================================================================
|
816
|
-
def exchange_covbond_deal(
|
820
|
+
def exchange_covbond_deal(rank=10,option='1'):
|
817
821
|
"""
|
818
822
|
功能:获得沪深债券市场可转券即时行情
|
819
823
|
输入:从头开始显示的个数num;选项option:默认1按照交易时间排列,
|
@@ -821,6 +825,8 @@ def exchange_covbond_deal(num,option='1'):
|
|
821
825
|
5按照涨跌幅从低到高,6按照成交量从高到低排列,7按照成交量从低到高排列。
|
822
826
|
其他选项按照默认排列。
|
823
827
|
"""
|
828
|
+
num=rank
|
829
|
+
|
824
830
|
print("开始搜索互联网,可能需要一点时间,请耐心等候......")
|
825
831
|
#定义标准输出关闭类
|
826
832
|
import os, sys
|
@@ -883,7 +889,7 @@ def exchange_covbond_deal(num,option='1'):
|
|
883
889
|
'name':texttranslate('债券名称'),'trade':texttranslate('成交价'),'pricechange':texttranslate('涨跌(元)'), \
|
884
890
|
'open':texttranslate('开盘价'),'high':texttranslate('最高价'),'low':texttranslate('最低价'), \
|
885
891
|
'buy':texttranslate('买入价'),'sell':texttranslate('卖出价'),'volume':texttranslate('成交量')})
|
886
|
-
|
892
|
+
"""
|
887
893
|
print("\n***",texttranslate("沪深交易所可转债现券即时行情(")+optiontxt+texttranslate(",前")+str(num)+texttranslate("名)***"))
|
888
894
|
import pandas as pd
|
889
895
|
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
@@ -895,6 +901,15 @@ def exchange_covbond_deal(num,option='1'):
|
|
895
901
|
today = datetime.date.today().strftime("%Y-%m-%d")
|
896
902
|
footnote="\n"+texttranslate("数据来源:新浪财经,")+today
|
897
903
|
print(footnote)
|
904
|
+
"""
|
905
|
+
titletxt=texttranslate("沪深交易所可转债现券即时行情(")+optiontxt+texttranslate(",前")+str(num)+texttranslate("名)")
|
906
|
+
import datetime; todaydt = datetime.date.today().strftime("%Y-%m-%d")
|
907
|
+
footnote="\n"+texttranslate("数据来源:新浪财经,")+todaydt
|
908
|
+
|
909
|
+
df_display_CSS(df2.head(num),titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=3, \
|
910
|
+
first_col_align='left',second_col_align='left', \
|
911
|
+
last_col_align='center',other_col_align='center')
|
912
|
+
|
898
913
|
|
899
914
|
return df1
|
900
915
|
|
@@ -923,14 +938,18 @@ if __name__=='__main__':
|
|
923
938
|
|
924
939
|
cov=exchange_covbond_price(symbol,fromdate,todate)
|
925
940
|
|
926
|
-
def exchange_covbond_price(symbol,fromdate,todate,power=0,graph=True):
|
941
|
+
#def exchange_covbond_price(symbol,fromdate,todate,power=0,graph=True):
|
942
|
+
def exchange_covbond_price(ticker,start='MRY',end='today',power=0,graph=True):
|
927
943
|
"""
|
928
944
|
功能:获得沪深市场可转债历史成交行情
|
929
945
|
输入:沪深债券代码symbol,起始日期fromdate,截止日期todate。
|
930
946
|
返回:历史价格df
|
931
947
|
输出:折线图
|
932
948
|
"""
|
933
|
-
|
949
|
+
symbol=ticker
|
950
|
+
fromdate,todate=start_end_preprocess(start,end)
|
951
|
+
|
952
|
+
print(" Searching for bond",symbol,"\b, it may take time ...")
|
934
953
|
|
935
954
|
import pandas as pd
|
936
955
|
import akshare as ak
|
@@ -1142,7 +1161,11 @@ def bond_malkiel1(aytm,yper,c,fv=100,mterm=1, \
|
|
1142
1161
|
df4=df3.rename(columns={'到期收益率变化':'YTM Change','到期收益率%':'YTM%','债券价格':'Bond Price'})
|
1143
1162
|
else:
|
1144
1163
|
df4=df3
|
1145
|
-
print("\n",df4.to_string(index=False))
|
1164
|
+
#print("\n",df4.to_string(index=False))
|
1165
|
+
df_display_CSS(df4,titletxt='',footnote='',facecolor='papayawhip', \
|
1166
|
+
first_col_align='center',second_col_align='center', \
|
1167
|
+
last_col_align='center',other_col_align='center')
|
1168
|
+
|
1146
1169
|
|
1147
1170
|
#绘图
|
1148
1171
|
plt.plot(df['xLabel'],df['Price'],color='red',marker='o')
|
@@ -1241,7 +1264,11 @@ def bond_malkiel2(aytm,yper,c,fv=100,mterm=1, \
|
|
1241
1264
|
df4=df3.rename(columns={'到期时间(年)':'Year(s) to Maturity','债券价格变化':'Bond Price Change'})
|
1242
1265
|
else:
|
1243
1266
|
df4=df3
|
1244
|
-
print("\n",df4.to_string(index=False))
|
1267
|
+
#print("\n",df4.to_string(index=False))
|
1268
|
+
df_display_CSS(df4,titletxt='',footnote='',facecolor='papayawhip', \
|
1269
|
+
first_col_align='center',second_col_align='center', \
|
1270
|
+
last_col_align='center',other_col_align='center')
|
1271
|
+
|
1245
1272
|
|
1246
1273
|
#绘图
|
1247
1274
|
plt.plot(df['Maturity'],df['deltaPrice'],color='red',marker='o')
|
siat/capm_beta.py
CHANGED
@@ -316,22 +316,36 @@ def capm_beta_yearly(ticker,mktidx,yearlist):
|
|
316
316
|
betas=betas._append(row,ignore_index=True)
|
317
317
|
#print(year,round(beta,4),round(r_value**2,3),round(p_value,4))
|
318
318
|
|
319
|
+
betas['Significance']=betas['p-value'].apply(lambda x: '***' if x<0.01 \
|
320
|
+
else '**' if x<0.05 else '*' if x<0.1 else '')
|
321
|
+
|
319
322
|
#设置打印标题与数据对齐
|
323
|
+
"""
|
320
324
|
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
321
325
|
pd.set_option('display.unicode.east_asian_width', True)
|
322
326
|
pd.set_option('display.width', 180) # 设置打印宽度(**重要**)
|
323
327
|
|
324
|
-
print("\n =====
|
328
|
+
print("\n ===== 分年度静态贝塔系数:",ticker_name(ticker),"=====")
|
325
329
|
print(betas.to_string(index=False))
|
326
|
-
import datetime as dt;
|
327
|
-
print("
|
328
|
-
|
330
|
+
import datetime as dt; todaydt=dt.date.today()
|
331
|
+
print("数据来源:新浪/stooq/fred,基于"+ticker_name(mktidx)+','+str(dttoday))
|
332
|
+
print('') #空一行
|
333
|
+
"""
|
334
|
+
titletxt="分年度静态贝塔系数: "+ticker_name(ticker)
|
335
|
+
import datetime as dt; todaydt=dt.date.today()
|
336
|
+
footnote="数据来源:新浪/stooq/fred,基于"+ticker_name(mktidx)+', '+str(todaydt)
|
337
|
+
df_display_CSS(betas,titletxt=titletxt,footnote=footnote,facecolor='papayawhip', \
|
338
|
+
decimals=4, \
|
339
|
+
first_col_align='center',second_col_align='center', \
|
340
|
+
last_col_align='center',other_col_align='center')
|
341
|
+
|
342
|
+
#准备绘图
|
329
343
|
betas.set_index('Year',inplace=True)
|
330
344
|
|
331
345
|
#绘图:年度贝塔系数趋势
|
332
346
|
df=pd.DataFrame(betas['Beta'])
|
333
|
-
title="
|
334
|
-
foot="\n数据来源:新浪/stooq/fred,基于"+ticker_name(mktidx)+','+str(
|
347
|
+
title="分年度静态贝塔系数: "+ticker_name(ticker)
|
348
|
+
foot="\n数据来源:新浪/stooq/fred,基于"+ticker_name(mktidx)+','+str(todaydt)
|
335
349
|
plot_trend(title,foot,df,power=3,axhline_value=1,axhline_label='市场风险线')
|
336
350
|
|
337
351
|
return betas
|
@@ -485,13 +499,24 @@ def capm_beta_portfolio_yearly(tickerlist,sharelist,mktidx,yearlist):
|
|
485
499
|
betas=betas.append(row,ignore_index=True)
|
486
500
|
except:
|
487
501
|
betas=betas._append(row,ignore_index=True)
|
488
|
-
|
489
|
-
|
502
|
+
|
503
|
+
betas['Significance']=betas['p-value'].apply(lambda x: '***' if x<0.01 \
|
504
|
+
else '**' if x<0.05 else '*' if x<0.1 else '')
|
505
|
+
#print("\n",betas)
|
506
|
+
|
507
|
+
titletxt="投资组合的静态年度贝塔系数"
|
508
|
+
import datetime as dt; todaydt=dt.date.today()
|
509
|
+
footnote="数据来源:新浪/stooq/fred,基于"+ticker_name(mktidx)+', '+str(todaydt)
|
510
|
+
df_display_CSS(betas,titletxt=titletxt,footnote=footnote,facecolor='papayawhip', \
|
511
|
+
decimals=4, \
|
512
|
+
first_col_align='center',second_col_align='center', \
|
513
|
+
last_col_align='center',other_col_align='center')
|
514
|
+
|
490
515
|
betas.set_index('Year',inplace=True)
|
491
516
|
|
492
517
|
#绘图:年度贝塔系数变化
|
493
518
|
df=pd.DataFrame(betas['Beta'])
|
494
|
-
title="
|
519
|
+
title="投资组合的静态年度贝塔系数"+ \
|
495
520
|
"\n成分股: "+str(ticker_name(tickerlist,'bond'))+"\n持仓权重: "+str(sharelist)
|
496
521
|
import datetime; today = datetime.date.today()
|
497
522
|
foot="数据来源: 新浪/stooq/fred,"+str(today)
|