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
- 最新修订日期:20201021
7
+ 最新修订日期:2024526
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='2022Q4'
26
- quarter2='2023Q1'
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 stock holding info, it may take time, please wait ...\n")
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[['股票代码', '股票名称', s1_share,s1_value, s1_ratio,s2_share,s2_value,s2_ratio, '持股数变化']]
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.head(-rank)
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, it may take time, please wait ...\n")
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(10)
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(10)
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 info type",info_type)
597
- print(" Supported info type:",typelist)
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 type:",fundtypelist)
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
- indicator="7日年化%"
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 info type",info_type)
1188
- print(" Supported info type:",typelist)
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 type:",fundtypelist)
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.1.3
3
+ Version: 3.1.4
4
4
  Summary: Securities Investment Analysis Tools (siat)
5
5
  Home-page: https://pypi.org/project/siat/
6
6
  Author: Prof. WANG Dehong, International Business School, Beijing Foreign Studies University
@@ -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=_obFT-JBjhvzX71HVyqafwFXKE3YCIMpVhsKz_Wir-4,94035
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.3.dist-info/METADATA,sha256=h-Ogl_X_X9zSfrdOjdfY0uOX4hRUPUTlOHnKoMkzS9g,1447
136
- siat-3.1.3.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
137
- siat-3.1.3.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
138
- siat-3.1.3.dist-info/RECORD,,
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