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/assets_liquidity.py +168 -30
- siat/bond.py +34 -7
- siat/capm_beta.py +34 -9
- siat/common.py +88 -7
- siat/economy2.py +75 -1
- siat/exchange_bond_china.pickle +0 -0
- siat/fama_french.py +201 -12
- siat/financial_statements.py +26 -85
- siat/financials.py +114 -14
- siat/financials_china.py +1 -1
- siat/fund_china.py +6 -5
- siat/future_china.py +8 -2
- siat/holding_risk.py +38 -31
- siat/market_china.py +20 -10
- siat/markowitz2.py +72 -10
- siat/option_china.py +45 -17
- siat/option_pricing.py +3 -0
- siat/other_indexes.py +16 -3
- siat/risk_adjusted_return.py +182 -114
- siat/risk_evaluation.py +252 -20
- siat/sector_china.py +12 -9
- siat/security_price2.py +19 -4
- siat/security_prices.py +222 -23
- siat/security_trend2.py +3 -3
- siat/stock.py +32 -0
- siat/translate.py +18 -9
- siat/var_model_validation.py +59 -0
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/METADATA +1 -1
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/RECORD +32 -32
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/LICENSE +0 -0
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/WHEEL +0 -0
- {siat-3.10.75.dist-info → siat-3.10.125.dist-info}/top_level.txt +0 -0
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=
|
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
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
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
|
-
|
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
|
-
|
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+":
|
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期权",
|
418
|
-
"
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
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",
|
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股指期权",
|
428
|
-
|
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='
|
1171
|
-
contract='
|
1184
|
+
end_month='2512'
|
1185
|
+
contract='510300C2512M04000'
|
1172
1186
|
direction='call'
|
1173
1187
|
|
1174
|
-
today='
|
1175
|
-
sample_days=
|
1188
|
+
today='2025-6-18'
|
1189
|
+
sample_days=183
|
1176
1190
|
|
1177
|
-
rate_type='
|
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,
|
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
|
-
|
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','
|
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
|
-
|
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
|
-
|
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']
|