siat 3.4.16__py3-none-any.whl → 3.4.27__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/economy.py CHANGED
@@ -197,7 +197,8 @@ if __name__=='__main__':
197
197
 
198
198
 
199
199
 
200
- def economy_trend(start,end,scope='China',factor='GDP',datatag=False,power=0,zeroline=False):
200
+ def economy_trend(start,end,scope='China',factor='GDP',datatag=False,power=0, \
201
+ zeroline=False,yline=999,facecolor='papayawhip'):
201
202
  """
202
203
  功能:绘制宏观经济指标,单线,有趋势线
203
204
  """
@@ -222,7 +223,26 @@ def economy_trend(start,end,scope='China',factor='GDP',datatag=False,power=0,zer
222
223
  footnote='单位: '+list(ds['units'])[0]+', '+list(ds['freq'])[0]+ \
223
224
  '\n数据来源: OECD|IMF|WB|FRED, '+str(today)
224
225
  ds.dropna(inplace=True)
225
- plot_line(ds,'VALUE',ectranslate(factor),ylabeltxt,titletxt,footnote,datatag,power=power,zeroline=zeroline)
226
+
227
+ if factor in ['GNP Ratio','GNI Ratio']:
228
+ ylabeltxt='GNP(GNI)/GDP'
229
+ if yline==999:
230
+ yline=1 #绘制y=1的水平线
231
+ if factor in ['Currency Value','Constant CPI']:
232
+ ylabeltxt=ectranslate(factor)
233
+ if yline==999:
234
+ yline=100 #绘制y=100的水平线
235
+
236
+ if yline !=999:
237
+ zeroline=yline
238
+ if power==0:
239
+ power=3
240
+
241
+ plot_line(ds,'VALUE',ectranslate(factor), \
242
+ ylabeltxt=ylabeltxt,titletxt=titletxt,footnote=footnote,datatag=datatag, \
243
+ power=power,zeroline=zeroline, \
244
+ mark_top=False,mark_bottom=False,mark_end=False, \
245
+ facecolor=facecolor)
226
246
 
227
247
  return ds
228
248
 
@@ -236,16 +256,26 @@ if __name__=='__main__':
236
256
 
237
257
  #==============================================================================
238
258
  if __name__=='__main__':
259
+ #测试1
239
260
  tickers=['China','USA']
240
261
  measures='M2 GoB'
241
262
  measures='GNI'
263
+
264
+ #测试2
265
+ tickers=['China','USA']
266
+ measures='Constant CPI'
267
+ measures='Currency Value'
268
+
269
+
270
+
242
271
  fromdate='1999-12-1'
243
272
  todate='2022-4-1'
244
273
  power=0; twinx=False; loc1='upper left'; loc2='lower right'
245
274
 
246
275
 
247
276
  def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
248
- loc1='upper left',loc2='lower right'):
277
+ yline=999, \
278
+ loc1='upper left',loc2='lower right',facecolor='papayawhip'):
249
279
  """
250
280
  功能:对比绘制折线图:一个国家的两种测度,或两个国家的同一个测度。
251
281
  输入:
@@ -260,6 +290,10 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
260
290
  输出:绘制经济指标折线图,手动指定是否使用单轴或双轴坐标。
261
291
  返回:无
262
292
  """
293
+ DEBUG=False
294
+ if DEBUG:
295
+ print("DEBUG: tickers =",tickers,"\b, measures =",measures)
296
+
263
297
  #检查日期期间的合理性
264
298
  valid,_,_=check_period(fromdate,todate)
265
299
  if not valid:
@@ -354,15 +388,21 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
354
388
  source_txt+str(today)
355
389
 
356
390
  if lang == 'Chinese':
391
+ """
357
392
  plot_line2(df1,ectranslate(ticker1),'VALUE',ectranslate(measure1), \
358
393
  df2,ectranslate(ticker1),'VALUE',ectranslate(measure2), \
359
394
  ylabeltxt,titletxt,footnote, \
360
395
  power=power,twinx=twinx,loc1=loc1,loc2=loc2)
396
+ """
397
+ plot_line2(df1,ticker1,'VALUE',ectranslate(measure1), \
398
+ df2,ticker1,'VALUE',ectranslate(measure2), \
399
+ ylabeltxt,titletxt,footnote, \
400
+ power=power,twinx=twinx,loc1=loc1,loc2=loc2,facecolor=facecolor)
361
401
  else:
362
402
  plot_line2(df1,ticker1,'VALUE',measure1, \
363
403
  df2,ticker1,'VALUE',measure2, \
364
404
  ylabeltxt,titletxt,footnote, \
365
- power=power,twinx=twinx,loc1=loc1,loc2=loc2)
405
+ power=power,twinx=twinx,loc1=loc1,loc2=loc2,facecolor=facecolor)
366
406
 
367
407
  elif (security_num >= 2) and (measure_num >= 1):
368
408
  #双国家+单个测度指标
@@ -402,13 +442,15 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
402
442
  #绘制双国家单指标对比图
403
443
  ylabeltxt=ectranslate(measure1)
404
444
  #这里的GNP指标实际上是GNP vs GDP的百分比
405
- yline=999 #默认不绘制水平线
445
+ #yline=999 #默认不绘制水平线
406
446
  if measure1 in ['GNP Ratio','GNI Ratio']:
407
447
  ylabeltxt='GNP(GNI)/GDP'
408
- yline=1 #绘制y=1的水平线
448
+ if yline==999:
449
+ yline=1 #绘制y=1的水平线
409
450
  if measure1 in ['Currency Value','Constant CPI']:
410
451
  ylabeltxt=ectranslate(measure1)
411
- yline=100 #绘制y=100的水平线
452
+ if yline==999:
453
+ yline=100 #绘制y=100的水平线
412
454
 
413
455
  if lang == 'Chinese':
414
456
  titletxt=ectranslate(list(df1['name'])[0])+'趋势对比:'+ \
@@ -425,15 +467,21 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
425
467
  source_txt+str(today)
426
468
 
427
469
  if lang == 'Chinese':
470
+ """
428
471
  plot_line2(df1,ectranslate(ticker1),'VALUE',ectranslate(measure1), \
429
472
  df2,ectranslate(ticker2),'VALUE',ectranslate(measure1), \
430
473
  ylabeltxt,titletxt,footnote, \
431
474
  power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2)
475
+ """
476
+ plot_line2(df1,ticker1,'VALUE',measure1, \
477
+ df2,ticker2,'VALUE',measure1, \
478
+ ylabeltxt,titletxt,footnote, \
479
+ power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2,facecolor=facecolor)
432
480
  else:
433
481
  plot_line2(df1,ticker1,'VALUE',measure1, \
434
482
  df2,ticker2,'VALUE',measure1, \
435
483
  ylabeltxt,titletxt,footnote, \
436
- power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2)
484
+ power=power,twinx=twinx,yline=yline,loc1=loc1,loc2=loc2,facecolor=facecolor)
437
485
 
438
486
  else:
439
487
  print(" #Error(compare_economy): no idea on what to compare")
@@ -711,7 +759,7 @@ def fred_factor_codes():
711
759
  ['Italy','Current GDP','Annual','Gross Domestic Product','MKTGDPITA646NWDB','Current USD, Not Seasonally Adjusted'],
712
760
  ['Cambodia','Current GDP','Annual','Gross Domestic Product','MKTGDPKHA646NWDB','Current USD, Not Seasonally Adjusted'],
713
761
 
714
- # Real GDP at Constant National Prices:不变价格GDP,年度指标,百万美元,2017年基准,未经季节性调整。扣除通胀因素,扣除汇率变化因素
762
+ # Real GDP at Constant National Prices:不变价格GDP,年度指标,百万元,2017年基准,未经季节性调整。扣除通胀因素,扣除汇率变化因素
715
763
  ['India','Constant GDP','Annual','Real GDP at Constant National Prices','RGDPNAINA666NRUG','2017 USD Millions, Not Seasonally Adjusted'],
716
764
  ['China','Constant GDP','Annual','Real GDP at Constant National Prices','RGDPNACNA666NRUG','2017 USD Millions, Not Seasonally Adjusted'],
717
765
  ['Japan','Constant GDP','Annual','Real GDP at Constant National Prices','RGDPNAJPA666NRUG','2017 USD Millions, Not Seasonally Adjusted'],
@@ -1027,11 +1075,12 @@ def fred_factor_codes():
1027
1075
  #==============================================================================
1028
1076
  #==============================================================================
1029
1077
  if __name__ =="__main__":
1030
- fromdate='2022-1-1'
1031
- todate='2023-3-18'
1078
+ fromdate='2024-1-1'
1079
+ todate='2024-8-31'
1032
1080
  df=pmi_china(fromdate,todate)
1081
+ loc='best'; facecolor='papayawhip'
1033
1082
 
1034
- def pmi_china(fromdate,todate,loc='lower center'):
1083
+ def pmi_china(fromdate,todate,date_range=True,loc='best',facecolor='papayawhip'):
1035
1084
  """
1036
1085
  功能:绘制中国的PMI指数制造业/非制造业单线图
1037
1086
  """
@@ -1072,6 +1121,7 @@ def pmi_china(fromdate,todate,loc='lower center'):
1072
1121
  df2['制造业PMI']=df2['制造业-指数'].astype('float')
1073
1122
  df2['非制造业PMI']=df2['非制造业-指数'].astype('float')
1074
1123
 
1124
+ """
1075
1125
  #绘图:制造业
1076
1126
  ticker1=ticker2='PMI'
1077
1127
  colname2="benchmark"
@@ -1087,7 +1137,7 @@ def pmi_china(fromdate,todate,loc='lower center'):
1087
1137
  titletxt="中国采购经理人指数PMI:制造业"
1088
1138
  plot_line2(df2,ticker1,colname1,label1, \
1089
1139
  df2,ticker2,colname2,label2, \
1090
- ylabeltxt,titletxt,footnote,loc1=loc)
1140
+ ylabeltxt,titletxt,footnote,loc1=loc,facecolor=facecolor)
1091
1141
 
1092
1142
  #绘图:非制造业
1093
1143
  colname1="非制造业PMI"
@@ -1095,13 +1145,24 @@ def pmi_china(fromdate,todate,loc='lower center'):
1095
1145
  titletxt="中国采购经理人指数PMI:非制造业"
1096
1146
  plot_line2(df2,ticker1,colname1,label1, \
1097
1147
  df2,ticker2,colname2,label2, \
1098
- ylabeltxt,titletxt,footnote,loc1=loc)
1148
+ ylabeltxt,titletxt,footnote,loc1=loc,facecolor=facecolor)
1099
1149
  """
1150
+ titletxt="中国采购经理人指数PMI"
1151
+ ticker1=ticker2='PMI'
1152
+ colname1="制造业PMI"; label1="制造业"
1153
+ colname2="非制造业PMI"; label2="非制造业"
1154
+ ylabeltxt=''
1155
+
1156
+ import datetime
1157
+ today=datetime.date.today()
1158
+ footnote="数据来源:东方财富,"+str(today)
1159
+
1100
1160
  plot2_line2(df2,ticker1,colname1,label1, \
1101
1161
  df2,ticker2,colname2,label2, \
1102
- ylabeltxt,titletxt,footnote,loc1=loc, \
1103
- date_range=True,date_freq='1M',date_fmt='%Y-%m')
1104
- """
1162
+ yline=50, \
1163
+ ylabeltxt=ylabeltxt,titletxt=titletxt,footnote=footnote,loc1=loc, \
1164
+ date_range=date_range,date_fmt='%Y-%m',facecolor=facecolor)
1165
+
1105
1166
  #返回数据
1106
1167
  return df2
1107
1168
 
@@ -1168,13 +1229,13 @@ def internal_growth_rate_df(df0,fieldlist=['VALUE','scope','factor','freq','name
1168
1229
  if lang == 'Chinese':
1169
1230
  print('从'+date0+'至'+date1+':')
1170
1231
  if freq != 'Annual':
1171
- print(' '+ectranslate(scope)+ectranslate(factor)+'的'+ectranslate(freq)+'均环比增长率:',round(item_gr*100.0,4),'\b%')
1172
- print(' '+ectranslate(scope)+ectranslate(factor)+'的年均增长率:',round(annual_gr*100.0,4),'\b%')
1232
+ print(' '+ectranslate(scope)+ectranslate(factor)+'的'+ectranslate(freq)+'均环比复合增长率:',round(item_gr*100.0,4),'\b%')
1233
+ print(' '+ectranslate(scope)+ectranslate(factor)+'的年均复合增长率:',round(annual_gr*100.0,4),'\b%')
1173
1234
  else:
1174
1235
  print('From '+date0+' to '+date1+':')
1175
1236
  if freq != 'Annual':
1176
- print(' '+scope+', '+factor+' mom growth rate:',round(item_gr*100.0,4),'\b%')
1177
- print(' '+scope+', '+factor+' yoy growth rate:',round(annual_gr*100.0,4),'\b%')
1237
+ print(' '+scope+', '+factor+' mom compound growth rate:',round(item_gr*100.0,4),'\b%')
1238
+ print(' '+scope+', '+factor+' yoy compound growth rate:',round(annual_gr*100.0,4),'\b%')
1178
1239
 
1179
1240
  return
1180
1241
 
@@ -1204,6 +1265,81 @@ def internal_growth_rate(rvar,fieldlist=['VALUE','scope','factor','freq','name',
1204
1265
  if __name__ =="__main__":
1205
1266
  internal_growth_rate(df)
1206
1267
  #==============================================================================
1268
+ if __name__ =="__main__":
1269
+ ticker='China'
1270
+ indicator='GDP'
1271
+
1272
+
1273
+ def macro_trend(ticker,indicator,start='L10Y',end='today', \
1274
+ power=0,twinx=False,attention_value=999,zeroline=False, \
1275
+ datatag=False,date_range=False, \
1276
+ loc1='best',loc2='best',facecolor='papayawhip'):
1277
+ """
1278
+ 功能:套壳函数,compare_economy, economy_trend
1279
+ """
1280
+
1281
+ # 处理日期
1282
+ fromdate,todate=start_end_preprocess(start,end)
1283
+
1284
+ # 判断ticker个数
1285
+ if isinstance(ticker,str):
1286
+ ticker_num=1
1287
+ if isinstance(ticker,list):
1288
+ ticker_num=len(ticker)
1289
+ if ticker_num==1:
1290
+ ticker=ticker[0]
1291
+
1292
+ # 判断indicator个数
1293
+ if isinstance(indicator,str):
1294
+ indicator_num=1
1295
+ if isinstance(indicator,list):
1296
+ indicator_num=len(indicator)
1297
+ if indicator_num==1:
1298
+ indicator=indicator[0]
1299
+
1300
+ # 是否PMI
1301
+ if ticker_num==1 and indicator_num==1:
1302
+ if indicator.upper()=='PMI' and ticker.title()=='China':
1303
+ df=pmi_china(fromdate=fromdate,todate=todate, \
1304
+ date_range=date_range,loc=loc1,facecolor=facecolor)
1305
+
1306
+ return df
1307
+
1308
+ # 双ticker或者双indicator
1309
+ if ticker_num>=2 or indicator_num>=2:
1310
+ if 'YoY PPI' in indicator:
1311
+ attention_value=0
1312
+
1313
+ df=compare_economy(tickers=ticker,measures=indicator, \
1314
+ fromdate=fromdate,todate=todate, \
1315
+ power=power,twinx=twinx, \
1316
+ yline=attention_value, \
1317
+ loc1=loc1,loc2=loc2,facecolor=facecolor)
1318
+ # 计算增长率
1319
+ # 有inf/nan错误,未找出原因,先避开
1320
+ if not 'YoY PPI' in indicator:
1321
+ internal_growth_rate(df)
1322
+ return df
1323
+
1324
+ # 单ticker且单indicator
1325
+ if ticker_num==1 and indicator_num==1:
1326
+ if 'YoY PPI' in indicator:
1327
+ attention_value=0
1328
+
1329
+ df=economy_trend(start=fromdate,end=todate,scope=ticker,factor=indicator, \
1330
+ datatag=datatag,power=power, \
1331
+ zeroline=zeroline,yline=attention_value,facecolor=facecolor)
1332
+ # 计算增长率
1333
+ # 有inf/nan错误,未找出原因,先避开
1334
+ if not 'YoY PPI' in indicator:
1335
+ internal_growth_rate(df)
1336
+
1337
+ return df
1338
+
1339
+ print(" #Warning(macro_trend): puzzled on what to for",ticker,"with",indicator)
1340
+ return None
1341
+
1342
+
1207
1343
  #==============================================================================
1208
1344
  #==============================================================================
1209
1345
 
siat/grafix.py CHANGED
@@ -119,7 +119,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
119
119
  resample_freq='H',loc='best', \
120
120
  date_range=False,date_freq=False,date_fmt='%Y-%m-%d', \
121
121
  mark_top=True,mark_bottom=True,mark_end=True, \
122
- facecolor='whitesmoke'):
122
+ facecolor='whitesmoke'):
123
123
  """
124
124
  功能:绘制折线图。如果power=0不绘制趋势图,否则绘制多项式趋势图
125
125
  假定:数据表有索引,且已经按照索引排序
@@ -296,7 +296,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
296
296
  ylabeltxt=ylabeltxt.replace('收盘价','单位净值')
297
297
 
298
298
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
299
- plt.xlabel(footnote,fontsize=xlabel_txt_size)
299
+ plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
300
300
  plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
301
301
 
302
302
  plt.show()
@@ -560,7 +560,7 @@ def plot_line2_coaxial(df01,ticker1,colname1,label1, \
560
560
  plt.gca().set_facecolor("whitesmoke")
561
561
 
562
562
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
563
- plt.xlabel(footnote,fontsize=xlabel_txt_size)
563
+ plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
564
564
  plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
565
565
  plt.show()
566
566
  plt.close()
@@ -749,7 +749,7 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
749
749
  plt.gca().set_facecolor("whitesmoke")
750
750
 
751
751
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
752
- plt.xlabel(footnote,fontsize=xlabel_txt_size)
752
+ plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
753
753
  plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
754
754
  plt.show()
755
755
  plt.close()
@@ -877,7 +877,7 @@ def plot_line2_twinx(df01,ticker1,colname1,label1, \
877
877
  label2txt=ticker_name(ticker2,ticker_type_list[1])+"("+trend_txt+")"
878
878
  ax2.plot(df2.index, f(df2.id),"c--", label=label2txt,linewidth=1)
879
879
 
880
- ax.set_xlabel(footnote,fontsize=xlabel_txt_size)
880
+ ax.set_xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
881
881
 
882
882
  if ticker1 == '':
883
883
  label1txt=label1
@@ -1019,7 +1019,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1019
1019
  label1txt=ticker_name(ticker1,ticker_type_list[0])+"("+trend_txt+")"
1020
1020
  ax.plot(df1.index, f(df1.id),"r--", label=label1txt,linewidth=1)
1021
1021
 
1022
- ax.set_xlabel(footnote,fontsize=xlabel_txt_size)
1022
+ ax.set_xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
1023
1023
 
1024
1024
  if ticker1 == '':
1025
1025
  label1txt=label1
@@ -1307,7 +1307,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1307
1307
 
1308
1308
  x_label_t=ectranslate(x_label)
1309
1309
  if x_label != "":
1310
- plt.xlabel(x_label_t,fontweight='bold',fontsize=xlabel_txt_size)
1310
+ plt.xlabel(x_label_t,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
1311
1311
  #图示标题
1312
1312
  plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
1313
1313
 
@@ -1541,7 +1541,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1541
1541
  #坐标轴标记
1542
1542
  plt.ylabel(y_label,fontweight='bold',fontsize=ylabel_txt_size)
1543
1543
  if x_label != "":
1544
- plt.xlabel(x_label,fontweight='bold',fontsize=xlabel_txt_size)
1544
+ plt.xlabel(x_label,fontweight='bold',fontsize=xlabel_txt_size,ha='center')
1545
1545
  #图示标题
1546
1546
  plt.title(title_txt,fontweight='bold',fontsize=title_txt_size)
1547
1547
  plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
@@ -1579,7 +1579,7 @@ def plot_barh(df,colname,titletxt,footnote,datatag=True, \
1579
1579
 
1580
1580
  plt.barh(df.index,df[colname],align='center',color=colors,alpha=0.8)
1581
1581
  coltxt=ectranslate(colname)
1582
- plt.xlabel(footnote,fontsize=xlabel_txt_size)
1582
+ plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
1583
1583
  plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
1584
1584
 
1585
1585
  #xmin=int(min(df[colname]))
@@ -1784,7 +1784,7 @@ def plot_2lines(df01,colname1,label1, \
1784
1784
  plt.axvline(x=vline,ls=":",c="black")
1785
1785
 
1786
1786
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
1787
- plt.xlabel(footnote,fontsize=xlabel_txt_size)
1787
+ plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
1788
1788
  plt.legend(loc='best',fontsize=legend_txt_size)
1789
1789
 
1790
1790
  plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
@@ -2007,7 +2007,7 @@ def plot_norm(mu,sd,graph='pdf',obs_num=100,facecolor='whitesmoke'):
2007
2007
  wid1=5*sd+mu
2008
2008
  wid2=1*sd+mu
2009
2009
  plt.xticks(np.arange(-wid,wid1,wid2))
2010
- plt.xlabel('分位点',fontsize=xlabel_txt_size) #x轴文本
2010
+ plt.xlabel('分位点',fontsize=xlabel_txt_size,ha='center') #x轴文本
2011
2011
  plt.yticks(np.arange(0,0.45,0.05))
2012
2012
  plt.ylabel('概率密度',fontsize=ylabel_txt_size) #y轴文本
2013
2013
 
@@ -2015,7 +2015,7 @@ def plot_norm(mu,sd,graph='pdf',obs_num=100,facecolor='whitesmoke'):
2015
2015
  wid1=3.5*sd+mu
2016
2016
  wid2=0.5*sd+mu
2017
2017
  plt.xticks(np.arange(-wid,wid1,wid2))
2018
- plt.xlabel('分位点',fontsize=xlabel_txt_size) #x轴文本
2018
+ plt.xlabel('分位点',fontsize=xlabel_txt_size,ha='center') #x轴文本
2019
2019
  plt.yticks(np.arange(0,1.1,0.1))
2020
2020
  plt.ylabel('累积概率密度',fontsize=ylabel_txt_size) #y轴文本
2021
2021
 
@@ -2026,7 +2026,7 @@ def plot_norm(mu,sd,graph='pdf',obs_num=100,facecolor='whitesmoke'):
2026
2026
  plt.yticks(np.arange(-wid,wid1,wid2))
2027
2027
  plt.ylabel('分位点',fontsize=ylabel_txt_size) #y轴文本
2028
2028
  plt.xticks(np.arange(0,1.1,0.1))
2029
- plt.xlabel('累积概率密度',fontsize=xlabel_txt_size) #x轴文本
2029
+ plt.xlabel('累积概率密度',fontsize=xlabel_txt_size,ha='center') #x轴文本
2030
2030
 
2031
2031
  plt.title('正态分布示意图: $\mu$=%.1f, $\sigma$=%.1f'%(mu,sd),fontweight='bold',fontsize=title_txt_size) #标题
2032
2032
  plt.tight_layout()
siat/security_price2.py CHANGED
@@ -37,8 +37,11 @@ if __name__=='__main__':
37
37
  ticker='sz159998' #基金
38
38
 
39
39
  ticker='801010.SW' #申万
40
+ ticker='851242.SW' #申万
40
41
 
41
42
  ticker='AAPL'
43
+
44
+
42
45
  fromdate='2024-5-1'; todate='2024-5-20'
43
46
 
44
47
  ticker_type='auto'
@@ -49,7 +52,7 @@ if __name__=='__main__':
49
52
  ticker_type='fund'
50
53
 
51
54
  source='auto'
52
- source='yahoo'
55
+ #source='yahoo'
53
56
 
54
57
  adjust='qfq'
55
58
  fill=True
@@ -84,6 +87,7 @@ def get_price_1ticker(ticker,fromdate,todate, \
84
87
  #检查日期期间合理性
85
88
  valid_period,fromdatepd,todatepd=check_period(fromdate,todate)
86
89
  if not valid_period:
90
+ pass
87
91
  #print(" #Warning(get_price_1ticker): invalid date period from",fromdate,"to",todate)
88
92
  return df,found
89
93
 
@@ -612,6 +616,9 @@ if __name__=='__main__':
612
616
  ticker='180202.SZ'
613
617
  ticker_type='fund'
614
618
 
619
+ ticker='851242.SW'
620
+ ticker_type='auto'
621
+
615
622
  fromdate='2021-1-1'
616
623
  todate='2024-5-30'
617
624
  adjust=''
siat/security_prices.py CHANGED
@@ -2805,10 +2805,10 @@ def china_security_identify(ticker6):
2805
2805
 
2806
2806
  #==============================================================================
2807
2807
  if __name__=='__main__':
2808
- ticker='850831'
2808
+ ticker='850831.SW'
2809
2809
 
2810
- start='2023-1-1'
2811
- end='2023-4-4'
2810
+ start='2024-1-1'
2811
+ end='2024-4-4'
2812
2812
  info_types=['Close','Volume']
2813
2813
 
2814
2814
  df3=fetch_price_swindex(ticker,start,end)
@@ -2834,12 +2834,17 @@ def fetch_price_swindex(ticker,start,end,info_types=['Close','Volume'],adjust=-2
2834
2834
  _,start1pd,_=check_period(start1,end)
2835
2835
 
2836
2836
  import akshare as ak
2837
+ if len(ticker)==6:
2838
+ ticker=ticker+'.SW'
2839
+ ticker6=ticker[:6]
2837
2840
  try:
2838
- prices= ak.index_hist_sw(symbol=ticker,period="day")
2841
+ prices= ak.index_hist_sw(symbol=ticker6,period="day")
2839
2842
  except: pass
2840
2843
 
2841
2844
  found=df_have_data(prices)
2842
- if found not in ['Found','Empty']: return df
2845
+ if found not in ['Found','Empty']:
2846
+ pass
2847
+ return df
2843
2848
 
2844
2849
  prices.columns=['Code','Date','Close','Open','High','Low','Volume','Amount']
2845
2850
  million=1000000
siat/security_trend2.py CHANGED
@@ -76,6 +76,7 @@ if __name__=='__main__':
76
76
  indicator='Close'
77
77
  start="2020-1-1"
78
78
  end="2020-6-30"
79
+ ticker_type='auto'
79
80
 
80
81
 
81
82
  #测试组5
@@ -85,6 +86,29 @@ if __name__=='__main__':
85
86
  end="2024-5-30"
86
87
  ticker_type='fund'
87
88
 
89
+ #测试组6
90
+ ticker="851242.SW"
91
+ indicator='Close'
92
+ start="2024-1-1"
93
+ end="2024-6-30"
94
+ ticker_type='auto'
95
+
96
+ attention_value=''; average_value=False
97
+ kline=False; kline_demo=False; mav=[5,10,20]
98
+ dividend=False; split=False
99
+ ret_type='Annual Adj Ret%'; RF=0; regression_period=365; market_index="auto"
100
+ sortby='tpw_mean'; trailing=7; trend_threshhold=0.05
101
+ band_area=''
102
+ graph=True; twinx=False; loc1='best'; loc2='best'
103
+ datatag=False; power=0
104
+ smooth=True; date_range=False; date_freq=False
105
+ preprocess='none'; scaling_option='change%'
106
+ annotate=False; annotate_value=False
107
+ mark_top=False; mark_bottom=False; mark_end=False
108
+ printout=False; source='auto'
109
+ ticker_type='auto'
110
+ facecolor='papayawhip'
111
+
88
112
  df=security_trend(ticker,indicator,start,end,ticker_type=ticker_type)
89
113
 
90
114
 
siat/stock.py CHANGED
@@ -613,6 +613,16 @@ if __name__ =="__main__":
613
613
  ticker_type='auto'
614
614
  facecolor='whitesmoke'
615
615
 
616
+ # 测试组5
617
+ ticker='851242.SW'
618
+ indicator='Close'
619
+ fromdate='2024-5-1'; todate='2024-5-20'
620
+ adjust=''
621
+ zeroline=False; average_value=False; datatag=False; power=0; graph=True
622
+ source='auto'
623
+ mark_top=True; mark_bottom=True; mark_end=True
624
+ ticker_type='auto'
625
+ facecolor='whitesmoke'
616
626
 
617
627
  df=security_indicator(ticker,indicator,fromdate,todate,ticker_type=ticker_type)
618
628
 
siat/translate.py CHANGED
@@ -3266,6 +3266,10 @@ def ticker1_name(ticker,ticker_type='auto'):
3266
3266
  """
3267
3267
  功能:翻译单个证券名称:股票,基金,债券,投资组合
3268
3268
  """
3269
+ DEBUG=False
3270
+ if DEBUG:
3271
+ print("DEBUG: ticker=",ticker)
3272
+
3269
3273
  #投资组合
3270
3274
  if isinstance(ticker,dict):
3271
3275
  return portfolio_name(ticker)
@@ -3282,7 +3286,11 @@ def ticker1_name(ticker,ticker_type='auto'):
3282
3286
  return tname
3283
3287
  """
3284
3288
  tname=codetranslate(ticker)
3285
- if tname != ticker: #翻译成功,注意证券代码与其名称相同的情形,例如IBM
3289
+ if tname != ticker or ticker in ["IBM"]: #翻译成功,注意证券代码与其名称相同的情形,例如IBM
3290
+ return tname
3291
+
3292
+ tname=ectranslate(ticker)
3293
+ if tname != ticker:
3286
3294
  return tname
3287
3295
 
3288
3296
  symbol=ticker1_cvt2yahoo(ticker)
@@ -0,0 +1,7 @@
1
+ Copyright 2024 WANG Dehong
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software (siat) and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.4.16
3
+ Version: 3.4.27
4
4
  Summary: Securities Investment Analysis Tools (siat)
5
5
  Home-page: https://pypi.org/project/siat/
6
6
  Author: Prof. WANG Dehong, International Business School, Beijing Foreign Studies University
7
7
  Author-email: wdehong2000@163.com
8
8
  License: Copyright (C) WANG Dehong, 2024. For educational purpose only!
9
9
  Description-Content-Type: text/markdown
10
+ License-File: LICENSE
10
11
  Requires-Dist: pandas-datareader
11
12
  Requires-Dist: yfinance
12
13
  Requires-Dist: tqdm
@@ -35,18 +36,18 @@ Requires-Dist: itables
35
36
  Requires-Dist: py-trans
36
37
  Requires-Dist: bottleneck
37
38
 
38
- <center><font size=6>Welcome to SIAT
39
39
 
40
40
  # What is siat?
41
- siat is a Python plug-in for security investment analysis, specially designed for teaching and learning purposes in universities for undergraduate and postgraduate programs.
41
+ siat is a Python 3 plug-in for security investment analysis, primarily designed for teaching and learning purposes in universities for undergraduate and postgraduate programs.
42
42
 
43
- Most of the results by siat are in the form of figures and/or tables.
44
- # Version history
43
+ siat is recommended to run in Jupyter Notebook or Jupyter Lab, and most of its results are in the forms of figures and/or tables.
44
+ # Version naming
45
45
  Version structure: X.Y.Z
46
46
 
47
47
  X is the major version for architecture upgrade only.
48
- Y is the functional version for functional enhancement.
48
+ Y is the functional version for functional enhancements.
49
49
  Z is the minor version just for bug fixing.
50
+
50
51
  # Quick examples of using siat
51
52
 
52
53
 
@@ -68,7 +69,7 @@ set_language("English")
68
69
  # Simple way: show Apple's stock price in recent month
69
70
  apple=security_trend("AAPL")
70
71
  ```
71
- You may expect to more information, such as price trend in a recent year (MRY), with the high/low point, current price and average price, like below:
72
+ You may expect more information, such as price trend in a recent year (MRY), with the high/low point, current price and average price, like below:
72
73
 
73
74
  ```python
74
75
  apple=security_trend("AAPL", start="MRY",
@@ -85,7 +86,7 @@ Since there is a major stock split for NVidia in 2024 by 1:10, it is necessary t
85
86
  comp=security_trend(['AAPL','MSFT','NVDA'],
86
87
  start='MRQ',
87
88
  indicator='Adj Close',
88
- preprocess='scaling',
89
+ preprocess='scaling', #use scaling drawing method to avoid loss of details
89
90
  mark_top=True, mark_bottom=True,
90
91
  annotate=True, annotate_value=True)
91
92
  ```
@@ -94,8 +95,7 @@ comp=security_trend(['AAPL','MSFT','NVDA'],
94
95
 
95
96
 
96
97
  ```python
97
- # Script security_technical only supports 4 popular technical indicators: MACD, Bollinger band, KDJ and RSI.
98
-
98
+ # security_technical only supports 4 popular technical indicators: MACD, Bollinger, KDJ and RSI.
99
99
  apple=security_technical("AAPL",
100
100
  technical="Bollinger",
101
101
  start="MRQ",
@@ -107,15 +107,15 @@ apple=security_technical("AAPL",
107
107
 
108
108
 
109
109
  ```python
110
- # Script security_technical2 supports about 20 popular technical methods.
111
-
110
+ # security_technical2 supports up to 14 popular technical indicators.
111
+ # security_technical2 uses a simplied drawing method (Dehong graph) to avoid trypophobia [藢tr瑟p蓹u'f蓹蕣bj蓹]
112
112
  apple=security_technical2("AAPL",
113
113
  technical="CCI",
114
114
  start="MRM",
115
115
  loc1="upper left", loc2="lower right")
116
116
  ```
117
117
 
118
- # What security product does siat support?
118
+ # What security products does siat support?
119
119
  1. Public company profile: world-wide
120
120
  2. Stock & stock market index: world-wide
121
121
  3. Stock valuation: primarily in China (mainland and HK) and the U.S.
@@ -131,13 +131,13 @@ apple=security_technical2("AAPL",
131
131
  13. Cash flow statement: in China mainland (full function) and world-wide (basic function)
132
132
  14. DuPont Identity: world-wide
133
133
  15. Sector trend and valuation: primarily in China
134
- # What analytical methodology does siat support?
134
+ # What analytical methods does siat support?
135
135
  1. Trend analysis
136
136
  2. Panel comparation
137
137
  3. Return analysis: rolling returns, holding period returns
138
138
  4. Risk analysis: rolling volatility, holding period volatility, LPSD
139
139
  5. Technical analysis: more than 15 indicators
140
- 6. Risk-adjusted return: sharpe, sortino, treynor, Jensen alpha
140
+ 6. Risk-adjusted return: Sharpe ratio, Sortino ratio, Treynor ratio, Jensen alpha
141
141
  7. Portfolio optimization: four risk-adjusted returns
142
142
  8. CAPM beta trend
143
143
  9. Beta adjustments: simple adjustment, Scholes-Williams, Dimson
@@ -163,11 +163,15 @@ The main data sources siat uses:
163
163
  7. IMF
164
164
  8. Shanghai Stock Exchange
165
165
  9. Shenzhen Stock Exchange
166
- 10. Tokyo Stock Exchange
167
- 11. HKEX
168
- 12. Sustainalytics
169
-
170
- Thanks the above websites for their valuable data supply!
166
+ 10. Hong Kong Stock Exchange
167
+ 11. Beijing Stock Exchange
168
+ 12. Tokyo Stock Exchange
169
+ 13. London Stock Exchange
170
+ 14. New York Stock Exchange
171
+ 15. NASDAQ
172
+ 16. Sustainalytics
173
+
174
+ Thanks the above websites for their valuable data!
171
175
  # How to install siat?
172
176
  The author strongly recommends using siat together with Jupyter Notebook or Jupyter Lab in Anaconda.
173
177
  In order to install siat for the very first time, open a Jupyter Notebook, and type in the following command:
@@ -202,7 +206,7 @@ pip install --upgrade siat https://mirrors.aliyun.com/pypi/simple/
202
206
  *** Warning
203
207
  1. The pip command itself may need upgrade as well.
204
208
  2. The pip command sometimes may have conflicts with some vpn programs.
205
- If in this case, try quit vpn program, and try again.
209
+ If in this case, try quit vpn program first, and try again.
206
210
  # Are there more detailed case studies on using siat?
207
211
  YES!
208
212
 
@@ -28,7 +28,7 @@ siat/cryptocurrency.py,sha256=IjQTzqTkdp19aS0PrD15nU3-tfCJHyzt0oBd5nWvwk8,27449
28
28
  siat/cryptocurrency_test.py,sha256=3AikTNJ7j-HwLGLIYEfyXZ3bLVuLeru9mwiwHQi2SdA,2669
29
29
  siat/derivative.py,sha256=qV8n09799eqLc26ojR6vN5n_X-xd7rGwdYjgq-wBih8,41483
30
30
  siat/economy-20230125.py,sha256=vxZZlPnLkh7SpGMVEPLwxjt0yYLSVmdZrO-s2NYLyoM,73848
31
- siat/economy.py,sha256=J0-xBtp6gg6CNP9N-UvpKLJ-0Tw5O_DKaDvEq1R35Fw,73853
31
+ siat/economy.py,sha256=ijMAVA5ydghbQDgNDDdz8fz9NPd2eq90RzpJSRGWz5c,78638
32
32
  siat/economy_test.py,sha256=6vjNlPz7W125pJb7simCddobSEp3jmLIMvVkLRZ7zW8,13339
33
33
  siat/esg.py,sha256=GMhaonIKtvOK83rhpQUH5aJt2OL3HQBSVfD__Yw-0oo,19040
34
34
  siat/esg_test.py,sha256=Z9m6GUt8O7oHZSEG9aDYpGdvvrv2AiRJdHTiU6jqmZ0,2944
@@ -60,7 +60,7 @@ siat/future_china.py,sha256=F-HsIf2Op8Z22RzTjet1g8COzldgnMjFNSXsAkeGyWo,17595
60
60
  siat/future_china_test.py,sha256=BrSzmDVaOHki6rntOtosmRn-6dkfOBuLulJNqh7MOpc,1163
61
61
  siat/global_index_test.py,sha256=hnFp3wqqzzL-kAP8mgxDZ54Bd5Ijf6ENi5YJlGBgcXw,2402
62
62
  siat/google_authenticator.py,sha256=ZUbZR8OW0IAKDbcYtlqGqIpZdERpFor9NccFELxg9yI,1637
63
- siat/grafix.py,sha256=dFec-2Ds76JEfvsMj2HS-gHcufv3vpsWe4LwpNX_XoM,87219
63
+ siat/grafix.py,sha256=4e8_w2QT8cJo0uoKyICvod9b5a-L4-qFHnlr4YVnPwg,87359
64
64
  siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
65
65
  siat/holding_risk.py,sha256=G3wpaewAKF9CwEqRpr4khyuDu9SU2EGyQUHdk7cmHOA,30693
66
66
  siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
@@ -97,15 +97,15 @@ siat/risk_free_rate_test.py,sha256=CpmhUf8aEAEZeNu4gvWP2Mz2dLoIgBX5bI41vfUBEr8,4
97
97
  siat/sector_china.py,sha256=_-NgVSI2AMRCZw3U85ov6CgU5riii4Y9oY-rfUrfVSk,132551
98
98
  siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
99
99
  siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
100
- siat/security_price2.py,sha256=65s64L68aRZdVVK3V8UYxdPd_JHMqgJ2FBJJX5MSW-Q,26174
101
- siat/security_prices.py,sha256=ZEnuKgLnkw1O41BpR44Mpq53N69mW3UdSzEnI_4LuPc,106387
100
+ siat/security_price2.py,sha256=Y4suVC-4koUSI_n8kY0l0y4lo_CTcoeM_kwTHiIFzyM,26291
101
+ siat/security_prices.py,sha256=lh4G7Q20HoC3Iph8hOuACFcIc33xKyWBgMqhTykh8Qo,106492
102
102
  siat/security_prices_test.py,sha256=OEphoJ87NPKoNow1QA8EU_5MUYrJF-qKoWKNapVfZNI,10779
103
103
  siat/security_trend.py,sha256=o0vpWdrJkmODCP94X-Bvn-w7efHhj9HpUYBHtLl55D0,17240
104
104
  siat/security_trend2-20240620.py,sha256=QVnEcb7AyVbO77jVqfFsJffGXrX8pgJ9xCfoAKmWBPk,24854
105
- siat/security_trend2.py,sha256=lUMab8HilXIUPo_z9ZkztMiZ5kf3jAbbCwPPkYbQ1TI,25288
105
+ siat/security_trend2.py,sha256=za9vUgWUsfG_xCjwjtCdo3kpQKWjzw8pDNAJZuDwXl0,26115
106
106
  siat/setup.py,sha256=up65rQGLmTBkhtaMLowjoQXYmIsnycnm4g1SYmeQS6o,1335
107
107
  siat/shenwan index history test.py,sha256=JCVAzOSEldHalhSFa3pqD8JI_8_djPMQOxpkuYU-Esg,1418
108
- siat/stock.py,sha256=IY4-RC8jztjFEN4FFdc6YP299IRyIOwIcPRObswg588,152527
108
+ siat/stock.py,sha256=o8Mowq8qKYnRUczYdjV4Q_HSSMfbShylLUowDyYkXQ8,152856
109
109
  siat/stock_advice_linear.py,sha256=-twT7IGP-NEplkL1WPSACcNJjggRB2j4mlAQCkzOAuo,31655
110
110
  siat/stock_base.py,sha256=uISvbRyOGy8p9QREA96CVydgflBkn5L3OXOGKl8oanc,1312
111
111
  siat/stock_china.py,sha256=zyUyghIrkkkYWlHRRP7Hoblxzfp-jrck60pTJpwMahg,91553
@@ -131,7 +131,7 @@ siat/transaction_test.py,sha256=Z8g1LJCN4-mnUByXMUMoFmN0t105cbmsz2QmvSuIkbU,1858
131
131
  siat/translate-20230125.py,sha256=NPPSXhT38s5t9fzMvl_fvi4ckSB73ThLmZetVI-xGdU,117953
132
132
  siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,118133
133
133
  siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
134
- siat/translate.py,sha256=Isa2gjmuY6xKo3HwaPOR0CJzPqLalcu0J1Qw2cZbmFs,218567
134
+ siat/translate.py,sha256=un7Fqe1v35MXsja5exZgjmLzrZtt66NARZIGlyFuGGU,218747
135
135
  siat/translate_20240606.py,sha256=63IyHWEU3Uz9mjwyuAX3fqY4nUMdwh0ICQAgmgPXP7Y,215121
136
136
  siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
137
137
  siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
@@ -139,7 +139,8 @@ siat/valuation_china.py,sha256=EkZQaVkoBjM0c4MCNbaX-bMnlG0e3FXeaWczZDnkptU,67784
139
139
  siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
140
140
  siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
141
141
  siat/yf_name.py,sha256=9U_XfEeMlS3TrCrO3Bww21nuFgghbnO-cqDJMhQWqew,16193
142
- siat-3.4.16.dist-info/METADATA,sha256=6jn_hf0WErGP2RdyweWl-65rvA-ypaJ2y-UumDF2fyU,7683
143
- siat-3.4.16.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
144
- siat-3.4.16.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
145
- siat-3.4.16.dist-info/RECORD,,
142
+ siat-3.4.27.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
143
+ siat-3.4.27.dist-info/METADATA,sha256=q5-qoM2N-gp0-nDdPBTIigtYlPFAQldahmL6euBi0a0,8010
144
+ siat-3.4.27.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
145
+ siat-3.4.27.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
146
+ siat-3.4.27.dist-info/RECORD,,
File without changes