class FetchDaily(BaseService):
    def __init__(self):
        super(FetchDaily,
              self).__init__(f'../log/{self.__class__.__name__}.log')

        self.path = config_dict('data_path')
        self.check_path(self.path)
        self.df_today_all = pd.DataFrame()
        self.TIMEOUT = 10
        self.DB = DBSelector()
        self.engine = self.DB.get_engine('db_daily', 'qq')

    def get_today_market(self, re_try=10):

        while re_try > 0:
            try:
                df = ts.get_today_all()
                if df is None:
                    continue
                if len(df) == 0:
                    continue
            except Exception as e:
                self.logger.error(e)
                re_try = re_try - 1
                time.sleep(self.TIMEOUT)
            else:
                return df

        return None

    def run(self):

        self.df_today_all = self.get_today_market()
        # 存储每天 涨幅排行  榜,避免每次读取耗时过长
        filename = self.today + '_all_.xls'
        # 放在data文件夹下
        full_filename = os.path.join(self.path, filename)

        if self.df_today_all is not None:
            # 保留小数点的后两位数
            self.df_today_all['turnoverratio'] = self.df_today_all[
                'turnoverratio'].map(lambda x: round(x, 2))
            self.df_today_all['per'] = self.df_today_all['per'].map(
                lambda x: round(x, 2))
            self.df_today_all['pb'] = self.df_today_all['pb'].map(
                lambda x: round(x, 2))

            try:
                self.df_today_all.to_excel(full_filename)
            except Exception as e:
                notify(title='写excel出错', desp=f'{self.__class__}')
                self.logger.error(e)

            try:
                self.df_today_all.to_sql(self.today,
                                         self.engine,
                                         if_exists='fail')
            except Exception as e:
                notify(title='mysql出错', desp=f'{self.__class__}')
                self.logger.error(e)
Esempio n. 2
0
    def get_data(self, table):
        DB = DBSelector()
        engine = DB.get_engine('db_zdt', 'qq')

        try:
            df = pd.read_sql(table, engine)
        except Exception as e:
            self.logger.error('table_name >>> {}'.format(table))
            self.logger.error(e)
            return None
        else:
            return df
class DataFetcher():

    def __init__(self):
        # today='2020-03-27'
        self.DB = DBSelector()

    @property
    def jsl_bond(self):
        engine = self.DB.get_engine('db_stock', 'qq')
        jsl_df = pd.read_sql('tb_bond_jisilu', con=engine)
        return jsl_df

    @property
    def basic_info(self):
        engine = self.DB.get_engine('db_stock', 'qq')
        basic_df = pd.read_sql('tb_basic_info', con=engine, index_col='index')
        return basic_df

    @property
    def daily(self):
        engine_daily = self.DB.get_engine('db_daily', 'qq')
        daily_df = pd.read_sql(datetime.date.today().strftime('%Y-%m-%d'), con=engine_daily)
        return daily_df
Esempio n. 4
0
class Jisilu(BaseService):
    def __init__(self, check_holiday=False, remote='qq'):
        super(Jisilu, self).__init__(logfile='log/jisilu.log')

        if check_holiday:
            self.check_holiday()

        self.date = datetime.datetime.now().strftime('%Y-%m-%d')
        # self.date = '2020-02-07' # 用于调整时间

        self.timestamp = int(time.time() * 1000)
        self.headers = {
            'User-Agent':
            'User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
            'X-Requested-With': 'XMLHttpRequest'
        }
        self.url = 'https://www.jisilu.cn/data/cbnew/cb_list/?___jsl=LST___t={}'.format(
            self.timestamp)
        self.pre_release_url = 'https://www.jisilu.cn/data/cbnew/pre_list/?___jsl=LST___t={}'.format(
            self.timestamp)
        self.remote = remote
        self.DB = DBSelector()
        self.engine = self.DB.get_engine('db_jisilu', self.remote)

    def check_holiday(self):
        if self.is_weekday():
            self.logger.info("Start")
        else:
            self.logger.info("Holidy")
            exit(0)

    def download(self, url, data, retry=5):

        for i in range(retry):
            try:
                r = requests.post(url, headers=self.headers, data=data)
                if not r.text or r.status_code != 200:
                    continue
                else:
                    return r
            except Exception as e:
                self.logger.info(e)
                self.notify(title='下载失败', desp=f'{self.__class__}')
                continue

        return None

    def daily_update(self, adjust_no_use=True):

        post_data = {
            'btype': 'C',
            'listed': 'Y',
            'rp': '50',
            'is_search': 'N',
        }

        js = self.download(self.url, data=post_data)
        if not js:
            return None

        ret = js.json()
        bond_list = ret.get('rows', {})
        df = self.data_parse(bond_list, adjust_no_use)
        self.store_mysql(df)

    def data_parse(self, bond_list, adjust_no_use):

        cell_list = []
        for item in bond_list:
            cell_list.append(pd.Series(item.get('cell')))
        df = pd.DataFrame(cell_list)

        if adjust_no_use:

            # 类型转换 部分含有%
            df['premium_rt'] = df['premium_rt'].map(
                lambda x: float(x.replace('%', '')))
            df['price'] = df['price'].astype('float64')
            df['convert_price'] = df['convert_price'].astype('float64')
            df['premium_rt'] = df['premium_rt'].astype('float64')
            df['redeem_price'] = df['redeem_price'].astype('float64')

            def convert_float(x):
                try:
                    ret_float = float(x)
                except:
                    ret_float = None
                return ret_float

            def convert_percent(x):
                try:
                    ret = float(x) * 100
                except:
                    ret = None
                return ret

            def remove_percent(x):
                try:
                    ret = x.replace(r'%', '')
                    ret = float(ret)
                except Exception as e:
                    ret = None

                return ret

            df['put_convert_price'] = df['put_convert_price'].map(
                convert_float)
            df['sprice'] = df['sprice'].map(convert_float)
            df['ration'] = df['ration'].map(convert_percent)
            df['volume'] = df['volume'].map(convert_float)
            df['convert_amt_ratio'] = df['convert_amt_ratio'].map(
                remove_percent)
            df['ration_rt'] = df['ration_rt'].map(convert_float)
            df['increase_rt'] = df['increase_rt'].map(remove_percent)
            df['sincrease_rt'] = df['sincrease_rt'].map(remove_percent)

            rename_columns = {
                'bond_id': '可转债代码',
                'bond_nm': '可转债名称',
                'price': '可转债价格',
                'stock_nm': '正股名称',
                'stock_cd': '正股代码',
                'sprice': '正股现价',
                'sincrease_rt': '正股涨跌幅',
                'convert_price': '最新转股价',
                'premium_rt': '溢价率',
                'increase_rt': '可转债涨幅',
                'put_convert_price': '回售触发价',
                'convert_dt': '转股起始日',
                'short_maturity_dt': '到期时间',
                'volume': '成交额(万元)',
                'redeem_price': '强赎价格',
                'year_left': '剩余时间',
                'next_put_dt': '回售起始日',
                'rating_cd': '评级',
                # 'issue_dt': '发行时间',
                # 'redeem_tc': '强制赎回条款',
                # 'adjust_tc': '下修条件',
                'adjust_tip': '下修提示',
                # 'put_tc': '回售',
                'adj_cnt': '下调次数',
                #   'ration':'已转股比例'
                'convert_amt_ratio': '转债剩余占总市值比',
                'curr_iss_amt': '剩余规模',
                'orig_iss_amt': '发行规模',
                'ration_rt': '股东配售率',
                'redeem_flag': '发出强赎公告',
                'redeem_dt': '强赎日期',
                'guarantor': '担保',
            }

            df = df.rename(columns=rename_columns)
            df = df[list(rename_columns.values())]
            df['更新日期'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')

        df = df.set_index('可转债代码', drop=True)
        return df

    def store_mysql(self, df):
        try:

            df.to_sql('tb_jsl_{}'.format(self.date),
                      self.engine,
                      if_exists='replace',
                      dtype={'可转债代码': VARCHAR(10)})
            db_stock = self.DB.get_engine('db_stock', self.remote)
            df.to_sql('tb_bond_jisilu'.format(self.date),
                      db_stock,
                      if_exists='replace',
                      dtype={'可转债代码': VARCHAR(10)})

        except Exception as e:
            self.logger.info(e)
            send_from_aliyun(title='jisilu可转债', content='写入数据库出错')

    def init_release_table(self, conn):

        creat_table = '''
        create table if not exists tb_bond_release (
        可转债代码 varchar(10),
        可转债名称 varchar(10),
        集思录建议 varchar(500),
        包销比例 float(6,3),
        中签率 float(6,3),
        上市日期 varchar(20),
        申购户数(万户) int,
        单账户中签(顶格) float(6,3),
        股东配售率 float(6,3),
        评级 varchar(8),
        现价比转股价 float(6,3),
        抓取时间 datetime
        );
        '''
        self.execute(creat_table, (), conn)

    def get_conn(self):
        return self.DB.get_mysql_conn('db_stock', 'qq')

    # 这个数据最好晚上10点执行
    def release_data(self):

        conn = self.get_conn()
        self.init_release_table(conn)
        post_data = {
            'cb_type_Y': 'Y',
            'progress': '',
            'rp': 22,
        }

        r = self.download(url=self.pre_release_url, data=post_data)
        js_data = r.json()
        rows = js_data.get('rows')
        self.save_release_data(rows, conn)

    def save_release_data(self, rows, conn):
        for items in rows:
            item = items.get('cell')
            single_draw = item.get('single_draw')
            if single_draw:
                jsl_advise_text = item.get('jsl_advise_text')  # 集思录建议
                underwriter_rt = self.convert_float(
                    item.get('underwriter_rt'))  # 包销比例
                bond_nm = item.get('bond_nm')
                lucky_draw_rt = self.convert_float(
                    item.get('lucky_draw_rt'))  # 中签率
                if lucky_draw_rt:
                    lucky_draw_rt = lucky_draw_rt * 100
                list_date = item.get('list_date')
                valid_apply = self.convert_float(
                    item.get('valid_apply'))  # 申购户数(万户)
                single_draw = self.convert_float(
                    item.get('single_draw'))  # 单账户中签(顶格)
                ration_rt = self.convert_float(item.get('ration_rt'))  # 股东配售率
                rating_cd = item.get('rating_cd')  # 评级
                bond_id = item.get('bond_id')  # 可转债代码
                pma_rt = self.convert_float(item.get('pma_rt'))  # 现价比转股价
                update_time = datetime.datetime.now()

                if self.check_bond_exist(bond_id, conn):
                    if self.check_update(bond_id, conn):
                        update_data = (underwriter_rt, list_date, update_time,
                                       bond_id)
                        self.update_release_data(update_data, conn)
                    else:
                        continue

                # 插入
                else:
                    insert_data_tuple = (bond_id, bond_nm, jsl_advise_text,
                                         underwriter_rt, lucky_draw_rt,
                                         list_date, valid_apply, single_draw,
                                         ration_rt, rating_cd, pma_rt,
                                         update_time)
                    self.insert_release_data(insert_data_tuple, conn)

    def check_update(self, bond_id, conn):
        check_update = '''select * from tb_bond_release where 可转债代码=%s and 包销比例 is null'''
        return self.execute(check_update, bond_id, conn)

    def update_release_data(self, update_data, conn):
        '''更新发布数据'''

        update_sql = '''update tb_bond_release set 包销比例=%s , 上市日期=%s ,抓取时间=%s where 可转债代码 = %s'''
        self.execute(update_sql, update_data, conn)

    def insert_release_data(self, data, conn):
        '''插入发布数据'''
        insert_sql = '''insert into tb_bond_release (可转债代码 , 可转债名称 , 集思录建议 , 包销比例 , 中签率 ,上市日期 ,申购户数(万户), 单账户中签(顶格), 股东配售率 ,评级 ,  现价比转股价,抓取时间) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'''
        self.execute(insert_sql, data, conn)

    def check_bond_exist(self, bond_id, conn):
        '''
        判断债券是否存在
        '''
        check_exist = '''select * from tb_bond_release where 可转债代码=%s'''
        return self.execute(check_exist, bond_id, conn)

    def execute(self, cmd, data, conn):
        cursor = conn.cursor()
        if not isinstance(data, tuple):
            data = (data, )
        try:
            cursor.execute(cmd, data)
        except Exception as e:
            conn.rollback()
            self.logger.error('执行数据库错误 {}'.format(e))
            ret = None
        else:
            ret = cursor.fetchall()
            conn.commit()

        return ret

    def convert_float(self, x):
        if not x:
            return None

        if '%' in x:
            ration = 100
        else:
            ration = 1

        x = re.sub('%', '', x)
        try:
            ret = float(x) * ration
        except Exception as e:
            self.logger.error('转换失败{}'.format(e))
            ret = None

        return ret
Esempio n. 5
0
File: zdt.py Progetto: hvnobug/stock
class GetZDT(BaseService):
    def __init__(self, today=None):
        '''
        TODAY 格式 20200701
        :param today:
        '''
        super(GetZDT, self).__init__('log/zdt.log')

        if today:
            self.today = today
        else:
            self.today = time.strftime("%Y%m%d")

        self.user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/64.0.3282.167 Chrome/64.0.3282.167 Safari/537.36"
        self.path = config_dict('data_path')
        self.zdt_url = f'http://home.flashdata2.jrj.com.cn/limitStatistic/ztForce/{self.today}.js'
        self.zrzt_url = 'http://hqdata.jrj.com.cn/zrztjrbx/limitup.js'
        self.host = "home.flashdata2.jrj.com.cn"
        self.reference = "http://stock.jrj.com.cn/tzzs/zdtwdj/zdforce.shtml"

        self.header_zdt = {
            "User-Agent": self.user_agent,
            "Host": self.host,
            "Referer": self.reference
        }

        self.zdt_indexx = [
            '代码', '名称', '最新价格', '涨跌幅', '封成比', '封流比', '封单金额', '最后一次涨停时间',
            '第一次涨停时间', '打开次数', '振幅', '涨停强度'
        ]

        self.zrzt_indexx = [
            '序号', '代码', '名称', '昨日涨停时间', '最新价格', '今日涨幅', '最大涨幅', '最大跌幅', '是否连板',
            '连续涨停次数', '昨日涨停强度', '今日涨停强度', '是否停牌', '昨天的日期', '昨日涨停价', '今日开盘价格',
            '今日开盘涨幅'
        ]
        self.header_zrzt = {
            "User-Agent": self.user_agent,
            "Host": "hqdata.jrj.com.cn",
            "Referer": "http://stock.jrj.com.cn/tzzs/zrztjrbx.shtml"
        }

        self.DB = DBSelector()

    def download(self, url, headers, retry=5):

        for i in range(retry):
            try:
                resp = requests.get(url=url, headers=headers)
                content = resp.text
                md_check = re.findall('summary|lasttradedate', content)
                if content and len(md_check) > 0:
                    return content
                else:
                    time.sleep(60)
                    self.logger.info(
                        'failed to get content, retry: {}'.format(i))
                    continue
            except Exception as e:
                self.notify(title=f'{self.__class__}取涨跌停数据出错')
                self.logger.error(e)
                time.sleep(60)
                continue

        return None

    def convert_json(self, content):
        p = re.compile(r'"Data":(.*)};', re.S)
        if len(content) <= 0:
            self.logger.info('Content\'s length is 0')
            exit(0)
        result = p.findall(content)
        if result:
            try:
                t1 = result[0]
                t2 = re.sub('[\\r\\n]', '', t1)
                t2 = re.sub(',,', ',0,0', t2)
                t2 = re.sub('Infinity', '-1', t2)
                t2 = re.sub('NaN', '-1', t2)
                t2 = list(eval(t2))
                return t2
            except Exception as e:
                self.notify(title=f'{self.__class__}获取涨跌停数据出错')
                self.logger.info(e)
                return None
        else:
            return None

    def convert_dataframe(self, data, index, choice, post_fix):
        engine = self.DB.get_engine('db_zdt', 'qq')
        data_len = len(data)

        if choice == 1:
            for i in range(data_len):
                data[i][choice] = data[i][choice]

        df = pd.DataFrame(data, columns=index)

        # 今日涨停
        if choice == 1:
            self.today_zt(df, post_fix, engine)
        # 昨日涨停
        if choice == 2:
            self.yesterday_zt(df, post_fix, engine)

    # 今日涨停存储
    def today_zt(self, df, post_fix, engine):
        filename = os.path.join(self.path,
                                self.today + "_" + post_fix + ".xls")

        df['今天的日期'] = self.today
        df.to_excel(filename, encoding='gbk')
        try:
            df.to_sql(self.today + post_fix, engine, if_exists='fail')
        except Exception as e:
            self.logger.info(e)

    # 昨日涨停今日的状态,今日涨停
    def yesterday_zt(self, df, post_fix, engine):
        df = df.set_index('序号')
        formula = lambda x: round(x * 100, 3)
        df['最大涨幅'] = df['最大涨幅'].map(formula)
        df['最大跌幅'] = df['最大跌幅'].map(formula)
        df['今日开盘涨幅'] = df['今日开盘涨幅'].map(formula)
        df['昨日涨停强度'] = df['昨日涨停强度'].map(lambda x: round(x, 0))
        df['今日涨停强度'] = df['今日涨停强度'].map(lambda x: round(x, 0))

        try:
            df.to_sql(self.today + post_fix, engine, if_exists='fail')
        except Exception as e:
            self.notify(f'{self.__class__} 出错')
            self.logger.info(e)

        title, content = self.generate_html(df)
        try:
            send_from_aliyun(title, content, types='html')
        except Exception as e:
            self.logger.error(e)

    def generate_html(self, df):
        avg = round(df['今日涨幅'].mean(), 2)
        median = round(df['今日涨幅'].median(), 2)
        min_v = round(df['今日涨幅'].min(), 2)
        min_index = df['今日涨幅'].argmin()
        min_percent_name = df.iloc[min_index]['名称']
        current = datetime.datetime.now().strftime('%Y-%m-%d')
        title = '昨涨停今天{}平均涨{}\n'.format(current, avg)
        content = '<p>昨天涨停今天<font color="red">{}</font></p>' \
                  '<p>平均涨幅 <font color="red">{}</font></p>' \
                  '<p>涨幅中位数 <font color="red">{}</font></p>' \
                  '<p>涨幅最小 <font color="red">{}</font></p>' \
                  '<p>涨幅最小股 <font color="red">{}</font></p>'.format(current, avg, median, min_v, min_percent_name)

        return title, content

    def start(self):
        zdt_content = self.download(self.zdt_url, headers=self.header_zdt)
        zdt_js = self.convert_json(zdt_content)
        self.convert_dataframe(zdt_js, self.zdt_indexx, 1, 'zdt')
        # 昨日涨停数据会如果不是当天获取会失效
        zrzt_content = self.download(self.zrzt_url, headers=self.header_zrzt)
        zrzt_js = self.convert_json(zrzt_content)
        self.convert_dataframe(zrzt_js, self.zrzt_indexx, 2, 'zrzt')
Esempio n. 6
0
# -*-coding=utf-8-*-
# @Time : 2019/9/2 9:35
# @File : send_bond_info.py
# 发送邮件的,集思录双底

import pandas as pd
import datetime
from configure.settings import send_from_aliyun, DBSelector
from common.BaseService import BaseService
from configure.util import notify

DB = DBSelector()
con = DB.get_engine('db_stock', 'qq')


def map_rate(x):
    map_dict = {'A+': 1, 'AA-': 1.2, 'AA': 1.4, 'AA+': 1.6, 'AAA': 1.8}
    x = x.replace(' ', '')
    return map_dict.get(x, 1)


def get_df_data():
    df = pd.read_sql('tb_bond_jisilu', con=con)
    return df


def convert(df):
    df['grade'] = df['评级'].map(lambda x: map_rate(x))
    df['可转债综合价格'] = df['可转债价格'] + df['溢价率'] * df['grade']
    df = df.sort_values(by='可转债综合价格')
    df['剩余规模'] = df['剩余规模'].map(lambda x: round(float(x), 2))
class BigDeal(BaseService):
    def __init__(self):
        super(BigDeal, self).__init__('log/BigDeal.log')

        self.DB = DBSelector()
        self.db_stock_engine = self.DB.get_engine('db_stock', 'qq')
        self.jisilu_df = self.get_bond()
        self.code_name_dict = dict(
            zip(list(self.jisilu_df['可转债代码'].values),
                list(self.jisilu_df['可转债名称'].values)))
        self.mongodb = self.DB.mongo(type='qq')

    def get_ticks(self, code, date):
        df = ts.get_tick_data(code, date=date, src='tt')
        df['time'] = df['time'].map(lambda x: date + ' ' + x)
        return df

    def get_volume_distribition(self,
                                code,
                                date,
                                types='min',
                                big_deal=BIG_DEAL):
        '''
        # 从mongo获取数据 默认分钟 1000张
        :param code:
        :param date:
        :param types:
        :param big_deal:
        :return:
        '''
        # code='110030'
        # date='2019-04-02'

        # big_deal = 1000 # 1000张 100w

        date_d = datetime.datetime.strptime(date, '%Y-%m-%d')
        next_day = date_d + datetime.timedelta(days=1)

        doc = self.mongodb['cb_deal'][code]
        d = []
        for item in doc.find({'time': {
                '$gte': date_d,
                '$lt': next_day
        }}, {'_id': 0}):
            d.append(item)

        if len(d) == 0:
            return (code, -1)

        df = pd.DataFrame(d)
        df = df.set_index('time', drop=True)
        min_df = df.resample(types).sum()[['price', 'volume']]
        count = min_df[min_df['volume'] > big_deal]['volume'].count()
        return (code, count)

    def get_tick(self, code, date, retry=20):
        fs_df = None

        for i in range(retry):

            try:
                fs_df = ts.get_tick_data(code, date=date, src='tt')

            except Exception as e:
                self.logger.error('获取tick失败>>>>code={},date'.format(
                    code, date))
                self.logger.error(e)
                time.sleep(random.randint(2, 5))

            else:
                if fs_df is not None and len(fs_df) > 0:
                    break
                else:
                    self.logger.error('>>>>code={},date={} 获取行情重试 {}次'.format(
                        code, date, i))

        return fs_df

    def total_bonds(self, date):

        code_list = self.jisilu_df['可转债代码'].values
        for code in code_list:
            self.individual_bond(code, date)

    def individual_bond(self, code, date):
        # 储存一个可转债
        fs_df = self.get_tick(code, date)

        if fs_df is None:
            return None

        fs_df['time'] = fs_df['time'].map(lambda x: date + ' ' + x)
        fs_df['time'] = pd.to_datetime(fs_df['time'],
                                       format='%Y-%m-%d %H:%M:%S')

        ret = self.save_mongo(code, fs_df)

        if ret.get('status') == -1:
            self.notify('bigdeal', 'bigdeal保存mongo出错')
            self.logger.error('保存失败 >>>> code={}, date={}'.format(code, date))
        else:
            self.logger.info('保存成功 >>>> code={}, date={}'.format(code, date))

    def save_mongo(self, code, df):
        df['code'] = code
        js = json.loads(df.T.to_json()).values()

        for row in js:
            row['time'] = datetime.datetime.utcfromtimestamp(row['time'] /
                                                             1000)

        try:
            self.mongodb['cb_deal'][code].insert_many(js)
        except Exception as e:
            self.logger.error(e)
            self.logger.error('插入数据失败')
            return {'status': -1, 'code': code}

        else:
            return {'status': 0, 'code': code}

    def get_bond(self):
        df = pd.read_sql('tb_bond_jisilu', con=self.db_stock_engine)
        return df

    def fetch_bigdeal(self, today=True):
        '''
        # 获取大单数据
        # 获取当天数据,18点之后
        :param today:
        :return:
        '''
        if today:
            self.total_bonds(self.today)

        # 获取历史数据的数据看看
        else:
            delta = DELTA_DAY
            for i in range(1, delta + 1):
                d = (datetime.date.today() +
                     datetime.timedelta(days=i * -1)).strftime('%Y-%m-%d')
                print('going>>>>{}'.format(d))
                self.total_bonds(d)

    # 发送大单数据到手机
    def analysis(self, date=None, head=300):

        date = datetime.date.today().strftime(
            '%Y-%m-%d') if date is None else None

        kzz_big_deal_count = []
        for code in self.jisilu_df['可转债代码'].values:
            kzz_big_deal_count.append(self.get_volume_distribition(code, date))

        kzz_big_deal_order = list(
            sorted(kzz_big_deal_count, key=lambda x: x[1], reverse=True))
        send_content = []
        for item in kzz_big_deal_order[:head]:
            self.logger.info('{} |大单{}'.format(
                self.code_name_dict.get(item[0]), item[1]))
            send_content.append('{}|大单 {}'.format(
                self.code_name_dict.get(item[0]), item[1]))

        # 入库的
        big_deal_doc = self.mongodb['db_stock']['big_deal_logger']
        batch_size = []
        for item in kzz_big_deal_order:
            d = {
                'Date': date,
                'name': self.code_name_dict.get(item[0]),
                'times': int(item[1])
            }
            batch_size.append(d)

        try:
            big_deal_doc.insert_many(batch_size)  # 写入mongo
        except Exception as e:
            self.logger.error(e)

        content = '\n'.join(send_content)
        title = '{}-大单监控'.format(date)

        try:
            send_from_aliyun(title, content)
        except Exception as e:
            self.notify('bigdeal msg', 'bigdeal send failed')
            self.logger.error(e)
        else:
            self.logger.info('发送成功')
Esempio n. 8
0
def get_basic_info():
    DB = DBSelector()
    engine = DB.get_engine('db_stock', 'qq')
    base_info = pd.read_sql('tb_basic_info', engine, index_col='index')
    return base_info
Esempio n. 9
0
class ReachTarget(BaseService):
    def __init__(self):
        super(ReachTarget, self).__init__('log/reach_target.log')
        self.DB = DBSelector()
        self.engine = self.DB.get_engine('db_stock', 'qq')
        self.api = ts.get_apis()

        # python3 这个返回的不是list,需要手工转换

        # self.kzz_code_list = list(self.stocks.keys())
        # pool_code,pool_name=self.stock_pool()
        # self.pool_dict = dict(zip(pool_code,pool_name))
        # self.pool_list= list(self.pool_dict.keys())

        # 添加一部分持仓数据 或者 监测仓

        # self.df = pd.read_table(file, encoding='gbk', dtype={'证券代码': np.str})
        # try:
        #     del self.df['Unnamed: 15']
        # except Exception as e:
        #     logger.error(e)
        #     logger.error('删除多余列失败')
        #
        # code_list = list(self.df['证券代码'].values)
        #
        # # 移除非法证券代码 中签
        # t = [code_list.remove(i) for i in code_list.copy() if i.startswith('7') or i[:2] == '07']
        #
        # self.code_lists=code_list

    def all_bond_market(self):
        self.kzz_code, self.kzz_name, self.zg_code, self.name, self.yjl = self.zg_bond(
        )

        self.kzz_stocks = dict(zip(self.kzz_code, self.kzz_name))
        self.zg_stocks = dict(zip(self.zg_code, self.name))

        self.kzz_stocks_yjl = dict(zip(self.kzz_code, self.yjl))
        self.zg_stocks_yjl = dict(zip(self.zg_code, self.yjl))

        return (self.kzz_stocks, self.zg_stocks, self.kzz_stocks_yjl,
                self.zg_stocks_yjl)

    # 数据库获取模拟股,这个要废弃
    def stock_pool(self):
        pool_table = 'tb_current_hold'
        pool_df = pd.read_sql(pool_table, self.engine, index_col='index')

        return list(pool_df['代码'].values), list(pool_df['名字'].values)

    # 判断市场
    def identify_market(self, x):
        if x.startswith('3') or x.startswith('6') or x.startswith('0'):
            return False
        else:
            return True

    # 获取当前持仓个股
    def get_current_position(self):
        engine = self.DB.get_engine('db_position', 'qq')

        df = pd.read_sql('tb_position_2019-06-17', con=engine)

        # 只关注可转债
        df = df[df['证券代码'].map(self.identify_market)]

        kzz_stocks = dict(zip(list(df['证券代码'].values),
                              list(df['证券名称'].values)))

        cons = self.DB.get_mysql_conn('db_stock', 'qq')
        cursor = cons.cursor()
        query_cmd = 'select 正股代码,正股名称,溢价率 from tb_bond_jisilu where 可转债代码=%s'
        zg_stocks = {}
        kzz_yjl = {}
        zg_yjl = {}
        for code in kzz_stocks:
            cursor.execute(query_cmd, (code))
            ret = cursor.fetchone()
            if ret:
                zg_stocks[ret[0]] = ret[1]
                kzz_yjl[code] = ret[2]
                zg_yjl[ret[0]] = ret[2]

        # 可转债代码
        # dict,dict,dict,dict
        return (kzz_stocks, zg_stocks, kzz_yjl, zg_yjl)

    # 获取市场所有可转债数据个股代码 正股
    def zg_bond(self):
        bond_table = 'tb_bond_jisilu'

        try:
            jsl_df = pd.read_sql(bond_table, self.engine)

        except Exception as e:
            self.logger.info(e)
            return [], [], [], [], []

        else:
            return list(jsl_df['可转债代码']), list(jsl_df['可转债名称']), list(jsl_df['正股代码'].values), \
                   list(jsl_df['正股名称'].values), list(jsl_df['溢价率'].values)

    # 可转债的监测
    def monitor(self, total_market=True):
        '''
        total_market 默认监控全市场 total_market = True
        '''
        if total_market:
            (kzz_stocks, zg_stocks, kzz_yjl, zg_yjl) = self.all_bond_market()
        else:
            (kzz_stocks, zg_stocks, kzz_yjl,
             zg_yjl) = self.get_current_position()

        zg_code = list(zg_stocks.keys())
        kzz_code = list(kzz_stocks.keys())
        self.has_sent_kzz = dict(
            zip(kzz_code, [datetime.datetime.now()] * len(kzz_code)))
        self.has_sent_diff = dict(
            zip(kzz_code, [datetime.datetime.now()] * len(kzz_code)))
        self.has_sent_zg = dict(
            zip(zg_code, [datetime.datetime.now()] * len(zg_code)))

        while 1:

            current = trading_time()
            if current == MARKET_OPENING:

                self.get_realtime_info(kzz_code, self.has_sent_kzz, '转债',
                                       kzz_stocks, kzz_yjl, ZZ_ALERT_PERCENT)
                self.get_realtime_info(zg_code, self.has_sent_zg, '正股',
                                       zg_stocks, zg_yjl, ZG_ALERT_PERCENT)
                self.get_price_diff(codes=kzz_code,
                                    has_sent_=self.has_sent_diff,
                                    types='差价',
                                    kzz_stocks=kzz_stocks,
                                    kzz_stocks_yjl=kzz_yjl)

                time.sleep(LOOP_TIME)

            elif current == -1:
                time.sleep(LOOP_TIME)

            elif current == 1:
                try:
                    ts.close_apis(self.api)

                except Exception as e:
                    self.logger.info('fail to  stop monitor {}'.format(
                        datetime.datetime.now()))
                    self.logger.info(e)
                exit(0)

    # 获取实时报价
    def get_realtime_info(self, codes, has_sent, types, stock, yjl, percent):

        try:
            price_df = ts.quotes(codes, conn=self.api)

        except Exception as e:
            self.logger.error('获取可转债异常 >>>> {}'.format(e))
            try:
                self.api = ts.get_apis()
            except Exception as e:
                self.logger.error('异常中存在异常{}'.format(e))

            time.sleep(EXECEPTION_TIME)

        else:

            if len(price_df) != 0:
                price_df = price_df[price_df['cur_vol'] != 0]
                price_df['percent'] = (
                    price_df['price'] -
                    price_df['last_close']) / price_df['last_close'] * 100
                price_df['percent'] = price_df['percent'].map(
                    lambda x: round(x, 2))
                ret_dt = \
                    price_df[
                        (price_df['percent'] > percent) | (price_df['percent'] < -1 * percent)][
                        ['code', 'price', 'percent']]

                if len(ret_dt) > 0:

                    # 提醒一次后,下一次的间隔为DELTA_TIME分钟后
                    # sent_list = []
                    for i in ret_dt['code']:

                        if has_sent[i] <= datetime.datetime.now():
                            name_list = []
                            yjl_list = []
                            name_list.append(stock[i])
                            yjl_list.append(yjl[i])
                            has_sent[i] = datetime.datetime.now(
                            ) + datetime.timedelta(minutes=DELTA_TIME)

                            ret_dt1 = ret_dt[ret_dt['code'] == i]
                            ret_dt1['名称'] = name_list
                            ret_dt1['溢价率'] = yjl_list

                            name = ret_dt1['名称'].values[0]
                            price = ret_dt1['price'].values[0]
                            percent = ret_dt1['percent'].values[0]
                            yjl_v = ret_dt1['溢价率'].values[0]
                            now = datetime.datetime.now().strftime(
                                '%Y-%m-%d %H:%M:%S')

                            content0 = '{t}\n{name}:价格:{price} 涨幅:{percent},溢价率:{yjl}'.format(
                                name=name,
                                price=price,
                                percent=percent,
                                yjl=yjl_v,
                                t=now)

                            self.logger.info(content0)

                            try:
                                notify(title=content0)

                            except Exception as e:
                                self.logger.info('发送微信失败')
                                self.logger.info(e)

    # 获取差价 可转债
    def get_price_diff(self, codes, has_sent_, types, kzz_stocks,
                       kzz_stocks_yjl):
        # 针对可转债
        try:
            df = ts.quotes(codes, conn=self.api)

        except Exception as e:
            self.logger.error('获取可转债异常 >>>> {}'.format(e))
            try:
                self.api = ts.get_apis()
            except Exception as e:
                self.logger.error('异常中存在异常{}'.format(e))

            time.sleep(EXECEPTION_TIME)

        else:
            df['bid1'] = df['bid1'].astype(float)
            df['ask1'] = df['ask1'].astype(float)
            df['diff'] = np.abs(df['bid1'] - df['ask1'])
            result = df[df['diff'] >= DIFF_V]
            if result.empty:
                # continue
                return
            else:
                for j in result['code']:

                    if has_sent_[j] <= datetime.datetime.now():
                        has_sent_[j] = datetime.datetime.now(
                        ) + datetime.timedelta(minutes=DIFF_DELTA_TIME)
                        name_list = []
                        yjl_list = []
                        name_list.append(kzz_stocks[j])
                        yjl_list.append(kzz_stocks_yjl[j])
                        ret_dt1 = result[result['code'] == j]
                        ret_dt1['名称'] = name_list
                        ret_dt1['溢价率'] = yjl_list
                        # ret_dt1 = ret_dt1.set_index('code', drop=True)

                        code = j
                        name = ret_dt1['名称'].values[0]
                        price = ret_dt1['price'].values[0]
                        bid = ret_dt1['bid1'].values[0]
                        ask = ret_dt1['ask1'].values[0]
                        diff = round(ret_dt1['diff'].values[0], 2)
                        now = datetime.datetime.now().strftime(
                            '%Y-%m-%d %H:%M:%S')
                        content0 = '{t}\n{code}::{name}:价格:{price} 买1:{bid} 卖1:{ask}差价:{diff}'.format(
                            code=code,
                            name=name,
                            price=price,
                            bid=bid,
                            ask=ask,
                            diff=diff,
                            t=now)
                        self.logger.info(content0)
                        try:
                            wechat.send_content(content0)
                        except Exception as e:
                            self.logger.info('发送微信失败')
                            self.logger.info(e)
Esempio n. 10
0
class BreakMonitor(BaseService):
    def __init__(self, send=True):
        super(BreakMonitor, self).__init__()
        self.send = send
        self.DB = DBSelector()
        self.engine = self.DB.get_engine('db_stock', 'qq')
        self.bases = pd.read_sql('tb_basic_info',
                                 self.engine,
                                 index_col='index')

    def read_stock_list(self, file=None):
        if file:
            with open(file, 'r') as f:
                monitor_list = f.readlines()
                monitor_list = list(map(lambda x: x.strip(), monitor_list))
        else:
            monitor_list = ['300100']

        return monitor_list

    def percent(self, current, close):
        return (current - close) * 1.0 / close * 100

    # 开板提示
    def break_ceil(self, code):
        print(threading.current_thread().name)

        while 1:

            # 交易时间
            if trading_time() != 0:
                break

            try:
                df = ts.get_realtime_quotes(code)
            except Exception as e:
                self.logger.error(e)
                time.sleep(5)
                continue

            v = float(df['b1_v'].values[0])

            if self.percent(float(df.iloc[0]['price']),
                            float(df.iloc[0]['pre_close'])) < 9:
                if self.send == True:
                    title = f'{code}已经板了'
                    notify(title)
                    break

            if v <= 1000:
                print(datetime.datetime.now().strftime("%H:%M:%S"))
                print(u"小于万手,小心!跑")
                print(self.bases[self.bases['code'] == code]['name'].values[0])
                if self.send == True:
                    title = f'{code}开板了'
                    notify(title)

            time.sleep(10)

    def monitor_break(self):
        thread_num = len(self.read_stock_list())  # 线程数和股票输一样
        thread_list = []
        for i in range(thread_num):
            t = threading.Thread(target=self.break_ceil,
                                 args=(self.read_stock_list()[i], ))
            thread_list.append(t)

        for j in thread_list:
            j.start()

        for k in thread_list:
            k.join()
Esempio n. 11
0
# -*-coding=utf-8-*-
# 获取 不同形态的k线
import random
import time
import tushare as ts
import pandas as pd
import os, datetime, math
import numpy as np
import logging
from configure.settings import DBSelector, MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, REDIS_HOST
import redis
from threading import Thread
from common.BaseService import  BaseService

DB = DBSelector()
engine = DB.get_engine('history', 'qq')
conn = ts.get_apis()
MYSQL_DB = 'history'
cursor = DB.get_mysql_conn(MYSQL_DB, 'qq').cursor()


# pd.set_option('display.max_rows', None)

class Kline(BaseService):
    def __init__(self):
        super(Kline, self).__init__('log/kline.log')

        path = os.path.join(os.getcwd(), 'data')
        self.today_date = datetime.datetime.now().strftime('%Y-%m-%d')

        if not os.path.exists(path):
    def get_bond_data(self):
        DB = DBSelector()
        engine = DB.get_engine('db_stock', 'qq')

        df = pd.read_sql('tb_bond_jisilu', con=engine)
        return df
Esempio n. 13
0
 def db_init(self):
     DB = DBSelector()
     self.engine = DB.get_engine('db_stock', 'qq')
     self.conn = DB.get_mysql_conn('db_stock', 'qq')