siat 3.2.5__py3-none-any.whl → 3.2.15__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
@@ -247,24 +247,35 @@ if __name__=='__main__':
247
247
  }
248
248
  portfolio=dict(Market,**porkbig,**porksmall)
249
249
 
250
- thedate='2024-5-30'
251
- pastyears=1
252
- printout=True
253
- graph=False
254
-
255
250
  #测试3
256
- Market={'Market':('China','000300.SS','锂电池1号')}
257
- Stocks={'300750.SZ':0.4,#宁德时代
258
- '002594.SZ':0.3,#比亚迪
259
- '300014.SZ':0.2,#亿纬锂能
260
- '300207.SZ':0.1,#欣旺达
251
+ Market={'Market':('China','000300.SS','股债基组合')}
252
+ Stocks={'600519.SS':0.3,#股票:贵州茅台
253
+ 'sh010504':[0.5,'bond'],#05国债⑷
254
+ '010504.SS':('fund',0.2),#招商稳兴混合C基金
261
255
  }
262
256
  portfolio=dict(Market,**Stocks)
263
257
 
258
+ printout=True
259
+ graph=False
260
+
264
261
  indicator='Adj Close'
265
262
  adjust='qfq'; source='auto'; ticker_type='bond'
266
263
  thedate='2024-6-19'
267
264
  pastyears=2
265
+
266
+
267
+ #测试3
268
+ Market={'Market':('China','000300.SS','股债基组合')}
269
+ Stocks={'600519.SS':0.3,#股票:贵州茅台
270
+ 'sh010504':[0.5,'bond'],#05国债⑷
271
+ '010504.SS':('fund',0.2),#招商稳兴混合C基金
272
+ }
273
+ portfolio=dict(Market,**Stocks)
274
+
275
+ indicator='Close'
276
+ adjust=''; source='auto'; ticker_type='auto'
277
+ thedate='2024-6-19'
278
+ pastyears=1
268
279
  printout=True
269
280
  graph=False
270
281
 
@@ -312,7 +323,7 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
312
323
 
313
324
  print("\n Searching for portfolio info, which may take time ...")
314
325
  # 解构投资组合
315
- scope,_,tickerlist,sharelist0=decompose_portfolio(portfolio)
326
+ scope,_,tickerlist,sharelist0,ticker_type=decompose_portfolio(portfolio)
316
327
  pname=portfolio_name(portfolio)
317
328
 
318
329
  #如果持仓份额总数不为1,则将其转换为总份额为1
@@ -440,7 +451,7 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
440
451
 
441
452
  title_txt=text_lang("投资组合: 日收益率的变化趋势","Investment Portfolio: Daily Return")
442
453
  ylabel_txt=text_lang("日收益率","Daily Return")
443
- source_txt=text_lang("来源: 综合Sina/EM/stooq, ","Source: sina/eastmoney/stooq, ")
454
+ source_txt=text_lang("来源: 综合新浪/东方财富/stooq/雅虎等, ","Source: sina/eastmoney/stooq, ")
444
455
 
445
456
  plt.title(title_txt)
446
457
  plt.ylabel(ylabel_txt)
@@ -460,7 +471,7 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
460
471
 
461
472
  titletxt=text_lang("投资组合: 持有收益率的变化趋势","Investment Portfolio: Holding Return")
462
473
  ylabeltxt=text_lang("持有收益率","Holding Return")
463
- xlabeltxt1=text_lang("来源: 综合Sina/EM/stooq, ","Source: sina/eastmoney/stooq, ")
474
+ xlabeltxt1=text_lang("来源: 综合新浪/东方财富/stooq/雅虎等, ","Source: sina/eastmoney/stooq, ")
464
475
  xlabeltxt=xlabeltxt1+str(stoday)
465
476
 
466
477
  #绘制持有收益率曲线
@@ -476,22 +487,29 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
476
487
  StockReturns['Portfolio_EW']=stock_return.mul(portfolio_weights_ew,axis=1).sum(axis=1)
477
488
  #..........................................................................
478
489
 
479
- # 创建交易额加权组合:按照成交金额计算期间内交易额均值
480
- tamount=prices['Close']*prices['Volume']
481
- tamountlist=tamount.mean(axis=0) #求列的均值
482
- tamountlist_array = np.array(tamountlist)
483
- # 计算成交金额权重
484
- portfolio_weights_lw = tamountlist_array / np.sum(tamountlist_array)
485
- # 计算成交金额加权的组合收益
486
- StockReturns['Portfolio_LW'] = stock_return.mul(portfolio_weights_lw, axis=1).sum(axis=1)
490
+ # 创建交易额加权组合:按照成交金额计算期间内交易额均值。债券和基金信息中无交易量!
491
+ if ('bond' not in ticker_type) and ('fund' not in ticker_type):
492
+ tamount=prices['Close']*prices['Volume']
493
+ tamountlist=tamount.mean(axis=0) #求列的均值
494
+ tamountlist_array = np.array(tamountlist)
495
+ # 计算成交金额权重
496
+ portfolio_weights_lw = tamountlist_array / np.sum(tamountlist_array)
497
+ # 计算成交金额加权的组合收益
498
+ StockReturns['Portfolio_LW'] = stock_return.mul(portfolio_weights_lw, axis=1).sum(axis=1)
487
499
 
488
500
  #绘制累计收益率对比曲线
489
501
  title_txt=text_lang("投资组合策略:业绩对比","Portfolio Strategies: Performance Comparison")
490
502
  Portfolio_EW_txt=text_lang("等权重策略","Equal-weight")
491
- Portfolio_LW_txt=text_lang("交易额加权策略","Amount-weight")
503
+ if ('bond' not in ticker_type) and ('fund' not in ticker_type):
504
+ Portfolio_LW_txt=text_lang("交易额加权策略","Amount-weight")
492
505
 
493
- name_list=['Portfolio', 'Portfolio_EW', 'Portfolio_LW']
494
- label_list=[pname, Portfolio_EW_txt, Portfolio_LW_txt]
506
+ name_list=['Portfolio', 'Portfolio_EW', 'Portfolio_LW']
507
+ label_list=[pname, Portfolio_EW_txt, Portfolio_LW_txt]
508
+ else:
509
+ name_list=['Portfolio', 'Portfolio_EW']
510
+ label_list=[pname, Portfolio_EW_txt]
511
+
512
+
495
513
  titletxt=title_txt
496
514
 
497
515
  #绘制各个投资组合的持有收益率曲线
@@ -501,9 +519,11 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
501
519
  #打印各个投资组合的持股比例
502
520
  member_returns=stock_return
503
521
  if printout:
504
- portfolio_expectation_universal(pname,member_returns,portfolio_weights,member_prices)
505
- portfolio_expectation_universal(Portfolio_EW_txt,member_returns,portfolio_weights_ew,member_prices)
506
- portfolio_expectation_universal(Portfolio_LW_txt,member_returns,portfolio_weights_lw,member_prices)
522
+ portfolio_expectation_universal(pname,member_returns,portfolio_weights,member_prices,ticker_type)
523
+ portfolio_expectation_universal(Portfolio_EW_txt,member_returns,portfolio_weights_ew,member_prices,ticker_type)
524
+
525
+ if ('bond' not in ticker_type) and ('fund' not in ticker_type):
526
+ portfolio_expectation_universal(Portfolio_LW_txt,member_returns,portfolio_weights_lw,member_prices,ticker_type)
507
527
 
508
528
  #返回投资组合的综合信息
509
529
  member_returns=stock_return
@@ -516,8 +536,14 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
516
536
  if printout:
517
537
  portfolio_ranks(portfolio_returns,pname)
518
538
 
519
- return [[portfolio,thedate,member_returns,rf_df,member_prices], \
520
- [portfolio_returns,portfolio_weights,portfolio_weights_ew,portfolio_weights_lw]]
539
+ #
540
+ if ('bond' not in ticker_type) and ('fund' not in ticker_type):
541
+ return [[portfolio,thedate,member_returns,rf_df,member_prices], \
542
+ [portfolio_returns,portfolio_weights,portfolio_weights_ew,portfolio_weights_lw]]
543
+ else:
544
+ return [[portfolio,thedate,member_returns,rf_df,member_prices], \
545
+ [portfolio_returns,portfolio_weights,portfolio_weights_ew,None]]
546
+
521
547
 
522
548
  if __name__=='__main__':
523
549
  X=portfolio_build(portfolio,'2021-9-30')
@@ -656,10 +682,10 @@ if __name__=='__main__':
656
682
  portfolio=dict(Market,**Stocks1,**Stocks2)
657
683
  pf_info=portfolio_expret(portfolio,'2019-12-31')
658
684
 
659
- portfolio_expectation(pf_info)
685
+ portfolio_expectation_original(pf_info)
660
686
 
661
687
  #==============================================================================
662
- def portfolio_expectation_universal(pname,member_returns,portfolio_weights,member_prices):
688
+ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,member_prices,ticker_type):
663
689
  """
664
690
  功能:计算给定成份股收益率和持股权重的投资组合年均收益率和标准差
665
691
  输入:投资组合名称,成份股历史收益率数据表,投资组合权重series
@@ -704,12 +730,12 @@ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,membe
704
730
  print(" 投资组合:",pname)
705
731
  print(" 分析日期:",str(hend))
706
732
  # 投资组合中即使持股比例最低的股票每次交易最少也需要1手(100股)
707
- print(" 期末1手组合单位价值:","约"+str(round(portfolio_value_thedate/10000*100,2))+"万")
733
+ print(" 1手组合单位价值:","约"+str(round(portfolio_value_thedate/10000*100,2))+"万")
708
734
  print(" 观察期间:",hstart+'至'+hend)
709
735
  print(" 年化收益率:",round(annual_return,4))
710
736
  print(" 年化标准差:",round(annual_std,4))
711
737
  print(" ***投资组合持仓策略***")
712
- print_tickerlist_sharelist(tickerlist,portfolio_weights,leading_blanks=4,ticker_type='bond')
738
+ print_tickerlist_sharelist(tickerlist,portfolio_weights,leading_blanks=4,ticker_type=ticker_type)
713
739
 
714
740
  print(" *来源:Sina/EM/stooq,"+str(stoday)+"统计")
715
741
  else:
@@ -740,7 +766,7 @@ if __name__=='__main__':
740
766
  portfolio_expectation2(pname,member_returns, portfolio_weights)
741
767
 
742
768
  #==============================================================================
743
- def portfolio_expectation(pname,pf_info,portfolio_weights):
769
+ def portfolio_expectation(pname,pf_info,portfolio_weights,ticker_type):
744
770
  """
745
771
  功能:计算给定pf_info和持仓权重的投资组合年均收益率和标准差
746
772
  输入:投资组合名称,pf_info,投资组合权重series
@@ -749,7 +775,7 @@ def portfolio_expectation(pname,pf_info,portfolio_weights):
749
775
  """
750
776
  [[_,_,member_returns,_,member_prices],_]=pf_info
751
777
 
752
- portfolio_expectation_universal(pname,member_returns,portfolio_weights,member_prices)
778
+ portfolio_expectation_universal(pname,member_returns,portfolio_weights,member_prices,ticker_type)
753
779
 
754
780
  return
755
781
 
@@ -1080,7 +1106,7 @@ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
1080
1106
  """
1081
1107
  [[portfolio,thedate,stock_return,_,_],_]=pf_info
1082
1108
  pname=portfolio_name(portfolio)
1083
- _,_,tickerlist,_=decompose_portfolio(portfolio)
1109
+ _,_,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
1084
1110
 
1085
1111
  #取出观察期
1086
1112
  hstart0=stock_return.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
@@ -1233,7 +1259,7 @@ def portfolio_es_sharpe(pf_info,simulation=1000,RF=0):
1233
1259
 
1234
1260
  [[portfolio,thedate,stock_return0,rf_df,_],_]=pf_info
1235
1261
  pname=portfolio_name(portfolio)
1236
- scope,_,tickerlist,_=decompose_portfolio(portfolio)
1262
+ scope,_,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
1237
1263
 
1238
1264
  #取出观察期
1239
1265
  hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
@@ -1327,7 +1353,7 @@ def portfolio_es_sortino(pf_info,simulation=1000,RF=0):
1327
1353
 
1328
1354
  [[portfolio,thedate,stock_return0,rf_df,_],_]=pf_info
1329
1355
  pname=portfolio_name(portfolio)
1330
- scope,_,tickerlist,_=decompose_portfolio(portfolio)
1356
+ scope,_,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
1331
1357
 
1332
1358
  #取出观察期
1333
1359
  hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
@@ -1427,7 +1453,7 @@ def portfolio_es_alpha(pf_info,simulation=1000,RF=0):
1427
1453
 
1428
1454
  [[portfolio,thedate,stock_return0,rf_df,_],_]=pf_info
1429
1455
  pname=portfolio_name(portfolio)
1430
- scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
1456
+ scope,mktidx,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
1431
1457
 
1432
1458
  #取出观察期
1433
1459
  hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
@@ -1545,7 +1571,7 @@ def portfolio_es_treynor(pf_info,simulation=1000,RF=0):
1545
1571
 
1546
1572
  [[portfolio,_,stock_return0,rf_df,_],_]=pf_info
1547
1573
  pname=portfolio_name(portfolio)
1548
- scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
1574
+ scope,mktidx,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
1549
1575
 
1550
1576
  #取出观察期
1551
1577
  hstart0=stock_return0.index[0]; hstart=str(hstart0.strftime("%Y-%m-%d"))
@@ -2049,7 +2075,7 @@ def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk,
2049
2075
  """
2050
2076
  #解析传入的数据
2051
2077
  [[[portfolio,thedate,stock_return,_,_],[StockReturns,_,_,_]],RandomPortfolios]=es_info
2052
- _,_,tickerlist,_=decompose_portfolio(portfolio)
2078
+ _,_,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
2053
2079
  numstocks=len(tickerlist)
2054
2080
  pname=portfolio_name(portfolio)
2055
2081
 
@@ -2158,6 +2184,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2158
2184
 
2159
2185
  [[portfolio,_,_,_,_],_]=pf_info
2160
2186
  pname=portfolio_name(portfolio)
2187
+ _,_,_,_,ticker_type=decompose_portfolio(portfolio)
2161
2188
 
2162
2189
  #观察马科维茨可行集:风险溢价-标准差,用于夏普比率优化
2163
2190
  func_es="portfolio_es_"+ratio
@@ -2189,10 +2216,10 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2189
2216
  #打印投资组合构造和业绩表现
2190
2217
  hi_name=modify_portfolio_name(name_hiret+zhuhe_txt)
2191
2218
  lo_name=modify_portfolio_name(name_lorisk+zhuhe_txt)
2192
- portfolio_expectation(hi_name,pf_info,hiret_weights)
2219
+ portfolio_expectation(hi_name,pf_info,hiret_weights,ticker_type)
2193
2220
 
2194
2221
  if hirar_return:
2195
- scope,mktidx,tickerlist,_=decompose_portfolio(portfolio)
2222
+ scope,mktidx,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
2196
2223
  hwdf=pd.DataFrame(hiret_weights)
2197
2224
  hwdft=hwdf.T
2198
2225
  hwdft.columns=tickerlist
@@ -2207,7 +2234,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2207
2234
  portfolio_new=dict(Market,**stocks_new)
2208
2235
 
2209
2236
  if lorisk:
2210
- portfolio_expectation(lo_name,pf_info,lorisk_weights)
2237
+ portfolio_expectation(lo_name,pf_info,lorisk_weights,ticker_type)
2211
2238
 
2212
2239
  #现有投资组合的排名
2213
2240
  ranks=portfolio_ranks(portfolio_returns,pname)
@@ -2594,7 +2621,7 @@ def describe_portfolio(portfolio):
2594
2621
  输出:市场,市场指数,股票代码列表和份额列表
2595
2622
  """
2596
2623
 
2597
- scope,mktidx,tickerlist,sharelist=decompose_portfolio(portfolio)
2624
+ scope,mktidx,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
2598
2625
  pname=portfolio_name(portfolio)
2599
2626
 
2600
2627
  print("*** 投资组合信息:",pname)
@@ -2626,7 +2653,7 @@ def portfolio_drop(portfolio,last=0,droplist=[],new_name=''):
2626
2653
  """
2627
2654
  功能:删除最后几个成分股
2628
2655
  """
2629
- scope,mktidx,tickerlist,sharelist=decompose_portfolio(portfolio)
2656
+ scope,mktidx,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
2630
2657
  pname=portfolio_name(portfolio)
2631
2658
 
2632
2659
  if not (last ==0):
@@ -143,7 +143,7 @@ def print_rar_ratio(regdf,portfolio,ret_mean,ratio_name,ratio):
143
143
  """
144
144
 
145
145
  #从字典中提取信息
146
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
146
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
147
147
  stocklist1,_=cvt_yftickerlist(stocklist)
148
148
 
149
149
  date_start=str(regdf.index[0].year)+'-'+str(regdf.index[0].month)+ \
@@ -199,7 +199,7 @@ def treynor_ratio_portfolio(portfolio,start,end,RF=True,printout=True):
199
199
  return None,None
200
200
 
201
201
  #从字典中提取信息
202
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
202
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
203
203
 
204
204
  #第2步:计算投资组合的日收益率序列
205
205
  #抓取日投资组合价格
@@ -280,7 +280,7 @@ def rar_ratio_portfolio(portfolio,start,end,ratio_name='treynor',RF=True,printou
280
280
  return None,None
281
281
 
282
282
  #从字典中提取信息
283
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
283
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
284
284
 
285
285
  #第2步:计算投资组合的日收益率序列
286
286
  #抓取日投资组合价格
@@ -373,7 +373,7 @@ def rar_ratio_rolling(portfolio,start,end,ratio_name='treynor',RF=True, \
373
373
  startdate1=date_adjust(startdate, adjust=-startdate_delta)
374
374
 
375
375
  #从字典中提取信息
376
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
376
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
377
377
 
378
378
  #第2步:计算投资组合的日收益率序列
379
379
  #抓取日投资组合价格
@@ -465,7 +465,7 @@ def draw_rar_ratio(rars,portfolio,ratio_name):
465
465
  输入:滚动数据df,投资组合,指数名称
466
466
  """
467
467
 
468
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
468
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
469
469
  stocklist1,_=cvt_yftickerlist(stocklist)
470
470
 
471
471
  """
@@ -545,7 +545,7 @@ def sharpe_ratio_portfolio(portfolio,start,end,RF=True,printout=True):
545
545
  return None,None
546
546
 
547
547
  #从字典中提取信息
548
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
548
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
549
549
 
550
550
  #检查份额配比是否合理
551
551
  """
@@ -597,7 +597,7 @@ def sharpe_ratio_portfolio(portfolio,start,end,RF=True,printout=True):
597
597
  '-'+str(reg.index[-1].day)
598
598
  print("\n===== 风险调整收益率 =====")
599
599
 
600
- _,_,tickerlist,sharelist=decompose_portfolio(portfolio)
600
+ _,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
601
601
  if len(tickerlist)==1:
602
602
  product=str(ticker_name(tickerlist,'bond'))
603
603
  else:
@@ -640,7 +640,7 @@ def sortino_ratio_portfolio(portfolio,start,end,RF=True,printout=True):
640
640
  return None,None
641
641
 
642
642
  #从字典中提取信息
643
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
643
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
644
644
 
645
645
  #检查份额配比是否合理
646
646
  """
@@ -693,7 +693,7 @@ def sortino_ratio_portfolio(portfolio,start,end,RF=True,printout=True):
693
693
  '-'+str(reg.index[-1].day)
694
694
  print("\n===== 风险调整收益率 =====")
695
695
 
696
- _,_,tickerlist,sharelist=decompose_portfolio(portfolio)
696
+ _,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
697
697
  if len(tickerlist)==1:
698
698
  product=str(ticker_name(tickerlist,'bond'))
699
699
  else:
@@ -738,7 +738,7 @@ def jensen_alpha_portfolio(portfolio,start,end,RF=True,printout=True):
738
738
  return None,None
739
739
 
740
740
  #从字典中提取信息
741
- scope,mktidx,stocklist,portionlist=decompose_portfolio(portfolio)
741
+ scope,mktidx,stocklist,portionlist,ticker_type=decompose_portfolio(portfolio)
742
742
  #检查份额配比是否合理
743
743
  """
744
744
  if round(sum(portionlist),1) != 1.0:
@@ -798,7 +798,7 @@ def jensen_alpha_portfolio(portfolio,start,end,RF=True,printout=True):
798
798
  '-'+str(reg.index[-1].day)
799
799
  print("\n===== 风险调整收益率 =====")
800
800
 
801
- _,_,tickerlist,sharelist=decompose_portfolio(portfolio)
801
+ _,_,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
802
802
  if len(tickerlist)==1:
803
803
  product=str(ticker_name(tickerlist,'bond'))
804
804
  else:
@@ -1120,14 +1120,14 @@ def compare_rar_portfolio(portfolio1,portfolio2,start,end,ratio_name='sharpe', \
1120
1120
  ylabeltxt=label1
1121
1121
  titletxt="证券风险调整收益的滚动趋势对比"
1122
1122
 
1123
- _,_,tickers1,shares1=decompose_portfolio(portfolio1)
1123
+ _,_,tickers1,shares1,ticker_type=decompose_portfolio(portfolio1)
1124
1124
  if len(tickers1) == 1:
1125
1125
  ticker1=tickers1[0]
1126
1126
  pf1str=tickers1[0]
1127
1127
  else:
1128
1128
  pf1str=ticker1+':成分'+str(tickers1)+',比例'+str(shares1)
1129
1129
 
1130
- _,_,tickers2,shares2=decompose_portfolio(portfolio2)
1130
+ _,_,tickers2,shares2,ticker_type=decompose_portfolio(portfolio2)
1131
1131
  if len(tickers2) == 1:
1132
1132
  ticker2=tickers2[0]
1133
1133
  pf2str=tickers2[0]
siat/security_price2.py CHANGED
@@ -86,8 +86,8 @@ def get_price_1ticker(ticker,fromdate,todate, \
86
86
  #print(" #Warning(get_price_1ticker): invalid date period from",fromdate,"to",todate)
87
87
  return df,found
88
88
 
89
- #检查复权选项合理性
90
- ak_fq_list=['','qfq','hfq','qfq-factor','hfq-factor']
89
+ #检查复权选项合理性:adj_only特别指最高最低价开盘收盘价全为复权价
90
+ ak_fq_list=['','qfq','hfq','qfq-factor','hfq-factor','adj_only']
91
91
  if adjust not in ak_fq_list:
92
92
  adjust='qfq'
93
93
 
@@ -149,11 +149,11 @@ def get_price_1ticker(ticker,fromdate,todate, \
149
149
  if source in ['auto','yahoo'] and found not in ['Found','Empty']:
150
150
  dft=None
151
151
  if test_yahoo_finance():
152
- #数据源情形3:yahoo, yfinance, 需要访问yahoo
152
+ #数据源情形3:yahoo, yfinance, 需要访问yahoo,直接为复权价?
153
153
  dft=get_price_yf(ticker1,fromdate,todate)
154
154
  found=df_have_data(dft)
155
155
 
156
- #数据源情形4:yahoo, pandas_datareader,需要访问yahoo,近期似乎不工作!
156
+ #数据源情形4:yahoo, pandas_datareader,需要访问yahoo,似乎不工作!
157
157
  if found not in ['Found','Empty']:
158
158
  dft=get_prices_yahoo(ticker1,fromdate,todate)
159
159
  found=df_have_data(dft)
@@ -364,13 +364,13 @@ def get_price_1portfolio(ticker,fromdate,todate, \
364
364
  return df,found
365
365
 
366
366
  #拆分投资组合为成份股列表和份额列表
367
- _,_,tickerlist,sharelist=decompose_portfolio(ticker)
367
+ _,_,tickerlist,sharelist,ticker_type=decompose_portfolio(ticker)
368
368
 
369
369
  #处理份额列表,确保其和为1
370
370
  share_sum=sum(sharelist)
371
371
  sharelist1=[x / share_sum for x in sharelist]
372
372
 
373
- #预处理ticker_type
373
+ #预处理ticker_type,是否还需要?
374
374
  ticker_type=ticker_type_preprocess_1portfolio(ticker,ticker_type)
375
375
 
376
376
  #抓取各个成份股的价格信息
siat/security_prices.py CHANGED
@@ -78,9 +78,9 @@ def get_prices_all(ticker,fromdate,todate,adj=False,source='auto',ticker_type='a
78
78
 
79
79
  #投资组合
80
80
  if isinstance(ticker_list[0],dict):
81
- _,_,tickerlist,sharelist=decompose_portfolio(ticker_list[0])
81
+ _,_,tickerlist,sharelist,ticker_type=decompose_portfolio(ticker_list[0])
82
82
  df=get_price_portfolio(tickerlist,sharelist,fromdate,todate,adj=adj, \
83
- source=source,ticker_type='bond')
83
+ source=source,ticker_type=ticker_type)
84
84
  return df
85
85
 
86
86
  #多个证券
@@ -95,9 +95,9 @@ def get_prices_all(ticker,fromdate,todate,adj=False,source='auto',ticker_type='a
95
95
 
96
96
  #投资组合
97
97
  if isinstance(t,dict):
98
- _,_,tickerlist,sharelist=decompose_portfolio(t)
98
+ _,_,tickerlist,sharelist,ticker_type=decompose_portfolio(t)
99
99
  dft=get_price_portfolio(tickerlist,sharelist,fromdate,todate,adj=adj, \
100
- source=source,ticker_type='bond')
100
+ source=source,ticker_type=ticker_type)
101
101
  t=portfolio_name(t)
102
102
 
103
103
  columns=create_tuple_for_columns(dft,t)
@@ -755,14 +755,14 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
755
755
  end1=end.strftime('%Y%m%d')
756
756
 
757
757
  #adjustlist=['none','hfq','qfq']
758
- adjustlist=['','qfq','hfq','qfq-factor','hfq-factor']
758
+ adjustlist=['','qfq','hfq','qfq-factor','hfq-factor','adj_only']
759
759
  if adjust not in adjustlist:
760
760
  print(" #Warning(get_price_ak_cn): adjust only supports",adjustlist)
761
761
  return None
762
762
 
763
763
  _,prefix,suffix=split_prefix_suffix(ticker2)
764
- #考虑股票复权情形:指数/基金/债券无复权
765
- if adjust != '':
764
+ #考虑股票复权情形:仅收盘价为复权价,指数/基金/债券无复权
765
+ if adjust not in ['','adj_only']:
766
766
  if ticker_type in ['auto','stock'] and suffix not in ['SW']:
767
767
  try:
768
768
  #仅用于股票的历史行情数据(考虑复权)
@@ -775,6 +775,18 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
775
775
  except:
776
776
  df=None
777
777
  found=df_have_data(df)
778
+
779
+ #考虑股票复权情形:所有价格均为复权价,指数/基金/债券无复权
780
+ if adjust == 'adj_only':
781
+ if ticker_type in ['auto','stock'] and suffix not in ['SW']:
782
+ try:
783
+ #仅用于股票的历史行情数据(考虑复权)
784
+ df=ak.stock_zh_a_daily(ticker2,start1,end1,adjust='qfq')
785
+ df['Adj Close']=df['close']
786
+ df['Date']=df['date']
787
+ except:
788
+ df=None
789
+ found=df_have_data(df)
778
790
 
779
791
  #股票(无复权)指数/基金/债券
780
792
  if found != 'Found':
@@ -961,6 +973,10 @@ def get_price_ak_us(symbol, fromdate, todate, adjust=""):
961
973
  try:
962
974
  if adjust=='':
963
975
  df=ak.stock_us_daily(symbol=symbol,adjust=adjust)
976
+ elif adjust=='Adj_only':
977
+ df=ak.stock_us_daily(symbol=symbol,adjust='qfq')
978
+ df['Adj Close']=df['close']
979
+
964
980
  else:
965
981
  dffqno=ak.stock_us_daily(symbol=symbol,adjust='')
966
982
  dffq=ak.stock_us_daily(symbol=symbol,adjust='qfq')
@@ -1048,6 +1064,9 @@ def get_price_ak_hk(symbol,fromdate,todate,adjust=""):
1048
1064
  try:
1049
1065
  if adjust == '':
1050
1066
  df=ak.stock_hk_daily(symbol=symbol3, adjust=adjust)
1067
+ elif adjust == 'Adj_only':
1068
+ df=ak.stock_hk_daily(symbol=symbol3, adjust='qfq')
1069
+ df['Adj Close']=df['close']
1051
1070
  else:
1052
1071
  dffqno=ak.stock_hk_daily(symbol=symbol3, adjust='')
1053
1072
  dffq =ak.stock_hk_daily(symbol=symbol3,adjust='qfq')
@@ -1503,7 +1522,7 @@ if __name__=='__main__':
1503
1522
  ticker_type='auto'
1504
1523
 
1505
1524
  ticker={'Market':('China','000001.SS','白酒组合'),'600519.SS':0.4,'000858.SZ':0.6}
1506
- _,_,tickerlist,sharelist=decompose_portfolio(ticker)
1525
+ _,_,tickerlist,sharelist,ticker_type=decompose_portfolio(ticker)
1507
1526
 
1508
1527
  p=get_prices_portfolio(tickerlist,sharelist,fromdate,todate,source='auto')
1509
1528
 
@@ -2157,7 +2176,7 @@ def get_portfolio_prices(portfolio,fromdate,todate,adj=False,source='auto'):
2157
2176
  """
2158
2177
 
2159
2178
  #解构投资组合
2160
- _,mktidx,tickerlist,sharelist=decompose_portfolio(portfolio)
2179
+ _,mktidx,tickerlist,sharelist,ticker_type=decompose_portfolio(portfolio)
2161
2180
 
2162
2181
  #检查股票列表个数与份额列表个数是否一致
2163
2182
  if len(tickerlist) != len(sharelist):
@@ -2405,7 +2424,7 @@ def get_price_security(security,start,end,source='auto'):
2405
2424
  """
2406
2425
 
2407
2426
  if isinstance(security,dict): #投资组合
2408
- scope,mktidx,tickerlist,sharelist=decompose_portfolio(security)
2427
+ scope,mktidx,tickerlist,sharelist,ticker_type=decompose_portfolio(security)
2409
2428
  prices=get_price_portfolio(tickerlist,sharelist,start,end,source=source)
2410
2429
 
2411
2430
  pname=portfolio_name(security)
siat/stock.py CHANGED
@@ -3531,7 +3531,7 @@ def portfolio_esg2(portfolio):
3531
3531
  企业最新的可持续性发展数据,数据框
3532
3532
  """
3533
3533
  #解构投资组合
3534
- _,_,stocklist,_=decompose_portfolio(portfolio)
3534
+ _,_,stocklist,_,ticker_type=decompose_portfolio(portfolio)
3535
3535
 
3536
3536
  #抓取数据
3537
3537
  try: