Code Monkey home page Code Monkey logo

easyquotation's Introduction

easyquotation

Package Travis License

快速获取新浪/腾讯的全市场行情, 网络正常的情况下只需要 200+ms

前言

  • 获取新浪的免费实时行情
  • 获取腾讯财经的免费实时行情
  • 获取集思路的分级基金数据

微信群以及公众号

欢迎大家扫码关注公众号「食灯鬼」,一起交流。进群可通过菜单加我好友,备注量化。

公众号二维码

若二维码因 Github 网络无法打开,请点击公众号二维码直接打开图片。

Author

easyquotation © shidenggui, Released under the MIT License.

Blog @shidenggui · Weibo @食灯鬼 · Twitter @shidenggui

其他作品

requirements

Python 3.6+

pip install -r requirements.txt

安装

pip install easyquotation

也可以下载源码,然后安装

python setup.py install

升级

pip install easyquotation --upgrade

用法

引入:

import easyquotation

选择行情

quotation = easyquotation.use('sina') # 新浪 ['sina'] 腾讯 ['tencent', 'qq'] 

获取所有股票行情

quotation.market_snapshot(prefix=True) # prefix 参数指定返回的行情字典中的股票代码 key 是否带 sz/sh 前缀

return

 {'sh000159': {'name': '国际实业', # 股票名
  'buy': 8.87, # 竞买价
  'sell': 8.88, # 竞卖价
  'now': 8.88, # 现价
  'open': 8.99, # 开盘价
  'close': 8.96, # 昨日收盘价
  'high': 9.15, # 今日最高价
  'low': 8.83, # 今日最低价
  'turnover': 22545048, # 交易股数
  'volume': 202704887.74# 交易金额
  'ask1': 8.88, # 卖一价
  'ask1_volume': 111900, # 卖一量
  'ask2': 8.89,
  'ask2_volume': 54700,
  'bid1': 8.87, # 买一价
  'bid1_volume': 21800, # 买一量
  ...
  'bid2': 8.86, 
  'bid2_volume': 78400,
  'date': '2016-02-19',
  'time': '14:30:00',
  ...},
  ......
}
单只股票
quotation.real('162411') # 支持直接指定前缀,如 'sh000001'
多只股票
quotation.stocks(['000001', '162411']) 
同时获取指数和行情
quotation.stocks(['sh000001', 'sz000001'], prefix=True) 

更新股票代码

easyquotation.update_stock_codes()

选择 jsl(集思路) 行情

quotation = easyquotation.use('jsl') # ['jsl']
设置 cookie (可选)

不设置的话获取相关数据有限制

quotation.set_cookie('从浏览器获取的集思录 Cookie')
获取分级基金信息
quotation.funda() # 参数可选择利率、折价率、交易量、有无下折、是否永续来过滤

quotation.fundb() # 参数如上

对应的分级 A 数据

return

{ 150020:
{'abrate': '5:5',
'calc_info': None,
'coupon_descr': '+3.0%',
'coupon_descr_s': '+3.0%',
'fund_descr': '每年第一个工作日定折,无下折,A不参与上折,净值<1元无定折',
'funda_amount': 178823,
'funda_amount_increase': '0',
'funda_amount_increase_rt': '0.00%',
'funda_base_est_dis_rt': '2.27%',
'funda_base_est_dis_rt_t1': '2.27%',
'funda_base_est_dis_rt_t2': '-0.34%',
'funda_base_est_dis_rt_tip': '',
'funda_base_fund_id': '163109',
'funda_coupon': '5.75',
'funda_coupon_next': '4.75',
'funda_current_price': '0.783',
'funda_discount_rt': '24.75%',
'funda_id': '150022',
'funda_increase_rt': '0.00%',
'funda_index_id': '399001',
'funda_index_increase_rt': '0.00%',
'funda_index_name': '深证成指',
'funda_left_year': '永续',
'funda_lower_recalc_rt': '1.82%',
'funda_name': '深成指A',
'funda_nav_dt': '2015-09-14',
'funda_profit_rt': '7.74%',
'funda_profit_rt_next': '6.424%',
'funda_value': '1.0405',
'funda_volume': '0.00',
'fundb_upper_recalc_rt': '244.35%',
'fundb_upper_recalc_rt_info': '深成指A不参与上折',
'last_time': '09:18:22',
'left_recalc_year': '0.30411',
'lower_recalc_profit_rt': '-',
'next_recalc_dt': '<span style="font-style:italic">2016-01-04</span>',
'owned': 0,
'status_cd': 'N'}>'}}
分级基金套利接口
quotation.fundarb(jsl_username, jsl_password, avolume=100, bvolume=100, ptype='price')
jsl_username: 集思录用户名
jsl_password: 集思路登录密码
avolume: A成交额,单位百万
bvolume: B成交额,单位百万
ptype: 溢价计算方式,price=现价,buy=买一,sell=卖一

return

{
    "165511":{
        'base_fund_id': '165511',                         # 母基金代码
        'AB_price': '现价A/B : 1.008/1.329',
        'a_profit_rt_next': '4.705',
        'a_ratio': 4,
        'abrate': '4:6',
        'apply_fee': '0',
        'apply_fee_tip': '0',
        'apply_sell': '-0.59',
        'asset_ratio': '95%',
        'asset_ratio_last': '99%',
        'asset_ratio_num': '95.00',
        'b_est_val': '1.340',
        'b_gangan': '1.502',
        'b_ratio': 6,
        'base_est_dis_rt': '-0.56%',
        'base_est_val': '1.2073',
        'base_fund_nm': '信诚500',
        'base_lower_recalc_rt': '54.15%',
        'base_nav': '1.1970',
        'base_nav_dt': '2016-04-13',
        'buy1A': '1.007',
        'buy1B': '1.329',
        'buy1_amountA': '0.201',
        'buy1_amountB': '7.123',
        'buy_redeem': '-0.51',
        'calc_info': None,
        'coupon': '0.00%',
        'coupon_next': '4.700',
        'est_dis_rt': '-0.55%',
        'est_time': '2016-04-14 15:10:05',
        'fundA_amount': '6667',
        'fundA_amount_increase': '-51',
        'fundA_amount_increase_rt': '-0.76%',
        'fundA_amount_tip': '2016-04-14 A类总份额6667.000万份,份额增长-0.76%',
        'fundA_id': '150028',
        'fundA_last_dt': '2016-04-14',
        'fundA_last_time': '14:57:02',
        'fundA_nav': '1.0090',
        'fundA_nav_dt': '2016-04-13',
        'fundA_nm': '中证500A',
        'fundA_stock_volume': '28.2446',
        'fundA_stock_volume_tip': 'A类总份额6667.000万份, 成交28万份',
        'fundA_turnover_rt': '0.42%',
        'fundA_volume': '28.46',
        'fundB_amount': 10000.5,
        'fundB_amount_increase': '-76',
        'fundB_amount_tip': '2016-04-14 B类总份额10000万份,份额增长-0.76%',
        'fundB_id': '150029',
        'fundB_last_dt': '2016-04-14',
        'fundB_last_time': '15:00:27',
        'fundB_nav': '1.3220',
        'fundB_nav_dt': '2016-04-13',
        'fundB_nm': '中证500B',
        'fundB_stock_volume': '255.5280',
        'fundB_stock_volume_tip': 'B类总份额10000万份, 成交256万份',
        'fundB_turnover_rt': '2.56%',
        'fundB_volume': '337.24',
        'fund_company_nm': '信诚基金',
        'funda_name_tip': '下期利率:4.70,修正收益率:4.71%',
        'idx_incr_rt': '0.91%',
        'increase_rtA': '-0.10%',
        'increase_rtB': '1.06%',
        'index_id': '399905',
        'index_nm': '中证 500',
        'is_est_val': 1,
        'is_last_nav': 1,
        'lower_recalc_rt': '54.15',
        'maturity_dt': '-',
        'merge_price': '1.2006',
        'min_apply_amount': None,
        'notes': 'http://www.xcfunds.com/funds_2012/165511/fundinfor.shtml\r\n',
        'ownedA': 0,
        'ownedM': 1,
        'priceA': '1.008',
        'priceB': '1.329',
        'real_idx_increase_rt': '0.91',
        'recalc_to': None,
        'redeem_fee': '0.5%',
        'redeem_fee_tip': '0.5%',
        'sell1A': '1.008',
        'sell1B': '1.330',
        'sell1_amountA': '7.132',
        'sell1_amountB': '16.820',
        'status_cd': 'N'
    }
}
指数ETF查询接口

TIP : 尚未包含黄金ETF和货币ETF

集思录ETF源网页

quotation.etfindex(index_id="", min_volume=0, max_discount=None, min_discount=None)

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",        # 估值最后时间(未确定)
    }
}
分数图

腾讯分时图地址

quotation = easyquotation.use("timekline")
data = quotation.real(['603828'], prefix=True)

return

{
   'sh603828': {
        'date': '170721',  #日期 
        'time_data': {
            '201707210930': ['0930', '19.42', '61'], # [时间, 当前价, 上一分钟到这一分钟之间的成交数量]
            '201707210931': ['0931', '19.42','122'], 
            '201707210932': ['0932', '19.43', '123'], 
            '201707210933': ['0933', '19.48', '125'], 
            '201707210934': ['0934', '19.49', '133'], 
            '201707210935': ['0935', '19.48', '161'], 
            ...
    }
}
港股日k线图

腾讯日k线图

import easyquotation
quotation  = easyquotation.use("daykline")
data = quotation.real(['00001','00700'])
print(data)

return

{
    '00001': [
                ['2017-10-09', '352.00', '349.00', '353.00', '348.60', '13455864.00'], # [日期, 今开, 今收, 最高, 最低, 成交量 ]
                ['2017-10-10', '350.80', '351.20', '352.60', '349.80', '10088970.00'],
               ]
    '00700':[
        
    ]           
     }
}
腾讯港股时时行情

腾讯控股时时行情

import easyquotation
quotation = easyquotation.use("hkquote")
data = quotation.real(['00001','00700'])
print(data)
{
    '00001': 
        {
            'stock_code': '00001', # 股票代码
            'lotSize': '"100', # 每手数量
            'name': '长和', # 股票名称
            'price': '97.20', # 股票当前价格
            'lastPrice': '97.75', # 股票昨天收盘价格
            'openPrice': '97.75', # 股票今天开盘价格
            'amount': '1641463.0', # 股票成交量 
            'time': '2017/11/29 15:38:58', # 当前时间
            'high': '98.05', # 当天最高价格
            'low': '97.15' # 当天最低价格
        }, 
    '00700': 
        {
            'stock_code': '00700', 
            'lotSize': '"100',
            'name': '腾讯控股', 
            'price': '413.20', 
            'lastPrice': '419.20', 
            'openPrice': '422.20', 
            'amount': '21351010.0', 
            'time': '2017/11/29 15:39:01', 
            'high': '422.80',
            'low': '412.40'
        }
}

开发指南

初始化环境

进入项目目录后运行

make init

提交代码时通过所有 hooks 检查即可

easyquotation's People

Contributors

asxzy avatar fanwz avatar gavin-huang avatar jingsailu avatar joeyjiao avatar lamter avatar lynic avatar saperpsh avatar shidenggui avatar szhu3210 avatar wangyu190810 avatar xgdgsc avatar z1018143 avatar zhangpf avatar zhengle2008 avatar zheolong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easyquotation's Issues

内存消耗太大

现在的easyquotation,取数据很耗内存,每取一次全场数据就要消耗3M内存,还不会自动释放内存。有没有办法解决内存消耗大的问题?

新浪接口返回数据会错位

新浪的接口有些股票没有数据,会返回以下内容

var hq_str_sz160922="恒生中小,0.000,1.074,0.000,0.000,0.000,1.053,1.110,0,0.000,42000,1.053,7500,1.050,0,0.000,0,0.000,0,0.000,3100,1.110,100,1.130,2900,1.169,12000,1.170,0,0.000,2019-04-08,09:41:45,00";
var hq_str_sz160923="";
var hq_str_sz160924="恒指LOF,0.000,1.095,0.000,0.000,0.000,1.034,1.077,0,0.000,42000,1.034,300,1.031,700,1.009,500,0.992,8000,0.990,400,1.077,900,1.134,9300,1.160,1000,1.196,0,0.000,2019-04-08,09:41:36,00";

而正则没有对这种情况做处理,导致后面的股票顶替了前面股票的行情

    {
 "160923": {
        "name": "\";\nvar hq_str_sz160924=\"\u6052\u6307LOF",
        "open": 0.0,
        "close": 1.095,
        "now": 0.0
}

能否獲得更久以前的港股k線數據

試過設定為一個較大的天數,還是只能拿到三年左右的數據,
想問能拿到例如2010-2011年間的數據嗎,
如果只是沒實現功能,但API設對參數能取得的話我能幫忙改一改

Sina API Naming issue

file: easyquotation/easyquotation/sina.py
stock_dict[stock[0]] = dict(..., turnover=int(stock[9]), volume=float(stock[10]),

turnover => volume
volume => amount

注:
turnover:换手(率)
volume:成交量(股)
amount:成交额(元)

通过实时数据计算k线

请问通过该库查询实时股价,能否做到准确地计算k线数据。
另外问下有没有什么实时计算k线的方式。

代码列表建议添加东财的数据

个人感觉,目前easyquotation通过shdjt获取的代码列表有时候会不够准确,可以考虑再加上东财这个列表,例如今天st长油重新上市,shdjt代码列表中就没有及时更新。(但东财这个列表里面没有指数)

这段代码有缺陷

max_num = 800
....
for range_start in range(request_num):
num_start = self.max_num * range_start
num_end = self.max_num * (range_start + 1)
request_list = ','.join(stock_with_exchange_list[num_start:num_end])
stock_list.append(request_list)

num_start 和num_end 最后将超出 request_num , 也就是说会远超出stock_with_exchange_list的长度。这样结尾拼接的时候,其实你是多出来很多的 ‘,’, 的。

获取所有股票实时行情数据不全

刚刚测试了一下,就发现并不是所有股票啊
比如:300577,300571,603868就没有,和通达信的股票列表对比 少了很多
为什么?可以解决么

sina行情的grep_detail不支持解析股票名称带空格的

比如:

var hq_str_sz000876="新 希 望,20.190,19.980,21.000,21.100,20.100,21.000,21.010,62322585,1294566229.360,227909,21.000,36600,20.990,66891,20.980,30300,20.970,24113,20.960,37300,21.010,41900,21.020,105486,21.030,100500,21.040,118693,21.050,2020-02-14,15:00:03,00";

var hq_str_sz002224="三 力 士,7.640,7.740,7.550,7.970,7.450,7.550,7.560,60848442,467735944.480,307800,7.550,22200,7.540,29300,7.530,68200,7.520,34500,7.510,329700,7.560,141600,7.570,52200,7.580,101214,7.590,140000,7.600,2020-02-14,15:00:03,00";

出现异常

我用了try来执行quotation.all,以免抓取异常退出,但在服务器上执行抓取偶尔会出现如下错误:
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7faee5fb1470>

应该是异常后这里可能没执行到?
https://github.com/shidenggui/easyquotation/blob/master/easyquotation/basequotation.py#L73

查了下aiohttp的issue aio-libs/aiohttp#1175
他似乎是提倡特定的用法,但我看不太懂。

如果长时间稳定的抓取,怎样的方案比较好呢?谢谢

集思路套利接口异常

data=easyquotation.use('jsl').fundarb('_','_',avolume=100,bvolume=100,ptype='price')
集思路套利接口的ptype参数无效,变换参数返回结果是一样的。

获取全部股票时,返回数据不全,原因是

stocks_detail = "".join(rep_data)
grep_str = self.grep_detail_with_prefix if prefix else self.grep_detail
这两句中间要加一句
stocks_detail = stocks_detail.replace(" ","")
否则如果股票名字中有空格,就会被过滤掉

lever_fun取数据的问题

1.aiohttp已经不支持get了,目前是request,aiohttp.request(url=Leverfun.stock_api,params=params,method='GET')
2.两次取一个ID的实时level2,第二次包含第一次的结果,感觉像是bug
if name == 'main':
q = Leverfun()
q.real('000001')
print(q.stocks_dict)
q.real('000005')
print(q.stocks_dict)

第二次print 包含第一次的数据

0.4.3 在取大于800支股票的时候崩溃

下列代码会导致崩溃。测试环境为aiohttp 1.0.5

import easyquotation as eq
sina = eq.use('sina')
print(sina.all)

原因可能是ClientSession的误用,aiohttp的文档中描述了,不应该为每一个请求建立一个session,如URL:

http://aiohttp.readthedocs.io/en/stable/client.html

而0.4.3版的easyquotation的代码在get_stocks_by_range函数中正是这样做的,因此会导致如果请求大于800支股票,产生多个routines的时候崩溃。

一个可能的解决方法是把session设为成员变量。如下:

    async def get_stocks_by_range(self, params):
        headers = {
            'Accept-Encoding': 'gzip'
        }
        async with self._session.get(self.stock_api + params, timeout=5, headers=headers) as r:
            response_text = await r.text()
            return response_text

    def get_stock_data(self, stock_list):
        coroutines = []
        self._session = aiohttp.ClientSession()
        for params in stock_list:
            coroutine = self.get_stocks_by_range(params)
            coroutines.append(coroutine)
        try:
            loop = asyncio.get_event_loop()
        except RuntimeError:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
        res = loop.run_until_complete(asyncio.gather(*coroutines))

        self._session.close()
        return self.format_response_data(res)

新浪多个股票自动encode的问题 可以这么解决

看了下aiohttp的文档. 发现url可以是一个yarl.URL的变量.

import asyncio

import aiohttp
import yarl


# t = easyquotation.use('sina')
# quote = t.all
# print(quote)
async def main():
    async with aiohttp.ClientSession() as c:
        url = yarl.URL('http://hq.sinajs.cn/list=sh601006,sh600000', encoded=True)
        a = await c.get(url)
        print(await a.text())


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

调用分级基金套利接口 quotation.fundarb 返回的不是json

jsl_username = '不吃鸟的虫'
jsl_password = 'xxx'
jsl_quotation.fundarb(jsl_username, jsl_password, avolume=100, bvolume=100, ptype='price')
结果报错了:
Traceback (most recent call last):
File "E:/PythonProject/AutoTrader/AutoTrader/easyquotation_test.py", line 43, in
jsl_quotation.fundarb(jsl_username, jsl_password, avolume=100, bvolume=100, ptype='price')
File "F:\Anaconda3\lib\site-packages\easyquotation\jsl.py", line 301, in fundarb
fundajson = json.loads(rep.text)
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

调试发现联网请求返回的是 html 格式的而不是 json 格式的,导致json 解析异常

查找港股指数数据

def format_response_data(self, rep_data, **kwargs):
    stocks_detail = "".join(rep_data)

    stock_dict = {}
    for raw_quotation in re.findall(r'v_r_hk\d+=".*?"', stocks_detail):
        quotation = re.search('"(.*?)"', raw_quotation).group(1).split("~")
        stock_dict[quotation[2]] = dict(
            lotSize=float(quotation[0]),
            name=quotation[1],
            price=float(quotation[3]),
            lastPrice=float(quotation[4]),
            openPrice=float(quotation[5]),
            amount=float(quotation[6]),
            time=quotation[30],
            dtd=float(quotation[32]),
            high=float(quotation[33]),
            low=float(quotation[34]),
        )

查找指数数据时,因为匹配的是数字r'v_r_hk\d,所以无法读出HSI等指数的数据,建议改为匹配文字
另外可以加入daily return项目dtd=float(quotation[32]),

股票代码重叠时,指定前缀也会导致返回结果部分丢失

譬如我想同时拿到上证指数和平安银行的价格,代码如下,但是返回的数据集中会把stock list中的靠前一个股票给覆盖掉。鉴于上证的指数与深圳的股票代码大量重叠,这不是个例,是否可以改成返回的dict中的key也是带前缀的股票代码?

In[2]: import easyquotation as eq
In[3]: qq = eq.use('qq')
In[4]: b = qq.stocks(['sh000001', 'sz000001'])
In[5]: b
Out[5]:
{'000001': {'PB': 0.87,
'PE': 6.56,
'ask1': 10.25,
'ask1_volume': 239200,
'ask2': 10.26,
'ask2_volume': 552000,
'ask3': 10.27,
'ask3_volume': 582900,
'ask4': 10.28,
'ask4_volume': 289600,
'ask5': 10.29,
'ask5_volume': 441700,
'ask_volume': 8754200.0,
'bid1': 10.24,
'bid1_volume': 242200,
'bid2': 10.23,
'bid2_volume': 223700,
'bid3': 10.22,
'bid3_volume': 594400,
'bid4': 10.21,
'bid4_volume': 710900,
'bid5': 10.2,
'bid5_volume': 1003700,
'bid_volume': 8036600,
'close': 10.27,
'code': '000001',
'datetime': datetime.datetime(2016, 5, 30, 11, 30, 15),
'high': 10.27,
'high_2': 10.27,
'low': 10.2,
'low_2': 10.2,
'name': '平安银行',
'now': 10.24,
'open': 10.25,
'turnover': 0.14,
'unknown': '',
'volume': 16790800.0,
'价格/成交量(手)/成交额': '10.24/165561/169371889',
'总市值': 1465.21,
'成交量(手)': 16790800,
'成交额(万)': 171780000.0,
'振幅': 0.68,
'最近逐笔成交': '11:29:57/10.24/48/S/49152/17511|11:29:54/10.25/6/B/6150/17507|11:29:51/10.25/2083/B/2135075/17496|11:29:48/10.25/1/B/1025/17486|11:29:36/10.25/20/B/20500/17464|11:29:33/10.25/17/B/17425/17458',
'流通市值': 1248.52,
'涨停价': 11.3,
'涨跌': -0.03,
'涨跌(%)': -0.29,
'跌停价': 9.24}}

exception received

Exception in thread Thread-4:
Traceback (most recent call last):
File "C:\Python35\lib\asyncio\selector_events.py", line 664, in _read_ready
data = self._sock.recv(self.max_size)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Python35\lib\site-packages\aiohttp\client.py", line 187, in _request
yield from resp.start(conn, read_until_eof)
File "C:\Python35\lib\site-packages\aiohttp\client_reqrep.py", line 606, in start
message = yield from httpstream.read()
File "C:\Python35\lib\site-packages\aiohttp\streams.py", line 591, in read
result = yield from super().read()
File "C:\Python35\lib\site-packages\aiohttp\streams.py", line 446, in read
yield from self._waiter
File "C:\Python35\lib\asyncio\futures.py", line 358, in iter
yield self # This tells Task to wait for completion.
File "C:\Python35\lib\asyncio\tasks.py", line 290, in _wakeup
future.result()
File "C:\Python35\lib\asyncio\futures.py", line 274, in result
raise self._exception
aiohttp.errors.ServerDisconnectedError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Python35\lib\threading.py", line 914, in _bootstrap_inner
self.run()
File "C:\Python35\lib\threading.py", line 862, in run
self._target(_self._args, *_self._kwargs)
File "C:\wenjie\workspace\playAll\myEasyTrader\easyquant\push_engine\base_engine.py", line 30, in push_quotation
response_data = self.fetch_quotation()
File "C:\wenjie\workspace\playAll\myEasyTrader\easyquant\push_engine\quotation_engine.py", line 16, in fetch_quotation
return self.source.all
File "C:\wenjie\workspace\playAll\myEasyTrader\easyquotation\basequotation.py", line 38, in all
return self.get_stock_data(self.stock_list)
File "C:\wenjie\workspace\playAll\myEasyTrader\easyquotation\basequotation.py", line 62, in get_stock_data
res = loop.run_until_complete(asyncio.gather(*coroutines))
File "C:\Python35\lib\asyncio\base_events.py", line 337, in run_until_complete
return future.result()
File "C:\Python35\lib\asyncio\futures.py", line 274, in result
raise self._exception
File "C:\Python35\lib\asyncio\tasks.py", line 241, in _step
result = coro.throw(exc)
File "C:\wenjie\workspace\playAll\myEasyTrader\easyquotation\basequotation.py", line 48, in get_stocks_by_range
async with aiohttp.get(self.stock_api + params) as r:
File "C:\Python35\lib\site-packages\aiohttp\client.py", line 538, in aenter
self._resp = yield from self._coro
File "C:\Python35\lib\site-packages\aiohttp\client.py", line 194, in _request
raise aiohttp.ClientResponseError() from exc
aiohttp.errors.ClientResponseError

Regular match bug in sina api

有些股票名称中有空格,正则匹配时会出bug。例如sz000002股票新浪api返回结果是

var hq_str_sz000002="万 科A,26.850,26.920,26.700,27.070,26.700,26.700,26.710,20014595,537589152.850,189399,26.700,18400,26.690,47300,26.680,6000,26.670,66800,26.660,800,26.710,12600,26.720,5000,26.730,2000,26.740,22000,26.750,2019-05-31,15:00:03,00";

得到的是“万 科A”,导致结果出错。一个比较丑陋的方式是去除返回字符串中的空格,在basequotation.py中作如下修改。

return [re.sub(r'\s', "", d) for d in res if d is not None]

关于调用all越来越慢的问题

本人反复做过测试,发现all越来越慢,后来发现stock_data数组每次都没有清空,而后来却又append下次数据,导致需要处理的数据越来越多,需要在all函数开始的地方或者get_stock_data函数开始的地方加入del stock_data[:],本人为了移植到2.7修改了源代码,改成了多进程版,原版应该也有这个问题

获取港股信息出现错误

按照Readme.md中最后一部分,获取腾讯股票的信息,结果报错

>>> import easyquotation
>>> quotation = easyquotation.use("hkquote")
>>> data = quotation.get_stock_data(stock_list=['00001','00700'])
('00700',)
http://sqt.gtimg.cn/utf8/q=r_hk00700
('00001',)
http://sqt.gtimg.cn/utf8/q=r_hk00001
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda3\lib\site-packages\easyquotation\hkqoute.py", line 90, in get_stock_data
    res = loop.run_until_complete(asyncio.gather(*coroutines))
  File "C:\Anaconda3\lib\asyncio\base_events.py", line 467, in run_until_complete
    return future.result()
  File "C:\Anaconda3\lib\asyncio\futures.py", line 294, in result
    raise self._exception
  File "C:\Anaconda3\lib\asyncio\tasks.py", line 240, in _step
    result = coro.send(None)
  File "C:\Anaconda3\lib\site-packages\easyquotation\hkqoute.py", line 72, in get_stocks_by_range
    async with self._session.get(url, timeout=10, headers=headers) as r:
AttributeError: __aexit__

在apscheduler添加easyquotation的job, 运行10秒后出错

如果不使用apscheduler单独运行这个函数是没有问题的,可以不断循环执行, 但是在使用apscheduler进行计划任务的时候, 调用第三次这个函数就会出现如下错误, 排查不了,还希望作者帮忙解决.

log如下

2017-05-14 13:11:31 INFO - Job "open_limit_up_buy_job (trigger: cron[year=''
, month='
', day='', week='', day_of_week='', hour='', minute='', second='
/1'], next run at: 2017-05-14 13:11:32 CST)" executed successfully
2017-05-14 13:11:32 INFO - Running job "open_limit_up_buy_job (trigger: cron[
year='', month='', day='', week='', day_of_week='', hour='', minute='', s
econd='
/1'], next run at: 2017-05-14 13:11:32 CST)" (scheduled at 2017-05-14 13
:11:32+08:00)
2017-05-14 13:11:32 INFO - now 29.18!= open28.45
2017-05-14 13:11:32 INFO - now 28.89!= open28.04
2017-05-14 13:11:32 INFO - now 18.95!= open18.3
2017-05-14 13:11:32 INFO - Job "open_limit_up_buy_job (trigger: cron[year=''
, month='
', day='', week='', day_of_week='', hour='', minute='', second='
/1'], next run at: 2017-05-14 13:11:33 CST)" executed successfully
2017-05-14 13:11:33 INFO - Running job "open_limit_up_buy_job (trigger: cron[
year='', month='', day='', week='', day_of_week='', hour='', minute='', s
econd='
/1'], next run at: 2017-05-14 13:11:33 CST)" (scheduled at 2017-05-14 13
:11:33+08:00)
2017-05-14 13:11:33 ERROR - Job "open_limit_up_buy_job (trigger: cron[year=''
, month='
', day='', week='', day_of_week='', hour='', minute='', second='
/1'], next run at: 2017-05-14 13:11:34 CST)" raised an exception
Traceback (most recent call last):
File "C:\Program Files\Anaconda3\lib\site-packages\apscheduler\executors\base.
py", line 125, in run_job
retval = job.func(*job.args, **job.kwargs)
File "C:\Miico\jobs\open_limit_up_buy_job.py", line 41, in call
prices = quotation.stocks(self.watching_list)
File "C:\Program Files\Anaconda3\lib\site-packages\easyquotation\basequotation
.py", line 59, in stocks
return self.get_stock_data(stock_list)
File "C:\Program Files\Anaconda3\lib\site-packages\easyquotation\basequotation
.py", line 114, in get_stock_data
res = loop.run_until_complete(asyncio.gather(*coroutines))
File "C:\Program Files\Anaconda3\lib\asyncio\base_events.py", line 387, in run
_until_complete
return future.result()
File "C:\Program Files\Anaconda3\lib\asyncio\futures.py", line 274, in result
raise self._exception
File "C:\Program Files\Anaconda3\lib\asyncio\tasks.py", line 239, in _step
result = coro.send(None)
File "C:\Program Files\Anaconda3\lib\site-packages\easyquotation\basequotation
.py", line 96, in get_stocks_by_range
async with self._session.get(url, timeout=10, headers=headers) as r:
File "C:\Program Files\Anaconda3\lib\site-packages\aiohttp\client.py", line 62
6, in aenter
self._resp = yield from self._coro
File "C:\Program Files\Anaconda3\lib\site-packages\aiohttp\client.py", line 20
8, in _request
with timer:
File "C:\Program Files\Anaconda3\lib\site-packages\aiohttp\helpers.py", line 6
80, in enter
raise RuntimeError('Timeout context manager should be used '
RuntimeError: Timeout context manager should be used inside a task

获取数据超时

对获取超时没有做异常处理,网络不稳定的情况下会抛出exception。

Traceback (most recent call last):
  File "crawler.py", line 16, in <module>
    data = quotation.all
  File "/usr/local/lib/python3.5/site-packages/easyquotation/basequotation.py", line 39, in all
    return self.get_stock_data(self.stock_list)
  File "/usr/local/lib/python3.5/site-packages/easyquotation/basequotation.py", line 68, in get_stock_data
    res = loop.run_until_complete(asyncio.gather(*coroutines))
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/base_events.py", line 387, in run_until_complete
    return future.result()
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/futures.py", line 274, in result
    raise self._exception
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/tasks.py", line 241, in _step
    result = coro.throw(exc)
  File "/usr/local/lib/python3.5/site-packages/easyquotation/basequotation.py", line 52, in get_stocks_by_range
    async with self._session.get(self.stock_api + params, timeout=0.1, headers=headers) as r:
  File "/usr/local/lib/python3.5/site-packages/aiohttp/client.py", line 565, in __aenter__
    self._resp = yield from self._coro
  File "/usr/local/lib/python3.5/site-packages/aiohttp/client.py", line 198, in _request
    conn = yield from self._connector.connect(req)
  File "/usr/local/lib/python3.5/site-packages/async_timeout/__init__.py", line 44, in __exit__
    raise asyncio.TimeoutError from None
concurrent.futures._base.TimeoutError
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x10de2d9b0>

timeKline 不能用

看了下,是stock_api 的地址问题,改了下就可以了。当然我这么改会影响其它接口...
_20180425130033
_20180425130039

腾讯分时数据,一次可以查询几支股票?

你好,
请问,为什么一次只能得到前四支股票数据
import easyquotation
quotation = easyquotation.use("timekline")
codelist=['600220', '000533', '002400', '002077','000565','000009','002179']
data = quotation.real(codelist, prefix=False)
print(data.keys())

是不是调用太频繁,需要time.sleep( )之类的?

使用获取所有行情的接口market_snapshot()一直报ClientPayloadError,单只股票的没问题

使用的腾讯财经数据源
quotation = easyquotation.use('tencent')
quotation.market_snapshot()

以下是错误堆栈:
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/apscheduler/executors/base.py", line 125, in run_job
retval = job.func(*job.args, **job.kwargs)
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/quote/tasks/quote_server.py", line 83, in real_time
print(quotation.market_snapshot())
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/easyquotation/basequotation.py", line 85, in market_snapshot
return self.get_stock_data(self.stock_list, prefix=prefix)
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/easyquotation/basequotation.py", line 113, in get_stock_data
res = loop.run_until_complete(asyncio.gather(*coroutines))
File "/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 466, in run_until_complete
return future.result()
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/easyquotation/basequotation.py", line 97, in get_stocks_by_range
response_text = await r.text()
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/aiohttp/client_reqrep.py", line 773, in text
yield from self.read()
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/aiohttp/client_reqrep.py", line 746, in read
self._content = yield from self.content.read()
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/aiohttp/streams.py", line 607, in read
return (yield from super().read(n))
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/aiohttp/streams.py", line 323, in read
block = yield from self.readany()
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/aiohttp/streams.py", line 623, in readany
return (yield from super().readany())
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/aiohttp/streams.py", line 340, in readany
yield from self._wait('readany')
File "/Users/zzhoo8/Projects/x/galaxy/rose/rose-quote/venv/lib/python3.6/site-packages/aiohttp/streams.py", line 259, in _wait
yield from waiter
aiohttp.client_exceptions.ClientPayloadError: Response payload is not completed

单只股票返回的name多了个双引号

import easyquotation
quotation = easyquotation.use('sina')
stock_name = quotation.real(162411)['162411']['name']
print(stock_name)

Output:
"华宝油气

用新浪数据源,返回的股票名左边多了一个双引号。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.