siat 3.1.2__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/common.py
CHANGED
@@ -3866,4 +3866,14 @@ def df_index_timezone_remove(df):
|
|
3866
3866
|
|
3867
3867
|
return df
|
3868
3868
|
#==============================================================================
|
3869
|
+
|
3870
|
+
def df_swap_columns(df, col1, col2):
|
3871
|
+
"""
|
3872
|
+
功能:交换df中的两个列的位置
|
3873
|
+
"""
|
3874
|
+
cols = df.columns.tolist()
|
3875
|
+
i1, i2 = cols.index(col1), cols.index(col2)
|
3876
|
+
cols[i2], cols[i1] = cols[i1], cols[i2]
|
3877
|
+
|
3878
|
+
return df[cols]
|
3869
3879
|
#==============================================================================
|
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,12 +469,22 @@ 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
|
|
404
485
|
df=reits_list_china(rank=10)
|
405
486
|
|
406
|
-
def reits_list_china(
|
487
|
+
def reits_list_china(indicator='最新价',rank=10):
|
407
488
|
"""
|
408
489
|
功能:REITs基金信息概述和列表
|
409
490
|
目前能正常工作
|
@@ -415,26 +496,37 @@ def reits_list_china(rank=10,sort='最新价'):
|
|
415
496
|
print(" #Error(reits_profile_china): akshare does not work properly now")
|
416
497
|
return None
|
417
498
|
df2.drop('序号', axis=1, inplace=True)
|
499
|
+
df2['成交额']=df2['成交额'].apply(lambda x: int(x))
|
500
|
+
df2.fillna("---",inplace=True)
|
418
501
|
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
502
|
+
df2=df_swap_columns(df2, col1='代码', col2='名称')
|
503
|
+
num=len(df2)
|
504
|
+
|
505
|
+
indicatorlist=list(df2)
|
506
|
+
if indicator not in indicatorlist:
|
507
|
+
print(" #Error(reits_list_china):",indicator,"is not supported")
|
508
|
+
print(" Supported indicators:",indicatorlist)
|
423
509
|
return None
|
424
510
|
|
425
|
-
#df2.
|
426
|
-
df2.sort_values(by=[
|
511
|
+
#df2.indicator_values(by=['昨收'],ascending=False,inplace=True)
|
512
|
+
df2.sort_values(by=[indicator],ascending=False,inplace=True)
|
427
513
|
df2.reset_index(drop=True,inplace=True)
|
428
|
-
|
429
|
-
num=len(df2)
|
514
|
+
collist=list(df2)
|
430
515
|
|
516
|
+
for i in ['名称','代码',indicator]:
|
517
|
+
collist.remove(i)
|
518
|
+
collist1=['名称','代码',indicator]+collist
|
519
|
+
|
520
|
+
df2['序号']=df2.index + 1
|
521
|
+
df2=df2[['序号']+collist1]
|
522
|
+
"""
|
431
523
|
#设置打印对齐
|
432
524
|
pd.set_option('display.max_columns', 1000)
|
433
525
|
pd.set_option('display.width', 1000)
|
434
526
|
pd.set_option('display.max_colwidth', 1000)
|
435
527
|
pd.set_option('display.unicode.ambiguous_as_wide', True)
|
436
528
|
pd.set_option('display.unicode.east_asian_width', True)
|
437
|
-
|
529
|
+
"""
|
438
530
|
if rank > 0:
|
439
531
|
order='前'
|
440
532
|
dfb=df2.head(rank)
|
@@ -443,11 +535,8 @@ def reits_list_china(rank=10,sort='最新价'):
|
|
443
535
|
rank=-rank
|
444
536
|
dfb=df2.tail(rank)
|
445
537
|
|
446
|
-
dfb.fillna("---",inplace=True)
|
447
|
-
dfb['成交额']=dfb['成交额'].apply(lambda x: int(x))
|
448
|
-
|
449
538
|
#print("\n===== 中国REITs基金列表(按最新价高低排列,"+order+str(rank)+"名) =====\n")
|
450
|
-
titletxt="中国REITs基金列表(按"+
|
539
|
+
titletxt="中国REITs基金列表(按"+indicator+"降序排列,"+order+str(rank)+"名)"
|
451
540
|
"""
|
452
541
|
print(dfb.to_string(index=False))
|
453
542
|
"""
|
@@ -464,10 +553,10 @@ def reits_list_china(rank=10,sort='最新价'):
|
|
464
553
|
"""
|
465
554
|
import datetime; todaydt = datetime.date.today()
|
466
555
|
#print("\n*** 数据来源:东方财富, 总计"+str(num)+"只REITs基金,",today)
|
467
|
-
footnote="
|
556
|
+
footnote="数据来源:东方财富,共找到"+str(num)+"只REITs基金,"+str(todaydt)
|
468
557
|
|
469
558
|
df_display_CSS(dfb,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=3, \
|
470
|
-
first_col_align='
|
559
|
+
first_col_align='center',second_col_align='left', \
|
471
560
|
last_col_align='right',other_col_align='right', \
|
472
561
|
titile_font_size='16px',heading_font_size='15px', \
|
473
562
|
data_font_size='15px')
|
@@ -577,14 +666,16 @@ if __name__=='__main__':
|
|
577
666
|
info_type='单位净值'
|
578
667
|
fund_type='股票型'
|
579
668
|
|
580
|
-
def oef_rank_china(
|
669
|
+
def oef_rank_china(indicator='单位净值',fund_type='全部类型',rank=5):
|
581
670
|
"""
|
582
671
|
功能:中国开放式基金排名,单位净值,累计净值,手续费
|
583
672
|
"""
|
673
|
+
info_type=indicator
|
674
|
+
|
584
675
|
typelist=['单位净值','累计净值','手续费','增长率']
|
585
676
|
if info_type not in typelist:
|
586
|
-
print(" #Error(oef_rank_china): unsupported
|
587
|
-
print(" Supported
|
677
|
+
print(" #Error(oef_rank_china): unsupported indicator",info_type)
|
678
|
+
print(" Supported indicators:",typelist)
|
588
679
|
return None
|
589
680
|
|
590
681
|
print("Searching for open-ended fund (OEF) information in China ...")
|
@@ -650,7 +741,7 @@ def oef_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
650
741
|
break
|
651
742
|
if not found:
|
652
743
|
print(" #Error(oef_rank_china): unsupported fund type",fund_type)
|
653
|
-
print(" Supported fund
|
744
|
+
print(" Supported fund types:",fundtypelist)
|
654
745
|
return None
|
655
746
|
fund_filter=lambda x: fund_type in x
|
656
747
|
df.dropna(inplace=True)
|
@@ -664,26 +755,30 @@ def oef_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
664
755
|
if info_type == '单位净值':
|
665
756
|
df['单位净值']=df['单位净值'].apply(lambda x: round(x,2))
|
666
757
|
df.sort_values(by=['单位净值'],ascending=False,inplace=True)
|
667
|
-
dfprint=df[['基金简称','基金代码','基金类型','单位净值','申购状态','赎回状态']]
|
758
|
+
#dfprint=df[['基金简称','基金代码','基金类型','单位净值','申购状态','赎回状态']]
|
759
|
+
dfprint=df[['基金简称','基金代码','基金类型','单位净值','累计净值']]
|
668
760
|
#print(texttranslate("\n===== 中国开放式基金排名:单位净值 ====="))
|
669
761
|
titletxt="中国开放式基金排名:单位净值"
|
670
762
|
|
671
763
|
if info_type == '累计净值':
|
672
764
|
df['累计净值']=df['累计净值'].apply(lambda x: round(x,2))
|
673
765
|
df.sort_values(by=['累计净值'],ascending=False,inplace=True)
|
674
|
-
dfprint=df[['基金简称','基金代码','基金类型','累计净值','申购状态','赎回状态']]
|
766
|
+
#dfprint=df[['基金简称','基金代码','基金类型','累计净值','申购状态','赎回状态']]
|
767
|
+
dfprint=df[['基金简称','基金代码','基金类型','累计净值','单位净值']]
|
675
768
|
#print(texttranslate("\n===== 中国开放式基金排名:累计净值 ====="))
|
676
769
|
titletxt="中国开放式基金排名:累计净值"
|
677
770
|
|
678
771
|
if info_type == '手续费':
|
679
772
|
df.sort_values(by=['手续费'],ascending=False,inplace=True)
|
680
|
-
dfprint=df[['基金简称','基金代码','基金类型','手续费','申购状态','赎回状态']]
|
773
|
+
#dfprint=df[['基金简称','基金代码','基金类型','手续费','申购状态','赎回状态']]
|
774
|
+
dfprint=df[['基金简称','基金代码','基金类型','手续费','单位净值']]
|
681
775
|
#print(texttranslate("\n===== 中国开放式基金排名:手续费 ====="))
|
682
776
|
titletxt="中国开放式基金排名:手续费"
|
683
777
|
|
684
778
|
if info_type == '增长率':
|
685
779
|
df.sort_values(by=['日增长率'],ascending=False,inplace=True)
|
686
|
-
dfprint=df[['基金简称','基金代码','基金类型','日增长率','申购状态','赎回状态']]
|
780
|
+
#dfprint=df[['基金简称','基金代码','基金类型','日增长率','申购状态','赎回状态']]
|
781
|
+
dfprint=df[['基金简称','基金代码','基金类型','日增长率','单位净值']]
|
687
782
|
#print(texttranslate("\n===== 中国开放式基金排名:增长率% ====="))
|
688
783
|
titletxt="中国开放式基金排名:增长率%"
|
689
784
|
|
@@ -700,6 +795,10 @@ def oef_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
700
795
|
dfprint.reset_index(drop=True,inplace=True)
|
701
796
|
dfprint.index=dfprint.index + 1
|
702
797
|
|
798
|
+
collist=list(dfprint)
|
799
|
+
dfprint['序号']=dfprint.index
|
800
|
+
dfprint=dfprint[['序号']+collist]
|
801
|
+
|
703
802
|
if rank >= 0:
|
704
803
|
dfprint10=dfprint.head(rank)
|
705
804
|
else:
|
@@ -738,7 +837,7 @@ def oef_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
738
837
|
footnote=footnote1+footnote2+footnote3+footnote4
|
739
838
|
|
740
839
|
df_display_CSS(dfprint10,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=4, \
|
741
|
-
first_col_align='
|
840
|
+
first_col_align='center',second_col_align='left', \
|
742
841
|
last_col_align='right',other_col_align='right', \
|
743
842
|
titile_font_size='16px',heading_font_size='15px', \
|
744
843
|
data_font_size='15px')
|
@@ -787,15 +886,19 @@ if __name__=='__main__':
|
|
787
886
|
twinx=False
|
788
887
|
zeroline=False
|
789
888
|
|
790
|
-
def oef_trend_china(
|
889
|
+
def oef_trend_china(ticker,start,end='today',indicator='净值', \
|
791
890
|
power=0,twinx=False, \
|
792
|
-
|
891
|
+
average_value=True,facecolor='whitesmoke',
|
892
|
+
loc1='best',loc2='best'):
|
793
893
|
"""
|
794
894
|
功能:开放式基金业绩趋势,单位净值,累计净值,近三个月收益率,同类排名,总排名
|
795
895
|
"""
|
896
|
+
fund=ticker
|
796
897
|
fromdate,todate=start_end_preprocess(start,end)
|
898
|
+
trend_type=indicator
|
899
|
+
|
797
900
|
#检查走势类型
|
798
|
-
trendlist=["净值","收益率","排名"]
|
901
|
+
trendlist=["净值","单位净值","累计净值","收益率","排名"]
|
799
902
|
if trend_type not in trendlist:
|
800
903
|
print(" #Error(oef_trend_china): unsupported trend type:",trend_type)
|
801
904
|
print(" Supported trend types:",trendlist)
|
@@ -814,6 +917,7 @@ def oef_trend_china(fund,start,end='today',trend_type='净值', \
|
|
814
917
|
"""
|
815
918
|
print("Searching for open-ended fund (OEF) trend info in China ...")
|
816
919
|
import akshare as ak
|
920
|
+
import pandas as pd
|
817
921
|
|
818
922
|
#开放式基金-历史数据
|
819
923
|
import datetime; today = datetime.date.today()
|
@@ -823,7 +927,6 @@ def oef_trend_china(fund,start,end='today',trend_type='净值', \
|
|
823
927
|
fund_name=ticker_name(fund1,'fund')
|
824
928
|
|
825
929
|
#绘制单位/累计净值对比图
|
826
|
-
import pandas as pd
|
827
930
|
if trend_type == '净值':
|
828
931
|
df1 = ak.fund_open_fund_info_em(fund1, indicator="单位净值走势")
|
829
932
|
df1.rename(columns={'净值日期':'date','单位净值':'单位净值'}, inplace=True)
|
@@ -853,13 +956,91 @@ def oef_trend_china(fund,start,end='today',trend_type='净值', \
|
|
853
956
|
titletxt=texttranslate("开放式基金的净值趋势:")+fund_name
|
854
957
|
|
855
958
|
#footnote=source+', '+str(today)
|
856
|
-
footnote='
|
959
|
+
footnote='注意:图中为交易市场数据,存在溢价或折价,可能与基金公司公布的净值存在差异\n'+source+', '+str(today)
|
857
960
|
|
858
961
|
plot_line2(dfp,ticker1,colname1,label1, \
|
859
|
-
|
860
|
-
|
962
|
+
dfp,ticker2,colname2,label2, \
|
963
|
+
ylabeltxt,titletxt,footnote,power=power,twinx=twinx, \
|
964
|
+
facecolor=facecolor, \
|
861
965
|
loc1=loc1,loc2=loc2)
|
862
966
|
return df
|
967
|
+
|
968
|
+
#绘制单位净值图
|
969
|
+
if trend_type == '单位净值':
|
970
|
+
df1 = ak.fund_open_fund_info_em(fund1, indicator="单位净值走势")
|
971
|
+
df1.rename(columns={'净值日期':'date','单位净值':'单位净值'}, inplace=True)
|
972
|
+
df1['日期']=df1['date']
|
973
|
+
df1.set_index(['date'],inplace=True)
|
974
|
+
"""
|
975
|
+
df2 = ak.fund_open_fund_info_em(fund1, indicator="累计净值走势")
|
976
|
+
df2.rename(columns={'净值日期':'date','累计净值':'累计净值'}, inplace=True)
|
977
|
+
df2.set_index(['date'],inplace=True)
|
978
|
+
"""
|
979
|
+
#合并
|
980
|
+
#df = pd.merge(df1,df2,left_index=True,right_index=True,how='inner')
|
981
|
+
df = df1
|
982
|
+
df['日期']=df['日期'].apply(lambda x: pd.to_datetime(x))
|
983
|
+
|
984
|
+
dfp=df[(df['日期'] >= start)]
|
985
|
+
dfp=dfp[(dfp['日期'] <= end)]
|
986
|
+
if len(dfp) == 0:
|
987
|
+
print(" #Error(oef_trend_china): no info found for",fund,"in the period:",fromdate,todate)
|
988
|
+
return
|
989
|
+
|
990
|
+
#绘图
|
991
|
+
ticker1=fund1; colname1='单位净值';label1=texttranslate('单位净值')
|
992
|
+
#ticker2=fund1; colname2='累计净值';label2=texttranslate('累计净值')
|
993
|
+
#ylabeltxt='人民币元'
|
994
|
+
ylabeltxt=texttranslate('单位净值')
|
995
|
+
|
996
|
+
titletxt=texttranslate("开放式基金的净值趋势:")+fund_name
|
997
|
+
|
998
|
+
#footnote=source+', '+str(today)
|
999
|
+
footnote='图中为交易市场数据,存在溢价或折价,可能与基金公司公布的净值存在差异\n'+source+', '+str(today)
|
1000
|
+
|
1001
|
+
plot_line(dfp,colname1,label1,ylabeltxt,titletxt,footnote,power=power,loc=loc1, \
|
1002
|
+
average_value=average_value,facecolor=facecolor)
|
1003
|
+
"""
|
1004
|
+
plot_line2(dfp,ticker1,colname1,label1, \
|
1005
|
+
dfp,ticker2,colname2,label2, \
|
1006
|
+
ylabeltxt,titletxt,footnote,power=power,twinx=twinx, \
|
1007
|
+
facecolor=facecolor, \
|
1008
|
+
loc1=loc1,loc2=loc2)
|
1009
|
+
"""
|
1010
|
+
return df
|
1011
|
+
|
1012
|
+
#绘制累计净值图
|
1013
|
+
if trend_type == '累计净值':
|
1014
|
+
df2 = ak.fund_open_fund_info_em(fund1, indicator="累计净值走势")
|
1015
|
+
df2.rename(columns={'净值日期':'date','累计净值':'累计净值'}, inplace=True)
|
1016
|
+
df2['日期']=df2['date']
|
1017
|
+
df2.set_index(['date'],inplace=True)
|
1018
|
+
|
1019
|
+
#合并
|
1020
|
+
df = df2
|
1021
|
+
df['日期']=df['日期'].apply(lambda x: pd.to_datetime(x))
|
1022
|
+
|
1023
|
+
dfp=df[(df['日期'] >= start)]
|
1024
|
+
dfp=dfp[(dfp['日期'] <= end)]
|
1025
|
+
if len(dfp) == 0:
|
1026
|
+
print(" #Error(oef_trend_china): no info found for",fund,"in the period:",fromdate,todate)
|
1027
|
+
return
|
1028
|
+
|
1029
|
+
#绘图
|
1030
|
+
ticker2=fund1; colname2='累计净值';label2=texttranslate('累计净值')
|
1031
|
+
#ylabeltxt='人民币元'
|
1032
|
+
ylabeltxt=texttranslate('累计净值')
|
1033
|
+
|
1034
|
+
titletxt=texttranslate("开放式基金的净值趋势:")+fund_name
|
1035
|
+
|
1036
|
+
#footnote=source+', '+str(today)
|
1037
|
+
footnote='图中为交易市场数据,存在溢价或折价,可能与基金公司公布的净值存在差异\n'+source+', '+str(today)
|
1038
|
+
|
1039
|
+
plot_line(dfp,colname2,label2,ylabeltxt,titletxt,footnote,power=power,loc=loc1, \
|
1040
|
+
average_value=average_value,facecolor=facecolor)
|
1041
|
+
|
1042
|
+
return df
|
1043
|
+
|
863
1044
|
|
864
1045
|
#绘制累计收益率单线图
|
865
1046
|
if trend_type == '收益率':
|
@@ -875,10 +1056,11 @@ def oef_trend_china(fund,start,end='today',trend_type='净值', \
|
|
875
1056
|
return
|
876
1057
|
|
877
1058
|
colname='累计收益率'; collabel=texttranslate('累计收益率%')
|
878
|
-
ylabeltxt=texttranslate('
|
1059
|
+
ylabeltxt=texttranslate('累计收益率%')
|
879
1060
|
titletxt=texttranslate("开放式基金的累计收益率趋势:")+fund_name
|
880
|
-
footnote=source+'
|
881
|
-
plot_line(dfp,colname,collabel,ylabeltxt,titletxt,footnote,power=power,loc=loc1
|
1061
|
+
footnote=source+','+str(today)
|
1062
|
+
plot_line(dfp,colname,collabel,ylabeltxt,titletxt,footnote,power=power,loc=loc1, \
|
1063
|
+
average_value=average_value,facecolor=facecolor)
|
882
1064
|
return df
|
883
1065
|
|
884
1066
|
#绘制同类排名图:近三个月收益率
|
@@ -922,8 +1104,9 @@ def oef_trend_china(fund,start,end='today',trend_type='净值', \
|
|
922
1104
|
dfp1=pd.DataFrame(dfp[colname1])
|
923
1105
|
dfp2=pd.DataFrame(dfp[colname2])
|
924
1106
|
plot_line2(dfp1,ticker1,colname1,label1, \
|
925
|
-
|
926
|
-
|
1107
|
+
dfp2,ticker2,colname2,label2, \
|
1108
|
+
ylabeltxt,titletxt,footnote,power=power,twinx=twinx, \
|
1109
|
+
facecolor=facecolor, \
|
927
1110
|
loc1=loc1,loc2=loc2)
|
928
1111
|
|
929
1112
|
return df
|
@@ -932,78 +1115,73 @@ def oef_trend_china(fund,start,end='today',trend_type='净值', \
|
|
932
1115
|
if __name__=='__main__':
|
933
1116
|
pass
|
934
1117
|
|
935
|
-
def mmf_rank_china(rank=
|
1118
|
+
def mmf_rank_china(indicator="7日年化%",rank=5):
|
936
1119
|
"""
|
937
1120
|
功能:中国货币型基金排名,7日年化收益率%
|
938
|
-
|
1121
|
+
货币基金的万份收益指的是基金公司每日公布的当日每万份基金单位产生的收益金额,即万份基金单位收益。
|
1122
|
+
注意:万份基金单位收益与万份基金累计收益是不一样的,投资者想要买货币基金应改看基金的万份基金单位收益。
|
1123
|
+
货币基金具体的收益计算方式是:
|
1124
|
+
货币基金收益=已确认金额/10000*当日万分收益。
|
1125
|
+
另外,货币基金每日公布一次收益,周末及节假日,通常在节后首个交易日公布周末或这节假日期间的累计收益。
|
1126
|
+
"""
|
1127
|
+
indicator_list=["万份收益","7日年化%"]
|
1128
|
+
if indicator not in indicator_list:
|
1129
|
+
print(" #Warning(mmf_rank_china): unsupported indicator",indicator,"reset to","7日年化%")
|
1130
|
+
print(" Supported indicators:",indicator_list)
|
1131
|
+
#indicator="7日年化%"
|
1132
|
+
return None
|
939
1133
|
|
940
1134
|
print("Searching for money market fund (OEF) information in China ...")
|
941
1135
|
import akshare as ak
|
1136
|
+
import pandas as pd
|
942
1137
|
|
943
1138
|
#获取货币型基金实时信息
|
944
1139
|
df = ak.fund_money_fund_daily_em()
|
945
1140
|
collist=list(df)
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
1141
|
+
nvname1=collist[2]
|
1142
|
+
nvname2=collist[3]
|
1143
|
+
if df[nvname1].eq('').all():
|
1144
|
+
nvname1=collist[5]
|
1145
|
+
nvname2=collist[6]
|
1146
|
+
nvdate=nvname1[:10]
|
1147
|
+
|
950
1148
|
#修改列名
|
951
|
-
df.rename(columns={
|
1149
|
+
df.rename(columns={nvname1:'万份收益',nvname2:'7日年化%'}, inplace=True)
|
952
1150
|
#dfa=df.drop(df[df['7日年化%']==''].index)
|
953
|
-
dfb=df[['基金代码','基金简称','7日年化%','成立日期','基金经理','手续费']]
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
pd.set_option('display.unicode.east_asian_width', True)
|
967
|
-
|
1151
|
+
dfb=df[['基金代码','基金简称','万份收益','7日年化%','成立日期','基金经理','手续费']].copy()
|
1152
|
+
dfb=dfb[dfb['7日年化%'] != '---']
|
1153
|
+
|
1154
|
+
if indicator=='7日年化%':
|
1155
|
+
dfb.sort_values(by=['7日年化%'],ascending=False,inplace=True)
|
1156
|
+
dfprint=dfb[['基金简称','基金代码','7日年化%','万份收益']].copy()
|
1157
|
+
titletxt="中国货币型基金排名:7日年化收益率"
|
1158
|
+
if indicator=='万份收益':
|
1159
|
+
dfb.sort_values(by=['万份收益'],ascending=False,inplace=True)
|
1160
|
+
dfprint=dfb[['基金简称','基金代码','万份收益','7日年化%']].copy()
|
1161
|
+
titletxt="中国货币型基金排名:万份收益金额(元)"
|
1162
|
+
|
1163
|
+
#设置打印
|
968
1164
|
dfprint.dropna(inplace=True)
|
969
1165
|
dfprint.reset_index(drop=True,inplace=True)
|
970
1166
|
dfprint.index=dfprint.index + 1
|
971
1167
|
|
972
|
-
|
1168
|
+
collist=list(dfprint)
|
1169
|
+
dfprint['序号']=dfprint.index
|
1170
|
+
dfprint=dfprint[['序号']+collist]
|
1171
|
+
|
1172
|
+
if rank >0:
|
973
1173
|
dfprint10=dfprint.head(rank)
|
974
1174
|
else:
|
975
1175
|
dfprint10=dfprint.tail(-rank)
|
976
|
-
|
977
|
-
""
|
978
|
-
|
979
|
-
"""
|
980
|
-
"""
|
981
|
-
print('') #在标题与表格之间空一行
|
982
|
-
alignlist=['right','left','center','center','center','right']
|
983
|
-
try:
|
984
|
-
print(dfprint10.to_markdown(index=True,tablefmt='plain',colalign=alignlist))
|
985
|
-
except:
|
986
|
-
#解决汉字编码gbk出错问题
|
987
|
-
print_df=dfprint10.to_markdown(index=True,tablefmt='plain',colalign=alignlist)
|
988
|
-
print_df2=print_df.encode("utf-8",errors="strict")
|
989
|
-
print(print_df2)
|
990
|
-
|
991
|
-
print('') #在表格与脚注之间空一行
|
992
|
-
print(texttranslate("共找到披露收益率信息的货币型基金数量:"),len(dfprint))
|
993
|
-
|
994
|
-
print(texttranslate("收益率日期:"),nvdate,'\b. ',end='')
|
995
|
-
import datetime
|
996
|
-
today = datetime.date.today()
|
997
|
-
print(texttranslate("数据来源:东方财富/天天基金,"),today)
|
998
|
-
"""
|
999
|
-
footnote1="披露收益率信息的货币型基金数量:"+str(len(dfprint))+'\n'
|
1000
|
-
footnote2="收益率日期:"+str(nvdate)+','
|
1176
|
+
|
1177
|
+
footnote1="披露收益信息的货币型基金数量:"+str(len(dfprint))+','
|
1178
|
+
footnote2=str(nvdate)+'\n'
|
1001
1179
|
import datetime; todaydt = datetime.date.today()
|
1002
|
-
footnote3="数据来源:东方财富/天天基金,"+str(todaydt)
|
1180
|
+
footnote3="数据来源:东方财富/天天基金,"+str(todaydt)+"统计"
|
1003
1181
|
footnote=footnote1+footnote2+footnote3
|
1004
1182
|
|
1005
1183
|
df_display_CSS(dfprint10,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=4, \
|
1006
|
-
first_col_align='
|
1184
|
+
first_col_align='center',second_col_align='left', \
|
1007
1185
|
last_col_align='right',other_col_align='right', \
|
1008
1186
|
titile_font_size='16px',heading_font_size='15px', \
|
1009
1187
|
data_font_size='15px')
|
@@ -1020,34 +1198,38 @@ if __name__=='__main__':
|
|
1020
1198
|
todate='2020-10-16'
|
1021
1199
|
power=0
|
1022
1200
|
|
1023
|
-
def mmf_trend_china(
|
1201
|
+
def mmf_trend_china(ticker,start,end='today',indicator='7日年化%',power=0, \
|
1202
|
+
average_value=True,facecolor='whitesmoke'):
|
1024
1203
|
"""
|
1025
1204
|
功能:货币型基金业绩趋势,7日年化收益率
|
1026
1205
|
"""
|
1206
|
+
fund=ticker
|
1207
|
+
|
1027
1208
|
fromdate,todate=start_end_preprocess(start,end)
|
1028
1209
|
#检查日期
|
1029
1210
|
result,start,end=check_period(fromdate,todate)
|
1030
1211
|
if not result:
|
1031
1212
|
print(" #Error(mmf_trend_china): invalid date period:",fromdate,todate)
|
1032
1213
|
return None
|
1033
|
-
import datetime
|
1214
|
+
import datetime; todaydt = datetime.date.today()
|
1034
1215
|
startdate=datetime.datetime.strftime(start,"%Y-%m-%d")
|
1035
1216
|
enddate=str(datetime.datetime.strftime(end,"%Y-%m-%d"))
|
1036
1217
|
|
1037
1218
|
print("Searching for money market fund (MMF) trend info in China ...")
|
1038
1219
|
import akshare as ak
|
1220
|
+
import pandas as pd
|
1039
1221
|
|
1040
1222
|
#基金历史数据
|
1041
|
-
import datetime; today = datetime.date.today()
|
1042
1223
|
source=texttranslate("数据来源:东方财富/天天基金")
|
1043
1224
|
|
1044
1225
|
#绘制收益率单线图
|
1045
1226
|
fund1=fund[:6]
|
1046
1227
|
df = ak.fund_money_fund_info_em(fund1)
|
1047
|
-
df.sort_values(by=['净值日期'],ascending=True,inplace=True)
|
1048
1228
|
df['7日年化%']=df['7日年化收益率'].astype("float")
|
1229
|
+
df['万份收益']=df['每万份收益'].astype("float")
|
1230
|
+
|
1231
|
+
df.sort_values(by=['净值日期'],ascending=True,inplace=True)
|
1049
1232
|
|
1050
|
-
import pandas as pd
|
1051
1233
|
df['date']=pd.to_datetime(df['净值日期'])
|
1052
1234
|
df.set_index(['date'],inplace=True)
|
1053
1235
|
|
@@ -1057,11 +1239,16 @@ def mmf_trend_china(fund,start,end='today',power=0):
|
|
1057
1239
|
print(" #Error(mmf_trend_china): no info found for",fund,"in the period:",fromdate,todate)
|
1058
1240
|
return
|
1059
1241
|
|
1060
|
-
|
1242
|
+
if indicator=='7日年化%':
|
1243
|
+
colname='7日年化%'; collabel='7日年化%'
|
1244
|
+
else:
|
1245
|
+
colname='万份收益'; collabel="万份收益(元)"
|
1246
|
+
|
1061
1247
|
ylabeltxt=''
|
1062
|
-
titletxt=
|
1063
|
-
footnote=source+', '+str(
|
1064
|
-
plot_line(dfp,colname,collabel,ylabeltxt,titletxt,footnote,power=power
|
1248
|
+
titletxt="货币型基金的收益趋势:"+get_fund_name_china2(fund)+","+collabel
|
1249
|
+
footnote=source+', '+str(todaydt)
|
1250
|
+
plot_line(dfp,colname,collabel,ylabeltxt,titletxt,footnote,power=power, \
|
1251
|
+
average_value=average_value,facecolor=facecolor)
|
1065
1252
|
|
1066
1253
|
return df
|
1067
1254
|
|
@@ -1072,14 +1259,16 @@ if __name__=='__main__':
|
|
1072
1259
|
fund_type='增长率'
|
1073
1260
|
rank=10
|
1074
1261
|
|
1075
|
-
def etf_rank_china(
|
1262
|
+
def etf_rank_china(indicator='单位净值',fund_type='全部类型',rank=5):
|
1076
1263
|
"""
|
1077
1264
|
功能:中国ETF基金排名,单位净值,累计净值,手续费
|
1078
1265
|
"""
|
1266
|
+
info_type=indicator
|
1267
|
+
|
1079
1268
|
typelist=['单位净值','累计净值','市价','增长率']
|
1080
1269
|
if info_type not in typelist:
|
1081
|
-
print(" #Error(etf_rank_china): unsupported
|
1082
|
-
print(" Supported
|
1270
|
+
print(" #Error(etf_rank_china): unsupported indicator",info_type)
|
1271
|
+
print(" Supported indicators:",typelist)
|
1083
1272
|
return None
|
1084
1273
|
|
1085
1274
|
print("Searching for exchange traded fund (ETF) information in China ...")
|
@@ -1105,7 +1294,7 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1105
1294
|
|
1106
1295
|
#修改列名
|
1107
1296
|
df3=df2.rename(columns={nvname1:'单位净值',nvname2:'累计净值'})
|
1108
|
-
df=df3[['基金简称','基金代码','类型','单位净值','累计净值','增长率','市价']]
|
1297
|
+
df=df3[['基金简称','基金代码','类型','单位净值','累计净值','增长率','市价']].copy()
|
1109
1298
|
|
1110
1299
|
# 过滤idx行
|
1111
1300
|
df=df[df.index != 'idx']
|
@@ -1120,7 +1309,7 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1120
1309
|
break
|
1121
1310
|
if not found:
|
1122
1311
|
print(" #Error(etf_rank_china): unsupported fund type",fund_type)
|
1123
|
-
print(" Supported fund
|
1312
|
+
print(" Supported fund types:",fundtypelist)
|
1124
1313
|
return None
|
1125
1314
|
fund_filter=lambda x: fund_type in x
|
1126
1315
|
df['基金类型s']=df['类型'].apply(fund_filter)
|
@@ -1135,7 +1324,7 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1135
1324
|
df=df.replace('---',0)
|
1136
1325
|
df['单位净值']=df['单位净值'].astype(float)
|
1137
1326
|
df.sort_values(by=['单位净值'],ascending=False,inplace=True)
|
1138
|
-
dfprint=df[['基金简称','基金代码','类型','单位净值','市价']]
|
1327
|
+
dfprint=df[['基金简称','基金代码','类型','单位净值','市价']].copy()
|
1139
1328
|
#print(texttranslate("\n===== 中国ETF基金排名:单位净值 ====="))
|
1140
1329
|
titletxt="中国ETF基金排名:单位净值"
|
1141
1330
|
dfprint=dfprint[dfprint['单位净值'] != 0]
|
@@ -1144,7 +1333,7 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1144
1333
|
df=df.replace('---',0)
|
1145
1334
|
df['累计净值']=df['累计净值'].astype(float)
|
1146
1335
|
df.sort_values(by=['累计净值'],ascending=False,inplace=True)
|
1147
|
-
dfprint=df[['基金简称','基金代码','类型','累计净值','单位净值']]
|
1336
|
+
dfprint=df[['基金简称','基金代码','类型','累计净值','单位净值']].copy()
|
1148
1337
|
#print(texttranslate("\n===== 中国ETF基金排名:累计净值 ====="))
|
1149
1338
|
titletxt="中国ETF基金排名:累计净值"
|
1150
1339
|
dfprint=dfprint[dfprint['累计净值'] != 0]
|
@@ -1153,7 +1342,7 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1153
1342
|
df=df.replace('---',0)
|
1154
1343
|
df['市价']=df['市价'].astype(float)
|
1155
1344
|
df.sort_values(by=['市价'],ascending=False,inplace=True)
|
1156
|
-
dfprint=df[['基金简称','基金代码','类型','市价','单位净值']]
|
1345
|
+
dfprint=df[['基金简称','基金代码','类型','市价','单位净值']].copy()
|
1157
1346
|
#print(texttranslate("\n===== 中国ETF基金排名:市价 ====="))
|
1158
1347
|
titletxt="中国ETF基金排名:市价"
|
1159
1348
|
dfprint=dfprint[dfprint['市价'] != 0]
|
@@ -1161,7 +1350,7 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1161
1350
|
if info_type == '增长率':
|
1162
1351
|
df['增长率']=df['增长率'].astype(str)
|
1163
1352
|
df.sort_values(by=['增长率'],ascending=False,inplace=True)
|
1164
|
-
dfprint=df[['基金简称','基金代码','类型','增长率','市价','单位净值']]
|
1353
|
+
dfprint=df[['基金简称','基金代码','类型','增长率','市价','单位净值']].copy()
|
1165
1354
|
#print(texttranslate("\n===== 中国ETF基金排名:增长率 ====="))
|
1166
1355
|
titletxt="中国ETF基金排名:增长率"
|
1167
1356
|
dfprint=dfprint[dfprint['增长率'] != 0]
|
@@ -1178,6 +1367,10 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1178
1367
|
dfprint.reset_index(drop=True,inplace=True)
|
1179
1368
|
dfprint.index=dfprint.index + 1
|
1180
1369
|
|
1370
|
+
collist=list(dfprint)
|
1371
|
+
dfprint['序号']=dfprint.index
|
1372
|
+
dfprint=dfprint[['序号']+collist]
|
1373
|
+
|
1181
1374
|
if rank >=0:
|
1182
1375
|
dfprint10=dfprint.head(rank)
|
1183
1376
|
else:
|
@@ -1208,13 +1401,13 @@ def etf_rank_china(info_type='单位净值',fund_type='全部类型',rank=10):
|
|
1208
1401
|
"""
|
1209
1402
|
footnote1="披露净值信息的ETF基金数量:"+str(len(dfprint))+','
|
1210
1403
|
footnote2="基金类型:"+str(fund_type)+'\n'
|
1211
|
-
footnote3="
|
1404
|
+
footnote3="披露日期:"+str(nvdate)+','
|
1212
1405
|
import datetime; todaydt = datetime.date.today()
|
1213
1406
|
footnote4="数据来源:东方财富/天天基金,"+str(todaydt)
|
1214
1407
|
footnote=footnote1+footnote2+footnote3+footnote4
|
1215
1408
|
|
1216
1409
|
df_display_CSS(dfprint10,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=3, \
|
1217
|
-
first_col_align='
|
1410
|
+
first_col_align='center',second_col_align='left', \
|
1218
1411
|
last_col_align='right',other_col_align='right', \
|
1219
1412
|
titile_font_size='16px',heading_font_size='15px', \
|
1220
1413
|
data_font_size='15px')
|
@@ -1232,33 +1425,38 @@ if __name__=='__main__':
|
|
1232
1425
|
fromdate='2020-1-1'
|
1233
1426
|
todate='2020-10-16'
|
1234
1427
|
|
1235
|
-
def etf_trend_china(
|
1428
|
+
def etf_trend_china(ticker,start,end='today',indicator='净值',power=0, \
|
1429
|
+
average_value=True,facecolor='whitesmoke', \
|
1430
|
+
loc1='best',loc2='best',twinx=False,graph=True):
|
1236
1431
|
"""
|
1237
1432
|
功能:ETF基金业绩趋势,单位净值,累计净值
|
1238
1433
|
"""
|
1434
|
+
fund=ticker
|
1239
1435
|
fromdate,todate=start_end_preprocess(start,end='today')
|
1240
1436
|
|
1437
|
+
indicator_list=['净值','单位净值','累计净值']
|
1438
|
+
if indicator not in indicator_list:
|
1439
|
+
indicator='净值'
|
1440
|
+
|
1241
1441
|
#检查日期
|
1242
1442
|
result,start,end=check_period(fromdate,todate)
|
1243
1443
|
if not result:
|
1244
1444
|
print(" #Error(oef_trend_china): invalid date period:",fromdate,todate)
|
1245
1445
|
return None
|
1246
1446
|
#转换日期格式
|
1247
|
-
import datetime
|
1447
|
+
import datetime; todaydt = datetime.date.today()
|
1248
1448
|
startdate=str(datetime.datetime.strftime(start,"%Y-%m-%d"))
|
1249
1449
|
enddate=str(datetime.datetime.strftime(end,"%Y-%m-%d"))
|
1250
1450
|
|
1251
1451
|
print("Searching for exchange traded fund (ETF) trend info in China ...")
|
1252
1452
|
import akshare as ak
|
1453
|
+
import pandas as pd
|
1253
1454
|
|
1254
|
-
import datetime; today = datetime.date.today()
|
1255
1455
|
source=texttranslate("数据来源:东方财富/天天基金")
|
1256
|
-
|
1257
1456
|
|
1258
1457
|
#获取基金数据
|
1259
1458
|
fund1=fund[:6]
|
1260
1459
|
df = etf_hist_df = ak.fund_etf_fund_info_em(fund1)
|
1261
|
-
import pandas as pd
|
1262
1460
|
df['date']=pd.to_datetime(df['净值日期'])
|
1263
1461
|
df.set_index(['date'],inplace=True)
|
1264
1462
|
df['单位净值']=df['单位净值'].astype("float")
|
@@ -1275,14 +1473,25 @@ def etf_trend_china(fund,start,end='today',loc1='best',loc2='best',twinx=False,g
|
|
1275
1473
|
if graph:
|
1276
1474
|
ticker1=fund1; colname1='单位净值';label1=texttranslate('单位净值')
|
1277
1475
|
ticker2=fund1; colname2='累计净值';label2=texttranslate('累计净值')
|
1278
|
-
ylabeltxt=texttranslate('人民币元')
|
1279
1476
|
titletxt=texttranslate("ETF基金的净值趋势:")+get_fund_name_china2(fund)
|
1280
|
-
footnote=source+', '+str(
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1477
|
+
footnote=source+', '+str(todaydt)
|
1478
|
+
|
1479
|
+
if indicator=='净值':
|
1480
|
+
ylabeltxt=texttranslate('净值(元)')
|
1481
|
+
plot_line2(dfp,ticker1,colname1,label1, \
|
1482
|
+
dfp,ticker2,colname2,label2, \
|
1483
|
+
ylabeltxt,titletxt,footnote, twinx=twinx, \
|
1484
|
+
facecolor=facecolor,loc1=loc1,loc2=loc2)
|
1485
|
+
|
1486
|
+
if indicator=='单位净值':
|
1487
|
+
ylabeltxt=texttranslate('单位净值(元)')
|
1488
|
+
plot_line(dfp,colname1,label1,ylabeltxt,titletxt,footnote,power=power,loc=loc1, \
|
1489
|
+
average_value=average_value,facecolor=facecolor)
|
1490
|
+
|
1491
|
+
if indicator=='累计净值':
|
1492
|
+
ylabeltxt=texttranslate('累计净值(元)')
|
1493
|
+
plot_line(dfp,colname2,label2,ylabeltxt,titletxt,footnote,power=power,loc=loc1, \
|
1494
|
+
average_value=average_value,facecolor=facecolor)
|
1286
1495
|
|
1287
1496
|
return dfp
|
1288
1497
|
|
@@ -17,7 +17,7 @@ siat/capm_beta.py,sha256=cxXdRVBQBllhbfz1LeTJAIWvyRYhW54nhtNUXv4HwS0,29063
|
|
17
17
|
siat/capm_beta2.py,sha256=UOI4sCz3ld7yezlARqPHvgHzfduDiGeRqNa82dDTCZ8,25849
|
18
18
|
siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
|
19
19
|
siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
|
20
|
-
siat/common.py,sha256=
|
20
|
+
siat/common.py,sha256=kGsyiuYJX-Y8VNb2mmspSp7rNc5r8eexxEt9JiKmwHM,143250
|
21
21
|
siat/compare_cross.py,sha256=3iP9TH2h3w27F2ARZc7FjKcErYCzWRc-TPiymOyoVtw,24171
|
22
22
|
siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
|
23
23
|
siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
|
@@ -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
|