示例#1
0
def equity_interest_pledge_too_high(securities: str, data_hub: DataHubEntry,
                                    database: DatabaseEntry, context: AnalysisContext) -> AnalysisResult:
    nop(database)
    nop(context)

    query_fields = ['质押次数', '无限售股质押数量', '限售股份质押数量', '总股本', '质押比例']
    if not data_hub.get_data_center().check_readable_name(query_fields):
        return AnalysisResult(securities, AnalysisResult.SCORE_NOT_APPLIED, 'Unknown readable name detect.')

    df = data_hub.get_data_center().query('Stockholder.PledgeStatus', securities, (years_ago(2), now()),
                                          fields=query_fields + ['stock_identity', 'due_date'], readable=True)
    if df is None or len(df) == 0:
        return AnalysisResult(securities, AnalysisResult.SCORE_NOT_APPLIED, 'No data for ' + str(securities))
    df = df.sort_values('due_date', ascending=False)

    score = 100
    reason = []
    for index, row in df.iterrows():
        due_date = row['due_date']

        pledge_rate = row['质押比例']
        if pledge_rate > 0.5:
            score = 0
        if pledge_rate > 0.1:
            reason.append('%s: 质押比例:%.2f%%' % (str(due_date), pledge_rate * 100))

    return AnalysisResult(securities, score, reason)
def analysis_finance_report_sign(securities: str, data_hub: DataHubEntry,
                                 database: DatabaseEntry,
                                 context: AnalysisContext) -> AnalysisResult:
    nop(database)

    if context.cache.get('finance_audit', None) is None:
        context.cache['finance_audit'] = data_hub.get_data_center().query(
            'Finance.Audit')
    df = context.cache.get('finance_audit', None)

    error_report = check_gen_report_when_data_missing(
        df, securities, 'Finance.Audit',
        ['stock_identity', 'period', 'conclusion'])
    if error_report is not None:
        return error_report

    df_slice = df[df['stock_identity'] == securities]
    df_slice_in_4_years = df_slice[df_slice['period'] > years_ago(4)]

    score = 100
    reason = []

    for index, row in df_slice_in_4_years.iterrows():
        period = row['period']
        conclusion = row['conclusion']

        if conclusion != '标准无保留意见':
            score = 0
            reason.append(date2text(period) + ' : ' + conclusion)
    if len(reason) == 0:
        reason.append('近四年均为标准无保留意见')

    return AnalysisResult(securities, score, reason)
def analysis_dispersed_ownership(securities: str, data_hub: DataHubEntry,
                                 database: DatabaseEntry,
                                 context: AnalysisContext) -> AnalysisResult:
    nop(database, context)
    df = data_hub.get_data_center().query(
        'Stockholder.Statistics',
        securities,
        (years_ago(3), now()),
    )
    if df is None or len(df) == 0:
        return AnalysisResult(securities, AnalysisResult.SCORE_NOT_APPLIED,
                              '没有数据')
    df = df[df['period'].dt.month == 12]
    df = df.sort_values('period', ascending=False)

    score = 100
    reason = []
    applied = False
    for index, row in df.iterrows():
        period = row['period']
        stockholder_top10 = row['stockholder_top10']
        stockholder_top10_nt = row['stockholder_top10_nt']

        if not isinstance(stockholder_top10, (list, tuple)):
            continue
        if len(stockholder_top10) != 10:
            continue

        largest_ratio = 0.0
        biggest_holder = ''
        for stockholder_data in stockholder_top10:
            if 'hold_ratio' not in stockholder_data.keys(
            ) or 'holder_name' not in stockholder_data.keys():
                break
            applied = True
            hold_ratio = stockholder_data.get('hold_ratio')
            holder_name = stockholder_data.get('holder_name')
            if hold_ratio > largest_ratio:
                largest_ratio = hold_ratio
                biggest_holder = holder_name
        if largest_ratio == 0.0:
            return AnalysisResult(securities, AnalysisResult.SCORE_NOT_APPLIED,
                                  '缺少必要数据,请确保数据包含tushare pro数据源')
        if largest_ratio < 0.1:
            score = 0
            reason.append('%s: 最大股东 %s 持股比例为%.2f%%,小于10%%' %
                          (str(period), biggest_holder, largest_ratio * 100))
        else:
            reason.append('%s: 最大股东 %s 持股比例为%.2f%%' %
                          (str(period), biggest_holder, largest_ratio * 100))

    if len(reason) == 0:
        reason.append('没有数据')
    return AnalysisResult(securities, score, reason) if applied else \
        AnalysisResult(securities, AnalysisResult.SCORE_NOT_APPLIED, reason)
示例#4
0
def analysis_location_limitation(securities: str, data_hub: DataHubEntry,
                                 database: DatabaseEntry, context: AnalysisContext) -> AnalysisResult:
    nop(database)

    if context.cache.get('securities_info', None) is None:
        context.cache['securities_info'] = data_hub.get_data_center().query('Market.SecuritiesInfo')
    df = context.cache.get('securities_info', None)

    df_slice = df[df['stock_identity'] == securities]
    area = get_dataframe_slice_item(df_slice, 'area', 0, '')
    exclude = area in ['黑龙江', '辽宁', '吉林']
    reason = securities + '地域为' + str(area)
    return AnalysisResult(securities, not exclude, reason)
示例#5
0
def analysis_less_than_3_years(securities: str, data_hub: DataHubEntry,
                               database: DatabaseEntry, context: AnalysisContext) -> AnalysisResult:
    nop(database)

    if context.cache.get('securities_info', None) is None:
        context.cache['securities_info'] = data_hub.get_data_center().query('Market.SecuritiesInfo')
    df = context.cache.get('securities_info', None)

    df_slice = df[df['stock_identity'] == securities]
    listing_date = get_dataframe_slice_item(df_slice, 'listing_date', 0, now())
    exclude = now().year - listing_date.year < 3
    reason = '上市日期' + str(listing_date) + ('小于三年' if exclude else '大于三年')
    return AnalysisResult(securities, not exclude, reason)
def analysis_exclude_industries(securities: str, data_hub: DataHubEntry,
                                database: DatabaseEntry, context: AnalysisContext) -> AnalysisResult:
    nop(database)

    if context.cache.get('securities_info', None) is None:
        context.cache['securities_info'] = data_hub.get_data_center().query('Market.SecuritiesInfo')
    df = context.cache.get('securities_info', None)

    df_slice = df[df['stock_identity'] == securities]

    industry = get_dataframe_slice_item(df_slice, 'industry', 0, '')
    exclude = industry in ['种植业', '渔业', '林业', '畜禽养殖', '农业综合']
    reason = '所在行业[' + str(industry) + (']属于农林牧渔' if exclude else ']不属于农林牧渔')
    return AnalysisResult(securities, not exclude, reason)
def check_industry_in(securities: str, industries: [str],
                      data_hub: DataHubEntry, database: DatabaseEntry,
                      context: AnalysisContext) -> bool:
    nop(database)

    if context.cache.get('securities_info', None) is None:
        context.cache['securities_info'] = data_hub.get_data_center().query(
            'Market.SecuritiesInfo')
    df_info = context.cache.get('securities_info', None)

    df_slice = df_info[df_info['stock_identity'] == securities]
    industry = get_dataframe_slice_item(df_slice, 'industry', 0, '')

    return industry in industries
示例#8
0
def query_finance_pattern(data_hub: DataHubEntry, identity: str,
                          time_serial: tuple, fields: list, mapping: dict) -> pd.DataFrame:
    query_fields = [mapping.get(f, f) for f in fields]
    query_fields = list(set(query_fields))

    if 'period' in query_fields:
        query_fields.remove('period')
    if 'stock_identity' in query_fields:
        query_fields.remove('stock_identity')

    data_utility = data_hub.get_data_utility()
    df = data_utility.auto_query(identity, time_serial, query_fields, join_on=['stock_identity', 'period'])

    df.fillna(0.0, inplace=True)
    df = df.sort_values('period', ascending=False)

    inv_dict = {v: k for k, v in mapping.items()}
    df = df.rename(inv_dict, axis='columns')

    return df
def analysis_investigation(securities: str, data_hub: DataHubEntry,
                           database: DatabaseEntry,
                           context: AnalysisContext) -> AnalysisResult:
    nop(database)

    if context.cache.get('investigation', None) is None:
        context.cache['investigation'] = data_hub.get_data_center().query(
            'Market.Investigation')
    df = context.cache.get('investigation', None)

    error_report = check_gen_report_when_data_missing(
        df, securities, 'Market.Investigation', [
            'stock_identity', 'investigate_date', 'investigate_topic',
            'investigate_reason'
        ])
    if error_report is not None:
        return error_report

    df_slice = df[df['stock_identity'] == securities]
    df_slice_in_4_years = df_slice[df_slice['investigate_date'] > years_ago(5)]

    score = 100
    reason = []

    for index, row in df_slice_in_4_years.iterrows():
        score = 0
        investigate_date = row['investigate_date']
        investigate_topic = row['investigate_topic']
        investigate_reason = row['investigate_reason']
        reason.append('%s: <<%s>> -- %s' %
                      (date2text(investigate_date), investigate_topic,
                       investigate_reason))
    if len(reason) == 0:
        reason.append('近四年无立案调查记录')

    return AnalysisResult(securities, score, reason)
def analysis_inquiry(securities: str, data_hub: DataHubEntry,
                     database: DatabaseEntry,
                     context: AnalysisContext) -> AnalysisResult:
    nop(database)

    df = data_hub.get_data_center().query('Market.Enquiries', securities)
    if df is None or len(df) == 0:
        return AnalysisResult(securities, AnalysisResult.SCORE_PASS,
                              '四年内无问询记录(也可能是数据缺失)')

    error_report = check_gen_report_when_data_missing(
        df, securities, 'Market.Enquiries',
        ['stock_identity', 'enquiry_date', 'enquiry_topic'])
    if error_report is not None:
        return error_report

    df_slice = df[df['stock_identity'] == securities]
    df_slice_in_4_years = df_slice[df_slice['enquiry_date'] > years_ago(5)]

    score = 100
    reason = []

    for index, row in df_slice_in_4_years.iterrows():
        enquiry_date = row['enquiry_date']
        enquiry_topic = row['enquiry_topic']
        enquiry_title = row['enquiry_title']
        if '问询函' in enquiry_topic or '关注函' in enquiry_topic:
            score = 59
            reason.append(
                '%s: <<%s>> -- %s' %
                (date2text(enquiry_date), enquiry_topic, enquiry_title))

    if len(reason) == 0:
        reason.append('近四年无敏感问询')

    return AnalysisResult(securities, score, reason)
示例#11
0
def analysis_finance_report_sign(securities: str, data_hub: DataHubEntry,
                                 database: DatabaseEntry, context: AnalysisContext) -> AnalysisResult:
    nop(database)

    if context.cache.get('finance_audit', None) is None:
        context.cache['finance_audit'] = data_hub.get_data_center().query('Finance.Audit')
    df = context.cache.get('finance_audit', None)

    error_report = check_gen_report_when_data_missing(df, securities, 'Finance.IncomeStatement',
                                                      ['stock_identity', 'period', 'conclusion'])
    if error_report is not None:
        return error_report

    df_slice = df[df['stock_identity'] == securities]
    df_slice_in_4_years = df_slice[df_slice['period'] > years_ago(4)]

    score = 100
    reason = []

    for index, row in df_slice_in_4_years.iterrows():
        period = row['period']
        conclusion = row['conclusion']

        if conclusion != '标准无保留意见':
            score = 0
            reason.append(date2text(period) + ' : ' + conclusion)
    if len(reason) == 0:
        reason.append('近四年均为标准无保留意见')

    # df_slice.sort_values('period', ascending=True)
    #
    # if len(df_slice) == 1:
    #     print('Too less record: ' + securities)
    # df_slice_in_3_years = df_slice[df_slice['period'] > years_ago(3)]
    #
    # conclusion_all = df_slice['conclusion']
    # conclusion_all_list = conclusion_all.to_list()
    #
    # conclusion_3_years = df_slice_in_3_years['conclusion']
    # conclusion_3_years_list = conclusion_3_years.to_list()

    # ok_count = 0
    # nok_count = 0
    # for conclusion in conclusion_all_list:
    #     if conclusion != '标准无保留意见':
    #         nok_count += 1
    #     else:
    #         ok_count += 1
    # score = 100 * ok_count / (ok_count + nok_count) if (ok_count + nok_count) > 0 else 100
    #
    # for conclusion in conclusion_3_years_list:
    #     if conclusion != '标准无保留意见':
    #         score = 0
    #         break

    # agency = get_dataframe_slice_item(df_slice, 'agency', 0, '')
    # sign = get_dataframe_slice_item(df_slice, 'sign', 0, '')

    # reason = '标准无保留意见' if score == 100 else '存在非标意见'

    return AnalysisResult(securities, score, reason)