Ejemplo n.º 1
0
def st():
    db_client = MongoDBClient(
        config.get("db").get("mongodb"),
        config.get("db").get("database"))

    st_df = pd.read_csv(config.get("files").get("st"), header=0)
    st_df['ticker'] = st_df['ticker'].map(lambda x: str(x).zfill(6))

    for index, row in st_df.iterrows():
        _date = str(row["tradeDate"]).replace('-', '')
        _market = 0
        if str(row["exchangeCD"]) == "XSHG":
            _market = 1

        db_client.upsert_one(_filter={
            "code": str(row["ticker"]),
            "market": _market,
            "date": _date
        },
                             _value={
                                 "st": 1,
                                 "name": "%s" % row['tradeAbbrName']
                             },
                             _upsert=False)
        print("更新记录: %d" % index)
Ejemplo n.º 2
0
def plot1(years, money):
    tax = 0.00025  # 买卖按照万分之2.5计算

    for item in config.get("indexes"):
        _market = item[0]
        _idx_code = item[1]
        _money_per = money
        click.echo("开始计算 %d - %s 指数的回测策略" % (_market, _idx_code))
        _start_date = date.datetime_to_str(date.years_ago(years))
        last_day_list = date.last_days(int(_start_date), 1,
                                       True)  # 每月最后一个交易日集合

        data = []
        db_client = MongoDBClient(
            config.get("db").get("mongodb"),
            config.get("db").get("database"))

        _idx_list = db_client.find_stock_list(_filter={
            "code": _idx_code,
            "market": _market
        },
                                              _sort=[("date",
                                                      pymongo.ASCENDING)],
                                              _fields={
                                                  "date": 1,
                                                  "close": 1
                                              })

        item_df = pd.DataFrame(list(_idx_list), columns=["date", "close"])
        item_df = item_df.dropna(0)

        total_count = int(0)  # 累计数量

        for idx, item_date in enumerate(last_day_list):
            last_df = item_df[item_df["date"] == str(item_date)]
            if last_df is None or len(last_df) <= 0:
                continue

            item_point = last_df.ix[last_df.index.values[0]]["close"]
            item_count = _money_per * (1 - tax) / item_point
            total_count += item_count
            data.append([item_date, "买入", item_point, item_count, total_count])

        item = data.pop(-1)
        item_count = total_count * item[2] * (1 - tax) / item[2]
        data.append([item[0], "卖出", item[2], item_count, 0])
        result_df = pd.DataFrame(data,
                                 columns=["日期", "操作", "单价", "数量", "累计数量"])

        result_df.to_csv(config.get("files").get("plots") %
                         (PROJECT_ROOT, "plot1", _market, _idx_code),
                         index=False,
                         mode="w",
                         header=True,
                         encoding='gb18030',
                         float_format="%.3f")
Ejemplo n.º 3
0
def _indexes(idx_market, idx_code, start_date, calendar_df):
    db_client = MongoDBClient(
        config.get("db").get("mongodb"),
        config.get("db").get("database"))

    today = int("".join(time.strftime('%Y%m%d', time.localtime(time.time()))))
    item_last = db_client.find_stock_item(_filter={
        "code": idx_code,
        "market": idx_market,
        "dr": {
            "$exists": True
        }
    },
                                          _sort=[("date", pymongo.DESCENDING)])

    if item_last is not None and len(item_last) > 0:
        calendar_df = calendar_df[
            calendar_df["calendarDate"] > int(item_last.get("date"))]

    click.echo("\t开始 %s 指数的估值信息..." % idx_code)
    for _, row in calendar_df.iterrows():
        cal_date = int(row["calendarDate"])
        if row['isOpen'] == 0 or cal_date < start_date or cal_date > today:
            continue

        click.echo("\t\t计算%d-%s - %d ..." % (idx_market, idx_code, cal_date))
        _result = index.index_val(cal_date, idx_code, db_client)

        if _result is not None:
            click.echo("\t\t\t code:%s, pe_ttm:%s, pb:%s" %
                       (idx_code, _result[0], _result[1]))
            db_client.upsert_one(_filter={
                "code": str(idx_code),
                "market": idx_market,
                "date": str(cal_date)
            },
                                 _value={
                                     "pe_ttm": _result[0],
                                     "pb": _result[1],
                                     "roe": _result[2],
                                     "dr": _result[3]
                                 })
    click.echo("\t%s 指数的估值信息计算完毕" % idx_code)
Ejemplo n.º 4
0
def a():
    """计算A股PE中值"""
    click.echo("开始计算整个A股的估值信息...")
    first = True
    result_list = []
    db_client = MongoDBClient(
        config.get("db").get("mongodb"),
        config.get("db").get("database"))

    calendar_df = pd.read_csv(config.get("files").get("calendar"), header=0)
    today = int("".join(time.strftime('%Y%m%d', time.localtime(time.time()))))

    try:
        stock_df = pd.read_csv(config.get("files").get("stock_a"),
                               header=0,
                               encoding="utf8")
        if len(stock_df) > 0:
            first = False
            item_last = stock_df.loc[stock_df.index[-1]]

            calendar_df = calendar_df[
                calendar_df["calendarDate"] > int(item_last["date"])]

    except FileNotFoundError:
        pass

    for _, row in calendar_df.iterrows():
        cal_date = int(row["calendarDate"])
        if row['isOpen'] == 0 or 20020328 > cal_date or cal_date > today:
            continue

        stock_day_list = db_client.find_stock_list(_filter={
            "date": str(cal_date),
            "fixed": {
                "$exists": True
            }
        },
                                                   _sort=[("code",
                                                           pymongo.ASCENDING)],
                                                   _fields={
                                                       "market": 1,
                                                       "code": 1,
                                                       "close": 1,
                                                       "pe_ttm": 1,
                                                       "pb": 1,
                                                       "roe": 1,
                                                       "dr": 1
                                                   })

        stock_df = pd.DataFrame(
            stock_day_list,
            columns=['market', 'code', 'close', 'pe_ttm', 'pb', 'roe', 'dr'])
        stock_df = stock_df.fillna(0)

        pe_list = []
        pb_list = []
        roe_list = []
        dr_list = []
        for _, r in stock_df.iterrows():
            pe_list.append(r['pe_ttm'])
            pb_list.append(r['pb'])
            roe_list.append(r['roe'])
            dr_list.append(r['dr'])

        mid_value_pe = number.get_median(pe_list)
        mid_value_pb = number.get_median(pb_list)
        avg_value_roe = number.get_average(roe_list)
        avg_value_dr = number.get_average(dr_list)
        click.echo("计算 %s 日的数据中值, pe=%f, pb=%f, roe=%f, dr=%f ... " %
                   (cal_date, mid_value_pe, mid_value_pb, avg_value_roe,
                    avg_value_dr))

        result_list.append([
            cal_date, mid_value_pe, mid_value_pb, avg_value_roe, avg_value_dr
        ])

        if len(result_list) % 50 == 0:
            if first:
                first = False

                result_df = pd.DataFrame(
                    result_list, columns=['date', 'pe', 'pb', 'roe', 'dr'])
                result_df.to_csv(config.get("files").get("stock_a"),
                                 index=False,
                                 mode="w",
                                 header=True,
                                 encoding='utf8',
                                 float_format="%.6f")
            else:
                result_df = pd.DataFrame(
                    result_list, columns=['date', 'pe', 'pb', 'roe', 'dr'])
                result_df.to_csv(config.get("files").get("stock_a"),
                                 index=False,
                                 mode="a+",
                                 header=False,
                                 encoding='utf8',
                                 float_format="%.6f")

            result_list = []

    result_df = pd.DataFrame(result_list,
                             columns=['date', 'pe', 'pb', 'roe', 'dr'])
    result_df.to_csv(config.get("files").get("stock_a"),
                     index=False,
                     mode="a+",
                     header=False,
                     encoding='utf8',
                     float_format="%.6f")
    click.echo("整个A股的估值信息计算完毕...")
Ejemplo n.º 5
0
def plot2(years, money):
    """
    红利指数定投进阶方案
    80% <= pe百分位: 全卖
    60% <= pe百分位 < 80%: 定赎回
    40% <= pe百分位 < 60%: 正常定投
    20% <= pe百分位 < 40%: 1.5倍定投
    pe百分位 < 20%: 2倍定投

    :return:
    """
    tax = 0.00025  # 买卖按照万分之2.5计算

    for item in config.get("indexes"):
        data = []
        _market = item[0]
        _idx_code = item[1]
        _money_per = money

        click.echo("开始计算 %d - %s 指数的回测策略" % (_market, _idx_code))
        _start_date = date.datetime_to_str(date.years_ago(years))
        last_day_list = date.last_days(int(_start_date), 1,
                                       True)  # 每月最后一个交易日集合

        db_client = MongoDBClient(
            config.get("db").get("mongodb"),
            config.get("db").get("database"))

        _idx_list = db_client.find_stock_list(_filter={
            "code": _idx_code,
            "market": _market
        },
                                              _sort=[("date",
                                                      pymongo.ASCENDING)],
                                              _fields={
                                                  "date": 1,
                                                  "pe_ttm": 1,
                                                  "close": 1
                                              })

        item_df = pd.DataFrame(list(_idx_list),
                               columns=["date", "pe_ttm", "close"])
        item_df = item_df.dropna(0)

        _pe_series = 1 / item_df["pe_ttm"]
        item_df.insert(0, 'rank', _pe_series.rank(pct=True))
        item_df = item_df.reset_index()

        total_count = 0  # 累计数量

        for idx, item_date in enumerate(last_day_list):
            last_df = item_df[item_df["date"] == str(item_date)]
            if last_df is None or len(last_df) <= 0:
                continue

            _tmp_rank = last_df.ix[last_df.index.values[0]]["rank"]
            item_point = last_df.ix[last_df.index.values[0]]["close"]
            item_rank = float("%.2f" % ((1 - _tmp_rank) * 100))

            if item_rank >= 80 and total_count > 0:
                # 全部卖出, 卖出后要扣税费
                item_count = total_count * item_point * (1 - tax) / item_point
                data.append(
                    [item_date, item_rank, "卖出", -item_point, item_count, 0])
                total_count = 0

            elif 60 <= item_rank < 80:
                # 卖出1份
                _op = "卖出"
                # 卖出的这一份应该包含税费,所以要多卖出一部分税费的数量
                item_count = _money_per * (1 + tax) / item_point
                if total_count >= item_count:
                    total_count -= item_count
                elif total_count > 0:
                    item_count = total_count
                    total_count = 0
                else:
                    _op = "/"
                    item_count = 0
                    total_count = 0

                data.append([
                    item_date, item_rank, _op, -item_point, item_count,
                    total_count
                ])

            elif 40 <= item_rank < 60:
                # 买入1份
                item_count = _money_per * (1 - tax) / item_point
                total_count += item_count
                data.append([
                    item_date, item_rank, "买入", item_point, item_count,
                    total_count
                ])

            elif 20 <= item_rank < 40:
                # 买入1.5份
                item_count = (_money_per * 1.5) * (1 - tax) / item_point
                total_count += item_count
                data.append([
                    item_date, item_rank, "买入", item_point, item_count,
                    total_count
                ])
            elif 0 <= item_rank < 20:
                # 买入2份
                item_count = (_money_per * 2) * (1 - tax) / item_point
                total_count += item_count
                data.append([
                    item_date, item_rank, "买入", item_point, item_count,
                    total_count
                ])
            else:
                data.append(
                    [item_date, item_rank, "/", item_point, 0, total_count])

        result_df = pd.DataFrame(
            data, columns=["日期", "百分位", "操作", "单价", "数量", "累计数量"])

        result_df.to_csv(config.get("files").get("plots") %
                         (PROJECT_ROOT, "plot2", _market, _idx_code),
                         index=False,
                         mode="w",
                         header=True,
                         encoding='gb18030',
                         float_format="%.3f")
Ejemplo n.º 6
0
def mv():
    """
        总市值=当前股价×总股本
    """
    click.echo("计算总股本、流通股本、流通市值、总市值、股息率...")

    db_client = MongoDBClient(
        config.get("db").get("mongodb"),
        config.get("db").get("database"))

    base_df = stocks.stock_a_list()
    bonus_df = bonus.bonus_with(None)

    report_df = pd.read_csv(config.get("files").get("reports"),
                            header=0,
                            encoding="utf8")
    report_df['code'] = report_df['code'].map(lambda x: str(x).zfill(6))

    for index, row in base_df.iterrows():
        try:
            print("计算 %d-%s 的股本、市值、股息率" % (row["market"], row["code"]))

            ccs = 0  # 流通股
            tcs = 0  # 总股本

            stock_day_list = db_client.find_stock_list(_filter={
                "code": row['code'],
                "market": row["market"],
                "close": {
                    "$exists": True
                }
            },
                                                       _sort=[
                                                           ("date",
                                                            pymongo.ASCENDING)
                                                       ],
                                                       _fields={
                                                           "date": 1,
                                                           "close": 1
                                                       })
            if len(stock_day_list) <= 0:
                # 股票本身没有交易量
                continue

            stock_day_df = pd.DataFrame(stock_day_list,
                                        columns=['date', 'close'])

            try:
                item_last = db_client.find_stock_item(_filter={
                    "code": row['code'],
                    "market": row["market"],
                    "dr": {
                        "$exists": True
                    }
                },
                                                      _sort=[
                                                          ("date",
                                                           pymongo.DESCENDING)
                                                      ])

                if item_last is not None and len(item_last) > 0:
                    # 如果之前计算过,则无需重头计算
                    last_day_df = stock_day_df[stock_day_df["date"] ==
                                               item_last['date']]
                    stock_day_df = stock_day_df[
                        stock_day_df.index > last_day_df.index.values[0]]

                    ccs = item_last["cmv"] // item_last["close"]  # 流通股
                    tcs = item_last["tmv"] // item_last["close"]  # 总股本

            except FileNotFoundError:
                pass

            filter_bonus_df = bonus_df[(bonus_df["code"] == row["code"])
                                       & (bonus_df["type"] != 6) &
                                       ((bonus_df["type"] > 1) &
                                        (bonus_df["type"] < 13))]
            filter_bonus_df = filter_bonus_df.sort_values(['date'],
                                                          ascending=True)

            filter_report_df = report_df[report_df["code"] == row["code"]]
            filter_report_df = filter_report_df.sort_values(['date'],
                                                            ascending=True)

            for idx, item in stock_day_df.iterrows():
                item_df = filter_bonus_df[filter_bonus_df["date"] == int(
                    item["date"])]
                if len(item_df) > 0:
                    # 高送转中记录的数据单位都到万
                    ccs = item_df.ix[item_df.index.values[0]]["count"] * 10000
                    tcs = item_df.ix[item_df.index.values[0]]["rate"] * 10000

                item_df = filter_report_df[filter_report_df["publish"] == int(
                    item["date"])]
                if len(item_df) > 0:
                    ccs = item_df.ix[item_df.index.values[0]]["ccs"]
                    tcs = item_df.ix[item_df.index.values[0]]["tcs"]

                ccs_mv = item["close"] * ccs
                tcs_mv = item["close"] * tcs
                # 3年的股息率
                dr = bonus.dividend_rate_with(int(item["date"]), row["code"],
                                              item["close"])

                db_client.upsert_one(_filter={
                    "code": str(row["code"]),
                    "market": row["market"],
                    "date": str(item["date"])
                },
                                     _value={
                                         "cmv": ccs_mv,
                                         "tmv": tcs_mv,
                                         "dr": dr
                                     })

        except FileNotFoundError:
            continue

    click.echo("总股本、流通股本、流通市值、总市值、股息率 计算完毕...")
Ejemplo n.º 7
0
def pe_pb_roe():
    """

    转换PE、PB、ROE、股息率 四个指标需要的信息
    1.基本每股收益、4.每股净资产、96.归属于母公司所有者的净利润、238.总股本、239.已上市流通A股
        PE=股价/每股收益
        PB=股价/每股净资产
        ROE=利润/每股净资产=PB/PE : 财报中已有静态的净资产收益率数据, 这里通过TTM计算一个大概的ROE作为参考
    :return:
    """
    db_client = MongoDBClient(
        config.get("db").get("mongodb"),
        config.get("db").get("database"))

    base_df = stocks.stock_a_list()

    for index, row in base_df.iterrows():
        try:
            print("计算 %d-%s 的PE、PB、ROE数据..." % (row["market"], row["code"]))

            stock_day_list = db_client.find_stock_list(_filter={
                "code": row['code'],
                "market": row["market"],
                "close": {
                    "$exists": True
                }
            },
                                                       _sort=[
                                                           ("date",
                                                            pymongo.ASCENDING)
                                                       ],
                                                       _fields={
                                                           "date": 1,
                                                           "close": 1
                                                       })
            if len(stock_day_list) <= 0:
                # 股票本身没有交易量
                continue

            stock_day_df = pd.DataFrame(stock_day_list,
                                        columns=['date', 'close'])

            item_last = db_client.find_stock_item(_filter={
                "code": row['code'],
                "market": row["market"],
                "pb": {
                    "$exists": True
                }
            },
                                                  _sort=[("date",
                                                          pymongo.DESCENDING)])

            if item_last is not None and len(item_last) > 0:
                # 如果之前计算过,则无需重头计算
                last_day_df = stock_day_df[stock_day_df["date"] ==
                                           item_last['date']]
                stock_day_df = stock_day_df[
                    stock_day_df.index > last_day_df.index.values[0]]

            for idx, item in stock_day_df.iterrows():
                lyr_value = rt.lyr_with(int(item["date"]), row['code'],
                                        item["close"])
                pe_value = rt.ttm_with(int(item["date"]), row['code'],
                                       item["close"])
                pb_value = rt.pb_with(int(item["date"]), row['code'],
                                      item["close"])
                roe_value = 0.0
                if pe_value != 0.0:
                    roe_value = pb_value / pe_value
                db_client.upsert_one(_filter={
                    "code": str(row["code"]),
                    "market": row["market"],
                    "date": str(item["date"])
                },
                                     _value={
                                         "lyr": lyr_value,
                                         "pe_ttm": pe_value,
                                         "pb": pb_value,
                                         "roe": roe_value
                                     })

        except FileNotFoundError:
            continue
Ejemplo n.º 8
0
def fixed():
    db_client = MongoDBClient(
        config.get("db").get("mongodb"),
        config.get("db").get("database"))

    base_df = stocks.stock_a_list()
    bonus_df = bonus.bonus_with(None)

    for index, row in base_df.iterrows():
        try:
            prev_close = 0
            prev_fixed_close = 0

            print("计算 %d-%s 的后复权数据" % (row["market"], row["code"]))

            stock_day_list = db_client.find_stock_list(_filter={
                "code": row['code'],
                "market": row["market"]
            },
                                                       _sort=[
                                                           ("date",
                                                            pymongo.ASCENDING)
                                                       ],
                                                       _fields={
                                                           "date": 1,
                                                           "close": 1
                                                       })
            if len(stock_day_list) <= 0:
                # 股票本身没有交易量无需复权
                continue

            stock_day_df = pd.DataFrame(stock_day_list,
                                        columns=['date', 'close'])

            try:
                item_last = db_client.find_stock_item(_filter={
                    "code": row['code'],
                    "market": row["market"],
                    "fixed": {
                        "$exists": True
                    }
                },
                                                      _sort=[
                                                          ("date",
                                                           pymongo.DESCENDING)
                                                      ])

                if item_last is not None and len(item_last) > 0:
                    # 如果之前计算过后复权价,则无需重头计算
                    last_day_df = stock_day_df[stock_day_df["date"] ==
                                               item_last['date']]

                    prev_close = last_day_df.ix[
                        last_day_df.index.values[0]]["close"]
                    prev_fixed_close = item_last["fixed"]

                    stock_day_df = stock_day_df[
                        stock_day_df.index > last_day_df.index.values[0]]

            except FileNotFoundError:
                # 如果从来没计算过后复权价则不管
                pass

            filter_df = bonus_df[(bonus_df["type"] == 1)
                                 & (bonus_df["code"] == row["code"])]
            filter_df = filter_df.sort_values(['date'], ascending=True)
            for idx, item in stock_day_df.iterrows():
                money = 0  # 分红
                count = 0  # 送股数

                item_df = filter_df[filter_df["date"] == int(item["date"])]
                if len(item_df) > 0:
                    money = item_df.ix[item_df.index.values[0]]["money"] / 10
                    count = item_df.ix[item_df.index.values[0]]["count"] / 10

                # 除息除权日当天复权后的涨幅 =(当天不复权收盘价 *(1 + 每股送股数量)+每股分红金额) / 上一个交易日的不复权收盘价
                # 复权收盘价 = 上一个交易日的复权收盘价 *(1 + 复权涨幅)
                if prev_close > 0:
                    daily_rate_close = (item["close"] *
                                        (1 + count) + money) / prev_close
                    prev_fixed_close = prev_fixed_close * daily_rate_close

                else:
                    prev_fixed_close = item["close"]

                prev_close = item["close"]
                db_client.upsert_one(_filter={
                    "code": str(row["code"]),
                    "market": row["market"],
                    "date": str(item["date"])
                },
                                     _value={"fixed": prev_fixed_close})

        except FileNotFoundError:
            continue