Ejemplo n.º 1
0
def index_dr_json(_code=None):
    if _code is None or len(_code) < 8:
        return "error"
    _code = _code.upper()
    is_all = request.args.get('all')
    data = []
    _market = 1 if _code[:2] == "SH" else 0
    _idx_code = _code[2:]

    stock_model = StockModel()

    _filter = {"code": _idx_code, "market": _market}
    if is_all is None or len(is_all) <= 0:
        from_date = date.datetime_to_str(date.years_ago(10))
        _filter["date"] = {"$gte": from_date}

    _idx_list = stock_model.stock_list(_filter=_filter, _sort=[("date", pymongo.ASCENDING)],
                                       _fields={"date": 1, "dr": 1, "close": 1})

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

    for idx, row in item_df.iterrows():
        data.append([row["date"], float("%.2f" % (row["dr"] * 100)), float("%.2f" % row["close"])])

    return json.dumps(data)
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 index(_code=None):
    if _code is None or len(_code) < 8:
        return "error"

    """获取某个指数的详情"""
    _market = 1 if _code[:2] == "SH" else 0
    _idx_code = _code[2:]

    stock_model = StockModel()

    _filter = {"code": _idx_code, "market": _market, "date": {"$gte": date.datetime_to_str(date.years_ago(10))}}

    _idx_list = stock_model.stock_list(_filter=_filter, _sort=[("date", pymongo.ASCENDING)],
                                       _fields={"date": 1, "name": 1, "pe_ttm": 1, "pb": 1, "dr": 1})

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

    _pe_series = 1 / item_df["pe_ttm"]
    pe_ranks = _pe_series.rank(pct=True)

    _pb_series = 1 / item_df["pb"]
    pb_ranks = _pb_series.rank(pct=True)

    return render_template('indexes/detail.mako', ctx={
        "index_name": item_df["name"].values[0],
        "index_code": _code,
        "start_date": date.datetime_to_str(date.years_ago(years=3)),

        "pe_max": "%.2f" % item_df["pe_ttm"].max(),
        "pe_min": "%.2f" % item_df["pe_ttm"].min(),
        "pe_mean": "%.2f" % item_df["pe_ttm"].mean(),
        "pe_high": "%.2f" % item_df["pe_ttm"].quantile(0.75),
        "pe_middle": "%.2f" % item_df["pe_ttm"].quantile(0.5),
        "pe_low": "%.2f" % item_df["pe_ttm"].quantile(0.2),
        "pe_value": "%.2f" % item_df["pe_ttm"].values[-1],
        "pe_rate": "%.2f%%" % ((1 - pe_ranks.values[-1]) * 100),

        "pb_max": "%.2f" % item_df["pb"].max(),
        "pb_min": "%.2f" % item_df["pb"].min(),
        "pb_mean": "%.2f" % item_df["pb"].mean(),
        "pb_high": "%.2f" % item_df["pb"].quantile(0.75),
        "pb_middle": "%.2f" % item_df["pb"].quantile(0.5),
        "pb_low": "%.2f" % item_df["pb"].quantile(0.2),
        "pb_value": "%.2f" % item_df["pb"].values[-1],
        "pb_rate": "%.2f%%" % ((1 - pb_ranks.values[-1]) * 100),

        "dr_max": "%.2f%%" % (item_df["dr"].max() * 100),
        "dr_min": "%.2f%%" % (item_df["dr"].min() * 100),
        "dr_mean": "%.2f%%" % (item_df["dr"].mean() * 100),
        "dr_value": "%.2f%%" % (item_df["dr"].values[-1] * 100)
    })
Ejemplo n.º 4
0
def stock_pe_json(_code: str = None):
    if _code is None or len(_code) < 8:
        return "error"
    _code = _code.upper()
    is_all = request.args.get('all')
    data = []
    _market = 1 if _code[:2] == "SH" else 0
    _idx_code = _code[2:]

    stockModel = StockModel()

    _filter = {"code": _idx_code, "market": _market}
    if is_all is None or len(is_all) <= 0:
        from_date = date.datetime_to_str(date.years_ago(10))
        _filter["date"] = {"$gte": from_date}

    _idx_list = stockModel.stock_list(_filter=_filter,
                                      _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)
    item_df = item_df.reset_index()

    _pe_series = 1 / item_df["pe_ttm"]
    pe_ranks = _pe_series.rank(pct=True)

    _pe_list = []
    for idx, row in item_df.iterrows():
        _pe_list.append(row["pe_ttm"])

        _pe_high = np.percentile(_pe_list, 75)
        _pe_middle = np.percentile(_pe_list, 50)
        _pe_low = np.percentile(_pe_list, 20)

        _item_rank = float("%.2f" % ((1 - pe_ranks.values[idx]) * 100))
        data.append([
            row["date"],
            float("%.2f" % row["pe_ttm"]),
            float("%.2f" % _pe_high),
            float("%.2f" % _pe_middle),
            float("%.2f" % _pe_low), _item_rank,
            float("%.2f" % row["close"])
        ])

    return json.dumps(data)
Ejemplo n.º 5
0
def dividend_rate_with(_date: int, _code: str, _price: float):
    """
    求某只股票在指定时间点的三年平均股息率
    :param _date:
    :param _code:
    :param _price:
    :return:
    """
    end = date.str_to_datetime(str(_date))
    start = date.years_ago(years=3, from_date=end)
    bonus_df = bonus_with(_code=_code).sort_values(['date'], ascending=True)
    filter_df = bonus_df[(bonus_df["type"] == 1) & (
        bonus_df["date"] >= int(date.datetime_to_str(start))) &
                         (bonus_df["date"] <= int(date.datetime_to_str(end)))]

    total_money = 0.0
    for idx, item in filter_df.iterrows():
        # 每股分红的三年之和
        total_money += item["money"] / 10

    return total_money / (3 * _price)
Ejemplo n.º 6
0
def indexes():
    """显示指数估值信息"""
    _lp_file = None

    try:
        _lp_file = open("%s/last_update" % PROJECT_ROOT, 'r')
        _content = _lp_file.read()
        last_date = _content.strip()
    finally:
        if _lp_file:
            _lp_file.close()

    _tmp_date = date.datetime_to_str(date.years_ago(years=3))
    _tmp_date = _tmp_date if date.is_work_day(int(_tmp_date)) else str(date.next_day(int(_tmp_date)))

    last_date = last_date if date.is_work_day(int(last_date)) else str(date.prev_day(int(last_date)))

    return render_template('indexes/list.mako', ctx={
        "last_date": last_date,
        "start_date": _tmp_date
    })
Ejemplo n.º 7
0
def home():
    """首页 """
    return render_template('home.mako', ctx={
        "title": "宽基PB走势图",
        "start_date": date.datetime_to_str(date.years_ago(years=3))
    })
Ejemplo n.º 8
0
def indexes_json():
    """显示指数估值信息"""
    # '上证50', '沪深300', '中证500', '中证1000', '上证红利', '中证红利','中小板指', '创业扳指'
    # '食品饮料'
    idx_list = config.get("indexes")
    stock_model = StockModel()
    result = []

    for idx, item in enumerate(idx_list):
        index_obj = {"idx": idx + 1}
        _market = 'SZ' if item[0] == 0 else 'SH'

        item_detail = stock_model.stock_item(_filter={"code": item[1], "market": item[0]},
                                             _sort=[("date", pymongo.DESCENDING)])

        index_obj["name"] = "<a href='/index/%s%s' title='%s的估值信息'> %s </a>" % \
                            (_market, item_detail["code"], item_detail["name"], item_detail["name"])
        index_obj["interest"] = "%.2f%%" % (1 / item_detail["pe_ttm"] * 100)
        index_obj["dr"] = "%.2f%%" % (item_detail["dr"] * 100)
        index_obj["roe"] = "%.2f%%" % (item_detail["roe"] * 100)
        index_obj["PE"] = "%.2f" % item_detail["pe_ttm"]
        index_obj["PB"] = "%.2f" % item_detail["pb"]

        _filter = {"code": item[1], "market": item[0], "date": {"$gte": date.datetime_to_str(date.years_ago(10))}}
        item_list = stock_model.stock_list(_filter=_filter, _sort=[("date", pymongo.ASCENDING)],
                                           _fields={"pe_ttm": 1, "pb": 1})

        item_df = pd.DataFrame(list(item_list), columns=["pe_ttm", "pb"])
        item_df = item_df.dropna(0)

        _pe_series = 1 / item_df["pe_ttm"]
        pe_ranks = _pe_series.rank(pct=True)

        _pb_series = 1 / item_df["pb"]
        pb_ranks = _pb_series.rank(pct=True)

        index_obj["PE_RATE"] = "%.2f%%" % ((1 - pe_ranks.values[-1]) * 100)
        index_obj["PB_RATE"] = "%.2f%%" % ((1 - pb_ranks.values[-1]) * 100)

        # 本周以来的涨跌幅
        now = datetime.today()
        _tmp_date = (now - timedelta(days=now.weekday())).strftime('%Y%m%d')
        item_last_week = stock_model.stock_item(_filter={"code": item[1], "market": item[0],
                                                         "date": _tmp_date if date.is_work_day(int(_tmp_date))
                                                         else str(date.next_day(int(_tmp_date)))})
        if item_last_week is None:
            item_last_week = item_detail

        # 本月以来
        _tmp_date = datetime(now.year, now.month, 1).strftime('%Y%m%d')
        item_last_month = stock_model.stock_item(_filter={"code": item[1], "market": item[0],
                                                          "date": _tmp_date if date.is_work_day(int(_tmp_date))
                                                          else str(date.next_day(int(_tmp_date)))})
        if item_last_month is None:
            item_last_month = item_detail

        # 本季度以来
        month = (now.month - 1) - (now.month - 1) % 3 + 1
        _tmp_date = datetime(now.year, month, 1).strftime('%Y%m%d')
        item_last_quarter = stock_model.stock_item(_filter={"code": item[1], "market": item[0],
                                                            "date": _tmp_date if date.is_work_day(int(_tmp_date))
                                                            else str(date.next_day(int(_tmp_date)))})

        if item_last_quarter is None:
            item_last_quarter = item_detail

        # 本年度以来
        _tmp_date = datetime(now.year, 1, 1).strftime('%Y%m%d')
        item_last_year = stock_model.stock_item(_filter={"code": item[1], "market": item[0],
                                                         "date": _tmp_date if date.is_work_day(int(int(_tmp_date)))
                                                         else str(date.next_day(int(_tmp_date)))})

        if item_last_year is None:
            item_last_year = item_detail

        index_obj["last_week"] = "%.2f%%" % (
                    (item_detail["close"] - item_last_week["close"]) / item_last_week["close"] * 100)
        index_obj["last_month"] = "%.2f%%" % (
                    (item_detail["close"] - item_last_month["close"]) / item_last_month["close"] * 100)
        index_obj["last_quarter"] = "%.2f%%" % (
                    (item_detail["close"] - item_last_quarter["close"]) / item_last_quarter["close"] * 100)
        index_obj["last_year"] = "%.2f%%" % (
                    (item_detail["close"] - item_last_year["close"]) / item_last_year["close"] * 100)
        result.append(index_obj)

    # 追加A股市场的估值信息
    stock_a_df = pd.read_csv(config.get("files").get("stock_a"), header=0, encoding="utf8")
    stock_a_df = stock_a_df.dropna(0)
    if len(stock_a_df) > 0:
        item_last = stock_a_df.loc[stock_a_df.index[-1]]

        pe_array = 1 / stock_a_df["pe"]
        pb_array = 1 / stock_a_df["pb"]
        pe_ranks = pe_array.rank(pct=True)
        pb_ranks = pb_array.rank(pct=True)

        stock_a_item = {"idx": len(idx_list) + 1, "name": "A股市场", "interest": "%.2f%%" % (1 / item_last["pe"] * 100),
                        "dr": "%.2f%%" % (item_last["dr"] * 100), "roe": "%.2f%%" % (item_last["roe"] * 100),
                        "PE": "%.2f" % item_last["pe"], "PB": "%.2f" % item_last["pb"],
                        "PE_RATE": "%.2f%%" % ((1 - pe_ranks.values[-1]) * 100),
                        "PB_RATE": "%.2f%%" % ((1 - pb_ranks.values[-1]) * 100)}

        result.append(stock_a_item)

    # 追加国债收益供参考
    bond_df = pd.read_csv(config.get("files").get("bond"), header=0, encoding="utf8")
    if len(bond_df) > 0:
        item_last = bond_df.loc[bond_df.index[-1]]
        bond_item = {"idx": len(idx_list) + 2,
                     "name": "<a href='http://www.pbc.gov.cn/rmyh/108976/index.html#Container' "
                             "title='%s的历史利率' target='_blank'> 十年国债利率 </a>",
                     "interest": "%.2f%%" % item_last["10year"]}
        result.append(bond_item)

    return json.dumps(result)
Ejemplo n.º 9
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")