siat 3.1.12__py3-none-any.whl → 3.1.13__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/markowitz2.py CHANGED
@@ -154,10 +154,10 @@ def cumulative_returns_plot(retgroup,name_list="",titletxt="投资组合策略
154
154
  #取出观察期
155
155
  hstart0=retgroup.index[0]
156
156
  #hstart=str(hstart0.date())
157
- hstart=str(hstart0)
157
+ hstart=str(hstart0.strftime("%Y-%m-%d"))
158
158
  hend0=retgroup.index[-1]
159
159
  #hend=str(hend0.date())
160
- hend=str(hend0)
160
+ hend=str(hend0.strftime("%Y-%m-%d"))
161
161
 
162
162
  lang = check_language()
163
163
  import datetime as dt; stoday=dt.date.today()
@@ -222,28 +222,37 @@ def portfolio_hpr(portfolio,thedate,pastyears=1, \
222
222
  功能:套壳函数portfolio_build
223
223
  """
224
224
  dflist=portfolio_build(portfolio=portfolio,thedate=thedate,pastyears=pastyears, \
225
- RF=RF, \
226
- printout=printout,graph=graph)
225
+ printout=printout,graph=graph)
227
226
 
228
227
  return dflist
229
228
 
230
229
  #==============================================================================
231
230
  if __name__=='__main__':
231
+ #测试1
232
232
  Market={'Market':('US','^GSPC')}
233
233
  Market={'Market':('US','^GSPC','我的组合001')}
234
234
  Stocks1={'AAPL':.3,'MSFT':.15,'AMZN':.15,'GOOG':.01}
235
235
  Stocks2={'XOM':.02,'JNJ':.02,'JPM':.01,'TSLA':.3,'SBUX':.03}
236
236
  portfolio=dict(Market,**Stocks1,**Stocks2)
237
-
238
- ticker_name(portfolio)
239
237
 
240
- portfolio=dict(Market,**Stocks1)
238
+ #测试2
239
+ Market={'Market':('China','000300.SS','养猪1号组合')}
240
+ porkbig={'000876.SZ':0.20,#新希望
241
+ '300498.SZ':0.15,#温氏股份
242
+ }
243
+ porksmall={'002124.SZ':0.10,#天邦股份
244
+ '600975.SS':0.10,#新五丰
245
+ '603477.SS':0.10,#巨星股份
246
+ '000735.SZ':0.07,#罗牛山
247
+ }
248
+ portfolio=dict(Market,**porkbig,**porksmall)
249
+
241
250
  thedate='2024-5-30'
242
251
  pastyears=1
243
252
  printout=True
244
- graph=True
253
+ graph=False
245
254
 
246
- pf_info=portfolio_build(portfolio,'2024-5-30')
255
+ pf_info=portfolio_build(portfolio,thedate,pastyears,printout,graph)
247
256
 
248
257
  """
249
258
  def portfolio_cumret(portfolio,thedate,pastyears=1, \
@@ -262,7 +271,7 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
262
271
  if thedate=='default':
263
272
  thedate=str(stoday)
264
273
  else:
265
- if not check_date(adate):
274
+ if not check_date(thedate):
266
275
  print(" #Warning(portfolio_build): invalid date",thedate)
267
276
  return None
268
277
 
@@ -275,8 +284,8 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
275
284
  import numpy as np
276
285
  totalshares=np.sum(sharelist0)
277
286
  if abs(totalshares - 1) >= 0.00001:
278
- print("\n #Warning(portfolio_build): total weights is",totalshares,"\b, expecting 1.0 here")
279
- print(" Action: automatically converted into total weights 1.0")
287
+ print(" #Warning(portfolio_build): total weights is",totalshares,"\b, expecting 1.0 here")
288
+ print(" Action taken: automatically converted into total weights 1.0")
280
289
  sharelist=list(sharelist0/totalshares)
281
290
  else:
282
291
  sharelist=sharelist0
@@ -502,8 +511,8 @@ def portfolio_correlate(pf_info):
502
511
  pname=portfolio_name(portfolio)
503
512
 
504
513
  #取出观察期
505
- hstart0=stock_return.index[0]; hstart=str(hstart0)
506
- hend0=stock_return.index[-1]; hend=str(hend0)
514
+ hstart0=stock_return.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
515
+ hend0=stock_return.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
507
516
 
508
517
  sr=stock_return.copy()
509
518
  collist=list(sr)
@@ -550,8 +559,8 @@ def portfolio_covar(pf_info):
550
559
  pname=portfolio_name(portfolio)
551
560
 
552
561
  #取出观察期
553
- hstart0=stock_return.index[0]; hstart=str(hstart0)
554
- hend0=stock_return.index[-1]; hend=str(hend0)
562
+ hstart0=stock_return.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
563
+ hend0=stock_return.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
555
564
 
556
565
  # 计算协方差矩阵
557
566
  cov_mat = stock_return.cov()
@@ -613,10 +622,10 @@ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,membe
613
622
  #观察期
614
623
  hstart0=member_returns.index[0]
615
624
  #hstart=str(hstart0.date())
616
- hstart=str(hstart0)
625
+ hstart=str(hstart0.strftime("%Y-%m-%d"))
617
626
  hend0=member_returns.index[-1]
618
627
  #hend=str(hend0.date())
619
- hend=str(hend0)
628
+ hend=str(hend0.strftime("%Y-%m-%d"))
620
629
  tickerlist=list(member_returns)
621
630
 
622
631
  #合成投资组合的历史收益率,按行横向加权求和
@@ -652,7 +661,7 @@ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,membe
652
661
  print(" 年化收益率:",round(annual_return,4))
653
662
  print(" 年化标准差:",round(annual_std,4))
654
663
  print(" ***投资组合持仓策略***")
655
- print_tickerlist_sharelist(tickerlist,portfolio_weights,4)
664
+ print_tickerlist_sharelist(tickerlist,portfolio_weights,leading_blanks=4,ticker_type='bond')
656
665
 
657
666
  print(" *来源:Sina/EM/stooq,"+str(stoday)+"统计")
658
667
  else:
@@ -1013,18 +1022,21 @@ def portfolio_ranks_en(portfolio_returns,pname):
1013
1022
  if __name__=='__main__':
1014
1023
  simulation=1000
1015
1024
  simulation=50000
1025
+
1026
+ portfolio_eset(pf_info,simulation=50000)
1016
1027
 
1017
- def portfolio_eset(pf_info,simulation=50000):
1028
+ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
1018
1029
  """
1019
1030
  功能:基于随机数,生成大量可能的投资组合,计算各个投资组合的年均收益率和标准差,绘制投资组合的可行集
1031
+ 默认绘制散点图凸包:convex_hull=True
1020
1032
  """
1021
1033
  [[portfolio,thedate,stock_return,_,_],_]=pf_info
1022
1034
  pname=portfolio_name(portfolio)
1023
1035
  _,_,tickerlist,_=decompose_portfolio(portfolio)
1024
1036
 
1025
1037
  #取出观察期
1026
- hstart0=stock_return.index[0]; hstart=str(hstart0)
1027
- hend0=stock_return.index[-1]; hend=str(hend0)
1038
+ hstart0=stock_return.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
1039
+ hend0=stock_return.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
1028
1040
 
1029
1041
  #获得成份股个数
1030
1042
  numstocks=len(tickerlist)
@@ -1078,9 +1090,46 @@ def portfolio_eset(pf_info,simulation=50000):
1078
1090
 
1079
1091
  #plt.style.use('seaborn-dark') #不支持中文
1080
1092
  #plt.figure(figsize=(9, 5))
1081
- plt.scatter(pf_volatilities, pf_returns, c=pf_ratio,cmap='RdYlGn', edgecolors='black',marker='o')
1093
+ plt.scatter(pf_volatilities,pf_returns,c=pf_ratio,cmap='RdYlGn',edgecolors='black',marker='o')
1082
1094
  #plt.grid(True)
1083
1095
 
1096
+ #绘制散点图轮廓线凸包(convex hull)
1097
+ if convex_hull:
1098
+ from scipy.spatial import ConvexHull
1099
+
1100
+ #构造散点对的列表
1101
+ pf_volatilities_list=list(pf_volatilities)
1102
+ pf_returns_list=list(pf_returns)
1103
+ points=[]
1104
+ for x in pf_volatilities_list:
1105
+ pos=pf_volatilities_list.index(x)
1106
+ y=pf_returns_list[pos]
1107
+ points=points+[[x,y]]
1108
+
1109
+ # 计算散点集的外轮廓
1110
+ hull = ConvexHull(points)
1111
+ # 绘制外轮廓线
1112
+ for simplex in hull.simplices:
1113
+ plt.plot([points[simplex[0]][0], points[simplex[1]][0]],
1114
+ [points[simplex[0]][1], points[simplex[1]][1]], 'k-')
1115
+
1116
+ """
1117
+ #滚动法寻找上边沿
1118
+ points_sorted=points
1119
+ points_sorted.sort(key=lambda x: x[0])
1120
+ points_df=pd.DataFrame(points_sorted,columns=['x','y'])
1121
+
1122
+ window=100
1123
+ nwindow=int(len(points_df)/window)
1124
+ upper_points=[]
1125
+ for n in range(nwindow):
1126
+ tmp_df=points_df[n*window:n*window+window]
1127
+ max_y=max(tmp_df['y'])
1128
+ max_x=tmp_df[tmp_df['y']==max_y]['x'].values[0]
1129
+
1130
+ upper_points=upper_points+[[max_x,max_y]]
1131
+ """
1132
+
1084
1133
  import datetime as dt; stoday=dt.date.today()
1085
1134
  lang = check_language()
1086
1135
  if lang == 'Chinese':
@@ -1139,8 +1188,8 @@ def portfolio_es_sharpe(pf_info,simulation=1000,RF=0):
1139
1188
  scope,_,tickerlist,_=decompose_portfolio(portfolio)
1140
1189
 
1141
1190
  #取出观察期
1142
- hstart0=stock_return0.index[0]; hstart=str(hstart0)
1143
- hend0=stock_return0.index[-1]; hend=str(hend0)
1191
+ hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
1192
+ hend0=stock_return0.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
1144
1193
 
1145
1194
  import pandas as pd
1146
1195
  #处理无风险利率
@@ -1233,8 +1282,8 @@ def portfolio_es_sortino(pf_info,simulation=1000,RF=0):
1233
1282
  scope,_,tickerlist,_=decompose_portfolio(portfolio)
1234
1283
 
1235
1284
  #取出观察期
1236
- hstart0=stock_return0.index[0]; hstart=str(hstart0)
1237
- hend0=stock_return0.index[-1]; hend=str(hend0)
1285
+ hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
1286
+ hend0=stock_return0.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
1238
1287
 
1239
1288
  import pandas as pd
1240
1289
  #处理无风险利率
@@ -1333,8 +1382,8 @@ def portfolio_es_alpha(pf_info,simulation=1000,RF=0):
1333
1382
  scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
1334
1383
 
1335
1384
  #取出观察期
1336
- hstart0=stock_return0.index[0]; hstart=str(hstart0)
1337
- hend0=stock_return0.index[-1]; hend=str(hend0)
1385
+ hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
1386
+ hend0=stock_return0.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
1338
1387
 
1339
1388
  #计算市场指数的收益率
1340
1389
  import pandas as pd
@@ -1449,8 +1498,8 @@ def portfolio_es_treynor(pf_info,simulation=1000,RF=0):
1449
1498
  scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
1450
1499
 
1451
1500
  #取出观察期
1452
- hstart0=stock_return0.index[0]; hstart=str(hstart0)
1453
- hend0=stock_return0.index[-1]; hend=str(hend0)
1501
+ hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
1502
+ hend0=stock_return0.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
1454
1503
 
1455
1504
  #计算市场指数的收益率
1456
1505
  import pandas as pd
@@ -1549,7 +1598,7 @@ if __name__=='__main__':
1549
1598
  #==============================================================================
1550
1599
  def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1551
1600
  ylabeltxt,x_axis_name,pname,simulation,hstart,hend, \
1552
- hiret_point,lorisk_point):
1601
+ hiret_point,lorisk_point,convex_hull=True):
1553
1602
  """
1554
1603
  功能:将生成的马科维茨可行集RandomPortfolios绘制成彩色散点图
1555
1604
  """
@@ -1587,6 +1636,27 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1587
1636
  plt.scatter(pf_volatilities, pf_returns, c=pf_ratio,cmap='RdYlGn', edgecolors='black',marker='o')
1588
1637
  plt.colorbar(label=colorbartxt)
1589
1638
 
1639
+ #绘制散点图轮廓线凸包(convex hull)
1640
+ if convex_hull:
1641
+ from scipy.spatial import ConvexHull
1642
+
1643
+ #构造散点对的列表
1644
+ pf_volatilities_list=list(pf_volatilities)
1645
+ pf_returns_list=list(pf_returns)
1646
+ points=[]
1647
+ for x in pf_volatilities_list:
1648
+ pos=pf_volatilities_list.index(x)
1649
+ y=pf_returns_list[pos]
1650
+ points=points+[[x,y]]
1651
+
1652
+ # 计算散点集的外轮廓
1653
+ hull = ConvexHull(points)
1654
+ # 绘制外轮廓线
1655
+ for simplex in hull.simplices:
1656
+ plt.plot([points[simplex[0]][0], points[simplex[1]][0]],
1657
+ [points[simplex[0]][1], points[simplex[1]][1]], 'k-')
1658
+
1659
+
1590
1660
  lang = check_language()
1591
1661
  if lang == 'Chinese':
1592
1662
  if pname == '': pname='投资组合'
@@ -1695,7 +1765,7 @@ def cvt_portfolio_name(pname,portfolio_returns):
1695
1765
 
1696
1766
  #==============================================================================
1697
1767
 
1698
- def portfolio_optimize_sharpe(es_info,graph=True):
1768
+ def portfolio_optimize_sharpe(es_info,graph=True,convex_hull=False):
1699
1769
  """
1700
1770
  功能:计算投资组合的最高夏普比率组合,并绘图
1701
1771
  MSR: Maximium Sharpe Rate, 最高夏普指数方案
@@ -1748,7 +1818,8 @@ def portfolio_optimize_sharpe(es_info,graph=True):
1748
1818
  #计算指数,寻找最大指数点和风险最低点,并绘图标注两个点
1749
1819
  hiret_weights,lorisk_weights,portfolio_returns = \
1750
1820
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1751
- colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph)
1821
+ colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
1822
+ convex_hull=convex_hull)
1752
1823
 
1753
1824
  print("【注释】")
1754
1825
  print("★MSR : Maximized Sharpe Ratio,最大夏普比率点")
@@ -1771,7 +1842,7 @@ if __name__=='__main__':
1771
1842
 
1772
1843
  #==============================================================================
1773
1844
 
1774
- def portfolio_optimize_sortino(es_info,graph=True):
1845
+ def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False):
1775
1846
  """
1776
1847
  功能:计算投资组合的最高索替诺比率组合,并绘图
1777
1848
  MSO: Maximium Sortino ratio, 最高索替诺比率方案
@@ -1796,7 +1867,8 @@ def portfolio_optimize_sortino(es_info,graph=True):
1796
1867
  #计算指数,寻找最大指数点和风险最低点,并绘图标注两个点
1797
1868
  hiret_weights,lorisk_weights,portfolio_returns = \
1798
1869
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1799
- colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph)
1870
+ colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
1871
+ convex_hull=convex_hull)
1800
1872
 
1801
1873
  print("【注释】")
1802
1874
  print("★MSO : Maximum SOrtino ratio,最大索替诺比率点")
@@ -1819,7 +1891,7 @@ if __name__=='__main__':
1819
1891
 
1820
1892
  #==============================================================================
1821
1893
 
1822
- def portfolio_optimize_alpha(es_info,graph=True):
1894
+ def portfolio_optimize_alpha(es_info,graph=True,convex_hull=False):
1823
1895
  """
1824
1896
  功能:计算投资组合的最高詹森阿尔法组合,并绘图
1825
1897
  MAR: Maximium Alpha Ratio, 最高阿尔法指数方案
@@ -1843,7 +1915,8 @@ def portfolio_optimize_alpha(es_info,graph=True):
1843
1915
  #计算指数,寻找最大指数点和风险最低点,并绘图标注两个点
1844
1916
  hiret_weights,lorisk_weights,portfolio_returns = \
1845
1917
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1846
- colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph)
1918
+ colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
1919
+ convex_hull=convex_hull)
1847
1920
 
1848
1921
  print("【注释】")
1849
1922
  print("★MAR : Maximum Alpha Ratio,最大阿尔法点")
@@ -1865,7 +1938,7 @@ if __name__=='__main__':
1865
1938
 
1866
1939
  #==============================================================================
1867
1940
 
1868
- def portfolio_optimize_treynor(es_info,graph=True):
1941
+ def portfolio_optimize_treynor(es_info,graph=True,convex_hull=False):
1869
1942
  """
1870
1943
  功能:计算投资组合的最高特雷诺比率组合,并绘图
1871
1944
  MTR: Maximium Treynor Ratio, 最高特雷诺指数方案
@@ -1889,7 +1962,8 @@ def portfolio_optimize_treynor(es_info,graph=True):
1889
1962
  #计算指数,寻找最大指数点和风险最低点,并绘图标注两个点
1890
1963
  hiret_weights,lorisk_weights,portfolio_returns = \
1891
1964
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1892
- colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph)
1965
+ colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
1966
+ convex_hull=convex_hull)
1893
1967
 
1894
1968
  print("【注释】")
1895
1969
  print("★MTR : Maximum Treynor Ratio,最大特雷诺比率点")
@@ -1901,7 +1975,8 @@ def portfolio_optimize_treynor(es_info,graph=True):
1901
1975
 
1902
1976
 
1903
1977
  def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1904
- colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=True):
1978
+ colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=True, \
1979
+ convex_hull=False):
1905
1980
  """
1906
1981
  功能:提供rar比率优化的共同处理部分
1907
1982
  基于RandomPortfolios中的随机投资组合,计算相应的指数,寻找最大指数点和风险最小点,并绘图标注两个点
@@ -1925,8 +2000,8 @@ def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk,
1925
2000
  pname=portfolio_name(portfolio)
1926
2001
 
1927
2002
  #取出观察期
1928
- hstart0=StockReturns.index[0]; hstart=str(hstart0)
1929
- hend0=StockReturns.index[-1]; hend=str(hend0)
2003
+ hstart0=StockReturns.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
2004
+ hend0=StockReturns.index[-1]; hend=str(hend0.strftime("%Y-%m-%d"))
1930
2005
 
1931
2006
  #识别并计算指数..........................................................
1932
2007
  if col_ratio in ['Alpha']:
@@ -1975,8 +2050,8 @@ def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk,
1975
2050
  lorisk_point=[lorisk_x,lorisk_y,name_lorisk+point_txt]
1976
2051
  if graph:
1977
2052
  RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1978
- ylabeltxt,x_axis_name,pname,simulation,hstart,hend, \
1979
- hiret_point,lorisk_point)
2053
+ ylabeltxt,x_axis_name,pname,simulation,hstart,hend, \
2054
+ hiret_point,lorisk_point,convex_hull=convex_hull)
1980
2055
 
1981
2056
  #返回数据,供进一步分析
1982
2057
  portfolio_returns=StockReturns.copy()
@@ -2011,7 +2086,7 @@ if __name__=='__main__':
2011
2086
  graph=True;hirar_return=False;lorisk=True
2012
2087
 
2013
2088
  def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2014
- graph=True,hirar_return=False,lorisk=True):
2089
+ graph=True,hirar_return=False,lorisk=True,convex_hull=False):
2015
2090
  """
2016
2091
  功能:集成式投资组合优化策略
2017
2092
  注意:实验发现RF较小时对于结果的影响极其微小难以观察,默认设为不使用无风险利率调整收益
@@ -2041,7 +2116,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2041
2116
  eval(func_optimize)(es_info=es_info,RF=RF,graph=graph)
2042
2117
  """
2043
2118
  name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns= \
2044
- eval(func_optimize)(es_info=es_info,graph=graph)
2119
+ eval(func_optimize)(es_info=es_info,graph=graph,convex_hull=convex_hull)
2045
2120
 
2046
2121
 
2047
2122
  lang = check_language()
siat/sector_china.py CHANGED
@@ -3057,9 +3057,12 @@ if __name__=='__main__':
3057
3057
 
3058
3058
  find_industry_sw(ticker)
3059
3059
 
3060
- def find_industry_sw(ticker,level='1',ticker_order=True):
3060
+ def find_industry_sw(ticker,level='1',ticker_order=True,max_sleep=8):
3061
3061
  """
3062
- 功能:寻找一只股票所属的申万行业
3062
+ 功能:寻找一只或一组股票所属的申万行业,支持股票代码和股票名称。
3063
+ level='1':默认只查找申万1级行业,以便节省时间
3064
+ ticker_order=True:默认输出结果按照ticker中的顺序,而非按照所属行业排序
3065
+ max_sleep=8:为防止反爬虫,默认每次爬虫后睡眠最多几秒钟
3063
3066
  """
3064
3067
  print(" Searching shenwan industries for securities ... ...")
3065
3068
 
@@ -3140,7 +3143,7 @@ def find_industry_sw(ticker,level='1',ticker_order=True):
3140
3143
  if len(result) == len(tickerlist): break
3141
3144
 
3142
3145
  #生成随机数睡眠,试图防止被反爬虫,不知是否管用!
3143
- random_int=random.randint(1,5)
3146
+ random_int=random.randint(1,max_sleep)
3144
3147
  time.sleep(random_int)
3145
3148
 
3146
3149
  #排序
siat/security_price2.py CHANGED
@@ -43,6 +43,10 @@ if __name__=='__main__':
43
43
  ticker_type='auto'
44
44
  ticker_type='bond'
45
45
 
46
+ ticker='000418'
47
+ ticker='180202.SZ'
48
+ ticker_type='fund'
49
+
46
50
  source='auto'
47
51
  source='yahoo'
48
52
 
@@ -50,15 +54,15 @@ if __name__=='__main__':
50
54
  fill=True
51
55
 
52
56
  price,found=get_price_1ticker(ticker=ticker,fromdate=fromdate,todate=todate, \
53
- ticker_type=ticker_type,source=source, \
54
- adjust=adjust,fill=fill)
57
+ ticker_type=ticker_type)
55
58
 
56
59
  def get_price_1ticker(ticker,fromdate,todate, \
57
60
  ticker_type='auto',source='auto', \
58
61
  adjust='',fill=False):
59
62
  """
60
63
  功能:抓取一只证券的价格序列,不处理列表,不处理投资组合
61
- 数据源优先度:1-source2-ticker属地,3-ticker_type
64
+ 类型优先顺序:ticker_typeauto-自动,stock-指定股票,fund-指定基金,bond-指定债券
65
+ 数据源优先顺序:1-source,2-ticker属地,3-ticker_type
62
66
  adjust:""-未复权,qfq-前复权,hfq-后复权,qfq-factor:前复权因子和调整,hfq-factor: 后复权因子和调整
63
67
  返回值:
64
68
  df: None-未找到ticker,空df-找到ticker但规定时间段内无数据
@@ -112,7 +116,30 @@ def get_price_1ticker(ticker,fromdate,todate, \
112
116
  adjust='qfq' if adjust != '' else ''
113
117
  dft=get_price_ak_us(ticker1,fromdate,todate,adjust=adjust)
114
118
  found=df_have_data(dft)
115
-
119
+ """
120
+ if ticker_type in ['fund']:
121
+ #变换代码格式
122
+ ticker2=tickers_cvt2ak(ticker1)
123
+ try:
124
+ #优先抓取开放式基金单位净值
125
+ dft =get_price_oef_china(ticker2,fromdate,todate)
126
+ dft['Date']=dft.index
127
+ except:
128
+ dft=None
129
+ found=df_have_data(dft)
130
+
131
+ if ticker_type in ['bond']:
132
+ #变换代码格式
133
+ ticker2=tickers_cvt2ak(ticker1)
134
+ try:
135
+ #最后抓取交易所债券行情
136
+ dft = exchange_bond_price(ticker2,fromdate,todate,graph=False,data_crop=False)
137
+ dft['Date']=dft.index
138
+ except:
139
+ #print(" #Error(get_price_ak_cn): failed to find prices for",ticker)
140
+ return None
141
+ found=df_have_data(dft)
142
+ """
116
143
  #数据源情形2:stooq
117
144
  if source in ['auto','stooq'] and found not in ['Found','Empty']:
118
145
  dft=get_price_stooq(ticker1,fromdate,todate)
@@ -193,8 +220,10 @@ if __name__=='__main__':
193
220
  ticker=['801002.SW',"600519.SS","sh510050","sh010504"] #申万指数,股票,ETF基金,国债
194
221
  ticker_type='bond'
195
222
 
223
+ ticker=["180801.SZ","180101.SZ"]
196
224
  fromdate="2024-3-1"
197
225
  todate="2024-4-1"
226
+ ticker_type='fund'
198
227
 
199
228
  adjust=''
200
229
  adjust=['','qfq']
@@ -460,14 +489,16 @@ if __name__=='__main__':
460
489
  ticker=[pf,'000002.SZ','002594.SZ','sh018003','sh010504']
461
490
  ticker_type=[['auto','stock'],'auto','auto','bond'] #不足部分自动延续最后一个类型
462
491
 
492
+ ticker=["180801.SZ","180101.SZ"]
493
+ ticker_type='fund'
494
+
463
495
  fromdate='2024-1-1'
464
496
  todate='2024-4-1'
465
497
  adjust=''
466
498
  source='auto'
467
499
  fill=True
468
500
 
469
- mix,found=get_price_mticker_mixed(ticker=ticker,fromdate=fromdate,todate=todate, \
470
- adjust=adjust,source=source,ticker_type=ticker_type,fill=fill)
501
+ mix,found=get_price_mticker_mixed(ticker=ticker,fromdate=fromdate,todate=todate,ticker_type=ticker_type)
471
502
 
472
503
  def get_price_mticker_mixed(ticker,fromdate,todate, \
473
504
  adjust='',source='auto',ticker_type='auto',fill=False):
@@ -565,14 +596,17 @@ if __name__=='__main__':
565
596
  ticker='sh018003'
566
597
  ticker_type='bond'
567
598
 
568
- fromdate='2024-1-1'
569
- todate='2024-4-1'
599
+ ticker='180202.SZ'
600
+ ticker_type='fund'
601
+
602
+ fromdate='2021-1-1'
603
+ todate='2024-5-30'
570
604
  adjust=''
571
605
  source='auto'
572
606
  fill=True
573
607
 
574
608
  mixed,found=get_price_1ticker_mixed(ticker=ticker,fromdate=fromdate,todate=todate, \
575
- adjust=adjust,source=source,ticker_type=ticker_type,fill=fill)
609
+ ticker_type=ticker_type)
576
610
 
577
611
  def get_price_1ticker_mixed(ticker,fromdate,todate, \
578
612
  adjust='',source='auto',ticker_type='auto',fill=False):
siat/security_prices.py CHANGED
@@ -716,6 +716,10 @@ if __name__=='__main__':
716
716
  ticker='100303.SZ'
717
717
  ticker_type='auto'
718
718
 
719
+ ticker='000418'
720
+ ticker='180202.SZ'
721
+ ticker_type='fund'
722
+
719
723
  fromdate='2024-1-1'; todate='2024-3-31'
720
724
  adjust=''
721
725
 
@@ -768,14 +772,15 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
768
772
  df=None
769
773
  found=df_have_data(df)
770
774
 
771
- #不是股票:指数/基金/债券
775
+ #股票(无复权)指数/基金/债券
772
776
  if found != 'Found':
773
777
  if ticker_type in ['auto','stock'] and suffix not in ['SW']:
774
778
  try:
775
779
  #指数/股票/基金
776
780
  df = ak.stock_zh_index_daily(symbol=ticker2)
777
781
  df['Date']=df['date'].apply(lambda x: pd.to_datetime(x))
778
- except: pass
782
+ except:
783
+ df=None
779
784
  found=df_have_data(df)
780
785
 
781
786
  if found != 'Found':
@@ -783,7 +788,8 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
783
788
  #特殊函数(不考虑复权)
784
789
  df=ak.stock_zh_a_cdr_daily(ticker2,start1,end1)
785
790
  df['Date']=pd.to_datetime(df['date'])
786
- except: pass
791
+ except:
792
+ df=None
787
793
  found=df_have_data(df)
788
794
 
789
795
  if found != 'Found':
@@ -806,7 +812,8 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
806
812
  #优先抓取交易所债券行情
807
813
  df = exchange_bond_price(ticker2,fromdate,todate,graph=False,data_crop=False)
808
814
  df['Date']=df.index
809
- except: pass
815
+ except:
816
+ df=None
810
817
  found=df_have_data(df)
811
818
 
812
819
  #已找到证券信息,但在规定时段无数据
@@ -818,7 +825,8 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
818
825
  df=ak.stock_zh_a_daily(ticker2,start1,end1,adjust=adjust)
819
826
  df['Date']=df['date']
820
827
  df['Date']=df['Date'].dt.tz_localize(None)
821
- except: pass
828
+ except:
829
+ df=None
822
830
  found=df_have_data(df)
823
831
 
824
832
  if found != 'Found':
@@ -826,7 +834,8 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
826
834
  #接着查找指数
827
835
  df = ak.stock_zh_index_daily(symbol=ticker2)
828
836
  df['Date']=df['date'].apply(lambda x: pd.to_datetime(x))
829
- except: pass
837
+ except:
838
+ df=None
830
839
  found=df_have_data(df)
831
840
 
832
841
  if found != 'Found':
@@ -834,7 +843,8 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
834
843
  #最后查找开放式基金
835
844
  df =get_price_oef_china(ticker2,fromdate,todate)
836
845
  df['Date']=df.index
837
- except: pass
846
+ except:
847
+ df=None
838
848
  found=df_have_data(df)
839
849
 
840
850
  #基金。因部分债券代码(特别是国债)与基金代码重合,需要甄别!
@@ -843,18 +853,20 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
843
853
  #优先抓取开放式基金单位净值
844
854
  df =get_price_oef_china(ticker2,fromdate,todate)
845
855
  df['Date']=df.index
846
- except: pass
856
+ except:
857
+ df=None
847
858
  found=df_have_data(df)
848
859
 
849
860
  #已找到证券信息,但在规定时段无数据
850
- if found=='Empty': return df
861
+ #if found=='Empty': return df
851
862
 
852
- if found != 'Found': #未找到,其次抓取股票行情
863
+ if found != 'Found': #未找到,其次从股票爬虫抓取基金行情
853
864
  try:
854
865
  df=ak.stock_zh_a_daily(ticker2,start1,end1,adjust=adjust)
855
866
  df['Date']=df['date']
856
867
  df['Date']=df['Date'].dt.tz_localize(None)
857
- except: pass
868
+ except:
869
+ df=None
858
870
  found=df_have_data(df)
859
871
 
860
872
  if found != 'Found':
@@ -862,23 +874,26 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
862
874
  #再次查找股票指数
863
875
  df = ak.stock_zh_index_daily(symbol=ticker2)
864
876
  df['Date']=df['date'].apply(lambda x: pd.to_datetime(x))
865
- except: pass
877
+ except:
878
+ df=None
866
879
  found=df_have_data(df)
867
880
 
868
881
  if found != 'Found':
869
882
  try:
870
- #最后查找债券
883
+ #最后从债券爬虫查找基金信息
871
884
  df = exchange_bond_price(ticker2,fromdate,todate,graph=False,data_crop=False)
872
885
  df['Date']=df.index
873
- except: pass
886
+ except:
887
+ df=None
874
888
  found=df_have_data(df)
875
889
 
876
-
890
+ #申万指数
877
891
  if suffix in ['SW']:
878
892
  try:
879
893
  df = fetch_price_swindex(prefix,fromdate,todate)
880
894
  df['Date']=df.index
881
- except: pass
895
+ except:
896
+ df=None
882
897
  #print(" #Error(get_price_ak_cn): failed to retrieve prices for",ticker)
883
898
  found=df_have_data(df)
884
899