siat 3.10.131__py3-none-any.whl → 3.10.132__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- build/lib/build/lib/siat/__init__.py +75 -0
- build/lib/build/lib/siat/allin.py +137 -0
- build/lib/build/lib/siat/assets_liquidity.py +915 -0
- build/lib/build/lib/siat/beta_adjustment.py +1058 -0
- build/lib/build/lib/siat/beta_adjustment_china.py +548 -0
- build/lib/build/lib/siat/blockchain.py +143 -0
- build/lib/build/lib/siat/bond.py +2900 -0
- build/lib/build/lib/siat/bond_base.py +992 -0
- build/lib/build/lib/siat/bond_china.py +100 -0
- build/lib/build/lib/siat/bond_zh_sina.py +143 -0
- build/lib/build/lib/siat/capm_beta.py +783 -0
- build/lib/build/lib/siat/capm_beta2.py +887 -0
- build/lib/build/lib/siat/common.py +5360 -0
- build/lib/build/lib/siat/compare_cross.py +642 -0
- build/lib/build/lib/siat/copyrights.py +18 -0
- build/lib/build/lib/siat/cryptocurrency.py +667 -0
- build/lib/build/lib/siat/economy.py +1471 -0
- build/lib/build/lib/siat/economy2.py +1853 -0
- build/lib/build/lib/siat/esg.py +536 -0
- build/lib/build/lib/siat/event_study.py +815 -0
- build/lib/build/lib/siat/fama_french.py +1521 -0
- build/lib/build/lib/siat/fin_stmt2_yahoo.py +982 -0
- build/lib/build/lib/siat/financial_base.py +1160 -0
- build/lib/build/lib/siat/financial_statements.py +598 -0
- build/lib/build/lib/siat/financials.py +2339 -0
- build/lib/build/lib/siat/financials2.py +1278 -0
- build/lib/build/lib/siat/financials_china.py +4433 -0
- build/lib/build/lib/siat/financials_china2.py +2212 -0
- build/lib/build/lib/siat/fund.py +629 -0
- build/lib/build/lib/siat/fund_china.py +3307 -0
- build/lib/build/lib/siat/future_china.py +551 -0
- build/lib/build/lib/siat/google_authenticator.py +47 -0
- build/lib/build/lib/siat/grafix.py +3636 -0
- build/lib/build/lib/siat/holding_risk.py +867 -0
- build/lib/build/lib/siat/luchy_draw.py +638 -0
- build/lib/build/lib/siat/market_china.py +1168 -0
- build/lib/build/lib/siat/markowitz.py +2363 -0
- build/lib/build/lib/siat/markowitz2.py +3150 -0
- build/lib/build/lib/siat/markowitz2_20250704.py +2969 -0
- build/lib/build/lib/siat/markowitz2_20250705.py +3158 -0
- build/lib/build/lib/siat/markowitz_simple.py +373 -0
- build/lib/build/lib/siat/ml_cases.py +2291 -0
- build/lib/build/lib/siat/ml_cases_example.py +60 -0
- build/lib/build/lib/siat/option_china.py +3069 -0
- build/lib/build/lib/siat/option_pricing.py +1925 -0
- build/lib/build/lib/siat/other_indexes.py +409 -0
- build/lib/build/lib/siat/risk_adjusted_return.py +1576 -0
- build/lib/build/lib/siat/risk_adjusted_return2.py +1900 -0
- build/lib/build/lib/siat/risk_evaluation.py +2218 -0
- build/lib/build/lib/siat/risk_free_rate.py +351 -0
- build/lib/build/lib/siat/sector_china.py +4140 -0
- build/lib/build/lib/siat/security_price2.py +727 -0
- build/lib/build/lib/siat/security_prices.py +3408 -0
- build/lib/build/lib/siat/security_trend.py +402 -0
- build/lib/build/lib/siat/security_trend2.py +646 -0
- build/lib/build/lib/siat/stock.py +4284 -0
- build/lib/build/lib/siat/stock_advice_linear.py +934 -0
- build/lib/build/lib/siat/stock_base.py +26 -0
- build/lib/build/lib/siat/stock_china.py +2095 -0
- build/lib/build/lib/siat/stock_prices_kneighbors.py +910 -0
- build/lib/build/lib/siat/stock_prices_linear.py +386 -0
- build/lib/build/lib/siat/stock_profile.py +707 -0
- build/lib/build/lib/siat/stock_technical.py +3305 -0
- build/lib/build/lib/siat/stooq.py +74 -0
- build/lib/build/lib/siat/transaction.py +347 -0
- build/lib/build/lib/siat/translate.py +5183 -0
- build/lib/build/lib/siat/valuation.py +1378 -0
- build/lib/build/lib/siat/valuation_china.py +2076 -0
- build/lib/build/lib/siat/var_model_validation.py +444 -0
- build/lib/build/lib/siat/yf_name.py +811 -0
- build/lib/siat/__init__.py +75 -0
- build/lib/siat/allin.py +137 -0
- build/lib/siat/assets_liquidity.py +915 -0
- build/lib/siat/beta_adjustment.py +1058 -0
- build/lib/siat/beta_adjustment_china.py +548 -0
- build/lib/siat/blockchain.py +143 -0
- build/lib/siat/bond.py +2900 -0
- build/lib/siat/bond_base.py +992 -0
- build/lib/siat/bond_china.py +100 -0
- build/lib/siat/bond_zh_sina.py +143 -0
- build/lib/siat/capm_beta.py +783 -0
- build/lib/siat/capm_beta2.py +887 -0
- build/lib/siat/common.py +5360 -0
- build/lib/siat/compare_cross.py +642 -0
- build/lib/siat/copyrights.py +18 -0
- build/lib/siat/cryptocurrency.py +667 -0
- build/lib/siat/economy.py +1471 -0
- build/lib/siat/economy2.py +1853 -0
- build/lib/siat/esg.py +536 -0
- build/lib/siat/event_study.py +815 -0
- build/lib/siat/fama_french.py +1521 -0
- build/lib/siat/fin_stmt2_yahoo.py +982 -0
- build/lib/siat/financial_base.py +1160 -0
- build/lib/siat/financial_statements.py +598 -0
- build/lib/siat/financials.py +2339 -0
- build/lib/siat/financials2.py +1278 -0
- build/lib/siat/financials_china.py +4433 -0
- build/lib/siat/financials_china2.py +2212 -0
- build/lib/siat/fund.py +629 -0
- build/lib/siat/fund_china.py +3307 -0
- build/lib/siat/future_china.py +551 -0
- build/lib/siat/google_authenticator.py +47 -0
- build/lib/siat/grafix.py +3636 -0
- build/lib/siat/holding_risk.py +867 -0
- build/lib/siat/luchy_draw.py +638 -0
- build/lib/siat/market_china.py +1168 -0
- build/lib/siat/markowitz.py +2363 -0
- build/lib/siat/markowitz2.py +3150 -0
- build/lib/siat/markowitz2_20250704.py +2969 -0
- build/lib/siat/markowitz2_20250705.py +3158 -0
- build/lib/siat/markowitz_simple.py +373 -0
- build/lib/siat/ml_cases.py +2291 -0
- build/lib/siat/ml_cases_example.py +60 -0
- build/lib/siat/option_china.py +3069 -0
- build/lib/siat/option_pricing.py +1925 -0
- build/lib/siat/other_indexes.py +409 -0
- build/lib/siat/risk_adjusted_return.py +1576 -0
- build/lib/siat/risk_adjusted_return2.py +1900 -0
- build/lib/siat/risk_evaluation.py +2218 -0
- build/lib/siat/risk_free_rate.py +351 -0
- build/lib/siat/sector_china.py +4140 -0
- build/lib/siat/security_price2.py +727 -0
- build/lib/siat/security_prices.py +3408 -0
- build/lib/siat/security_trend.py +402 -0
- build/lib/siat/security_trend2.py +646 -0
- build/lib/siat/stock.py +4284 -0
- build/lib/siat/stock_advice_linear.py +934 -0
- build/lib/siat/stock_base.py +26 -0
- build/lib/siat/stock_china.py +2095 -0
- build/lib/siat/stock_prices_kneighbors.py +910 -0
- build/lib/siat/stock_prices_linear.py +386 -0
- build/lib/siat/stock_profile.py +707 -0
- build/lib/siat/stock_technical.py +3305 -0
- build/lib/siat/stooq.py +74 -0
- build/lib/siat/transaction.py +347 -0
- build/lib/siat/translate.py +5183 -0
- build/lib/siat/valuation.py +1378 -0
- build/lib/siat/valuation_china.py +2076 -0
- build/lib/siat/var_model_validation.py +444 -0
- build/lib/siat/yf_name.py +811 -0
- siat/__init__.py +0 -0
- siat/allin.py +0 -0
- siat/assets_liquidity.py +0 -0
- siat/beta_adjustment.py +0 -0
- siat/beta_adjustment_china.py +0 -0
- siat/blockchain.py +0 -0
- siat/bond.py +0 -0
- siat/bond_base.py +0 -0
- siat/bond_china.py +0 -0
- siat/bond_zh_sina.py +0 -0
- siat/capm_beta.py +0 -0
- siat/capm_beta2.py +0 -0
- siat/common.py +136 -3
- siat/compare_cross.py +0 -0
- siat/copyrights.py +0 -0
- siat/cryptocurrency.py +0 -0
- siat/economy.py +0 -0
- siat/economy2.py +0 -0
- siat/esg.py +0 -0
- siat/event_study.py +0 -0
- siat/exchange_bond_china.pickle +0 -0
- siat/fama_french.py +0 -0
- siat/fin_stmt2_yahoo.py +0 -0
- siat/financial_base.py +0 -0
- siat/financial_statements.py +0 -0
- siat/financials.py +0 -0
- siat/financials2.py +0 -0
- siat/financials_china.py +0 -0
- siat/financials_china2.py +0 -0
- siat/fund.py +0 -0
- siat/fund_china.pickle +0 -0
- siat/fund_china.py +0 -0
- siat/future_china.py +0 -0
- siat/google_authenticator.py +0 -0
- siat/grafix.py +1 -1
- siat/holding_risk.py +0 -0
- siat/luchy_draw.py +0 -0
- siat/market_china.py +1 -1
- siat/markowitz.py +0 -0
- siat/markowitz2.py +240 -39
- siat/markowitz2_20250704.py +2969 -0
- siat/markowitz2_20250705.py +3158 -0
- siat/markowitz_simple.py +0 -0
- siat/ml_cases.py +0 -0
- siat/ml_cases_example.py +0 -0
- siat/option_china.py +0 -0
- siat/option_pricing.py +0 -0
- siat/other_indexes.py +0 -0
- siat/risk_adjusted_return.py +0 -0
- siat/risk_adjusted_return2.py +0 -0
- siat/risk_evaluation.py +0 -0
- siat/risk_free_rate.py +0 -0
- siat/sector_china.py +0 -0
- siat/security_price2.py +0 -0
- siat/security_prices.py +3 -1
- siat/security_trend.py +0 -0
- siat/security_trend2.py +1 -1
- siat/stock.py +4 -2
- siat/stock_advice_linear.py +0 -0
- siat/stock_base.py +0 -0
- siat/stock_china.py +0 -0
- siat/stock_info.pickle +0 -0
- siat/stock_prices_kneighbors.py +0 -0
- siat/stock_prices_linear.py +0 -0
- siat/stock_profile.py +0 -0
- siat/stock_technical.py +0 -0
- siat/stooq.py +0 -0
- siat/transaction.py +0 -0
- siat/translate.py +11 -11
- siat/valuation.py +0 -0
- siat/valuation_china.py +0 -0
- siat/var_model_validation.py +0 -0
- siat/yf_name.py +0 -0
- {siat-3.10.131.dist-info → siat-3.10.132.dist-info}/METADATA +235 -227
- siat-3.10.132.dist-info/RECORD +218 -0
- {siat-3.10.131.dist-info → siat-3.10.132.dist-info}/WHEEL +1 -1
- {siat-3.10.131.dist-info → siat-3.10.132.dist-info/licenses}/LICENSE +0 -0
- siat-3.10.132.dist-info/top_level.txt +4 -0
- siat-3.10.131.dist-info/RECORD +0 -76
- siat-3.10.131.dist-info/top_level.txt +0 -1
@@ -0,0 +1,548 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
"""
|
4
|
+
版权:王德宏,北京外国语大学国际商学院
|
5
|
+
功能:计算CAPM模型贝塔系数的滨田调整,仅限于中国股票
|
6
|
+
版本:2021-11-22
|
7
|
+
"""
|
8
|
+
|
9
|
+
#==============================================================================
|
10
|
+
#关闭所有警告
|
11
|
+
import warnings; warnings.filterwarnings('ignore')
|
12
|
+
from siat.common import *
|
13
|
+
from siat.translate import *
|
14
|
+
from siat.grafix import *
|
15
|
+
from siat.security_prices import *
|
16
|
+
from siat.security_price2 import *
|
17
|
+
from siat.beta_adjustment import *
|
18
|
+
#==============================================================================
|
19
|
+
import matplotlib.pyplot as plt
|
20
|
+
|
21
|
+
#处理绘图汉字乱码问题
|
22
|
+
import sys; czxt=sys.platform
|
23
|
+
if czxt in ['win32','win64']:
|
24
|
+
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置默认字体
|
25
|
+
mpfrc={'font.family': 'SimHei'}
|
26
|
+
|
27
|
+
if czxt in ['darwin']: #MacOSX
|
28
|
+
plt.rcParams['font.family']= ['Heiti TC']
|
29
|
+
mpfrc={'font.family': 'Heiti TC'}
|
30
|
+
|
31
|
+
if czxt in ['linux']: #website Jupyter
|
32
|
+
plt.rcParams['font.family']= ['Heiti TC']
|
33
|
+
mpfrc={'font.family':'Heiti TC'}
|
34
|
+
|
35
|
+
# 解决保存图像时'-'显示为方块的问题
|
36
|
+
plt.rcParams['axes.unicode_minus'] = False
|
37
|
+
|
38
|
+
#==============================================================================
|
39
|
+
if __name__=='__main__':
|
40
|
+
ticker="600606.SS"
|
41
|
+
start='2015-1-1'
|
42
|
+
end='2021-12-31'
|
43
|
+
period_type='annual'
|
44
|
+
period_type='quarterly'
|
45
|
+
period_type='all'
|
46
|
+
|
47
|
+
def prepare_hamada_is_ak(ticker,start,end,period_type='all'):
|
48
|
+
"""
|
49
|
+
从akshare获取利润表数据
|
50
|
+
获取的项目:所得税费用,税前利润
|
51
|
+
"""
|
52
|
+
|
53
|
+
#是否中国股票
|
54
|
+
result,prefix,suffix=split_prefix_suffix(ticker)
|
55
|
+
if not (suffix in ['SS','SZ']):
|
56
|
+
print(" #Error(prepare_hamada_is_ak): not a stock in China",ticker)
|
57
|
+
return None
|
58
|
+
|
59
|
+
#抓取利润表
|
60
|
+
import akshare as ak
|
61
|
+
try:
|
62
|
+
fs = ak.stock_financial_report_sina(stock=prefix, symbol="利润表")
|
63
|
+
except:
|
64
|
+
print(" #Error(prepare_hamada_is_ak): no income stmt available for",ticker)
|
65
|
+
return None
|
66
|
+
|
67
|
+
fs1=fs.drop_duplicates(subset=['报表日期'],keep='first') #去重
|
68
|
+
fs1.sort_values(by=['报表日期'],ascending=True,inplace=True) #升序排序
|
69
|
+
|
70
|
+
#重建索引,排序
|
71
|
+
fs1['date']=pd.to_datetime(fs1['报表日期'])
|
72
|
+
fs1.set_index('date',inplace=True)
|
73
|
+
|
74
|
+
#提取需要的项目:所得税费用,税前利润
|
75
|
+
fs1['Income Tax Expense']=fs1['减:所得税费用'].astype('float')
|
76
|
+
fs1['Income Before Tax']=fs1['四、利润总额'].astype('float')
|
77
|
+
fs1['Net Income']=fs1['五、净利润'].astype('float')
|
78
|
+
fs2=fs1[['Income Before Tax','Income Tax Expense','Net Income']].copy()
|
79
|
+
#fs2['Profit Margin']=fs2['Income Before Tax']-fs2['Income Tax Expense']
|
80
|
+
|
81
|
+
#过滤日期和类型
|
82
|
+
valid,start1,end1=check_period(start,end)
|
83
|
+
if not valid:
|
84
|
+
print(" #Warning(prepare_hamada_is_ak): invalid period",start,end)
|
85
|
+
fs3=fs2
|
86
|
+
else:
|
87
|
+
fs2a=fs2[fs2.index >=start1]
|
88
|
+
fs3=fs2a[fs2a.index <=end1]
|
89
|
+
|
90
|
+
fs3['Year']=fs3.index.year
|
91
|
+
fs3['Month']=fs3.index.month
|
92
|
+
period_type=period_type.lower()
|
93
|
+
if period_type=='annual':
|
94
|
+
fs4=fs3[fs3['Month']==12]
|
95
|
+
else:
|
96
|
+
fs4=fs3
|
97
|
+
fs5=fs4[['Income Before Tax','Income Tax Expense','Net Income']]
|
98
|
+
|
99
|
+
return fs5
|
100
|
+
|
101
|
+
if __name__=='__main__':
|
102
|
+
prepare_hamada_is_ak('600519.SS','2018-1-1','2020-12-31')
|
103
|
+
prepare_hamada_is_ak('600519.SS','2010-1-1','2020-12-31',period_type='annual')
|
104
|
+
|
105
|
+
#==============================================================================
|
106
|
+
if __name__=='__main__':
|
107
|
+
ticker="600519.SS"
|
108
|
+
start='2015-1-1'
|
109
|
+
end='2021-12-31'
|
110
|
+
period_type='annual'
|
111
|
+
period_type='quarterly'
|
112
|
+
period_type='all'
|
113
|
+
|
114
|
+
def prepare_hamada_bs_ak(ticker,start,end,period_type='all'):
|
115
|
+
"""
|
116
|
+
从akshare获取资产负债表数据
|
117
|
+
获取的项目:负债合计,股东权益合计
|
118
|
+
"""
|
119
|
+
|
120
|
+
#是否中国股票
|
121
|
+
result,prefix,suffix=split_prefix_suffix(ticker)
|
122
|
+
if not (suffix in ['SS','SZ']):
|
123
|
+
print(" #Error(prepare_hamada_is_ak): not a stock in China",ticker)
|
124
|
+
return None
|
125
|
+
|
126
|
+
#抓取资产负债表
|
127
|
+
import akshare as ak
|
128
|
+
try:
|
129
|
+
fs = ak.stock_financial_report_sina(stock=prefix, symbol="资产负债表")
|
130
|
+
except:
|
131
|
+
print(" #Error(prepare_hamada_bs_ak): no balance sheet available for",ticker)
|
132
|
+
return None
|
133
|
+
|
134
|
+
fs1=fs.drop_duplicates(subset=['报表日期'],keep='first') #去重
|
135
|
+
fs1.sort_values(by=['报表日期'],ascending=True,inplace=True) #升序排序
|
136
|
+
|
137
|
+
#重建索引,排序
|
138
|
+
fs1['date']=pd.to_datetime(fs1['报表日期'])
|
139
|
+
fs1.set_index('date',inplace=True)
|
140
|
+
|
141
|
+
#提取需要的项目:所得税费用,税前利润
|
142
|
+
fs1['Total Liab']=fs1['负债合计'].astype('float')
|
143
|
+
fs1['Total Stockholder Equity']=fs1['所有者权益(或股东权益)合计'].astype('float')
|
144
|
+
fs1['Total Assets']=fs1['资产总计'].astype('float')
|
145
|
+
fs2=fs1[['Total Liab','Total Stockholder Equity','Total Assets']].copy()
|
146
|
+
#fs2['Total Assets2']=fs2['Total Liab']+fs2['Total Stockholder Equity']
|
147
|
+
|
148
|
+
#过滤日期和类型
|
149
|
+
valid,start1,end1=check_period(start,end)
|
150
|
+
if not valid:
|
151
|
+
print(" #Warning(prepare_hamada_is_ak): invalid period",start,end)
|
152
|
+
fs3=fs2
|
153
|
+
else:
|
154
|
+
fs2a=fs2[fs2.index >=start1]
|
155
|
+
fs3=fs2a[fs2a.index <=end1]
|
156
|
+
|
157
|
+
fs3['Year']=fs3.index.year
|
158
|
+
fs3['Month']=fs3.index.month
|
159
|
+
period_type=period_type.lower()
|
160
|
+
if period_type=='annual':
|
161
|
+
fs4=fs3[fs3['Month']==12]
|
162
|
+
else:
|
163
|
+
fs4=fs3
|
164
|
+
fs5=fs4[['Total Liab','Total Stockholder Equity','Total Assets']]
|
165
|
+
|
166
|
+
return fs5
|
167
|
+
|
168
|
+
if __name__=='__main__':
|
169
|
+
prepare_hamada_bs_ak('600519.SS','2018-1-1','2020-12-31')
|
170
|
+
prepare_hamada_bs_ak('600519.SS','2010-1-1','2020-12-31',period_type='annual')
|
171
|
+
|
172
|
+
#==============================================================================
|
173
|
+
if __name__ =="__main__":
|
174
|
+
ticker='600606.SS'
|
175
|
+
start='2017-1-1'
|
176
|
+
end='2020-9-30'
|
177
|
+
period_type='all'
|
178
|
+
|
179
|
+
def prepare_hamada_ak(ticker,start,end,period_type='all'):
|
180
|
+
"""
|
181
|
+
功能:从akshare下载财报数据,计算hamada模型需要的因子
|
182
|
+
局限:只能下载中国股票的财报
|
183
|
+
输入:股票代码
|
184
|
+
输出:
|
185
|
+
寻找数据项:所得税费用,税前利润,计算实际税率;
|
186
|
+
总负债,所有者权益,计算财务杠杆
|
187
|
+
数据框, CFLB,贝塔Lev对贝塔Unlev的倍数
|
188
|
+
年度列表
|
189
|
+
"""
|
190
|
+
print(" Searching for financial information for",ticker,"...")
|
191
|
+
|
192
|
+
#利润表
|
193
|
+
is1=prepare_hamada_is_ak(ticker,start,end,period_type)
|
194
|
+
|
195
|
+
is1['tax rate']=is1['Income Tax Expense']/is1['Income Before Tax']
|
196
|
+
import pandas as pd
|
197
|
+
tax=pd.DataFrame(is1['tax rate'])
|
198
|
+
|
199
|
+
#资产负债表
|
200
|
+
bs1=prepare_hamada_bs_ak(ticker,start,end,period_type)
|
201
|
+
|
202
|
+
bs1['lev ratio']=bs1['Total Liab']/bs1["Total Stockholder Equity"]
|
203
|
+
lev=pd.DataFrame(bs1['lev ratio'])
|
204
|
+
|
205
|
+
#合成,计算
|
206
|
+
fac=pd.merge(lev,tax,how='left',left_index=True,right_index=True)
|
207
|
+
fac['CFLB%']=1/(1+(1/fac['lev ratio'])*(1/abs(1-fac['tax rate'])))*100
|
208
|
+
fac['lev_unlev']=1+fac['lev ratio']*(1-fac['tax rate'])
|
209
|
+
|
210
|
+
fac['ticker']=ticker
|
211
|
+
|
212
|
+
return fac
|
213
|
+
|
214
|
+
if __name__ =="__main__":
|
215
|
+
prepare_hamada_ak("600519.SS",'2018-1-1','2020-12-31')
|
216
|
+
prepare_hamada_ak("600519.SS",'2018-1-1','2020-12-31','all')
|
217
|
+
|
218
|
+
#==============================================================================
|
219
|
+
if __name__ =="__main__":
|
220
|
+
stkcd='600519.SS'
|
221
|
+
mktidx='000001.SS'
|
222
|
+
start='2010-1-1'
|
223
|
+
end='2020-12-31'
|
224
|
+
|
225
|
+
def get_beta_hamada_china_v0(stkcd,mktidx,start,end,printout=True,graph=True):
|
226
|
+
"""
|
227
|
+
函数功能:使用Hamada(1972)方法,计算无杠杆贝塔系数
|
228
|
+
输入参数:
|
229
|
+
stkcd: 股票代码
|
230
|
+
mktidx: 指数代码
|
231
|
+
输出数据:显示CAPM市场模型回归的beta, 以及调整后的beta系数
|
232
|
+
返回数据:CAPM的beta, Hamada beta,CFLB(债务融资对CAPM beta系数的贡献率)
|
233
|
+
注:本函数废弃
|
234
|
+
"""
|
235
|
+
|
236
|
+
#计算Hamada参数,并返回可用的年度列表
|
237
|
+
fac=prepare_hamada_ak(stkcd,start,end,period_type='annual')
|
238
|
+
if fac is None:
|
239
|
+
print("#Error(get_beta_hamada_china): no financial info available for",stkcd)
|
240
|
+
return None
|
241
|
+
fac['year']=fac.index.strftime("%Y")
|
242
|
+
yearlist=list(fac['year'])
|
243
|
+
|
244
|
+
#读取股价并准备好收益率数据
|
245
|
+
try:
|
246
|
+
R=prepare_capm(stkcd,mktidx,start,end)
|
247
|
+
except:
|
248
|
+
print(" #Error(get_beta_hamada_china): preparing CAPM data failed!")
|
249
|
+
print(" Info:",stkcd,mktidx,yearlist)
|
250
|
+
return None
|
251
|
+
|
252
|
+
if (R is None):
|
253
|
+
print(" #Error(get_beta_hamada_china): no CAPM beta calculated")
|
254
|
+
return None
|
255
|
+
if (len(R) == 0):
|
256
|
+
print(" #Error(get_beta_hamada_china): no CAPM beta available")
|
257
|
+
return None
|
258
|
+
|
259
|
+
R=R.dropna()
|
260
|
+
|
261
|
+
#用于保存beta(CAPM)和beta(Hamada)
|
262
|
+
import pandas as pd
|
263
|
+
betas=pd.DataFrame(columns=('Year','Beta(CAPM)','Beta(Unlevered)','CFLB%', \
|
264
|
+
'lev ratio','tax rate'))
|
265
|
+
|
266
|
+
from scipy import stats
|
267
|
+
for year in yearlist:
|
268
|
+
r=R[R['Year']==year]
|
269
|
+
if len(r) != 0:
|
270
|
+
output=stats.linregress(r['Close_x'],r['Close_y'])
|
271
|
+
(beta_capm,alpha,r_value,p_value,std_err)=output
|
272
|
+
|
273
|
+
#Hamada无杠杆因子
|
274
|
+
lev_unlev=fac[fac['year']==year]['lev_unlev'].values[0]
|
275
|
+
beta_hamada=beta_capm/lev_unlev
|
276
|
+
cflb=fac[fac['year']==year]['CFLB%'].values[0]
|
277
|
+
|
278
|
+
lev_ratio=fac[fac['year']==year]['lev ratio'].values[0]
|
279
|
+
tax_rate=fac[fac['year']==year]['tax rate'].values[0]
|
280
|
+
row=pd.Series({'Year':year,'Beta(CAPM)':beta_capm, \
|
281
|
+
'Beta(Unlevered)':beta_hamada,'CFLB%':cflb, \
|
282
|
+
'lev ratio':lev_ratio,'tax rate':tax_rate})
|
283
|
+
try:
|
284
|
+
betas=betas.append(row,ignore_index=True)
|
285
|
+
except:
|
286
|
+
betas=betas._append(row,ignore_index=True)
|
287
|
+
|
288
|
+
betas.set_index(["Year"], inplace=True)
|
289
|
+
|
290
|
+
import datetime as dt; today=dt.date.today()
|
291
|
+
if printout == True:
|
292
|
+
pd.set_option('display.max_columns', 1000)
|
293
|
+
pd.set_option('display.width', 1000)
|
294
|
+
pd.set_option('display.max_colwidth', 1000)
|
295
|
+
print("\n=有杠杆(CAPM)对比无杠杆(Unlevered)贝塔系数=")
|
296
|
+
betas1=betas[['Beta(CAPM)','Beta(Unlevered)','CFLB%']]
|
297
|
+
print(betas1)
|
298
|
+
print("\n*** 数据来源:新浪,"+str(today))
|
299
|
+
|
300
|
+
if graph == True:
|
301
|
+
model="有/无杠杆贝塔系数趋势对比"
|
302
|
+
draw2_betas(model,mktidx,stkcd,betas)
|
303
|
+
|
304
|
+
#绘制CFLB
|
305
|
+
if len(betas)<=1: return betas
|
306
|
+
|
307
|
+
plt.plot(betas['CFLB%'],marker='o',color='red',lw=3,label='CFLB%')
|
308
|
+
|
309
|
+
cflb_mean=betas['CFLB%'].mean()
|
310
|
+
plt.axhline(y=cflb_mean,color='b',linestyle=':',label='均值线')
|
311
|
+
|
312
|
+
title1=ticker_name(stkcd)+": 财务杠杆对贝塔系数的贡献度(CFLB)"+ \
|
313
|
+
"\n(基于"+ticker_name(mktidx)+")"
|
314
|
+
plt.title(title1,fontsize=12,fontweight='bold')
|
315
|
+
plt.ylabel("CFLB%",fontsize=12,fontweight='bold')
|
316
|
+
|
317
|
+
|
318
|
+
footnote="注:CFLB均值="+str(round(cflb_mean,2))+'%\n数据来源:新浪,'+str(today)
|
319
|
+
plt.xlabel(footnote)
|
320
|
+
|
321
|
+
plt.grid(ls='-.')
|
322
|
+
#查看可用的样式:print(plt.style.available)
|
323
|
+
#样式:bmh(好),classic,ggplot(好,图大),tableau-colorblind10,
|
324
|
+
#样式:seaborn-bright,seaborn-poster,seaborn-whitegrid
|
325
|
+
plt.style.use('bmh')
|
326
|
+
plt.legend(loc='best')
|
327
|
+
plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
|
328
|
+
plt.gca().set_facecolor('whitesmoke')
|
329
|
+
|
330
|
+
#plt.xticks(rotation=30)
|
331
|
+
plt.show()
|
332
|
+
|
333
|
+
return betas
|
334
|
+
|
335
|
+
if __name__=='__main__':
|
336
|
+
betas=get_beta_hamada_china('000002.SZ','399001.SZ','2000-1-1','2021-12-31')
|
337
|
+
|
338
|
+
#==============================================================================
|
339
|
+
def draw_hamada_factors_china(stkcd,mktidx,betas):
|
340
|
+
"""
|
341
|
+
功能:绘制Hamada模型因子的变化折线图,企业实际所得税税率,资产负债率,CFLB
|
342
|
+
"""
|
343
|
+
if len(betas)<=1: return
|
344
|
+
|
345
|
+
#计算资产负债率:由 D/E到 D/(A=D+E)
|
346
|
+
betas['Debt/Assets%']=1/(1+1/(betas['lev ratio']/100))*100
|
347
|
+
|
348
|
+
#fig=plt.figure(figsize=(12.8,6.4))
|
349
|
+
fig=plt.figure()
|
350
|
+
ax1=fig.add_subplot(111)
|
351
|
+
ax1.plot(betas['CFLB%'],marker='o',color='green',lw=3,label='CFLB%')
|
352
|
+
ax1.plot(betas['Debt/Assets%'],marker='o',color='red',lw=2,ls='--', \
|
353
|
+
label='资产负债率%')
|
354
|
+
ax1.set_ylabel("CFLB%, 资产负债率%")
|
355
|
+
ax1.legend(loc='upper left')
|
356
|
+
ax1.set_xticklabels(betas.index,rotation=45)
|
357
|
+
|
358
|
+
ax2=ax1.twinx()
|
359
|
+
ax2.plot(betas['tax rate'],marker='o',color='black',lw=2,ls='-.', \
|
360
|
+
label='实际税率%')
|
361
|
+
ax2.set_ylabel('实际税率%')
|
362
|
+
ax2.legend(loc='lower right')
|
363
|
+
ax2.set_xticklabels(betas.index,rotation=45)
|
364
|
+
|
365
|
+
title1=ticker_name(stkcd)+": 滨田因子对贝塔系数的影响"+ \
|
366
|
+
"\n(基于"+ticker_name(mktidx)+")"
|
367
|
+
plt.title(title1,fontsize=12,fontweight='bold')
|
368
|
+
plt.style.use('ggplot')
|
369
|
+
|
370
|
+
plt.gca().set_facecolor('whitesmoke')
|
371
|
+
plt.show()
|
372
|
+
|
373
|
+
return
|
374
|
+
|
375
|
+
if __name__ =="__main__":
|
376
|
+
draw_hamada_factors_china('000002.SZ','399001.SZ',betas)
|
377
|
+
#==============================================================================
|
378
|
+
#==============================================================================
|
379
|
+
#==============================================================================
|
380
|
+
if __name__ =="__main__":
|
381
|
+
stkcd='600606.SS'
|
382
|
+
mktidx='000001.SS'
|
383
|
+
start='2018-1-1'
|
384
|
+
end='2021-9-30'
|
385
|
+
period_type='all'
|
386
|
+
|
387
|
+
def get_beta_hamada_china(stkcd,mktidx,start,end,period_type='all', \
|
388
|
+
printout=True,graph=True):
|
389
|
+
"""
|
390
|
+
函数功能:使用Hamada(1972)方法,计算无杠杆贝塔系数,绘图,仅限于中国股票
|
391
|
+
输入参数:
|
392
|
+
stkcd: 股票代码
|
393
|
+
mktidx: 指数代码
|
394
|
+
输出数据:显示CAPM市场模型回归的beta, 以及调整后的beta系数
|
395
|
+
返回数据:CAPM的beta, Hamada beta,CFLB(债务融资对CAPM beta系数的贡献率)
|
396
|
+
特点:既能处理年报,也能处理季报
|
397
|
+
"""
|
398
|
+
|
399
|
+
#计算Hamada参数,并返回可用的年度列表
|
400
|
+
fac=prepare_hamada_ak(stkcd,start,end,period_type)
|
401
|
+
if fac is None:
|
402
|
+
print(" #Error(get_beta_hamada_china2): no financial info available for",stkcd)
|
403
|
+
return None
|
404
|
+
|
405
|
+
datecvt=lambda x: str(x.strftime("%Y-%m-%d"))
|
406
|
+
fac['fsdate']=fac.index.date
|
407
|
+
fac['fsdate']=fac['fsdate'].apply(datecvt)
|
408
|
+
|
409
|
+
#读取股价并准备好收益率数据
|
410
|
+
try:
|
411
|
+
R=prepare_capm(stkcd,mktidx,start,end)
|
412
|
+
except:
|
413
|
+
print(" #Error(get_beta_hamada_china): preparing CAPM data failed for",stkcd,mktidx)
|
414
|
+
return None
|
415
|
+
if R is None:
|
416
|
+
print(" #Error(get_beta_hamada_china): info in CAPM inaccessible for",stkcd,mktidx)
|
417
|
+
return None
|
418
|
+
if len(R) == 0:
|
419
|
+
print(" #Error(get_beta_hamada_china): zero record found in CAPM for",stkcd,mktidx)
|
420
|
+
return None
|
421
|
+
|
422
|
+
R=R.dropna()
|
423
|
+
R['prcdate']=R.index.date
|
424
|
+
R['prcdate']=R['prcdate'].apply(datecvt)
|
425
|
+
|
426
|
+
#用于保存beta(CAPM)和beta(Hamada)
|
427
|
+
import pandas as pd
|
428
|
+
betas=pd.DataFrame(columns=('Date','Beta(CAPM)','Beta(Unlevered)','CFLB%'))
|
429
|
+
fsdatelist=list(fac['fsdate'])
|
430
|
+
from scipy import stats
|
431
|
+
for d in fsdatelist:
|
432
|
+
dstart=date_adjust(d,adjust=-365)
|
433
|
+
r=R[R['prcdate'] >= dstart]
|
434
|
+
r=r[r['prcdate'] <= d]
|
435
|
+
if len(r) != 0:
|
436
|
+
output=stats.linregress(r['Close_x'],r['Close_y'])
|
437
|
+
(beta_capm,alpha,r_value,p_value,std_err)=output
|
438
|
+
|
439
|
+
#Hamada无杠杆因子
|
440
|
+
lev_unlev=fac[fac['fsdate']==d]['lev_unlev'].values[0]
|
441
|
+
beta_hamada=beta_capm/lev_unlev
|
442
|
+
cflb=fac[fac['fsdate']==d]['CFLB%'].values[0]
|
443
|
+
|
444
|
+
row=pd.Series({'Date':d,'Beta(CAPM)':beta_capm, \
|
445
|
+
'Beta(Unlevered)':beta_hamada,'CFLB%':cflb})
|
446
|
+
try:
|
447
|
+
betas=betas.append(row,ignore_index=True)
|
448
|
+
except:
|
449
|
+
betas=betas._append(row,ignore_index=True)
|
450
|
+
betas.set_index(["Date"], inplace=True)
|
451
|
+
|
452
|
+
#打印
|
453
|
+
import datetime as dt; today=dt.date.today()
|
454
|
+
if printout == True:
|
455
|
+
pd.set_option('display.max_columns', 1000)
|
456
|
+
pd.set_option('display.width', 1000)
|
457
|
+
pd.set_option('display.max_colwidth', 1000)
|
458
|
+
print("\n=有杠杆(CAPM)对比无杠杆(Unlevered)贝塔系数=")
|
459
|
+
print(betas)
|
460
|
+
print("\n*** 数据来源:新浪,"+str(today))
|
461
|
+
|
462
|
+
#绘图:两种杠杆对比图,CFLB图
|
463
|
+
if graph == True:
|
464
|
+
if len(betas)<=1:
|
465
|
+
print(" #Notice(get_beta_hamada_china): too few info for graphics of",stkcd)
|
466
|
+
return betas
|
467
|
+
|
468
|
+
#图1:绘制Hamada对比图
|
469
|
+
titletxt=ticker_name(stkcd)+":CAPM/无杠杆贝塔系数对比"
|
470
|
+
import datetime; today = datetime.date.today()
|
471
|
+
footnote="注: 基于"+ticker_name(mktidx)
|
472
|
+
footnote2="\n数据来源: 新浪,"+str(today)
|
473
|
+
#draw2_betas(model,mktidx,stkcd,betas)
|
474
|
+
plot_2lines(betas,'Beta(CAPM)','CAPM贝塔系数', \
|
475
|
+
betas,'Beta(Unlevered)','无杠杆贝塔系数', \
|
476
|
+
'贝塔系数',titletxt,footnote+footnote2,hline=1,vline=0,resample_freq='H')
|
477
|
+
|
478
|
+
#图2:绘制CFLB单图
|
479
|
+
"""
|
480
|
+
plt.plot(betas['CFLB%'],marker='o',color='red',lw=3,label='CFLB%')
|
481
|
+
"""
|
482
|
+
#均值
|
483
|
+
cflb_avg=betas['CFLB%'].mean()
|
484
|
+
cflb_avg_txt=',CFLB%均值为'+str(round(cflb_avg,1))+'%'
|
485
|
+
"""
|
486
|
+
plt.axhline(y=cflb_avg,color='b',linestyle=':',label=cflb_avg_txt)
|
487
|
+
|
488
|
+
#plt.title(title1,fontsize=12,fontweight='bold')
|
489
|
+
plt.title(title1)
|
490
|
+
#plt.ylabel("CFLB %",fontsize=12,fontweight='bold')
|
491
|
+
plt.xlabel(footnote+footnote2)
|
492
|
+
|
493
|
+
plt.grid(ls='-.')
|
494
|
+
#查看可用的样式:print(plt.style.available)
|
495
|
+
#样式:bmh(好),classic,ggplot(好,图大),tableau-colorblind10,
|
496
|
+
#样式:seaborn-bright,seaborn-poster,seaborn-whitegrid
|
497
|
+
plt.style.use('bmh')
|
498
|
+
plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
|
499
|
+
plt.legend(loc='best')
|
500
|
+
plt.show(); plt.close()
|
501
|
+
"""
|
502
|
+
titletxt=ticker_name(stkcd)+": 财务杠杆对于贝塔系数的贡献度(CFLB)"
|
503
|
+
plot_line(betas,'CFLB%','CFLB%','财务杠杆对于贝塔系数的贡献度%',titletxt, \
|
504
|
+
footnote+cflb_avg_txt+footnote2,power=6)
|
505
|
+
|
506
|
+
#图3:绘制CFLB+财务杠杆双图
|
507
|
+
df1=betas; df2=fac.set_index(["fsdate"])
|
508
|
+
ticker1=ticker2=stkcd
|
509
|
+
colname1='CFLB%'; colname2='lev ratio'
|
510
|
+
label1='CFLB%'; label2='财务杠杆'
|
511
|
+
titletxt=ticker_name(stkcd)+": CFLB与财务杠杆之间的关系"
|
512
|
+
footnote='注: 这里的财务杠杆使用的是负债/所有者权益'
|
513
|
+
|
514
|
+
plot_line2_twinx(df1,ticker1,colname1,label1,df2,ticker2,colname2,label2, \
|
515
|
+
titletxt,footnote+footnote2)
|
516
|
+
|
517
|
+
#图4:绘制CFLB+税率双图
|
518
|
+
#df1=betas; df2=fac.set_index(["fsdate"])
|
519
|
+
#ticker1=ticker2=stkcd
|
520
|
+
colname1='CFLB%'; colname2='tax rate'
|
521
|
+
label1='CFLB%'; label2='实际税率'
|
522
|
+
titletxt=ticker_name(stkcd)+": CFLB与税率之间的关系"
|
523
|
+
footnote='注: 这里使用的是实际税率'
|
524
|
+
|
525
|
+
plot_line2_twinx(df1,ticker1,colname1,label1,df2,ticker2,colname2,label2, \
|
526
|
+
titletxt,footnote+footnote2)
|
527
|
+
|
528
|
+
return betas
|
529
|
+
|
530
|
+
if __name__=='__main__':
|
531
|
+
betas1=get_beta_hamada_china('000002.SZ','399001.SZ','2010-1-1','2021-12-31','annual')
|
532
|
+
|
533
|
+
#==============================================================================
|
534
|
+
#==============================================================================
|
535
|
+
#==============================================================================
|
536
|
+
|
537
|
+
|
538
|
+
|
539
|
+
|
540
|
+
|
541
|
+
|
542
|
+
|
543
|
+
|
544
|
+
|
545
|
+
|
546
|
+
|
547
|
+
|
548
|
+
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
本模块功能:区块链的创建与查询,仅限测试使用
|
4
|
+
所属工具包:证券投资分析工具SIAT
|
5
|
+
SIAT:Security Investment Analysis Tool
|
6
|
+
创建日期:2018年9月18日
|
7
|
+
最新修订日期:2020年2月7日
|
8
|
+
作者:王德宏 (WANG Dehong, Peter)
|
9
|
+
作者单位:北京外国语大学国际商学院
|
10
|
+
版权所有:王德宏
|
11
|
+
用途限制:仅限研究与教学使用,不可商用!商用需要额外授权。
|
12
|
+
特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
|
13
|
+
"""
|
14
|
+
|
15
|
+
import hashlib as hasher
|
16
|
+
class Block:
|
17
|
+
"""
|
18
|
+
定义一个区块链中的区块:
|
19
|
+
为了保证整个区块链的完整性,每一个区块都有一个唯一的哈希值,用于自我标识。
|
20
|
+
比如比特币,每一个区块的哈希值是由区块的索引、时间戳、数据以及前一个区块的哈希,
|
21
|
+
经过加密后得到的。其中,数据可以选取任意值。
|
22
|
+
"""
|
23
|
+
def __init__(self, index, timestamp, data, previous_hash):
|
24
|
+
self.index = index
|
25
|
+
self.timestamp = timestamp
|
26
|
+
self.data = data
|
27
|
+
self.previous_hash = previous_hash
|
28
|
+
self.hash = self.hash_block()
|
29
|
+
|
30
|
+
def hash_block(self):
|
31
|
+
sha = hasher.sha256()
|
32
|
+
sha.update((str(self.index) +
|
33
|
+
str(self.timestamp) +
|
34
|
+
str(self.data) +
|
35
|
+
str(self.previous_hash)).encode('utf-8'))
|
36
|
+
return sha.hexdigest()
|
37
|
+
|
38
|
+
|
39
|
+
import datetime as date
|
40
|
+
def create_genesis_block():
|
41
|
+
"""
|
42
|
+
创建一个区块链中的创世区块:即第一个区块
|
43
|
+
这个区块的索引为0,此外,它所包含的数据以及前一个区块的哈希值都是一个任意的值。
|
44
|
+
"""
|
45
|
+
# Manually construct ablock with
|
46
|
+
# index zero and arbitrary previous hash
|
47
|
+
return Block(0, date.datetime.now(), "RootBlock", "0")
|
48
|
+
|
49
|
+
|
50
|
+
def next_block(last_block,this_data):
|
51
|
+
"""
|
52
|
+
增加一个区块:
|
53
|
+
还需要一个函数来生成链上更多的区块。该函数将链上前一个区块作为参数,
|
54
|
+
为后面的区块生成数据,并返回具有带有数据的新区块。
|
55
|
+
当生成的新区块包含了前一个区块的哈希值,区块链的完整性就会随着每个区块的增加而增加。
|
56
|
+
这样的操作虽然看起来有点复杂,但如果不这么做,其他人就会很容易篡改链上的数据,
|
57
|
+
甚至把整条链都给换了。所以,链上区块的哈希值就充当了密码证明,
|
58
|
+
确保区块一旦被添加到区块链上,就不能被替换或者删除。
|
59
|
+
"""
|
60
|
+
this_index =last_block.index + 1
|
61
|
+
this_timestamp =date.datetime.now()
|
62
|
+
#this_data = "Hey! I'm block " +str(this_index)
|
63
|
+
this_hash = last_block.hash
|
64
|
+
return Block(this_index, this_timestamp, this_data, this_hash)
|
65
|
+
|
66
|
+
|
67
|
+
def create_block_chain(transactions):
|
68
|
+
"""
|
69
|
+
创建一个实际的区块链例子并打印出来
|
70
|
+
"""
|
71
|
+
# Create the blockchain and add the genesis block
|
72
|
+
blockchain = [create_genesis_block()]
|
73
|
+
previous_block = blockchain[0]
|
74
|
+
# How many blocks should we add to the chain after the genesis block
|
75
|
+
num_of_blocks_to_add= len(transactions)
|
76
|
+
# Add blocks to the chain
|
77
|
+
for i in range(0, num_of_blocks_to_add):
|
78
|
+
block_to_add= next_block(previous_block,transactions[i])
|
79
|
+
blockchain.append(block_to_add)
|
80
|
+
previous_block = block_to_add
|
81
|
+
# Tell everyone about it!
|
82
|
+
print ("#{}区块已加入区块链!".format(block_to_add.index))
|
83
|
+
print ("上家哈希值:{}".format(block_to_add.previous_hash))
|
84
|
+
print ("区块哈希值:{}".format(block_to_add.hash))
|
85
|
+
print ("本区块内容:{}".format(block_to_add.data))
|
86
|
+
print ("本块时间戳:{}\n".format(block_to_add.timestamp))
|
87
|
+
|
88
|
+
return blockchain
|
89
|
+
|
90
|
+
if __name__=='__main__':
|
91
|
+
transactions=["交易1:开户","交易2:存款1万元","交易3:取款5千元"]
|
92
|
+
blockchain=create_block_chain(transactions)
|
93
|
+
|
94
|
+
|
95
|
+
def append_block_chain(blockchain,transactions):
|
96
|
+
"""
|
97
|
+
增加区块至现有的一个区块链
|
98
|
+
"""
|
99
|
+
l = len(blockchain)
|
100
|
+
previous_block = blockchain[l-1]
|
101
|
+
# How many blocks should we add to the chain after the genesis block
|
102
|
+
num_of_blocks_to_add= len(transactions)
|
103
|
+
# Add blocks to the chain
|
104
|
+
for i in range(0, num_of_blocks_to_add):
|
105
|
+
block_to_add= next_block(previous_block,transactions[i])
|
106
|
+
blockchain.append(block_to_add)
|
107
|
+
previous_block = block_to_add
|
108
|
+
# Tell everyone about it!
|
109
|
+
print ("#{}区块已加入区块链!".format(block_to_add.index))
|
110
|
+
print ("上家哈希值:{}".format(block_to_add.previous_hash))
|
111
|
+
print ("区块哈希值:{}".format(block_to_add.hash))
|
112
|
+
print ("本区块内容:{}".format(block_to_add.data))
|
113
|
+
print ("本块时间戳:{}\n".format(block_to_add.timestamp))
|
114
|
+
|
115
|
+
return blockchain
|
116
|
+
|
117
|
+
if __name__=='__main__':
|
118
|
+
transactions2=["交易A:转账3千元","交易B:取款1千元"]
|
119
|
+
blockchain=append_block_chain(blockchain,transactions2)
|
120
|
+
|
121
|
+
|
122
|
+
def search_block_chain(blockchain,word):
|
123
|
+
"""
|
124
|
+
搜索一个区块链的数据内容
|
125
|
+
"""
|
126
|
+
found=0
|
127
|
+
# 遍历整个区块链
|
128
|
+
for i in range(0, len(blockchain)):
|
129
|
+
data=blockchain[i].data
|
130
|
+
if data.find(word) != -1:
|
131
|
+
found=found+1
|
132
|
+
print ("找到区块#{}".format(blockchain[i].index))
|
133
|
+
#print ("上家哈希值:{}".format(blockchain[i].previous_hash))
|
134
|
+
#print ("区块哈希值:{}".format(blockchain[i].hash))
|
135
|
+
print ("本区块内容:{}".format(blockchain[i].data))
|
136
|
+
print ("本块时间戳:{}\n".format(blockchain[i].timestamp))
|
137
|
+
if found == 0: print("抱歉,区块链中未能找到搜索关键字:"+word)
|
138
|
+
else: print("共找到"+str(found)+"个区块含有搜索关键字:"+word)
|
139
|
+
|
140
|
+
return
|
141
|
+
|
142
|
+
if __name__=='__main__':
|
143
|
+
search_block_chain(blockchain,"万元")
|