siat 3.7.29__py3-none-any.whl → 3.8.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/allin.py +2 -0
- siat/common.py +19 -1
- siat/economy2.py +976 -0
- siat/grafix.py +128 -35
- siat/sector_china.py +50 -19
- siat/stock.py +1 -1
- siat/translate.py +280 -5
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/METADATA +1 -1
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/RECORD +12 -11
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/LICENSE +0 -0
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/WHEEL +0 -0
- {siat-3.7.29.dist-info → siat-3.8.2.dist-info}/top_level.txt +0 -0
siat/grafix.py
CHANGED
@@ -124,7 +124,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
124
124
|
resample_freq='H',loc='best', \
|
125
125
|
date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
|
126
126
|
mark_top=True,mark_bottom=True,mark_end=True, \
|
127
|
-
facecolor='whitesmoke'):
|
127
|
+
facecolor='whitesmoke',maxticks=10,translate=False):
|
128
128
|
"""
|
129
129
|
功能:绘制折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
|
130
130
|
假定:数据表有索引,且已经按照索引排序
|
@@ -136,6 +136,8 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
136
136
|
注意1:需要日期类型作为df索引
|
137
137
|
注意2:date_freq不为False时,必须设置date_range=True,否则无法完成日期设置!
|
138
138
|
"""
|
139
|
+
DEBUG=False
|
140
|
+
|
139
141
|
import pandas as pd
|
140
142
|
|
141
143
|
#空值判断
|
@@ -176,6 +178,10 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
176
178
|
lwadjust=linewidth_adjust(df)
|
177
179
|
|
178
180
|
#if 'filled' not in list(df):
|
181
|
+
if translate:
|
182
|
+
collabel=lang_auto2(collabel)
|
183
|
+
|
184
|
+
if DEBUG: print(f"df.index: {df.index}")
|
179
185
|
plt.plot(df.index,df[colname],'-',label=collabel, \
|
180
186
|
linestyle='-',color='blue', linewidth=lwadjust)
|
181
187
|
"""
|
@@ -243,7 +249,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
243
249
|
x_end = df_end[colname].idxmin() # 末端值的x坐标
|
244
250
|
|
245
251
|
#y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
|
246
|
-
y1=str(round(y_end,
|
252
|
+
y1=str(round(y_end,1)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
|
247
253
|
plt.annotate(text=' '+y1,
|
248
254
|
xy=(x_end, y_end),
|
249
255
|
xytext=(x_end, y_end),fontsize=annotate_size)
|
@@ -286,6 +292,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
286
292
|
plt.fill_between(df.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
|
287
293
|
|
288
294
|
import pandas as pd
|
295
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
289
296
|
if not attention_point=='':
|
290
297
|
if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
|
291
298
|
atp_list=[attention_point]
|
@@ -304,9 +311,12 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
304
311
|
|
305
312
|
#判断是否日期字符串
|
306
313
|
try:
|
314
|
+
#at=datetime.strptime(at, date_format)
|
307
315
|
atpd=pd.to_datetime(at)
|
308
316
|
except:
|
309
317
|
atpd=at
|
318
|
+
|
319
|
+
if DEBUG: print(f"atpd={atpd}")
|
310
320
|
plt.axvline(x=atpd,ls=":",c=color,linewidth=1.5,label=text_lang("关注点","Attention point ")+str(at))
|
311
321
|
|
312
322
|
if not attention_point_area=='':
|
@@ -314,12 +324,18 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
314
324
|
apa_list=[]
|
315
325
|
for ap in attention_point_area:
|
316
326
|
try:
|
327
|
+
#ap=datetime.strptime(ap, date_format)
|
317
328
|
appd=pd.to_datetime(ap)
|
318
329
|
except:
|
319
330
|
appd=ap
|
320
331
|
apa_list=apa_list+[appd]
|
321
332
|
|
322
333
|
yaxis_data=plt.ylim()
|
334
|
+
|
335
|
+
if DEBUG:
|
336
|
+
print(f"yaxis_data={yaxis_data}")
|
337
|
+
print(f"apa_list[0]={apa_list[0]}")
|
338
|
+
print(f"apa_list[1]={apa_list[1]}")
|
323
339
|
plt.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
|
324
340
|
|
325
341
|
if average_value:
|
@@ -352,7 +368,11 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
352
368
|
if ylabeltxt != '' or average_value or isinstance(zeroline,bool):
|
353
369
|
if haveLegend:
|
354
370
|
plt.legend(loc=loc,fontsize=legend_txt_size)
|
355
|
-
|
371
|
+
|
372
|
+
# 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
|
373
|
+
import matplotlib.dates as mdates
|
374
|
+
ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
|
375
|
+
|
356
376
|
plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
|
357
377
|
try:
|
358
378
|
plt.gca().set_facecolor(facecolor) #设置画布背景颜色
|
@@ -362,6 +382,11 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
362
382
|
|
363
383
|
if '基金' in titletxt and '收盘价' in ylabeltxt and not ('基金指数' in titletxt):
|
364
384
|
ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
|
385
|
+
|
386
|
+
if translate:
|
387
|
+
ylabeltxt=lang_auto2(ylabeltxt)
|
388
|
+
footnote=lang_auto2(footnote)
|
389
|
+
titletxt=lang_auto2(titletxt)
|
365
390
|
|
366
391
|
plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
|
367
392
|
plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
|
@@ -610,6 +635,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
|
|
610
635
|
|
611
636
|
#是否绘制垂直线
|
612
637
|
import pandas as pd
|
638
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
613
639
|
if xline != 999:
|
614
640
|
attention_point=xline
|
615
641
|
#用于关注点的颜色列表
|
@@ -633,6 +659,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
|
|
633
659
|
|
634
660
|
#判断是否日期字符串
|
635
661
|
try:
|
662
|
+
at=datetime.strptime(at, date_format)
|
636
663
|
atpd=pd.to_datetime(at)
|
637
664
|
except:
|
638
665
|
atpd=at
|
@@ -647,6 +674,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
|
|
647
674
|
apa_list=[]
|
648
675
|
for ap in attention_point_area:
|
649
676
|
try:
|
677
|
+
ap=datetime.strptime(ap, date_format)
|
650
678
|
appd=pd.to_datetime(ap)
|
651
679
|
except:
|
652
680
|
appd=ap
|
@@ -869,6 +897,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
|
|
869
897
|
|
870
898
|
#是否绘制垂直线
|
871
899
|
import pandas as pd
|
900
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
872
901
|
if xline != 999:
|
873
902
|
attention_point=xline
|
874
903
|
#用于关注点的颜色列表
|
@@ -891,6 +920,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
|
|
891
920
|
|
892
921
|
#判断是否日期字符串
|
893
922
|
try:
|
923
|
+
at=datetime.strptime(at, date_format)
|
894
924
|
atpd=pd.to_datetime(at)
|
895
925
|
except:
|
896
926
|
atpd=at
|
@@ -905,6 +935,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
|
|
905
935
|
apa_list=[]
|
906
936
|
for ap in attention_point_area:
|
907
937
|
try:
|
938
|
+
ap=datetime.strptime(ap, date_format)
|
908
939
|
appd=pd.to_datetime(ap)
|
909
940
|
except:
|
910
941
|
appd=ap
|
@@ -1073,6 +1104,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
|
|
1073
1104
|
|
1074
1105
|
#绘制关注点
|
1075
1106
|
import pandas as pd
|
1107
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
1076
1108
|
if xline != 999:
|
1077
1109
|
attention_point=xline
|
1078
1110
|
|
@@ -1100,6 +1132,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
|
|
1100
1132
|
|
1101
1133
|
#判断是否日期字符串
|
1102
1134
|
try:
|
1135
|
+
at=datetime.strptime(at, date_format)
|
1103
1136
|
atpd=pd.to_datetime(at)
|
1104
1137
|
except:
|
1105
1138
|
atpd=at
|
@@ -1110,6 +1143,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
|
|
1110
1143
|
apa_list=[]
|
1111
1144
|
for ap in attention_point_area:
|
1112
1145
|
try:
|
1146
|
+
ap=datetime.strptime(ap, date_format)
|
1113
1147
|
appd=pd.to_datetime(ap)
|
1114
1148
|
except:
|
1115
1149
|
appd=ap
|
@@ -1304,6 +1338,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
|
|
1304
1338
|
|
1305
1339
|
#绘制关注点
|
1306
1340
|
import pandas as pd
|
1341
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
1307
1342
|
if xline != 999:
|
1308
1343
|
attention_point=xline
|
1309
1344
|
|
@@ -1331,6 +1366,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
|
|
1331
1366
|
|
1332
1367
|
#判断是否日期字符串
|
1333
1368
|
try:
|
1369
|
+
at=datetime.strptime(at, date_format)
|
1334
1370
|
atpd=pd.to_datetime(at)
|
1335
1371
|
except:
|
1336
1372
|
atpd=at
|
@@ -1341,6 +1377,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
|
|
1341
1377
|
apa_list=[]
|
1342
1378
|
for ap in attention_point_area:
|
1343
1379
|
try:
|
1380
|
+
ap=datetime.strptime(ap, date_format)
|
1344
1381
|
appd=pd.to_datetime(ap)
|
1345
1382
|
except:
|
1346
1383
|
appd=ap
|
@@ -1478,11 +1515,12 @@ if __name__ =="__main__":
|
|
1478
1515
|
|
1479
1516
|
def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
1480
1517
|
data_label=True,resample_freq='H',smooth=True,linewidth=1.5, \
|
1481
|
-
loc='best',
|
1518
|
+
band_area='',loc='best', \
|
1519
|
+
annotate=False,annotate_value=False,plus_sign=False, \
|
1482
1520
|
attention_value='',attention_value_area='', \
|
1483
1521
|
attention_point='',attention_point_area='', \
|
1484
1522
|
mark_top=False,mark_bottom=False,mark_end=False, \
|
1485
|
-
ticker_type='auto',facecolor='whitesmoke'):
|
1523
|
+
ticker_type='auto',facecolor='whitesmoke',maxticks=10,translate=False):
|
1486
1524
|
"""
|
1487
1525
|
函数功能:根据df的内容绘制折线图
|
1488
1526
|
输入参数:
|
@@ -1500,6 +1538,10 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1500
1538
|
注意:需要日期类型作为df索引
|
1501
1539
|
"""
|
1502
1540
|
DEBUG=False
|
1541
|
+
if DEBUG:
|
1542
|
+
print(f"band_area={band_area}")
|
1543
|
+
print(f"df0={df0}")
|
1544
|
+
|
1503
1545
|
|
1504
1546
|
if DEBUG:
|
1505
1547
|
print("annotate=",annotate,"annotate_value=",annotate_value)
|
@@ -1552,6 +1594,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1552
1594
|
firstline=True
|
1553
1595
|
|
1554
1596
|
#绘制折线图
|
1597
|
+
ax=plt.gca()
|
1555
1598
|
print('')
|
1556
1599
|
y_end_list=[]
|
1557
1600
|
for c in collist:
|
@@ -1598,7 +1641,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1598
1641
|
clabel=c+str(round(dfg[c].values[0],2))
|
1599
1642
|
else:
|
1600
1643
|
clabel=c
|
1601
|
-
plt.plot(dfg,label=clabel,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
|
1644
|
+
plt.plot(dfg,label=auto_translate2(clabel,translate),linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
|
1602
1645
|
else:
|
1603
1646
|
plt.plot(dfg,linewidth=lwadjust,ls=lsc,marker=mkc,markersize=3)
|
1604
1647
|
|
@@ -1615,12 +1658,12 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1615
1658
|
if annotate_value: #在标记曲线名称的同时标记其末端数值
|
1616
1659
|
#y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
|
1617
1660
|
y1=str(round(y_end,2)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
|
1618
|
-
plt.annotate(text=c+':'+y1,
|
1661
|
+
plt.annotate(text=' '+auto_translate2(c,translate)+':'+y1,
|
1619
1662
|
xy=(x_end, y_end),
|
1620
1663
|
xytext=(x_end, y_end),fontsize=annotate_size,
|
1621
1664
|
color=last_line_color)
|
1622
1665
|
else:
|
1623
|
-
plt.annotate(text=c,
|
1666
|
+
plt.annotate(text=' '+auto_translate2(c,translate),
|
1624
1667
|
xy=(x_end, y_end),
|
1625
1668
|
#xytext=(x_end, y_end),fontsize=9)
|
1626
1669
|
xytext=(x_end, y_end),fontsize=annotate_size,
|
@@ -1669,7 +1712,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1669
1712
|
x_end = df_end[c].idxmin() # 末端值的x坐标
|
1670
1713
|
|
1671
1714
|
#y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
|
1672
|
-
y1=str(round(y_end,
|
1715
|
+
y1=str(round(y_end,1)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
|
1673
1716
|
plt.annotate(text=' '+y1,
|
1674
1717
|
xy=(x_end, y_end),
|
1675
1718
|
xytext=(x_end, y_end),fontsize=annotate_size,
|
@@ -1696,8 +1739,35 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1696
1739
|
if not attention_value_area=='':
|
1697
1740
|
if isinstance(attention_value_area,list) and len(attention_value_area)>=2:
|
1698
1741
|
plt.fill_between(dfg.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
|
1742
|
+
|
1743
|
+
#绘制曲线之间的带状区域
|
1744
|
+
if DEBUG:
|
1745
|
+
print(f"dfg={dfg}")
|
1746
|
+
|
1747
|
+
if band_area != '' and isinstance(band_area,list) and len(band_area)>=2:
|
1748
|
+
upper_line=band_area[0]; lower_line=band_area[1]
|
1749
|
+
if upper_line not in collist:
|
1750
|
+
upper_line=ectranslate(upper_line)
|
1751
|
+
lower_line=ectranslate(lower_line)
|
1699
1752
|
|
1700
|
-
|
1753
|
+
if upper_line not in collist:
|
1754
|
+
upper_line=ticker_name(upper_line)
|
1755
|
+
lower_line=ticker_name(lower_line)
|
1756
|
+
|
1757
|
+
if upper_line not in collist:
|
1758
|
+
upper_line=None
|
1759
|
+
lower_line=None
|
1760
|
+
|
1761
|
+
if not (upper_line is None) and not (lower_line is None):
|
1762
|
+
try:
|
1763
|
+
plt.fill_between(df2.index,df2[upper_line],df2[lower_line],df2[upper_line] > df2[lower_line],color='aquamarine',alpha=0.5,label='',interpolate=True)
|
1764
|
+
plt.fill_between(df2.index,df2[upper_line],df2[lower_line],df2[upper_line] < df2[lower_line],color='lightcoral',alpha=0.5,label='',interpolate=True)
|
1765
|
+
except:
|
1766
|
+
print(f" #Warning(draw_lines): band area elements {upper_line} or {lower_line} not found")
|
1767
|
+
|
1768
|
+
import pandas as pd
|
1769
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
1770
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
1701
1771
|
if not attention_point=='':
|
1702
1772
|
if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
|
1703
1773
|
atp_list=[attention_point]
|
@@ -1721,10 +1791,13 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1721
1791
|
|
1722
1792
|
color=atp_color_list[-1]
|
1723
1793
|
|
1724
|
-
#判断是否日期字符串
|
1725
1794
|
try:
|
1795
|
+
#判断是否日期字符串
|
1796
|
+
at=datetime.strptime(at, date_format)
|
1797
|
+
#若是日期字符串
|
1726
1798
|
atpd=pd.to_datetime(at)
|
1727
1799
|
except:
|
1800
|
+
#不是日期字符串
|
1728
1801
|
atpd=at
|
1729
1802
|
|
1730
1803
|
"""
|
@@ -1752,6 +1825,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1752
1825
|
apa_list=[]
|
1753
1826
|
for ap in attention_point_area:
|
1754
1827
|
try:
|
1828
|
+
ap=datetime.strptime(ap, date_format)
|
1755
1829
|
appd=pd.to_datetime(ap)
|
1756
1830
|
except:
|
1757
1831
|
appd=ap
|
@@ -1764,19 +1838,23 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1764
1838
|
if axhline_label !="":
|
1765
1839
|
if '零线' in axhline_label:
|
1766
1840
|
axhline_label=''
|
1767
|
-
plt.axhline(y=axhline_value,label=axhline_label,color='black',linestyle=':',linewidth=2)
|
1841
|
+
plt.axhline(y=axhline_value,label=auto_translate2(axhline_label,translate),color='black',linestyle=':',linewidth=2)
|
1768
1842
|
#plt.axhline(y=axhline_value,color='purple',linestyle=':',linewidth=1.5)
|
1769
1843
|
|
1770
1844
|
#坐标轴标记
|
1771
1845
|
y_label_t=ectranslate(y_label)
|
1772
|
-
plt.ylabel(y_label_t,fontweight='bold',fontsize=ylabel_txt_size)
|
1846
|
+
plt.ylabel(auto_translate2(y_label_t,translate),fontweight='bold',fontsize=ylabel_txt_size)
|
1773
1847
|
|
1774
1848
|
x_label_t=ectranslate(x_label)
|
1775
1849
|
if x_label != "":
|
1776
|
-
plt.xlabel(x_label_t,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
|
1850
|
+
plt.xlabel(auto_translate2(x_label_t,translate),fontweight='bold',fontsize=xlabel_txt_size,ha='center')
|
1777
1851
|
#图示标题
|
1778
|
-
plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
|
1852
|
+
plt.title(auto_translate2(title_txt,translate),fontweight='bold',fontsize=title_txt_size)
|
1779
1853
|
|
1854
|
+
# 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
|
1855
|
+
import matplotlib.dates as mdates
|
1856
|
+
ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
|
1857
|
+
|
1780
1858
|
plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
|
1781
1859
|
try:
|
1782
1860
|
plt.gca().set_facecolor(facecolor)
|
@@ -1822,7 +1900,7 @@ if __name__=='__main__':
|
|
1822
1900
|
|
1823
1901
|
#==============================================================================
|
1824
1902
|
def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
1825
|
-
data_label=False,resample_freq='
|
1903
|
+
data_label=False,resample_freq='1D',smooth=True, \
|
1826
1904
|
date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
|
1827
1905
|
colorlist=[],lslist=[],lwlist=[], \
|
1828
1906
|
#指定纵轴两个变量之间的区域
|
@@ -1835,7 +1913,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1835
1913
|
attention_point_area='', \
|
1836
1914
|
annotate=False,annotate_value=False, \
|
1837
1915
|
mark_top=False,mark_bottom=False,mark_end=False, \
|
1838
|
-
facecolor='whitesmoke'):
|
1916
|
+
facecolor='whitesmoke',maxticks=10,translate=False):
|
1839
1917
|
"""
|
1840
1918
|
函数功能:根据df的内容绘制折线图
|
1841
1919
|
输入参数:
|
@@ -1858,6 +1936,9 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1858
1936
|
"""
|
1859
1937
|
import pandas as pd
|
1860
1938
|
DEBUG=False
|
1939
|
+
if DEBUG:
|
1940
|
+
print(f"band_area={band_area}")
|
1941
|
+
print(f"df0={df0}")
|
1861
1942
|
|
1862
1943
|
#空值判断
|
1863
1944
|
if len(df0) ==0:
|
@@ -1927,17 +2008,17 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1927
2008
|
|
1928
2009
|
if (lcolor !='') and (lls !=''):
|
1929
2010
|
if not annotate:
|
1930
|
-
plt.plot(df[c],label=c,linewidth=llw,ls=lls,color=lcolor)
|
2011
|
+
plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw,ls=lls,color=lcolor)
|
1931
2012
|
else:
|
1932
2013
|
plt.plot(df[c],linewidth=llw,ls=lls,color=lcolor)
|
1933
2014
|
elif (lcolor !=''):
|
1934
2015
|
if not annotate:
|
1935
|
-
plt.plot(df[c],label=c,linewidth=llw,color=lcolor)
|
2016
|
+
plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw,color=lcolor)
|
1936
2017
|
else:
|
1937
2018
|
plt.plot(df[c],linewidth=llw,color=lcolor)
|
1938
2019
|
else:
|
1939
2020
|
if not annotate:
|
1940
|
-
plt.plot(df[c],label=c,linewidth=llw)
|
2021
|
+
plt.plot(df[c],label=auto_translate2(c,translate),linewidth=llw)
|
1941
2022
|
else:
|
1942
2023
|
plt.plot(df[c],linewidth=llw)
|
1943
2024
|
|
@@ -1987,12 +2068,12 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1987
2068
|
if annotate_value: #在标记曲线名称的同时标记其末端数值
|
1988
2069
|
#y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
|
1989
2070
|
y1=str(int(y_end)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 10 else str(round(y_end,4))
|
1990
|
-
plt.annotate(text=c+':'+y1,
|
2071
|
+
plt.annotate(text=auto_translate2(c,translate)+':'+y1,
|
1991
2072
|
xy=(x_end, y_end),
|
1992
2073
|
xytext=(x_end, y_end),fontsize=annotate_size,
|
1993
2074
|
color=last_line_color)
|
1994
2075
|
else:
|
1995
|
-
plt.annotate(text=c,
|
2076
|
+
plt.annotate(text=auto_translate2(c,translate),
|
1996
2077
|
xy=(x_end, y_end),
|
1997
2078
|
xytext=(x_end, y_end),fontsize=annotate_size,
|
1998
2079
|
color=last_line_color)
|
@@ -2004,7 +2085,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
2004
2085
|
x_end = df_end[c].idxmin() # 末端值的x坐标
|
2005
2086
|
|
2006
2087
|
#y1=str(int(y_end)) if y_end >= 100 else str(round(y_end,2))
|
2007
|
-
y1=str(round(y_end,
|
2088
|
+
y1=str(round(y_end,1)) if abs(y_end) >= 100 else str(round(y_end,2)) if abs(y_end) >= 1 else str(round(y_end,3))
|
2008
2089
|
plt.annotate(text=y1,
|
2009
2090
|
xy=(x_end, y_end),
|
2010
2091
|
xytext=(x_end, y_end),fontsize=annotate_size,
|
@@ -2026,15 +2107,19 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
2026
2107
|
lower_line=None
|
2027
2108
|
|
2028
2109
|
if not (upper_line is None) and not (lower_line is None):
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2110
|
+
try:
|
2111
|
+
"""
|
2112
|
+
plt.fill_between(df.index,df[upper_line],df[lower_line],color='moccasin',alpha=0.5,label='',where=df[upper_line]>=df[lower_line])
|
2113
|
+
plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='',where=df[upper_line]<=df[lower_line])
|
2114
|
+
"""
|
2115
|
+
#plt.fill_between(df.index,df[upper_line],df[lower_line],color='aquamarine',alpha=0.5,label='')
|
2116
|
+
plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] > df[lower_line],color='aquamarine',alpha=0.5,label='',interpolate=True)
|
2117
|
+
plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] < df[lower_line],color='lightcoral',alpha=0.5,label='',interpolate=True)
|
2118
|
+
#plt.fill_between(df.index,df[upper_line],df[lower_line],df[upper_line] == df[lower_line],color='lightgray',alpha=0.5,label='')
|
2119
|
+
except:
|
2120
|
+
print(f" #Warning(draw_lines2): lack of data for either {upper_line} or {lower_line}")
|
2121
|
+
#return None
|
2122
|
+
|
2038
2123
|
#绘制水平辅助线
|
2039
2124
|
if axhline_label !="":
|
2040
2125
|
if DEBUG:
|
@@ -2068,6 +2153,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
2068
2153
|
plt.fill_between(df.index,attention_value_area[0],attention_value_area[1],color='lightgray',alpha=0.5)
|
2069
2154
|
|
2070
2155
|
import pandas as pd
|
2156
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
2071
2157
|
if not attention_point=='':
|
2072
2158
|
if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
|
2073
2159
|
atp_list=[attention_point]
|
@@ -2085,6 +2171,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
2085
2171
|
|
2086
2172
|
#判断是否日期字符串
|
2087
2173
|
try:
|
2174
|
+
at=datetime.strptime(at, date_format)
|
2088
2175
|
atpd=pd.to_datetime(at)
|
2089
2176
|
except:
|
2090
2177
|
atpd=at
|
@@ -2095,6 +2182,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
2095
2182
|
apa_list=[]
|
2096
2183
|
for ap in attention_point_area:
|
2097
2184
|
try:
|
2185
|
+
ap=datetime.strptime(ap, date_format)
|
2098
2186
|
appd=pd.to_datetime(ap)
|
2099
2187
|
except:
|
2100
2188
|
appd=ap
|
@@ -2104,11 +2192,16 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
2104
2192
|
plt.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
|
2105
2193
|
|
2106
2194
|
#坐标轴标记
|
2107
|
-
plt.ylabel(y_label,fontweight='bold',fontsize=ylabel_txt_size)
|
2195
|
+
plt.ylabel(auto_translate2(y_label,translate),fontweight='bold',fontsize=ylabel_txt_size)
|
2108
2196
|
if x_label != "":
|
2109
|
-
plt.xlabel(x_label,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
|
2197
|
+
plt.xlabel(auto_translate2(x_label,translate),fontweight='bold',fontsize=xlabel_txt_size,ha='center')
|
2110
2198
|
#图示标题
|
2111
|
-
plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
|
2199
|
+
plt.title(auto_translate2(title_txt,translate),fontweight='bold',fontsize=title_txt_size)
|
2200
|
+
|
2201
|
+
# 使用 AutoDateLocator 自动选择最佳间隔,目的是显示最后一个日期,亲测有效!!!
|
2202
|
+
import matplotlib.dates as mdates
|
2203
|
+
ax.xaxis.set_major_locator(mdates.AutoDateLocator(maxticks=maxticks))
|
2204
|
+
|
2112
2205
|
plt.gcf().autofmt_xdate(ha="center") # 优化标注(自动倾斜)
|
2113
2206
|
try:
|
2114
2207
|
plt.gca().set_facecolor(facecolor)
|
siat/sector_china.py
CHANGED
@@ -889,9 +889,17 @@ def display_industry_sw(sw_level='1',numberPerLine=4,colalign='left'):
|
|
889
889
|
"""
|
890
890
|
按照类别打印申万行业列表,名称(代码),每行5个, 套壳函数
|
891
891
|
"""
|
892
|
-
itype_list=['1','2','3','F','S','B','C']
|
893
|
-
|
894
|
-
|
892
|
+
#itype_list=['1','2','3','F','S','B','C']
|
893
|
+
itype_list=['1','2','3','F','S','B']
|
894
|
+
#sw_level_list=['1','2','3','F','S','B','C']
|
895
|
+
sw_level_list=['1','2','3','F','S','B']
|
896
|
+
|
897
|
+
try:
|
898
|
+
pos=sw_level_list.index(sw_level)
|
899
|
+
except:
|
900
|
+
print(f" #Warning(display_industry_sw): no such level in Shenwan system {sw_level}")
|
901
|
+
print(f" Supported Shenwan system: {sw_level_list}")
|
902
|
+
|
895
903
|
itype=itype_list[pos]
|
896
904
|
|
897
905
|
print_industry_sw(itype=itype,numberPerLine=numberPerLine,colalign=colalign)
|
@@ -2884,6 +2892,7 @@ if __name__=='__main__':
|
|
2884
2892
|
|
2885
2893
|
def find_peers_china(industry='',top=20,rank=20,sw_level='2'):
|
2886
2894
|
"""
|
2895
|
+
===========================================================================
|
2887
2896
|
功能:找出一个申万行业的上市公司排名
|
2888
2897
|
主要参数:
|
2889
2898
|
industry:申万行业名称。当industry = '',显示的内容由sw_level控制。申万二级行业分类
|
@@ -3489,10 +3498,13 @@ if __name__=='__main__':
|
|
3489
3498
|
|
3490
3499
|
def find_industry_sw(ticker,level='1',ticker_order=True,max_sleep=30):
|
3491
3500
|
"""
|
3501
|
+
===========================================================================
|
3492
3502
|
功能:寻找一只或一组股票所属的申万行业,支持股票代码和股票名称。
|
3493
|
-
level='1':默认只查找申万1
|
3494
|
-
ticker_order=True:默认输出结果按照ticker
|
3495
|
-
max_sleep
|
3503
|
+
level='1':默认只查找申万1级行业;查找2/3级行业时间较久,可能触发反爬虫机制。
|
3504
|
+
ticker_order=True:默认输出结果按照ticker中的顺序,而非按照所属行业排序。
|
3505
|
+
max_sleep:为防止触发反爬虫机制,默认每次爬虫后睡眠最多30秒钟。
|
3506
|
+
|
3507
|
+
返回值:查找结果df。
|
3496
3508
|
"""
|
3497
3509
|
print(" Searching shenwan industries for securities ... ...")
|
3498
3510
|
|
@@ -3621,21 +3633,24 @@ if __name__=='__main__':
|
|
3621
3633
|
|
3622
3634
|
peers=stock_industry_peer_em(ticker,indicator="市盈率",rank=10)
|
3623
3635
|
|
3624
|
-
def stock_peers_em(ticker='',indicator='',rank=10, \
|
3636
|
+
def stock_peers_em(ticker='',indicator='市盈率',rank=10, \
|
3625
3637
|
force_show_stock=True, \
|
3626
3638
|
font_size="16px",facecolor="papayawhip", \
|
3627
3639
|
numberPerLine=5):
|
3628
3640
|
"""
|
3629
|
-
|
3630
|
-
|
3641
|
+
===========================================================================
|
3642
|
+
功能:基于东方财富行业分类,查找股票所属的行业板块以及主要同行排名。
|
3643
|
+
特点:行业分类较粗糙,略胜于无。
|
3631
3644
|
主要参数:
|
3632
|
-
ticker:股票代码,默认''
|
3633
|
-
indicator:排名指标,默认''。例如:"股价"、"流动性"、"市净率"、"市盈率"
|
3634
|
-
rank:排名数量,默认10
|
3635
|
-
force_show_stock:是否显示股票信息,默认False
|
3636
|
-
font_size:表格字体大小,默认"16px"
|
3637
|
-
facecolor:输出表格的背景颜色,默认"papayawhip"
|
3638
|
-
numberPerLine:输出表格中的每行显示个数,默认5
|
3645
|
+
ticker:股票代码,默认''显示所有板块名称。
|
3646
|
+
indicator:排名指标,默认''。例如:"股价"、"流动性"、"市净率"、"市盈率"。
|
3647
|
+
rank:排名数量,默认10前十名。
|
3648
|
+
force_show_stock:是否显示股票信息,默认False。
|
3649
|
+
font_size:表格字体大小,默认"16px"。
|
3650
|
+
facecolor:输出表格的背景颜色,默认"papayawhip"。
|
3651
|
+
numberPerLine:输出表格中的每行显示个数,默认5。
|
3652
|
+
|
3653
|
+
注意:若结果异常,可尝试升级插件akshare。
|
3639
3654
|
|
3640
3655
|
示例:
|
3641
3656
|
industries=stock_peers_em() # 显示东方财富所有行业板块分类
|
@@ -3663,6 +3678,7 @@ def stock_peers_em(ticker='',indicator='',rank=10, \
|
|
3663
3678
|
except:
|
3664
3679
|
if not ticker=='':
|
3665
3680
|
print(" #Warning(stock_peer_em): stock info not found for",ticker)
|
3681
|
+
print(" Solution: if stock code is correct, upgrade akshare and try again")
|
3666
3682
|
|
3667
3683
|
df_em=ak.stock_board_industry_name_em()
|
3668
3684
|
#df_em.sort_values(by="板块名称",ascending=True,inplace=True)
|
@@ -3725,7 +3741,8 @@ def stock_peers_em(ticker='',indicator='',rank=10, \
|
|
3725
3741
|
df_disp=cfg[collist].tail(abs(rank))
|
3726
3742
|
|
3727
3743
|
#强制显示所选股票
|
3728
|
-
if force_show_stock and rank != 10:
|
3744
|
+
#if force_show_stock and rank != 10:
|
3745
|
+
if force_show_stock:
|
3729
3746
|
#所选股票是否在其中?
|
3730
3747
|
if not ticker[:6] in list(df_disp["代码"]):
|
3731
3748
|
ticker_seq=cfg[cfg["代码"]==ticker[:6]]["序号"].values[0]
|
@@ -3780,8 +3797,22 @@ def concept_stocks_em(concept='',ticker='',indicator="市盈率",rank=10, \
|
|
3780
3797
|
force_show_stock=False, \
|
3781
3798
|
font_size="16px",facecolor="papayawhip",numberPerLine=5):
|
3782
3799
|
"""
|
3783
|
-
|
3784
|
-
|
3800
|
+
===========================================================================
|
3801
|
+
功能:基于东方财富概念板块,查找关键字相关概念以及股票业绩。
|
3802
|
+
特点:概念板块划分细致,同一股票可能分属多个板块,与行业分类不同。
|
3803
|
+
参数:
|
3804
|
+
concept:概念板块名称,或名称中的关键字,默认''输出所有概念板块名称;
|
3805
|
+
若查找到多个名称,则优先输出查找到的名称;
|
3806
|
+
若仅仅找到一个板块,则按indicator输出该板块的股票排行。
|
3807
|
+
ticker:股票代码,默认''
|
3808
|
+
indicator:指标名称,默认"市盈率",还支持:股价,市净率,涨跌幅,流动性,换手率。
|
3809
|
+
rank:排名,支持正负数,默认10。
|
3810
|
+
force_show_stock:若ticker不为空,且不在rank范围内,是否强制显示该股票,默认False。
|
3811
|
+
font_size:显示字体大小,默认"16px"。
|
3812
|
+
facecolor:表格背景颜色,默认"papayawhip"。
|
3813
|
+
numberPerLine:当显示板块名称时,每行显示个数,默认5。
|
3814
|
+
|
3815
|
+
返回值:df
|
3785
3816
|
"""
|
3786
3817
|
if indicator in ["股价","股票价格","价格","收盘价","价位"]:
|
3787
3818
|
indicator="最新价"
|
siat/stock.py
CHANGED
@@ -987,7 +987,7 @@ def security_mindicators(ticker,measures,
|
|
987
987
|
titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)
|
988
988
|
|
989
989
|
draw_lines2(df,y_label,x_label,axhline_value,axhline_label,titletxt, \
|
990
|
-
data_label=False,resample_freq='
|
990
|
+
data_label=False,resample_freq='1D',smooth=smooth, \
|
991
991
|
date_range=date_range,date_freq=date_freq,date_fmt='%Y-%m-%d', \
|
992
992
|
attention_value=attention_value,attention_value_area=attention_value_area, \
|
993
993
|
attention_point=attention_point,attention_point_area=attention_point_area, \
|