最近開始玩股票量化,由于想要做完整的股票回測,是以股票的上市和退市資訊就必不可少。因為我們回測的時候必須要知道某一日期滬深股票的成分包含哪些對吧。是以我們要把滬深全部股票的上市時間、退市時間全部都爬下來(儲存到本地以後檢索會更快)。
最近開始玩股票量化,由于想要做完整的股票回測,是以股票的上市和退市資訊就必不可少。因為我們回測的時候必須要知道某一日期滬深股票的成分包含哪些對吧。是以我們要把滬深全部股票的上市時間、退市時間全部都爬下來(儲存到本地以後檢索會更快)。
0.1.确認主要工具
要用到的工具包括:
(1)python:基本工具
(2)pandas:格式化資料處理
(3)通聯資料接口:http://www.datayes.com
(4)通聯接口API:https://api.wmcloud.com/docs/pages/viewpage.action?pageId=1867781
1.開始擷取資料
首先,我們先要擷取全部上市公司的上市時間和退市時間(如果有)的清單,用通聯資料的接口會發現我們的任務非常簡單。
from pandas import DataFrame
from dataapiclient import Client
import json
client = Client()
client.init('cae5c4acc4ad4ccb93a8aaac4b8adb04363feaa9852c34d14ddd2248613b09b3')
url='/api/equity/getEqu.json?field=ticker,secShortName,listDate,delistDate&listStatusCD=L,S,DE,UN&secID=&ticker=&equTypeCD=A'
code, result = client.getData(url)
j = json.loads(result.decode())
d = DataFrame(j['data'])
d = d.set_index('ticker')
d = d[['secShortName','listDate','delistDate']]
d.to_csv('data/ticker_and _day_of_(de)list_date.csv')
如此一來,ticker_and _day_of_(de)list_date.csv檔案中就儲存了所需内容。需要注意的是資料中有個特例:DY600019
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yM2YDO4UTN4ITMtADOxgTMxMTNxUDM2AjNxAjMtcTO0EDO08CX2AjNxAjMvw1N5QTM4QzLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
這是由于當時的重組并購導緻主體變更,是以通聯資料在股票代碼前加上了DY字首以示差別。
然後為了友善的擷取曆史某一時刻全部可交易的A股股票代碼,我們定義一個函數,預設使用本地資料:get_a_stocks(date=None, update=False),date預設日期是系統目前日期,update表示是否需要更新本地資料。檔案名beefinance.py
from pandas import DataFrame
from datetime import datetime
from dataapiclient import Client
import pandas
import json
import os
import types
import datetime
import time
def get_a_stocks(date=None, update=False):
if date is None:
date = datetime.datetime.now()
if isinstance(date,str):
date = datetime.datetime.strptime(date, "%Y-%m-%d")
if not isinstance(date,datetime.datetime):
raise ValueError('date不接受此類型')
if not isinstance(update, bool):
raise ValueError('update不接受此類型')
data_dir = u'data'
data_filename = data_dir + u'/ticker_and _day_of_(de)list_date.csv'
if not os.path.exists(data_dir):
os.mkdir(data_dir)
if (not os.path.exists(data_filename)) or update:
client = Client()
client.init('cae5c4acc4ad4ccb93a8aaac4b8adb04363feaa9852c34d14ddd2248613b09b3')
url='/api/equity/getEqu.json?field=ticker,secShortName,listDate,delistDate&listStatusCD=L,S,DE,UN&secID=&ticker=&equTypeCD=A'
code, result = client.getData(url)
j = json.loads(result.decode())
d = DataFrame(j['data'])
d = d.set_index('ticker')
d = d[['secShortName','listDate','delistDate']]
d.to_csv(data_filename, encoding='utf-8')
d['listDate'] = pandas.to_datetime(d['listDate'])
d['delistDate'] = pandas.to_datetime(d['delistDate'])
d = d[d['listDate']<=date]
d1 = d[pandas.isnull(d['delistDate'])]
d2 = d[pandas.notnull(d['delistDate'])]
d2 = d2[d2['delistDate']>date]
d = d1.append(d2)
return d
else:
d = pandas.read_csv(data_filename, index_col='ticker', parse_dates=['listDate','delistDate'],encoding='utf-8')
d['listDate'] = pandas.to_datetime(d['listDate'])
d['delistDate'] = pandas.to_datetime(d['delistDate'])
d = d[d['listDate']<=date]
d1 = d[pandas.isnull(d['delistDate'])]
d2 = d[pandas.notnull(d['delistDate'])]
d2 = d2[d2['delistDate']>date]
d = d1.append(d2)
return d
下面測試效果:
from beefinance import get_a_stocks
d = get_a_stocks('2010-05-05')
print(d)
data/ticker_and _day_of_(de)list_date.csv
secShortName listDate delistDate
ticker
000001 平安銀行 1991-04-03 NaT
000002 萬科A 1991-01-29 NaT
000004 國農科技 1991-01-14 NaT
000005 世紀星源 1990-12-10 NaT
000006 深振業A 1992-04-27 NaT
000007 全新好 1992-04-13 NaT
000008 神州高鐵 1992-05-07 NaT
000009 中國寶安 1991-06-25 NaT
000010 美麗生态 1995-10-27 NaT
000011 深物業A 1992-03-30 NaT
000012 南玻A 1992-02-28 NaT
000014 沙河股份 1992-06-02 NaT
000016 深康佳A 1992-03-27 NaT
000017 深中華A 1992-03-31 NaT
000018 神州長城 1992-06-16 NaT
000019 深深寶A 1992-10-12 NaT
000020 深華發A 1992-04-28 NaT
000021 深科技 1994-02-02 NaT
000022 深赤灣A 1993-05-05 NaT
000023 深天地A 1993-04-29 NaT
000025 特力A 1993-06-21 NaT
000026 飛亞達A 1993-06-03 NaT
000027 深圳能源 1993-09-03 NaT
000028 國藥一緻 1993-08-09 NaT
000029 深深房A 1993-09-15 NaT
000030 富奧股份 1993-09-29 NaT
000031 中糧地産 1993-10-08 NaT
000032 深桑達A 1993-10-28 NaT
000033 *ST新都 1994-01-03 NaT
000034 神州數位 1994-05-09 NaT
... ... ... ...
601899 紫金礦業 2008-04-25 NaT
601918 *ST新集 2007-12-19 NaT
601919 中國遠洋 2007-06-26 NaT
601939 建設銀行 2007-09-25 NaT
601958 金钼股份 2008-04-17 NaT
601988 中國銀行 2006-07-05 NaT
601989 中國重工 2009-12-16 NaT
601991 大唐發電 2006-12-20 NaT
601998 中信銀行 2007-04-27 NaT
601999 出版傳媒 2007-12-21 NaT
000024 招商地産 1993-06-07 2015-12-30
000522 白雲山A 1993-11-08 2013-04-26
000527 美的電器 1993-11-12 2013-09-18
000562 宏源證券 1994-02-02 2015-01-26
000578 鹽湖集團 1995-03-03 2011-03-22
000594 國恒退 1996-03-20 2015-07-13
000602 金馬集團 1996-08-19 2013-08-14
000787 *ST創智 1997-06-26 2013-02-08
000805 *ST炎黃 1998-05-29 2013-03-27
600087 退市長油 1997-06-12 2014-06-05
600102 萊鋼股份 1997-08-28 2012-02-28
600253 天方藥業 2000-12-27 2013-07-15
600263 路橋建設 2000-07-25 2012-03-01
600553 太行水泥 2002-08-22 2011-02-18
600631 百聯股份 1993-02-19 2011-08-23
600656 退市博元 1990-12-19 2016-05-13
600832 東方明珠 1994-02-24 2015-05-20
600991 廣汽長豐 2004-06-14 2012-03-20
601268 *ST二重 2010-02-02 2015-05-21
601299 中國北車 2009-12-29 2015-05-20
[1815 rows x 3 columns]
還不錯。