繁簡切換您正在訪問的是FX168財經網,本網站所提供的內容及信息均遵守中華人民共和國香港特別行政區當地法律法規。

FX168财经网>人物频道>帖子

懒人风格:将自己的持仓股票或选股,添加到雪球自选股列表

作者/jjdsad 2019-05-10 05:59 0 来源: FX168财经网人物频道

想要观察 策略选股,或持仓股票,以前经常手动添加到APP的自选股列表。
而策略又经常调仓,累啊,于是发扬懒人风格。想办法自动同步策略的持仓到APP里去。
参考了一下easytrader,决定同步到雪球自选股里去
为啥是雪球,纯粹是因为程序容易写,同花顺和腾讯自选股的登录一堆加密,不想整。
具体看研究

import requests
import json
import time


def get_unix_time():
    return int(time.time())

def chang_xq_stocks(stock):
    stock = stock.upper()
    if stock[:2] in ['SH', 'SZ']:
        return stock
    return ('SH' + stock[:6] if stock[-4:] == 'XSHG'    #聚宽代码
            else 'SZ' + stock[:6] if stock[-4:] == 'XSHE'
            else 'SH' + stock if int(stock[0]) >= 5 # 纯股票代码
            else 'SZ' + stock
            )
    
# 雪球自选股操作类
class XqStocks(object):
    def __init__(self, **kwargs):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0',
            'Host': 'xueqiu.com',
            'Pragma': 'no-cache',
            'Connection': 'keep-alive',
            'Accept': '*/*',
            'Accept-Encoding': 'gzip,deflate,sdch',
            'Cache-Control': 'no-cache',
            'Referer': 'https://xueqiu.com/portfolios',
            'X-Requested-With': 'XMLHttpRequest',
            'Accept-Language': 'zh-CN,zh;q=0.5',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        }
        self.session = requests.Session()
        self.session.headers.update(headers)
        if 'proxy_ip' in kwargs:
            s = "%s:%s" % (kwargs['proxy_ip'], kwargs.get('proxy_port',808))
            if 'proxy_user' in kwargs and 'proxy_pwd' in kwargs:
                s = '%s:%s@%s' % (kwargs['proxy_user'], kwargs['proxy_pwd'], s)
            self.session.proxies = {
                "http": "http://" + s,
                "https": "https://" + s,
            }
        self.account_config = kwargs
        self.config = {
            'login_api': 'https://xueqiu.com/user/login',
            'stocks': 'https://xueqiu.com/v4/stock/portfolio/stocks.json?size=1000&pid=%d&category=%s&type=%s',
            'poster': 'https://xueqiu.com/service/poster',
            'group_list': 'https://xueqiu.com/v4/stock/portfolio/list.json?system=true'
        }
        self.group_infos = {}
        self.defalut_group_name = kwargs.get('group_name', '')
        self.defalut_group_info = {
             'category': 2,
             'type': 1,
             'id': -1,
             'name': ''
        }
        self.is_logon = False

    # 登录并获取分组信息
    def login(self):
        login_post_data = {
            'username': self.account_config.get('username', ''),
            'areacode': '86',
            'telephone': self.account_config['account'],
            'remember_me': '0',
            'password': self.account_config['password']
        }
        login_response = self.session.post(self.config['login_api'], data=login_post_data)
        login_status = json.loads(login_response.text)
        if 'error_description' in login_status:
            return False
        self.update_group_infos()
        self.is_logon = True
        return True

    # 获取一个分组名的信息dict
    def get_group_params(self, group_name):
        if group_name is None:
            group_name = self.defalut_group_name
        if isinstance(group_name,str):
            group_name = group_name.decode('utf-8')
        if group_name != '':
            if group_name not in self.group_infos.keys():
                self.create_group(group_name)  # 创建分组
                self.update_group_infos()  # 更新分组信息
                if group_name not in self.group_infos.keys():
                    return self.defalut_group_info
        return self.group_infos.get(group_name, self.defalut_group_info)

    # 获取一个分组下的自选股
    def get_stocks(self, group_name=None):
        d = self.get_group_params(group_name)
        stocks = self.session.get(self.config['stocks'] % (
            d.get('id', -1), d.get('category', 1), d.get('type', 1))).text
        stocks = json.loads(stocks)[u'stocks']
        return [x['code'] for x in stocks if (x['exchange'] == 'SH') or (x['exchange'] == 'SZ')]

    # 更新分组信息
    def update_group_infos(self):
        res = self.session.get(self.config['group_list']).text
        res = json.loads(res)[u'portfolios']
        self.group_infos = {}
        for p in res:
            self.group_infos[p['name']] = {'category': p['portfolio']['category'],
                                           'type': p['type'],
                                           'id': p['id'],
                                           'name': p['name']}

    # 创建一个分组
    def create_group(self, group_name):
        post_data = {
            'data[_]': get_unix_time(),
            'data[pname]': group_name,
            'url': '/stock/portfolio/create.json'
        }
        res = self.session.post(self.config['poster'], data=post_data).text
        return json.loads(res)['success']

    # 删除一个分组下的股票 group_name=None时,用参数里的默认分组。==''时为不分组添加
    def del_stock(self, stock, group_name=None):
        post_data = {
            'data[_]': get_unix_time(),
            'data[code]': stock,
            'url': '/stock/portfolio/delstock.json'
        }
        d = self.get_group_params(group_name)
        if d.get('name', '') != '':
            post_data['data[pname]'] = d.get('name', '')
            post_data['data[pids]'] = d.get('type', '')
        res = self.session.post(self.config['poster'], data=post_data).text
        return json.loads(res)['success']

    # 向一个分组下添加股票
    def add_stock(self, stock, group_name=None):
        post_data = {
            'data[_]': get_unix_time(),
            'data[code]': stock,
            'data[isnotice]': 1,
            'data[targetpercent]': 7,
            'url': '/stock/portfolio/addstock.json'
        }
        d = self.get_group_params(group_name)
        if d.get('name', '') != '':
            post_data['data[pnames]'] = d.get('name', '')
            post_data['data[pids]'] = d.get('type', '')
        res = self.session.post(self.config['poster'], data=post_data).text
        return json.loads(res)['success']

    def sync(self, stocks, group_name=None):
        """
        同步一个自选股列表到雪球自选股
        :param stocks: 雪球格式的自选股列表
        :param group_name: 雪球自选股分组名(不存在则自动创建)
        :return: 成功返回 '' 失败返回错误信息
        """
        try:
            if not self.is_logon:
                if not self.login():
                    return u'登录雪球错误'
            stocks = [chang_xq_stocks(x) for x in stocks] # 转成雪球的股票代码列表
            old_s = self.get_stocks(group_name) # 获取雪球分组自选股列表            
            for stock in [x for x in old_s if x not in stocks]:
                self.del_stock(stock, group_name)
            for stock in [x for x in stocks if x not in old_s]:
                self.add_stock(stock, group_name)
            return ''
        except Exception as e:
            return (u'同步雪球错误: %s' % str(e))
# 创建对象
xq = XqStocks(user_name='' # 用户名,一般为''
              , account='XXXXXXXXX' # 登录帐号,一般为手机号
              , password='XXXXXX' # 密码
              , group_name='测试' # 默认操作的自选股的分组名,默认为''
#               , proxy_ip='XXX.XXX.XXX.XXX' # http代码的IP # 不用代理可以不写
#               , proxy_port='808'  # http代理的端口
#               , proxy_user='' # 代理用户名,无需登录的用户名可以不写
#               , proxy_pwd='' # 代理密码
             )
# 单独测试
if not xq.login():
    print '登录错误'
else:
    stocks = xq.get_stocks()
    print '雪球自选股:'
    print stocks
    print '添加股票结果:%s' % xq.add_stock('SH000016')
    print '删除股票结果:%s' % xq.del_stock('SH600392')
    print '测试后雪球自选股:'
    print xq.get_stocks()

    # 同步测试
    stocks = ['000001.XSHE','399678.XSHE','600392.XSHG']
    xq.sync(stocks) # 将雪球自选股列表更新为stocks
    print '同步后雪球自选股:'
    print xq.get_stocks()

    print '获取所有雪球自选股列表'
    print xq.get_stocks('全部')
雪球自选股:
[u'SH600392', u'SZ399678', u'SZ000001']
添加股票结果:True
删除股票结果:True
测试后雪球自选股:
[u'SH000016', u'SZ399678', u'SZ000001']
同步后雪球自选股:
[u'SH600392', u'SZ399678', u'SZ000001']
获取所有雪球自选股列表
[u'SH600392', u'SZ000001', u'SZ399678', u'SZ300699', u'SH601949', u'SZ002857', u'SH603226', u'SH603269', u'SH603090', u'SH603580', u'SZ002865', u'SH603536', u'SH603991', u'SH000001', u'SH603330']
 
 
分享到:
举报财经168客户端下载

全部回复

0/140

投稿 您想发表你的观点和看法?

更多人气分析师

  • 张亦巧

    人气2192文章4145粉丝45

    暂无个人简介信息

  • 王启蒙现货黄金

    人气296文章3215粉丝8

    本人做分析师以来,并专注于贵金属投资市场,尤其是在现货黄金...

  • 指导老师

    人气1864文章4423粉丝52

    暂无个人简介信息

  • 李冉晴

    人气2320文章3821粉丝34

    李冉晴,专业现贷实盘分析师。

  • 梁孟梵

    人气2176文章3177粉丝39

    qq:2294906466 了解群指导添加微信mfmacd

  • 张迎妤

    人气1896文章3305粉丝34

    个人专注于行情技术分析,消息面解读剖析,给予您第一时间方向...

  • 金泰铬J

    人气2328文章3925粉丝51

    投资问答解咨询金泰铬V/信tgtg67即可获取每日的实时资讯、行情...

  • 金算盘

    人气2696文章7761粉丝125

    高级分析师,混过名校,厮杀于股市和期货、证券市场多年,专注...

  • 金帝财神

    人气4760文章8329粉丝119

    本文由资深分析师金帝财神微信:934295330,指导黄金,白银,...

FX168财经

FX168财经学院

FX168财经

FX168北美