siat 3.8.2__py3-none-any.whl → 3.8.20__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
- 最新修订日期:2024526
7
+ 最新修订日期:2025328
8
8
  作者:王德宏 (WANG Dehong, Peter)
9
9
  作者单位:北京外国语大学国际商学院
10
10
  版权所有:王德宏
@@ -19,6 +19,7 @@ from siat.common import *
19
19
  from siat.translate import *
20
20
  from siat.grafix import *
21
21
  from siat.bond_base import *
22
+ from siat.security_trend2 import *
22
23
  #==============================================================================
23
24
  def compare_fund_holding_china(ticker,quarters,rank=10,font_size='14px'):
24
25
  """
@@ -439,7 +440,7 @@ def reits_jsl_china(fund='',rank=10):
439
440
  df1 = ak.reits_info_jsl()
440
441
  df2 = ak.reits_realtime_em()
441
442
  except:
442
- print(" #Error(reits_jsl_china): sorry, data source has rejected access")
443
+ print("Sorry, data source rejected access")
443
444
  return None
444
445
 
445
446
  #合成基金类型信息
@@ -2687,8 +2688,566 @@ def fund_info_china(fund):
2687
2688
  #==============================================================================
2688
2689
  #==============================================================================
2689
2690
  #==============================================================================
2691
+ if __name__=='__main__':
2692
+ num_quarters=8
2693
+
2694
+ get_past_quarters()
2695
+
2696
+
2697
+ def get_past_quarters(num_quarters=8,date_format="%Y%m%d",date_reverse=False):
2698
+ """
2699
+ 功能:生成最近多个季度结束日期列表
2700
+ 参数:
2701
+ num_quarters:最近的季度个数,默认8.
2702
+
2703
+ 返回值:列表,日期格式为YYYYMMDD,适合akshare的要求
2704
+ """
2705
+
2706
+ from datetime import datetime, date
2707
+ from dateutil.relativedelta import relativedelta
2708
+
2709
+ # 获取当前日期
2710
+ today = date.today()
2711
+ # 确定当前季度的结束日期
2712
+ current_year = today.year
2713
+ current_month = today.month
2714
+ current_quarter = (current_month - 1) // 3 + 1 # 计算当前季度
2715
+ quarter_end_month = current_quarter * 3 # 当前季度的结束月份
2716
+ quarter_end_day = 31 if quarter_end_month in [3, 12] else 30 # 3月和12月是31天,其他季度末月份是30天
2717
+ current_quarter_end_date = date(current_year, quarter_end_month, quarter_end_day)
2718
+
2719
+ # 如果今天还没到季度末,需要调整为上一个季度的结束日期
2720
+ if today < current_quarter_end_date:
2721
+ current_quarter_end_date -= relativedelta(months=3)
2722
+ quarter_end_month = current_quarter_end_date.month
2723
+ quarter_end_day = 31 if quarter_end_month in [3, 12] else 30
2724
+ current_quarter_end_date = date(current_quarter_end_date.year, quarter_end_month, quarter_end_day)
2725
+
2726
+ # 生成过去连续的 num_quarters 个季度结束日期
2727
+ quarter_dates = []
2728
+ for _ in range(num_quarters):
2729
+ quarter_dates.append(current_quarter_end_date)
2730
+ current_quarter_end_date -= relativedelta(months=3)
2731
+
2732
+ current_year = current_quarter_end_date.year
2733
+ current_month = current_quarter_end_date.month
2734
+ quarter_end_day = 31 if current_month in [3, 12] else 30 # 3月和12月是31天,其他季度末月份是30天
2735
+ current_quarter_end_date = date(current_year, current_month, quarter_end_day)
2736
+
2737
+
2738
+ # 格式化日期为 YYYY-MM-DD
2739
+ quarter_dates = [date.strftime(date_format) for date in quarter_dates]
2740
+
2741
+ if not date_reverse:
2742
+ quarter_dates.reverse()
2743
+
2744
+ return quarter_dates
2745
+
2746
+
2690
2747
  #==============================================================================
2748
+ if __name__=='__main__':
2749
+ date_str='20241231'
2750
+ from_format="%Y%m%d"; to_format="%Y-%m-%d"
2751
+
2752
+ format_date(date_str,from_format="%Y%m%d",to_format="%Y-%m-%d")
2753
+
2754
+ def format_date(date_str,from_format="%Y%m%d",to_format="%Y-%m-%d"):
2755
+ # 将 YYYYMMDD 格式的字符串解析为日期对象
2756
+
2757
+ from datetime import datetime
2758
+
2759
+ date_obj = datetime.strptime(date_str, "%Y%m%d")
2760
+ # 将日期对象格式化为 YYYY-MM-DD 格式
2761
+ formatted_date = date_obj.strftime("%Y-%m-%d")
2762
+
2763
+ return formatted_date
2764
+
2691
2765
  #==============================================================================
2766
+ if __name__=='__main__':
2767
+ top=10
2768
+ sortby='持有基金家数'
2769
+ sortby='持股变动数值'
2770
+ holder_type="基金持仓"
2771
+
2772
+ def fund_holding_stock_rank_china(ticker='',top=5,sortby='持有基金家数',holder_type="基金持仓"):
2773
+ """
2774
+ ===========================================================================
2775
+ 功能:列出基金持股比例最高的股票及其持股信息
2776
+ 参数:
2777
+ ticker:股票代码,默认空'',对全市场股票进行排行;若指定股票代码,则着重显示该股票的排行。
2778
+ top=5:若不指定股票代码,列出基金持股比例最高的股票个数,默认10;
2779
+ 若指定股票代码,则列示该股票及其前后的排行。
2780
+ sortby:排行指标,默认'持有基金家数'。
2781
+ 支持指标:'持有基金家数','持股总数','持股市值','持股变动数值','持股变动比例'(百分比)
2782
+
2783
+ holder_type:持仓基金类别,默认"基金持仓"。
2784
+ 支持类别:"基金持仓", "QFII持仓", "社保持仓", "券商持仓", "保险持仓", "信托持仓"
2785
+ 1. 基金持仓:主要反映公募基金和私募基金的持仓情况。
2786
+ 2. QFII持仓:反映合格境外机构投资者(QFII)的持仓情况。
2787
+ 3. 社保持仓:反映社保基金的持仓情况。
2788
+ 4. 券商持仓:反映证券公司的自营业务持仓情况。
2789
+ 5. 保险持仓:反映保险资金的持仓情况。
2790
+ 6. 信托持仓:反映信托公司的持仓情况。
2791
+ 在东方财富网中,“基金持仓”不包括QFII持仓、社保持仓、券商持仓、保险持仓或信托持仓。
2792
+
2793
+ • 基金持仓:多样化投资策略,专业管理,透明度高,追求相对收益。
2794
+ 公募基金通常具有较高的流动性,投资者可以方便地申购和赎回。
2795
+ 公募基金通常追求超越基准指数的收益,注重长期业绩表现。
2796
+ • QFII持仓:注重基本面和估值,长期投资,偏好高ROE和成长股,行业集中度较高。
2797
+ QFII倾向于选择基本面良好、估值合理的股票,偏好行业龙头。
2798
+ QFII的投资策略较为长期,持股时间较长,注重公司的长期增长潜力。
2799
+ QFII偏好高净资产收益率(ROE)的个股,近年来也逐渐增加对成长股的投资。
2800
+ 重仓行业通常集中在相对安全、稳健的行业,如银行、食品饮料、医药等。
2801
+ QFII在市场趋势判断方面表现出色,能够在市场高点前加仓,在低点前减仓。
2802
+ • 社保持仓:长期价值投资,稳健投资,风险控制严格,市场风向标。
2803
+ 社保基金注重长期投资,追求稳定收益,通常持有股票的时间较长。
2804
+ 偏好稳健的股票,注重公司的基本面和盈利能力。
2805
+ 社保基金对风险控制要求高,投资决策较为谨慎。
2806
+ 社保基金的持仓变化被视为市场的风向标,其增仓或减仓行为可能预示市场趋势。
2807
+ • 券商持仓:灵活性高,信息优势,强周期性,注重短期收益。
2808
+ 券商可能更注重短期的市场波动和交易机会,追求短期收益。
2809
+ • 保险持仓:稳健保守,长期投资,资产配置多元化,风险控制严格。
2810
+ 保险资金注重资产的安全性和流动性,追求稳健收益。
2811
+ 保险资金的投资期限较长,通常进行长期投资。
2812
+ 对风险控制要求高,注重资产负债匹配管理。
2813
+ • 信托持仓:灵活性高,定制化服务,风险与收益平衡,专业管理。
2814
+ 信托可以根据委托人的需求提供定制化的投资方案。
2815
+
2816
+
2817
+ 返回值:df
2818
+ """
2819
+ holder_type_list=["基金持仓", "QFII持仓", "社保持仓", "券商持仓", "保险持仓", "信托持仓"]
2820
+ if not (holder_type in holder_type_list):
2821
+ print(f" #Warning(fund_holding_stock_rank): {holder_type} not supported")
2822
+ print(f" Supported types: {holder_type_list}")
2823
+ holder_type="基金持仓"
2824
+
2825
+ import akshare as ak
2826
+
2827
+ quarter_dates=get_past_quarters(num_quarters=4,date_format="%Y%m%d",date_reverse=False)
2828
+ recent_quarter_date=quarter_dates[-1]
2829
+ recent_quarter_date2=format_date(recent_quarter_date,from_format="%Y%m%d",to_format="%Y-%m-%d")
2830
+
2831
+ # symbol="基金持仓"; choice of {"基金持仓", "QFII持仓", "社保持仓", "券商持仓", "保险持仓", "信托持仓"}
2832
+ df = ak.stock_report_fund_hold(symbol=holder_type, date=recent_quarter_date)
2833
+
2834
+ sortby_list=['持有基金家数','持股总数','持股市值','持股变化','持股变动数值','持股变动比例']
2835
+ if sortby not in sortby_list:
2836
+ print(" #Warning: sortby option only supports the following:")
2837
+ print(f" {sortby_list}")
2838
+ sortby=sortby_list[0]
2839
+
2840
+ if sortby != '持有基金家数':
2841
+ df.sort_values(sortby,ascending=False,inplace=True)
2842
+ else:
2843
+ df = df.sort_values(by=[sortby, '持股总数'], ascending=[False, False])
2844
+
2845
+ df.reset_index(drop=True,inplace=True)
2846
+ df['序号']=df.index+1
2847
+
2848
+ # 挪动排名项目
2849
+ df=shift_column_position(df,sortby,position=3)
2850
+
2851
+ df2=df.copy()
2852
+
2853
+ wan=10000; yiyuan=100000000
2854
+ df2['持股总数'] =df2['持股总数']/wan
2855
+ df2['持股总数'] =df2['持股总数'].apply(lambda x: round(x,2))
2856
+
2857
+ df2['持股变动数值'] =df2['持股变动数值']/wan
2858
+ df2['持股变动数值'] =df2['持股变动数值'].apply(lambda x: round(x,2))
2859
+
2860
+ df2['持股市值'] =df2['持股市值']/yiyuan
2861
+ df2['持股市值'] =df2['持股市值'].apply(lambda x: round(x,2))
2862
+
2863
+ if top > 0:
2864
+ df3=df2.head(top)
2865
+ elif top < 0:
2866
+ df3=df2.tail(-top)
2867
+ else:
2868
+ df3=df2.head(5)
2869
+
2870
+ #强制显示所选股票
2871
+ #if force_show_stock and rank != 10:
2872
+ if ticker != '':
2873
+ #所选股票是否在其中?
2874
+ if not ticker[:6] in list(df3["股票代码"]):
2875
+ try:
2876
+ ticker_seq=df2[df2["股票代码"]==ticker[:6]]["序号"].values[0]
2877
+ except:
2878
+ print(f" #Error(fund_holding_stock_rank): {ticker} not found in {holder_type}")
2879
+ return None
2880
+
2881
+ num_before=int(top/2)
2882
+ if num_before * 2 == top: num_before=num_before-1
2883
+ num_after=top-num_before-1
2884
+
2885
+ #seq1=ticker_seq-4; seq2=ticker_seq+5
2886
+ seq1=ticker_seq-num_before; seq2=ticker_seq+num_after
2887
+ #如果超出开头
2888
+ if seq1 <=0:
2889
+ seq1=1; seq2=top
2890
+ #如果超出结尾
2891
+ if seq2 > len(df2):
2892
+ seq2=len(df2); seq1=len(df2)-(top-1)
2893
+
2894
+ #注意:此处的&不能换为and
2895
+ df3=df2[(df2["序号"]>=seq1) & (df2["序号"]<=seq2)]
2896
+
2897
+ titletxt=holder_type+'排名:基于'+sortby
2898
+ import datetime
2899
+ todaydt = datetime.date.today()
2900
+ #footnote0="【注释】排名方法:"+sortby
2901
+ footnote0="【注释】数据截至"+recent_quarter_date2
2902
+ footnote1=';持股总数/持股变动数值:万股,持股市值:亿元'
2903
+ footnote2='。数据来源:东方财富/天天基金,'+str(todaydt)
2904
+ footnote=footnote0+footnote1+footnote2
2905
+
2906
+ df_display_CSS(df3,titletxt=titletxt,footnote=footnote, \
2907
+ facecolor='papayawhip',decimals=2, \
2908
+ first_col_align='left',second_col_align='left', \
2909
+ last_col_align='right',other_col_align='right', \
2910
+ titile_font_size='16px',heading_font_size='15px', \
2911
+ data_font_size='14px',footnote_font_size='13px')
2912
+
2913
+ return df
2914
+
2915
+ #==============================================================================
2916
+ if __name__=='__main__':
2917
+ ticker='689009.SS'
2918
+ num_quarters=8
2919
+
2920
+
2921
+ def fund_holding_stock_trend_china(ticker,num_quarters=8,holder_type="基金持仓", \
2922
+ close_price=False):
2923
+ """
2924
+ ===========================================================================
2925
+ 功能:列出一只股票被基金持股的变动趋势
2926
+ 参数:
2927
+ ticker:股票代码
2928
+ num_quarters:最近基金持股的季度个数,默认8。
2929
+ holder_type:持仓基金类别,默认"基金持仓";若为'ALL'则扫描所有机构持股信息,时间较长。
2930
+
2931
+ 返回值:df
2932
+ """
2933
+ holder_type_list=["基金持仓", "QFII持仓", "社保持仓", "券商持仓", "保险持仓", "信托持仓"]
2934
+ if not (holder_type in holder_type_list):
2935
+ print(f" #Warning(fund_holding_stock_trend): {holder_type} not supported")
2936
+ print(f" Supported types: {holder_type_list}")
2937
+ holder_type="基金持仓"
2938
+
2939
+ import akshare as ak
2940
+ import pandas as pd
2941
+
2942
+ quarter_dates=get_past_quarters(num_quarters=num_quarters,date_format="%Y%m%d",date_reverse=False)
2943
+
2944
+
2945
+ df=pd.DataFrame()
2946
+ for d in quarter_dates:
2947
+ print(f" Searching {holder_type} info on {ticker} in {d} ...")
2948
+
2949
+ # symbol="基金持仓"; choice of {"基金持仓", "QFII持仓", "社保持仓", "券商持仓", "保险持仓", "信托持仓"}
2950
+ try:
2951
+ dftmp = ak.stock_report_fund_hold(symbol=holder_type, date=d)
2952
+ except:
2953
+ continue
2954
+
2955
+ try:
2956
+ dftmp2=dftmp[dftmp['股票代码']==ticker[:6]]
2957
+ except:
2958
+ break
2959
+
2960
+ d2=format_date(d,from_format="%Y%m%d",to_format="%Y-%m-%d")
2961
+ dftmp2['季度']=d2
2962
+ #dftmp2['机构类别']=holder_type
2963
+
2964
+
2965
+ if len(df)==0:
2966
+ df=dftmp2
2967
+ else:
2968
+ df=pd.concat([df, dftmp2], axis=0, ignore_index=True)
2969
+
2970
+ # 未找到股票
2971
+ if len(df)==0:
2972
+ print(f" #Error(fund_holding_stock_trend): stock {ticker} not found or not holded by fund")
2973
+ return None
2974
+
2975
+ # 重排字段
2976
+ stock_name=df['股票简称'].values[0]
2977
+ col_list=['季度','持股变化','持股变动数值','持股变动比例','持有基金家数','持股总数','持股市值']
2978
+ df2=df[col_list]
2979
+
2980
+
2981
+ wan=10000; yiyuan=100000000
2982
+ df2['持股总数'] =df2['持股总数']/wan
2983
+ df2['持股总数'] =df2['持股总数'].apply(lambda x: round(x,2))
2984
+
2985
+ df2['持股变动数值'] =df2['持股变动数值']/wan
2986
+ df2['持股变动数值'] =df2['持股变动数值'].apply(lambda x: round(x,2))
2987
+
2988
+ df2['持股市值'] =df2['持股市值']/yiyuan
2989
+ df2['持股市值'] =df2['持股市值'].apply(lambda x: round(x,2))
2990
+
2991
+ if not close_price:
2992
+ df4=df2
2993
+ else:
2994
+ ticker2=tickers_cvt2ak(ticker)
2995
+ fromdate=df2['季度'].values[0]; fromdate=date_adjust(fromdate, adjust=-30)
2996
+ todate=df2['季度'].values[-1]; todate=date_adjust(todate, adjust=30)
2997
+ result,start,end=check_period(fromdate,todate)
2998
+ start1=start.strftime('%Y%m%d'); end1=end.strftime('%Y%m%d')
2999
+ prices=security_trend(ticker,start=fromdate,end=todate,graph=False)
3000
+ prices.index = pd.to_datetime(prices.index, format='%Y-%m-%d')
3001
+ prices['收盘价']=prices['Close']
3002
+ prices['季度']=prices.index.strftime('%Y-%m-%d')
3003
+ prices2=prices[['季度','收盘价']]
3004
+
3005
+
3006
+ df3=pd.merge(df2,prices2,on='季度',how='outer')
3007
+ # 使用前一个非空值填充某一列的空缺值
3008
+ df3['收盘价'] = df3['收盘价'].fillna(method='ffill')
3009
+ # 使用后一个非空值填充某一列的空缺值
3010
+ df3['收盘价'] = df3['收盘价'].fillna(method='bfill')
3011
+ # 删除列 'A' 中包含空缺值的所有行
3012
+ df4 = df3.dropna(subset=['持有基金家数'])
3013
+
3014
+ titletxt=holder_type+'变动趋势:'+stock_name
3015
+ import datetime
3016
+ todaydt = datetime.date.today()
3017
+ #footnote0="【注释】排名方法:"+sortby
3018
+ footnote0="【注释】"
3019
+ footnote1='持股总数/持股变动数值:万股,持股市值:亿元'
3020
+ footnote2='。数据来源:东方财富/天天基金,'+str(todaydt)
3021
+ footnote=footnote0+footnote1+footnote2
3022
+
3023
+ df_display_CSS(df4,titletxt=titletxt,footnote=footnote, \
3024
+ facecolor='papayawhip',decimals=2, \
3025
+ first_col_align='left',second_col_align='left', \
3026
+ last_col_align='right',other_col_align='right', \
3027
+ titile_font_size='16px',heading_font_size='15px', \
3028
+ data_font_size='14px',footnote_font_size='13px')
3029
+
3030
+ return df
3031
+
3032
+ #==============================================================================
3033
+ if __name__=='__main__':
3034
+ ticker='689009.SS'
3035
+ ticker='600519.SS'
3036
+ num_quarters=8
3037
+
3038
+
3039
+ def fund_holding_stock_trend_all_china(ticker,num_quarters=4):
3040
+ """
3041
+ ===========================================================================
3042
+ 功能:列出一只股票被所有机构类别持股的变动趋势
3043
+ 参数:
3044
+ ticker:股票代码
3045
+ num_quarters:最近基金持股的季度个数,默认8。
3046
+
3047
+ 返回值:df
3048
+ """
3049
+ holder_type_list=["基金持仓", "QFII持仓", "社保持仓", "券商持仓", "保险持仓", "信托持仓"]
3050
+
3051
+ import akshare as ak
3052
+ import pandas as pd
3053
+
3054
+ quarter_dates=get_past_quarters(num_quarters=num_quarters,date_format="%Y%m%d",date_reverse=False)
3055
+
3056
+
3057
+ df=pd.DataFrame()
3058
+ for ht in holder_type_list:
3059
+ print(f" Searching {ht} info on {ticker} ...")
3060
+
3061
+ for d in quarter_dates:
3062
+
3063
+ try:
3064
+ dftmp = ak.stock_report_fund_hold(symbol=ht, date=d)
3065
+ except:
3066
+ continue
3067
+
3068
+ try:
3069
+ dftmp2=dftmp[dftmp['股票代码']==ticker[:6]]
3070
+ except:
3071
+ break
3072
+
3073
+ d2=format_date(d,from_format="%Y%m%d",to_format="%Y-%m-%d")
3074
+ dftmp2['季度']=d2
3075
+ dftmp2['机构类别']=ht
3076
+
3077
+
3078
+ if len(df)==0:
3079
+ df=dftmp2
3080
+ else:
3081
+ df=pd.concat([df, dftmp2], axis=0, ignore_index=True)
3082
+
3083
+ # 未找到股票
3084
+ if len(df)==0:
3085
+ print(f" #Error(fund_holding_stock_trend): stock {ticker} not found or not holded by fund")
3086
+ return None
3087
+
3088
+ # 重排字段
3089
+ stock_name=df['股票简称'].values[0]
3090
+ col_list=['季度','机构类别','持股变化','持股变动数值','持股变动比例','持有基金家数','持股总数','持股市值']
3091
+ df2=df[col_list]
3092
+ df2= df2.sort_values(['季度'],ascending=[True])
3093
+
3094
+
3095
+ wan=10000; yiyuan=100000000
3096
+ df2['持股总数'] =df2['持股总数']/wan
3097
+ df2['持股总数'] =df2['持股总数'].apply(lambda x: round(x,2))
3098
+
3099
+ df2['持股变动数值'] =df2['持股变动数值']/wan
3100
+ df2['持股变动数值'] =df2['持股变动数值'].apply(lambda x: round(x,2))
3101
+
3102
+ df2['持股市值'] =df2['持股市值']/yiyuan
3103
+ df2['持股市值'] =df2['持股市值'].apply(lambda x: round(x,2))
3104
+
3105
+ titletxt='机构持仓变动趋势:'+stock_name
3106
+ import datetime
3107
+ todaydt = datetime.date.today()
3108
+ #footnote0="【注释】排名方法:"+sortby
3109
+ footnote0="【注释】"
3110
+ footnote1='持股总数/持股变动数值:万股,持股市值:亿元'
3111
+ footnote2='。数据来源:东方财富/天天基金,'+str(todaydt)
3112
+ footnote=footnote0+footnote1+footnote2
3113
+
3114
+ df_display_CSS(df2,titletxt=titletxt,footnote=footnote, \
3115
+ facecolor='papayawhip',decimals=2, \
3116
+ first_col_align='left',second_col_align='left', \
3117
+ last_col_align='right',other_col_align='right', \
3118
+ titile_font_size='16px',heading_font_size='15px', \
3119
+ data_font_size='14px',footnote_font_size='13px')
3120
+
3121
+ return df
3122
+
3123
+
3124
+ #==============================================================================
3125
+ if __name__=='__main__':
3126
+ ticker='600519.SS'
3127
+ ticker='600305.SS'
3128
+ top=3
3129
+
3130
+ def stock_heldby_fund_detail_china(ticker,top=5):
3131
+ """
3132
+ ===========================================================================
3133
+ 功能:列示持有一只股票最多的前几名基金列表。
3134
+ 参数:
3135
+ ticker:股票代码
3136
+ top:列示前几名,默认5
3137
+
3138
+ 返回值:数据表
3139
+ """
3140
+
3141
+ import akshare as ak
3142
+
3143
+ # 获取某只股票被基金持股的数据
3144
+ try:
3145
+ df = ak.stock_fund_stock_holder(symbol=ticker[:6])
3146
+ except:
3147
+ print(f"Sorry, no fund holding details found for {ticker} in data source")
3148
+ return None
3149
+
3150
+ df2=df.copy()
3151
+
3152
+ wan=10000; yiyuan=100000000
3153
+ df2['持仓数量'] =df2['持仓数量']/wan
3154
+ df2['持仓数量'] =df2['持仓数量'].apply(lambda x: round(x,2))
3155
+
3156
+ df2['持股市值'] =df2['持股市值']/yiyuan
3157
+ df2['持股市值'] =df2['持股市值'].apply(lambda x: round(x,2))
3158
+
3159
+ # 按持股比例降序排列
3160
+ df3 = df2.sort_values(by='占流通股比例', ascending=False)
3161
+
3162
+ # 取前五名基金
3163
+ df4 = df3.head(top)
3164
+ df4['序号']=df4.index+1
3165
+ df4=shift_column_position(df4,col_name='序号',position=0)
3166
+
3167
+ ddl_date=df4['截止日期'].values[0]
3168
+ del df4['截止日期']
3169
+
3170
+ quarter_dates=get_past_quarters(num_quarters=8,date_format="%Y%m%d",date_reverse=False)
3171
+ recent_quarter_date=quarter_dates[-1]
3172
+ recent_quarter_date2=format_date(recent_quarter_date,from_format="%Y%m%d",to_format="%Y-%m-%d")
3173
+ if str(ddl_date) < str(recent_quarter_date2):
3174
+ print("Pity, fund holding stock info may be far out of date:-(")
3175
+
3176
+ titletxt=ticker_name(ticker)+':机构持仓情况,截至'+str(ddl_date)
3177
+ import datetime
3178
+ todaydt = datetime.date.today()
3179
+ #footnote0="【注释】排名方法:"+sortby
3180
+ footnote0="【注释】"
3181
+ footnote1='持仓数量:万股,持股市值:亿元'
3182
+ footnote2='。数据来源:新浪财经,'+str(todaydt)
3183
+ footnote=footnote0+footnote1+footnote2
3184
+
3185
+ df_display_CSS(df4,titletxt=titletxt,footnote=footnote, \
3186
+ facecolor='papayawhip',decimals=2, \
3187
+ first_col_align='center',second_col_align='left', \
3188
+ last_col_align='right',other_col_align='right', \
3189
+ titile_font_size='16px',heading_font_size='15px', \
3190
+ data_font_size='14px',footnote_font_size='13px')
3191
+
3192
+ return df
3193
+ #==============================================================================
3194
+
3195
+
3196
+
3197
+ def fund_holding_stock_china(ticker='',top=5,sortby='持有基金家数', \
3198
+ holder_type="基金持仓",quarter='recent', \
3199
+ detail=False, \
3200
+ close_price=False):
3201
+ """
3202
+ ===========================================================================
3203
+ 功能:列示中国内地机构持股情况。
3204
+ 参数:
3205
+ ticker:股票代码,默认'',列示最受机构追捧的股票排行及其被机构持仓情况。
3206
+ 若为一个股票代码,则列示该股票的排行情况及其被机构持仓情况。
3207
+ top:列示排行时的个数,默认5。
3208
+ sortby:当列示排行时标示排行的指标,默认'持有基金家数'。
3209
+ holder_type:机构持仓的类别,默认"基金持仓"。
3210
+ 当为ALL时列示所有机构类别的持仓情况。
3211
+ 仅有少数热门股票在除“基金持仓”以外的类别有数据,数据亦可能较久远。
3212
+ quarter:指示列示数据的季度,默认'recent'仅列示最近一个季度末的披露数据。
3213
+ 若为数字则列示近若干个季度的机构持仓变动趋势。
3214
+ 与holder_type='ALL'配合时列示近若干个季度的所有机构类别的持仓变动趋势。
3215
+ detail:是否列示持有一只股票的机构持仓情况,仅当ticker不为空时有效,默认False。
3216
+ close_price:当列示持有一只股票的机构持仓情况是否同时列示股价,默认False。
3217
+
3218
+ 返回值:数据表,无数据时返回空。
3219
+ """
3220
+
3221
+ if quarter=='recent' and holder_type.upper() != 'ALL' and not detail:
3222
+ df=fund_holding_stock_rank_china(ticker=ticker,top=top, \
3223
+ sortby=sortby,holder_type=holder_type)
3224
+
3225
+ elif ticker != '' and isinstance(quarter,int) and holder_type.upper() != 'ALL' and not detail:
3226
+ df=fund_holding_stock_trend_china(ticker=ticker,num_quarters=quarter, \
3227
+ holder_type=holder_type, \
3228
+ close_price=close_price)
3229
+
3230
+ elif ticker != '' and isinstance(quarter,int) and holder_type.upper() == 'ALL' and not detail:
3231
+ df=fund_holding_stock_trend_all_china(ticker=ticker,num_quarters=quarter)
3232
+
3233
+ elif ticker != '' and detail:
3234
+ df=stock_heldby_fund_detail_china(ticker=ticker,top=top)
3235
+
3236
+ else:
3237
+ print("Sorry, no idea on what you expect to do:-(")
3238
+
3239
+ return df
3240
+
3241
+
3242
+ #==============================================================================
3243
+ #==============================================================================
3244
+ #==============================================================================
3245
+ #==============================================================================
3246
+ #==============================================================================
3247
+ #==============================================================================
3248
+ #==============================================================================
3249
+ #==============================================================================
3250
+
2692
3251
 
2693
3252
 
2694
3253