siat 3.8.30__py3-none-any.whl → 3.8.35__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/grafix.py +525 -12
- siat/valuation_china.py +14 -13
- {siat-3.8.30.dist-info → siat-3.8.35.dist-info}/METADATA +1 -1
- {siat-3.8.30.dist-info → siat-3.8.35.dist-info}/RECORD +7 -7
- {siat-3.8.30.dist-info → siat-3.8.35.dist-info}/LICENSE +0 -0
- {siat-3.8.30.dist-info → siat-3.8.35.dist-info}/WHEEL +0 -0
- {siat-3.8.30.dist-info → siat-3.8.35.dist-info}/top_level.txt +0 -0
siat/grafix.py
CHANGED
@@ -433,7 +433,8 @@ def plot_line2(df1,ticker1,colname1,label1, \
|
|
433
433
|
df2,ticker2,colname2,label2, \
|
434
434
|
ylabeltxt,titletxt,footnote, \
|
435
435
|
power=0,datatag1=False,datatag2=False,yscalemax=5, \
|
436
|
-
zeroline=False,
|
436
|
+
zeroline=False, \
|
437
|
+
twinx=False, \
|
437
438
|
yline=999,attention_value_area='', \
|
438
439
|
xline=999,attention_point_area='', \
|
439
440
|
resample_freq='D',loc1='best',loc2='best', \
|
@@ -465,7 +466,36 @@ def plot_line2(df1,ticker1,colname1,label1, \
|
|
465
466
|
print("Going to plot_line2_coaxial")
|
466
467
|
print("yline=",yline,"; xline=",xline)
|
467
468
|
|
468
|
-
if not twinx:
|
469
|
+
#if not twinx:
|
470
|
+
if twinx == True: # 双轴会图
|
471
|
+
plot_line2_twinx(df1,ticker1,colname1,label1, \
|
472
|
+
df2,ticker2,colname2,label2, \
|
473
|
+
titletxt,footnote,power,datatag1,datatag2, \
|
474
|
+
resample_freq=resample_freq, \
|
475
|
+
xline=xline,attention_point_area=attention_point_area, \
|
476
|
+
loc1=loc1,loc2=loc2, \
|
477
|
+
color1=color1,color2=color2,facecolor=facecolor, \
|
478
|
+
maxticks=maxticks)
|
479
|
+
elif 'LR' in twinx.upper(): # 左右双图
|
480
|
+
plot_line2_LR(df1,ticker1,colname1,label1, \
|
481
|
+
df2,ticker2,colname2,label2, \
|
482
|
+
titletxt,footnote,power,datatag1,datatag2, \
|
483
|
+
resample_freq=resample_freq, \
|
484
|
+
xline=xline,attention_point_area=attention_point_area, \
|
485
|
+
loc1=loc1,loc2=loc2, \
|
486
|
+
color1=color1,color2=color2,facecolor=facecolor, \
|
487
|
+
maxticks=maxticks)
|
488
|
+
elif 'UD' in twinx.upper(): # 上下双图
|
489
|
+
plot_line2_UD(df1,ticker1,colname1,label1, \
|
490
|
+
df2,ticker2,colname2,label2, \
|
491
|
+
titletxt,footnote,power,datatag1,datatag2, \
|
492
|
+
resample_freq=resample_freq, \
|
493
|
+
xline=xline,attention_point_area=attention_point_area, \
|
494
|
+
loc1=loc1,loc2=loc2, \
|
495
|
+
color1=color1,color2=color2,facecolor=facecolor, \
|
496
|
+
maxticks=maxticks)
|
497
|
+
|
498
|
+
else: # twinx == False # 正常绘图
|
469
499
|
plot_line2_coaxial(df1,ticker1,colname1,label1, \
|
470
500
|
df2,ticker2,colname2,label2, \
|
471
501
|
ylabeltxt,titletxt,footnote,power,datatag1,datatag2,zeroline, \
|
@@ -475,15 +505,7 @@ def plot_line2(df1,ticker1,colname1,label1, \
|
|
475
505
|
loc1=loc1,loc2=loc2, \
|
476
506
|
color1=color1,color2=color2,facecolor=facecolor, \
|
477
507
|
maxticks=maxticks)
|
478
|
-
|
479
|
-
plot_line2_twinx(df1,ticker1,colname1,label1, \
|
480
|
-
df2,ticker2,colname2,label2, \
|
481
|
-
titletxt,footnote,power,datatag1,datatag2, \
|
482
|
-
resample_freq=resample_freq, \
|
483
|
-
xline=xline,attention_point_area=attention_point_area, \
|
484
|
-
loc1=loc1,loc2=loc2, \
|
485
|
-
color1=color1,color2=color2,facecolor=facecolor, \
|
486
|
-
maxticks=maxticks)
|
508
|
+
|
487
509
|
return
|
488
510
|
|
489
511
|
|
@@ -1298,10 +1320,501 @@ if __name__ =="__main__":
|
|
1298
1320
|
df2,'600266.SS','Close','收盘价', \
|
1299
1321
|
"证券价格走势对比图","数据来源:新浪/stooq")
|
1300
1322
|
|
1301
|
-
|
1323
|
+
plot_line2_LR(df1,'000002.SZ','Close','收盘价', \
|
1302
1324
|
df2,'600266.SS','Close','收盘价', \
|
1303
1325
|
"证券价格走势对比图","数据来源:新浪/stooq",power=3)
|
1304
1326
|
|
1327
|
+
#==============================================================================
|
1328
|
+
def plot_line2_LR(df01,ticker1,colname1,label1, \
|
1329
|
+
df02,ticker2,colname2,label2, \
|
1330
|
+
titletxt,footnote,power=0, \
|
1331
|
+
datatag1=False,datatag2=False, \
|
1332
|
+
resample_freq='D', \
|
1333
|
+
xline=999,attention_point_area='', \
|
1334
|
+
loc1='upper left',loc2='lower left', \
|
1335
|
+
color1='red',color2='blue',facecolor='whitesmoke', \
|
1336
|
+
ticker_type='auto', \
|
1337
|
+
maxticks=15):
|
1338
|
+
"""
|
1339
|
+
功能:绘制两个证券或指标的左右折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
|
1340
|
+
假定:数据表有索引,且已经按照索引排序
|
1341
|
+
输入:
|
1342
|
+
证券1:数据表df1,证券代码ticker1,列名1,列名标签1;
|
1343
|
+
证券2:数据表df2,证券代码ticker2,列名2,列名标签2;
|
1344
|
+
标题titletxt,脚注footnote;是否在图中标记数据datatag;趋势图的多项式次数power
|
1345
|
+
输出:绘制左右并列折线图
|
1346
|
+
返回值:无
|
1347
|
+
注意:需要日期类型作为df索引
|
1348
|
+
"""
|
1349
|
+
DEBUG=False
|
1350
|
+
|
1351
|
+
#plt.rcParams['axes.grid']=False
|
1352
|
+
|
1353
|
+
#插值平滑
|
1354
|
+
try:
|
1355
|
+
df01x=df01[[colname1]].astype('float')
|
1356
|
+
df1=df_smooth_manual(df01x,resample_freq=resample_freq)
|
1357
|
+
except:
|
1358
|
+
df1=df01
|
1359
|
+
try:
|
1360
|
+
df02x=df02[[colname2]].astype('float')
|
1361
|
+
df2=df_smooth_manual(df02x,resample_freq=resample_freq)
|
1362
|
+
except:
|
1363
|
+
df2=df02
|
1364
|
+
|
1365
|
+
#预处理ticker_type
|
1366
|
+
ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
|
1367
|
+
|
1368
|
+
#创建画布:绘制折线图,左右双子图
|
1369
|
+
fig, (ax, ax2) = plt.subplots(1, 2)
|
1370
|
+
|
1371
|
+
#设置主标题
|
1372
|
+
#plt.suptitle(titletxt,fontweight='bold',fontsize=title_txt_size, y=1.01) # y参数调整垂直位置
|
1373
|
+
plt.suptitle(titletxt,fontweight='bold',fontsize=title_txt_size)
|
1374
|
+
|
1375
|
+
# 绘制左子图================================================================
|
1376
|
+
#设置画布背景颜色
|
1377
|
+
try:
|
1378
|
+
ax.set_facecolor(facecolor)
|
1379
|
+
except:
|
1380
|
+
print(" #Warning(plot_line2_twinx): color",facecolor,"is unsupported")
|
1381
|
+
facecolor="whitesmoke"
|
1382
|
+
ax.set_facecolor(facecolor)
|
1383
|
+
|
1384
|
+
# 设置折线标签
|
1385
|
+
if ticker1 == '':
|
1386
|
+
label1txt=label1
|
1387
|
+
else:
|
1388
|
+
if label1 == '':
|
1389
|
+
label1txt=ticker_name(ticker1,ticker_type_list[0])
|
1390
|
+
else:
|
1391
|
+
label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
|
1392
|
+
|
1393
|
+
# 设置子图标题
|
1394
|
+
if ticker1 != ticker2:
|
1395
|
+
ax.set_title(label1txt,fontsize=xlabel_txt_size)
|
1396
|
+
else:
|
1397
|
+
ax.set_title(ectranslate(colname1),fontsize=xlabel_txt_size)
|
1398
|
+
|
1399
|
+
# 绘图
|
1400
|
+
lwadjust=linewidth_adjust(df1)
|
1401
|
+
"""
|
1402
|
+
ax.plot(df1.index,df1[colname1],'-',label=label1txt, \
|
1403
|
+
linestyle='-',color=color1,linewidth=lwadjust)
|
1404
|
+
"""
|
1405
|
+
ax.plot(df1.index,df1[colname1],'-', \
|
1406
|
+
linestyle='-',color=color1,linewidth=lwadjust)
|
1407
|
+
|
1408
|
+
#证券1:绘制数据标签
|
1409
|
+
if datatag1:
|
1410
|
+
for x, y in zip(df1.index, df1[colname1]):
|
1411
|
+
ax.text(x,y+0.1,'%.2f' % y,ha='center',va='bottom',color='black')
|
1412
|
+
|
1413
|
+
#绘制关注点
|
1414
|
+
import pandas as pd
|
1415
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
1416
|
+
if xline != 999:
|
1417
|
+
attention_point=xline
|
1418
|
+
|
1419
|
+
#用于关注点的颜色列表
|
1420
|
+
atp_color_list=["crimson","dodgerblue","magenta","lightseagreen","chocolate"]
|
1421
|
+
|
1422
|
+
if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
|
1423
|
+
atp_list=[attention_point]
|
1424
|
+
elif isinstance(attention_point,list):
|
1425
|
+
atp_list=attention_point
|
1426
|
+
else:
|
1427
|
+
atp_list=[]
|
1428
|
+
#去重,不打乱原来的顺序
|
1429
|
+
atp_list=list(dict.fromkeys(atp_list))
|
1430
|
+
|
1431
|
+
if DEBUG:
|
1432
|
+
print("In plot_line2_twinx")
|
1433
|
+
print("atp_list=",atp_list)
|
1434
|
+
|
1435
|
+
if not atp_list==[] and not atp_list==['']:
|
1436
|
+
|
1437
|
+
for at in atp_list:
|
1438
|
+
pos=atp_list.index(at)
|
1439
|
+
color=atp_color_list[pos]
|
1440
|
+
|
1441
|
+
#判断是否日期字符串
|
1442
|
+
try:
|
1443
|
+
at=datetime.strptime(at, date_format)
|
1444
|
+
atpd=pd.to_datetime(at)
|
1445
|
+
except:
|
1446
|
+
atpd=at
|
1447
|
+
ax.axvline(x=atpd,ls=":",c=color,linewidth=1.5,label=text_lang("关注点","Attention point ")+str(at))
|
1448
|
+
|
1449
|
+
if not attention_point_area=='':
|
1450
|
+
if isinstance(attention_point_area,list) and len(attention_point_area)>=2:
|
1451
|
+
apa_list=[]
|
1452
|
+
for ap in attention_point_area:
|
1453
|
+
try:
|
1454
|
+
ap=datetime.strptime(ap, date_format)
|
1455
|
+
appd=pd.to_datetime(ap)
|
1456
|
+
except:
|
1457
|
+
appd=ap
|
1458
|
+
apa_list=apa_list+[appd]
|
1459
|
+
|
1460
|
+
yaxis_data=plt.ylim()
|
1461
|
+
ax.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
|
1462
|
+
|
1463
|
+
#绘证券1:制趋势线
|
1464
|
+
if power > 0:
|
1465
|
+
lang=check_language()
|
1466
|
+
trend_txt='趋势线'
|
1467
|
+
if lang == 'English':
|
1468
|
+
trend_txt='Trend line'
|
1469
|
+
|
1470
|
+
#生成行号,借此将横轴的日期数量化,以便拟合
|
1471
|
+
df1['id']=range(len(df1))
|
1472
|
+
|
1473
|
+
#设定多项式拟合,power为多项式次数
|
1474
|
+
import numpy as np
|
1475
|
+
parameter = np.polyfit(df1.id, df1[colname1], power)
|
1476
|
+
f = np.poly1d(parameter)
|
1477
|
+
|
1478
|
+
if ticker1 == '':
|
1479
|
+
label1txt=''
|
1480
|
+
else:
|
1481
|
+
label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
|
1482
|
+
ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
|
1483
|
+
|
1484
|
+
# 纵轴标签
|
1485
|
+
#ax.set_ylabel(label1txt,fontsize=ylabel_txt_size)
|
1486
|
+
#ax.legend(loc=loc1,fontsize=legend_txt_size)
|
1487
|
+
|
1488
|
+
# 横轴标签
|
1489
|
+
#ax.set_xlabel(text_lang("日期","Date"),fontsize=xlabel_txt_size,ha='center')
|
1490
|
+
|
1491
|
+
#绘图右图===================================================================
|
1492
|
+
#设置画布背景颜色
|
1493
|
+
ax2.set_facecolor(facecolor)
|
1494
|
+
|
1495
|
+
# 折线标签
|
1496
|
+
if ticker2 == '':
|
1497
|
+
label2txt=label2
|
1498
|
+
else:
|
1499
|
+
if label2 == '':
|
1500
|
+
label2txt=ticker_name(ticker2,ticker_type_list[1])
|
1501
|
+
else:
|
1502
|
+
label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
|
1503
|
+
|
1504
|
+
# 设置子图标题
|
1505
|
+
if ticker1 != ticker2:
|
1506
|
+
ax2.set_title(label2txt,fontsize=xlabel_txt_size)
|
1507
|
+
else:
|
1508
|
+
ax2.set_title(ectranslate(colname2),fontsize=xlabel_txt_size)
|
1509
|
+
|
1510
|
+
# 绘图
|
1511
|
+
lwadjust=linewidth_adjust(df2)
|
1512
|
+
"""
|
1513
|
+
ax2.plot(df2.index,df2[colname2],'-',label=label2txt, \
|
1514
|
+
linestyle='-.',color=color2,linewidth=lwadjust)
|
1515
|
+
"""
|
1516
|
+
ax2.plot(df2.index,df2[colname2],'-', \
|
1517
|
+
linestyle='-.',color=color2,linewidth=lwadjust)
|
1518
|
+
|
1519
|
+
#证券2:绘制数据标签
|
1520
|
+
if datatag2:
|
1521
|
+
for x, y in zip(df2.index, df2[colname2]):
|
1522
|
+
ax2.text(x,y+0.1,'%.2f' % y,ha='center',va='bottom',color='black')
|
1523
|
+
|
1524
|
+
#绘证券2:制趋势线
|
1525
|
+
if power > 0:
|
1526
|
+
lang=check_language()
|
1527
|
+
trend_txt='趋势线'
|
1528
|
+
if lang == 'English':
|
1529
|
+
trend_txt='Trend line'
|
1530
|
+
|
1531
|
+
#生成行号,借此将横轴的日期数量化,以便拟合
|
1532
|
+
df2['id']=range(len(df2))
|
1533
|
+
|
1534
|
+
#设定多项式拟合,power为多项式次数
|
1535
|
+
import numpy as np
|
1536
|
+
parameter = np.polyfit(df2.id, df2[colname2], power)
|
1537
|
+
f = np.poly1d(parameter)
|
1538
|
+
|
1539
|
+
if ticker2 == '':
|
1540
|
+
label2txt=''
|
1541
|
+
else:
|
1542
|
+
label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
|
1543
|
+
ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
|
1544
|
+
|
1545
|
+
# 纵轴标签
|
1546
|
+
#ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
|
1547
|
+
#ax2.legend(loc=loc2,fontsize=legend_txt_size)
|
1548
|
+
|
1549
|
+
# 横轴标签
|
1550
|
+
#ax2.set_xlabel(text_lang("日期","Date"),fontsize=xlabel_txt_size,ha='center')
|
1551
|
+
|
1552
|
+
#自动优化x轴标签
|
1553
|
+
#ax2.autofmt_xdate(ha="center") # 优化标注(自动倾斜)
|
1554
|
+
|
1555
|
+
# 共同脚注==================================================================
|
1556
|
+
fig.text(0.5,-0.01,footnote,ha='center',fontsize=xlabel_txt_size,color='gray')
|
1557
|
+
#plt.xlabel(footnote,ha='center',fontsize=xlabel_txt_size,color='gray')
|
1558
|
+
|
1559
|
+
# 自动倾斜横轴日期
|
1560
|
+
fig.autofmt_xdate(ha="center")
|
1561
|
+
|
1562
|
+
# 调整布局防止重叠
|
1563
|
+
plt.tight_layout()
|
1564
|
+
plt.show()
|
1565
|
+
|
1566
|
+
return
|
1567
|
+
|
1568
|
+
|
1569
|
+
#==============================================================================
|
1570
|
+
def plot_line2_UD(df01,ticker1,colname1,label1, \
|
1571
|
+
df02,ticker2,colname2,label2, \
|
1572
|
+
titletxt,footnote,power=0, \
|
1573
|
+
datatag1=False,datatag2=False, \
|
1574
|
+
resample_freq='D', \
|
1575
|
+
xline=999,attention_point_area='', \
|
1576
|
+
loc1='upper left',loc2='lower left', \
|
1577
|
+
color1='red',color2='blue',facecolor='whitesmoke', \
|
1578
|
+
ticker_type='auto', \
|
1579
|
+
maxticks=15):
|
1580
|
+
"""
|
1581
|
+
功能:绘制两个证券或指标的上下折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
|
1582
|
+
假定:数据表有索引,且已经按照索引排序
|
1583
|
+
输入:
|
1584
|
+
证券1:数据表df1,证券代码ticker1,列名1,列名标签1;
|
1585
|
+
证券2:数据表df2,证券代码ticker2,列名2,列名标签2;
|
1586
|
+
标题titletxt,脚注footnote;是否在图中标记数据datatag;趋势图的多项式次数power
|
1587
|
+
输出:绘制上下并列折线图
|
1588
|
+
返回值:无
|
1589
|
+
注意:需要日期类型作为df索引
|
1590
|
+
"""
|
1591
|
+
DEBUG=False
|
1592
|
+
|
1593
|
+
#plt.rcParams['axes.grid']=False
|
1594
|
+
|
1595
|
+
#插值平滑
|
1596
|
+
try:
|
1597
|
+
df01x=df01[[colname1]].astype('float')
|
1598
|
+
df1=df_smooth_manual(df01x,resample_freq=resample_freq)
|
1599
|
+
except:
|
1600
|
+
df1=df01
|
1601
|
+
try:
|
1602
|
+
df02x=df02[[colname2]].astype('float')
|
1603
|
+
df2=df_smooth_manual(df02x,resample_freq=resample_freq)
|
1604
|
+
except:
|
1605
|
+
df2=df02
|
1606
|
+
|
1607
|
+
#预处理ticker_type
|
1608
|
+
ticker_type_list=ticker_type_preprocess_mticker_mixed([ticker1,ticker2],ticker_type)
|
1609
|
+
|
1610
|
+
#创建画布:绘制折线图,上下双子图
|
1611
|
+
fig, (ax, ax2) = plt.subplots(2, 1)
|
1612
|
+
|
1613
|
+
#设置主标题
|
1614
|
+
#plt.suptitle(titletxt,fontweight='bold',fontsize=title_txt_size, y=1.01) # y参数调整垂直位置
|
1615
|
+
plt.suptitle(titletxt,fontweight='bold',fontsize=title_txt_size)
|
1616
|
+
|
1617
|
+
# 绘制左子图================================================================
|
1618
|
+
#设置画布背景颜色
|
1619
|
+
try:
|
1620
|
+
ax.set_facecolor(facecolor)
|
1621
|
+
except:
|
1622
|
+
print(" #Warning(plot_line2_twinx): color",facecolor,"is unsupported")
|
1623
|
+
facecolor="whitesmoke"
|
1624
|
+
ax.set_facecolor(facecolor)
|
1625
|
+
|
1626
|
+
# 设置折线标签
|
1627
|
+
if ticker1 == '':
|
1628
|
+
label1txt=label1
|
1629
|
+
else:
|
1630
|
+
if label1 == '':
|
1631
|
+
label1txt=ticker_name(ticker1,ticker_type_list[0])
|
1632
|
+
else:
|
1633
|
+
label1txt=ticker_name(ticker1,ticker_type_list[0])+'('+label1+')'
|
1634
|
+
|
1635
|
+
# 设置子图标题
|
1636
|
+
"""
|
1637
|
+
if ticker1 != ticker2:
|
1638
|
+
ax.set_title(label1txt,fontsize=xlabel_txt_size)
|
1639
|
+
else:
|
1640
|
+
ax.set_title(ectranslate(colname1),fontsize=xlabel_txt_size)
|
1641
|
+
"""
|
1642
|
+
# 绘图
|
1643
|
+
lwadjust=linewidth_adjust(df1)
|
1644
|
+
"""
|
1645
|
+
ax.plot(df1.index,df1[colname1],'-',label=label1txt, \
|
1646
|
+
linestyle='-',color=color1,linewidth=lwadjust)
|
1647
|
+
"""
|
1648
|
+
ax.plot(df1.index,df1[colname1],'-', \
|
1649
|
+
linestyle='-',color=color1,linewidth=lwadjust)
|
1650
|
+
|
1651
|
+
#证券1:绘制数据标签
|
1652
|
+
if datatag1:
|
1653
|
+
for x, y in zip(df1.index, df1[colname1]):
|
1654
|
+
ax.text(x,y+0.1,'%.2f' % y,ha='center',va='bottom',color='black')
|
1655
|
+
|
1656
|
+
#绘制关注点
|
1657
|
+
import pandas as pd
|
1658
|
+
from datetime import datetime; date_format="%Y-%m-%d"
|
1659
|
+
if xline != 999:
|
1660
|
+
attention_point=xline
|
1661
|
+
|
1662
|
+
#用于关注点的颜色列表
|
1663
|
+
atp_color_list=["crimson","dodgerblue","magenta","lightseagreen","chocolate"]
|
1664
|
+
|
1665
|
+
if isinstance(attention_point,str) or isinstance(attention_point,int) or isinstance(attention_point,float):
|
1666
|
+
atp_list=[attention_point]
|
1667
|
+
elif isinstance(attention_point,list):
|
1668
|
+
atp_list=attention_point
|
1669
|
+
else:
|
1670
|
+
atp_list=[]
|
1671
|
+
#去重,不打乱原来的顺序
|
1672
|
+
atp_list=list(dict.fromkeys(atp_list))
|
1673
|
+
|
1674
|
+
if DEBUG:
|
1675
|
+
print("In plot_line2_twinx")
|
1676
|
+
print("atp_list=",atp_list)
|
1677
|
+
|
1678
|
+
if not atp_list==[] and not atp_list==['']:
|
1679
|
+
|
1680
|
+
for at in atp_list:
|
1681
|
+
pos=atp_list.index(at)
|
1682
|
+
color=atp_color_list[pos]
|
1683
|
+
|
1684
|
+
#判断是否日期字符串
|
1685
|
+
try:
|
1686
|
+
at=datetime.strptime(at, date_format)
|
1687
|
+
atpd=pd.to_datetime(at)
|
1688
|
+
except:
|
1689
|
+
atpd=at
|
1690
|
+
ax.axvline(x=atpd,ls=":",c=color,linewidth=1.5,label=text_lang("关注点","Attention point ")+str(at))
|
1691
|
+
|
1692
|
+
if not attention_point_area=='':
|
1693
|
+
if isinstance(attention_point_area,list) and len(attention_point_area)>=2:
|
1694
|
+
apa_list=[]
|
1695
|
+
for ap in attention_point_area:
|
1696
|
+
try:
|
1697
|
+
ap=datetime.strptime(ap, date_format)
|
1698
|
+
appd=pd.to_datetime(ap)
|
1699
|
+
except:
|
1700
|
+
appd=ap
|
1701
|
+
apa_list=apa_list+[appd]
|
1702
|
+
|
1703
|
+
yaxis_data=plt.ylim()
|
1704
|
+
ax.fill_betweenx(yaxis_data,apa_list[0],apa_list[1],color='powderblue',alpha=0.5)
|
1705
|
+
|
1706
|
+
#绘证券1:制趋势线
|
1707
|
+
if power > 0:
|
1708
|
+
lang=check_language()
|
1709
|
+
trend_txt='趋势线'
|
1710
|
+
if lang == 'English':
|
1711
|
+
trend_txt='Trend line'
|
1712
|
+
|
1713
|
+
#生成行号,借此将横轴的日期数量化,以便拟合
|
1714
|
+
df1['id']=range(len(df1))
|
1715
|
+
|
1716
|
+
#设定多项式拟合,power为多项式次数
|
1717
|
+
import numpy as np
|
1718
|
+
parameter = np.polyfit(df1.id, df1[colname1], power)
|
1719
|
+
f = np.poly1d(parameter)
|
1720
|
+
|
1721
|
+
if ticker1 == '':
|
1722
|
+
label1txt=''
|
1723
|
+
else:
|
1724
|
+
label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
|
1725
|
+
ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
|
1726
|
+
|
1727
|
+
# 纵轴标签
|
1728
|
+
if ticker1 != ticker2:
|
1729
|
+
ax.set_ylabel(label1txt,fontsize=ylabel_txt_size)
|
1730
|
+
else:
|
1731
|
+
ax.set_ylabel(ectranslate(colname1),fontsize=ylabel_txt_size)
|
1732
|
+
#ax.legend(loc=loc1,fontsize=legend_txt_size)
|
1733
|
+
|
1734
|
+
# 横轴标签
|
1735
|
+
#ax.set_xlabel(text_lang("日期","Date"),fontsize=xlabel_txt_size,ha='center')
|
1736
|
+
|
1737
|
+
#绘图右图===================================================================
|
1738
|
+
#设置画布背景颜色
|
1739
|
+
ax2.set_facecolor(facecolor)
|
1740
|
+
|
1741
|
+
# 折线标签
|
1742
|
+
if ticker2 == '':
|
1743
|
+
label2txt=label2
|
1744
|
+
else:
|
1745
|
+
if label2 == '':
|
1746
|
+
label2txt=ticker_name(ticker2,ticker_type_list[1])
|
1747
|
+
else:
|
1748
|
+
label2txt=ticker_name(ticker2,ticker_type_list[1])+'('+label2+')'
|
1749
|
+
|
1750
|
+
# 设置子图标题
|
1751
|
+
"""
|
1752
|
+
if ticker1 != ticker2:
|
1753
|
+
ax2.set_title(label2txt,fontsize=xlabel_txt_size)
|
1754
|
+
else:
|
1755
|
+
ax2.set_title(ectranslate(colname2),fontsize=xlabel_txt_size)
|
1756
|
+
"""
|
1757
|
+
# 绘图
|
1758
|
+
lwadjust=linewidth_adjust(df2)
|
1759
|
+
"""
|
1760
|
+
ax2.plot(df2.index,df2[colname2],'-',label=label2txt, \
|
1761
|
+
linestyle='-.',color=color2,linewidth=lwadjust)
|
1762
|
+
"""
|
1763
|
+
ax2.plot(df2.index,df2[colname2],'-', \
|
1764
|
+
linestyle='-.',color=color2,linewidth=lwadjust)
|
1765
|
+
|
1766
|
+
#证券2:绘制数据标签
|
1767
|
+
if datatag2:
|
1768
|
+
for x, y in zip(df2.index, df2[colname2]):
|
1769
|
+
ax2.text(x,y+0.1,'%.2f' % y,ha='center',va='bottom',color='black')
|
1770
|
+
|
1771
|
+
#绘证券2:制趋势线
|
1772
|
+
if power > 0:
|
1773
|
+
lang=check_language()
|
1774
|
+
trend_txt='趋势线'
|
1775
|
+
if lang == 'English':
|
1776
|
+
trend_txt='Trend line'
|
1777
|
+
|
1778
|
+
#生成行号,借此将横轴的日期数量化,以便拟合
|
1779
|
+
df2['id']=range(len(df2))
|
1780
|
+
|
1781
|
+
#设定多项式拟合,power为多项式次数
|
1782
|
+
import numpy as np
|
1783
|
+
parameter = np.polyfit(df2.id, df2[colname2], power)
|
1784
|
+
f = np.poly1d(parameter)
|
1785
|
+
|
1786
|
+
if ticker2 == '':
|
1787
|
+
label2txt=''
|
1788
|
+
else:
|
1789
|
+
label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
|
1790
|
+
ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
|
1791
|
+
|
1792
|
+
# 纵轴标签
|
1793
|
+
if ticker1 != ticker2:
|
1794
|
+
ax2.set_ylabel(label2txt,fontsize=ylabel_txt_size)
|
1795
|
+
else:
|
1796
|
+
ax2.set_ylabel(ectranslate(colname2),fontsize=ylabel_txt_size)
|
1797
|
+
#ax2.legend(loc=loc2,fontsize=legend_txt_size)
|
1798
|
+
|
1799
|
+
# 横轴标签
|
1800
|
+
#ax2.set_xlabel(text_lang("日期","Date"),fontsize=xlabel_txt_size,ha='center')
|
1801
|
+
|
1802
|
+
#自动优化x轴标签
|
1803
|
+
#ax2.autofmt_xdate(ha="center") # 优化标注(自动倾斜)
|
1804
|
+
|
1805
|
+
# 共同脚注==================================================================
|
1806
|
+
fig.text(0.5,-0.01,footnote,ha='center',fontsize=xlabel_txt_size,color='gray')
|
1807
|
+
#plt.xlabel(footnote,ha='center',fontsize=xlabel_txt_size,color='gray')
|
1808
|
+
|
1809
|
+
# 自动倾斜横轴日期
|
1810
|
+
fig.autofmt_xdate(ha="center")
|
1811
|
+
|
1812
|
+
# 调整布局防止重叠
|
1813
|
+
plt.tight_layout()
|
1814
|
+
plt.show()
|
1815
|
+
|
1816
|
+
return
|
1817
|
+
|
1305
1818
|
#==============================================================================
|
1306
1819
|
def plot_line2_twinx2(df01,ticker1,colname1,label1, \
|
1307
1820
|
df02,ticker2,colname2,label2, \
|
siat/valuation_china.py
CHANGED
@@ -205,20 +205,19 @@ if __name__ =="__main__":
|
|
205
205
|
|
206
206
|
|
207
207
|
def valuation_china(start='MRY',end='today',indicator='pe', \
|
208
|
-
|
209
|
-
|
210
|
-
|
208
|
+
method='lyr',value='value',statistic='median', \
|
209
|
+
average_value=False,show_index=False, \
|
210
|
+
power=0,twinx=False, \
|
211
211
|
|
212
|
-
|
213
|
-
|
214
|
-
|
212
|
+
band_area='', \
|
213
|
+
attention_value='',attention_value_area='', \
|
214
|
+
attention_point='',attention_point_area='', \
|
215
215
|
|
216
|
-
|
217
|
-
|
216
|
+
annotate=False,annotate_value=False,plus_sign=True, \
|
217
|
+
mark_start=False,mark_top=False,mark_bottom=False,mark_end=False, \
|
218
218
|
|
219
|
-
|
220
|
-
|
221
|
-
maxticks=20):
|
219
|
+
loc1='upper left',loc2='lower right', \
|
220
|
+
facecolor='whitesmoke',maxticks=20):
|
222
221
|
"""
|
223
222
|
===========================================================================
|
224
223
|
功能:比较中国全A股市场的估值指标变化趋势
|
@@ -440,7 +439,8 @@ def valuation_china(start='MRY',end='today',indicator='pe', \
|
|
440
439
|
mark_start=True,mark_top=True,mark_bottom=True,mark_end=mark_end, \
|
441
440
|
facecolor=facecolor,maxticks=maxticks)
|
442
441
|
|
443
|
-
elif twinx and len(list(df)) >= 2:
|
442
|
+
#elif twinx and len(list(df)) >= 2:
|
443
|
+
elif twinx != False and len(list(df)) >= 2:
|
444
444
|
ticker1=ticker2=''
|
445
445
|
colname1=label1=list(df)[0]; df1=df[[colname1]]
|
446
446
|
colname2=label2=list(df)[1]; df2=df[[colname2]]
|
@@ -449,7 +449,8 @@ def valuation_china(start='MRY',end='today',indicator='pe', \
|
|
449
449
|
df2,ticker2,colname2,label2, \
|
450
450
|
ylabeltxt,titletxt,footnote, \
|
451
451
|
power=power,datatag1=False,datatag2=False,yscalemax=5, \
|
452
|
-
zeroline=False,
|
452
|
+
zeroline=False, \
|
453
|
+
twinx=twinx, \
|
453
454
|
yline=999,attention_value_area='', \
|
454
455
|
xline=999,attention_point_area='', \
|
455
456
|
resample_freq='H',loc1=loc1,loc2=loc2, \
|
@@ -64,7 +64,7 @@ siat/future_china.py,sha256=F-HsIf2Op8Z22RzTjet1g8COzldgnMjFNSXsAkeGyWo,17595
|
|
64
64
|
siat/future_china_test.py,sha256=BrSzmDVaOHki6rntOtosmRn-6dkfOBuLulJNqh7MOpc,1163
|
65
65
|
siat/global_index_test.py,sha256=hnFp3wqqzzL-kAP8mgxDZ54Bd5Ijf6ENi5YJlGBgcXw,2402
|
66
66
|
siat/google_authenticator.py,sha256=ZUbZR8OW0IAKDbcYtlqGqIpZdERpFor9NccFELxg9yI,1637
|
67
|
-
siat/grafix.py,sha256=
|
67
|
+
siat/grafix.py,sha256=Noy_gIwVGjktPgfUIx-KZQJ-pjtwR3o7iBI030m4wzs,139126
|
68
68
|
siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
|
69
69
|
siat/holding_risk.py,sha256=uWRtMMJqKr-puQn26g6Fq5N3mFB70c0B99zLQug8hAo,30774
|
70
70
|
siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
|
@@ -140,12 +140,12 @@ siat/translate_20240606.py,sha256=63IyHWEU3Uz9mjwyuAX3fqY4nUMdwh0ICQAgmgPXP7Y,21
|
|
140
140
|
siat/translate_241003_keep.py,sha256=un7Fqe1v35MXsja5exZgjmLzrZtt66NARZIGlyFuGGU,218747
|
141
141
|
siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
142
142
|
siat/valuation.py,sha256=K7epQC_UtELjRR5cyjJp4gskSyJMxXy-jHIAS0SUEj8,51801
|
143
|
-
siat/valuation_china.py,sha256=
|
143
|
+
siat/valuation_china.py,sha256=eSKIDckyjG8QkENlW_OKkqbQHno8pzDcomBO9iGNJVM,83079
|
144
144
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
145
145
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
146
146
|
siat/yf_name.py,sha256=laNKMTZ9hdenGX3IZ7G0a2RLBKEWtUQJFY9CWuk_fp8,24058
|
147
|
-
siat-3.8.
|
148
|
-
siat-3.8.
|
149
|
-
siat-3.8.
|
150
|
-
siat-3.8.
|
151
|
-
siat-3.8.
|
147
|
+
siat-3.8.35.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
|
148
|
+
siat-3.8.35.dist-info/METADATA,sha256=3q8Ct67TlVKt9RRhekzd2I5JXTdrtUqT-4G62BkeH-I,8321
|
149
|
+
siat-3.8.35.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
150
|
+
siat-3.8.35.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
151
|
+
siat-3.8.35.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|