import json
import time
import requests
import pandas as pd
class XQ(object):
def __init__(self):
self.headers = {
'authority': 'stock.xueqiu.com',
'accept': '*/*',
'accept-language': 'zh-CN,zh;q=0.9',
'origin': 'https://xueqiu.com',
'referer': 'https://xueqiu.com/S/SZ300911',
'sec-ch-ua': '"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
}
# cookie可以写到redis中
self.cookies = dict()
def set_cookie(self):
req = requests.get("https://xueqiu.com/", headers=self.headers)
self.cookies.update({'xq_a_token': req.cookies.get("xq_a_token")})
def get_stock_detail(self, code: str):
"""
:param code: SZ300911 股票代码
:return:
"""
params = {
# SZ300911
'symbol': code,
'extend': 'detail',
}
response = requests.get('https://stock.xueqiu.com/v5/stock/quote.json', params=params, cookies=self.cookies,
headers=self.headers)
if response.status_code != 200:
self.set_cookie()
response = requests.get('https://stock.xueqiu.com/v5/stock/quote.json', params=params, cookies=self.cookies,
headers=self.headers)
return response.text
def get_hs_rank_percent(self, page: str, size: str, order: str, orderby: str) -> list:
"""
:param page: 页数
:param size: 个数
:param order: 排序的方式 desc asc
:param orderby: 排序的字段
:return:
"""
params = {
'page': page,
'size': size,
'order': order,
'orderby': orderby,
'order_by': orderby,
'market': 'CN',
'type': 'sh_sz',
}
response = requests.get('https://stock.xueqiu.com/v5/stock/screener/quote/list.json', params=params,
cookies=self.cookies, headers=self.headers)
if response.status_code != 200:
self.set_cookie()
response = requests.get('https://stock.xueqiu.com/v5/stock/screener/quote/list.json', params=params,
cookies=self.cookies, headers=self.headers)
all = []
try:
data = json.loads(response.text).get("data").get("list")
for d in data:
all.append(
{"name": d.get("name"), "code": d.get("symbol"), "现价": d.get("current"), "涨幅": d.get("percent"),
"市值/亿": float(d.get("market_capital")) / 10 ** 8, "成交额": d.get("amount"), "成交量/股": d.get("volume"),
"流通股/股": d.get("float_shares"),
"成交量/流通量": d.get("volume") / d.get("float_shares") if d.get("float_shares")!=0 else "新股暂无流通量",
"换手率": d.get("turnover_rate"), "振幅": d.get("amplitude"), "北向流入": d.get("north_net_inflow"),
"年初至今涨幅": d.get("current_year_percent"),
"上市至今涨幅": d.get("total_percent"),
})
except Exception as e:
print("", e)
return all
def get_section_stock(self, symbol: str, begin: str, period: str, count: str, indicator: str):
"""
:param symbol: SZ300813
:param begin: 1669853231808
:param period: period=day || week || month || quarter || year || 120m || 60m
:param count: -10 从开始向前的k线数量
:param indicator: 指标 kline,pe,pb,ps,pcf,market_capital,agt,ggt,balance
:return:
"""
url = "https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=%s&begin=%s&period=%s&type=before&count=%s&indicator=%s"
response = requests.get(url % (symbol, begin, period, count, indicator), cookies=self.cookies,
headers=self.headers)
if response.status_code != 200:
self.set_cookie()
response = requests.get(url % (symbol, begin, period, count, indicator), cookies=self.cookies,
headers=self.headers)
try:
data = json.loads(response.text).get("data")
col = data.get("column")
item = data.get("item")
df = pd.DataFrame(item, columns=col)
return df
except Exception as e:
print("", e)
return pd.DataFrame
if __name__ == '__main__':
xueqiu = XQ()
def sort_rank(rank_type: str, reverse: bool = False) -> list:
"""
涨幅倒序数据再以其他指标 选标的
:param rank_type: 排序字段
:param reverse: 是否倒叙
:return:
"""
turnover_rate = xueqiu.get_hs_rank_percent(page='1', size='300', order='desc', orderby='percent')
return sorted(turnover_rate, key=lambda x: x.get(rank_type) if x.get(rank_type) != None else 0, reverse=reverse)
# 以市值正序
print(sort_rank("市值"))
# 以北向流入倒序 north_net_inflow
print(sort_rank("北向流入", True))
# 以换手率倒序
print(sort_rank("换手率"), True)
# 以年初至今涨幅
print(sort_rank("年初至今涨幅"))
def timestamp(timing: str) -> int:
"""
时间转时间戳
:param timing:
:return:
"""
s_t = time.strptime(timing, "%Y-%m-%d %H:%M:%S")
mkt = int(time.mktime(s_t)) * 1000
return (mkt)
def stp_t(timestamp: int) -> str:
"""
时间戳转时间
:param timestamp:
:return:
"""
# localtime /seconds
timeArray = time.localtime(timestamp / 1000)
otherStyleTime = time.strftime("%Y-%m-%d", timeArray)
return otherStyleTime
# str(timestamp("2022-11-25 00:00:00"))
# 深纺织A nb
res_pd = xueqiu.get_section_stock(symbol='SZ000045', begin=str(int(time.time() * 1000)), period='day',
count='-10', indicator='kline,pe,pb,ps,pcf,market_capital,agt,ggt,balance')
res_pd["timestamp"] = res_pd["timestamp"].map(lambda timestamp: stp_t(timestamp))
def stock_daily_strategy(data: pd.DataFrame)->dict:
# 是否爆量
q_rate = data['volume'].max() / data['volume'].min()
# 量能变化
volume_chg = [i for i in data['volume'].values]
# 换手率变化
turnoverrate_chg = [i for i in data['turnoverrate'].values]
# >=9.6个点涨幅
zt_data = {data['timestamp'][p[0]]: p[1] for p in data['percent'].items() if p[1] >= 9.6}
# 涨跌幅变化
percent_chg = [i for i in data['percent'].values]
# 几个交易日的总的涨跌幅度
percent_sum = data['percent'].sum()
return {"量能变化": volume_chg, "量能max/min": q_rate, "换手率变化": turnoverrate_chg, "涨停数据": zt_data,
"涨跌幅变化": percent_chg, "总的涨跌幅": percent_sum}
print(stock_daily_strategy(res_pd))
10-21
07-24