siat 2.11.14__py3-none-any.whl → 2.12.1__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 +20 -11
- siat/market_china.py +19 -18
- siat/option_china.py +423 -54
- siat/valuation.py +13 -1
- siat/valuation_china.py +437 -14
- {siat-2.11.14.dist-info → siat-2.12.1.dist-info}/METADATA +2 -1
- {siat-2.11.14.dist-info → siat-2.12.1.dist-info}/RECORD +9 -9
- {siat-2.11.14.dist-info → siat-2.12.1.dist-info}/WHEEL +0 -0
- {siat-2.11.14.dist-info → siat-2.12.1.dist-info}/top_level.txt +0 -0
siat/valuation_china.py
CHANGED
@@ -442,24 +442,24 @@ if __name__=='__main__':
|
|
442
442
|
graph=True
|
443
443
|
loc='best'
|
444
444
|
|
445
|
-
def
|
445
|
+
def industry_valuation_history_sw_daily(industry,start,end,vtype='PE', \
|
446
446
|
graph=True,loc='best'):
|
447
447
|
"""
|
448
|
-
|
448
|
+
功能:绘制一个申万行业的日历史估值趋势,不支持二级三级行业分类
|
449
449
|
vtype: PE, PB, dividend
|
450
450
|
|
451
451
|
"""
|
452
452
|
#检查日期期间
|
453
453
|
result,start1,end1=check_period(start,end)
|
454
454
|
if not result:
|
455
|
-
print(" #Warning(
|
455
|
+
print(" #Warning(industry_valuation_history_sw_daily): invalid date period",start,end)
|
456
456
|
return None
|
457
457
|
|
458
458
|
#检查估值类型
|
459
459
|
typelist=['pe','pb','dividend']
|
460
460
|
vtypeu=vtype.lower()
|
461
461
|
if not (vtypeu in typelist):
|
462
|
-
print(" #Warning(
|
462
|
+
print(" #Warning(industry_valuation_history_sw_daily): unsupported valuation type",vtype)
|
463
463
|
print(" Supported types:",typelist)
|
464
464
|
return None
|
465
465
|
|
@@ -475,7 +475,7 @@ def industry_valuation_history_sw(industry,start,end,vtype='PE', \
|
|
475
475
|
# 不支持申万三级行业
|
476
476
|
df = ak.index_value_hist_funddb(symbol=sindustry, indicator=vtypes)
|
477
477
|
except:
|
478
|
-
print(" #Warning(
|
478
|
+
print(" #Warning(industry_valuation_history_sw_daily): failed to fetch industry info for",industry)
|
479
479
|
return None
|
480
480
|
|
481
481
|
import pandas as pd
|
@@ -491,7 +491,7 @@ def industry_valuation_history_sw(industry,start,end,vtype='PE', \
|
|
491
491
|
df2['平均值']=df2[vtypes].mean()
|
492
492
|
df2['中位数']=df2[vtypes].median()
|
493
493
|
|
494
|
-
titletxt="行业估值趋势:"+industry+','+vtypes
|
494
|
+
titletxt="行业估值趋势:"+industry_sw_name(industry)+','+vtypes
|
495
495
|
|
496
496
|
footnote0="注:申万宏源行业指数,"
|
497
497
|
footnote1=''
|
@@ -511,19 +511,372 @@ def industry_valuation_history_sw(industry,start,end,vtype='PE', \
|
|
511
511
|
return df2
|
512
512
|
|
513
513
|
if __name__=='__main__':
|
514
|
-
df=
|
515
|
-
df=
|
516
|
-
df=
|
514
|
+
df=industry_valuation_history_sw_daily(industry,start,end,vtype='PE')
|
515
|
+
df=industry_valuation_history_sw_daily(industry,start,end,vtype='PB')
|
516
|
+
df=industry_valuation_history_sw_daily(industry,start,end,vtype='dividend')
|
517
|
+
|
518
|
+
df=industry_valuation_history_sw_daily(industry='纺织服饰',start=start,end=end,vtype='PE')
|
519
|
+
df=industry_valuation_history_sw_daily(industry='纺织服饰',start=start,end=end,vtype='PB')
|
520
|
+
df=industry_valuation_history_sw_daily(industry='纺织服饰',start=start,end=end,vtype='dividend')
|
521
|
+
|
522
|
+
#==============================================================================
|
523
|
+
#==============================================================================
|
524
|
+
if __name__=='__main__':
|
525
|
+
adate='2023-12-14'
|
526
|
+
|
527
|
+
def get_last_friday(adate):
|
528
|
+
"""
|
529
|
+
功能:给定日期,找出上一个周五的日期,配合申万指数估值函数使用
|
530
|
+
"""
|
531
|
+
|
532
|
+
result,fdate=check_date2(adate)
|
533
|
+
if not result:
|
534
|
+
return None
|
535
|
+
|
536
|
+
import pendulum
|
537
|
+
wrk=pendulum.parse(fdate).day_of_week
|
538
|
+
|
539
|
+
import datetime
|
540
|
+
todaydt = datetime.date.today().strftime('%Y-%m-%d')
|
541
|
+
if fdate > todaydt:
|
542
|
+
fdate=todaydt
|
543
|
+
|
544
|
+
if wrk==5:
|
545
|
+
if fdate != todaydt:
|
546
|
+
adj=-1
|
547
|
+
else:
|
548
|
+
adj=-(2+wrk)
|
549
|
+
elif wrk==6:
|
550
|
+
adj=-1
|
551
|
+
else:
|
552
|
+
adj=-(2+wrk)
|
553
|
+
last_fri=date_adjust(fdate,adjust=adj)
|
554
|
+
|
555
|
+
return last_fri
|
556
|
+
|
557
|
+
if __name__=='__main__':
|
558
|
+
start='2023-1-1'
|
559
|
+
end='2023-12-14'
|
560
|
+
get_all_friday(start,end)
|
561
|
+
|
562
|
+
def get_all_friday(start,end):
|
563
|
+
"""
|
564
|
+
功能:获取start和end之间所有的周五日期,配合申万指数估值函数使用
|
565
|
+
"""
|
566
|
+
#import pandas as pd
|
567
|
+
start_fri=get_last_friday(start)
|
568
|
+
end_fri=get_last_friday(end)
|
569
|
+
|
570
|
+
import akshare as ak
|
571
|
+
wrk_df=ak.index_analysis_week_month_sw("week")
|
572
|
+
wrk_df['Date']=wrk_df['date'].apply(lambda x:x.strftime('%Y-%m-%d'))
|
573
|
+
frilist=list(wrk_df['Date'])
|
574
|
+
|
575
|
+
period_frilist=[]
|
576
|
+
for f in frilist:
|
577
|
+
if (f >= start_fri) and (f <= end_fri):
|
578
|
+
period_frilist=period_frilist+[f]
|
579
|
+
|
580
|
+
return period_frilist
|
581
|
+
|
582
|
+
#==============================================================================
|
583
|
+
|
584
|
+
if __name__=='__main__':
|
585
|
+
industry='食品饮料'
|
586
|
+
industry='白酒Ⅱ'
|
587
|
+
start='2023-10-1'
|
588
|
+
end='2023-12-15'
|
589
|
+
vtype='PE'
|
590
|
+
|
591
|
+
graph=True
|
592
|
+
loc='best'
|
593
|
+
df=industry_valuation_history_sw_weekly(industry,start,end,vtype)
|
594
|
+
|
595
|
+
def industry_valuation_history_sw_weekly(industry,start,end,vtype='PE', \
|
596
|
+
graph=True,loc='best'):
|
597
|
+
"""
|
598
|
+
功能:绘制一个申万行业的周历史估值趋势,支持申万"市场表征", "一级行业", "二级行业", "风格指数"
|
599
|
+
不支持三级行业,若为非二级行业,转为industry_valuation_history_sw_daily函数处理日数据,专注处理二级行业周数据
|
600
|
+
vtype: PE, PB, dividend
|
601
|
+
|
602
|
+
"""
|
603
|
+
#检查日期期间
|
604
|
+
result,start1,end1=check_period(start,end)
|
605
|
+
if not result:
|
606
|
+
print(" #Warning(industry_valuation_history_sw_weekly): invalid date period",start,end)
|
607
|
+
return None
|
608
|
+
fridays=get_all_friday(start,end)
|
609
|
+
|
610
|
+
#检查估值类型
|
611
|
+
typelist=['pe','pb','dividend']
|
612
|
+
vtypeu=vtype.lower()
|
613
|
+
if not (vtypeu in typelist):
|
614
|
+
print(" #Warning(industry_valuation_history_sw_weekly): unsupported valuation type",vtype)
|
615
|
+
print(" Supported types:",typelist)
|
616
|
+
return None
|
617
|
+
|
618
|
+
vtypelist=['pe','pb','dividend']
|
619
|
+
typelist=['市盈率','市净率','股息率']
|
620
|
+
pos=vtypelist.index(vtypeu)
|
621
|
+
vtypes=typelist[pos]
|
622
|
+
|
623
|
+
#分辨申万行业代码类别
|
624
|
+
sw_codes=industry_sw_list()
|
625
|
+
sw_codes['type_name']=''
|
626
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '市场表征' if x['type']=='F' else x['type_name'],axis=1)
|
627
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '一级行业' if x['type']=='I' else x['type_name'],axis=1)
|
628
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '二级行业' if x['type']=='T' else x['type_name'],axis=1)
|
629
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '风格指数' if x['type']=='S' else x['type_name'],axis=1)
|
630
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '三级行业' if x['type']=='3' else x['type_name'],axis=1)
|
631
|
+
|
632
|
+
industry1=industry.split('.')[0]
|
633
|
+
industry_name_flag=industry_code_flag=False
|
634
|
+
try:
|
635
|
+
type_name=sw_codes[sw_codes['name']==industry1]['type_name'].values[0]
|
636
|
+
industry_name_flag=True
|
637
|
+
except:
|
638
|
+
try:
|
639
|
+
type_name=sw_codes[sw_codes['code']==industry1]['type_name'].values[0]
|
640
|
+
industry_code_flag=True
|
641
|
+
except:
|
642
|
+
print(" #Error(industry_valuation_history_sw_weekly): Shenwan industry not found for",industry)
|
643
|
+
return None
|
644
|
+
|
645
|
+
if type_name=='三级行业':
|
646
|
+
print(" #Error(industry_valuation_history_sw_weekly): currently does not support Shenwan 3rd_level industry",industry)
|
647
|
+
return None
|
648
|
+
|
649
|
+
if not (type_name=='二级行业'):
|
650
|
+
df=industry_valuation_history_sw_daily(industry=industry,start=start,end=end,vtype=vtype, \
|
651
|
+
graph=graph,loc=loc)
|
652
|
+
return df
|
653
|
+
|
654
|
+
# 获取行业估值历史周数据
|
655
|
+
import pandas as pd
|
656
|
+
import akshare as ak
|
657
|
+
df=None
|
658
|
+
for f in fridays:
|
659
|
+
f1=f[:4]+f[5:7]+f[8:]
|
660
|
+
try:
|
661
|
+
dft=ak.index_analysis_weekly_sw(symbol=type_name, date=f1)
|
662
|
+
except:
|
663
|
+
continue
|
664
|
+
|
665
|
+
"""
|
666
|
+
dft的结构:
|
667
|
+
['指数代码','指数名称','发布日期','收盘指数','成交量','涨跌幅','换手率',
|
668
|
+
'市盈率','市净率','均价','成交额占比','流通市值','平均流通市值','股息率']
|
669
|
+
"""
|
670
|
+
|
671
|
+
if not (dft is None):
|
672
|
+
if industry_name_flag:
|
673
|
+
dft2=dft[dft['指数名称']==industry1]
|
674
|
+
if industry_code_flag:
|
675
|
+
dft2=dft[dft['指数代码']==industry1]
|
676
|
+
|
677
|
+
if df is None:
|
678
|
+
df=dft2
|
679
|
+
else:
|
680
|
+
df=pd.concat([df,dft2])
|
681
|
+
|
682
|
+
df['date']=pd.to_datetime(df['发布日期'])
|
683
|
+
df.set_index('date',inplace=True)
|
684
|
+
df1=df[[vtypes]]
|
517
685
|
|
518
|
-
|
519
|
-
|
520
|
-
|
686
|
+
#筛选期间
|
687
|
+
#df2=df1[(df1.index >= start1) & (df1.index <= end1)]
|
688
|
+
df2=df1.dropna()
|
689
|
+
|
690
|
+
#绘图
|
691
|
+
if graph:
|
692
|
+
df2['平均值']=df2[vtypes].mean()
|
693
|
+
df2['中位数']=df2[vtypes].median()
|
694
|
+
|
695
|
+
titletxt="行业估值趋势:"+industry+','+vtypes
|
696
|
+
|
697
|
+
footnote0="注:申万宏源行业指数,"
|
698
|
+
footnote1=''
|
699
|
+
import datetime
|
700
|
+
today = datetime.date.today()
|
701
|
+
footnote2="数据来源: 申万宏源,"+str(today)
|
702
|
+
footnote=footnote0+footnote1+footnote2
|
703
|
+
|
704
|
+
colname=vtypes
|
705
|
+
collabel=vtypes
|
706
|
+
ylabeltxt=vtypes
|
707
|
+
|
708
|
+
draw_lines(df2,y_label=ylabeltxt,x_label=footnote, \
|
709
|
+
axhline_value=0,axhline_label='', \
|
710
|
+
title_txt=titletxt,data_label=False,resample_freq='D')
|
711
|
+
|
712
|
+
return df2
|
521
713
|
|
522
714
|
#==============================================================================
|
715
|
+
|
716
|
+
if __name__=='__main__':
|
717
|
+
industry='食品饮料'
|
718
|
+
industry='白酒Ⅱ'
|
719
|
+
start='2023-10-1'
|
720
|
+
end='2023-12-15'
|
721
|
+
vtype='PE'
|
722
|
+
|
723
|
+
graph=True
|
724
|
+
loc='best'
|
725
|
+
df=industry_valuation_history_sw(industry,start,end,vtype)
|
726
|
+
|
727
|
+
def industry_valuation_history_sw(industry,start,end,vtype='PE', \
|
728
|
+
graph=True,loc='best'):
|
729
|
+
"""
|
730
|
+
功能:绘制一个申万行业的日历史估值趋势,支持申万"市场表征", "一级行业", "二级行业", "风格指数"
|
731
|
+
不支持三级行业,若为非二级行业,转为industry_valuation_history_sw_daily函数处理日数据,专注处理二级行业日数据
|
732
|
+
vtype: PE, PB, dividend
|
733
|
+
|
734
|
+
"""
|
735
|
+
#检查日期期间
|
736
|
+
result,start1,end1=check_period(start,end)
|
737
|
+
if not result:
|
738
|
+
print(" #Warning(industry_valuation_history_sw): invalid date period",start,end)
|
739
|
+
return None
|
740
|
+
|
741
|
+
#检查估值类型
|
742
|
+
typelist=['pe','pb','dividend']
|
743
|
+
vtypeu=vtype.lower()
|
744
|
+
if not (vtypeu in typelist):
|
745
|
+
print(" #Warning(industry_valuation_history_sw): unsupported valuation type",vtype)
|
746
|
+
print(" Supported types:",typelist)
|
747
|
+
return None
|
748
|
+
|
749
|
+
vtypelist=['pe','pb','dividend']
|
750
|
+
typelist=['市盈率','市净率','股息率']
|
751
|
+
pos=vtypelist.index(vtypeu)
|
752
|
+
vtypes=typelist[pos]
|
753
|
+
|
754
|
+
#分辨申万行业代码类别
|
755
|
+
sw_codes=industry_sw_list()
|
756
|
+
sw_codes['type_name']=''
|
757
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '市场表征' if x['type']=='F' else x['type_name'],axis=1)
|
758
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '一级行业' if x['type']=='I' else x['type_name'],axis=1)
|
759
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '二级行业' if x['type']=='T' else x['type_name'],axis=1)
|
760
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '风格指数' if x['type']=='S' else x['type_name'],axis=1)
|
761
|
+
sw_codes['type_name']=sw_codes.apply(lambda x: '三级行业' if x['type']=='3' else x['type_name'],axis=1)
|
762
|
+
|
763
|
+
industry1=industry.split('.')[0]
|
764
|
+
industry_name_flag=industry_code_flag=False
|
765
|
+
try:
|
766
|
+
type_name=sw_codes[sw_codes['name']==industry1]['type_name'].values[0]
|
767
|
+
industry_name_flag=True
|
768
|
+
except:
|
769
|
+
try:
|
770
|
+
type_name=sw_codes[sw_codes['code']==industry1]['type_name'].values[0]
|
771
|
+
industry_code_flag=True
|
772
|
+
except:
|
773
|
+
print(" #Error(industry_valuation_history_sw): Shenwan industry not found for",industry)
|
774
|
+
return None
|
775
|
+
|
776
|
+
if type_name=='三级行业':
|
777
|
+
print(" #Error(industry_valuation_history_sw): currently does not support Shenwan 3rd_level industry",industry)
|
778
|
+
return None
|
779
|
+
|
780
|
+
if not (type_name=='二级行业'):
|
781
|
+
df=industry_valuation_history_sw_daily(industry=industry,start=start,end=end,vtype=vtype, \
|
782
|
+
graph=graph,loc=loc)
|
783
|
+
return df
|
784
|
+
|
785
|
+
# 获取行业估值历史周数据
|
786
|
+
import pandas as pd
|
787
|
+
import akshare as ak
|
788
|
+
start2=start1.strftime('%Y-%m-%d')
|
789
|
+
end2 =end1.strftime('%Y-%m-%d')
|
790
|
+
pdate=end2
|
791
|
+
dstep=7
|
792
|
+
df=None
|
793
|
+
while (pdate >= start2) or (abs(date_delta(pdate,start2)) < dstep):
|
794
|
+
if pdate >= start2:
|
795
|
+
enddate=pdate
|
796
|
+
fromdate=date_adjust(pdate,adjust=-dstep)
|
797
|
+
else:
|
798
|
+
enddate=start2
|
799
|
+
fromdate=pdate
|
800
|
+
|
801
|
+
try:
|
802
|
+
fromdate1=fromdate[:4]+fromdate[5:7]+fromdate[8:10]
|
803
|
+
enddate1=enddate[:4]+enddate[5:7]+enddate[8:10]
|
804
|
+
dft=ak.index_analysis_daily_sw(symbol=type_name,start_date=fromdate1,end_date=enddate1)
|
805
|
+
except:
|
806
|
+
dft=None
|
807
|
+
"""
|
808
|
+
try:
|
809
|
+
fromdate1=fromdate[:4]+fromdate[5:7]+fromdate[8:10]
|
810
|
+
enddate1=enddate[:4]+enddate[5:7]+enddate[8:10]
|
811
|
+
dft=ak.index_analysis_daily_sw(symbol=type_name,start_date=fromdate1,end_date=enddate1)
|
812
|
+
except:
|
813
|
+
continue
|
814
|
+
"""
|
815
|
+
"""
|
816
|
+
dft的结构:
|
817
|
+
['指数代码','指数名称','发布日期','收盘指数','成交量','涨跌幅','换手率',
|
818
|
+
'市盈率','市净率','均价','成交额占比','流通市值','平均流通市值','股息率']
|
819
|
+
"""
|
820
|
+
|
821
|
+
if not (dft is None):
|
822
|
+
if industry_name_flag:
|
823
|
+
dft2=dft[dft['指数名称']==industry1]
|
824
|
+
if industry_code_flag:
|
825
|
+
dft2=dft[dft['指数代码']==industry1]
|
826
|
+
|
827
|
+
if df is None:
|
828
|
+
df=dft2
|
829
|
+
else:
|
830
|
+
df=pd.concat([df,dft2])
|
831
|
+
|
832
|
+
# 开始下一轮循环
|
833
|
+
pdate=date_adjust(fromdate,adjust=-1)
|
834
|
+
|
835
|
+
df.sort_values('发布日期',ascending=True,inplace=True)
|
836
|
+
df.drop_duplicates(inplace=True)
|
837
|
+
|
838
|
+
#df=df[df.index >= start1]
|
839
|
+
#df.dropna(inplace=True)
|
840
|
+
|
841
|
+
df['date']=pd.to_datetime(df['发布日期'])
|
842
|
+
df.set_index('date',inplace=True)
|
843
|
+
df1=df[[vtypes]]
|
844
|
+
|
845
|
+
#筛选期间
|
846
|
+
#df2=df1[(df1.index >= start1) & (df1.index <= end1)]
|
847
|
+
df2=df1
|
848
|
+
|
849
|
+
#绘图
|
850
|
+
if graph:
|
851
|
+
df2['平均值']=df2[vtypes].mean()
|
852
|
+
df2['中位数']=df2[vtypes].median()
|
853
|
+
|
854
|
+
titletxt="行业估值趋势:"+industry+','+vtypes
|
855
|
+
|
856
|
+
footnote0="注:申万行业分类指数,"
|
857
|
+
footnote1=''
|
858
|
+
import datetime
|
859
|
+
today = datetime.date.today()
|
860
|
+
footnote2="数据来源: 申万宏源,"+str(today)
|
861
|
+
footnote=footnote0+footnote1+footnote2
|
862
|
+
|
863
|
+
colname=vtypes
|
864
|
+
collabel=vtypes
|
865
|
+
ylabeltxt=vtypes
|
866
|
+
|
867
|
+
draw_lines(df2,y_label=ylabeltxt,x_label=footnote, \
|
868
|
+
axhline_value=0,axhline_label='', \
|
869
|
+
title_txt=titletxt,data_label=False,resample_freq='D')
|
870
|
+
|
871
|
+
return df2
|
872
|
+
|
873
|
+
#==============================================================================
|
874
|
+
#==============================================================================
|
523
875
|
if __name__=='__main__':
|
524
876
|
industries=['食品饮料','纺织服饰']
|
525
|
-
|
526
|
-
|
877
|
+
industries=['银行','国有大型银行Ⅱ','股份制银行Ⅱ','城商行Ⅱ','农商行Ⅱ']
|
878
|
+
start='2023-12-1'
|
879
|
+
end='2023-12-15'
|
527
880
|
vtypes='PE'
|
528
881
|
|
529
882
|
industries='纺织服饰'
|
@@ -532,6 +885,8 @@ if __name__=='__main__':
|
|
532
885
|
graph=True
|
533
886
|
loc1='lower left'
|
534
887
|
loc2='upper right'
|
888
|
+
|
889
|
+
df5=compare_industry_valuation_sw(industries,start,end,vtypes)
|
535
890
|
|
536
891
|
def compare_industry_valuation_sw(industries,start,end,vtypes='PE', \
|
537
892
|
graph=True,loc1='best',loc2='best'):
|
@@ -564,6 +919,8 @@ def compare_industry_valuation_sw(industries,start,end,vtypes='PE', \
|
|
564
919
|
import pandas as pd
|
565
920
|
df=pd.DataFrame()
|
566
921
|
for i in industries:
|
922
|
+
# debug
|
923
|
+
print(" ...Searching valuation info for",i,'\b, which may take time ...')
|
567
924
|
dft=industry_valuation_history_sw(i,start=start,end=end,vtype=vtype,graph=False)
|
568
925
|
if not (dft is None):
|
569
926
|
dft.rename(columns={vtypec:i},inplace=True)
|
@@ -1301,4 +1658,70 @@ def multi_ols(df,xList,y,industryDummies,yearDummies):
|
|
1301
1658
|
|
1302
1659
|
return coefMatrix
|
1303
1660
|
|
1661
|
+
#==============================================================================
|
1662
|
+
#==============================================================================
|
1663
|
+
#==============================================================================
|
1664
|
+
if __name__=='__main__':
|
1665
|
+
sw_code='850831.SW'
|
1666
|
+
sw_code='801193.SW'
|
1667
|
+
indicator='PE'
|
1668
|
+
start='2023-1-1'
|
1669
|
+
end='2023-12-15'
|
1670
|
+
top=10
|
1671
|
+
|
1672
|
+
def valuation_industry_sw_generating(sw_code,indicator,start,end,top=5):
|
1673
|
+
"""
|
1674
|
+
功能:模拟申万行业指数的估值,PE/PB/股息率等
|
1675
|
+
sw_code:申万行业分类指数,各个级别
|
1676
|
+
start/end:开始/结束日期
|
1677
|
+
top:使用前几大成分股的估值进行合成
|
1678
|
+
|
1679
|
+
注意:指数模拟出的估值曲线波动过大,缺乏实用价值!
|
1680
|
+
"""
|
1681
|
+
import pandas as pd
|
1682
|
+
#查找申万行业指数成分股
|
1683
|
+
clist,cdf=industry_stock_sw(industry=sw_code,top=top)
|
1684
|
+
|
1685
|
+
#查找成分股的历史估值
|
1686
|
+
df=None
|
1687
|
+
for t in clist:
|
1688
|
+
dft=get_stock_valuation_cn_hk(ticker=t,indicators=indicator,start=start,end=end)
|
1689
|
+
dft[t]=dft[indicator]
|
1690
|
+
dft2=dft[[t]]
|
1691
|
+
if dft2 is None: continue
|
1692
|
+
|
1693
|
+
#将负数填充为0,不计入估值?整个成分股剔除?
|
1694
|
+
dft2[t]=dft2[t].apply(lambda x: 0 if x<0 else x)
|
1695
|
+
|
1696
|
+
if df is None:
|
1697
|
+
df=dft2
|
1698
|
+
else:
|
1699
|
+
df=pd.merge(df,dft2,how='outer',left_index=True,right_index=True)
|
1700
|
+
|
1701
|
+
#成分股权重
|
1702
|
+
weight=list(cdf['最新权重'])
|
1703
|
+
|
1704
|
+
#各行权重分别求和
|
1705
|
+
dfw=df.copy()
|
1706
|
+
collist=list(dfw)
|
1707
|
+
for c in collist:
|
1708
|
+
dfw[c]=dfw[c].apply(lambda x: 0 if x<=0 else 1)
|
1709
|
+
dfw['weight']=dfw.dot(weight)
|
1710
|
+
dfw2=dfw[['weight']]
|
1711
|
+
|
1712
|
+
#加权平均
|
1713
|
+
df['weighted_total']=df.dot(weight)
|
1714
|
+
df2=pd.merge(df,dfw2,left_index=True,right_index=True)
|
1715
|
+
|
1716
|
+
df2['weighted_avg']=df2['weighted_total']/df2['weight']
|
1717
|
+
df2['code']=sw_code
|
1718
|
+
df3=df2[['code','weighted_avg']]
|
1719
|
+
|
1720
|
+
#因有市盈率负数,不管如何处理都会导致加权平均后数值波动过大,不能实用
|
1721
|
+
return df3
|
1722
|
+
|
1723
|
+
|
1724
|
+
|
1725
|
+
|
1726
|
+
|
1304
1727
|
#==============================================================================
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: siat
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.12.1
|
4
4
|
Summary: Securities Investment Analysis Tools (siat)
|
5
5
|
Home-page: https://pypi.org/project/siat/
|
6
6
|
Author: Prof. WANG Dehong, Business School, BFSU
|
@@ -28,6 +28,7 @@ Requires-Dist: ruamel-yaml
|
|
28
28
|
Requires-Dist: prettytable
|
29
29
|
Requires-Dist: graphviz
|
30
30
|
Requires-Dist: luddite
|
31
|
+
Requires-Dist: pendulum
|
31
32
|
|
32
33
|
|
33
34
|
This plug-in is designed to use with the author's textbooks on security investment,
|
@@ -15,7 +15,7 @@ siat/bond_test.py,sha256=yUOFw7ddGU-kb1rJdnsjkJWziDNgUR7OLDA7F7Ub91A,5246
|
|
15
15
|
siat/capm_beta.py,sha256=cqbmfM4mrq73Ub0bq5QjWJjmJHj9x7-dSqbmNxnEj7k,28946
|
16
16
|
siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
|
17
17
|
siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
|
18
|
-
siat/common.py,sha256=
|
18
|
+
siat/common.py,sha256=ud2D94_SQ-ZEForVQN6o1XY4Hcsyf-HFd7-zuaNnrIY,79844
|
19
19
|
siat/compare_cross.py,sha256=-MZzxmX8_9oFZ7X0IcR51w87EWwssbitiw-BcmHMFzQ,26228
|
20
20
|
siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
|
21
21
|
siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
|
@@ -61,7 +61,7 @@ siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
|
|
61
61
|
siat/holding_risk.py,sha256=Dh4zXEw-0hnbMNorbsRS142C8mUzq4NhFjYnauWu5tc,30548
|
62
62
|
siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
|
63
63
|
siat/local_debug_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
64
|
-
siat/market_china.py,sha256=
|
64
|
+
siat/market_china.py,sha256=pwCjEqkNAcOrs4Ba5DIQ5WgyAC73ntOi-d7Cb29wOWk,37849
|
65
65
|
siat/markowitz.py,sha256=gs_R-FiykUMXfTVS0r_HswLC6VFmdmQMcQh7dh285iM,96379
|
66
66
|
siat/markowitz_ccb_test.py,sha256=xBkkoaNHdq9KSUrNuHGgKTdNYUvgi84kNYcf719eoyE,1593
|
67
67
|
siat/markowitz_ef_test.py,sha256=wjNlICkgRIqnonPeSIHo4Mu2GRtb9dr21wDt2kMNEcI,4032
|
@@ -73,7 +73,7 @@ siat/markowitz_test2.py,sha256=FcVZqYU5va4567WGUVUJ7cMQdVbBGxeBAz82Y3BhCTI,2193
|
|
73
73
|
siat/ml_cases.py,sha256=FYDk0O7l9hhHlbrlOVGgbH-h2DA503lhKFi9XugH1f0,86874
|
74
74
|
siat/ml_cases_example.py,sha256=xRGb3YTQEDTOnaWNzZN_myU5umQnA2RdMNiPrxTmn9c,1673
|
75
75
|
siat/ml_cases_example1.py,sha256=xRGb3YTQEDTOnaWNzZN_myU5umQnA2RdMNiPrxTmn9c,1673
|
76
|
-
siat/option_china.py,sha256=
|
76
|
+
siat/option_china.py,sha256=SlMShz7VrPhlBCdPlhucVJ0rAsX2K8FBhm9AMZWnsgA,112383
|
77
77
|
siat/option_china_test.py,sha256=UQ-YUHUjoGBQyanLcM-yzqeEIUQP_gCQIeT0W6rnUnA,16355
|
78
78
|
siat/option_pricing.py,sha256=hTz0lD4Yoeq0jK4Kt38qKJC_iOz9a5qXC2OeXgnMmv8,70231
|
79
79
|
siat/option_pricing_test.py,sha256=eeorV5Ja5vjlRXnP6fWJHetGU5Vb8SnLopkC6RV3GfA,2203
|
@@ -120,11 +120,11 @@ siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,11
|
|
120
120
|
siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
|
121
121
|
siat/translate.py,sha256=zAemLG2s7wABKhZjM7esMfqH3tKX48O53sTEOLdilZI,142620
|
122
122
|
siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
123
|
-
siat/valuation.py,sha256=
|
124
|
-
siat/valuation_china.py,sha256=
|
123
|
+
siat/valuation.py,sha256=3VKrO9b9xY9dOJGGuF0ZhytzB5d2pCx3kO3TtMml7mo,44025
|
124
|
+
siat/valuation_china.py,sha256=oEQRrktJNHiOG1mJSQN1aSSQAQrwrg-ppIHyNVjMjNg,67603
|
125
125
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
126
126
|
siat/var_model_validation.py,sha256=zB_Skk_tmzIR15l6oAW3am4HBGVIG-eZ8gJhCdXZ8Qw,14859
|
127
|
-
siat-2.
|
128
|
-
siat-2.
|
129
|
-
siat-2.
|
130
|
-
siat-2.
|
127
|
+
siat-2.12.1.dist-info/METADATA,sha256=q8nIQGb5SBa9xZknlCS7_vuSM37y3qmH2nuLDCKkJ4o,1378
|
128
|
+
siat-2.12.1.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
129
|
+
siat-2.12.1.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
130
|
+
siat-2.12.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|