siat 3.10.132__py3-none-any.whl → 3.11.1__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 (221) hide show
  1. siat/__init__.py +0 -0
  2. siat/allin.py +8 -0
  3. siat/assets_liquidity.py +0 -0
  4. siat/beta_adjustment.py +0 -0
  5. siat/beta_adjustment_china.py +0 -0
  6. siat/blockchain.py +0 -0
  7. siat/bond.py +0 -0
  8. siat/bond_base.py +0 -0
  9. siat/bond_china.py +0 -0
  10. siat/bond_zh_sina.py +0 -0
  11. siat/capm_beta.py +0 -0
  12. siat/capm_beta2.py +4 -4
  13. siat/common.py +9 -6
  14. siat/compare_cross.py +0 -0
  15. siat/copyrights.py +0 -0
  16. siat/cryptocurrency.py +0 -0
  17. siat/economy.py +0 -0
  18. siat/economy2.py +0 -0
  19. siat/esg.py +0 -0
  20. siat/event_study.py +0 -0
  21. siat/exchange_bond_china.pickle +0 -0
  22. siat/fama_french.py +0 -0
  23. siat/fin_stmt2_yahoo.py +0 -0
  24. siat/financial_base.py +0 -0
  25. siat/financial_statements.py +0 -0
  26. siat/financials.py +0 -0
  27. siat/financials2.py +0 -0
  28. siat/financials_china.py +0 -0
  29. siat/financials_china2.py +0 -0
  30. siat/fund.py +0 -0
  31. siat/fund_china.pickle +0 -0
  32. siat/fund_china.py +0 -0
  33. siat/future_china.py +0 -0
  34. siat/google_authenticator.py +0 -0
  35. siat/grafix.py +55 -4
  36. siat/holding_risk.py +0 -0
  37. siat/luchy_draw.py +0 -0
  38. siat/market_china.py +0 -0
  39. siat/markowitz.py +0 -0
  40. siat/markowitz2.py +1 -0
  41. siat/markowitz2_20250704.py +0 -0
  42. siat/markowitz2_20250705.py +0 -0
  43. siat/markowitz_simple.py +0 -0
  44. siat/ml_cases.py +0 -0
  45. siat/ml_cases_example.py +0 -0
  46. siat/option_china.py +0 -0
  47. siat/option_pricing.py +0 -0
  48. siat/other_indexes.py +0 -0
  49. siat/risk_adjusted_return.py +0 -0
  50. siat/risk_adjusted_return2.py +8 -4
  51. siat/risk_evaluation.py +0 -0
  52. siat/risk_free_rate.py +0 -0
  53. siat/save2docx.py +345 -0
  54. siat/save2pdf.py +145 -0
  55. siat/sector_china.py +0 -0
  56. siat/security_price2.py +0 -0
  57. siat/security_prices.py +168 -6
  58. siat/security_trend.py +0 -0
  59. siat/security_trend2.py +2 -2
  60. siat/stock.py +11 -1
  61. siat/stock_advice_linear.py +0 -0
  62. siat/stock_base.py +0 -0
  63. siat/stock_china.py +0 -0
  64. siat/stock_info.pickle +0 -0
  65. siat/stock_prices_kneighbors.py +0 -0
  66. siat/stock_prices_linear.py +0 -0
  67. siat/stock_profile.py +0 -0
  68. siat/stock_technical.py +0 -0
  69. siat/stooq.py +0 -0
  70. siat/transaction.py +0 -0
  71. siat/translate.py +0 -0
  72. siat/valuation.py +0 -0
  73. siat/valuation_china.py +0 -0
  74. siat/var_model_validation.py +0 -0
  75. siat/yf_name.py +0 -0
  76. {siat-3.10.132.dist-info/licenses → siat-3.11.1.dist-info}/LICENSE +0 -0
  77. {siat-3.10.132.dist-info → siat-3.11.1.dist-info}/METADATA +234 -235
  78. siat-3.11.1.dist-info/RECORD +80 -0
  79. {siat-3.10.132.dist-info → siat-3.11.1.dist-info}/WHEEL +1 -1
  80. {siat-3.10.132.dist-info → siat-3.11.1.dist-info}/top_level.txt +0 -1
  81. build/lib/build/lib/siat/__init__.py +0 -75
  82. build/lib/build/lib/siat/allin.py +0 -137
  83. build/lib/build/lib/siat/assets_liquidity.py +0 -915
  84. build/lib/build/lib/siat/beta_adjustment.py +0 -1058
  85. build/lib/build/lib/siat/beta_adjustment_china.py +0 -548
  86. build/lib/build/lib/siat/blockchain.py +0 -143
  87. build/lib/build/lib/siat/bond.py +0 -2900
  88. build/lib/build/lib/siat/bond_base.py +0 -992
  89. build/lib/build/lib/siat/bond_china.py +0 -100
  90. build/lib/build/lib/siat/bond_zh_sina.py +0 -143
  91. build/lib/build/lib/siat/capm_beta.py +0 -783
  92. build/lib/build/lib/siat/capm_beta2.py +0 -887
  93. build/lib/build/lib/siat/common.py +0 -5360
  94. build/lib/build/lib/siat/compare_cross.py +0 -642
  95. build/lib/build/lib/siat/copyrights.py +0 -18
  96. build/lib/build/lib/siat/cryptocurrency.py +0 -667
  97. build/lib/build/lib/siat/economy.py +0 -1471
  98. build/lib/build/lib/siat/economy2.py +0 -1853
  99. build/lib/build/lib/siat/esg.py +0 -536
  100. build/lib/build/lib/siat/event_study.py +0 -815
  101. build/lib/build/lib/siat/fama_french.py +0 -1521
  102. build/lib/build/lib/siat/fin_stmt2_yahoo.py +0 -982
  103. build/lib/build/lib/siat/financial_base.py +0 -1160
  104. build/lib/build/lib/siat/financial_statements.py +0 -598
  105. build/lib/build/lib/siat/financials.py +0 -2339
  106. build/lib/build/lib/siat/financials2.py +0 -1278
  107. build/lib/build/lib/siat/financials_china.py +0 -4433
  108. build/lib/build/lib/siat/financials_china2.py +0 -2212
  109. build/lib/build/lib/siat/fund.py +0 -629
  110. build/lib/build/lib/siat/fund_china.py +0 -3307
  111. build/lib/build/lib/siat/future_china.py +0 -551
  112. build/lib/build/lib/siat/google_authenticator.py +0 -47
  113. build/lib/build/lib/siat/grafix.py +0 -3636
  114. build/lib/build/lib/siat/holding_risk.py +0 -867
  115. build/lib/build/lib/siat/luchy_draw.py +0 -638
  116. build/lib/build/lib/siat/market_china.py +0 -1168
  117. build/lib/build/lib/siat/markowitz.py +0 -2363
  118. build/lib/build/lib/siat/markowitz2.py +0 -3150
  119. build/lib/build/lib/siat/markowitz2_20250704.py +0 -2969
  120. build/lib/build/lib/siat/markowitz2_20250705.py +0 -3158
  121. build/lib/build/lib/siat/markowitz_simple.py +0 -373
  122. build/lib/build/lib/siat/ml_cases.py +0 -2291
  123. build/lib/build/lib/siat/ml_cases_example.py +0 -60
  124. build/lib/build/lib/siat/option_china.py +0 -3069
  125. build/lib/build/lib/siat/option_pricing.py +0 -1925
  126. build/lib/build/lib/siat/other_indexes.py +0 -409
  127. build/lib/build/lib/siat/risk_adjusted_return.py +0 -1576
  128. build/lib/build/lib/siat/risk_adjusted_return2.py +0 -1900
  129. build/lib/build/lib/siat/risk_evaluation.py +0 -2218
  130. build/lib/build/lib/siat/risk_free_rate.py +0 -351
  131. build/lib/build/lib/siat/sector_china.py +0 -4140
  132. build/lib/build/lib/siat/security_price2.py +0 -727
  133. build/lib/build/lib/siat/security_prices.py +0 -3408
  134. build/lib/build/lib/siat/security_trend.py +0 -402
  135. build/lib/build/lib/siat/security_trend2.py +0 -646
  136. build/lib/build/lib/siat/stock.py +0 -4284
  137. build/lib/build/lib/siat/stock_advice_linear.py +0 -934
  138. build/lib/build/lib/siat/stock_base.py +0 -26
  139. build/lib/build/lib/siat/stock_china.py +0 -2095
  140. build/lib/build/lib/siat/stock_prices_kneighbors.py +0 -910
  141. build/lib/build/lib/siat/stock_prices_linear.py +0 -386
  142. build/lib/build/lib/siat/stock_profile.py +0 -707
  143. build/lib/build/lib/siat/stock_technical.py +0 -3305
  144. build/lib/build/lib/siat/stooq.py +0 -74
  145. build/lib/build/lib/siat/transaction.py +0 -347
  146. build/lib/build/lib/siat/translate.py +0 -5183
  147. build/lib/build/lib/siat/valuation.py +0 -1378
  148. build/lib/build/lib/siat/valuation_china.py +0 -2076
  149. build/lib/build/lib/siat/var_model_validation.py +0 -444
  150. build/lib/build/lib/siat/yf_name.py +0 -811
  151. build/lib/siat/__init__.py +0 -75
  152. build/lib/siat/allin.py +0 -137
  153. build/lib/siat/assets_liquidity.py +0 -915
  154. build/lib/siat/beta_adjustment.py +0 -1058
  155. build/lib/siat/beta_adjustment_china.py +0 -548
  156. build/lib/siat/blockchain.py +0 -143
  157. build/lib/siat/bond.py +0 -2900
  158. build/lib/siat/bond_base.py +0 -992
  159. build/lib/siat/bond_china.py +0 -100
  160. build/lib/siat/bond_zh_sina.py +0 -143
  161. build/lib/siat/capm_beta.py +0 -783
  162. build/lib/siat/capm_beta2.py +0 -887
  163. build/lib/siat/common.py +0 -5360
  164. build/lib/siat/compare_cross.py +0 -642
  165. build/lib/siat/copyrights.py +0 -18
  166. build/lib/siat/cryptocurrency.py +0 -667
  167. build/lib/siat/economy.py +0 -1471
  168. build/lib/siat/economy2.py +0 -1853
  169. build/lib/siat/esg.py +0 -536
  170. build/lib/siat/event_study.py +0 -815
  171. build/lib/siat/fama_french.py +0 -1521
  172. build/lib/siat/fin_stmt2_yahoo.py +0 -982
  173. build/lib/siat/financial_base.py +0 -1160
  174. build/lib/siat/financial_statements.py +0 -598
  175. build/lib/siat/financials.py +0 -2339
  176. build/lib/siat/financials2.py +0 -1278
  177. build/lib/siat/financials_china.py +0 -4433
  178. build/lib/siat/financials_china2.py +0 -2212
  179. build/lib/siat/fund.py +0 -629
  180. build/lib/siat/fund_china.py +0 -3307
  181. build/lib/siat/future_china.py +0 -551
  182. build/lib/siat/google_authenticator.py +0 -47
  183. build/lib/siat/grafix.py +0 -3636
  184. build/lib/siat/holding_risk.py +0 -867
  185. build/lib/siat/luchy_draw.py +0 -638
  186. build/lib/siat/market_china.py +0 -1168
  187. build/lib/siat/markowitz.py +0 -2363
  188. build/lib/siat/markowitz2.py +0 -3150
  189. build/lib/siat/markowitz2_20250704.py +0 -2969
  190. build/lib/siat/markowitz2_20250705.py +0 -3158
  191. build/lib/siat/markowitz_simple.py +0 -373
  192. build/lib/siat/ml_cases.py +0 -2291
  193. build/lib/siat/ml_cases_example.py +0 -60
  194. build/lib/siat/option_china.py +0 -3069
  195. build/lib/siat/option_pricing.py +0 -1925
  196. build/lib/siat/other_indexes.py +0 -409
  197. build/lib/siat/risk_adjusted_return.py +0 -1576
  198. build/lib/siat/risk_adjusted_return2.py +0 -1900
  199. build/lib/siat/risk_evaluation.py +0 -2218
  200. build/lib/siat/risk_free_rate.py +0 -351
  201. build/lib/siat/sector_china.py +0 -4140
  202. build/lib/siat/security_price2.py +0 -727
  203. build/lib/siat/security_prices.py +0 -3408
  204. build/lib/siat/security_trend.py +0 -402
  205. build/lib/siat/security_trend2.py +0 -646
  206. build/lib/siat/stock.py +0 -4284
  207. build/lib/siat/stock_advice_linear.py +0 -934
  208. build/lib/siat/stock_base.py +0 -26
  209. build/lib/siat/stock_china.py +0 -2095
  210. build/lib/siat/stock_prices_kneighbors.py +0 -910
  211. build/lib/siat/stock_prices_linear.py +0 -386
  212. build/lib/siat/stock_profile.py +0 -707
  213. build/lib/siat/stock_technical.py +0 -3305
  214. build/lib/siat/stooq.py +0 -74
  215. build/lib/siat/transaction.py +0 -347
  216. build/lib/siat/translate.py +0 -5183
  217. build/lib/siat/valuation.py +0 -1378
  218. build/lib/siat/valuation_china.py +0 -2076
  219. build/lib/siat/var_model_validation.py +0 -444
  220. build/lib/siat/yf_name.py +0 -811
  221. siat-3.10.132.dist-info/RECORD +0 -218
@@ -1,887 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- 本模块功能:CAPM beta
4
- 所属工具包:证券投资分析工具SIAT
5
- SIAT:Security Investment Analysis Tool
6
- 创建日期:2024年3月22日
7
- 最新修订日期:2024年3月22日
8
- 作者:王德宏 (WANG Dehong, Peter)
9
- 作者单位:北京外国语大学国际商学院
10
- 作者邮件:wdehong2000@163.com
11
- 版权所有:王德宏
12
- 用途限制:仅限研究与教学使用,不可商用!
13
- 特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
14
- """
15
-
16
- #==============================================================================
17
- #关闭所有警告
18
- import warnings; warnings.filterwarnings('ignore')
19
- #==============================================================================
20
- from siat.common import *
21
- from siat.translate import *
22
- from siat.security_prices import *
23
- from siat.security_price2 import *
24
- from siat.grafix import *
25
-
26
- import pandas as pd
27
- import numpy as np
28
- #==============================================================================
29
- #==============================================================================
30
- #==============================================================================
31
- if __name__=='__main__':
32
- ticker="600519.SS"
33
-
34
- def get_market_index_code(ticker):
35
- """
36
- 功能:基于股票ticker确定其所在市场的大盘指数代码
37
- """
38
- ticker=tickers_cvt2yahoo(ticker)
39
- _,_,suffix=split_prefix_suffix(ticker)
40
-
41
- if suffix in ['SS']:
42
- mktidx='000001.SS' #上证综合指数
43
- elif suffix in ['SZ']:
44
- mktidx='399001.SZ'
45
- elif suffix in ['BJ']:
46
- mktidx='899050.BJ' #北证50指数
47
- elif suffix in ['CN']:
48
- mktidx='000300.SS' #沪深300指数
49
- elif suffix in ['HK']:
50
- mktidx='^HSI' #恒生指数
51
- elif suffix in ['TW']:
52
- mktidx='^TWII' #台湾加权指数
53
- elif suffix in ['SI']:
54
- mktidx='^STI' #新加坡海峡时报指数
55
- elif suffix in ['T']:
56
- mktidx='^N225' #日经225指数
57
- elif suffix in ['KS']:
58
- mktidx='^KS11' #韩国综合指数
59
- elif suffix in ['NS','BO']:
60
- mktidx='^SNX' #孟买敏感指数
61
- elif suffix =='':
62
- mktidx='^SPX' #标普500指数
63
- elif suffix in ['L','UK']:
64
- mktidx='^FTSE' #英国富时100指数
65
- elif suffix in ['DE']:
66
- mktidx='^DAX' #德国DAX30指数
67
- elif suffix in ['F']:
68
- mktidx='^CAC' #法国CAC40指数
69
- else:
70
- mktidx='^SPX' #标普500指数
71
-
72
- return mktidx
73
-
74
- #==============================================================================
75
- if __name__=='__main__':
76
- ticker="600519.SS"
77
- ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.7,'TAL':0.3}
78
-
79
- start2='2022-10-31'
80
- end='2024-3-23'
81
- RF=0.01759
82
- regtrddays=252
83
-
84
- mktidx='auto'; source='auto'
85
-
86
- reg_result,dretdf3=regression_capm(ticker,start2,end,RF,regtrddays)
87
-
88
- def regression_capm(ticker,start2,end, \
89
- adjust='qfq', \
90
- RF=0,regtrddays=252, \
91
- mktidx='auto',source='auto',ticker_type='auto'):
92
- """
93
- 功能:进行CAPM回归,R-Rf=beta*(Rm-Rf),无截距项回归
94
- x为(Rm-Rf),y为R-Rf,均为日收益率,默认回归样本长度一年(365日历日或252交易日)
95
- 返回:beta系数
96
- 注意:回归基于传统的日收益率,而非滚动收益率
97
- """
98
- DEBUG=False
99
-
100
- #抓取股价,计算股票日收益率
101
- if DEBUG:
102
- print("*** DEBUG:",ticker,start2,end)
103
- #pricedf=get_price(ticker,start2,end,source=source)
104
- #pricedf=get_price_security(ticker,start2,end,source=source)
105
- pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start2,todate=end, \
106
- adjust=adjust, \
107
- source=source,ticker_type=ticker_type)
108
-
109
- if pricedf is None:
110
- print(" #Error(regression_capm): info of security",ticker_name(ticker,ticker_type),"not found or inaccessible")
111
- return None,None
112
-
113
- #计算股票滚动收益率
114
- pricedf1=calc_daily_return(pricedf)
115
-
116
- #抓取大盘指数,计算指数日收益率
117
- """
118
- if 'auto' in mktidx.lower():
119
- mktidx=get_market_index_code(ticker)
120
- """
121
- if isinstance(ticker,dict):
122
- _,mktidx,pftickerlist,_,ticker_type=decompose_portfolio(ticker)
123
- if 'auto' in mktidx.lower():
124
- mktidx=get_market_index_code(pftickerlist[0])
125
- else:
126
- if 'auto' in mktidx.lower():
127
- mktidx=get_market_index_code(ticker)
128
-
129
- #marketdf=get_price(mktidx,start2,end,source=source)
130
- #大盘指数实际上无复权价?
131
- marketdf,found=get_price_1ticker_mixed(ticker=mktidx,fromdate=start2,todate=end, \
132
- adjust=adjust, \
133
- source=source,ticker_type=ticker_type)
134
-
135
- if marketdf is None:
136
- print(" #Error(regression_capm): info of market index",mktidx,"not found or inaccessible")
137
- return None,None
138
-
139
- marketdf1=calc_daily_return(marketdf)
140
-
141
- #合并股票和大盘指数日收益率
142
- dretdf1=pd.merge(marketdf1,pricedf1,how='inner',left_index=True,right_index=True)
143
-
144
- #准备CAPM回归文件
145
- if adjust == '':
146
- dretname='Daily Ret'
147
- else:
148
- dretname='Daily Adj Ret'
149
-
150
- #计算日无风险利率
151
- RF_daily=RF / 365
152
-
153
- dretx=dretname+'_x' #指数日收益率
154
- drety=dretname+'_y' #股票日收益率
155
- dretdf2=dretdf1[[dretx,drety]]
156
- dretdf2.dropna(inplace=True)
157
-
158
- #计算股票和指数收益率的风险溢价R-RF
159
- dretdfcols=list(dretdf2)
160
- for c in dretdfcols:
161
- dretdf2[c]=dretdf2[c].apply(lambda x: x-RF_daily)
162
- dretdf2=dretdf2.reset_index()
163
- #dretdf2.rename(columns={'index':'Date'},inplace=True)
164
- if 'Date' not in list(dretdf2):
165
- dretdf2['Date']=dretdf2['index']
166
-
167
- #CAPM回归,计算贝塔系数
168
- dretnum=len(dretdf2)
169
- if regtrddays >= dretnum:
170
- regtrddays=dretnum - 31 *2
171
-
172
- import statsmodels.api as sm
173
- reg_result=pd.DataFrame(columns=('Date','beta'))
174
- for i in range(dretnum):
175
- i2=dretnum-i
176
- i1=i2-regtrddays
177
- if i1 < 0: break
178
-
179
- regdf=dretdf2[i1:i2]
180
- lastdate=regdf.tail(1)['Date'].values[0]
181
-
182
- X=regdf[dretx] #无截距项回归
183
- Y=regdf[drety]
184
- model = sm.OLS(Y,X) #定义回归模型R-Rf=beta(Rm-Rf),X可为多元矩阵
185
- results = model.fit() #进行OLS回归
186
- beta=results.params[0] #提取回归系数
187
-
188
- row=pd.Series({'Date':lastdate,'beta':beta})
189
- try:
190
- reg_result=reg_result.append(row,ignore_index=True)
191
- except:
192
- reg_result=reg_result._append(row,ignore_index=True)
193
-
194
- reg_result.set_index(['Date'],inplace=True)
195
- reg_result.sort_index(inplace=True) #按日期升序排列
196
-
197
- dretdf3=dretdf2.set_index(['Date'])
198
- if 'index' in list(dretdf3):
199
- del dretdf3['index']
200
-
201
- reg_result['mktidx']=mktidx
202
-
203
- return reg_result,dretdf3
204
-
205
-
206
- def regression_capm_df(marketdf,pricedf,mktidx,adjust='qfq',RF=0,regtrddays=252):
207
- """
208
- 功能:进行CAPM回归,R-Rf=beta*(Rm-Rf),无截距项回归
209
- x为(Rm-Rf),y为R-Rf,均为日收益率,默认回归样本长度一年(365日历日或252交易日)
210
- 返回:beta系数
211
- 注意:回归基于传统的日收益率,而非滚动收益率
212
- """
213
-
214
- #合并股票和大盘指数日收益率
215
- dretdf1=pd.merge(marketdf,pricedf,how='inner',left_index=True,right_index=True)
216
-
217
- #准备CAPM回归文件
218
- if adjust == '':
219
- dretname='Daily Ret'
220
- else:
221
- dretname='Daily Adj Ret'
222
-
223
- #计算日无风险利率
224
- RF_daily=RF / 365
225
-
226
- dretx=dretname+'_x' #指数日收益率
227
- drety=dretname+'_y' #股票日收益率
228
- dretdf2=dretdf1[[dretx,drety]]
229
- dretdf2.dropna(inplace=True)
230
-
231
- #计算股票和指数收益率的风险溢价R-RF
232
- dretdfcols=list(dretdf2)
233
- for c in dretdfcols:
234
- dretdf2[c]=dretdf2[c].apply(lambda x: x-RF_daily)
235
- dretdf2=dretdf2.reset_index()
236
- #dretdf2.rename(columns={'index':'Date'},inplace=True)
237
- if 'Date' not in list(dretdf2):
238
- dretdf2['Date']=dretdf2['index']
239
-
240
- #CAPM回归,计算贝塔系数
241
- dretnum=len(dretdf2)
242
- if regtrddays >= dretnum:
243
- regtrddays=dretnum - 31 *2
244
-
245
- import statsmodels.api as sm
246
- reg_result=pd.DataFrame(columns=('Date','beta'))
247
- for i in range(dretnum):
248
- i2=dretnum-i
249
- i1=i2-regtrddays
250
- if i1 < 0: break
251
-
252
- regdf=dretdf2[i1:i2]
253
- lastdate=regdf.tail(1)['Date'].values[0]
254
-
255
- X=regdf[dretx] #无截距项回归
256
- Y=regdf[drety]
257
- model = sm.OLS(Y,X) #定义回归模型R-Rf=beta(Rm-Rf),X可为多元矩阵
258
- results = model.fit() #进行OLS回归
259
- beta=results.params[0] #提取回归系数
260
-
261
- row=pd.Series({'Date':lastdate,'beta':beta})
262
- try:
263
- reg_result=reg_result.append(row,ignore_index=True)
264
- except:
265
- reg_result=reg_result._append(row,ignore_index=True)
266
-
267
- reg_result.set_index(['Date'],inplace=True)
268
- reg_result.sort_index(inplace=True) #按日期升序排列
269
-
270
- dretdf3=dretdf2.set_index(['Date'])
271
- if 'index' in list(dretdf3):
272
- del dretdf3['index']
273
-
274
- reg_result['mktidx']=mktidx
275
-
276
- return reg_result,dretdf3
277
-
278
- #==============================================================================
279
- if __name__=='__main__':
280
- ticker="600519.SS"
281
- ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.5,'TAL':0.3,'TEDU':0.2}
282
-
283
- start="2024-1-1"
284
- end="2024-3-23"
285
- RF=0.01759
286
- regtrddays=252
287
- mktidx='auto'; source='auto'
288
-
289
- beta1=get_capm_beta(ticker,start,end,RF,regtrddays)
290
- beta1.plot()
291
-
292
- def get_capm_beta(ticker,start,end,adjust='qfq',RF=0,regtrddays=252,mktidx='auto', \
293
- source='auto',ticker_type='auto'):
294
- """
295
- 功能:套壳函数regression_capm,仅返回滚动的贝塔系数,基于日收益率
296
- 滚动窗口长度为regtrddays,默认为一年的交易日
297
- 注意函数regression_capm没有向前调整日期,需要本函数内进行调整。
298
- """
299
- start2=date_adjust(start,adjust=-365/252 * regtrddays -31*2)
300
-
301
- reg_result,_=regression_capm(ticker=ticker,start2=start2,end=end, \
302
- adjust=adjust, \
303
- RF=RF, \
304
- regtrddays=regtrddays,mktidx=mktidx, \
305
- source=source,ticker_type=ticker_type)
306
-
307
- startpd=pd.to_datetime(date_adjust(start,adjust=-7))
308
- endpd=pd.to_datetime(end)
309
-
310
- try:
311
- reg_result2=reg_result[(reg_result.index >= startpd) & (reg_result.index <= endpd)]
312
- except:
313
- print(" #Error(get_capm_beta): none obtained from capm regression")
314
-
315
- return reg_result2
316
-
317
- #==============================================================================
318
- #==============================================================================
319
- if __name__=='__main__':
320
- ticker=["600519.SS","000858.SZ"]
321
- ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.5,'TAL':0.3,'TEDU':0.2}
322
-
323
- start="2024-1-1"
324
- end="2024-3-23"
325
- RF=0.01759
326
- regression_period=365
327
-
328
- graph=True; axhline_value=1; axhline_label=''
329
- printout=False
330
- annotate=False
331
- mktidx='auto'
332
- source='auto'
333
- ticker_type='auto'
334
-
335
- betas=compare_mticker_1beta(ticker,start,end)
336
-
337
- def compare_mticker_1beta(ticker,start,end, \
338
- adjust='qfq', \
339
- RF=0,regression_period=365, \
340
- attention_value='',attention_value_area='', \
341
- attention_point='',attention_point_area='', \
342
- axhline_value=1,axhline_label='零线', \
343
- band_area='', \
344
- graph=True,facecolor='whitesmoke',loc='best', \
345
- annotate=False,annotate_value=False, \
346
- mark_top=False,mark_bottom=False, \
347
- mark_start=False,mark_end=False, \
348
- mktidx='auto',source='auto',ticker_type='auto'):
349
- """
350
- 功能:多只股票,对比其贝塔系数
351
- """
352
-
353
- import os,sys
354
- class HiddenPrints:
355
- def __enter__(self):
356
- self._original_stdout = sys.stdout
357
- sys.stdout = open(os.devnull, 'w')
358
-
359
- def __exit__(self, exc_type, exc_val, exc_tb):
360
- sys.stdout.close()
361
- sys.stdout = self._original_stdout
362
-
363
- #转换字符串和列表,避免下面的循环出错
364
- if isinstance(ticker,str) or isinstance(ticker,dict):
365
- ticker=[ticker]
366
- if isinstance(RF,list):
367
- RF=RF[0]
368
- if isinstance(regression_period,list):
369
- regression_period=regression_period[0]
370
- print(" Working on capm beta, please wait ......")
371
-
372
- #计算日历日regression_period对应的交易日数
373
- regtrddays=int(252 / 365 * regression_period)
374
-
375
- #预处理ticker_type
376
- ticker_type_list=ticker_type_preprocess_mticker_mixed(ticker,ticker_type)
377
-
378
- df=pd.DataFrame()
379
- for t in ticker:
380
- pos=ticker.index(t)
381
- tt=ticker_type_list[pos]
382
-
383
- #关闭print输出
384
- with HiddenPrints():
385
- df_tmp=get_capm_beta(t,start,end,adjust,RF,regtrddays,mktidx,source,ticker_type=tt)
386
-
387
- if df_tmp is None:
388
- break
389
- else:
390
- dft=df_tmp[['beta']]
391
-
392
- tname=ticker_name(t,tt)
393
- dft.rename(columns={'beta':tname},inplace=True)
394
- mktidx_name=ticker_name(df_tmp['mktidx'].values[0])
395
-
396
- # 将band_area中的ticker替换为tname
397
- if band_area != '':
398
- for index, item in enumerate(band_area):
399
- if item == t:
400
- band_area[index] = tname
401
-
402
- if len(df)==0: #第一个
403
- df=dft
404
- else:
405
- df=pd.merge(df,dft,how='outer',left_index=True,right_index=True)
406
-
407
- if len(df)==0:
408
- print(" #Error(compare_mticker_1beta): beta data not available for",t,"between",start,end)
409
- return None
410
-
411
- #仅用于绘图和制表
412
- df1=df.copy()
413
- beta_list=list(df1)
414
-
415
- for c in beta_list:
416
- #是否绘制水平线
417
- if df1[c].max() > axhline_value and df1[c].min() < axhline_value:
418
- axhline_label='零线'
419
- #df1.rename(columns={c:ticker_name(c)},inplace=True)
420
-
421
- #共同脚注
422
- footnote1=text_lang("注:","Notes: ")
423
- """
424
- if RF !=0:
425
- footnote2=text_lang("年化无风险利率为","RF = ")+str(round(RF*100,4))+text_lang('%。','% pa. ')
426
- else:
427
- footnote2="假设年化无风险利率为零。"
428
- """
429
- footnote2=text_lang("年化无风险利率为","RF = ")+str(round(RF*100,4))+text_lang('%。','% pa. ')
430
-
431
- footnote3=text_lang("基于","Beta using ")+mktidx_name+text_lang(",CAPM回归期间为",", CAPM rolling ")+str(regression_period)+text_lang("个自然日"," days")
432
-
433
- import datetime; todaydt = datetime.date.today()
434
- footnote4=text_lang("数据来源: 综合新浪/Stooq/Yahoo,","Data source: Sina/Stooq/Yahoo, ")+str(todaydt)+text_lang("统计",'')
435
- if footnote3 !='':
436
- footnotex=footnote1+footnote2+footnote3+'\n'+footnote4
437
- else:
438
- footnotex=footnote1+footnote2+footnote3+footnote4
439
-
440
- #绘图
441
- if graph:
442
- title_txt=text_lang("CAPM贝塔系数","CAPM Beta Coefficient")
443
- y_label=text_lang("贝塔系数","Beta")
444
-
445
- draw_lines(df1,y_label,x_label=footnotex, \
446
- axhline_value=axhline_value,axhline_label=axhline_label, \
447
- title_txt=title_txt,data_label=False, \
448
- attention_value=attention_value,attention_value_area=attention_value_area, \
449
- attention_point=attention_point,attention_point_area=attention_point_area, \
450
- band_area=band_area, \
451
- annotate=annotate,annotate_value=annotate, \
452
- mark_top=mark_top,mark_bottom=mark_bottom, \
453
- mark_start=mark_start,mark_end=mark_end, \
454
- facecolor=facecolor,loc=loc,precision=4)
455
-
456
- return df
457
-
458
- #==============================================================================
459
- if __name__=='__main__':
460
- ticker="600519.SS"
461
- ticker="000858.SZ"
462
- ticker={'Market':('China','000300.SS','白酒组合'),'600519.SS':0.2,'000858.SZ':0.3,'600809.SS':0.5}
463
-
464
- start="2024-3-11"
465
- end="2024-3-23"
466
- RF=[0,0.01759,0.05]
467
- regression_period=365
468
-
469
- graph=True; axhline_value=1; axhline_label=''
470
- annotate=False
471
- mktidx='auto'
472
- source='auto'
473
- ticker_type='auto'
474
-
475
- betas=compare_1ticker_mRF(ticker,start,end,RF)
476
-
477
- def compare_1ticker_mRF(ticker,start,end, \
478
- adjust='qfq', \
479
- RF=[0,0.02,0.05], \
480
- regression_period=365, \
481
- attention_value='',attention_value_area='', \
482
- attention_point='',attention_point_area='', \
483
- axhline_value=1,axhline_label='零线', \
484
- band_area='', \
485
- graph=True,facecolor='whitesmoke',loc='best', \
486
- annotate=False,annotate_value=False, \
487
- mark_top=False,mark_bottom=False, \
488
- mark_start=False,mark_end=False, \
489
- mktidx='auto',source='auto', \
490
- ticker_type='auto'):
491
- """
492
- 功能:一只股票,不同的无风险收益率
493
- """
494
-
495
- import os,sys
496
- class HiddenPrints:
497
- def __enter__(self):
498
- self._original_stdout = sys.stdout
499
- sys.stdout = open(os.devnull, 'w')
500
-
501
- def __exit__(self, exc_type, exc_val, exc_tb):
502
- sys.stdout.close()
503
- sys.stdout = self._original_stdout
504
-
505
- #转换字符串和列表,避免下面的循环出错
506
- if isinstance(ticker,list):
507
- ticker=ticker[0]
508
- if isinstance(RF,float):
509
- RF=[RF]
510
- if isinstance(regression_period,list):
511
- regression_period=regression_period[0]
512
- print(" Working on capm beta with different RFs, please wait ......")
513
-
514
- #计算日历日regression_period对应的交易日数
515
- regtrddays=int(252 / 365 * regression_period)
516
-
517
- #预处理ticker_type
518
- ticker_type=ticker_type_preprocess_mticker_mixed(ticker,ticker_type)
519
-
520
- df=pd.DataFrame()
521
- for t in RF:
522
- #关闭print输出
523
- with HiddenPrints():
524
- df_tmp=get_capm_beta(ticker,start,end,adjust,t,regtrddays,mktidx,source,ticker_type=ticker_type)
525
-
526
- if df_tmp is None:
527
- break
528
- else:
529
- dft=df_tmp[['beta']]
530
-
531
- #tname="基于无风险利率"+str(round(t*100,4))+'%'
532
- tname="RF="+str(round(t*100,4))+'%'
533
- dft.rename(columns={'beta':tname},inplace=True)
534
- mktidx_name=ticker_name(df_tmp['mktidx'].values[0])
535
-
536
- # 将band_area中的ticker替换为tname
537
- if band_area != '':
538
- for index, item in enumerate(band_area):
539
- if item == t:
540
- band_area[index] = tname
541
-
542
- if len(df)==0: #第一个
543
- df=dft
544
- else:
545
- df=pd.merge(df,dft,how='outer',left_index=True,right_index=True)
546
-
547
- if len(df)==0:
548
- print(" #Error(compare_1ticker_mRF): data not available for",ticker,"between",start,end)
549
- return None
550
-
551
- #仅用于绘图和制表
552
- df1=df.copy()
553
- beta_list=list(df1)
554
-
555
- for c in beta_list:
556
- #是否绘制水平线
557
- if df1[c].max() > axhline_value and df1[c].min() < axhline_value:
558
- axhline_label='零线'
559
- #df1.rename(columns={c:"基于无风险利率"+c},inplace=True)
560
-
561
- #去掉提前的数据
562
- start1=pd.to_datetime(date_adjust(start,adjust=-2))
563
- df1=df1[df1.index >= start1]
564
-
565
- #共同脚注
566
- footnote1="注:"
567
- footnote2=""
568
-
569
- #footnote3="贝塔系数基于日收益率,回归期间跨度为"+str(regression_period)+"个自然日。"
570
- footnote3="基于"+mktidx_name+",回归期间为"+str(regression_period)+"个自然日。"
571
-
572
- import datetime; todaydt = datetime.date.today()
573
- footnote4="数据来源: 综合新浪/stooq/Yahoo,"+str(todaydt)+"统计"
574
- if footnote3 !='':
575
- footnotex=footnote1+footnote3+'\n'+footnote4
576
- else:
577
- footnotex=footnote4
578
-
579
- #绘图
580
- if graph:
581
- title_txt="CAPM贝塔系数:"+ticker_name(ticker,ticker_type)
582
- y_label="贝塔系数"
583
-
584
- draw_lines(df1,y_label,x_label=footnotex, \
585
- axhline_value=axhline_value,axhline_label=axhline_label, \
586
- title_txt=title_txt,data_label=False, \
587
- attention_value=attention_value,attention_value_area=attention_value_area, \
588
- attention_point=attention_point,attention_point_area=attention_point_area, \
589
- band_area=band_area, \
590
- annotate=annotate,annotate_value=annotate, \
591
- mark_top=mark_top,mark_bottom=mark_bottom, \
592
- mark_start=mark_start,mark_end=mark_end, \
593
- facecolor=facecolor,loc=loc, \
594
- precision=4)
595
-
596
- return df
597
-
598
- #==============================================================================
599
- if __name__=='__main__':
600
- ticker="600519.SS"
601
- ticker={'Market':('China','000300.SS','白酒组合'),'600519.SS':0.2,'000858.SZ':0.3,'600809.SS':0.5}
602
-
603
- start="2024-1-1"
604
- end="2024-3-15"
605
- RF=0.01759
606
- regression_period=[365,183,730]
607
-
608
- graph=True; axhline_value=1; axhline_label=''
609
- annotate=False
610
- mktidx='auto'
611
- source='auto'
612
-
613
- betas=compare_1ticker_mregression_period(ticker,start,end,RF,regression_period)
614
-
615
- def compare_1ticker_mregression_period(ticker,start,end, \
616
- adjust='qfq', \
617
- RF=0, \
618
- regression_period=[183,365,730], \
619
- attention_value='',attention_value_area='', \
620
- attention_point='',attention_point_area='', \
621
- axhline_value=1,axhline_label='零线', \
622
- band_area='', \
623
- graph=True,facecolor='whitesmoke',loc='best', \
624
- annotate=False,annotate_value=False, \
625
- mark_top=False,mark_bottom=False, \
626
- mark_start=False,mark_end=False, \
627
- mktidx='auto',source='auto', \
628
- ticker_type='auto'):
629
- """
630
- 功能:一只股票或一个投资组合,不同的回归期间
631
- """
632
-
633
- import os,sys
634
- class HiddenPrints:
635
- def __enter__(self):
636
- self._original_stdout = sys.stdout
637
- sys.stdout = open(os.devnull, 'w')
638
-
639
- def __exit__(self, exc_type, exc_val, exc_tb):
640
- sys.stdout.close()
641
- sys.stdout = self._original_stdout
642
-
643
- #转换字符串和列表,避免下面的循环出错
644
- if isinstance(ticker,list):
645
- ticker=ticker[0]
646
- if isinstance(RF,list):
647
- RF=RF[0]
648
- if isinstance(regression_period,int):
649
- regression_period=[regression_period]
650
- print(" Working on capm beta with different regression periods ......")
651
-
652
- #预处理ticker_type
653
- ticker_type=ticker_type_preprocess_mticker_mixed(ticker,ticker_type)
654
-
655
- df=pd.DataFrame()
656
- for t in regression_period:
657
- #计算日历日regression_period对应的交易日数
658
- regtrddays=int(252 / 365 * t)
659
-
660
- #关闭print输出
661
- with HiddenPrints():
662
- df_tmp=get_capm_beta(ticker,start,end,adjust,RF,regtrddays,mktidx,source,ticker_type=ticker_type)
663
-
664
- if df_tmp is None:
665
- break
666
- else:
667
- dft=df_tmp[['beta']]
668
-
669
- #tname="基于"+str(t)+"自然日回归"
670
- tname="基于"+str(t)+"自然日回归"
671
- dft.rename(columns={'beta':tname},inplace=True)
672
- mktidx_name=ticker_name(df_tmp['mktidx'].values[0])
673
-
674
- # 将band_area中的ticker替换为tname
675
- if band_area != '':
676
- for index, item in enumerate(band_area):
677
- if item == t:
678
- band_area[index] = tname
679
-
680
- if len(df)==0: #第一个
681
- df=dft
682
- else:
683
- df=pd.merge(df,dft,how='outer',left_index=True,right_index=True)
684
-
685
- if len(df)==0:
686
- print(" #Error(compare_1ticker_mregression_period): data not available for",ticker,"between",start,end)
687
- return None
688
-
689
- #仅用于绘图和制表
690
- df1=df.copy()
691
- beta_list=list(df1)
692
-
693
- for c in beta_list:
694
- #是否绘制水平线
695
- if df1[c].max() > axhline_value and df1[c].min() < axhline_value:
696
- axhline_label='零线'
697
- #df1.rename(columns={c:"基于"+str(c)+"自然日回归"},inplace=True)
698
-
699
- #共同脚注
700
- footnote1="注:"
701
- footnote2=""
702
-
703
- #footnote3="贝塔系数基于日收益率,无风险利率为"+str(round(RF*100,4))+'%'
704
- footnote3="基于"+mktidx_name+",回归期间为"+str(regression_period)+"个自然日。"
705
-
706
- import datetime; todaydt = datetime.date.today()
707
- footnote4="数据来源: 综合新浪/stooq/Yahoo,"+str(todaydt)+"统计"
708
- if footnote3 !='':
709
- footnotex=footnote1+footnote3+'\n'+footnote4
710
- else:
711
- footnotex=footnote4
712
-
713
- #绘图
714
- if graph:
715
- title_txt="CAPM贝塔系数:"+ticker_name(ticker,ticker_type)
716
- y_label="贝塔系数"
717
-
718
- draw_lines(df1,y_label,x_label=footnotex, \
719
- axhline_value=axhline_value,axhline_label=axhline_label, \
720
- title_txt=title_txt,data_label=False, \
721
- attention_value=attention_value,attention_value_area=attention_value_area, \
722
- attention_point=attention_point,attention_point_area=attention_point_area, \
723
- band_area=band_area, \
724
- annotate=annotate,annotate_value=annotate, \
725
- mark_top=mark_top,mark_bottom=mark_bottom, \
726
- mark_start=mark_start,mark_end=mark_end, \
727
- facecolor=facecolor,loc=loc,precision=4)
728
-
729
- return df
730
-
731
-
732
- #==============================================================================
733
- # 合成函数
734
- #==============================================================================
735
- if __name__=='__main__':
736
- ticker="600519.SS"
737
- ticker=["600519.SS","000858.SZ"]
738
- ticker={'Market':('US','^SPX','中概教培组合'),'EDU':0.5,'TAL':0.3,'TEDU':0.2}
739
-
740
- start="2024-1-1"; end="2024-3-20"
741
-
742
- RF=0.01759
743
- RF=[0.005,0.01759,0.05]
744
-
745
- regression_period=365
746
-
747
- graph=True
748
- annotate=False
749
- source='auto'
750
-
751
- betas=compare_beta_security(ticker,start,end,RF)
752
-
753
- def compare_beta(ticker,start,end, \
754
- adjust='qfq', \
755
- RF=0,regression_period=365, \
756
- attention_value='',attention_value_area='', \
757
- attention_point='',attention_point_area='', \
758
- band_area='', \
759
- graph=True,facecolor='whitesmoke', \
760
- annotate=False,annotate_value=False, \
761
- mark_high=False,mark_low=False, \
762
- mark_start=False,mark_end=False, \
763
- mktidx='auto',source='auto', \
764
- ticker_type='auto',loc="best"):
765
- """
766
- 功能:组合情况,可能多只股票、多个投资组合或投资组合与股票的混合,多个无风险收益率
767
-
768
- """
769
- df=compare_beta_security(ticker=ticker,start=start,end=end, \
770
- adjust=adjust, \
771
- RF=RF,regression_period=regression_period, \
772
- attention_value=attention_value,attention_value_area=attention_value_area, \
773
- attention_point=attention_point,attention_point_area=attention_point_area, \
774
- band_area=band_area, \
775
- graph=graph,facecolor=facecolor, \
776
- annotate=annotate,annotate_value=annotate_value, \
777
- mark_top=mark_high,mark_bottom=mark_low, \
778
- mark_start=mark_start,mark_end=mark_end, \
779
- mktidx=mktidx,source=source, \
780
- ticker_type=ticker_type,loc=loc)
781
-
782
-
783
- def compare_beta_security(ticker,start,end, \
784
- adjust='qfq', \
785
- RF=0,regression_period=365, \
786
- attention_value='',attention_value_area='', \
787
- attention_point='',attention_point_area='', \
788
- band_area='', \
789
- graph=True,facecolor='whitesmoke', \
790
- annotate=False,annotate_value=False, \
791
- mark_top=False,mark_bottom=False, \
792
- mark_start=False,mark_end=False, \
793
- mktidx='auto',source='auto', \
794
- ticker_type='auto',loc="best"):
795
- """
796
- 功能:组合情况,可能多只股票、多个投资组合或投资组合与股票的混合,多个无风险收益率
797
-
798
- """
799
-
800
- #情形1:多个证券
801
- if isinstance(ticker,list):
802
- if len(ticker) > 1:
803
- if isinstance(RF,list):
804
- RF=RF[0]
805
-
806
- df=compare_mticker_1beta(ticker,start,end, \
807
- adjust=adjust, \
808
- RF=RF,regression_period=regression_period, \
809
- attention_value=attention_value,attention_value_area=attention_value_area, \
810
- attention_point=attention_point,attention_point_area=attention_point_area, \
811
- band_area=band_area, \
812
- graph=graph,facecolor=facecolor,loc=loc, \
813
- annotate=annotate,annotate_value=annotate, \
814
- mark_top=mark_top,mark_bottom=mark_bottom, \
815
- mark_start=mark_start,mark_end=mark_end, \
816
- mktidx=mktidx,source=source, \
817
- ticker_type=ticker_type)
818
- return df
819
- else:
820
- #实际上是单个证券
821
- ticker=ticker[0]
822
-
823
- #情形2:1只证券,多个RF。时间区间要尽可能短,不然难以看出差异!
824
- if isinstance(RF,list):
825
- if len(RF) > 1:
826
- df=compare_1ticker_mRF(ticker,start,end, \
827
- adjust=adjust, \
828
- RF=RF,regression_period=regression_period, \
829
- attention_value=attention_value,attention_value_area=attention_value_area, \
830
- attention_point=attention_point,attention_point_area=attention_point_area, \
831
- band_area=band_area, \
832
- graph=graph,facecolor=facecolor,loc=loc, \
833
- annotate=annotate,annotate_value=annotate, \
834
- mark_top=mark_top,mark_bottom=mark_bottom, \
835
- mark_start=mark_start,mark_end=mark_end, \
836
- mktidx=mktidx,source=source, \
837
- ticker_type=ticker_type)
838
- return df
839
- else:
840
- #实际上是单个RF
841
- RF=RF[0]
842
-
843
- #情形3:1只证券,多个回归天数
844
- if isinstance(regression_period,list):
845
- if len(regression_period) > 1:
846
- df=compare_1ticker_mregression_period(ticker,start,end, \
847
- adjust=adjust, \
848
- RF=RF,regression_period=regression_period, \
849
- attention_value=attention_value,attention_value_area=attention_value_area, \
850
- attention_point=attention_point,attention_point_area=attention_point_area, \
851
- band_area=band_area, \
852
- graph=graph,facecolor=facecolor,loc=loc, \
853
- annotate=annotate,annotate_value=annotate, \
854
- mark_top=mark_top,mark_bottom=mark_bottom, \
855
- mark_start=mark_start,mark_end=mark_end, \
856
- mktidx=mktidx,source=source, \
857
- ticker_type=ticker_type)
858
- return df
859
- else:
860
- #实际上是单个regression_period
861
- regression_period=regression_period[0]
862
-
863
- #情形4:1只证券,1个RF,1个回归天数?
864
- df=compare_mticker_1beta(ticker,start,end, \
865
- adjust=adjust, \
866
- RF=RF,regression_period=regression_period, \
867
- attention_value=attention_value,attention_value_area=attention_value_area, \
868
- attention_point=attention_point,attention_point_area=attention_point_area, \
869
- band_area=band_area, \
870
- graph=graph,facecolor=facecolor,loc=loc, \
871
- annotate=annotate,annotate_value=annotate, \
872
- mark_top=mark_top,mark_bottom=mark_bottom, \
873
- mark_start=mark_start,mark_end=mark_end, \
874
- mktidx=mktidx,source=source, \
875
- ticker_type=ticker_type)
876
-
877
- return df
878
-
879
-
880
- #==============================================================================
881
- #==============================================================================
882
-
883
- #==============================================================================
884
- #==============================================================================
885
- #==============================================================================
886
- #==============================================================================
887
- #==============================================================================