siat 3.10.125__py3-none-any.whl → 3.10.126__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/common.py +106 -2
- siat/exchange_bond_china.pickle +0 -0
- siat/fund_china.pickle +0 -0
- siat/stock.py +10 -2
- siat/stock_info.pickle +0 -0
- {siat-3.10.125.dist-info → siat-3.10.126.dist-info}/METADATA +234 -226
- siat-3.10.126.dist-info/RECORD +76 -0
- {siat-3.10.125.dist-info → siat-3.10.126.dist-info}/WHEEL +1 -1
- {siat-3.10.125.dist-info → siat-3.10.126.dist-info/licenses}/LICENSE +0 -0
- {siat-3.10.125.dist-info → siat-3.10.126.dist-info}/top_level.txt +0 -0
- siat/__init__ -20240701.py +0 -65
- siat/__init__.py.backup_20250214.py +0 -73
- siat/alpha_vantage_test.py +0 -24
- siat/assets_liquidity_test.py +0 -44
- siat/barrons_scraping_test.py +0 -276
- siat/beta_adjustment_test.py +0 -77
- siat/bond_test.py +0 -142
- siat/capm_beta_test.py +0 -49
- siat/cmat_commons.py +0 -961
- siat/compare_cross_test.py +0 -117
- siat/concepts_iwencai.py +0 -86
- siat/concepts_kpl.py +0 -93
- siat/cryptocurrency_test.py +0 -71
- siat/derivative.py +0 -1111
- siat/economy-20230125.py +0 -1206
- siat/economy_test.py +0 -360
- siat/esg_test.py +0 -63
- siat/fama_french_test.py +0 -115
- siat/financial_statements_test.py +0 -31
- siat/financials2 - /321/205/320/231/320/277/321/206/320/254/320/274.py" +0 -341
- siat/financials_china2_test.py +0 -67
- siat/financials_china2_test2.py +0 -88
- siat/financials_china2_test3.py +0 -87
- siat/financials_china_test.py +0 -475
- siat/financials_china_test2.py +0 -197
- siat/financials_china_test2_fin_indicator.py +0 -197
- siat/financials_test.py +0 -713
- siat/fred_test.py +0 -40
- siat/fund_china_test.py +0 -175
- siat/fund_test.py +0 -40
- siat/future_china_test.py +0 -37
- siat/global_index_test.py +0 -66
- siat/grafix_test.py +0 -112
- siat/holding_risk_test.py +0 -13
- siat/local_debug_test.py +0 -100
- siat/markowitz2-20240620.py +0 -2614
- siat/markowitz_ccb_test.py +0 -37
- siat/markowitz_ef_test.py +0 -136
- siat/markowitz_old.py +0 -871
- siat/markowitz_simple-20230709.py +0 -370
- siat/markowitz_test.py +0 -164
- siat/markowitz_test2.py +0 -69
- siat/ml_cases_example1.py +0 -60
- siat/option_china_test.py +0 -447
- siat/option_pricing_test.py +0 -81
- siat/option_sina_api_test.py +0 -112
- siat/proxy_test.py +0 -84
- siat/quandl_test.py +0 -39
- siat/risk_adjusted_return_test.py +0 -81
- siat/risk_evaluation_test.py +0 -96
- siat/risk_free_rate_test.py +0 -127
- siat/sector_china_test.py +0 -203
- siat/security_price.py +0 -831
- siat/security_prices_test.py +0 -310
- siat/security_trend2-20240620.py +0 -493
- siat/setup.py +0 -41
- siat/shenwan index history test.py +0 -41
- siat/stock_china_test.py +0 -38
- siat/stock_info_test.py +0 -189
- siat/stock_list_china_test.py +0 -33
- siat/stock_technical-20240620.py +0 -2736
- siat/stock_test.py +0 -487
- siat/temp.py +0 -36
- siat/test2_graphviz.py +0 -484
- siat/test_graphviz.py +0 -411
- siat/test_markowitz_simple.py +0 -198
- siat/test_markowitz_simple_revised.py +0 -215
- siat/test_markowitz_simple_revised2.py +0 -218
- siat/transaction_test.py +0 -436
- siat/translate-20230125.py +0 -2107
- siat/translate-20230206.py +0 -2109
- siat/translate-20230215.py +0 -2158
- siat/translate_20240606.py +0 -4206
- siat/translate_241003_keep.py +0 -4300
- siat/universal_test.py +0 -100
- siat/valuation_market_china_test.py +0 -36
- siat-3.10.125.dist-info/RECORD +0 -152
siat/derivative.py
DELETED
@@ -1,1111 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
"""
|
3
|
-
本模块功能:基金与衍生品函数
|
4
|
-
所属工具包:证券投资分析工具SIAT
|
5
|
-
SIAT:Security Investment Analysis Tool
|
6
|
-
创建日期:2020年1月18日
|
7
|
-
最新修订日期:2020年5月25日
|
8
|
-
作者:王德宏 (WANG Dehong, Peter)
|
9
|
-
作者单位:北京外国语大学国际商学院
|
10
|
-
版权所有:王德宏
|
11
|
-
用途限制:仅限研究与教学使用,不可商用!商用需要额外授权。
|
12
|
-
特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
|
13
|
-
"""
|
14
|
-
|
15
|
-
#==============================================================================
|
16
|
-
#关闭所有警告
|
17
|
-
import warnings; warnings.filterwarnings('ignore')
|
18
|
-
#==============================================================================
|
19
|
-
def interbank_bond_issue_monthly(df,fromdate='*DEFAULT',todate='*DEFAULT',type='ALL'):
|
20
|
-
"""
|
21
|
-
功能:获得银行间债券市场发行金额,按月累计
|
22
|
-
输入:债券发行记录明细df,开始日期fromdate,截止日期todate;
|
23
|
-
债券类型type,默认所有类型
|
24
|
-
类型:SCP 超短期融资券,CP 短期融资券(短融),PPN 定向工具(私募券),
|
25
|
-
MTN 中期票据(中票),ABN 资产支持票据,PRN 项目收益票据,SMECN 中小集合票据
|
26
|
-
PB指的就是熊猫债。熊猫债是指境外和多边金融机构等在华发行的人民币债券。
|
27
|
-
DFI债务融资工具,PN/PPN定向工具(私募券)。
|
28
|
-
"""
|
29
|
-
#过滤日期
|
30
|
-
import pandas as pd
|
31
|
-
if fromdate.upper() != '*DEFAULT':
|
32
|
-
#测试开始日期的合理性
|
33
|
-
try:
|
34
|
-
start=pd.to_datetime(fromdate)
|
35
|
-
except:
|
36
|
-
print("*** Error(interbank_bond_issue_monthly), invalid date:",fromdate)
|
37
|
-
return None
|
38
|
-
df=df.reset_index(drop = True)
|
39
|
-
df=df.drop(df[df['releaseTime2']<start].index)
|
40
|
-
|
41
|
-
if todate.upper() != '*DEFAULT':
|
42
|
-
#测试结束日期的合理性
|
43
|
-
try:
|
44
|
-
end=pd.to_datetime(todate)
|
45
|
-
except:
|
46
|
-
print("*** Error(interbank_bond_issue_monthly), invalid:",todate)
|
47
|
-
return None
|
48
|
-
df=df.reset_index(drop = True)
|
49
|
-
df=df.drop(df[df['releaseTime2']>end].index)
|
50
|
-
|
51
|
-
#检查债券类型
|
52
|
-
bondtype=type.upper()
|
53
|
-
typelist=['PN','SCP','MTN','ABN','PB','CP','PRN','PB-MTN','DFI','ALL']
|
54
|
-
if not (bondtype in typelist):
|
55
|
-
print("...Error(interbank_bond_issue_monthly), unsupported bond type:",type)
|
56
|
-
print(" Supported bond types:",typelist)
|
57
|
-
return None
|
58
|
-
|
59
|
-
#过滤债券类型
|
60
|
-
ibbid=df
|
61
|
-
if bondtype != 'ALL':
|
62
|
-
ibbid=df.drop(df[df['regPrdtType']!=bondtype].index)
|
63
|
-
ibbid=ibbid.reset_index(drop = True)
|
64
|
-
|
65
|
-
#统计每月债券发行量
|
66
|
-
lway=lambda x: x[0:7]
|
67
|
-
ibbid['Year_Month']=ibbid['releaseDate'].map(lway).astype('str')
|
68
|
-
ibbid['issueAmount']=ibbid['firstIssueAmount'].astype('float64')
|
69
|
-
import pandas as pd
|
70
|
-
ibbim=pd.DataFrame(ibbid.groupby(by=['Year_Month'])['issueAmount'].sum())
|
71
|
-
#升序排列
|
72
|
-
ibbim.sort_values(by=['Year_Month'],ascending=[True],inplace=True)
|
73
|
-
|
74
|
-
#绘图
|
75
|
-
titletxt="中国债券市场月发行量"
|
76
|
-
if bondtype != 'ALL':
|
77
|
-
titletxt=titletxt+"("+bondtype+")"
|
78
|
-
import datetime
|
79
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
80
|
-
footnote="数据来源:中国银行间市场交易商协会(NAFMII),"+today
|
81
|
-
plot_line(ibbim,'issueAmount',"发行量","金额(亿元)", \
|
82
|
-
titletxt,footnote,power=4)
|
83
|
-
|
84
|
-
return ibbim
|
85
|
-
|
86
|
-
|
87
|
-
if __name__=='__main__':
|
88
|
-
fromdate='2010-1-1'
|
89
|
-
todate='2019-12-31'
|
90
|
-
ibbi=interbank_bond_issue_detail(fromdate,todate)
|
91
|
-
save_to_excel(ibbi,"S:/siat","bond_issue_monthly_2012_2019.xlsx")
|
92
|
-
|
93
|
-
import pandas as pd
|
94
|
-
io=r"S:/siat/bond_issue_monthly_2012_2019.xlsx"
|
95
|
-
ibbi=pd.read_excel(io)
|
96
|
-
del ibbi['Unnamed: 0']
|
97
|
-
df=ibbi
|
98
|
-
|
99
|
-
fromdate='2018-1-1'; todate='2020-12-31'; type='SCP'
|
100
|
-
ibbim=interbank_bond_issue_monthly(ibbi,fromdate,todate)
|
101
|
-
ibbim=interbank_bond_issue_monthly(ibbi,fromdate,todate,type='SCP')
|
102
|
-
ibbim=interbank_bond_issue_monthly(ibbi,fromdate,todate,type='CP')
|
103
|
-
ibbim=interbank_bond_issue_monthly(ibbi,fromdate,todate,type='MTN')
|
104
|
-
ibbim=interbank_bond_issue_monthly(ibbi,fromdate,todate,type='ABN')
|
105
|
-
ibbim=interbank_bond_issue_monthly(ibbi,fromdate,todate,type='PN')
|
106
|
-
|
107
|
-
#==============================================================================
|
108
|
-
def interbank_bond_issue_yearly(df,type='ALL'):
|
109
|
-
"""
|
110
|
-
功能:获得银行间债券市场发行金额,按月累计
|
111
|
-
输入:债券发行记录明细df;
|
112
|
-
债券类型type,默认所有类型
|
113
|
-
类型:SCP 超短期融资券,CP 短期融资券(短融),PPN 定向工具(私募券),
|
114
|
-
MTN 中期票据(中票),ABN 资产支持票据,PRN 项目收益票据,SMECN 中小集合票据
|
115
|
-
PB指的就是熊猫债。熊猫债是指境外和多边金融机构等在华发行的人民币债券。
|
116
|
-
DFI债务融资工具,PN/PPN定向工具(私募券)。
|
117
|
-
"""
|
118
|
-
|
119
|
-
#检查债券类型
|
120
|
-
bondtype=type.upper()
|
121
|
-
typelist=['PN','SCP','MTN','ABN','PB','CP','PRN','PB-MTN','DFI','ALL']
|
122
|
-
if not (bondtype in typelist):
|
123
|
-
print("...Error(interbank_bond_issue_monthly), unsupported bond type:",type)
|
124
|
-
print(" Supported bond types:",typelist)
|
125
|
-
return None
|
126
|
-
|
127
|
-
#过滤债券类型
|
128
|
-
ibbid=df
|
129
|
-
if bondtype != 'ALL':
|
130
|
-
ibbid=df.drop(df[df['regPrdtType']!=bondtype].index)
|
131
|
-
ibbid=ibbid.reset_index(drop = True)
|
132
|
-
|
133
|
-
#统计每年债券发行量
|
134
|
-
ibbid['issueAmount']=ibbid['firstIssueAmount'].astype('float64')
|
135
|
-
import pandas as pd
|
136
|
-
ibbim=pd.DataFrame(ibbid.groupby(by=['releaseYear'])['issueAmount'].sum())
|
137
|
-
#升序排列
|
138
|
-
ibbim.sort_values(by=['releaseYear'],ascending=[True],inplace=True)
|
139
|
-
|
140
|
-
#绘图
|
141
|
-
titletxt="中国债券市场年发行量"
|
142
|
-
if bondtype != 'ALL':
|
143
|
-
titletxt=titletxt+"("+bondtype+")"
|
144
|
-
import datetime
|
145
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
146
|
-
footnote="数据来源:中国银行间市场交易商协会(NAFMII),"+today
|
147
|
-
plot_line(ibbim,'issueAmount',"发行量","金额(亿元)", \
|
148
|
-
titletxt,footnote,power=4)
|
149
|
-
|
150
|
-
return ibbim
|
151
|
-
|
152
|
-
if __name__=='__main__':
|
153
|
-
fromdate='2010-1-1'
|
154
|
-
todate='2019-12-31'
|
155
|
-
ibbim=interbank_bond_issue_detail(fromdate,todate)
|
156
|
-
save_to_excel(ibbim,"S:/siat","bond_issue_monthly_2012_2019.xlsx")
|
157
|
-
|
158
|
-
import pandas as pd
|
159
|
-
io=r"S:/siat/bond_issue_monthly_2012_2019.xlsx"
|
160
|
-
ibbi=pd.read_excel(io)
|
161
|
-
del ibbi['Unnamed: 0']
|
162
|
-
|
163
|
-
ibbiy=interbank_bond_issue_yearly(ibbi,type='SCP')
|
164
|
-
ibbiy=interbank_bond_issue_yearly(ibbi,type='CP')
|
165
|
-
|
166
|
-
|
167
|
-
#==============================================================================
|
168
|
-
def interbank_bond_quote(num,option='1'):
|
169
|
-
"""
|
170
|
-
功能:获得银行间债券市场现券报价
|
171
|
-
输入:从头开始显示的个数num;选项option:默认1按照收益率从高到低排列,
|
172
|
-
2按照发行时间从早到晚排列,3按照报价机构排列。其他选项按照默认排列。
|
173
|
-
"""
|
174
|
-
#抓取银行间市场债券报价
|
175
|
-
import akshare as ak
|
176
|
-
df=ak.bond_spot_quote()
|
177
|
-
|
178
|
-
#其他选项均作为默认选项
|
179
|
-
if not option in ['1','2','3','4']: option='1'
|
180
|
-
if option=='1':
|
181
|
-
df.sort_values(by=['买入/卖出收益率(%)'],ascending=[False],inplace=True)
|
182
|
-
optiontxt="按照收益率从高到低排序"
|
183
|
-
if option=='2':
|
184
|
-
df.sort_values(by=['债券简称'],ascending=[True],inplace=True)
|
185
|
-
optiontxt="按照发行时间从早到晚排序"
|
186
|
-
if option=='3':
|
187
|
-
df.sort_values(by=['债券简称'],ascending=[False],inplace=True)
|
188
|
-
optiontxt="按照发行时间从晚到早排序"
|
189
|
-
if option=='4':
|
190
|
-
df.sort_values(by=['报价机构'],ascending=[True],inplace=True)
|
191
|
-
optiontxt="按照报价机构排序"
|
192
|
-
#重新索引
|
193
|
-
df.reset_index(drop=True)
|
194
|
-
|
195
|
-
print("\n*** 中国银行间市场债券现券即时报价("+optiontxt+",前"+str(num)+"名)***")
|
196
|
-
import pandas as pd
|
197
|
-
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
198
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
199
|
-
pd.set_option('display.width', 180) # 设置打印宽度(**重要**)
|
200
|
-
print(df.head(num).to_string(index=False))
|
201
|
-
|
202
|
-
import datetime
|
203
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
204
|
-
footnote="\n 数据来源:中国银行间市场交易商协会(NAFMII),"+today
|
205
|
-
print(footnote)
|
206
|
-
|
207
|
-
return df
|
208
|
-
|
209
|
-
if __name__=='__main__':
|
210
|
-
num=10
|
211
|
-
option='1'
|
212
|
-
ibbq=interbank_bond_quote(num,option)
|
213
|
-
option='2'
|
214
|
-
ibbq=interbank_bond_quote(num,option)
|
215
|
-
option='6'
|
216
|
-
ibbq=interbank_bond_quote(num,option)
|
217
|
-
|
218
|
-
#==============================================================================
|
219
|
-
def interbank_bond_deal(num,option='1'):
|
220
|
-
"""
|
221
|
-
功能:获得银行间债券市场现券成交行情
|
222
|
-
输入:从头开始显示的个数num;选项option:默认1按照收益率从高到低排列,
|
223
|
-
2按照发行时间从早到晚排列,3按照发行时间从晚到早排列,4按照涨跌幅从高到低,
|
224
|
-
5按照涨跌幅从低到高。
|
225
|
-
其他选项按照默认排列。
|
226
|
-
"""
|
227
|
-
#抓取银行间市场债券报价
|
228
|
-
import akshare as ak
|
229
|
-
df=ak.bond_spot_deal()
|
230
|
-
|
231
|
-
#其他选项均作为默认选项
|
232
|
-
if not option in ['1','2','3','4','5']: option='1'
|
233
|
-
if option=='1':
|
234
|
-
df.sort_values(by=['最新收益率(%)'],ascending=[False],inplace=True)
|
235
|
-
optiontxt="按照收益率从高到低排序"
|
236
|
-
if option=='2':
|
237
|
-
df.sort_values(by=['债券简称'],ascending=[True],inplace=True)
|
238
|
-
optiontxt="按照发行时间从早到晚排序"
|
239
|
-
if option=='3':
|
240
|
-
df.sort_values(by=['债券简称'],ascending=[False],inplace=True)
|
241
|
-
optiontxt="按照发行时间从晚到早排序"
|
242
|
-
if option=='4':
|
243
|
-
df.sort_values(by=['涨跌(BP)'],ascending=[False],inplace=True)
|
244
|
-
optiontxt="按照涨跌幅从高到低排序"
|
245
|
-
if option=='5':
|
246
|
-
df.sort_values(by=['涨跌(BP)'],ascending=[True],inplace=True)
|
247
|
-
optiontxt="按照涨跌幅从低到高排序"
|
248
|
-
#删除空值段
|
249
|
-
del df["交易量(亿)"]
|
250
|
-
del df["加权收益率(%)"]
|
251
|
-
#重新索引
|
252
|
-
df.reset_index(drop=True)
|
253
|
-
|
254
|
-
print("\n*** 中国银行间市场债券现券即时成交价("+optiontxt+",前"+str(num)+"名)***")
|
255
|
-
import pandas as pd
|
256
|
-
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
257
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
258
|
-
pd.set_option('display.width', 180) # 设置打印宽度(**重要**)
|
259
|
-
print(df.head(num).to_string(index=False))
|
260
|
-
|
261
|
-
import datetime
|
262
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
263
|
-
footnote="\n 数据来源:中国银行间市场交易商协会(NAFMII),"+today
|
264
|
-
print(footnote)
|
265
|
-
|
266
|
-
return df
|
267
|
-
|
268
|
-
if __name__=='__main__':
|
269
|
-
num=10
|
270
|
-
option='1'
|
271
|
-
ibbd=interbank_bond_deal(num,option)
|
272
|
-
option='2'
|
273
|
-
ibbd=interbank_bond_deal(num,option)
|
274
|
-
option='6'
|
275
|
-
ibbd=interbank_bond_deal(num,option)
|
276
|
-
|
277
|
-
|
278
|
-
#==============================================================================
|
279
|
-
|
280
|
-
|
281
|
-
import os, sys
|
282
|
-
|
283
|
-
class HiddenPrints:
|
284
|
-
def __enter__(self):
|
285
|
-
self._original_stdout = sys.stdout
|
286
|
-
sys.stdout = open(os.devnull, 'w')
|
287
|
-
|
288
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
289
|
-
sys.stdout.close()
|
290
|
-
sys.stdout = self._original_stdout
|
291
|
-
#==============================================================================
|
292
|
-
def exchange_bond_deal(num,option='1'):
|
293
|
-
"""
|
294
|
-
功能:获得沪深债券市场现券成交行情
|
295
|
-
输入:从头开始显示的个数num;选项option:默认1按照交易时间排列,
|
296
|
-
2按照发行时间从早到晚排列,3按照发行时间从晚到早排列,4按照涨跌幅从高到低,
|
297
|
-
5按照涨跌幅从低到高,6按照成交量从高到低排列,7按照成交量从低到高排列。
|
298
|
-
其他选项按照默认排列。
|
299
|
-
"""
|
300
|
-
print("开始搜索互联网,可能需要较长时间,请耐心等候......")
|
301
|
-
#定义标准输出关闭类
|
302
|
-
import os, sys
|
303
|
-
class HiddenPrints:
|
304
|
-
def __enter__(self):
|
305
|
-
self._original_stdout = sys.stdout
|
306
|
-
sys.stdout = open(os.devnull, 'w')
|
307
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
308
|
-
sys.stdout.close()
|
309
|
-
sys.stdout = self._original_stdout
|
310
|
-
|
311
|
-
import pandas as pd
|
312
|
-
df=pd.DataFrame()
|
313
|
-
#抓取银行间市场债券报价
|
314
|
-
import akshare as ak
|
315
|
-
with HiddenPrints():
|
316
|
-
try:
|
317
|
-
df=ak.bond_zh_hs_spot()
|
318
|
-
except:
|
319
|
-
pass
|
320
|
-
if len(df)==0:
|
321
|
-
print("...错误(exchange_bond_deal),抓取信息中途失败,信息可能不完整,请稍候再试")
|
322
|
-
return None
|
323
|
-
|
324
|
-
#选取需要的字段
|
325
|
-
df1=df[['ticktime','symbol','name','trade','pricechange','open','high', \
|
326
|
-
'low','buy','sell','volume']]
|
327
|
-
#转换字符类型到数值类型
|
328
|
-
df1['trade']=df1['trade'].astype("float64")
|
329
|
-
df1['pricechange']=df1['pricechange'].astype("float64")
|
330
|
-
df1['volume']=df1['volume'].astype("int")
|
331
|
-
|
332
|
-
#其他选项均作为默认选项
|
333
|
-
if not option in ['1','2','3','4','5','6','7']: option='1'
|
334
|
-
if option=='1':
|
335
|
-
df1.sort_values(by=['ticktime'],ascending=[True],inplace=True)
|
336
|
-
optiontxt="按照交易时间排序"
|
337
|
-
if option=='2':
|
338
|
-
df1.sort_values(by=['name'],ascending=[True],inplace=True)
|
339
|
-
optiontxt="按照发行时间从早到晚排序"
|
340
|
-
if option=='3':
|
341
|
-
df1.sort_values(by=['name'],ascending=[False],inplace=True)
|
342
|
-
optiontxt="按照发行时间从晚到早排序"
|
343
|
-
if option=='4':
|
344
|
-
df1.sort_values(by=['pricechange'],ascending=[False],inplace=True)
|
345
|
-
optiontxt="按照涨跌幅从高到低排序"
|
346
|
-
if option=='5':
|
347
|
-
df1.sort_values(by=['pricechange'],ascending=[True],inplace=True)
|
348
|
-
optiontxt="按照涨跌幅从低到高排序"
|
349
|
-
if option=='6':
|
350
|
-
df1.sort_values(by=['volume'],ascending=[False],inplace=True)
|
351
|
-
optiontxt="按照成交量从高到低排序"
|
352
|
-
if option=='7':
|
353
|
-
df1.sort_values(by=['volume'],ascending=[True],inplace=True)
|
354
|
-
optiontxt="按照成交量从低到高排序"
|
355
|
-
#重新索引
|
356
|
-
df1.reset_index(drop=True)
|
357
|
-
|
358
|
-
df2=df1.rename(columns={'ticktime':'时间','symbol':'债券代码', \
|
359
|
-
'name':'债券名称','trade':'成交价','pricechange':'涨跌(元)', \
|
360
|
-
'open':'开盘价','high':'最高价','low':'最低价', \
|
361
|
-
'buy':'买入价','sell':'卖出价','volume':'成交量'})
|
362
|
-
|
363
|
-
print("\n*** 沪深交易所债券市场现券即时成交价("+optiontxt+",前"+str(num)+"名)***")
|
364
|
-
import pandas as pd
|
365
|
-
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
366
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
367
|
-
pd.set_option('display.width', 200) # 设置打印宽度(**重要**)
|
368
|
-
print(df2.head(num).to_string(index=False))
|
369
|
-
|
370
|
-
import datetime
|
371
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
372
|
-
footnote="\n 数据来源:新浪财经,"+today
|
373
|
-
print(footnote)
|
374
|
-
|
375
|
-
return df1
|
376
|
-
|
377
|
-
if __name__=='__main__':
|
378
|
-
num=10
|
379
|
-
option='1'
|
380
|
-
ebd=exchange_bond_deal(num,option)
|
381
|
-
option='4'
|
382
|
-
ebd=exchange_bond_deal(num,option)
|
383
|
-
option='6'
|
384
|
-
ebd=exchange_bond_deal(num,option)
|
385
|
-
|
386
|
-
#==============================================================================
|
387
|
-
def exchange_bond_price(symbol,fromdate,todate):
|
388
|
-
"""
|
389
|
-
功能:获得沪深债券市场历史成交行情
|
390
|
-
输入:沪深债券代码symbol,起始日期fromdate,截止日期todate。
|
391
|
-
返回:历史价格df
|
392
|
-
输出:折线图
|
393
|
-
"""
|
394
|
-
#检查日期期间的合理性
|
395
|
-
result,start,end=check_period(fromdate, todate)
|
396
|
-
if result is None: return None
|
397
|
-
|
398
|
-
#抓取历史行情
|
399
|
-
import akshare as ak
|
400
|
-
try:
|
401
|
-
df=ak.bond_zh_hs_daily(symbol=symbol)
|
402
|
-
except:
|
403
|
-
print("...Error(exchange_bond_price), 抓取债券信息失败:",symbol)
|
404
|
-
return None
|
405
|
-
|
406
|
-
#过滤日期期间
|
407
|
-
df1=df.drop(df[df.index < start].index)
|
408
|
-
df2=df1.drop(df1[df1.index > end].index)
|
409
|
-
|
410
|
-
#绘图
|
411
|
-
titletxt='沪深债券收盘价历史行情:'+symbol
|
412
|
-
import datetime
|
413
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
414
|
-
footnote="\n 数据来源:新浪财经,"+today
|
415
|
-
plot_line(df2,'close','收盘价','价格(元)',titletxt,footnote,power=4)
|
416
|
-
|
417
|
-
return df
|
418
|
-
|
419
|
-
if __name__=='__main__':
|
420
|
-
symbol='sh143595'
|
421
|
-
fromdate='2019-1-1'
|
422
|
-
todate='2020-3-30'
|
423
|
-
ebp=exchange_bond_price('sh019521',fromdate,todate)
|
424
|
-
|
425
|
-
#==============================================================================
|
426
|
-
def exchange_covbond_deal(num,option='1'):
|
427
|
-
"""
|
428
|
-
功能:获得沪深债券市场可转券即时行情
|
429
|
-
输入:从头开始显示的个数num;选项option:默认1按照交易时间排列,
|
430
|
-
2按照债券代码从小到大排列,3按照债券代码从大到小排列,4按照涨跌幅从高到低,
|
431
|
-
5按照涨跌幅从低到高,6按照成交量从高到低排列,7按照成交量从低到高排列。
|
432
|
-
其他选项按照默认排列。
|
433
|
-
"""
|
434
|
-
print("开始搜索互联网,可能需要一点时间,请耐心等候......")
|
435
|
-
#定义标准输出关闭类
|
436
|
-
import os, sys
|
437
|
-
class HiddenPrints:
|
438
|
-
def __enter__(self):
|
439
|
-
self._original_stdout = sys.stdout
|
440
|
-
sys.stdout = open(os.devnull, 'w')
|
441
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
442
|
-
sys.stdout.close()
|
443
|
-
sys.stdout = self._original_stdout
|
444
|
-
|
445
|
-
import pandas as pd
|
446
|
-
df=pd.DataFrame()
|
447
|
-
#抓取银行间市场债券报价
|
448
|
-
import akshare as ak
|
449
|
-
with HiddenPrints():
|
450
|
-
try:
|
451
|
-
df=ak.bond_zh_hs_cov_spot()
|
452
|
-
except:
|
453
|
-
pass
|
454
|
-
if len(df)==0:
|
455
|
-
print("...错误(exchange_covbond_deal),抓取信息中途失败,请稍候再试")
|
456
|
-
return None
|
457
|
-
|
458
|
-
#选取需要的字段
|
459
|
-
df1=df[['ticktime','symbol','name','trade','pricechange','open','high', \
|
460
|
-
'low','buy','sell','volume']]
|
461
|
-
#转换字符类型到数值类型
|
462
|
-
df1['trade']=df1['trade'].astype("float64")
|
463
|
-
df1['pricechange']=df1['pricechange'].astype("float64")
|
464
|
-
df1['volume']=df1['volume'].astype("int")
|
465
|
-
|
466
|
-
#其他选项均作为默认选项
|
467
|
-
if not option in ['1','2','3','4','5','6','7']: option='1'
|
468
|
-
if option=='1':
|
469
|
-
df1.sort_values(by=['ticktime'],ascending=[True],inplace=True)
|
470
|
-
optiontxt="按照交易时间排序"
|
471
|
-
if option=='2':
|
472
|
-
df1.sort_values(by=['symbol'],ascending=[True],inplace=True)
|
473
|
-
optiontxt="按照代码从小到大排序"
|
474
|
-
if option=='3':
|
475
|
-
df1.sort_values(by=['symbol'],ascending=[False],inplace=True)
|
476
|
-
optiontxt="按照代码从大到小排序"
|
477
|
-
if option=='4':
|
478
|
-
df1.sort_values(by=['pricechange'],ascending=[False],inplace=True)
|
479
|
-
optiontxt="按照涨跌幅从高到低排序"
|
480
|
-
if option=='5':
|
481
|
-
df1.sort_values(by=['pricechange'],ascending=[True],inplace=True)
|
482
|
-
optiontxt="按照涨跌幅从低到高排序"
|
483
|
-
if option=='6':
|
484
|
-
df1.sort_values(by=['volume'],ascending=[False],inplace=True)
|
485
|
-
optiontxt="按照成交量从高到低排序"
|
486
|
-
if option=='7':
|
487
|
-
df1.sort_values(by=['volume'],ascending=[True],inplace=True)
|
488
|
-
optiontxt="按照成交量从低到高排序"
|
489
|
-
#重新索引
|
490
|
-
df1.reset_index(drop=True)
|
491
|
-
|
492
|
-
df2=df1.rename(columns={'ticktime':'时间','symbol':'债券代码', \
|
493
|
-
'name':'债券名称','trade':'成交价','pricechange':'涨跌(元)', \
|
494
|
-
'open':'开盘价','high':'最高价','low':'最低价', \
|
495
|
-
'buy':'买入价','sell':'卖出价','volume':'成交量'})
|
496
|
-
|
497
|
-
print("\n*** 沪深交易所可转债现券即时行情("+optiontxt+",前"+str(num)+"名)***")
|
498
|
-
import pandas as pd
|
499
|
-
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
500
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
501
|
-
pd.set_option('display.width', 200) # 设置打印宽度(**重要**)
|
502
|
-
print(df2.head(num).to_string(index=False))
|
503
|
-
|
504
|
-
import datetime
|
505
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
506
|
-
footnote="\n 数据来源:新浪财经,"+today
|
507
|
-
print(footnote)
|
508
|
-
|
509
|
-
return df1
|
510
|
-
|
511
|
-
if __name__=='__main__':
|
512
|
-
num=10
|
513
|
-
option='1'
|
514
|
-
ebd=exchange_covbond_deal(num,option)
|
515
|
-
option='4'
|
516
|
-
ebd=exchange_covbond_deal(num,option)
|
517
|
-
option='5'
|
518
|
-
ebd=exchange_covbond_deal(num,option)
|
519
|
-
option='6'
|
520
|
-
ebd=exchange_covbond_deal(num,option)
|
521
|
-
option='7'
|
522
|
-
ebd=exchange_covbond_deal(num,option)
|
523
|
-
|
524
|
-
|
525
|
-
#==============================================================================
|
526
|
-
def exchange_covbond_price(symbol,fromdate,todate):
|
527
|
-
"""
|
528
|
-
功能:获得沪深市场可转债历史成交行情
|
529
|
-
输入:沪深债券代码symbol,起始日期fromdate,截止日期todate。
|
530
|
-
返回:历史价格df
|
531
|
-
输出:折线图
|
532
|
-
"""
|
533
|
-
#检查日期期间的合理性
|
534
|
-
result,start,end=check_period(fromdate, todate)
|
535
|
-
if result is None: return None
|
536
|
-
|
537
|
-
#抓取历史行情
|
538
|
-
import akshare as ak
|
539
|
-
try:
|
540
|
-
df=ak.bond_zh_hs_cov_daily(symbol=symbol)
|
541
|
-
except:
|
542
|
-
print("...Error(exchange_covbond_price), 抓取债券信息失败:",symbol)
|
543
|
-
return None
|
544
|
-
|
545
|
-
#过滤日期期间
|
546
|
-
df1=df.drop(df[df.index < start].index)
|
547
|
-
df2=df1.drop(df1[df1.index > end].index)
|
548
|
-
|
549
|
-
#绘图
|
550
|
-
titletxt='沪深市场可转债收盘价历史行情:'+symbol
|
551
|
-
import datetime
|
552
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
553
|
-
footnote="\n 数据来源:新浪财经,"+today
|
554
|
-
plot_line(df2,'close','收盘价','价格(元)',titletxt,footnote,power=4)
|
555
|
-
|
556
|
-
return df
|
557
|
-
|
558
|
-
if __name__=='__main__':
|
559
|
-
symbol='sh113565'
|
560
|
-
fromdate='2020-1-1'
|
561
|
-
todate='2020-5-6'
|
562
|
-
ebp=exchange_covbond_price('sz128086',fromdate,todate)
|
563
|
-
|
564
|
-
#==============================================================================
|
565
|
-
def country_bond_price(country,name,fromdate,todate):
|
566
|
-
"""
|
567
|
-
功能:获得全球政府债券市场历史成交行情
|
568
|
-
输入:国家country,政府债券名称name,起始日期fromdate,截止日期todate。
|
569
|
-
返回:历史价格df
|
570
|
-
输出:折线图
|
571
|
-
"""
|
572
|
-
#检查日期期间的合理性
|
573
|
-
result,start,end=check_period(fromdate, todate)
|
574
|
-
start_date=start.strftime("%Y/%m/%d")
|
575
|
-
end_date=end.strftime("%Y/%m/%d")
|
576
|
-
|
577
|
-
if result is None: return None
|
578
|
-
|
579
|
-
#抓取历史行情
|
580
|
-
import akshare as ak
|
581
|
-
try:
|
582
|
-
df=ak.get_country_bond(country=country,index_name=name, \
|
583
|
-
start_date=start_date, end_date=end_date)
|
584
|
-
except:
|
585
|
-
print("...Error(country_bond_price), 抓取债券信息失败:",country,"\b,",name)
|
586
|
-
return None
|
587
|
-
|
588
|
-
#过滤日期期间
|
589
|
-
df1=df.drop(df[df.index < start].index)
|
590
|
-
df2=df1.drop(df1[df1.index > end].index)
|
591
|
-
|
592
|
-
#绘图
|
593
|
-
titletxt='全球政府债券收盘价历史行情:'+name
|
594
|
-
import datetime
|
595
|
-
today = datetime.date.today().strftime("%Y-%m-%d")
|
596
|
-
footnote="\n 数据来源:英为财情,"+today
|
597
|
-
plot_line(df2,'收盘','收盘价','价格',titletxt,footnote,power=4)
|
598
|
-
|
599
|
-
return df
|
600
|
-
|
601
|
-
if __name__=='__main__':
|
602
|
-
country='中国'
|
603
|
-
name='中国1年期国债'
|
604
|
-
fromdate='2020-1-1'
|
605
|
-
todate='2020-5-6'
|
606
|
-
cbp=country_bond_price(country,name,fromdate,todate)
|
607
|
-
|
608
|
-
#==============================================================================
|
609
|
-
def bond_eval(aytm,yper,c,fv=100,mterm=1):
|
610
|
-
"""
|
611
|
-
功能:计算债券的估值价格,即现值
|
612
|
-
输入:
|
613
|
-
aytm: 年化折现率,年化市场利率
|
614
|
-
yper: 距离到期日的年数
|
615
|
-
c: 票面利率
|
616
|
-
fv: 票面价值
|
617
|
-
mterm: 每年付息期数,默认为1,期末付息
|
618
|
-
"""
|
619
|
-
#每期折现率
|
620
|
-
rate=aytm/mterm
|
621
|
-
#每期票息
|
622
|
-
pmt=fv*c/mterm
|
623
|
-
|
624
|
-
#循环计算现值
|
625
|
-
bvalue=0.0
|
626
|
-
for t in range(1,yper*mterm+1):
|
627
|
-
bvalue=bvalue+pmt/((1+rate)**t)
|
628
|
-
bvalue=bvalue+fv/((1+rate)**(yper*mterm))
|
629
|
-
|
630
|
-
return bvalue
|
631
|
-
|
632
|
-
if __name__=='__main__':
|
633
|
-
aytm=0.08
|
634
|
-
yper=3
|
635
|
-
fv=100
|
636
|
-
c=0.1
|
637
|
-
bvalue=bond_eval(aytm,yper,c,fv=100,mterm=1)
|
638
|
-
|
639
|
-
#==============================================================================
|
640
|
-
def bond_malkiel1(aytm,yper,c,fv=100,mterm=1, \
|
641
|
-
bp=[-100,-50,-20,-10,-5,5,10,20,50,100]):
|
642
|
-
"""
|
643
|
-
功能:计算债券的估值价格,即现值。演示债券估值定理一。
|
644
|
-
输入:
|
645
|
-
aytm: 年化折现率,年化市场利率,年化到期收益率
|
646
|
-
yper: 距离到期日的年数
|
647
|
-
c: 年化票面利率
|
648
|
-
fv: 票面价值
|
649
|
-
mterm: 每年付息期数,默认为1,期末付息
|
650
|
-
bp: 到期收益率变化的基点数列表,100 bp = 1%
|
651
|
-
"""
|
652
|
-
import pandas as pd
|
653
|
-
df=pd.DataFrame(columns=('bp','YTM','Price','xLabel'))
|
654
|
-
p0=round(bond_eval(aytm,yper,c,fv,mterm),2)
|
655
|
-
s=pd.Series({'bp':0,'YTM':aytm,'Price':p0,'xLabel':str(aytm*100)+'%'})
|
656
|
-
df=df.append(s, ignore_index=True)
|
657
|
-
|
658
|
-
#计算基点变化对于债券估计的影响
|
659
|
-
for b in bp:
|
660
|
-
ay=aytm + b/10000.0
|
661
|
-
pb=round(bond_eval(ay,yper,c,fv,mterm),2)
|
662
|
-
|
663
|
-
if b < 0:
|
664
|
-
xl='-'+str(abs(b))+'bp'
|
665
|
-
elif b > 0:
|
666
|
-
xl='+'+str(b)+'bp'
|
667
|
-
else:
|
668
|
-
xl=str(aytm*100)+'%'
|
669
|
-
s=pd.Series({'bp':b,'YTM':ay,'Price':pb,'xLabel':xl})
|
670
|
-
df=df.append(s, ignore_index=True)
|
671
|
-
|
672
|
-
#按照到期收益率升序排序
|
673
|
-
df.sort_values(by=['YTM'],ascending=[True],inplace=True)
|
674
|
-
#指定索引
|
675
|
-
df.reset_index(drop=True,inplace=True)
|
676
|
-
|
677
|
-
#显示
|
678
|
-
df1=df.copy()
|
679
|
-
df1['YTM%']=round(df1['YTM']*100,2)
|
680
|
-
df2=df1[['xLabel','YTM%','Price']]
|
681
|
-
df3=df2.rename(columns={'xLabel':'到期收益率变化','YTM%':'到期收益率%','Price':'债券价格'})
|
682
|
-
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
683
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
684
|
-
pd.set_option('display.width', 180) # 设置打印宽度(**重要**)
|
685
|
-
print("\n",df3.to_string(index=False))
|
686
|
-
|
687
|
-
#绘图
|
688
|
-
import matplotlib.pyplot as plt
|
689
|
-
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置默认字体
|
690
|
-
plt.rcParams['axes.unicode_minus'] = False
|
691
|
-
|
692
|
-
plt.plot(df['xLabel'],df['Price'],color='red',marker='o')
|
693
|
-
|
694
|
-
#绘制虚线
|
695
|
-
xpos=str(aytm*100)+'%'
|
696
|
-
ymax=max(df['Price'])
|
697
|
-
ymin=min(df['Price'])
|
698
|
-
plt.vlines(x=xpos,ymin=ymin,ymax=p0,ls=":",colors="blue")
|
699
|
-
|
700
|
-
titletxt="债券价格与到期收益率的关系"
|
701
|
-
plt.title(titletxt,fontsize=12)
|
702
|
-
plt.ylabel("债券价格")
|
703
|
-
footnote1="到期收益率及其变化幅度(100bp = 1%)"
|
704
|
-
footnote2="\n债券"+"面值"+str(fv)+",票面利率"+str(round(c*100,2))+"%,"
|
705
|
-
footnote3="每年付息"+str(mterm)+"次,"+"到期年数"+str(yper)
|
706
|
-
footnote4=",到期收益率"+str(round(aytm*100,2))+"%"
|
707
|
-
footnote=footnote1+footnote2+footnote3+footnote4
|
708
|
-
plt.xlabel(footnote,fontsize=9)
|
709
|
-
plt.tick_params(labelsize=8)
|
710
|
-
plt.xticks(rotation=30)
|
711
|
-
|
712
|
-
plt.show(); plt.close()
|
713
|
-
|
714
|
-
return
|
715
|
-
|
716
|
-
if __name__=='__main__':
|
717
|
-
aytm=0.08
|
718
|
-
yper=3
|
719
|
-
fv=100
|
720
|
-
c=0.1
|
721
|
-
mterm=1
|
722
|
-
bplist=[-100,-50,-20,-10,-5,5,10,20,50,100]
|
723
|
-
bond_malkiel1(aytm,yper,c,fv=100,mterm=1,bp=bplist)
|
724
|
-
|
725
|
-
#==============================================================================
|
726
|
-
def bond_malkiel2(aytm,yper,c,fv=100,mterm=1, \
|
727
|
-
yperlist=[1,2,5,10,20,50,100]):
|
728
|
-
"""
|
729
|
-
功能:计算债券估值价格的变化,演示债券估值定理二。
|
730
|
-
输入:
|
731
|
-
aytm: 年化折现率,年化市场利率,年化到期收益率
|
732
|
-
yper: 距离到期日的年数
|
733
|
-
c: 年化票面利率
|
734
|
-
fv: 票面价值
|
735
|
-
mterm: 每年付息期数,默认为1,期末付息
|
736
|
-
yperlist: 债券的不同期限年数列表
|
737
|
-
"""
|
738
|
-
import pandas as pd
|
739
|
-
df=pd.DataFrame(columns=('Maturity','YTM','Price','deltaPrice','xLabel'))
|
740
|
-
p0=round(bond_eval(aytm,yper,c,fv,mterm),2)
|
741
|
-
s=pd.Series({'Maturity':yper,'YTM':aytm,'Price':p0,'deltaPrice':0, \
|
742
|
-
'xLabel':str(yper)+'年'})
|
743
|
-
df=df.append(s, ignore_index=True)
|
744
|
-
|
745
|
-
#计算基点变化对于债券估计的影响
|
746
|
-
for y in yperlist:
|
747
|
-
pb=round(bond_eval(aytm,y,c,fv,mterm),2)
|
748
|
-
|
749
|
-
s=pd.Series({'Maturity':y,'YTM':aytm,'Price':pb,'deltaPrice':(pb-p0), \
|
750
|
-
'xLabel':str(y)+'年'})
|
751
|
-
df=df.append(s, ignore_index=True)
|
752
|
-
|
753
|
-
#按照到期收益率升序排序
|
754
|
-
df.sort_values(by=['Maturity'],ascending=[True],inplace=True)
|
755
|
-
#指定索引
|
756
|
-
df.reset_index(drop=True,inplace=True)
|
757
|
-
|
758
|
-
#显示
|
759
|
-
df1=df.copy()
|
760
|
-
df2=df1[['Maturity','deltaPrice']]
|
761
|
-
df3=df2.rename(columns={'Maturity':'债券期限变化(年)','deltaPrice':'债券价格变化'})
|
762
|
-
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
763
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
764
|
-
pd.set_option('display.width', 180) # 设置打印宽度(**重要**)
|
765
|
-
print("\n",df3.to_string(index=False))
|
766
|
-
|
767
|
-
#绘图
|
768
|
-
import matplotlib.pyplot as plt
|
769
|
-
plt.rcParams['font.sans-serif'] = ['SimHei']
|
770
|
-
plt.rcParams['axes.unicode_minus'] = False
|
771
|
-
|
772
|
-
plt.plot(df['Maturity'],df['deltaPrice'],color='red',marker='o')
|
773
|
-
|
774
|
-
#绘制虚线
|
775
|
-
xpos=yper
|
776
|
-
ymax=0
|
777
|
-
ymin=min(df['deltaPrice'])
|
778
|
-
plt.vlines(x=xpos,ymin=ymin,ymax=0,ls=":",color="blue")
|
779
|
-
plt.axhline(y=0,ls=":",c="black")
|
780
|
-
|
781
|
-
titletxt="债券价格的变化与债券期限长短的关系"
|
782
|
-
plt.title(titletxt,fontsize=12)
|
783
|
-
plt.ylabel("债券价格的变化")
|
784
|
-
footnote1="债券期限(年)"
|
785
|
-
footnote2="\n债券"+"面值"+str(fv)+",票面利率"+str(round(c*100,2))+"%,"
|
786
|
-
footnote3="每年付息"+str(mterm)+"次,"+"期限"+str(yper)+"年"
|
787
|
-
footnote4=",到期收益率"+str(round(aytm*100,2))+"%"
|
788
|
-
footnote=footnote1+footnote2+footnote3+footnote4
|
789
|
-
plt.xlabel(footnote,fontsize=9)
|
790
|
-
plt.tick_params(labelsize=8)
|
791
|
-
plt.xticks(rotation=30)
|
792
|
-
|
793
|
-
plt.show(); plt.close()
|
794
|
-
|
795
|
-
return
|
796
|
-
|
797
|
-
if __name__=='__main__':
|
798
|
-
aytm=0.08
|
799
|
-
yper=3
|
800
|
-
fv=100
|
801
|
-
c=0.1
|
802
|
-
mterm=1
|
803
|
-
yperlist=[1,2,5,10,15,30]
|
804
|
-
bond_malkiel2(aytm,yper,c,fv,mterm,yperlist=yperlist)
|
805
|
-
|
806
|
-
#==============================================================================
|
807
|
-
def bond_malkiel3(aytm,yper,c,fv=100,mterm=1):
|
808
|
-
"""
|
809
|
-
功能:计算债券的估值价格变化的速度,演示债券估值定理三。
|
810
|
-
输入:
|
811
|
-
aytm: 年化折现率,年化市场利率,年化到期收益率
|
812
|
-
yper: 距离到期日的年数
|
813
|
-
c: 年化票面利率
|
814
|
-
fv: 票面价值
|
815
|
-
mterm: 每年付息期数,默认为1,期末付息
|
816
|
-
"""
|
817
|
-
yperlist=list(range(1,yper*2+2))
|
818
|
-
|
819
|
-
import pandas as pd
|
820
|
-
df=pd.DataFrame(columns=('Maturity','Price'))
|
821
|
-
#计算期限变化对于债券价格的影响
|
822
|
-
for y in yperlist:
|
823
|
-
pb=round(bond_eval(aytm,y,c,fv,mterm),2)
|
824
|
-
s=pd.Series({'Maturity':str(y),'Price':pb})
|
825
|
-
df=df.append(s, ignore_index=True)
|
826
|
-
|
827
|
-
#价格变化
|
828
|
-
df['deltaPrice']=df['Price'].shift(-1)-df['Price']
|
829
|
-
df.dropna(inplace=True)
|
830
|
-
|
831
|
-
#价格与价格变化风险双轴折线图
|
832
|
-
import matplotlib.pyplot as plt
|
833
|
-
plt.rcParams['font.sans-serif'] = ['SimHei']
|
834
|
-
plt.rcParams['axes.unicode_minus'] = False
|
835
|
-
fig = plt.figure()
|
836
|
-
|
837
|
-
#绘制左侧纵轴
|
838
|
-
ax = fig.add_subplot(111)
|
839
|
-
ax.plot(df['Maturity'],df['Price'],'-',label="债券价格", \
|
840
|
-
linestyle='-',linewidth=2,color='blue')
|
841
|
-
ax.set_ylabel("债券价格")
|
842
|
-
footnote1="债券期限(年)"
|
843
|
-
footnote2="\n债券"+"面值"+str(fv)+",票面利率"+str(round(c*100,2))+"%,"
|
844
|
-
footnote3="每年付息"+str(mterm)+"次,"+"期限"+str(yper)+"年"
|
845
|
-
footnote4=",到期收益率"+str(round(aytm*100,2))+"%"
|
846
|
-
footnote=footnote1+footnote2+footnote3+footnote4
|
847
|
-
ax.set_xlabel(footnote)
|
848
|
-
ax.legend(loc='center left')
|
849
|
-
|
850
|
-
#绘制垂直虚线
|
851
|
-
xpos=yper-1
|
852
|
-
ymax=bond_eval(aytm,yper,c,fv,mterm)
|
853
|
-
ymin=min(df['Price'])
|
854
|
-
plt.vlines(x=xpos,ymin=ymin,ymax=ymax,ls=":",color="black")
|
855
|
-
|
856
|
-
#绘制右侧纵轴
|
857
|
-
ax2 = ax.twinx()
|
858
|
-
ax2.plot(df['Maturity'],df['deltaPrice'],'-',label="债券价格变化的速度", \
|
859
|
-
linestyle='-.',linewidth=2,color='orange')
|
860
|
-
ax2.set_ylabel("债券价格变化的速度")
|
861
|
-
ax2.legend(loc='center right')
|
862
|
-
|
863
|
-
titletxt="债券价格受债券期限影响的波动风险"
|
864
|
-
plt.title(titletxt, fontsize=12)
|
865
|
-
plt.show(); plt.close()
|
866
|
-
|
867
|
-
return
|
868
|
-
|
869
|
-
if __name__=='__main__':
|
870
|
-
aytm=0.08
|
871
|
-
yper=8
|
872
|
-
fv=100
|
873
|
-
c=0.1
|
874
|
-
mterm=2
|
875
|
-
bond_malkiel3(aytm,yper,c,fv,mterm)
|
876
|
-
|
877
|
-
#==============================================================================
|
878
|
-
def bond_malkiel4(aytm,yper,c,fv=100,mterm=1):
|
879
|
-
"""
|
880
|
-
功能:计算债券的估值价格变化,演示债券估值定理四。
|
881
|
-
输入:
|
882
|
-
aytm: 年化折现率,年化市场利率,年化到期收益率
|
883
|
-
yper: 距离到期日的年数
|
884
|
-
c: 年化票面利率
|
885
|
-
fv: 票面价值
|
886
|
-
mterm: 每年付息期数,默认为1,期末付息
|
887
|
-
"""
|
888
|
-
bplist=[-5,-4,-3,-2,-1,1,2,3,4,5]
|
889
|
-
import pandas as pd
|
890
|
-
df=pd.DataFrame(columns=('bp','YTM','Price','xLabel','deltaPrice'))
|
891
|
-
p0=bond_eval(aytm,yper,c,fv,mterm)
|
892
|
-
s=pd.Series({'bp':0,'YTM':aytm,'Price':p0,'xLabel':str(aytm*100)+'%','deltaPrice':0})
|
893
|
-
df=df.append(s, ignore_index=True)
|
894
|
-
|
895
|
-
#计算基点变化对于债券估计的影响
|
896
|
-
for b in bplist:
|
897
|
-
ay=aytm + b/10000.0
|
898
|
-
pb=bond_eval(ay,yper,c,fv,mterm)
|
899
|
-
|
900
|
-
if b < 0:
|
901
|
-
xl='-'+str(abs(b))+'bp'
|
902
|
-
elif b > 0:
|
903
|
-
xl='+'+str(b)+'bp'
|
904
|
-
else:
|
905
|
-
xl=str(aytm*100)+'%'
|
906
|
-
s=pd.Series({'bp':b,'YTM':ay,'Price':pb,'xLabel':xl,'deltaPrice':(pb-p0)})
|
907
|
-
df=df.append(s, ignore_index=True)
|
908
|
-
|
909
|
-
#按照到期收益率升序排序
|
910
|
-
df.sort_values(by=['YTM'],ascending=[True],inplace=True)
|
911
|
-
#指定索引
|
912
|
-
df.reset_index(drop=True,inplace=True)
|
913
|
-
|
914
|
-
#拆分为收益率降低/上升两部分
|
915
|
-
df1=df[df['deltaPrice'] >= 0]
|
916
|
-
df2=df[df['deltaPrice'] <= 0]
|
917
|
-
|
918
|
-
#将df2“两次翻折”,便于与df1比较
|
919
|
-
df3=df2.copy()
|
920
|
-
df3['deltaPrice1']=-df3['deltaPrice']
|
921
|
-
df3.sort_values(by=['YTM'],ascending=[False],inplace=True)
|
922
|
-
df3.reset_index(drop=True,inplace=True)
|
923
|
-
df3['xLabel1']=df3['xLabel'].apply(lambda x: x.replace('+','-'))
|
924
|
-
|
925
|
-
#绘图
|
926
|
-
import matplotlib.pyplot as plt
|
927
|
-
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置默认字体
|
928
|
-
plt.rcParams['axes.unicode_minus'] = False
|
929
|
-
|
930
|
-
plt.plot(df1['xLabel'],df1['deltaPrice'],color='red',marker='o', \
|
931
|
-
label="收益率下降导致的债券价格增加")
|
932
|
-
plt.plot(df2['xLabel'],df2['deltaPrice'],color='blue',marker='^', \
|
933
|
-
label="收益率上升导致的债券价格下降")
|
934
|
-
plt.plot(df3['xLabel1'],df3['deltaPrice1'],':',color='blue',marker='<', \
|
935
|
-
label="收益率上升导致的债券价格下降(两次翻折后)")
|
936
|
-
plt.axhline(y=0,ls="-.",c="black", linewidth=1)
|
937
|
-
|
938
|
-
#绘制垂直虚线
|
939
|
-
xpos=str(aytm*100)+'%'
|
940
|
-
ymax=0
|
941
|
-
ymin=min(df['deltaPrice'])
|
942
|
-
plt.vlines(x=xpos,ymin=ymin,ymax=ymax,ls="-.",color="green",linewidth=1)
|
943
|
-
plt.legend(loc='best')
|
944
|
-
|
945
|
-
titletxt="到期收益率与债券价格变化的非对称性"
|
946
|
-
plt.title(titletxt,fontsize=12)
|
947
|
-
plt.ylabel("债券价格的变化")
|
948
|
-
footnote1="到期收益率及其变化幅度(100bp = 1%)"
|
949
|
-
footnote2="\n债券"+"面值"+str(fv)+",票面利率"+str(round(c*100,2))+"%,"
|
950
|
-
footnote3="每年付息"+str(mterm)+"次,"+"期限"+str(yper)+"年"
|
951
|
-
footnote4=",到期收益率"+str(round(aytm*100,2))+"%"
|
952
|
-
footnote=footnote1+footnote2+footnote3+footnote4
|
953
|
-
plt.xlabel(footnote,fontsize=9)
|
954
|
-
plt.tick_params(labelsize=8)
|
955
|
-
plt.xticks(rotation=30)
|
956
|
-
|
957
|
-
plt.show(); plt.close()
|
958
|
-
|
959
|
-
return
|
960
|
-
|
961
|
-
if __name__=='__main__':
|
962
|
-
aytm=0.08
|
963
|
-
yper=3
|
964
|
-
fv=100
|
965
|
-
c=0.1
|
966
|
-
mterm=1
|
967
|
-
bond_malkiel4(aytm,yper,c,fv=100,mterm=1)
|
968
|
-
|
969
|
-
#==============================================================================
|
970
|
-
def bond_malkiel5(aytm,yper,c,fv=100,mterm=1):
|
971
|
-
"""
|
972
|
-
功能:计算债券的估值价格变化,演示债券估值定理五。
|
973
|
-
输入:
|
974
|
-
aytm: 年化折现率,年化市场利率,年化到期收益率
|
975
|
-
yper: 距离到期日的年数
|
976
|
-
c: 年化票面利率
|
977
|
-
fv: 票面价值
|
978
|
-
mterm: 每年付息期数,默认为1,期末付息
|
979
|
-
"""
|
980
|
-
clist=[-300,-250,-200,-150,-100,-50,50,100,150,200,250]
|
981
|
-
import pandas as pd
|
982
|
-
df=pd.DataFrame(columns=('bp','c','Price','xLabel'))
|
983
|
-
p0=bond_eval(aytm,yper,c,fv,mterm)
|
984
|
-
s=pd.Series({'bp':0,'c':c,'Price':p0,'xLabel':str(c*100)+'%'})
|
985
|
-
df=df.append(s, ignore_index=True)
|
986
|
-
|
987
|
-
#计算基点变化对于债券估计的影响
|
988
|
-
for b in clist:
|
989
|
-
cb=c + b/10000.0
|
990
|
-
if cb <= 0: continue
|
991
|
-
pb=bond_eval(aytm,yper,cb,fv,mterm)
|
992
|
-
|
993
|
-
if b < 0:
|
994
|
-
xl='-'+str(abs(b))+'bp'
|
995
|
-
elif b > 0:
|
996
|
-
xl='+'+str(b)+'bp'
|
997
|
-
else:
|
998
|
-
xl=str(c*100)+'%'
|
999
|
-
|
1000
|
-
s=pd.Series({'bp':b,'c':cb,'Price':pb,'xLabel':xl})
|
1001
|
-
df=df.append(s, ignore_index=True)
|
1002
|
-
|
1003
|
-
#按照到期收益率升序排序
|
1004
|
-
df.sort_values(by=['c'],ascending=[True],inplace=True)
|
1005
|
-
#指定索引
|
1006
|
-
df.reset_index(drop=True,inplace=True)
|
1007
|
-
#计算价格变化率
|
1008
|
-
df['deltaPrice']=df['Price']-df['Price'].shift(1)
|
1009
|
-
df['deltaPrice%']=df['Price'].pct_change()*100.0
|
1010
|
-
df.dropna(inplace=True)
|
1011
|
-
|
1012
|
-
#绘图
|
1013
|
-
import matplotlib.pyplot as plt
|
1014
|
-
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置默认字体
|
1015
|
-
plt.rcParams['axes.unicode_minus'] = False
|
1016
|
-
|
1017
|
-
df1=df[df['bp'] <= 0]
|
1018
|
-
df2=df[df['bp'] >= 0]
|
1019
|
-
plt.plot(df1['xLabel'],df1['deltaPrice%'],color='red',marker='<')
|
1020
|
-
plt.plot(df2['xLabel'],df2['deltaPrice%'],color='green',marker='>')
|
1021
|
-
|
1022
|
-
#绘制垂直虚线
|
1023
|
-
xpos=str(c*100)+'%'
|
1024
|
-
ymax=df[df['xLabel']==xpos]['deltaPrice%'].values[0]
|
1025
|
-
ymin=min(df['deltaPrice%'])
|
1026
|
-
plt.vlines(x=xpos,ymin=ymin,ymax=ymax,ls="-.",color="blue",linewidth=1)
|
1027
|
-
#plt.legend(loc='best')
|
1028
|
-
|
1029
|
-
titletxt="债券票息率与债券价格变化风险的关系"
|
1030
|
-
plt.title(titletxt,fontsize=12)
|
1031
|
-
plt.ylabel("债券价格的变化%")
|
1032
|
-
footnote1="票息率%及其变化幅度(100bp = 1%)"
|
1033
|
-
footnote2="\n债券"+"面值"+str(fv)+",票面利率"+str(round(c*100,2))+"%,"
|
1034
|
-
footnote3="每年付息"+str(mterm)+"次,"+"期限"+str(yper)+"年"
|
1035
|
-
footnote4=",到期收益率"+str(round(aytm*100,2))+"%"
|
1036
|
-
footnote=footnote1+footnote2+footnote3+footnote4
|
1037
|
-
plt.xlabel(footnote,fontsize=9)
|
1038
|
-
plt.tick_params(labelsize=8)
|
1039
|
-
plt.xticks(rotation=30)
|
1040
|
-
|
1041
|
-
plt.show(); plt.close()
|
1042
|
-
|
1043
|
-
return
|
1044
|
-
|
1045
|
-
if __name__=='__main__':
|
1046
|
-
aytm=0.65
|
1047
|
-
yper=8
|
1048
|
-
fv=100
|
1049
|
-
c=0.7
|
1050
|
-
mterm=2
|
1051
|
-
dp=bond_malkiel5(aytm,yper,c,fv,mterm=mterm)
|
1052
|
-
|
1053
|
-
#==============================================================================
|
1054
|
-
def cf_month(c,x,n,f=2,r=0.03):
|
1055
|
-
"""
|
1056
|
-
功能:计算国债期货的转换因子。
|
1057
|
-
输入:
|
1058
|
-
c: 可交割国债的票面利率
|
1059
|
-
x: 交割月到下一付息月的月份数
|
1060
|
-
n: 剩余付息次数
|
1061
|
-
f: 每年付息次数,默认2次
|
1062
|
-
r: 5年期国债期货合约票面利率,默认3%
|
1063
|
-
"""
|
1064
|
-
p1=(1+r/f)**(x*f/12)
|
1065
|
-
p2=c/f
|
1066
|
-
p3=c/r
|
1067
|
-
p4=1-p3
|
1068
|
-
p5=(1+r/f)**(n-1)
|
1069
|
-
p6=1-x*f/12
|
1070
|
-
|
1071
|
-
cf=(1/p1)*(p2+p3+p4/p5)-p2*p6
|
1072
|
-
|
1073
|
-
return cf
|
1074
|
-
|
1075
|
-
if __name__=='__main__':
|
1076
|
-
c=0.026
|
1077
|
-
x=1
|
1078
|
-
n=11
|
1079
|
-
f=2
|
1080
|
-
r=0.03
|
1081
|
-
cf_month(c,x,n)
|
1082
|
-
#==============================================================================
|
1083
|
-
def cf_day(c,v,m,f=2,r=0.03):
|
1084
|
-
"""
|
1085
|
-
功能:计算国债期货的转换因子。
|
1086
|
-
输入:
|
1087
|
-
c: 年化票面利率
|
1088
|
-
v: 到下一付息日的天数
|
1089
|
-
m: 下一付息日后剩余的付息次数
|
1090
|
-
f: 每年付息次数,默认2次
|
1091
|
-
stdrate: 标准利率,默认3%
|
1092
|
-
"""
|
1093
|
-
#基本折现因子
|
1094
|
-
p=1/(1+r/f)
|
1095
|
-
a=p**(v*f/365)
|
1096
|
-
e=(c/f)*(p*(1-p**m))/(1-p)
|
1097
|
-
d=p**m
|
1098
|
-
b=(1-v*f/365)*(c/f)
|
1099
|
-
|
1100
|
-
#假定票面价值为1元
|
1101
|
-
cf=a*(c/f+e+d)-b
|
1102
|
-
|
1103
|
-
return cf
|
1104
|
-
|
1105
|
-
if __name__=='__main__':
|
1106
|
-
c=0.026
|
1107
|
-
v=30
|
1108
|
-
m=10
|
1109
|
-
f=2
|
1110
|
-
r=0.03
|
1111
|
-
cf_day(c,v,m)
|