siat 3.10.75__py3-none-any.whl → 3.10.125__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
@@ -288,17 +288,23 @@ def portfolio_cumret(portfolio,thedate,pastyears=1, \
288
288
  RF=0, \
289
289
  printout=True,graph=True):
290
290
  """
291
- def portfolio_build(portfolio,thedate='default',pastyears=1, \
291
+ def portfolio_build(portfolio,thedate='default',pastyears=3, \
292
292
  indicator='Adj Close', \
293
293
  adjust='qfq',source='auto',ticker_type='auto', \
294
294
  printout=False,graph=False,facecolor='papayawhip'):
295
295
  """
296
296
  功能:收集投资组合成份股数据,绘制收益率趋势图,并与等权和期间内交易额加权策略组合比较
297
- 注意:此处无需RF,待到优化策略时再指定
298
- printout=True控制获取股价时是否逐个显示
299
-
300
- 特别注意:若ticker_type='fund'可能导致无法处理股票的复权价!
301
- 若要指定特定的证券为债券,则需要使用列表逐一指定证券的类型(股票,债券,基金)
297
+ 注意:
298
+ 1. 此处无需RF,待到优化策略时再指定
299
+ 2. printout=True控制下列内容是否显示:
300
+ 获取股价时的信息
301
+ 是否显示原始组合、等权重组合和交易金额加权组合的成分股构成
302
+ 是否显示原始组合、等权重组合和交易金额加权组合的收益风险排名
303
+ 3. pastyears=3更有可能生成斜向上的椭圆形可行集,需要与不同行业的证券搭配。
304
+ 同行业证券相关性较强,不易生成斜向上的椭圆形可行集。
305
+ 4. 若ticker_type='fund'可能导致无法处理股票的复权价!
306
+ 5. 若要指定特定的证券为债券,则需要使用列表逐一指定证券的类型(股票,债券,基金)
307
+ 6. 默认采用前复权计算收益率,更加平稳
302
308
  """
303
309
  #判断复权标志
304
310
  indicator_list=['Close','Adj Close']
@@ -1145,7 +1151,27 @@ if __name__=='__main__':
1145
1151
  portfolio_eset(pf_info,simulation=50000)
1146
1152
 
1147
1153
  def portfolio_feset(pf_info,simulation=50000,convex_hull=True,frontier="both",facecolor='papayawhip'):
1148
-
1154
+ """
1155
+ 功能:套壳函数portfolio_eset
1156
+ 当frontier不在列表['efficient','inefficient','both']中时,绘制可行集
1157
+ 当frontier == 'efficient'时绘制有效边界
1158
+ 当frontier == 'inefficient'时绘制无效边界
1159
+ 当frontier == 'both'时同时绘制有效边界和无效边界
1160
+ 当绘制有效/无效边界时,默认使用凸包绘制(convex_hull=True)
1161
+ """
1162
+ if frontier is None:
1163
+ convex_hull=False
1164
+ elif isinstance(frontier,str):
1165
+ frontier=frontier.lower()
1166
+
1167
+ frontier_list=['efficient','inefficient','both']
1168
+ if not any(element in frontier for element in frontier_list):
1169
+ convex_hull=False
1170
+ else:
1171
+ convex_hull=True
1172
+ else:
1173
+ convex_hull=False
1174
+
1149
1175
  results=portfolio_eset(pf_info,simulation=simulation,convex_hull=convex_hull,frontier=frontier,facecolor=facecolor)
1150
1176
 
1151
1177
  return results
@@ -1158,6 +1184,15 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
1158
1184
  """
1159
1185
  DEBUG=True; MORE_DETAIL=False
1160
1186
 
1187
+ frontier_list=['efficient','inefficient','both']
1188
+ if isinstance(frontier,str):
1189
+ if any(element in frontier for element in frontier_list):
1190
+ efficient_set=True
1191
+ else:
1192
+ efficient_set=False
1193
+ else:
1194
+ efficient_set=False
1195
+
1161
1196
  [[portfolio,thedate,stock_return,_,_],_]=pf_info
1162
1197
  pname=portfolio_name(portfolio)
1163
1198
  _,_,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
@@ -1322,7 +1357,20 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
1322
1357
  if pname == '': pname='投资组合'
1323
1358
 
1324
1359
  plt.colorbar(label='收益率/标准差')
1325
- plt.title(pname+": 马科维茨可行(有效)集",fontsize=title_txt_size)
1360
+
1361
+ if efficient_set:
1362
+ if frontier == 'efficient':
1363
+ titletxt0=": 马科维茨有效集(有效边界)"
1364
+ elif frontier == 'inefficient':
1365
+ titletxt0=": 马科维茨无效集(无效边界)"
1366
+ elif frontier == 'both':
1367
+ titletxt0=": 马科维茨有效边界与无效边界"
1368
+ else:
1369
+ titletxt0=": 马科维茨可行集"
1370
+ else:
1371
+ titletxt0=": 马科维茨可行集"
1372
+
1373
+ plt.title(pname+titletxt0,fontsize=title_txt_size)
1326
1374
  plt.ylabel("年化收益率",fontsize=ylabel_txt_size)
1327
1375
 
1328
1376
  footnote1="年化收益率标准差-->"
@@ -1332,6 +1380,18 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
1332
1380
  else:
1333
1381
  if pname == '': pname='Investment Portfolio'
1334
1382
 
1383
+ if efficient_set:
1384
+ if frontier == 'efficient':
1385
+ titletxt0=": Markowitz Efficient Set (Efficient Frontier)"
1386
+ elif frontier == 'inefficient':
1387
+ titletxt0=": Markowitz Inefficient Set (Inefficient Frontier)"
1388
+ elif frontier == 'both':
1389
+ titletxt0=": Markowitz Efficient & Inefficient Frontier"
1390
+ else:
1391
+ titletxt0=": Markowitz Feasible Set"
1392
+ else:
1393
+ titletxt0=": Markowitz Feasible Set"
1394
+
1335
1395
  plt.colorbar(label='Return/Std')
1336
1396
  plt.title(pname+": Feasible/Efficient Set",fontsize=title_txt_size)
1337
1397
  plt.ylabel("Annualized Return",fontsize=ylabel_txt_size)
@@ -1344,7 +1404,8 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",fa
1344
1404
  plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontsize=xlabel_txt_size)
1345
1405
 
1346
1406
  plt.gca().set_facecolor(facecolor)
1347
- plt.legend(loc='best')
1407
+ if efficient_set:
1408
+ plt.legend(loc='best')
1348
1409
  plt.show()
1349
1410
 
1350
1411
  return [pf_info,RandomPortfolios]
@@ -1905,7 +1966,7 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1905
1966
  if lang == 'Chinese':
1906
1967
  if pname == '': pname='投资组合'
1907
1968
 
1908
- plt.title(pname+": 马科维茨可行/有效集,基于"+title_ext,fontsize=title_txt_size)
1969
+ plt.title(pname+": 投资组合优化策略,基于"+title_ext,fontsize=title_txt_size)
1909
1970
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
1910
1971
 
1911
1972
  import datetime as dt; stoday=dt.date.today()
@@ -2350,6 +2411,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
2350
2411
  注意:实验发现RF较小时对于结果的影响极其微小难以观察,默认设为不使用无风险利率调整收益
2351
2412
  但RF较大时对于结果的影响明显变大,已经不能忽略!
2352
2413
  """
2414
+ ratio=ratio.lower()
2353
2415
 
2354
2416
  ratio_list=['treynor','sharpe','sortino','alpha']
2355
2417
  if not (ratio in ratio_list):
siat/option_china.py CHANGED
@@ -414,18 +414,32 @@ if __name__=='__main__':
414
414
  detail=False
415
415
 
416
416
  # 定义中国当前金融期权的所有品种
417
- option_fin_list_sse=["华夏上证50ETF期权","华夏科创50ETF期权","易方达科创50ETF期权", \
418
- "华泰柏瑞沪深300ETF期权","南方中证500ETF期权"]
419
- underlying_fin_list_sse=["510050.SS","588000.SS","588080.SS", \
420
- "510300.SS","510500.SS"]
421
-
422
- option_fin_list_szse=["易方达深证100ETF期权","易方达创业板ETF期权","嘉实沪深300ETF期权", \
417
+ option_fin_list_sse=["华夏上证50ETF期权", \
418
+ "华夏科创50ETF期权", \
419
+ "易方达科创50ETF期权", \
420
+ "华泰柏瑞沪深300ETF期权", \
421
+ "南方中证500ETF期权"]
422
+ underlying_fin_list_sse=["510050.SS", \
423
+ "588000.SS", \
424
+ "588080.SS", \
425
+ "510300.SS", \
426
+ "510500.SS"]
427
+
428
+ option_fin_list_szse=["易方达深证100ETF期权", \
429
+ "易方达创业板ETF期权", \
430
+ "嘉实沪深300ETF期权", \
423
431
  "嘉实中证500ETF期权"]
424
- underlying_fin_list_szse=["159901.SZ","159915.SZ","159919.SZ", \
432
+ underlying_fin_list_szse=["159901.SZ", \
433
+ "159915.SZ", \
434
+ "159919.SZ", \
425
435
  "159922.SZ"]
426
436
 
427
- option_fin_list_cffe=["上证50股指期权","沪深300股指期权","中证1000股指期权"]
428
- underlying_fin_list_cffe=["000016.SS","000300.SS","000852.SS"]
437
+ option_fin_list_cffe=["上证50股指期权", \
438
+ "沪深300股指期权", \
439
+ "中证1000股指期权"]
440
+ underlying_fin_list_cffe=["000016.SS", \
441
+ "000300.SS", \
442
+ "000852.SS"]
429
443
 
430
444
  option_fin_list=option_fin_list_sse + option_fin_list_szse + option_fin_list_cffe
431
445
  underlying_fin_list=underlying_fin_list_sse + underlying_fin_list_szse + underlying_fin_list_cffe
@@ -1167,21 +1181,33 @@ if __name__=='__main__':
1167
1181
  #=============================================================================
1168
1182
  if __name__=='__main__':
1169
1183
  option="华泰柏瑞沪深300ETF期权"
1170
- end_month='2206'
1171
- contract='510300C2206M04500'
1184
+ end_month='2512'
1185
+ contract='510300C2512M04000'
1172
1186
  direction='call'
1173
1187
 
1174
- today='2021-11-19'
1175
- sample_days=360
1188
+ today='2025-6-18'
1189
+ sample_days=183
1176
1190
 
1177
- rate_type='shibor'
1191
+ rate_type='treasury'
1178
1192
  rate_period='1Y'
1179
1193
  daysahead=183
1180
1194
 
1181
1195
  def option_fin_pricing_china(option,end_month,contract,today,direction='call', \
1182
- sample_days=183,rate_type='shibor',rate_period='1Y',printout=True):
1196
+ sample_days=183, \
1197
+ rate_type='treasury',rate_period='1Y',RF=0, \
1198
+ printout=True):
1183
1199
  """
1184
1200
  功能:将中国金融期权定价的过程整合在一起,提供默认选项,改善小白的使用体验
1201
+ 参数:
1202
+ option:金融期权品种
1203
+ end_month:期权到期YYMM
1204
+ contract:期权合约编号
1205
+ today:计算日,可选任意日期,最新日期建议选上一个交易日,便于获取数据
1206
+ direction:期权方向,默认认购/看涨'call'
1207
+ sample_days:计算(标的物)历史波动率的取样日历天数,默认183
1208
+ rate_type:获取无风险利率的方式,默认自动获取'treasury',也可直接指定数值'value'
1209
+ RF:当rate_type为'value'时,直接给出无风险利率的数值
1210
+
1185
1211
  注:波动率使用历史波动率
1186
1212
  """
1187
1213
 
@@ -1205,6 +1231,8 @@ def option_fin_pricing_china(option,end_month,contract,today,direction='call', \
1205
1231
  rf=shibor_rate(today,rate_period)
1206
1232
  elif rate_type=='TREASURY':
1207
1233
  rf=treasury_yield_china(today,rate_period)
1234
+ elif rate_type=='VALUE':
1235
+ rf=RF
1208
1236
  else:
1209
1237
  print(" #Error(option_fin_pricing_china): invalid rate type",rate_type.lower())
1210
1238
  return None
@@ -2322,8 +2350,8 @@ def fin_option_risk_sse2(option,maturity,exercise,trade_date, \
2322
2350
 
2323
2351
  import numpy as np
2324
2352
  textupper=0.01
2325
- textlower=0.065
2326
- #textlower=0.2
2353
+ #textlower=0.065
2354
+ textlower=0.01
2327
2355
 
2328
2356
  for a,b in zip(x,yv): ##控制标签位置:横坐标,纵坐标
2329
2357
  if b >= 0:
siat/option_pricing.py CHANGED
@@ -1173,6 +1173,7 @@ if __name__=='__main__':
1173
1173
  def option_maturity(ticker,printout=True):
1174
1174
  """
1175
1175
  功能:获得期权的各个到期日期
1176
+ 注意:目前yfinance无法使用,股票期权链功能暂时不可用,可尝试yahooquery?
1176
1177
  """
1177
1178
  """
1178
1179
  if not test_yahoo_access():
@@ -1180,6 +1181,8 @@ def option_maturity(ticker,printout=True):
1180
1181
  return None
1181
1182
  """
1182
1183
  import yfinance as yf
1184
+ # yf.__version__
1185
+
1183
1186
  opt = yf.Ticker(ticker)
1184
1187
 
1185
1188
  #获得期权的各个到期日
siat/other_indexes.py CHANGED
@@ -36,7 +36,7 @@ def other_index_translate(index_code):
36
36
  trans_dict=pd.DataFrame([
37
37
 
38
38
  ['INDEXCF','俄罗斯MICEX指数','俄罗斯MICEX指数','MICEX Index','sina'],
39
- ['RTS','俄罗斯RTS指数','俄罗斯RTS指数','RTS Index','sina'],
39
+ ['RTS','俄罗斯RTS指数','俄罗斯RTS指数','RTS Index','em'],
40
40
  ['CASE','埃及CASE 30指数','埃及CASE30指数','CASE30 Index','sina'],
41
41
  ['VNINDEX','越南胡志明','越南胡志明指数','Ho Chi-Ming Index','em'],
42
42
  ['HSCEI','国企指数','港股国企指数','HK H-share Index','em'],
@@ -99,7 +99,11 @@ def get_other_index_em(index_code,start,end):
99
99
  return None
100
100
 
101
101
  import akshare as ak
102
- dft = ak.index_global_hist_em(symbol=symbol)
102
+ try:
103
+ dft = ak.index_global_hist_em(symbol=symbol)
104
+ except:
105
+ return None
106
+
103
107
  dft.rename(columns={'日期':'Date','代码':'ticker','名称':'Name','今开':'Open', \
104
108
  '最新价':'Close','最高':'High','最低':'Low','振幅':'Change'}, \
105
109
  inplace=True)
@@ -123,6 +127,11 @@ if __name__=='__main__':
123
127
  start='2025-2-1'; end='2025-3-31'
124
128
  get_other_index_em(index_code,start,end)
125
129
  #==============================================================================
130
+ if __name__=='__main__':
131
+ index_code='RTS'
132
+ start='2025-2-1'; end='2025-3-31'
133
+ get_other_index_em(index_code,start,end)
134
+
126
135
  def get_other_index_sina(index_code,start,end):
127
136
  """
128
137
  功能:获取另类指数历史行情,新浪财经
@@ -135,7 +144,11 @@ def get_other_index_sina(index_code,start,end):
135
144
  return None
136
145
 
137
146
  import akshare as ak
138
- dft = ak.index_global_hist_sina(symbol=symbol)
147
+ try:
148
+ dft = ak.index_global_hist_sina(symbol=symbol)
149
+ except:
150
+ return None
151
+
139
152
  dft.rename(columns={'open':'Open','high':'High','low':'Low','close':'Close', \
140
153
  'volume':'Volume'},inplace=True)
141
154
  dft['ticker']=index_code; dft['Name']=name; dft['Date']=dft['date']