siat 3.10.125__py3-none-any.whl → 3.10.126__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.
Files changed (87) hide show
  1. siat/common.py +106 -2
  2. siat/exchange_bond_china.pickle +0 -0
  3. siat/fund_china.pickle +0 -0
  4. siat/stock.py +10 -2
  5. siat/stock_info.pickle +0 -0
  6. {siat-3.10.125.dist-info → siat-3.10.126.dist-info}/METADATA +234 -226
  7. siat-3.10.126.dist-info/RECORD +76 -0
  8. {siat-3.10.125.dist-info → siat-3.10.126.dist-info}/WHEEL +1 -1
  9. {siat-3.10.125.dist-info → siat-3.10.126.dist-info/licenses}/LICENSE +0 -0
  10. {siat-3.10.125.dist-info → siat-3.10.126.dist-info}/top_level.txt +0 -0
  11. siat/__init__ -20240701.py +0 -65
  12. siat/__init__.py.backup_20250214.py +0 -73
  13. siat/alpha_vantage_test.py +0 -24
  14. siat/assets_liquidity_test.py +0 -44
  15. siat/barrons_scraping_test.py +0 -276
  16. siat/beta_adjustment_test.py +0 -77
  17. siat/bond_test.py +0 -142
  18. siat/capm_beta_test.py +0 -49
  19. siat/cmat_commons.py +0 -961
  20. siat/compare_cross_test.py +0 -117
  21. siat/concepts_iwencai.py +0 -86
  22. siat/concepts_kpl.py +0 -93
  23. siat/cryptocurrency_test.py +0 -71
  24. siat/derivative.py +0 -1111
  25. siat/economy-20230125.py +0 -1206
  26. siat/economy_test.py +0 -360
  27. siat/esg_test.py +0 -63
  28. siat/fama_french_test.py +0 -115
  29. siat/financial_statements_test.py +0 -31
  30. siat/financials2 - /321/205/320/231/320/277/321/206/320/254/320/274.py" +0 -341
  31. siat/financials_china2_test.py +0 -67
  32. siat/financials_china2_test2.py +0 -88
  33. siat/financials_china2_test3.py +0 -87
  34. siat/financials_china_test.py +0 -475
  35. siat/financials_china_test2.py +0 -197
  36. siat/financials_china_test2_fin_indicator.py +0 -197
  37. siat/financials_test.py +0 -713
  38. siat/fred_test.py +0 -40
  39. siat/fund_china_test.py +0 -175
  40. siat/fund_test.py +0 -40
  41. siat/future_china_test.py +0 -37
  42. siat/global_index_test.py +0 -66
  43. siat/grafix_test.py +0 -112
  44. siat/holding_risk_test.py +0 -13
  45. siat/local_debug_test.py +0 -100
  46. siat/markowitz2-20240620.py +0 -2614
  47. siat/markowitz_ccb_test.py +0 -37
  48. siat/markowitz_ef_test.py +0 -136
  49. siat/markowitz_old.py +0 -871
  50. siat/markowitz_simple-20230709.py +0 -370
  51. siat/markowitz_test.py +0 -164
  52. siat/markowitz_test2.py +0 -69
  53. siat/ml_cases_example1.py +0 -60
  54. siat/option_china_test.py +0 -447
  55. siat/option_pricing_test.py +0 -81
  56. siat/option_sina_api_test.py +0 -112
  57. siat/proxy_test.py +0 -84
  58. siat/quandl_test.py +0 -39
  59. siat/risk_adjusted_return_test.py +0 -81
  60. siat/risk_evaluation_test.py +0 -96
  61. siat/risk_free_rate_test.py +0 -127
  62. siat/sector_china_test.py +0 -203
  63. siat/security_price.py +0 -831
  64. siat/security_prices_test.py +0 -310
  65. siat/security_trend2-20240620.py +0 -493
  66. siat/setup.py +0 -41
  67. siat/shenwan index history test.py +0 -41
  68. siat/stock_china_test.py +0 -38
  69. siat/stock_info_test.py +0 -189
  70. siat/stock_list_china_test.py +0 -33
  71. siat/stock_technical-20240620.py +0 -2736
  72. siat/stock_test.py +0 -487
  73. siat/temp.py +0 -36
  74. siat/test2_graphviz.py +0 -484
  75. siat/test_graphviz.py +0 -411
  76. siat/test_markowitz_simple.py +0 -198
  77. siat/test_markowitz_simple_revised.py +0 -215
  78. siat/test_markowitz_simple_revised2.py +0 -218
  79. siat/transaction_test.py +0 -436
  80. siat/translate-20230125.py +0 -2107
  81. siat/translate-20230206.py +0 -2109
  82. siat/translate-20230215.py +0 -2158
  83. siat/translate_20240606.py +0 -4206
  84. siat/translate_241003_keep.py +0 -4300
  85. siat/universal_test.py +0 -100
  86. siat/valuation_market_china_test.py +0 -36
  87. siat-3.10.125.dist-info/RECORD +0 -152
siat/security_price.py DELETED
@@ -1,831 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- 本模块功能:提供全球证券市场行情
4
- 所属工具包:证券投资分析工具SIAT
5
- SIAT:Security Investment Analysis Tool
6
- 创建日期:2020年1月5日
7
- 最新修订日期:2020年2月2日
8
- 作者:王德宏 (WANG Dehong, Peter)
9
- 作者单位:北京外国语大学国际商学院
10
- 作者邮件:wdehong2000@163.com
11
- 版权所有:王德宏
12
- 用途限制:仅限研究与教学使用,不可商用!商用需要额外授权。
13
- 特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
14
-
15
- 注意:本文件弃用!!!
16
- """
17
-
18
- #==============================================================================
19
- #屏蔽所有警告性信息
20
- import warnings; warnings.filterwarnings('ignore')
21
- #==============================================================================
22
- #以下使用雅虎财经数据源
23
- #==============================================================================
24
- def check_period(fromdate,todate):
25
- """
26
- 功能:根据开始/结束日期检查期间日期的合理性
27
- 输入参数:
28
- fromdate:开始日期。格式:YYYY-MM-DD
29
- enddate:开始日期。格式:YYYY-MM-DD
30
- 输出参数:
31
- validity:期间合理性。True-合理,False-不合理
32
- start:开始日期。格式:datetime类型
33
- end:结束日期。格式:datetime类型
34
- """
35
- import pandas as pd
36
- try:
37
- start=pd.to_datetime(fromdate)
38
- except:
39
- print("Error #1(check_period): invalid date:",fromdate)
40
- return None,None,None
41
- try:
42
- end=pd.to_datetime(todate)
43
- except:
44
- print("Error #2(check_period): invalid date:",todate)
45
- return None,None,None
46
- if start > end:
47
- print("Error #3(check_period): invalid period: from",fromdate,"to",todate)
48
- return None,None,None
49
-
50
- return True,start,end
51
-
52
- if __name__ =="__main__":
53
- check_period('2020-1-1','2020-2-4')
54
- check_period('2020-1-1','2010-2-4')
55
-
56
- #==============================================================================
57
- def get_price(ticker,fromdate,todate):
58
- """
59
- 功能:从雅虎财经抓取股票股价或指数价格或投资组合价值,使用pandas_datareader
60
- 输入:股票代码或股票代码列表,开始日期,结束日期
61
- ticker: 股票代码或者股票代码列表。
62
- 大陆股票代码加上后缀.SZ或.SS,港股代码去掉前导0加后缀.HK
63
- fromdate: 样本开始日期。
64
- todate: 样本结束日期。既可以是今天日期,也可以是一个历史日期
65
-
66
- 输出:股票价格序列,按照日期升序排列。原汁原味的抓取数据
67
- *Close price adjusted for splits.
68
- **Adjusted close price adjusted for both dividends and splits.
69
- """
70
- #检查期间合理性
71
- result,start,end=check_period(fromdate,todate)
72
- if result is None:
73
- print("Error #1(get_price): incorrect date or invalid period!")
74
- return None
75
-
76
- #抓取雅虎股票价格
77
- from pandas_datareader import data
78
- try:
79
- price=data.DataReader(ticker,'yahoo',start,end)
80
- except:
81
- print("Error #2(get_price): failed to get stock prices!")
82
- print("Information:",ticker,fromdate,todate)
83
- print("Possible reasons:")
84
- print(" 1)internet connection problems.")
85
- print(" 2)incorrect stock code.")
86
- print(" 3)stock delisted or suspended during the period.")
87
- return None
88
- if len(price)==0:
89
- print("Error #3(get_price): fetched empty stock data!")
90
- print("Possible reasons:")
91
- print(" 1)internet connection problems.")
92
- print(" 2)incorrect stock code.")
93
- print(" 3)stock delisted or suspended during the period.")
94
- return None
95
- """
96
- #去掉比起始日期更早的样本
97
- price2=price[price.index >= fromdate]
98
- #去掉比结束日期更晚的样本
99
- price2=price2[price2.index <= todate]
100
-
101
- #按日期升序排序,近期的价格排在后面
102
- sortedprice=price2.sort_index(axis=0,ascending=True)
103
- """
104
- return price
105
-
106
- if __name__ =="__main__":
107
- price=get_price('^GSPC','2020-1-1','2020-2-4')
108
- print(price['Close'].tail(10))
109
- price=get_price(['000001.SS','^HSI'],'2020-1-1','2020-2-4')
110
- apclose=price['Close']['^HSI']
111
- print(price['Close']['^HSI'].tail(10))
112
-
113
- #==============================================================================
114
- def compare_price(price,ticker1,ticker2,fromdate,todate):
115
- """
116
- 功能:比较两支股票的收盘价价格趋势,采用双坐标轴
117
- 输入:
118
- price:抓取到的多只股票价格序列
119
- ticker1/ticker2:股票或指数或ETF代码
120
- fromdate/todate:开始/结束日期
121
- 输出:折线图,双坐标轴,避免数量级差异过大的问题
122
- """
123
- #检查期间合理性
124
- result,start,end=check_period(fromdate,todate)
125
- if result is None:
126
- print("Error #1(compare_price): incorrect date or invalid period!")
127
- return
128
-
129
- #检查ticker1/ticker2是否已经抓取在price中
130
- try:
131
- p1=price['Close'][ticker1]
132
- except:
133
- print("Error #2(compare_price): price data not found for",ticker1)
134
- return
135
- try:
136
- p2=price['Close'][ticker2]
137
- except:
138
- print("Error #3(compare_price): price data not found for",ticker2)
139
- return
140
-
141
- #去掉比起始日期更早的样本
142
- p1b=p1[p1.index >= start]
143
- p2b=p2[p2.index >= start]
144
- #去掉比结束日期更晚的样本
145
- p1c=p1b[p1b.index <= end]
146
- p2c=p2b[p2b.index <= end]
147
-
148
- #绘制折线图,双坐标轴
149
- import matplotlib.pyplot as plt
150
- import matplotlib.dates as mdates
151
- fig = plt.figure()
152
- ax = fig.add_subplot(111)
153
- ax.plot(p1c, '-', label = ticker1, lw=3)
154
-
155
- #自动优化x轴标签
156
- plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d')) # 格式化时间轴标注
157
- plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
158
-
159
- #建立第二y轴
160
- ax2 = ax.twinx()
161
- ax2.plot(p2c, 'r:.', label = ticker2, lw=3)
162
- #fig.legend(loc='best', bbox_to_anchor=(1,1), bbox_transform=ax.transAxes)
163
- #fig.legend(loc='best', bbox_transform=ax.transAxes)
164
- #fig.legend(loc='best')
165
-
166
- plt.title("Compare Securities Price", fontsize=18)
167
- ax.set_xlabel("\nSource: Yahoo Finance", fontsize=13)
168
- ax.set_ylabel(ticker1)
169
- ax.legend(loc='lower left')
170
- ax2.legend(loc='upper right')
171
- ax2.set_ylabel(ticker2)
172
- fig.show()
173
-
174
- if __name__ =="__main__":
175
- tickerlist=['000001.SS','601939.SS','^HSI','0939.HK']
176
- price=get_price(tickerlist,'2019-1-1','2019-12-31')
177
- ticker1='000001.SS'
178
- ticker2='^HSI'
179
- fromdate='2019-11-1'
180
- todate='2019-12-31'
181
- compare_price(price,'601939.SS','000001.SS','2019-1-1','2019-12-31')
182
- compare_price(price,'601939.SS','000001.SS','2019-8-1','2019-9-1')
183
- compare_price(price,'0939.HK','^HSI','2019-8-1','2019-9-1')
184
- compare_price(price,'000001.SS','^HSI','2019-7-1','2019-10-1')
185
- compare_price(price,'601939.SS','000001.SS','2019-11-15','2019-12-1')
186
- #==============================================================================
187
- def compare_return(price,ticker1,ticker2,fromdate,todate):
188
- """
189
- 功能:比较两支股票的收盘价价格趋势,采用双坐标轴
190
- 输入:
191
- price:抓取到的多只股票价格序列
192
- ticker1/ticker2:股票或指数或ETF代码
193
- fromdate/todate:开始/结束日期
194
- 输出:折线图,双坐标轴,避免数量级差异过大的问题
195
- """
196
- #检查期间合理性
197
- result,start,end=check_period(fromdate,todate)
198
- if result is None:
199
- print("Error #1(compare_price): incorrect date or invalid period!")
200
- return
201
-
202
- #检查ticker1/ticker2是否已经抓取在price中
203
- try:
204
- p1=price['Close'][ticker1]
205
- except:
206
- print("Error #2(compare_price): price data not found for",ticker1)
207
- return
208
- try:
209
- p2=price['Close'][ticker2]
210
- except:
211
- print("Error #3(compare_price): price data not found for",ticker2)
212
- return
213
-
214
- import matplotlib.pyplot as plt
215
- import matplotlib.dates as mdates
216
- import pandas as pd
217
-
218
- #绘制折线图
219
- r1=p1.pct_change()
220
- r1df=pd.DataFrame(r1)
221
- r1df.columns=['ret']
222
- r1df['ret%']=round(r1df['ret']*100.0,2)
223
-
224
- r1dfs1=r1df[r1df.index >= start]
225
- r1dfs2=r1dfs1[r1dfs1.index <= end]
226
-
227
- plt.plot(r1dfs2['ret%'],label=ticker1,lw=3)
228
-
229
- r2=p2.pct_change()
230
- r2df=pd.DataFrame(r2)
231
- r2df.columns=['ret']
232
- r2df['ret%']=round(r2df['ret']*100.0,2)
233
-
234
- r2dfs1=r2df[r2df.index >= start]
235
- r2dfs2=r2dfs1[r2dfs1.index <= end]
236
-
237
- plt.plot(r2dfs2['ret%'],label=ticker2,lw=3,ls=':')
238
-
239
- #纵轴零线
240
- plt.axhline(y=0.0,color='green',linestyle='--')
241
-
242
- #图示标题
243
- titletxt="Compare Security Returns"
244
- plt.title(titletxt,fontweight='bold', fontsize=18)
245
- plt.ylabel("Capital gain %")
246
- plt.xlabel("Data source: Yahoo Finance")
247
- #plt.xticks(rotation=45)
248
- #自动优化x轴标签
249
- plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
250
- plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
251
- plt.legend(loc='best')
252
- plt.show()
253
-
254
-
255
- if __name__ =="__main__":
256
- tickerlist=['000001.SS','601939.SS','^HSI','0939.HK']
257
- price=get_price(tickerlist,'2019-1-1','2019-12-31')
258
- compare_return(price,'601939.SS','000001.SS','2019-8-1','2019-9-1')
259
- compare_return(price,'0939.HK','^HSI','2019-8-1','2019-9-1')
260
- compare_return(price,'000001.SS','^HSI','2019-7-1','2019-10-1')
261
-
262
-
263
- #==============================================================================
264
- #以下使用雅虎+tushare混合数据源
265
- #==============================================================================
266
- def ts_token():
267
- """
268
- 功能:获得tushare的token
269
- 输入:无
270
- 输出:tushare的token
271
- """
272
- import tushare as ts
273
- token='49f134b05e668d288be43264639ac77821ab9938ff40d6013c0ed24f'
274
- pro=ts.pro_api(token)
275
-
276
- return pro
277
-
278
- if __name__ =="__main__":
279
- pro=ts_token()
280
- #==============================================================================
281
- def cvtdate_yahootots(yahoodate):
282
- """
283
- 功能:日期格式转换, YYYY-MM-DD转换为YYYYMMDD
284
- 输入:日期,YYYY-MM-DD
285
- 输出:日期,YYYYMMDD
286
- """
287
- import pandas as pd
288
- try:
289
- dateu=pd.to_datetime(yahoodate)
290
- except:
291
- print("Error #1(datecvt_yahootots): invalid date:",yahoodate)
292
- return None
293
-
294
- yyyy=str(dateu.year)
295
- mm=dateu.month
296
- if mm <= 9: mm='0'+str(mm)
297
- else: mm=str(mm)
298
- dd=dateu.day
299
- if dd <= 9: dd='0'+str(dd)
300
- else: dd=str(dd)
301
- tsdate=yyyy+mm+dd
302
-
303
- return tsdate
304
-
305
- if __name__ =="__main__":
306
- yahoodate='2019-12-5'
307
- tsdate=cvtdate_yahootots(yahoodate)
308
- print(tsdate)
309
- #==============================================================================
310
- def cvtticker_yahootots(yahooticker):
311
- """
312
- 功能:股票代码格式转换, xxxxxx.SS转换为xxxxxx.SH
313
- 输入:股票代码,xxxxxx.SS
314
- 输出:股票代码,xxxxxx.SH
315
- """
316
-
317
- tsticker=yahooticker
318
- suffix=yahooticker[-3:]
319
- if suffix == '.SS':
320
- tsticker=yahooticker.replace(suffix,'.SH')
321
-
322
- return tsticker
323
-
324
- if __name__ =="__main__":
325
- yahooticker='601939.SS'
326
- tsticker=cvtticker_yahootots(yahooticker)
327
- #==============================================================================
328
- def ts_price_stock(ticker,fromdate,todate):
329
- """
330
- 功能:从tushare数据源获得股票行情数据
331
- 输入:
332
- ticker: 大陆股票代码,上交所后缀为.SS,深交所后缀为.SZ
333
- fromdate:开始日期,格式YYYY-MM-DD
334
- todate:结束日期
335
- 输出:
336
- 行情数据,df,雅虎格式
337
- """
338
- #设置tushare的token
339
- pro=ts_token()
340
-
341
- #检查期间合理性
342
- result,start,end=check_period(fromdate,todate)
343
- if result is None:
344
- print("Error #1(ts_price_stock): incorrect date or invalid period!")
345
- return None
346
-
347
- #转换输入日期
348
- tsstart=cvtdate_yahootots(fromdate)
349
- tsend=cvtdate_yahootots(todate)
350
- #转换股票代码
351
- tsticker=cvtticker_yahootots(ticker)
352
-
353
- #抓取股票日行情
354
- price=pro.daily(ts_code=tsticker,start_date=tsstart,end_date=tsend)
355
-
356
- #升序排列
357
- price.sort_values('trade_date',ascending=True,inplace=True)
358
-
359
- #转换日期格式,设置日期索引
360
- import pandas as pd
361
- price['date']=pd.to_datetime(price['trade_date'])
362
- price.set_index('date',inplace=True)
363
-
364
- #修改列名
365
- price.rename(columns= \
366
- {'ts_code':'Ticker','open':'Open','high':'High','low':'Low', \
367
- 'close':'Close','vol':'Volume'},inplace=True)
368
-
369
- #删除不需要的列
370
- price.drop(['trade_date','pre_close','change','pct_chg','amount'], \
371
- axis=1,inplace=True)
372
-
373
- return price
374
-
375
- if __name__ =="__main__":
376
- ticker='601939.SS'
377
- fromdate='2019-12-11'
378
- todate='2020-02-05'
379
- price=ts_price_stock(ticker,fromdate,todate)
380
-
381
- #==============================================================================
382
- def ts_price_index(ticker,fromdate,todate):
383
- """
384
- 功能:从tushare数据源获得指数行情数据
385
- 输入:
386
- ticker: 大陆指数代码,上交所后缀为.SS,深交所后缀为.SZ
387
- fromdate:开始日期,格式YYYY-MM-DD
388
- todate:结束日期
389
- 输出:
390
- 行情数据,df,雅虎格式
391
- """
392
- #设置tushare的token
393
- pro=ts_token()
394
-
395
- #检查期间合理性
396
- result,start,end=check_period(fromdate,todate)
397
- if result is None:
398
- print("Error #1(ts_price_stock): incorrect date or invalid period!")
399
- return None
400
-
401
- #转换输入日期
402
- tsstart=cvtdate_yahootots(fromdate)
403
- tsend=cvtdate_yahootots(todate)
404
- #转换指数代码
405
- tsticker=cvtticker_yahootots(ticker)
406
-
407
- #抓取指数日行情
408
- price=pro.index_daily(ts_code=tsticker,start_date=tsstart,end_date=tsend)
409
-
410
- #升序排列
411
- price.sort_values('trade_date',ascending=True,inplace=True)
412
-
413
- #转换日期格式,设置日期索引
414
- import pandas as pd
415
- price['date']=pd.to_datetime(price['trade_date'])
416
- price.set_index('date',inplace=True)
417
-
418
- #修改列名
419
- price.rename(columns= \
420
- {'ts_code':'Ticker','open':'Open','high':'High','low':'Low', \
421
- 'close':'Close','vol':'Volume'},inplace=True)
422
- price['Ticker']=ticker
423
-
424
- #删除不需要的列
425
- price.drop(['trade_date','pre_close','change','pct_chg','amount'], \
426
- axis=1,inplace=True)
427
-
428
- return price
429
-
430
- if __name__ =="__main__":
431
- ticker='000300.SS'
432
- fromdate='2019-12-11'
433
- todate='2020-02-05'
434
- price=ts_price_index(ticker,fromdate,todate)
435
-
436
- #==============================================================================
437
- def ts_nav_etf(etf_code,fromdate,todate):
438
- """
439
- 功能:从tushare获得etf每日净值数据,便于与二级市场行情比较套利空间
440
- 输入:
441
- etf_code: 大陆etf代码,雅虎格式,上交所后缀为.SS,深交所后缀为.SZ
442
- fromdate:开始日期,格式YYYY-MM-DD
443
- todate:结束日期
444
- 输出:
445
- 行情数据,df,升序排列
446
- """
447
- #设置tushare的token
448
- pro=ts_token()
449
-
450
- #检查期间合理性
451
- result,start,end=check_period(fromdate,todate)
452
- if result is None:
453
- print("Error #1(ts_price_stock): incorrect date or invalid period!")
454
- return None
455
-
456
- #转换输入日期格式
457
- tsstart=cvtdate_yahootots(fromdate)
458
- tsend=cvtdate_yahootots(todate)
459
- #转换etf代码
460
- tsticker=cvtticker_yahootots(etf_code)
461
-
462
- #抓取每日etf净值行情
463
- price=pro.fund_nav(ts_code=tsticker)
464
-
465
- #升序排列
466
- price.sort_values('end_date',ascending=True,inplace=True)
467
-
468
- #转换日期格式,设置日期索引
469
- import pandas as pd
470
- price['date']=pd.to_datetime(price['end_date'])
471
- price.set_index('date',inplace=True)
472
-
473
- #修改列名
474
- price.rename(columns={'ts_code':'Ticker','unit_nav':'Unit-nav', \
475
- 'adj_nav':'Adj-nav'},inplace=True)
476
- price['Ticker']=etf_code
477
-
478
- #提取需要的列
479
- nav=price[['Ticker','Unit-nav']].copy()
480
-
481
- #去掉日期范围以外的数据
482
- nav1=nav[nav.index >= start]
483
- nav2=nav1[nav1.index <= end]
484
-
485
- return nav2
486
-
487
- if __name__ =="__main__":
488
- etf_code='510050.SS'
489
- fromdate='2019-12-11'
490
- todate='2020-02-01'
491
- etf_nav=ts_nav_etf(etf_code,fromdate,todate)
492
-
493
- #==============================================================================
494
- def get_price_etf(etf_code,index_code,fromdate,todate):
495
- """
496
- 功能:获得etf及其对应指数日行情,便于对比业绩
497
- Parameters
498
- ----------
499
- etf_code : ETF代码,雅虎格式
500
- index_code : 指数代码,雅虎格式
501
- fromdate : 开始日期,雅虎格式
502
- todate : 截止日期,雅虎格式
503
- Returns
504
- -------
505
- 日行情价格,etf与指数数据,升序排列
506
- """
507
-
508
- #检查期间合理性
509
- result,start,end=check_period(fromdate,todate)
510
- if result is None:
511
- print("Error #1(get_price_etf): incorrect date or invalid period!")
512
- return None
513
-
514
- #从雅虎财经获得etf日行情
515
- etf=get_price(etf_code,fromdate,todate)
516
- try: etf['Ticker']=etf_code
517
- except:
518
- print("Error #2(get_price_etf): data not found for",etf_code)
519
- return None,None
520
-
521
- #去掉日期范围以外的数据
522
- etf1=etf[etf.index >= start]
523
- etf2=etf1[etf1.index <= end]
524
-
525
- #获得指数日行情
526
- flag1=index_code[0]
527
- flag2=index_code[-3:]
528
- if (flag1 != '^') and ((flag2 == '.SS') or (flag2 == '.SZ')):
529
- #从tushare获得中国大陆指数行情
530
- index=ts_price_index(index_code,fromdate,todate)
531
- else:
532
- #从雅虎财经获得非中国大陆指数行情
533
- index=get_price(index_code,fromdate,todate)
534
-
535
- try: index['Ticker']=index_code
536
- except:
537
- print("Error #3(get_price_etf): data not found for",index_code)
538
- return None,None
539
-
540
- #去掉日期范围以外的数据
541
- index1=index[index.index >= start]
542
- index2=index1[index1.index <= end]
543
-
544
- return etf2,index2
545
-
546
- if __name__ =="__main__":
547
- etf_code='510050.SS'
548
- index_code='000016.SS'
549
- fromdate='2019-12-11'
550
- todate='2020-02-05'
551
- etf_price,index_price=get_price_etf(etf_code,index_code,fromdate,todate)
552
-
553
- #==============================================================================
554
- def compare_price_etf(etf_price,index_price,fromdate,todate):
555
- """
556
- 功能:比较etf与对应指数的收盘价趋势,采用双坐标轴
557
- 输入:
558
- etf_price:抓取到的etf价格序列
559
- index_price:抓取到的指数价格序列
560
- fromdate/todate:开始/结束日期
561
- 输出:折线图,双坐标轴,避免数量级差异过大的问题
562
- """
563
- #检查期间合理性
564
- result,start,end=check_period(fromdate,todate)
565
- if result is None:
566
- print("Error #1(compare_price_etf): incorrect date or invalid period!")
567
- return
568
-
569
- #检查价格序列
570
- if (etf_price is None) or (index_price is None):
571
- print("Error #2(compare_price_etf): incorrect input for either etf or index")
572
- return
573
-
574
- #提取收盘价
575
- p1=etf_price['Close']
576
- try: ticker1=etf_price['Ticker'][0]
577
- except:
578
- print("Error #2(compare_price_etf): no data available for the etf!")
579
- return
580
- p2=index_price['Close']
581
- try: ticker2=index_price['Ticker'][0]
582
- except:
583
- print("Error #3(compare_price_etf): no data available for the index!")
584
- return
585
-
586
- #去掉比起始日期更早的样本
587
- p1b=p1[p1.index >= start]
588
- p2b=p2[p2.index >= start]
589
- #去掉比结束日期更晚的样本
590
- p1c=p1b[p1b.index <= end]
591
- p2c=p2b[p2b.index <= end]
592
-
593
- #绘制折线图,双坐标轴
594
- import matplotlib.pyplot as plt
595
- import matplotlib.dates as mdates
596
- fig = plt.figure()
597
- ax = fig.add_subplot(111)
598
- ax.plot(p1c, '-', label = ticker1, lw=3)
599
-
600
- #自动优化x轴标签,格式化时间轴标注
601
- plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
602
- plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
603
-
604
- #建立第二y轴
605
- ax2 = ax.twinx()
606
- ax2.plot(p2c, 'r:.', label = ticker2, lw=3)
607
- #fig.legend(loc='best', bbox_to_anchor=(1,1), bbox_transform=ax.transAxes)
608
- #fig.legend(loc='best', bbox_transform=ax.transAxes)
609
- #fig.legend(loc='best')
610
-
611
- plt.title("Sync of ETF Price and Index Based", fontsize=15)
612
- ax.set_xlabel("\nSource: Yahoo Finance", fontsize=13)
613
- ax.set_ylabel(ticker1)
614
- ax.legend(loc='upper center')
615
- ax2.legend(loc='lower center')
616
- ax2.set_ylabel(ticker2)
617
- fig.show()
618
-
619
- return
620
-
621
- if __name__ =="__main__":
622
- etf_code='510050.SS'
623
- index_code='000016.SS'
624
- fromdate='2019-7-1'
625
- todate='2020-02-05'
626
- etf_price,index_price=get_price_etf(etf_code,index_code,fromdate,todate)
627
- compare_price_etf(etf_price,index_price,'2019-7-1','2019-12-1')
628
- compare_price_etf(etf_price,index_price,'2019-7-1','2019-8-1')
629
-
630
- #==============================================================================
631
- def get_price_nav_etf(etf_code,fromdate,todate):
632
- """
633
- 功能:获得etf每日二级市场行情以及净值,便于寻找套利机会,限大陆etf
634
- Parameters
635
- ----------
636
- etf_code : ETF代码,雅虎格式
637
- fromdate : 开始日期,雅虎格式
638
- todate : 截止日期,雅虎格式
639
- Returns
640
- -------
641
- etf日二级市场行情价格,etf每日净值,升序排列
642
- """
643
-
644
- #检查期间合理性
645
- result,start,end=check_period(fromdate,todate)
646
- if result is None:
647
- print("Error #1(get_price_nav_etf): incorrect date or invalid period!")
648
- return None
649
-
650
- #从雅虎财经获得etf日行情
651
- etf=get_price(etf_code,fromdate,todate)
652
- etf['Ticker']=etf_code
653
-
654
- #去掉日期范围以外的数据
655
- etf1=etf[etf.index >= start]
656
- etf2=etf1[etf1.index <= end]
657
-
658
- #获得大陆etf每日净值
659
- nav2=ts_nav_etf(etf_code,fromdate,todate)
660
-
661
- return etf2,nav2
662
-
663
- if __name__ =="__main__":
664
- etf_code='510050.SS'
665
- fromdate='2019-1-1'
666
- todate='2020-02-05'
667
- etf_price,etf_nav=get_price_nav_etf(etf_code,fromdate,todate)
668
-
669
- #==============================================================================
670
- def compare_price_nav_etf(etf_price,etf_nav,fromdate,todate):
671
- """
672
- 功能:比较etf二级市场行情与其净值趋势
673
- 输入:
674
- etf_price:抓取到的etf二级市场价格序列
675
- etf_nav:抓取到的etf净值序列
676
- fromdate/todate:开始/结束日期
677
- 输出:折线图
678
- """
679
- #检查期间合理性
680
- result,start,end=check_period(fromdate,todate)
681
- if result is None:
682
- print("Error #1(compare_price_nav_etf): incorrect date or invalid period!")
683
- return
684
-
685
- #提取收盘价
686
- p1=etf_price['Close']
687
- try: ticker1=etf_price['Ticker'][0]+" price"
688
- except:
689
- print("Error #2(compare_price_nav_etf): no data available for the etf price!")
690
- return
691
- p2=etf_nav['Unit-nav']
692
- try: ticker2=etf_nav['Ticker'][0]+" nav"
693
- except:
694
- print("Error #3(compare_price_nav_etf): no data available for the etf nav!")
695
- return
696
-
697
- #去掉比起始日期更早的样本
698
- p1b=p1[p1.index >= start]
699
- p2b=p2[p2.index >= start]
700
- #去掉比结束日期更晚的样本
701
- p1c=p1b[p1b.index <= end]
702
- p2c=p2b[p2b.index <= end]
703
-
704
- #绘制折线图
705
- import matplotlib.pyplot as plt
706
- import matplotlib.dates as mdates
707
-
708
- plt.plot(p1c, '-', label = ticker1, lw=3)
709
- plt.plot(p2c, 'r:.', label = ticker2, lw=3)
710
-
711
- #自动优化x轴标签,格式化时间轴标注
712
- plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
713
- plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
714
-
715
- plt.title("ETF Arbitrage: Market Price vs. Net Asset Value", fontsize=13)
716
- plt.xlabel("\nSource: Yahoo Finance, Sina Finance", fontsize=11)
717
- plt.ylabel('Unit price/net asset value')
718
- plt.legend(loc='best')
719
- plt.show()
720
-
721
- return
722
-
723
- if __name__ =="__main__":
724
- etf_code='510050.SS'
725
- fromdate='2019-8-1'
726
- todate='2019-9-1'
727
- etf_price,etf_nav=get_price_nav_etf(etf_code,fromdate,todate)
728
- compare_price_nav_etf(etf_price,etf_nav,fromdate,todate)
729
-
730
- #==============================================================================
731
- def compare_return_nav_etf(etf_price,etf_nav,fromdate,todate):
732
- """
733
- 功能:比较etf二级市场行情与其净值的收益率
734
- 输入:
735
- etf_price:抓取到的etf二级市场价格序列
736
- etf_nav:抓取到的etf净值序列
737
- fromdate/todate:开始/结束日期
738
- 输出:收益率折线图
739
- """
740
- #检查期间合理性
741
- result,start,end=check_period(fromdate,todate)
742
- if result is None:
743
- print("Error #1(compare_return_nav_etf): incorrect date or invalid period!")
744
- return
745
-
746
- #提取收盘价的收益率
747
- import pandas as pd
748
- cp=etf_price['Close']
749
- r1=cp.pct_change()
750
- r1df=pd.DataFrame(r1)
751
- r1df.columns=['ret']
752
- r1df['ret%']=round(r1df['ret']*100.0,2)
753
- p1=r1df['ret%']
754
- try: ticker1=etf_price['Ticker'][0]+" market return"
755
- except:
756
- print("Error #2(compare_return_nav_etf): no data available for the etf price!")
757
- return
758
-
759
- nv=etf_nav['Unit-nav']
760
- r2=nv.pct_change()
761
- r2df=pd.DataFrame(r2)
762
- r2df.columns=['ret']
763
- r2df['ret%']=round(r2df['ret']*100.0,2)
764
- p2=r2df['ret%']
765
- try: ticker2=etf_nav['Ticker'][0]+" nav gain"
766
- except:
767
- print("Error #3(compare_return_nav_etf): no data available for the etf nav!")
768
- return
769
-
770
- #去掉比起始日期更早的样本
771
- p1b=p1[p1.index >= start]
772
- p2b=p2[p2.index >= start]
773
- #去掉比结束日期更晚的样本
774
- p1c=p1b[p1b.index <= end]
775
- p2c=p2b[p2b.index <= end]
776
-
777
- #绘制折线图
778
- import matplotlib.pyplot as plt
779
- import matplotlib.dates as mdates
780
-
781
- plt.plot(p1c, '-', label = ticker1, lw=3)
782
- plt.plot(p2c, 'r:.', label = ticker2, lw=3)
783
-
784
- #纵轴零线
785
- plt.axhline(y=0.0,color='green',linestyle='--')
786
-
787
- #自动优化x轴标签,格式化时间轴标注
788
- plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m-%d'))
789
- plt.gcf().autofmt_xdate() # 优化标注(自动倾斜)
790
-
791
- plt.title("ETF Arbitrage: Market Return vs. Nav Gain", fontsize=13)
792
- plt.xlabel("\nSource: Yahoo Finance, Sina Finance", fontsize=11)
793
- plt.ylabel('Market return/nav gain(%)')
794
- plt.legend(loc='best')
795
- plt.show()
796
-
797
- return
798
-
799
- if __name__ =="__main__":
800
- etf_code='510050.SS'
801
- fromdate='2019-8-1'
802
- todate='2019-9-1'
803
- etf_price,etf_nav=get_price_nav_etf(etf_code,fromdate,todate)
804
- compare_return_nav_etf(etf_price,etf_nav,fromdate,todate)
805
- #==============================================================================
806
-
807
- #==============================================================================
808
-
809
- #==============================================================================
810
- def get_price_ts(ticker,fromdate,todate,asset='E',freq='D'):
811
- """
812
- 功能:从tushare数据源获得交易数据
813
-
814
- Parameters
815
- ----------
816
- ticker : 资产代码
817
- 包括股票、指数、数字货币、期货、基金、期货、可转债.
818
- fromdate : 开始日期
819
- 格式:YYYY-MM-DD. 注意tushare的格式为YYYYMMDD
820
- todate : 截止日期
821
- 格式:YYYY-MM-DD.
822
- asset : 资产类别, optional
823
- 包括股票(E)、沪深指数(I)、数字货币(C)、期货(FT)、基金(FD)、期权(O)、
824
- 可转债(CB). The default is 'E'.
825
- freq : 频率, optional
826
- 数据频度:支持分钟(min)/日(D)/周(W)/月(M)K线,
827
- 其中1min表示1分钟(类推1/5/15/30/60分钟),默认D.
828
- Returns
829
- -------
830
- 价格行情,数据框,升序排列.
831
- """