siat 3.4.37__py3-none-any.whl → 3.5.2__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/sector_china.py CHANGED
@@ -731,7 +731,7 @@ def sector_position_china(ticker,sector="new_dlhy"):
731
731
 
732
732
  #==============================================================================
733
733
 
734
- def invest_concept_china(num=10):
734
+ def invest_concept_china(num=10,max_sleep=30):
735
735
  """
736
736
  废弃!
737
737
  功能:汇总投资概念股票名单,排行
@@ -755,7 +755,7 @@ def invest_concept_china(num=10):
755
755
 
756
756
  import pandas as pd
757
757
  totaldf=pd.DataFrame()
758
- import time
758
+ import time; import random
759
759
  i=0
760
760
  #新浪财经有反爬虫,这个循环做不下去
761
761
  for c in clist:
@@ -769,7 +769,10 @@ def invest_concept_china(num=10):
769
769
  print(', failed:-(')
770
770
  #continue
771
771
  #等待一会儿,避免被禁访问
772
- time.sleep(10)
772
+ #time.sleep(max_sleep)
773
+ random_int=random.randint(1,max_sleep)
774
+ time.sleep(random_int)
775
+
773
776
  i=i+1
774
777
  if i % 20 == 0:
775
778
  print(int(i/cnum*100),'\b%',end=' ')
@@ -804,7 +807,7 @@ def invest_concept_china(num=10):
804
807
  #==============================================================================
805
808
  def industry_sw_list_all():
806
809
  """
807
- 功能:输出申万指数所有代码df。动态,每次重新获取
810
+ 功能:输出申万指数所有代码df。动态,每次重新获取,自动更新!
808
811
  输入:
809
812
  输出:df,包括市场表征指数F,一级行业指数I,二级行业T,风格指数S,三级行业3
810
813
  """
@@ -816,6 +819,7 @@ def industry_sw_list_all():
816
819
  industry=pd.DataFrame()
817
820
  for s in symboltypes:
818
821
  try:
822
+ #目前有问题!
819
823
  dft = ak.index_realtime_sw(symbol=s)
820
824
  except: continue
821
825
 
@@ -944,38 +948,62 @@ if __name__=='__main__':
944
948
  iname='食品饮料'
945
949
  iname='银行'
946
950
  iname='汽车'
951
+ iname='高价股指数'
952
+ iname='申万A指'
953
+ iname='大类风格-医药医疗'
954
+
947
955
  numberPerLine=5
948
956
  colalign='right'
949
957
 
950
958
  print_industry_component_sw(iname,numberPerLine=5,colalign='right')
951
959
 
952
- def print_industry_component_sw(iname,numberPerLine=5,colalign='left',return_result=False):
960
+ def print_industry_component_sw(iname,numberPerLine=5,colalign='left', \
961
+ printout=True,return_result=False):
953
962
  """
954
963
  打印申万行业的成分股,名称(代码)
955
964
  """
956
965
  try:
957
966
  icode=industry_sw_code(iname)
958
967
  except:
959
- print(" #Warning(print_industry_component_sw): sector or industry name not found for",iname)
960
- return
968
+ print(" #Warning(print_industry_component_sw): failed to find index name for",iname)
969
+ if return_result:
970
+ return []
971
+ else:
972
+ return
973
+
974
+ if icode=='':
975
+ print(" #Warning(print_industry_component_sw): relevent index code not found for",iname)
976
+ if return_result:
977
+ return []
978
+ else:
979
+ return
980
+
981
+ clist,cdf=industry_stock_sw(icode,top=1000)
982
+ if clist is None:
983
+ if return_result:
984
+ print(" #Warning(print_industry_component_sw): no component stock found for",iname)
985
+ return []
986
+ else:
987
+ return
961
988
 
962
- clist,cdf=industry_stock_sw(icode,top=1000)
963
-
964
989
  #cdf['icode']=cdf['证券代码'].apply(lambda x: x+'.SS' if x[:1] in ['6'] else (x+'.SZ' if x[:1] in ['0','3'] else x+'.BJ' ))
965
990
  cdf['icode']=cdf['证券代码']
966
991
 
967
992
  # 删除'证券名称'为None的行
968
993
  cdf=cdf.mask(cdf.eq('None')).dropna()
969
- cdf['name_code']=cdf.apply(lambda x: x['证券名称']+'('+x['icode']+')',axis=1)
970
994
 
971
- #标题
972
- import datetime as dt; stoday=dt.date.today()
995
+ # 合成证券名称与代码
996
+ cdf['name_code']=cdf.apply(lambda x: x['证券名称']+'('+x['icode']+')',axis=1)
973
997
  ilist=list(cdf['name_code'])
974
998
 
975
- titletxt=iname+"("+icode+")行业/板块成分股:计"+str(len(ilist))+'只,按行业指数权重降序排列,'+str(stoday)
976
- print("\n"+titletxt,end='')
977
- #表格
978
- printInLine_md(ilist,numberPerLine=numberPerLine,colalign=colalign)
999
+ if printout:
1000
+ #标题
1001
+ import datetime as dt; stoday=dt.date.today()
1002
+
1003
+ titletxt=iname+"("+icode+")行业/板块成分股:计"+str(len(ilist))+'只,按行业指数权重降序排列,'+str(stoday)
1004
+ print("\n"+titletxt,end='')
1005
+ #表格
1006
+ printInLine_md(ilist,numberPerLine=numberPerLine,colalign=colalign)
979
1007
 
980
1008
  if return_result:
981
1009
  return ilist
@@ -1025,6 +1053,8 @@ def print_industry_component_sw2(icode,numberPerLine=5,colalign='left'):
1025
1053
 
1026
1054
  #==============================================================================
1027
1055
  if __name__=='__main__':
1056
+ iname='大类风格--医药医疗'
1057
+
1028
1058
  industry_sw_code('光伏设备')
1029
1059
 
1030
1060
  def industry_sw_code(iname):
@@ -1108,7 +1138,10 @@ def industry_ranking_sw(start,end,measure='Exp Ret%', \
1108
1138
  """
1109
1139
  完整版,全流程
1110
1140
  功能:模板,遍历某类申万指数,计算某项业绩指标,汇集排序
1111
- itype: F表征指数,n=1/2/3行业指数,S风格指数,B大类风格指数,C金创指数
1141
+ itype:
1142
+ 股票类指数:F表征指数,n=1/2/3行业指数,S风格指数,B大类风格指数,C金创指数?
1143
+ 基金类指数:J1/2/3基础一二三级,JF特色指数
1144
+
1112
1145
  period="day"; choice of {"day", "week", "month"}
1113
1146
  绘图:柱状图,可选
1114
1147
  """
@@ -1133,13 +1166,22 @@ def industry_ranking_sw(start,end,measure='Exp Ret%', \
1133
1166
  fail_list=[]
1134
1167
  for i in ilist:
1135
1168
 
1136
- print(" Processing industry",i,"\b, please wait ...")
1169
+ print(" Processing index",i,"\b, please wait ...")
1137
1170
  #抓取指数价格,选取期间范围
1138
1171
  try:
1139
1172
  dft = ak.index_hist_sw(symbol=i,period="day")
1140
1173
  except:
1141
- fail_list=fail_list+[i]
1142
- continue
1174
+ try:
1175
+ dft = ak.index_hist_fund_sw(symbol=i,period="day")
1176
+ dft['代码']=i
1177
+ dft['收盘']=dft['收盘指数']
1178
+ dft['开盘']=dft['收盘指数']
1179
+ dft['最高']=dft['收盘指数']
1180
+ dft['最低']=dft['收盘指数']
1181
+ dft['成交量']=0; dft['成交额']=0
1182
+ except:
1183
+ fail_list=fail_list+[i]
1184
+ continue
1143
1185
 
1144
1186
  dft['ticker']=dft['代码']
1145
1187
  dft['date']=dft['日期'].apply(lambda x: pd.to_datetime(x))
@@ -1179,10 +1221,10 @@ def industry_ranking_sw(start,end,measure='Exp Ret%', \
1179
1221
  df['name']=df['ticker'].apply(lambda x: industry_sw_name(x))
1180
1222
  df.set_index('name',inplace=True)
1181
1223
  colname='value'
1182
- titletxt="行业分析:业绩排名"
1224
+ titletxt="行业/指数分析:业绩排名"
1183
1225
  import datetime; today=datetime.date.today()
1184
1226
  footnote0=ectranslate(measure)+' ==>\n'
1185
- footnote1='申万行业分类,观察期:'+start+'至'+iend+'\n'
1227
+ footnote1='申万行业/指数分类,观察期:'+start+'至'+iend+'\n'
1186
1228
  footnote2="数据来源: 申万宏源, "+str(today)
1187
1229
  footnote=footnote0+footnote1+footnote2
1188
1230
 
@@ -1190,11 +1232,12 @@ def industry_ranking_sw(start,end,measure='Exp Ret%', \
1190
1232
  #plot_barh2(df,colname,titletxt,footnote)
1191
1233
 
1192
1234
  if len(fail_list) > 0:
1193
- print(" Unable to retrieve",len(fail_list),"industry(ies) as follows:")
1235
+ print(" Unable to retrieve",len(fail_list),"industry(ies) as follows:",end='')
1194
1236
  if len(fail_list) >= 10:
1195
1237
  printInLine_md(fail_list,numberPerLine=10,colalign='left',font_size='16px')
1196
1238
  else:
1197
1239
  printInLine_md(fail_list,numberPerLine=len(fail_list),colalign='left',font_size='16px')
1240
+ print('') #空一行
1198
1241
 
1199
1242
  return df
1200
1243
 
@@ -1247,8 +1290,17 @@ def industry_ranking_sw2(industrylist,start,end,measure='Exp Ret%', \
1247
1290
  try:
1248
1291
  dft = ak.index_hist_sw(symbol=i,period="day")
1249
1292
  except:
1250
- print(" #Warning(industry_ranking_sw2): industry not found for",i)
1251
- continue
1293
+ try:
1294
+ dft = ak.index_hist_fund_sw(symbol=i,period="day")
1295
+ dft['代码']=i
1296
+ dft['收盘']=dft['收盘指数']
1297
+ dft['开盘']=dft['收盘指数']
1298
+ dft['最高']=dft['收盘指数']
1299
+ dft['最低']=dft['收盘指数']
1300
+ dft['成交量']=0; dft['成交额']=0
1301
+ except:
1302
+ print(" #Warning(industry_ranking_sw2): index not found for",i)
1303
+ continue
1252
1304
 
1253
1305
  dft['ticker']=dft['代码']
1254
1306
  dft['date']=dft['日期'].apply(lambda x: pd.to_datetime(x))
@@ -1291,10 +1343,10 @@ def industry_ranking_sw2(industrylist,start,end,measure='Exp Ret%', \
1291
1343
  df.dropna(inplace=True)
1292
1344
 
1293
1345
  colname='value'
1294
- titletxt="行业分析:业绩排名"
1346
+ titletxt="行业/指数分析:业绩排名"
1295
1347
  import datetime; today=datetime.date.today()
1296
1348
  footnote0=ectranslate(measure)+' ==>\n'
1297
- footnote1='申万行业分类,观察期:'+start+'至'+iend+'\n'
1349
+ footnote1='申万行业/指数分类,观察期:'+start+'至'+iend+'\n'
1298
1350
  footnote2="数据来源: 申万宏源, "+str(today)
1299
1351
  footnote=footnote0+footnote1+footnote2
1300
1352
 
@@ -1311,10 +1363,13 @@ if __name__=='__main__':
1311
1363
  period="day"
1312
1364
  industry_list='all'
1313
1365
 
1314
- def get_industry_sw(itype='1',period="day",industry_list='all',max_sleep=15):
1366
+ def get_industry_sw(itype='1',period="day",industry_list='all',max_sleep=30):
1315
1367
  """
1316
1368
  功能:遍历某类申万指数,下载数据
1317
- itype: F表征指数,n=1/2/3行业指数,S风格指数,B大类风格,C金创类
1369
+ itype:
1370
+ 股票类指数:F表征指数,n=1/2/3行业指数,S风格指数,B大类风格指数,C金创指数?
1371
+ 基金类指数:J1/2/3基础一二三级,JF特色指数
1372
+
1318
1373
  period="day"; choice of {"day", "week", "month"}
1319
1374
  industry_list: 允许选择部分行业
1320
1375
  """
@@ -1345,7 +1400,7 @@ def get_industry_sw(itype='1',period="day",industry_list='all',max_sleep=15):
1345
1400
  import datetime; import random; import time
1346
1401
  df=pd.DataFrame()
1347
1402
 
1348
- print(" Start searching industry data, it takes time, please wait ...")
1403
+ print(" Searching industry data, it takes time, please wait ...")
1349
1404
  num=len(ilist)
1350
1405
  if num <= 10:
1351
1406
  steps=5
@@ -1362,9 +1417,18 @@ def get_industry_sw(itype='1',period="day",industry_list='all',max_sleep=15):
1362
1417
  try:
1363
1418
  dft = ak.index_hist_sw(symbol=i,period="day")
1364
1419
  except:
1365
- #print(" #Warning(get_industry_sw): unsupported industry",i)
1366
- fail_list=fail_list+[i]
1367
- continue
1420
+ try:
1421
+ dft = ak.index_hist_fund_sw(symbol=i,period="day")
1422
+ dft['代码']=i
1423
+ dft['收盘']=dft['收盘指数']
1424
+ dft['开盘']=dft['收盘指数']
1425
+ dft['最高']=dft['收盘指数']
1426
+ dft['最低']=dft['收盘指数']
1427
+ dft['成交量']=0; dft['成交额']=0
1428
+ except:
1429
+ #print(" #Warning(get_industry_sw): unsupported industry",i)
1430
+ fail_list=fail_list+[i]
1431
+ continue
1368
1432
 
1369
1433
  dft['ticker']=dft['代码']
1370
1434
  dft['date']=dft['日期'].apply(lambda x: pd.to_datetime(x))
@@ -1393,11 +1457,8 @@ def get_industry_sw(itype='1',period="day",industry_list='all',max_sleep=15):
1393
1457
  time.sleep(random_int)
1394
1458
 
1395
1459
  #num=list(set(list(df['ticker'])))
1396
- if len(fail_list)==0:
1397
- print(" Successfully retrieved",len(df),"records in",len(ilist),"industries")
1398
- else:
1399
- print("\n Successfully retrieved",len(df),"records in",len(ilist),"industries")
1400
- #print(" Successfully retrieved",len(df),"records in",num,"industries")
1460
+ if len(df)>0:
1461
+ print(" Successfully retrieved",len(df),"records in",len(ilist)-len(fail_list),"industries")
1401
1462
 
1402
1463
  if len(fail_list) > 0:
1403
1464
  print(" Failed to retrieve",len(fail_list),"industry(ies) as follows:")
@@ -1421,7 +1482,7 @@ if __name__=='__main__':
1421
1482
  industry_list=['850831.SW','801785.SW','801737.SW','801194.SW',
1422
1483
  '801784.SW','801783.SW','801782.SW']
1423
1484
 
1424
- def get_industry_sw2(industry_list,period="day",max_sleep=15):
1485
+ def get_industry_sw2(industry_list,period="day",max_sleep=30):
1425
1486
  """
1426
1487
  功能:遍历指定的申万指数列表,下载数据
1427
1488
  period="day"; choice of {"day", "week", "month"}
@@ -1454,9 +1515,18 @@ def get_industry_sw2(industry_list,period="day",max_sleep=15):
1454
1515
  try:
1455
1516
  dft = ak.index_hist_sw(symbol=i,period="day")
1456
1517
  except:
1457
- #print(" #Warning(get_industry_sw): unsupported industry",i)
1458
- fail_list=fail_list+[i]
1459
- continue
1518
+ try:
1519
+ dft = ak.index_hist_fund_sw(symbol=i,period="day")
1520
+ dft['代码']=i
1521
+ dft['收盘']=dft['收盘指数']
1522
+ dft['开盘']=dft['收盘指数']
1523
+ dft['最高']=dft['收盘指数']
1524
+ dft['最低']=dft['收盘指数']
1525
+ dft['成交量']=0; dft['成交额']=0
1526
+ except:
1527
+ #print(" #Warning(get_industry_sw): unsupported industry",i)
1528
+ fail_list=fail_list+[i]
1529
+ continue
1460
1530
 
1461
1531
  dft['ticker']=dft['代码']
1462
1532
  dft['date']=dft['日期'].apply(lambda x: pd.to_datetime(x))
@@ -1484,11 +1554,9 @@ def get_industry_sw2(industry_list,period="day",max_sleep=15):
1484
1554
  time.sleep(random_int)
1485
1555
 
1486
1556
  #num=list(set(list(df['ticker'])))
1487
- if len(fail_list) > 0:
1488
- print("\n Successfully retrieved",len(df),"records in",len(ilist),"industries")
1489
- else:
1490
- print(" Successfully retrieved",len(df),"records in",len(ilist),"industries")
1491
- #print(" Successfully retrieved",len(df),"records in",num,"industries")
1557
+ if len(df) > 0:
1558
+ print("\n Successfully retrieved",len(df),"records in",len(ilist)-len(fail_list),"industries")
1559
+
1492
1560
  if len(fail_list) > 0:
1493
1561
  print(" Failed to retrieve",len(fail_list),"industry(ies) as follows:")
1494
1562
  if len(fail_list) >= 10:
@@ -1501,8 +1569,8 @@ def get_industry_sw2(industry_list,period="day",max_sleep=15):
1501
1569
 
1502
1570
  #==============================================================================
1503
1571
  if __name__=='__main__':
1504
- start='2018-1-1'
1505
- end='2022-10-31'
1572
+ start='2023-8-31'
1573
+ end='2024-9-30'
1506
1574
  df=get_industry_sw('F')
1507
1575
 
1508
1576
  def calc_industry_sw(df,start,end):
@@ -1514,7 +1582,7 @@ def calc_industry_sw(df,start,end):
1514
1582
  #检查日期的合理性
1515
1583
  result,start1,end1=check_period(start,end)
1516
1584
  if not result:
1517
- print(" #Error(calc_industry_sw): invalid date period",start,end)
1585
+ print(" #Warning(calc_industry_sw): invalid date period",start,end)
1518
1586
  return None
1519
1587
 
1520
1588
  #屏蔽函数内print信息输出的类
@@ -1672,10 +1740,10 @@ def rank_industry_sw(idf,measure='Exp Ret%',industries=[], \
1672
1740
  gdf1=gdf
1673
1741
 
1674
1742
  if printout or graph:
1675
- titletxt="行业板块分析:最新业绩排名"
1743
+ titletxt="行业板块/指数分析:最新业绩排名"
1676
1744
  import datetime; today=datetime.date.today()
1677
1745
  footnote0=ectranslate(measure)+' -->\n\n'
1678
- footnote1='申万行业分类,'+iend+'快照'
1746
+ footnote1='申万行业/指数分类,'+iend+'快照'
1679
1747
  footnote2='观察期:'+istart+'至'+iend+','
1680
1748
  footnote3="数据来源: 申万宏源, "+str(today)+'统计'
1681
1749
  footnote=footnote0+footnote1+'\n'+footnote2+footnote3
@@ -1684,7 +1752,7 @@ def rank_industry_sw(idf,measure='Exp Ret%',industries=[], \
1684
1752
  gdf2=gdf1.sort_values(by=measure,ascending=False)
1685
1753
  gdf2.reset_index(inplace=True)
1686
1754
  gdf2.index=gdf2.index+1
1687
- gdf2.columns=['行业名称','行业代码',ectranslate(measure),'开始日期','结束日期']
1755
+ gdf2.columns=['行业/指数名称','行业/指数代码',ectranslate(measure),'开始日期','结束日期']
1688
1756
  """
1689
1757
  print("***",titletxt,'\n')
1690
1758
  alignlist=['center']+['left']*(len(list(gdf2))-1)
@@ -1705,7 +1773,7 @@ def rank_industry_sw(idf,measure='Exp Ret%',industries=[], \
1705
1773
  footnote=footnote0+footnote1+'\n'+footnote2+footnote3
1706
1774
  plot_barh(gdf1,colname,titletxt,footnote,axisamp=axisamp)
1707
1775
  else: #使用plotly_express
1708
- titletxt="行业板块业绩排名:"+ectranslate(measure)
1776
+ titletxt="行业板块/指数业绩排名:"+ectranslate(measure)
1709
1777
  footnote=footnote1+'。'+footnote2+footnote3
1710
1778
  plot_barh2(gdf1,colname,titletxt,footnote)
1711
1779
  else:
@@ -1772,6 +1840,11 @@ def compare_mindustry_sw(industry_list,measure,start,end, \
1772
1840
 
1773
1841
  #获取数据
1774
1842
  ddf=get_industry_sw(itype=itype,period=period,industry_list=industry_list)
1843
+ found=df_have_data(ddf)
1844
+ if not found=='Found':
1845
+ print(" #Warning(compare_mindustry_sw): data tentatively unavailable for group",itype)
1846
+ print(" Data is sometimes unavialble at certain tie points, eg public holidays")
1847
+ return None
1775
1848
 
1776
1849
  #计算指标
1777
1850
  _,idf=calc_industry_sw(ddf,start,end)
@@ -1815,13 +1888,13 @@ def compare_mindustry_sw(industry_list,measure,start,end, \
1815
1888
  dfs1=dfs[(dfs.index >= istartpd) & (dfs.index <= iendpd)]
1816
1889
 
1817
1890
  y_label=measure
1818
- title_txt="行业板块分析:市场业绩趋势与评价"
1891
+ title_txt="行业板块/指数分析:市场业绩趋势与评价"
1819
1892
  import datetime; today = datetime.date.today()
1820
1893
  if graph:
1821
1894
  colname=measure
1822
1895
 
1823
1896
  import datetime; today=datetime.date.today()
1824
- footnote1='\n申万行业分类,观察期:'+istart+'至'+iend+'\n'
1897
+ footnote1='\n申万行业/指数分类,观察期:'+istart+'至'+iend+'\n'
1825
1898
  footnote2="数据来源: 申万宏源, "+str(today)+'统计'
1826
1899
  footnote=footnote1+footnote2
1827
1900
 
@@ -1905,6 +1978,11 @@ def compare_mindustry_sw2(industry_list,measure,start,end, \
1905
1978
 
1906
1979
  #获取数据
1907
1980
  ddf=get_industry_sw2(industry_list=industry_list,period=period)
1981
+ found=df_have_data(ddf)
1982
+ if not found=='Found':
1983
+ print(" #Warning(compare_mindustry_sw): data tentatively unavailable for",industry_list)
1984
+ print(" Data is sometimes unavialble at certain tie points, eg public holidays")
1985
+ return None
1908
1986
 
1909
1987
  #计算指标
1910
1988
  _,idf=calc_industry_sw(ddf,start,end)
@@ -1948,13 +2026,13 @@ def compare_mindustry_sw2(industry_list,measure,start,end, \
1948
2026
  dfs1=dfs[(dfs.index >= istartpd) & (dfs.index <= iendpd)]
1949
2027
 
1950
2028
  y_label=measure
1951
- title_txt="行业(板块)分析:市场业绩趋势与评价"
2029
+ title_txt="行业(板块)/指数分析:市场业绩趋势与评价"
1952
2030
  import datetime; today = datetime.date.today()
1953
2031
  if graph:
1954
2032
  colname=measure
1955
- title_txt="行业(板块)分析:市场业绩趋势"
2033
+ title_txt="行业(板块)/指数分析:市场业绩趋势"
1956
2034
  import datetime; today=datetime.date.today()
1957
- footnote1='\n申万行业分类,观察期:'+istart+'至'+iend+'\n'
2035
+ footnote1='\n申万行业/指数分类,观察期:'+istart+'至'+iend+'\n'
1958
2036
  footnote2="数据来源: 申万宏源, "+str(today)+'统计'
1959
2037
  footnote=footnote1+footnote2
1960
2038
 
@@ -2088,10 +2166,10 @@ def compare_industry_sw(idfall,industry_list,measure,graph=True):
2088
2166
  if graph:
2089
2167
  y_label=measure
2090
2168
  colname=measure
2091
- title_txt="行业板块分析:市场业绩趋势"
2169
+ title_txt="行业板块/指数分析:市场业绩趋势"
2092
2170
 
2093
2171
  import datetime; today=datetime.date.today()
2094
- footnote1='\n申万行业分类,观察期:'+istart+'至'+iend+'\n'
2172
+ footnote1='\n申万行业/指数分类,观察期:'+istart+'至'+iend+'\n'
2095
2173
  footnote2="数据来源: 申万宏源, "+str(today)+'统计'
2096
2174
  footnote=footnote1+footnote2
2097
2175
 
@@ -2147,11 +2225,11 @@ def compare_industry_sw_sharpe(idfall,industries,base_return='Annual Ret%',graph
2147
2225
  sdf=atmp[industrylist]
2148
2226
  if graph:
2149
2227
  y_label='夏普比率(基于'+ectranslate(base_return)+')'
2150
- title_txt="行业板块分析:市场发展趋势"
2228
+ title_txt="行业板块/指数分析:市场发展趋势"
2151
2229
 
2152
2230
  istart=sdf.index[0].strftime('%Y-%m-%d')
2153
2231
  iend=sdf.index[-1].strftime('%Y-%m-%d')
2154
- footnote1='\n申万行业分类,观察期:'+istart+'至'+iend+'\n'
2232
+ footnote1='\n申万行业/指数分类,观察期:'+istart+'至'+iend+'\n'
2155
2233
  import datetime; today=datetime.date.today()
2156
2234
  #footnote2="数据来源: 申万宏源, "+str(today)+'统计(未计入无风险利率)'
2157
2235
  footnote2="数据来源: 申万宏源, "+str(today)+'统计'
@@ -2211,10 +2289,10 @@ def rank_industry_sw_sharpe(idfall,base_return='Exp Ret%',graph=True,axisamp=0.8
2211
2289
 
2212
2290
  if graph:
2213
2291
  colname=col
2214
- titletxt="行业板块分析:最新业绩排名"
2292
+ titletxt="行业板块/指数分析:最新业绩排名"
2215
2293
  import datetime; today=datetime.date.today()
2216
2294
  footnote0='夏普比率(基于'+ectranslate(base_return)+') -->\n\n'
2217
- footnote1='申万行业分类,'+iend+'快照'
2295
+ footnote1='申万行业/指数分类,'+iend+'快照'
2218
2296
  footnote2='观察期:'+istart+'至'+iend+','
2219
2297
  footnote3="数据来源: 申万宏源, "+str(today)+'统计'
2220
2298
  footnote=footnote0+footnote1+'\n'+footnote2+footnote3
@@ -2222,7 +2300,7 @@ def rank_industry_sw_sharpe(idfall,base_return='Exp Ret%',graph=True,axisamp=0.8
2222
2300
  footnote=footnote0+footnote1+'\n'+footnote2+footnote3
2223
2301
  plot_barh(dftail3,colname,titletxt,footnote,axisamp=axisamp)
2224
2302
  else: #使用plotly_express
2225
- titletxt="行业板块业绩排名:夏普比率(基于"+ectranslate(base_return)+')'
2303
+ titletxt="行业板块/指数业绩排名:夏普比率(基于"+ectranslate(base_return)+')'
2226
2304
  footnote=footnote1+'。'+footnote2+footnote3
2227
2305
  plot_barh2(dftail3,colname,titletxt,footnote)
2228
2306
 
@@ -2235,6 +2313,8 @@ if __name__=='__main__':
2235
2313
  industry='801193.SW'
2236
2314
  industry='851811.SW'
2237
2315
  industry='801181.SW'
2316
+ industry='801841.SW'
2317
+
2238
2318
  top=5
2239
2319
  df=industry_stock_sw(industry)
2240
2320
 
@@ -2257,10 +2337,14 @@ def industry_stock_sw(industry='801270.SW',top=5,printout=False):
2257
2337
  try:
2258
2338
  cdf = ak.index_component_sw(industry)
2259
2339
  except:
2260
- print(" #Warning(industry_stock_sw): failed to retrieve component info for",industry)
2261
- print(" Solution: upgrade akshare, restart jupyter and try again")
2340
+ print(" #Warning(industry_stock_sw): failed to retrieve component for index",industry)
2341
+ print(" Try solution: upgrade akshare, restart jupyter and try again")
2262
2342
  return None,None
2263
2343
 
2344
+ #去重,保留最新日期的记录
2345
+ cdf.sort_values(by=['证券代码','计入日期'],ascending=[True,False],inplace=True)
2346
+ cdf.drop_duplicates(subset=['证券代码'],keep='first',inplace=True)
2347
+
2264
2348
  # 删除'证券名称'为None的行
2265
2349
  cdf=cdf.mask(cdf.eq('None')).dropna()
2266
2350
  cdf_total=len(cdf)
@@ -2290,9 +2374,9 @@ def industry_stock_sw(industry='801270.SW',top=5,printout=False):
2290
2374
  if printout:
2291
2375
  if '.SW' not in industry:
2292
2376
  industry=industry+'.SW'
2293
- titletxt="申万行业指数成分股:"+industry_sw_name(industry)+'('+industry+')'
2377
+ titletxt="申万指数成分证券:"+industry_sw_name(industry)+'('+industry+')'
2294
2378
  import datetime as dt; todaydt=str(dt.date.today())
2295
- footnote="成分股总数:"+str(cdf_total)+",数据来源:申万宏源,"+str(todaydt)
2379
+ footnote="成分证券数量:"+str(cdf_total)+",申万宏源,"+str(todaydt)
2296
2380
 
2297
2381
  #df_directprint(cdf1,title_txt,footnote)
2298
2382
  df_display_CSS(cdf1,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=3, \
@@ -2355,6 +2439,11 @@ def get_industry_info_sw(start,end,itype='1'):
2355
2439
  print("\n*** Step 1:")
2356
2440
  # 获取行业历史数据,本步骤所需时间较长
2357
2441
  df=get_industry_sw(itype=itype)
2442
+ found=df_have_data(df)
2443
+ if not found=='Found':
2444
+ print(" #Warning(compare_mindustry_sw): data tentatively unavailable for group",itype)
2445
+ print(" Data is sometimes unavialble at certain time points, try again later")
2446
+ return None
2358
2447
 
2359
2448
  print("\n*** Step 2:")
2360
2449
  # 计算基础数据,本步骤所需时间较长
@@ -2389,6 +2478,11 @@ def get_industry_info_sw2(industry_list,start,end):
2389
2478
  print("\n*** Step 1:")
2390
2479
  # 获取行业历史数据,本步骤所需时间较长
2391
2480
  df=get_industry_sw2(industry_list)
2481
+ found=df_have_data(df)
2482
+ if not found=='Found':
2483
+ print(" #Warning(compare_mindustry_sw): data tentatively unavailable for",industry_list)
2484
+ print(" Data is sometimes unavialble at certain time points, try again later")
2485
+ return None
2392
2486
 
2393
2487
  print("\n*** Step 2:")
2394
2488
  # 计算基础数据,本步骤所需时间较长
@@ -2653,7 +2747,7 @@ def industry_correlation_sw(df,tickers,start,end, \
2653
2747
  elif pv< 0.001:
2654
2748
  ax1.text(n+widthx,m+widthy,'***',ha = 'center',color = 'k',fontdict=font_dict)
2655
2749
 
2656
- plt.title("行业板块"+info_type_cn+"之间的相关性")
2750
+ plt.title("行业板块/指数"+info_type_cn+"之间的相关性")
2657
2751
  plt.tick_params(labelsize=corr_size)
2658
2752
 
2659
2753
  footnote1="\n显著性数值:***非常显著(<0.001),**很显著(<0.01),*显著(<0.05),其余为不显著"
@@ -2661,7 +2755,7 @@ def industry_correlation_sw(df,tickers,start,end, \
2661
2755
 
2662
2756
  footnote3="\n观察期间: "+start+'至'+end
2663
2757
  import datetime as dt; stoday=dt.date.today()
2664
- footnote4=";来源:Sina/EM,"+str(stoday)+";基于申万行业分类"
2758
+ footnote4=";来源:Sina/EM,"+str(stoday)+";基于申万行业/指数分类"
2665
2759
 
2666
2760
  fontxlabel={'size':corr_size}
2667
2761
  plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontxlabel)
@@ -2865,8 +2959,17 @@ def get_sw_index(ticker,start,end):
2865
2959
  try:
2866
2960
  dft = ak.index_hist_sw(symbol=symbol,period="day")
2867
2961
  except:
2868
- print(" #Error(get_sw_index): failed to retrieve info for Shenwan industry index",symbol)
2869
- return None
2962
+ try:
2963
+ dft = ak.index_hist_fund_sw(symbol=symbol,period="day")
2964
+ dft['代码']=symbol
2965
+ dft['收盘']=dft['收盘指数']
2966
+ dft['开盘']=dft['收盘指数']
2967
+ dft['最高']=dft['收盘指数']
2968
+ dft['最低']=dft['收盘指数']
2969
+ dft['成交量']=0; dft['成交额']=0
2970
+ except:
2971
+ print(" #Error(get_sw_index): failed to retrieve index",symbol)
2972
+ return None
2870
2973
 
2871
2974
  dft['ticker']=dft['代码'].apply(lambda x: x+'.SW')
2872
2975
 
@@ -2979,7 +3082,8 @@ if __name__ =="__main__":
2979
3082
 
2980
3083
 
2981
3084
  def industry_scan_china(sw_level='F', \
2982
- indicator='Exp Ret%', \
3085
+ indicator='Exp Adj Ret%', \
3086
+ base_return='Exp Adj Ret%', \
2983
3087
  start='MRY',end='default', \
2984
3088
  RF=0, \
2985
3089
  printout='smart', \
@@ -2989,16 +3093,25 @@ def industry_scan_china(sw_level='F', \
2989
3093
  申万行业分类sw_level:F--市场表征(默认),S--投资风格(策略),B--大类风格,C--金创,
2990
3094
  1--一级行业,2--二级行业,3--三级行业
2991
3095
  评估期间start与end:允许MRM/MRQ/MRY(默认)/YTD/L3Y(近三年)/L5Y(近五年)
3096
+ base_return:计算sharpe和sortino比率使用的收益率类型。
3097
+ 当indicator不是sharpe或sortino比率时,base_return需要与indicator保持一致。
2992
3098
  RF:年化无风险收益率,默认0,可参照一年期国债收益率
2993
3099
  筛选方式printout:smart--收益前10名与后10名(默认),winner--仅限收益为正的行业,
2994
3100
  loser--仅限收益为负的行业,50--收益前50名,-10--收益后10名,all--所有行业
2995
3101
  """
2996
3102
  #indicator='Exp Ret%'
2997
3103
 
2998
- print(" Collecting industry info, it may take very long time ... ...")
3104
+ #print(" Evaluating industry performance, it may take up to hours ... ...")
3105
+
3106
+ #节省获取数据的量和时间
3107
+ if start=='MRY' and end=='default': #默认参数
3108
+ if 'Weekly' in indicator or 'Weekly' in base_return:
3109
+ start='MRM'
3110
+ if 'Monthly' in indicator or 'Monthly' in base_return:
3111
+ start='MRQ'
2999
3112
 
3000
3113
  # 检查申万行业
3001
- sw_level_list=['1','2','3','F','S','B','C']
3114
+ sw_level_list=['1','2','3','F','S','B','C','J1','J2','J3','JF']
3002
3115
  if sw_level not in sw_level_list:
3003
3116
  print(" #Warning(industry_scan_china): invalid Shenwan industry types for",sw_level)
3004
3117
  print(" Valid Shenwan industry types:",end='')
@@ -3006,14 +3119,38 @@ def industry_scan_china(sw_level='F', \
3006
3119
  return None
3007
3120
 
3008
3121
  # 检查支持的指标
3009
- indicator_list=['Exp Ret%','Exp Ret Volatility%','Exp Ret LPSD%', \
3010
- 'sharpe','sortino']
3122
+ base_return_list=['Exp Ret%','Exp Ret Volatility%','Exp Ret LPSD%', \
3123
+ 'Exp Adj Ret%','Exp Adj Ret Volatility%','Exp Adj Ret LPSD%', \
3124
+
3125
+ 'Annual Ret%','Annual Ret Volatility%','Annual Ret LPSD%', \
3126
+ 'Annual Adj Ret%','Annual Adj Ret Volatility%','Annual Adj Ret LPSD%', \
3127
+
3128
+ 'Quarterly Ret%','Quarterly Ret Volatility%','Quarterly Ret LPSD%', \
3129
+ 'Quarterly Adj Ret%','Quarterly Adj Ret Volatility%','Quarterly Adj Ret LPSD%', \
3130
+
3131
+ 'Monthly Ret%','Monthly Ret Volatility%','Monthly Ret LPSD%', \
3132
+ 'Monthly Adj Ret%','Monthly Adj Ret Volatility%','Monthly Adj Ret LPSD%', \
3133
+
3134
+ 'Weekly Ret%','Weekly Ret Volatility%','Weekly Ret LPSD%', \
3135
+ 'Weekly Adj Ret%','Weekly Adj Ret Volatility%','Weekly Adj Ret LPSD%', \
3136
+ ]
3137
+ if base_return not in base_return_list:
3138
+ print(" #Warning(industry_scan_china): unsupported base return type for",base_return)
3139
+ print(" Supported base return:")
3140
+ printlist(base_return_list,numperline=5,beforehand=' ',separator=', ')
3141
+ return None
3142
+
3143
+
3144
+ indicator_list=base_return_list + ['sharpe','sortino']
3145
+
3146
+ if indicator.lower() in ['sharpe','sortino']:
3147
+ indicator=indicator.lower()
3148
+
3011
3149
  if indicator not in indicator_list:
3012
3150
  print(" #Warning(industry_scan_china): unsupported indicator for",indicator)
3013
3151
  print(" Supported indicators:")
3014
3152
  printlist(indicator_list,numperline=5,beforehand=' ',separator=', ')
3015
3153
  return None
3016
-
3017
3154
 
3018
3155
  # 检查日期:
3019
3156
  fromdate,todate=start_end_preprocess(start,end)
@@ -3050,7 +3187,8 @@ def industry_scan_china(sw_level='F', \
3050
3187
  fromdate=date_adjust(todate,adjust=-31)
3051
3188
  """
3052
3189
  # 获取申万行业类别内部标识
3053
- itype_list=['1','2','3','F','S','B','C']
3190
+ #itype_list=['1','2','3','F','S','B','C']
3191
+ itype_list=sw_level_list
3054
3192
  pos=sw_level_list.index(sw_level)
3055
3193
  itype=itype_list[pos]
3056
3194
 
@@ -3060,21 +3198,68 @@ def industry_scan_china(sw_level='F', \
3060
3198
 
3061
3199
  # 循环获取行业指数,简单计算指数增长率,排序
3062
3200
  #print(" Retrieving industry info, which may need up to hours, take a break ...")
3063
- print("\n *** Step 1: Retrieving information")
3201
+ #print("\n *** Step 1: Retrieving industry information")
3202
+ print(" *** Step 1: ")
3064
3203
  # 获取行业历史数据,本步骤所需时间较长
3065
3204
  df=get_industry_sw(itype=itype)
3205
+ found=df_have_data(df)
3206
+ if not found=='Found':
3207
+ print(" #Warning(compare_mindustry_sw): data tentatively unavailable for group",itype)
3208
+ print(" Data is sometimes unavialble at certain time points, try again later")
3209
+ return None
3066
3210
 
3067
3211
  # 计算指标
3068
- print("\n *** Step 2: Computing indicators")
3212
+ #print("\n *** Step 2: Computing performance indicators")
3213
+ print("\n *** Step 2: ")
3069
3214
  # 计算基础数据,本步骤所需时间较长
3070
3215
  idf,idfall=calc_industry_sw(df,fromdate,todate)
3071
3216
 
3072
- RF_daily=RF/365*100 #百分数
3073
- #RF_daily=RF/365
3074
- RF_days=RF_daily * calculate_days(fromdate, todate)
3075
-
3076
- idf['sharpe']=(idf['Exp Ret%']-RF_days) / idf['Exp Ret Volatility%']
3077
- idf['sortino']=(idf['Exp Ret%']-RF_days) / idf['Exp Ret LPSD%']
3217
+ #设置base_return:非['sharpe','sortino']时
3218
+ if not indicator in ['sharpe','sortino']:
3219
+ #以下的判断顺序不可轻易改变
3220
+ if 'Ret Volatility%' in indicator:
3221
+ base_return=indicator.replace('Ret Volatility%','Ret%')
3222
+ elif 'Ret Volatility' in indicator:
3223
+ base_return=indicator.replace('Ret Volatility','Ret')
3224
+ elif 'Ret LPSD%' in indicator:
3225
+ base_return=indicator.replace('Ret LPSD%','Ret%')
3226
+ elif 'Ret LPSD' in indicator:
3227
+ base_return=indicator.replace('Ret LPSD','Ret')
3228
+ else:
3229
+ base_return=indicator
3230
+
3231
+
3232
+ #计算期间内的无风险收益率:RF为小数,而idf中的收益率为百分数
3233
+ if '%' in base_return:
3234
+ RFS=RF*100 #百分数
3235
+
3236
+ base_return_volatility=base_return.replace('Ret%','Ret Volatility%')
3237
+ base_return_lpsd=base_return.replace('Ret%','Ret LPSD%')
3238
+ else:
3239
+ RFS=RF
3240
+
3241
+ base_return_volatility=base_return.replace('Ret','Ret Volatility')
3242
+ base_return_lpsd=base_return.replace('Ret','Ret LPSD')
3243
+
3244
+ if 'Exp' in base_return:
3245
+ RF_daily=RFS/365
3246
+ RF_days=RF_daily * calculate_days(fromdate, todate)
3247
+
3248
+ elif 'Annual' in base_return:
3249
+ RF_days=RFS
3250
+
3251
+ elif 'Quarterly' in base_return:
3252
+ RF_days=RFS/4
3253
+
3254
+ elif 'Monthly' in base_return:
3255
+ RF_days=RFS/12
3256
+
3257
+ elif 'Weekly' in base_return:
3258
+ RF_days=RFS/52
3259
+
3260
+ idf['sharpe']=(idf[base_return]-RF_days) / idf[base_return_volatility]
3261
+ idf['sortino']=(idf[base_return]-RF_days) / idf[base_return_lpsd]
3262
+
3078
3263
 
3079
3264
  # 排序
3080
3265
  idf.sort_values(indicator,ascending=False,inplace=True)
@@ -3107,9 +3292,9 @@ def industry_scan_china(sw_level='F', \
3107
3292
  if printout=='all':
3108
3293
  df_prt=df2
3109
3294
  elif printout=='winner':
3110
- df_prt=df2[df2['Exp Ret%'] > 0]
3295
+ df_prt=df2[df2[indicator] > 0]
3111
3296
  elif printout=='loser':
3112
- df_prt=df2[df2['Exp Ret%'] <= 0]
3297
+ df_prt=df2[df2[indicator] <= 0]
3113
3298
  else:
3114
3299
  try:
3115
3300
  printoutd=int(printout)
@@ -3121,10 +3306,10 @@ def industry_scan_china(sw_level='F', \
3121
3306
  pass
3122
3307
 
3123
3308
  # 标题改中文
3124
- df_prt.rename(columns={'Industry Code':'行业代码','Industry Name':'行业名称', \
3125
- 'Exp Ret%':'投资收益率%', \
3126
- 'Exp Ret Volatility%':'投资收益波动率%', \
3127
- 'Exp Ret LPSD%':'投资收益损失风险%', \
3309
+ df_prt.rename(columns={'Industry Code':'代码','Industry Name':'名称', \
3310
+ base_return:ectranslate(base_return), \
3311
+ base_return_volatility:ectranslate(base_return_volatility), \
3312
+ base_return_lpsd:ectranslate(base_return_lpsd), \
3128
3313
  'sharpe':'夏普比率','sortino':'索替诺比率'}, \
3129
3314
  inplace=True)
3130
3315
 
@@ -3143,6 +3328,14 @@ def industry_scan_china(sw_level='F', \
3143
3328
  sw_level_txt='申万二级行业'
3144
3329
  elif sw_level=='3':
3145
3330
  sw_level_txt='申万三级行业'
3331
+ elif sw_level=='J1':
3332
+ sw_level_txt='申万基金基础一级指数'
3333
+ elif sw_level=='J2':
3334
+ sw_level_txt='申万基金基础二级指数'
3335
+ elif sw_level=='J3':
3336
+ sw_level_txt='申万基金基础三级指数'
3337
+ elif sw_level=='JF':
3338
+ sw_level_txt='申万基金特色指数'
3146
3339
  else:
3147
3340
  sw_level_txt='未知类别'
3148
3341
 
@@ -3161,9 +3354,9 @@ def industry_scan_china(sw_level='F', \
3161
3354
  num=int(printout)
3162
3355
  if len(df2) > abs(num):
3163
3356
  if num > 0:
3164
- printout_txt='收益前'+printout+"名"
3357
+ printout_txt='收益排名前'+printout+"名"
3165
3358
  else:
3166
- printout_txt='收益后'+str(abs(num))+"名"
3359
+ printout_txt='收益排名后'+str(abs(num))+"名"
3167
3360
  else:
3168
3361
  printout_txt='所有指数'
3169
3362
  except:
@@ -3171,7 +3364,7 @@ def industry_scan_china(sw_level='F', \
3171
3364
 
3172
3365
  #titletxt="申万行业业绩排行榜:"+sw_level_txt+',共'+str(len(df_prt))+"个指数符合条件"
3173
3366
  #titletxt="行业业绩排行榜:"+sw_level_txt+','+ectranslate(indicator)+',筛选方式:'+printout_txt
3174
- titletxt="中国股市板块表现排行榜:"+sw_level_txt+','+printout_txt
3367
+ titletxt="申万宏源行业/指数业绩龙虎榜:"+sw_level_txt+','+printout_txt
3175
3368
  #print("\n***",titletxt,'\n')
3176
3369
  """
3177
3370
  alignlist=['center']+['left']*(len(list(df_prt))-1)
@@ -3179,28 +3372,34 @@ def industry_scan_china(sw_level='F', \
3179
3372
  """
3180
3373
  #print("\n *** 数据来源:综合申万宏源/东方财富/新浪财经,",todaydt,"\b;分析期间:",fromdate+'至'+todate)
3181
3374
  #footnote1="筛选方式:all-所有,smart-收益最高最低各10个,winner-收益为正,loser-收益为负"
3182
- footnote2="数据来源:申万宏源,统计期间:"+str(fromdate)+'至'+str(todate)+"(截至昨日)。"+str(todaydt)+"制表"
3183
- #footnote=footnote1+'\n'+footnote2
3184
- footnote=footnote2
3375
+ footnote1="注:夏普/索梯诺比率基于"+ectranslate(base_return)+",年化无风险利率"+str(round(RF*100,4))+'%'
3376
+ footnote2="评估期间:"+str(fromdate)+''+str(todate)+",数据来源:申万宏源,"+str(todaydt)+"制表"
3377
+ footnote=footnote1+'\n'+footnote2
3378
+ #footnote=footnote2
3185
3379
 
3186
3380
  #确定表格字体大小
3187
3381
  titile_font_size=font_size
3188
3382
  heading_font_size=data_font_size=str(int(font_size.replace('px',''))-1)+'px'
3189
3383
 
3190
3384
  df_prt['序号']=df_prt.index
3191
- if indicator=='Exp Ret%':
3192
- df_prt=df_prt[['序号','行业名称','行业代码','投资收益率%','投资收益波动率%','投资收益损失风险%','夏普比率','索替诺比率']]
3193
- elif indicator=='Exp Ret Volatility%':
3194
- df_prt=df_prt[['序号','行业名称','行业代码','投资收益波动率%','投资收益率%','投资收益损失风险%','夏普比率','索替诺比率']]
3195
- elif indicator=='Exp Ret LPSD%':
3196
- df_prt=df_prt[['序号','行业名称','行业代码','投资收益损失风险%','投资收益波动率%','投资收益率%','夏普比率','索替诺比率']]
3197
- elif indicator=='sharpe':
3198
- df_prt=df_prt[['序号','行业名称','行业代码','夏普比率','索替诺比率','投资收益率%','投资收益波动率%','投资收益损失风险%']]
3385
+ if indicator=='sharpe':
3386
+ df_prt=df_prt[['序号','名称','代码','夏普比率','索替诺比率', \
3387
+ ectranslate(base_return),ectranslate(base_return_volatility),ectranslate(base_return_lpsd)]]
3199
3388
  elif indicator=='sortino':
3200
- df_prt=df_prt[['序号','行业名称','行业代码','索替诺比率','夏普比率','投资收益率%','投资收益波动率%','投资收益损失风险%']]
3201
-
3202
-
3389
+ df_prt=df_prt[['序号','名称','代码','索替诺比率','夏普比率', \
3390
+ ectranslate(base_return),ectranslate(base_return_volatility),ectranslate(base_return_lpsd)]]
3391
+
3392
+ elif 'Volatility' in indicator:
3393
+ df_prt=df_prt[['序号','名称','代码',ectranslate(base_return_volatility),ectranslate(base_return_lpsd), \
3394
+ ectranslate(base_return),'夏普比率','索替诺比率']]
3395
+ elif 'LPSD' in indicator:
3396
+ df_prt=df_prt[['序号','名称','代码',ectranslate(base_return_lpsd),ectranslate(base_return_volatility), \
3397
+ ectranslate(base_return),'夏普比率','索替诺比率']]
3398
+ else:
3399
+ df_prt=df_prt[['序号','名称','代码',ectranslate(base_return), \
3400
+ ectranslate(base_return_volatility),ectranslate(base_return_lpsd),'夏普比率','索替诺比率']]
3203
3401
 
3402
+ #显示表格
3204
3403
  df_display_CSS(df_prt,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
3205
3404
  first_col_align='center',second_col_align='left', \
3206
3405
  last_col_align='center',other_col_align='center', \
@@ -3233,12 +3432,12 @@ if __name__=='__main__':
3233
3432
 
3234
3433
  find_industry_sw(ticker)
3235
3434
 
3236
- def find_industry_sw(ticker,level='1',ticker_order=True,max_sleep=10):
3435
+ def find_industry_sw(ticker,level='1',ticker_order=True,max_sleep=30):
3237
3436
  """
3238
3437
  功能:寻找一只或一组股票所属的申万行业,支持股票代码和股票名称。
3239
3438
  level='1':默认只查找申万1级行业,以便节省时间
3240
3439
  ticker_order=True:默认输出结果按照ticker中的顺序,而非按照所属行业排序
3241
- max_sleep=8:为防止反爬虫,默认每次爬虫后睡眠最多几秒钟
3440
+ max_sleep:为防止反爬虫,默认每次爬虫后睡眠最多几秒钟
3242
3441
  """
3243
3442
  print(" Searching shenwan industries for securities ... ...")
3244
3443
 
@@ -3755,4 +3954,42 @@ def stock_peers_sw(ticker):
3755
3954
  print(footnote)
3756
3955
  return
3757
3956
 
3957
+ #==============================================================================
3958
+ if __name__ == '__main__':
3959
+ sw_index=['绩优股指数','大盘指数','中市盈率指数','高市净率指数',]
3960
+ sw_index=['大类风格-先进制造','大类风格--医药医疗']
3961
+
3962
+ index_intersection_sw(sw_index)
3963
+
3964
+ def index_intersection_sw(sw_index=[]):
3965
+ #寻找多个申万指数中共同的成分股
3966
+ if len(sw_index)==0:
3967
+ print(" #Warning(stock_intersection_sw): no index found for intersection")
3968
+ return
3969
+
3970
+ if isinstance(sw_index,str):
3971
+ sw_index=[sw_index]
3972
+
3973
+ result_list=[]
3974
+ for i in sw_index:
3975
+ try:
3976
+ ilist=print_industry_component_sw(i,printout=False,return_result=True)
3977
+ except:
3978
+ print(" #Warning(stock_intersection_sw): failed to find component for index",i)
3979
+ continue
3980
+
3981
+ if len(result_list)==0:
3982
+ result_list=[ilist]
3983
+ else:
3984
+ result_list=result_list+[ilist]
3985
+
3986
+ list_intersection(result_list)
3987
+
3988
+ return
3989
+ #==============================================================================
3990
+ #==============================================================================
3991
+ #==============================================================================
3992
+ #==============================================================================
3993
+ #==============================================================================
3994
+ #==============================================================================
3758
3995