diff --git a/README.md b/README.md index 9140f1a..334906c 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,12 @@ quotation = easyquotation.use('tencent') # or qq quotation.all ``` +#### 更新股票代码 + +``` +easyquotation.update_stock_codes() +``` + #### 选择 leverfun 免费十档行情 ``` @@ -205,8 +211,42 @@ ptype: 溢价计算方式,price=现价,buy=买一,sell=卖一 对应的分级 A 数据 -#### 更新股票代码 + +##### 指数ETF查询接口 + +**TIP :** 尚未包含黄金ETF和货币ETF + +*[集思录ETF源网页](https://www.jisilu.cn/data/etf/#tlink_2)* ``` -easyquotation.update_stock_codes() +quotation.etfindex() ``` + +**return** + +``` +{ + "510050": { + "fund_id": "510050", # 代码 + "fund_nm": "50ETF", # 名称 + "price": "2.066", # 现价 + "increase_rt": "0.34%", # 涨幅 + "volume": "71290.96", # 成交额(万元) + "index_nm": "上证50", # 指数 + "pe": "9.038", # 指数PE + "pb": "1.151", # 指数PB + "index_increase_rt": "0.45%", # 指数涨幅 + "estimate_value": "2.0733", # 估值 + "fund_nav": "2.0730", # 净值 + "nav_dt": "2016-03-11", # 净值日期 + "discount_rt": "-0.34%", # 溢价率 + "creation_unit": "90", # 最小申赎单位(万份) + "amount": "1315800", # 份额 + "unit_total": "271.84", # 规模(亿元) + "index_id": "000016", # 指数代码 + "last_time": "15:00:00", # 价格最后时间(未确定) + "last_est_time": "23:50:02", # 估值最后时间(未确定) + } +} +``` + diff --git a/easyquotation/jsl.py b/easyquotation/jsl.py index 5805f72..50a90a9 100644 --- a/easyquotation/jsl.py +++ b/easyquotation/jsl.py @@ -23,6 +23,12 @@ class Jsl(object): # 集思录登录接口 __jxl_login_url = 'http://www.jisilu.cn/account/ajax/login_process/' + # 集思录 ETF 接口 + __etf_index_url = "https://www.jisilu.cn/jisiludata/etf.php?___t={ctime:d}" + # 黄金 ETF , 货币 ETF 留坑,未完成 + __etf_gold_url = "https://www.jisilu.cn/jisiludata/etf.php?qtype=pmetf&___t={ctime:d}" + __etf_money_url = "https://www.jisilu.cn/data/money_fund/list/?___t={ctime:d}" + # 分级A数据 # 返回的字典格式 # { 150022: @@ -86,6 +92,26 @@ def formatfundbjson(fundbjson): d[fundb_id] = cell return d + @staticmethod + def formatetfindexjson(fundbjson): + """格式化集思录返回 指数ETF 的json数据,以字典形式保存""" + d = {} + for row in fundbjson['rows']: + cell = row['cell'] + fundb_id = cell['fund_id'] + d[fundb_id] = cell + return d + + + @staticmethod + def percentage2float(per): + """ + 将字符串的百分数转化为浮点数 + :param per: + :return: + """ + return float(per.strip('%')) / 100. + def funda(self, fields=[], min_volume=0, min_discount=0, ignore_nodown=False, forever=False): """以字典形式返回分级A数据 :param fields:利率范围,形如['+3.0%', '6.0%'] @@ -186,3 +212,61 @@ def fundarb(self, jsl_username, jsl_password, avolume=100, bvolume=100, ptype='p self.__fundarb = data return self.__fundarb + + + def etfindex(self, index_id="", min_volume=0, max_discount=None, min_discount=None): + """ + 以字典形式返回 指数ETF 数据 + :param index_id: 获取指定的指数 + :param min_volume: 最小成交量 + :param min_discount: 最低溢价率, 适用于溢价套利, 格式 "-1.2%", "-1.2", -0.012 三种均可 + :param max_discount: 最高溢价率, 适用于折价套利, 格式 "-1.2%", "-1.2", -0.012 三种均可 + :return: {"fund_id":{}} + """ + # 添加当前的ctime + self.__etf_index_url = self.__etf_index_url.format(ctime=int(time.time())) + # 请求数据 + rep = requests.get(self.__etf_index_url) + # 获取返回的json字符串, 转化为字典 + etfJson = rep.json() + + # 格式化返回的json字符串 + data = self.formatetfindexjson(etfJson) + + # 过滤 + if index_id: + # 指定跟踪的指数代码 + data = {fund_id: cell for fund_id, cell in data.items() if cell["index_id"] == index_id} + if min_volume: + # 过滤小于指定交易量的数据 + data = {fund_id: cell for fund_id, cell in data.items() if float(cell["volume"]) >= min_volume} + if min_discount: + # 指定最小溢价率 + if isinstance(min_discount, str): + if min_discount.endswith("%"): + # 如果是字符串形式,先转为浮点形式 + min_discount = self.percentage2float(min_discount) + else: + min_discount = float(min_discount) / 100. + data = {fund_id: cell for fund_id, cell in data.items() if self.percentage2float(cell["discount_rt"]) >= min_discount} + if max_discount: + # 指定最大溢价率 + if isinstance(max_discount, str): + if max_discount.endswith("%"): + # 如果是字符串形式,先转为浮点形式 + max_discount = self.percentage2float(max_discount) + else: + max_discount = float(max_discount) / 100. + data = {fund_id: cell for fund_id, cell in data.items() if self.percentage2float(cell["discount_rt"]) <= max_discount} + + self.__etfindex = data + return self.__etfindex + + +if __name__ == "__main__": + Jsl().etfindex( + index_id="000016", + min_volume=0, + max_discount="-0.4", + min_discount="-1.3%" + ) \ No newline at end of file