siat 3.1.3__py3-none-any.whl → 3.1.4__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/fund_china.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
所属工具包:证券投资分析工具SIAT
|
5
5
|
SIAT:Security Investment Analysis Tool
|
6
6
|
创建日期:2020年10月17日
|
7
|
-
最新修订日期:
|
7
|
+
最新修订日期:2024年5月26日
|
8
8
|
作者:王德宏 (WANG Dehong, Peter)
|
9
9
|
作者单位:北京外国语大学国际商学院
|
10
10
|
版权所有:王德宏
|
@@ -20,10 +20,25 @@ from siat.translate import *
|
|
20
20
|
from siat.grafix import *
|
21
21
|
from siat.bond_base import *
|
22
22
|
#==============================================================================
|
23
|
+
def compare_fund_holding_china(ticker,quarters,rank=10):
|
24
|
+
"""
|
25
|
+
功能:套壳函数fund_stock_holding_compare_china
|
26
|
+
"""
|
27
|
+
if len(quarters) < 2:
|
28
|
+
print(" #Warning(compare_fund_holding_china): need 2 quarters to compare at",quarters)
|
29
|
+
return None
|
30
|
+
if quarters[0] >= quarters[1]:
|
31
|
+
print(" #Warning(compare_fund_holding_china):",quarters[0],"is supposed to be earlier than",quarters[1])
|
32
|
+
return None
|
33
|
+
|
34
|
+
df=fund_stock_holding_compare_china(fund=ticker,quarter1=quarters[0],quarter2=quarters[1],rank=rank)
|
35
|
+
|
36
|
+
return df
|
37
|
+
|
23
38
|
if __name__=='__main__':
|
24
39
|
fund='000592.SS'
|
25
|
-
quarter1='
|
26
|
-
quarter2='
|
40
|
+
quarter1='2023Q4'
|
41
|
+
quarter2='2024Q1'
|
27
42
|
|
28
43
|
df=fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10)
|
29
44
|
|
@@ -36,7 +51,7 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
|
|
36
51
|
quarter1,str,靠前的季度, 格式为 'YYYYQ1',例如: '2021Q2';
|
37
52
|
quarter2,str,靠后的季度, 格式为 'YYYYQ1',例如: '2021Q2';
|
38
53
|
"""
|
39
|
-
print("Searching fund
|
54
|
+
print("Searching fund holding info, which may take time, please wait ...\n")
|
40
55
|
|
41
56
|
import akshare as ak
|
42
57
|
import pandas as pd
|
@@ -97,6 +112,7 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
|
|
97
112
|
|
98
113
|
df1 = df1[['股票代码', '股票名称','持股数','持仓市值','占净值比例']]
|
99
114
|
df1 = df1.rename(columns={'持股数':s1_share,'持仓市值':s1_value,'占净值比例':s1_ratio})
|
115
|
+
|
100
116
|
df2 =data[data['季度']==s2]
|
101
117
|
if len(df2)==0:
|
102
118
|
print(" #Error(fund_stock_holding_compare_china): no data available for",s2)
|
@@ -105,10 +121,10 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
|
|
105
121
|
df2 = df2[['股票代码', '股票名称','持股数','持仓市值','占净值比例']]
|
106
122
|
df2 = df2.rename(columns={'持股数':s2_share,'持仓市值':s2_value,'占净值比例':s2_ratio})
|
107
123
|
|
108
|
-
df_merge = pd.merge(df1,df2,on='股票代码',how='outer')
|
124
|
+
df_merge = pd.merge(df1,df2,on=['股票代码','股票名称'],how='outer')
|
109
125
|
|
110
|
-
# Q2 和 Q4,即半年度和年度报告,是需要披露全部持仓的
|
111
|
-
# 合并后,在dataframe 中 NaN 的数据应为 0
|
126
|
+
# Q2 和 Q4,即半年度和年度报告,是需要披露全部持仓的
|
127
|
+
# 合并后,在dataframe 中 NaN 的数据应为 0
|
112
128
|
|
113
129
|
if s1.endswith('Q2') or s1.endswith('Q4'):
|
114
130
|
df_merge[s1_share] = df_merge[s1_share].fillna(0)
|
@@ -123,17 +139,19 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
|
|
123
139
|
df_merge.fillna(0,inplace=True)
|
124
140
|
|
125
141
|
df_merge['持股数变化'] = df_merge[s2_share] - df_merge[s1_share]
|
142
|
+
df_merge['持仓比例变化'] = df_merge[s2_ratio] - df_merge[s1_ratio]
|
143
|
+
df_merge['持仓市值变化'] = df_merge[s2_value] - df_merge[s1_value]
|
126
144
|
df_merge = df_merge.sort_values(s2_value,ascending=False)
|
127
145
|
|
128
|
-
df_merge['股票名称'] = df_merge['股票名称_y']
|
129
|
-
df_merge.loc[df_merge['股票名称'].isna(),'股票名称'] = df_merge.loc[df_merge['股票名称'].isna(),'股票名称_x']
|
130
|
-
df_merge = df_merge[['
|
146
|
+
#df_merge['股票名称'] = df_merge['股票名称_y']
|
147
|
+
#df_merge.loc[df_merge['股票名称'].isna(),'股票名称'] = df_merge.loc[df_merge['股票名称'].isna(),'股票名称_x']
|
148
|
+
df_merge = df_merge[['股票名称','股票代码',s1_share,s2_share,'持股数变化',s1_ratio,s2_ratio,'持仓比例变化',s1_value,s2_value,'持仓市值变化']]
|
131
149
|
|
132
150
|
df_merge.reset_index(drop=True,inplace=True)
|
133
151
|
if rank>0:
|
134
152
|
df=df_merge.head(rank)
|
135
153
|
else:
|
136
|
-
df=df_merge.
|
154
|
+
df=df_merge.tail(-rank)
|
137
155
|
"""
|
138
156
|
#持股数和持仓比例取整数
|
139
157
|
df.fillna(0)
|
@@ -177,29 +195,69 @@ def fund_stock_holding_compare_china(fund,quarter1,quarter2,rank=10):
|
|
177
195
|
|
178
196
|
# 替换空值
|
179
197
|
df.fillna('---')
|
180
|
-
|
198
|
+
"""
|
181
199
|
print("===== 中国基金持仓股票分析:"+name+','+s1+"对比"+s2,"(按后者持仓比例高低排列,"+order+str(rank)+"名股票) =====\n")
|
182
200
|
print(df.to_string(index=False))
|
183
201
|
import datetime; today = datetime.date.today()
|
184
202
|
print("\n*** 注:持股数为万股,持仓市值为万元,持仓比例为占基金资产净值比例%,包括A股与非A股")
|
185
203
|
print(" 数据来源:天天基金/东方财富, 期间持仓股票总计"+str(len(df_merge))+"只,",today)
|
204
|
+
"""
|
205
|
+
titletxt="基金持仓分析:"+name+','+s1+"对比"+s2+"(按后者持仓比例降序排列,"+order+str(rank)+"名成份证券)"
|
206
|
+
|
207
|
+
footnote1="【注】持仓数为万股,持仓市值为万元,持仓比例为占基金资产净值比例%;"
|
208
|
+
footnote2="期间内(曾经)持仓证券数合计"+str(len(df_merge))+"只"+'\n'
|
209
|
+
import datetime; todaydt = datetime.date.today()
|
210
|
+
footnote9="数据来源:天天基金/东方财富,"+str(todaydt)+"统计"
|
211
|
+
footnote=footnote1+footnote2+footnote9
|
212
|
+
|
213
|
+
#调整字段顺序
|
214
|
+
collist=list(df)
|
215
|
+
df['序号']=df.index + 1
|
216
|
+
df=df[['序号']+collist]
|
217
|
+
"""
|
218
|
+
shares=[]; ratios=[]; values=[]
|
219
|
+
for c in collist:
|
220
|
+
if "持股数" in c:
|
221
|
+
shares=shares+[c]
|
222
|
+
if "持仓比例" in c:
|
223
|
+
ratios=ratios+[c]
|
224
|
+
if "持仓市值" in c:
|
225
|
+
values=values+[c]
|
226
|
+
collist1=['序号','股票名称','股票代码']+shares+ratios+values
|
227
|
+
df=df[collist1]
|
228
|
+
"""
|
229
|
+
df.replace(0,'---',inplace=True); df.replace('0','---',inplace=True)
|
230
|
+
|
231
|
+
df_display_CSS(df,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
|
232
|
+
first_col_align='center',second_col_align='left', \
|
233
|
+
last_col_align='right',other_col_align='right', \
|
234
|
+
titile_font_size='14px',heading_font_size='12px', \
|
235
|
+
data_font_size='12px')
|
186
236
|
|
187
237
|
return df_merge
|
188
238
|
|
189
239
|
#==============================================================================
|
240
|
+
def fund_holding_china(ticker,rank=10,pastyears=2):
|
241
|
+
"""
|
242
|
+
功能:套壳函数fund_stock_holding_rank_china
|
243
|
+
"""
|
244
|
+
df,data=fund_stock_holding_rank_china(fund=ticker,rank=rank,year_num=pastyears)
|
245
|
+
|
246
|
+
return df,data
|
190
247
|
|
191
248
|
if __name__=='__main__':
|
192
249
|
fund='000592.SS'
|
193
250
|
year_num=2
|
251
|
+
rank=10
|
194
252
|
|
195
253
|
df=fund_stock_holding_rank_china(fund,year_num=2)
|
196
254
|
|
197
255
|
# 获取单只基金的十大股票名称信息
|
198
|
-
def fund_stock_holding_rank_china(fund,year_num=2):
|
256
|
+
def fund_stock_holding_rank_china(fund,rank=10,year_num=2):
|
199
257
|
"""
|
200
258
|
比较股票型基金fund近year_num年持仓的前10大股票排名变化
|
201
259
|
"""
|
202
|
-
print("Searching fund stock holding info,
|
260
|
+
print("Searching fund stock holding info, which takes time, please wait ...\n")
|
203
261
|
code=fund[:6]
|
204
262
|
|
205
263
|
import akshare as ak
|
@@ -268,7 +326,7 @@ def fund_stock_holding_rank_china(fund,year_num=2):
|
|
268
326
|
dft.sort_values(by='占净值比例',ascending=False,inplace=True)
|
269
327
|
dft.reset_index(drop=True,inplace=True)
|
270
328
|
dft['序号']=dft.index + 1
|
271
|
-
dft2=dft.head(
|
329
|
+
dft2=dft.head(rank)
|
272
330
|
|
273
331
|
if len(data2)==0:
|
274
332
|
data2=dft2
|
@@ -281,7 +339,7 @@ def fund_stock_holding_rank_china(fund,year_num=2):
|
|
281
339
|
# 合成信息
|
282
340
|
data2['持股状况']=data2.apply(lambda x: x['股票名称']+'('+str(x['占净值比例'])+','+str(x['持股数'])+')',axis=1)
|
283
341
|
|
284
|
-
df = data2.set_index(['序号','季度']).stack().unstack([1,2]).head(
|
342
|
+
df = data2.set_index(['序号','季度']).stack().unstack([1,2]).head(rank)
|
285
343
|
|
286
344
|
#df = df.loc[:,(slice(None), '股票名称')] # 只选取 股票名称
|
287
345
|
df = df.loc[:,(slice(None), '持股状况')] # 只选取 持股状况
|
@@ -314,15 +372,28 @@ def fund_stock_holding_rank_china(fund,year_num=2):
|
|
314
372
|
"""
|
315
373
|
name=get_fund_name_china2(fund)
|
316
374
|
|
317
|
-
print("=== 基金持仓股票排行分析:"+name+",按照占净值比例高低排列 ===\n")
|
375
|
+
#print("=== 基金持仓股票排行分析:"+name+",按照占净值比例高低排列 ===\n")
|
376
|
+
titletxt="基金持仓分析:"+name+",按照占净值比例降序排列,前"+str(rank)+"名成份证券"
|
377
|
+
import datetime; todaydt = datetime.date.today()
|
378
|
+
#print("\n*** 注:包括A股与非A股。持股结构:股票简称(占净值比例%,持股数万股),",str(todaydt))
|
379
|
+
footnote="【注】持仓结构:证券简称(占净值比例%,持仓数万股),"+str(todaydt)+"统计"
|
380
|
+
|
381
|
+
#最新的日期方前面
|
382
|
+
collist=list(df)
|
383
|
+
collist.sort(reverse=True)
|
384
|
+
df=df[collist]
|
318
385
|
|
386
|
+
df_display_CSS(df,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=3, \
|
387
|
+
first_col_align='center',second_col_align='left', \
|
388
|
+
last_col_align='left',other_col_align='left', \
|
389
|
+
titile_font_size='16px',heading_font_size='15px', \
|
390
|
+
data_font_size='15px')
|
391
|
+
|
392
|
+
"""
|
319
393
|
alignlist=['center']+['left']*(len(list(df))-1)
|
320
394
|
print(df.to_markdown(index=False,tablefmt='plain',colalign=alignlist))
|
321
395
|
#print(df.to_string(index=False))
|
322
|
-
|
323
|
-
import datetime; today = datetime.date.today()
|
324
|
-
print("\n*** 注:包括A股与非A股。持股结构:股票简称(占净值比例%,持股数万股),",today)
|
325
|
-
#print("\n*** 注:包括A股与非A股。数据来源:天天基金/东方财富,",today)
|
396
|
+
"""
|
326
397
|
|
327
398
|
return df,data
|
328
399
|
|
@@ -398,6 +469,16 @@ def reits_jsl_china(fund='',rank=10):
|
|
398
469
|
return dfb
|
399
470
|
|
400
471
|
#==============================================================================
|
472
|
+
def reit_rank_china(indicator='最新价',rank=10):
|
473
|
+
"""
|
474
|
+
功能:套壳函数reits_list_china
|
475
|
+
"""
|
476
|
+
|
477
|
+
df=reits_list_china(indicator=indicator,rank=rank)
|
478
|
+
|
479
|
+
return df
|
480
|
+
|
481
|
+
|
401
482
|
if __name__=='__main__':
|
402
483
|
rank=10
|
403
484
|
|
@@ -593,8 +674,8 @@ def oef_rank_china(indicator='单位净值',fund_type='全部类型',rank=5):
|
|
593
674
|
|
594
675
|
typelist=['单位净值','累计净值','手续费','增长率']
|
595
676
|
if info_type not in typelist:
|
596
|
-
print(" #Error(oef_rank_china): unsupported
|
597
|
-
print(" Supported
|
677
|
+
print(" #Error(oef_rank_china): unsupported indicator",info_type)
|
678
|
+
print(" Supported indicators:",typelist)
|
598
679
|
return None
|
599
680
|
|
600
681
|
print("Searching for open-ended fund (OEF) information in China ...")
|
@@ -660,7 +741,7 @@ def oef_rank_china(indicator='单位净值',fund_type='全部类型',rank=5):
|
|
660
741
|
break
|
661
742
|
if not found:
|
662
743
|
print(" #Error(oef_rank_china): unsupported fund type",fund_type)
|
663
|
-
print(" Supported fund
|
744
|
+
print(" Supported fund types:",fundtypelist)
|
664
745
|
return None
|
665
746
|
fund_filter=lambda x: fund_type in x
|
666
747
|
df.dropna(inplace=True)
|
@@ -1046,7 +1127,9 @@ def mmf_rank_china(indicator="7日年化%",rank=5):
|
|
1046
1127
|
indicator_list=["万份收益","7日年化%"]
|
1047
1128
|
if indicator not in indicator_list:
|
1048
1129
|
print(" #Warning(mmf_rank_china): unsupported indicator",indicator,"reset to","7日年化%")
|
1049
|
-
|
1130
|
+
print(" Supported indicators:",indicator_list)
|
1131
|
+
#indicator="7日年化%"
|
1132
|
+
return None
|
1050
1133
|
|
1051
1134
|
print("Searching for money market fund (OEF) information in China ...")
|
1052
1135
|
import akshare as ak
|
@@ -1184,8 +1267,8 @@ def etf_rank_china(indicator='单位净值',fund_type='全部类型',rank=5):
|
|
1184
1267
|
|
1185
1268
|
typelist=['单位净值','累计净值','市价','增长率']
|
1186
1269
|
if info_type not in typelist:
|
1187
|
-
print(" #Error(etf_rank_china): unsupported
|
1188
|
-
print(" Supported
|
1270
|
+
print(" #Error(etf_rank_china): unsupported indicator",info_type)
|
1271
|
+
print(" Supported indicators:",typelist)
|
1189
1272
|
return None
|
1190
1273
|
|
1191
1274
|
print("Searching for exchange traded fund (ETF) information in China ...")
|
@@ -1226,7 +1309,7 @@ def etf_rank_china(indicator='单位净值',fund_type='全部类型',rank=5):
|
|
1226
1309
|
break
|
1227
1310
|
if not found:
|
1228
1311
|
print(" #Error(etf_rank_china): unsupported fund type",fund_type)
|
1229
|
-
print(" Supported fund
|
1312
|
+
print(" Supported fund types:",fundtypelist)
|
1230
1313
|
return None
|
1231
1314
|
fund_filter=lambda x: fund_type in x
|
1232
1315
|
df['基金类型s']=df['类型'].apply(fund_filter)
|
@@ -52,7 +52,7 @@ siat/financials_test.py,sha256=HJ3CPo_Xckz2wXi3AEP6ZNWCF1Duc1pLi0Y10USiImc,23829
|
|
52
52
|
siat/fred_test.py,sha256=KF50ssSbsfpa_kT6iuomD0vG4eXztAcOasZxg1OGX5w,1201
|
53
53
|
siat/fund.py,sha256=wMDORsCBV8ZXfgwbtq-0bu3qqWY66dHnbqgllW0gWCo,24637
|
54
54
|
siat/fund_china.pickle,sha256=QI3IjV46EeJ5ryO3xocmByc-6b_6_nDxgcXDhBHzop0,2380915
|
55
|
-
siat/fund_china.py,sha256=
|
55
|
+
siat/fund_china.py,sha256=uO2RexvO0ldclJwKAtbmdmaP9UvfkHq_uQDKOEVG5Sc,97516
|
56
56
|
siat/fund_china_test.py,sha256=-Bh6m0J0GPpIbYXx-H2vpzJoNFI6pE2C2jVPa8DazgE,6649
|
57
57
|
siat/fund_test.py,sha256=V4ADb8Gsp8gyeFTwcgRsJBpnUih_O-Q2V1ILc5oKjK8,1116
|
58
58
|
siat/future_china.py,sha256=F-HsIf2Op8Z22RzTjet1g8COzldgnMjFNSXsAkeGyWo,17595
|
@@ -132,7 +132,7 @@ siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
|
|
132
132
|
siat/valuation_china.py,sha256=Tde2LzPDQy3Z7xOQQDw4ckQMPdROp_z0-GjFE6Z5_lI,67639
|
133
133
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
134
134
|
siat/var_model_validation.py,sha256=f-oDewg7bPzyNanz_Y_jLH68NowAA3gXFehW_weKGG0,14898
|
135
|
-
siat-3.1.
|
136
|
-
siat-3.1.
|
137
|
-
siat-3.1.
|
138
|
-
siat-3.1.
|
135
|
+
siat-3.1.4.dist-info/METADATA,sha256=GjZl5T5oguZg8fcFxvDskZKFVJizNcgQEU-IxlH0RSI,1447
|
136
|
+
siat-3.1.4.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
137
|
+
siat-3.1.4.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
138
|
+
siat-3.1.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|